Search in sources :

Example 1 with NoSuchChannel

use of org.openecard.ifd.scio.wrapper.NoSuchChannel 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 2 with NoSuchChannel

use of org.openecard.ifd.scio.wrapper.NoSuchChannel 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 3 with NoSuchChannel

use of org.openecard.ifd.scio.wrapper.NoSuchChannel 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 4 with NoSuchChannel

use of org.openecard.ifd.scio.wrapper.NoSuchChannel 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 5 with NoSuchChannel

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

the class IFD method controlIFD.

/**
 * Note: the first byte of the command data is the control code.
 */
@Override
public ControlIFDResponse controlIFD(ControlIFD parameters) {
    ControlIFDResponse response;
    if (!hasContext()) {
        String msg = "Context not initialized.";
        Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE, msg);
        response = WSHelper.makeResponse(ControlIFDResponse.class, r);
        return response;
    }
    byte[] handle = parameters.getSlotHandle();
    byte[] command = parameters.getCommand();
    if (handle == null || command == null) {
        String msg = "Missing parameter.";
        Result r = WSHelper.makeResultUnknownError(msg);
        response = WSHelper.makeResponse(ControlIFDResponse.class, r);
        return response;
    }
    byte ctrlCode = command[0];
    command = Arrays.copyOfRange(command, 1, command.length);
    try {
        SingleThreadChannel ch = cm.getSlaveChannel(handle);
        TerminalInfo info = new TerminalInfo(cm, ch);
        Integer featureCode = info.getFeatureCodes().get(Integer.valueOf(ctrlCode));
        // see if the terminal can deal with that
        if (featureCode != null) {
            byte[] resultCommand = ch.transmitControlCommand(featureCode, command);
            // evaluate result
            Result result = evaluateControlIFDRAPDU(resultCommand);
            response = WSHelper.makeResponse(ControlIFDResponse.class, result);
            response.setResponse(resultCommand);
            return response;
        } else {
            String msg = "The terminal is not capable of performing the requested action.";
            Result r = WSHelper.makeResultUnknownError(msg);
            response = WSHelper.makeResponse(ControlIFDResponse.class, r);
            return response;
        }
    } catch (NoSuchChannel | IllegalStateException ex) {
        String msg = "The card or the terminal is not available anymore.";
        Result r = WSHelper.makeResultError(ECardConstants.Minor.IFD.Terminal.UNKNOWN_IFD, msg);
        response = WSHelper.makeResponse(ControlIFDResponse.class, r);
        LOG.warn(msg, ex);
        return response;
    } catch (SCIOException ex) {
        String msg = "Unknown error while sending transmit control command.";
        Result r = WSHelper.makeResultUnknownError(msg);
        response = WSHelper.makeResponse(ControlIFDResponse.class, r);
        LOG.warn(msg, ex);
        return response;
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BigInteger(java.math.BigInteger) ControlIFDResponse(iso.std.iso_iec._24727.tech.schema.ControlIFDResponse) SingleThreadChannel(org.openecard.ifd.scio.wrapper.SingleThreadChannel) NoSuchChannel(org.openecard.ifd.scio.wrapper.NoSuchChannel) SCIOException(org.openecard.common.ifd.scio.SCIOException) TerminalInfo(org.openecard.ifd.scio.wrapper.TerminalInfo) Result(oasis.names.tc.dss._1_0.core.schema.Result)

Aggregations

Result (oasis.names.tc.dss._1_0.core.schema.Result)5 SCIOException (org.openecard.common.ifd.scio.SCIOException)5 NoSuchChannel (org.openecard.ifd.scio.wrapper.NoSuchChannel)5 SingleThreadChannel (org.openecard.ifd.scio.wrapper.SingleThreadChannel)5 ExecutionException (java.util.concurrent.ExecutionException)4 ThreadTerminateException (org.openecard.common.ThreadTerminateException)4 ActionType (iso.std.iso_iec._24727.tech.schema.ActionType)1 BeginTransactionResponse (iso.std.iso_iec._24727.tech.schema.BeginTransactionResponse)1 ConnectionHandleType (iso.std.iso_iec._24727.tech.schema.ConnectionHandleType)1 ControlIFDResponse (iso.std.iso_iec._24727.tech.schema.ControlIFDResponse)1 DisconnectResponse (iso.std.iso_iec._24727.tech.schema.DisconnectResponse)1 EndTransactionResponse (iso.std.iso_iec._24727.tech.schema.EndTransactionResponse)1 InputAPDUInfoType (iso.std.iso_iec._24727.tech.schema.InputAPDUInfoType)1 TransmitResponse (iso.std.iso_iec._24727.tech.schema.TransmitResponse)1 BigInteger (java.math.BigInteger)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 NoSuchTerminal (org.openecard.common.ifd.scio.NoSuchTerminal)1 SCIOCard (org.openecard.common.ifd.scio.SCIOCard)1 Publish (org.openecard.common.interfaces.Publish)1 HandlerBuilder (org.openecard.common.util.HandlerBuilder)1