Search in sources :

Example 1 with SingleThreadChannel

use of org.openecard.ifd.scio.wrapper.SingleThreadChannel in project open-ecard by ecsec.

the class IfdEventRunner method fireEvents.

private void fireEvents(@Nonnull List<IFDStatusType> diff) {
    for (IFDStatusType term : diff) {
        String ifdName = term.getIFDName();
        // find out if the terminal is new, or only a slot got updated
        IFDStatusType oldTerm = getCorresponding(ifdName, currentState);
        boolean terminalAdded = oldTerm == null;
        IFDCapabilitiesType slotCapabilities = getCapabilities(ifdName);
        if (terminalAdded) {
            // TERMINAL ADDED
            // make copy of term
            oldTerm = new IFDStatusType();
            oldTerm.setIFDName(ifdName);
            oldTerm.setConnected(true);
            // add to current list
            currentState.add(oldTerm);
            // create event
            ConnectionHandleType h = makeConnectionHandle(ifdName, null, slotCapabilities);
            LOG.debug("Found a terminal added event ({}).", ifdName);
            env.getEventDispatcher().notify(EventType.TERMINAL_ADDED, new IfdEventObject(h));
        }
        // check each slot
        for (SlotStatusType slot : term.getSlotStatus()) {
            SlotStatusType oldSlot = getCorresponding(slot.getIndex(), oldTerm.getSlotStatus());
            boolean cardPresent = slot.isCardAvailable();
            boolean cardWasPresent = oldSlot != null && oldSlot.isCardAvailable();
            if (cardPresent && !cardWasPresent) {
                // CARD INSERTED
                // copy slot and add to list
                SlotStatusType newSlot = oldSlot;
                if (newSlot == null) {
                    newSlot = new SlotStatusType();
                    oldTerm.getSlotStatus().add(newSlot);
                }
                newSlot.setIndex(slot.getIndex());
                newSlot.setCardAvailable(true);
                newSlot.setATRorATS(slot.getATRorATS());
                // create event
                LOG.debug("Found a card insert event ({}).", ifdName);
                LOG.info("Card with ATR={} inserted.", ByteUtils.toHexString(slot.getATRorATS()));
                ConnectionHandleType handle = makeUnknownCardHandle(ifdName, newSlot, slotCapabilities);
                env.getEventDispatcher().notify(EventType.CARD_INSERTED, new IfdEventObject(handle));
                try {
                    SingleThreadChannel ch = cm.openMasterChannel(ifdName);
                    if (evtManager.isRecognize()) {
                        String proto = ch.getChannel().getCard().getProtocol().toUri();
                        evtManager.threadPool.submit(new Recognizer(env, handle, proto));
                    }
                } catch (NoSuchTerminal | SCIOException ex) {
                    LOG.error("Failed to connect card, nevertheless sending CARD_INSERTED event.", ex);
                }
            } else if (!terminalAdded && !cardPresent && cardWasPresent) {
                // this makes only sense when the terminal was already there
                // CARD REMOVED
                // remove slot entry
                BigInteger idx = oldSlot.getIndex();
                Iterator<SlotStatusType> it = oldTerm.getSlotStatus().iterator();
                while (it.hasNext()) {
                    SlotStatusType next = it.next();
                    if (idx.equals(next.getIndex())) {
                        it.remove();
                        break;
                    }
                }
                LOG.debug("Found a card removed event ({}).", ifdName);
                ConnectionHandleType h = makeConnectionHandle(ifdName, idx, slotCapabilities);
                env.getEventDispatcher().notify(EventType.CARD_REMOVED, new IfdEventObject(h));
            }
        }
        // terminal removed event comes after card removed events
        boolean terminalPresent = term.isConnected();
        if (!terminalPresent) {
            // TERMINAL REMOVED
            Iterator<IFDStatusType> it = currentState.iterator();
            while (it.hasNext()) {
                IFDStatusType toDel = it.next();
                if (toDel.getIFDName().equals(term.getIFDName())) {
                    it.remove();
                }
            }
            ConnectionHandleType h = makeConnectionHandle(ifdName, null, slotCapabilities);
            LOG.debug("Found a terminal removed event ({}).", ifdName);
            env.getEventDispatcher().notify(EventType.TERMINAL_REMOVED, new IfdEventObject(h));
        }
    }
}
Also used : ConnectionHandleType(iso.std.iso_iec._24727.tech.schema.ConnectionHandleType) NoSuchTerminal(org.openecard.common.ifd.scio.NoSuchTerminal) SingleThreadChannel(org.openecard.ifd.scio.wrapper.SingleThreadChannel) SCIOException(org.openecard.common.ifd.scio.SCIOException) IFDCapabilitiesType(iso.std.iso_iec._24727.tech.schema.IFDCapabilitiesType) Iterator(java.util.Iterator) BigInteger(java.math.BigInteger) IFDStatusType(iso.std.iso_iec._24727.tech.schema.IFDStatusType) SlotStatusType(iso.std.iso_iec._24727.tech.schema.SlotStatusType) IfdEventObject(org.openecard.common.event.IfdEventObject)

