Search in sources :

Example 6 with SingleThreadChannel

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

the class IFD method destroyChannel.

@Override
public DestroyChannelResponse destroyChannel(DestroyChannel parameters) {
    try {
        DestroyChannelResponse destroyChannelResponse = new DestroyChannelResponse();
        byte[] slotHandle = parameters.getSlotHandle();
        SingleThreadChannel channel = cm.getSlaveChannel(slotHandle);
        TerminalInfo termInfo = new TerminalInfo(cm, channel);
        // check if it is PACE and try to perform native implementation
        // get pace capabilities
        List<PACECapabilities.PACECapability> paceCapabilities = termInfo.getPACECapabilities();
        if (paceCapabilities.contains(PACECapabilities.PACECapability.DestroyPACEChannel)) {
            ExecutePACERequest execPaceReq = new ExecutePACERequest(ExecutePACERequest.Function.DestroyPACEChannel);
            byte[] reqData = execPaceReq.toBytes();
            LOG.debug("executeCtrlCode request: {}", ByteUtils.toHexString(reqData));
            // execute pace
            Map<Integer, Integer> features = termInfo.getFeatureCodes();
            byte[] resData = channel.transmitControlCommand(features.get(PCSCFeatures.EXECUTE_PACE), reqData);
            LOG.debug("Response of executeCtrlCode: {}", ByteUtils.toHexString(resData));
            // evaluate response
            ExecutePACEResponse execPaceRes = new ExecutePACEResponse(resData);
            if (execPaceRes.isError()) {
                destroyChannelResponse = WSHelper.makeResponse(DestroyChannelResponse.class, execPaceRes.getResult());
            }
        }
        channel.removeSecureMessaging();
        if (destroyChannelResponse.getResult() == null) {
            Result r = new Result();
            r.setResultMajor(ECardConstants.Major.OK);
            destroyChannelResponse.setResult(r);
        }
        return destroyChannelResponse;
    } catch (Throwable t) {
        return WSHelper.makeResponse(DestroyChannelResponse.class, WSHelper.makeResult(t));
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BigInteger(java.math.BigInteger) SingleThreadChannel(org.openecard.ifd.scio.wrapper.SingleThreadChannel) TerminalInfo(org.openecard.ifd.scio.wrapper.TerminalInfo) ExecutePACEResponse(org.openecard.ifd.scio.reader.ExecutePACEResponse) ExecutePACERequest(org.openecard.ifd.scio.reader.ExecutePACERequest) DestroyChannelResponse(iso.std.iso_iec._24727.tech.schema.DestroyChannelResponse) Result(oasis.names.tc.dss._1_0.core.schema.Result)

Example 7 with SingleThreadChannel

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

the class IFD method connect.

@Override
public ConnectResponse connect(Connect parameters) {
    try {
        ConnectResponse response;
        // check if the requested handle is valid
        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(ConnectResponse.class, r);
            return response;
        } else {
            try {
                String name = parameters.getIFDName();
                // make sure the slot is connected before attemting to get a slave channel
                cm.openMasterChannel(name);
                byte[] slotHandle = cm.openSlaveChannel(name).p1;
                SingleThreadChannel ch = cm.getSlaveChannel(slotHandle);
                // make connection exclusive
                Boolean exclusive = parameters.isExclusive();
                if (exclusive != null && exclusive == true) {
                    BeginTransaction transact = new BeginTransaction();
                    transact.setSlotHandle(slotHandle);
                    BeginTransactionResponse resp = beginTransaction(transact);
                    if (resp.getResult().getResultMajor().equals(ECardConstants.Major.ERROR)) {
                        // destroy channel, when not successful here
                        ch.shutdown();
                        response = WSHelper.makeResponse(ConnectResponse.class, resp.getResult());
                        return response;
                    }
                }
                // connection established, return result
                response = WSHelper.makeResponse(ConnectResponse.class, WSHelper.makeResultOK());
                response.setSlotHandle(slotHandle);
                return response;
            } catch (NoSuchTerminal | NullPointerException ex) {
                String msg = "The requested terminal does not exist.";
                Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.Terminal.UNKNOWN_IFD, msg);
                response = WSHelper.makeResponse(ConnectResponse.class, r);
                LOG.warn(msg, ex);
                return response;
            } catch (IllegalStateException ex) {
                String msg = "No card available in the requested terminal.";
                Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.Terminal.NO_CARD, msg);
                response = WSHelper.makeResponse(ConnectResponse.class, r);
                LOG.warn(msg, ex);
                return response;
            } catch (SCIOException ex) {
                String msg = "Unknown error in the underlying SCIO implementation.";
                Result r = WSHelper.makeResultUnknownError(msg);
                response = WSHelper.makeResponse(ConnectResponse.class, r);
                LOG.warn(msg, ex);
                return response;
            }
        }
    } catch (Exception ex) {
        LOG.warn(ex.getMessage(), ex);
        throwThreadKillException(ex);
        return WSHelper.makeResponse(ConnectResponse.class, WSHelper.makeResult(ex));
    }
}
Also used : NoSuchTerminal(org.openecard.common.ifd.scio.NoSuchTerminal) ConnectResponse(iso.std.iso_iec._24727.tech.schema.ConnectResponse) SingleThreadChannel(org.openecard.ifd.scio.wrapper.SingleThreadChannel) SCIOException(org.openecard.common.ifd.scio.SCIOException) 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) BeginTransactionResponse(iso.std.iso_iec._24727.tech.schema.BeginTransactionResponse) BeginTransaction(iso.std.iso_iec._24727.tech.schema.BeginTransaction)