Example 2 with SingleThreadChannel

use of org.openecard.ifd.scio.wrapper.SingleThreadChannel in project open-ecard by ecsec.

the class IFD method beginTransaction.

@Override
public BeginTransactionResponse beginTransaction(BeginTransaction beginTransaction) {
    try {
        BeginTransactionResponse response;
        if (!hasContext()) {
            String msg = "Context not initialized.";
            Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
            response = WSHelper.makeResponse(BeginTransactionResponse.class, r);
            return response;
        }
        try {
            byte[] handle = beginTransaction.getSlotHandle();
            SingleThreadChannel ch = cm.getSlaveChannel(handle);
            ch.beginExclusive();
        } catch (NoSuchChannel | IllegalStateException ex) {
            String msg = "No card available in the requested terminal.";
            Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
            response = WSHelper.makeResponse(BeginTransactionResponse.class, r);
            LOG.warn(msg, ex);
            return response;
        } catch (SCIOException ex) {
            String msg;
            String minor;
            switch(ex.getCode()) {
                case SCARD_W_RESET_CARD:
                case SCARD_W_REMOVED_CARD:
                case SCARD_E_READER_UNAVAILABLE:
                case SCARD_E_NO_SMARTCARD:
                case SCARD_E_NO_SERVICE:
                    msg = String.format("Slot handle is not available [%s].", ex.getCode().name());
                    minor = ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE;
                    LOG.debug(msg, ex);
                    break;
                default:
                    msg = "Unknown error in the underlying SCIO implementation.";
                    minor = ECardConstants.Minor.App.UNKNOWN_ERROR;
                    LOG.warn(msg, ex);
            }
            Result r = WSHelper.makeResultError(minor, msg);
            response = WSHelper.makeResponse(BeginTransactionResponse.class, r);
            return response;
        }
        response = WSHelper.makeResponse(BeginTransactionResponse.class, WSHelper.makeResultOK());
        return response;
    } catch (Exception ex) {
        LOG.warn(ex.getMessage(), ex);
        throwThreadKillException(ex);
        return WSHelper.makeResponse(BeginTransactionResponse.class, WSHelper.makeResult(ex));
    }
}
Also used : SingleThreadChannel(org.openecard.ifd.scio.wrapper.SingleThreadChannel) NoSuchChannel(org.openecard.ifd.scio.wrapper.NoSuchChannel) SCIOException(org.openecard.common.ifd.scio.SCIOException) ThreadTerminateException(org.openecard.common.ThreadTerminateException) SCIOException(org.openecard.common.ifd.scio.SCIOException) ExecutionException(java.util.concurrent.ExecutionException) BeginTransactionResponse(iso.std.iso_iec._24727.tech.schema.BeginTransactionResponse) Result(oasis.names.tc.dss._1_0.core.schema.Result)

Example 3 with SingleThreadChannel

use of org.openecard.ifd.scio.wrapper.SingleThreadChannel in project open-ecard by ecsec.

the class IFD method transmit.

@Publish
@Override
public TransmitResponse transmit(Transmit parameters) {
    try {
        TransmitResponse response;
        if (!hasContext()) {
            String msg = "Context not initialized.";
            Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
            response = WSHelper.makeResponse(TransmitResponse.class, r);
            return response;
        }
        try {
            byte[] handle = parameters.getSlotHandle();
            SingleThreadChannel ch = cm.getSlaveChannel(handle);
            List<InputAPDUInfoType> apdus = parameters.getInputAPDUInfo();
            // check that the apdus contain sane values
            for (InputAPDUInfoType apdu : apdus) {
                for (byte[] code : apdu.getAcceptableStatusCode()) {
                    if (code.length == 0 || code.length > 2) {
                        String msg = "Invalid accepted status code given.";
                        Result r = WSHelper.makeResultError(ECardConstants.Minor.App.PARM_ERROR, msg);
                        response = WSHelper.makeResponse(TransmitResponse.class, r);
                        return response;
                    }
                }
            }
            // transmit APDUs and stop if an error occurs or a not expected status is hit
            response = WSHelper.makeResponse(TransmitResponse.class, WSHelper.makeResultOK());
            Result result;
            List<byte[]> rapdus = response.getOutputAPDU();
            try {
                for (InputAPDUInfoType capdu : apdus) {
                    byte[] rapdu = ch.transmit(capdu.getInputAPDU(), capdu.getAcceptableStatusCode());
                    rapdus.add(rapdu);
                }
                result = WSHelper.makeResultOK();
            } catch (TransmitException ex) {
                rapdus.add(ex.getResponseAPDU());
                result = ex.getResult();
            } catch (SCIOException ex) {
                String msg = "Error during transmit.";
                LOG.warn(msg, ex);
                result = WSHelper.makeResultUnknownError(msg);
            } catch (IllegalStateException ex) {
                String msg = "Card removed during transmit.";
                LOG.warn(msg, ex);
                result = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
            } catch (IllegalArgumentException ex) {
                String msg = "Given command contains a MANAGE CHANNEL APDU.";
                LOG.error(msg, ex);
                result = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
            }
            response.setResult(result);
            return response;
        } catch (NoSuchChannel | IllegalStateException ex) {
            String msg = "No card with transaction available in the requested terminal.";
            Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
            response = WSHelper.makeResponse(TransmitResponse.class, r);
            LOG.warn(msg, ex);
            return response;
        }
    } catch (Exception ex) {
        LOG.warn(ex.getMessage(), ex);
        throwThreadKillException(ex);
        return WSHelper.makeResponse(TransmitResponse.class, WSHelper.makeResult(ex));
    }
}
Also used : SingleThreadChannel(org.openecard.ifd.scio.wrapper.SingleThreadChannel) SCIOException(org.openecard.common.ifd.scio.SCIOException) NoSuchChannel(org.openecard.ifd.scio.wrapper.NoSuchChannel) InputAPDUInfoType(iso.std.iso_iec._24727.tech.schema.InputAPDUInfoType) ThreadTerminateException(org.openecard.common.ThreadTerminateException) SCIOException(org.openecard.common.ifd.scio.SCIOException) ExecutionException(java.util.concurrent.ExecutionException) Result(oasis.names.tc.dss._1_0.core.schema.Result) TransmitResponse(iso.std.iso_iec._24727.tech.schema.TransmitResponse) Publish(org.openecard.common.interfaces.Publish)

Example 4 with SingleThreadChannel

use of org.openecard.ifd.scio.wrapper.SingleThreadChannel in project open-ecard by ecsec.

the class IFD method getIFDCapabilities.