Example 8 with SingleThreadChannel

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

the class IFD method disconnect.

@Override
public synchronized DisconnectResponse disconnect(Disconnect parameters) {
    try {
        DisconnectResponse response;
        if (!hasContext()) {
            String msg = "Context not initialized.";
            Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
            response = WSHelper.makeResponse(DisconnectResponse.class, r);
            return response;
        }
        try {
            byte[] handle = parameters.getSlotHandle();
            SingleThreadChannel ch = cm.getSlaveChannel(handle);
            cm.closeSlaveChannel(handle);
            // process actions
            SCIOCard card = ch.getChannel().getCard();
            ActionType action = parameters.getAction();
            if (ActionType.RESET == action) {
                String ifdName = card.getTerminal().getName();
                SingleThreadChannel master = cm.getMasterChannel(ifdName);
                HandlerBuilder builder = HandlerBuilder.create();
                ConnectionHandleType cHandleIn = builder.setCardType(ECardConstants.UNKNOWN_CARD).setCardIdentifier(card.getATR().getBytes()).setContextHandle(ctxHandle).setIfdName(ifdName).setSlotIdx(BigInteger.ZERO).buildConnectionHandle();
                builder = HandlerBuilder.create();
                ConnectionHandleType cHandleRm = builder.setContextHandle(ctxHandle).setIfdName(ifdName).setSlotIdx(BigInteger.ZERO).buildConnectionHandle();
                try {
                    master.reconnect();
                    evManager.resetCard(cHandleRm, cHandleIn, card.getProtocol().toUri());
                } catch (IllegalStateException ex) {
                    LOG.warn("Card reconnect failed, trying to establish new card connection.", ex);
                    cm.closeMasterChannel(ifdName);
                    LOG.debug("Master channel closed successfully.");
                    try {
                        cm.getMasterChannel(ifdName);
                        LOG.debug("New card connection established successfully.");
                        evManager.resetCard(cHandleRm, cHandleIn, card.getProtocol().toUri());
                    } catch (NoSuchTerminal ex2) {
                        LOG.error("No terminal present anymore.", ex);
                    }
                }
            }
            // TODO: take care of other actions (probably over ControlIFD)
            // the default is to not disconnect the card, because all existing connections would be broken
            response = WSHelper.makeResponse(DisconnectResponse.class, WSHelper.makeResultOK());
            return response;
        } catch (NoSuchChannel ex) {
            String msg = "No card available in the requested terminal.";
            Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
            response = WSHelper.makeResponse(DisconnectResponse.class, r);
            LOG.warn(msg, ex);
            return response;
        } catch (SCIOException ex) {
            String msg = "Unknown error in the underlying SCIO implementation.";
            Result r = WSHelper.makeResultUnknownError(msg);
            response = WSHelper.makeResponse(DisconnectResponse.class, r);
            LOG.warn(msg, ex);
            return response;
        }
    } catch (Exception ex) {
        LOG.warn(ex.getMessage(), ex);
        throwThreadKillException(ex);
        return WSHelper.makeResponse(DisconnectResponse.class, WSHelper.makeResult(ex));
    }
}
Also used : ConnectionHandleType(iso.std.iso_iec._24727.tech.schema.ConnectionHandleType) ActionType(iso.std.iso_iec._24727.tech.schema.ActionType) NoSuchTerminal(org.openecard.common.ifd.scio.NoSuchTerminal) SingleThreadChannel(org.openecard.ifd.scio.wrapper.SingleThreadChannel) NoSuchChannel(org.openecard.ifd.scio.wrapper.NoSuchChannel) SCIOException(org.openecard.common.ifd.scio.SCIOException) SCIOCard(org.openecard.common.ifd.scio.SCIOCard) 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) DisconnectResponse(iso.std.iso_iec._24727.tech.schema.DisconnectResponse) HandlerBuilder(org.openecard.common.util.HandlerBuilder)