@Override
public GetIFDCapabilitiesResponse getIFDCapabilities(GetIFDCapabilities parameters) {
    GetIFDCapabilitiesResponse response;
    // you thought of a different IFD obviously
    if (!ByteUtils.compare(ctxHandle, parameters.getContextHandle())) {
        String msg = "Invalid context handle specified.";
        Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_CONTEXT_HANDLE, msg);
        response = WSHelper.makeResponse(GetIFDCapabilitiesResponse.class, r);
        return response;
    }
    try {
        TerminalInfo info;
        String ifdName = parameters.getIFDName();
        try {
            SingleThreadChannel channel = cm.openMasterChannel(ifdName);
            info = new TerminalInfo(cm, channel);
        } catch (NoSuchTerminal ex) {
            // continue without a channel
            SCIOTerminal term = cm.getTerminals().getTerminal(ifdName);
            info = new TerminalInfo(cm, term);
        }
        IFDCapabilitiesType cap = new IFDCapabilitiesType();
        // slot capability
        SlotCapabilityType slotCap = info.getSlotCapability();
        cap.getSlotCapability().add(slotCap);
        // ask protocol factory which types it supports
        List<String> protocols = slotCap.getProtocol();
        for (String proto : protocolFactories.protocols()) {
            if (!protocols.contains(proto)) {
                protocols.add(proto);
            }
        }
        // TODO: PIN Compare should be a part of establishChannel and thus just appear in the software protocol list
        if (!protocols.contains(ECardConstants.Protocol.PIN_COMPARE)) {
            protocols.add(ECardConstants.Protocol.PIN_COMPARE);
        }
        // display capability
        DisplayCapabilityType dispCap = info.getDisplayCapability();
        if (dispCap != null) {
            cap.getDisplayCapability().add(dispCap);
        }
        // keypad capability
        KeyPadCapabilityType keyCap = info.getKeypadCapability();
        if (keyCap != null) {
            cap.getKeyPadCapability().add(keyCap);
        }
        // biosensor capability
        BioSensorCapabilityType bioCap = info.getBiosensorCapability();
        if (bioCap != null) {
            cap.getBioSensorCapability().add(bioCap);
        }
        // acoustic and optical elements
        cap.setOpticalSignalUnit(info.isOpticalSignal());
        cap.setAcousticSignalUnit(info.isAcousticSignal());
        // prepare response
        response = WSHelper.makeResponse(GetIFDCapabilitiesResponse.class, WSHelper.makeResultOK());
        response.setIFDCapabilities(cap);
        return response;
    } catch (NullPointerException | NoSuchTerminal ex) {
        String msg = String.format("Requested terminal not found.");
        LOG.warn(msg, ex);
        Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.Terminal.UNKNOWN_IFD, msg);
        response = WSHelper.makeResponse(GetIFDCapabilitiesResponse.class, r);
        return response;
    } catch (SCIOException ex) {
        String msg = String.format("Failed to request status from terminal.");
        // use debug when card has been removed, as this happens all the time
        SCIOErrorCode code = ex.getCode();
        if (!(code == SCIOErrorCode.SCARD_E_NO_SMARTCARD || code == SCIOErrorCode.SCARD_W_REMOVED_CARD)) {
            LOG.warn(msg, ex);
        } else {
            LOG.debug(msg, ex);
        }
        Result r = WSHelper.makeResultUnknownError(msg);
        response = WSHelper.makeResponse(GetIFDCapabilitiesResponse.class, r);
        return response;
    }
}
Also used : SlotCapabilityType(iso.std.iso_iec._24727.tech.schema.SlotCapabilityType) NoSuchTerminal(org.openecard.common.ifd.scio.NoSuchTerminal) SingleThreadChannel(org.openecard.ifd.scio.wrapper.SingleThreadChannel) SCIOException(org.openecard.common.ifd.scio.SCIOException) SCIOTerminal(org.openecard.common.ifd.scio.SCIOTerminal) DisplayCapabilityType(iso.std.iso_iec._24727.tech.schema.DisplayCapabilityType) IFDCapabilitiesType(iso.std.iso_iec._24727.tech.schema.IFDCapabilitiesType) TerminalInfo(org.openecard.ifd.scio.wrapper.TerminalInfo) Result(oasis.names.tc.dss._1_0.core.schema.Result) KeyPadCapabilityType(iso.std.iso_iec._24727.tech.schema.KeyPadCapabilityType) SCIOErrorCode(org.openecard.common.ifd.scio.SCIOErrorCode) GetIFDCapabilitiesResponse(iso.std.iso_iec._24727.tech.schema.GetIFDCapabilitiesResponse) BioSensorCapabilityType(iso.std.iso_iec._24727.tech.schema.BioSensorCapabilityType)

Example 5 with SingleThreadChannel

use of org.openecard.ifd.scio.wrapper.SingleThreadChannel in project open-ecard by ecsec.

the class IFD method verifyUser.

@Override
public VerifyUserResponse verifyUser(VerifyUser parameters) {
    // TODO: convert to IFD Protocol
    try {
        VerifyUserResponse response;
        if (!hasContext()) {
            String msg = "Context not initialized.";
            Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
            response = WSHelper.makeResponse(VerifyUserResponse.class, r);
            return response;
        }
        SingleThreadChannel channel = cm.getSlaveChannel(parameters.getSlotHandle());
        AbstractTerminal aTerm = new AbstractTerminal(this, cm, channel, gui, ctxHandle, parameters.getDisplayIndex());
        try {
            response = aTerm.verifyUser(parameters);
            return response;
        } catch (IFDException ex) {
            response = WSHelper.makeResponse(VerifyUserResponse.class, ex.getResult());
            return response;
        }
    } catch (Exception ex) {
        LOG.warn(ex.getMessage(), ex);
        throwThreadKillException(ex);
        return WSHelper.makeResponse(VerifyUserResponse.class, WSHelper.makeResult(ex));
    }
}
Also used : SingleThreadChannel(org.openecard.ifd.scio.wrapper.SingleThreadChannel) VerifyUserResponse(iso.std.iso_iec._24727.tech.schema.VerifyUserResponse) ThreadTerminateException(org.openecard.common.ThreadTerminateException) SCIOException(org.openecard.common.ifd.scio.SCIOException) ExecutionException(java.util.concurrent.ExecutionException) Result(oasis.names.tc.dss._1_0.core.schema.Result)

Aggregations

SingleThreadChannel (org.openecard.ifd.scio.wrapper.SingleThreadChannel)13 Result (oasis.names.tc.dss._1_0.core.schema.Result)11 SCIOException (org.openecard.common.ifd.scio.SCIOException)11 ExecutionException (java.util.concurrent.ExecutionException)6 ThreadTerminateException (org.openecard.common.ThreadTerminateException)6 NoSuchTerminal (org.openecard.common.ifd.scio.NoSuchTerminal)6 NoSuchChannel (org.openecard.ifd.scio.wrapper.NoSuchChannel)5 TerminalInfo (org.openecard.ifd.scio.wrapper.TerminalInfo)5 BigInteger (java.math.BigInteger)4 IFDStatusType (iso.std.iso_iec._24727.tech.schema.IFDStatusType)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 BeginTransactionResponse (iso.std.iso_iec._24727.tech.schema.BeginTransactionResponse)2 ConnectionHandleType (iso.std.iso_iec._24727.tech.schema.ConnectionHandleType)2 IFDCapabilitiesType (iso.std.iso_iec._24727.tech.schema.IFDCapabilitiesType)2 SlotStatusType (iso.std.iso_iec._24727.tech.schema.SlotStatusType)2 SCIOTerminal (org.openecard.common.ifd.scio.SCIOTerminal)2 ExecutePACERequest (org.openecard.ifd.scio.reader.ExecutePACERequest)2 ExecutePACEResponse (org.openecard.ifd.scio.reader.ExecutePACEResponse)2 ActionType (iso.std.iso_iec._24727.tech.schema.ActionType)1 BeginTransaction (iso.std.iso_iec._24727.tech.schema.BeginTransaction)1