Example 9 with SingleThreadChannel

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

the class IFD method endTransaction.

@Override
public EndTransactionResponse endTransaction(EndTransaction parameters) {
    try {
        EndTransactionResponse response;
        if (!hasContext()) {
            String msg = "Context not initialized.";
            Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
            response = WSHelper.makeResponse(EndTransactionResponse.class, r);
            return response;
        }
        try {
            byte[] handle = parameters.getSlotHandle();
            SingleThreadChannel ch = cm.getSlaveChannel(handle);
            ch.endExclusive();
        } 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(EndTransactionResponse.class, r);
            LOG.warn(msg, ex);
            return response;
        } catch (SCIOException ex) {
            String msg = "Unknown error in the underlying SCIO implementation.";
            Result r = WSHelper.makeResultUnknownError(msg);
            response = WSHelper.makeResponse(EndTransactionResponse.class, r);
            LOG.warn(msg, ex);
            return response;
        }
        response = WSHelper.makeResponse(EndTransactionResponse.class, WSHelper.makeResultOK());
        return response;
    } catch (Exception ex) {
        LOG.warn(ex.getMessage(), ex);
        throwThreadKillException(ex);
        return WSHelper.makeResponse(EndTransactionResponse.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) EndTransactionResponse(iso.std.iso_iec._24727.tech.schema.EndTransactionResponse) 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)

Example 10 with SingleThreadChannel

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

the class EventWatcher method updateState.

private void updateState(TerminalWatcher.StateChangeEvent event) {
    String name = event.getTerminal();
    if (event.getState() == TerminalWatcher.EventType.TERMINAL_ADDED) {
        currentState.add(createEmptyState(name));
    } else {
        Iterator<IFDStatusType> it = currentState.iterator();
        while (it.hasNext()) {
            IFDStatusType next = it.next();
            SlotStatusType slot = next.getSlotStatus().get(0);
            if (next.getIFDName().equals(name)) {
                switch(event.getState()) {
                    case CARD_INSERTED:
                        try {
                            SingleThreadChannel ch = cm.openMasterChannel(name);
                            slot.setCardAvailable(true);
                            slot.setATRorATS(ch.getChannel().getCard().getATR().getBytes());
                        } catch (NoSuchTerminal | SCIOException ex) {
                            LOG.error("Failed to open master channel for terminal '" + name + "'.", ex);
                            slot.setCardAvailable(false);
                            cm.closeMasterChannel(name);
                        }
                        break;
                    case CARD_REMOVED:
                        cm.closeMasterChannel(name);
                        slot.setCardAvailable(false);
                        break;
                    case TERMINAL_REMOVED:
                        // just in case
                        slot.setCardAvailable(false);
                        next.setConnected(false);
                        break;
                }
                // no need to look any further
                break;
            }
        }
    }
}
Also used : NoSuchTerminal(org.openecard.common.ifd.scio.NoSuchTerminal) SingleThreadChannel(org.openecard.ifd.scio.wrapper.SingleThreadChannel) SCIOException(org.openecard.common.ifd.scio.SCIOException) IFDStatusType(iso.std.iso_iec._24727.tech.schema.IFDStatusType) SlotStatusType(iso.std.iso_iec._24727.tech.schema.SlotStatusType)

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