Search in sources :

Example 1 with ControlIFDResponse

use of iso.std.iso_iec._24727.tech.schema.ControlIFDResponse in project open-ecard by ecsec.

the class PINTest method testModifyPin.

@Test(enabled = false)
public void testModifyPin() throws IFDException, WSMarshallerException, SAXException {
    IFD ifd = new IFD();
    ifd.setGUI(new SwingUserConsent(new SwingDialogWrapper()));
    EstablishContext eCtx = new EstablishContext();
    byte[] ctxHandle = ifd.establishContext(eCtx).getContextHandle();
    ListIFDs listIFDs = new ListIFDs();
    listIFDs.setContextHandle(ctxHandle);
    String ifdName = ifd.listIFDs(listIFDs).getIFDName().get(0);
    Connect connect = new Connect();
    connect.setContextHandle(ctxHandle);
    connect.setIFDName(ifdName);
    connect.setSlot(BigInteger.ZERO);
    byte[] slotHandle = ifd.connect(connect).getSlotHandle();
    // prepare pace call
    String xmlCall = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<iso:EstablishChannel xmlns:iso=\"urn:iso:std:iso-iec:24727:tech:schema\">\n" + "  <iso:SlotHandle>" + ByteUtils.toHexString(slotHandle) + "</iso:SlotHandle>\n" + "  <iso:AuthenticationProtocolData Protocol=\"urn:oid:0.4.0.127.0.7.2.2.4\">\n" + "    <iso:PinID>03</iso:PinID>\n" + "  </iso:AuthenticationProtocolData>\n" + "</iso:EstablishChannel>";
    WSMarshaller m = WSMarshallerFactory.createInstance();
    EstablishChannel eCh = (EstablishChannel) m.unmarshal(m.str2doc(xmlCall));
    // send pace call
    EstablishChannelResponse eChR = ifd.establishChannel(eCh);
    assertEquals(eChR.getResult().getResultMajor(), ECardConstants.Major.OK);
    PasswordAttributesType pwdAttr = create(true, ASCII_NUMERIC, 6, 6, 6);
    pwdAttr.setPadChar(new byte[] { (byte) 0x3F });
    PCSCPinModify ctrlStruct = new PCSCPinModify(pwdAttr, StringUtils.toByteArray("002C0203"));
    byte[] structData = ctrlStruct.toBytes();
    String pinStr = "00 2C 02 03 06 3F3F3F3F3F3F";
    String ctrlStr = "15 05 82 06 00 00 00 0606 01 02 02 0407 00 01 02 000000 0B000000";
    // This is the command the 'AusweisApp' sends
    // String ausweisApp = "150582080000000606010202090400010200000005000000002C020300";
    byte[] referenceData = StringUtils.toByteArray(ctrlStr + pinStr, true);
    assertEquals(referenceData, structData);
    ControlIFD controlIFD = new ControlIFD();
    controlIFD.setCommand(ByteUtils.concatenate((byte) PCSCFeatures.MODIFY_PIN_DIRECT, structData));
    controlIFD.setSlotHandle(slotHandle);
    ControlIFDResponse response = ifd.controlIFD(controlIFD);
}
Also used : ListIFDs(iso.std.iso_iec._24727.tech.schema.ListIFDs) PasswordAttributesType(iso.std.iso_iec._24727.tech.schema.PasswordAttributesType) ControlIFD(iso.std.iso_iec._24727.tech.schema.ControlIFD) ControlIFD(iso.std.iso_iec._24727.tech.schema.ControlIFD) PCSCPinModify(org.openecard.ifd.scio.reader.PCSCPinModify) Connect(iso.std.iso_iec._24727.tech.schema.Connect) EstablishChannelResponse(iso.std.iso_iec._24727.tech.schema.EstablishChannelResponse) WSMarshaller(org.openecard.ws.marshal.WSMarshaller) SwingDialogWrapper(org.openecard.gui.swing.SwingDialogWrapper) EstablishChannel(iso.std.iso_iec._24727.tech.schema.EstablishChannel) ControlIFDResponse(iso.std.iso_iec._24727.tech.schema.ControlIFDResponse) SwingUserConsent(org.openecard.gui.swing.SwingUserConsent) EstablishContext(iso.std.iso_iec._24727.tech.schema.EstablishContext) Test(org.testng.annotations.Test)

Example 2 with ControlIFDResponse

use of iso.std.iso_iec._24727.tech.schema.ControlIFDResponse in project open-ecard by ecsec.

the class GenericPINAction method performPINChange.

private StepActionResult performPINChange(Map<String, ExecutionResults> oldResults) {
    String newPINValue = null;
    String newPINRepeatValue = null;
    if (capturePin) {
        try {
            ExecutionResults executionResults = oldResults.get(getStepID());
            PasswordField newPINField = (PasswordField) executionResults.getResult(GenericPINStep.NEW_PIN_FIELD);
            newPINValue = new String(newPINField.getValue());
            PasswordField newPINRepeatField = (PasswordField) executionResults.getResult(GenericPINStep.NEW_PIN_REPEAT_FIELD);
            newPINRepeatValue = new String(newPINRepeatField.getValue());
            byte[] pin1 = newPINValue.getBytes(ISO_8859_1);
            byte[] pin2 = newPINRepeatValue.getBytes(ISO_8859_1);
            if (!ByteUtils.compare(pin1, pin2)) {
                LOG.warn("New PIN does not match the value from the confirmation field.");
                // to reset the text fields
                gPINStep.updateState(state);
                return new StepActionResult(StepActionResultStatus.REPEAT);
            }
        } catch (UnsupportedEncodingException ex) {
            LOG.error("ISO_8859_1 charset is not support.", ex);
            // to reset the text fields
            gPINStep.updateState(state);
            return new StepActionResult(StepActionResultStatus.REPEAT);
        }
    }
    try {
        EstablishChannelResponse pinResponse = performPACEWithPIN(oldResults);
        if (pinResponse == null) {
            // the entered pin has a wrong format repeat the entering of the data
            gPINStep.setFailedPINVerify(false);
            gPINStep.setWrongPINFormat(true);
            return new StepActionResult(StepActionResultStatus.REPEAT);
        }
        if (pinResponse.getResult().getResultMajor().equals(ECardConstants.Major.ERROR)) {
            switch(pinResponse.getResult().getResultMinor()) {
                case ECardConstants.Minor.IFD.PASSWORD_ERROR:
                    gPINStep.setFailedPINVerify(true);
                    gPINStep.setWrongPINFormat(false);
                    gPINStep.updateState(RecognizedState.PIN_activated_RC2);
                    state = RecognizedState.PIN_activated_RC2;
                    return new StepActionResult(StepActionResultStatus.REPEAT);
                case ECardConstants.Minor.IFD.PASSWORD_SUSPENDED:
                    gPINStep.setFailedPINVerify(true);
                    gPINStep.setWrongPINFormat(false);
                    gPINStep.updateState(RecognizedState.PIN_suspended);
                    state = RecognizedState.PIN_suspended;
                    return new StepActionResult(StepActionResultStatus.REPEAT);
                case ECardConstants.Minor.IFD.PASSWORD_BLOCKED:
                    gPINStep.setFailedPINVerify(true);
                    gPINStep.setWrongPINFormat(false);
                    gPINStep.updateState(RecognizedState.PIN_blocked);
                    state = RecognizedState.PIN_blocked;
                    return new StepActionResult(StepActionResultStatus.REPEAT);
                default:
                    WSHelper.checkResult(pinResponse);
                    break;
            }
        }
        if (capturePin) {
            if (newPINValue.equals(newPINRepeatValue) && newPINValue.length() == 6) {
                // no result check necessary everything except a 9000 leads to an APDU exception
                sendResetRetryCounter(newPINValue.getBytes(ISO_8859_1));
            }
        } else {
            ControlIFDResponse resp = sendModifyPIN();
            evaluateControlIFDResponse(resp);
        }
        // PIN modified successfully, proceed with next step
        return new StepActionResult(StepActionResultStatus.REPEAT, generateSuccessStep(lang.translationForKey(CHANGE_SUCCESS)));
    } catch (APDUException | IFDException | ParserConfigurationException ex) {
        LOG.error("An internal error occurred while trying to change the PIN", ex);
        return new StepActionResult(StepActionResultStatus.REPEAT, generateErrorStep(lang.translationForKey(ERROR_INTERNAL)));
    } catch (UnsupportedEncodingException ex) {
        LOG.warn("The encoding of the PIN is wrong.", ex);
        return new StepActionResult(StepActionResultStatus.REPEAT);
    } catch (WSHelper.WSException ex) {
        // This is for PIN Pad Readers in case the user pressed the cancel button on the reader.
        if (ex.getResultMinor().equals(ECardConstants.Minor.IFD.CANCELLATION_BY_USER)) {
            LOG.error("User canceled the authentication manually or removed the card.", ex);
            return new StepActionResult(StepActionResultStatus.REPEAT, generateErrorStep(lang.translationForKey(ERROR_USER_CANCELLATION_OR_CARD_REMOVED)));
        }
        // for people which think they have to remove the card in the process
        if (ex.getResultMinor().equals(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE)) {
            LOG.error("The SlotHandle was invalid so probably the user removed the card or an reset occurred.", ex);
            return new StepActionResult(StepActionResultStatus.REPEAT, generateErrorStep(lang.translationForKey(ERROR_CARD_REMOVED)));
        }
        // for users which forgot to type in something
        if (ex.getResultMinor().equals(ECardConstants.Minor.IFD.TIMEOUT_ERROR)) {
            LOG.error("The terminal timed out no password was entered.", ex);
            return new StepActionResult(StepActionResultStatus.REPEAT, generateErrorStep(lang.translationForKey(ERROR_TIMEOUT)));
        }
        // the verification of the new pin failed
        if (ex.getResultMinor().equals(ECardConstants.Minor.IFD.PASSWORDS_DONT_MATCH)) {
            LOG.error("The verification of the new PIN failed.", ex);
            return new StepActionResult(StepActionResultStatus.REPEAT, generateErrorStep(lang.translationForKey(ERROR_NON_MATCHING_PASSWORDS)));
        }
        // We don't know what happend so just show an general error message
        LOG.error("An unknown error occurred while trying to change the PIN.", ex);
        return new StepActionResult(StepActionResultStatus.REPEAT, generateErrorStep(lang.translationForKey(ERROR_UNKNOWN)));
    } finally {
        // destroy the pace channel
        DestroyChannel destChannel = new DestroyChannel();
        destChannel.setSlotHandle(slotHandle);
        dispatcher.safeDeliver(destChannel);
        // Transaction based communication does not work on java 8 so the PACE channel is not closed after an
        // EndTransaction call. So do a reset of the card to close the PACE channel.
        Disconnect disconnect = new Disconnect();
        disconnect.setSlotHandle(slotHandle);
        disconnect.setAction(ActionType.RESET);
        dispatcher.safeDeliver(disconnect);
    }
}
Also used : WSHelper(org.openecard.common.WSHelper) APDUException(org.openecard.common.apdu.exception.APDUException) ExecutionResults(org.openecard.gui.executor.ExecutionResults) EstablishChannelResponse(iso.std.iso_iec._24727.tech.schema.EstablishChannelResponse) UnsupportedEncodingException(java.io.UnsupportedEncodingException) StepActionResult(org.openecard.gui.executor.StepActionResult) Disconnect(iso.std.iso_iec._24727.tech.schema.Disconnect) CardApplicationDisconnect(iso.std.iso_iec._24727.tech.schema.CardApplicationDisconnect) ControlIFDResponse(iso.std.iso_iec._24727.tech.schema.ControlIFDResponse) DestroyChannel(iso.std.iso_iec._24727.tech.schema.DestroyChannel) PasswordField(org.openecard.gui.definition.PasswordField) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) IFDException(org.openecard.ifd.scio.IFDException)

Example 3 with ControlIFDResponse

use of iso.std.iso_iec._24727.tech.schema.ControlIFDResponse 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)

Example 4 with ControlIFDResponse

use of iso.std.iso_iec._24727.tech.schema.ControlIFDResponse in project open-ecard by ecsec.

the class GenericPINAction method sendModifyPIN.

/**
 * Send a ModifyPIN-PCSC-Command to the Terminal.
 *
 * @throws IFDException If building the Command fails.
 */
private ControlIFDResponse sendModifyPIN() throws IFDException {
    PasswordAttributesType pwdAttr = create(true, ASCII_NUMERIC, 6, 6, 6);
    pwdAttr.setPadChar(new byte[] { (byte) 0x3F });
    PCSCPinModify ctrlStruct = new PCSCPinModify(pwdAttr, StringUtils.toByteArray("002C0203"));
    byte[] structData = ctrlStruct.toBytes();
    ControlIFD controlIFD = new ControlIFD();
    controlIFD.setCommand(ByteUtils.concatenate((byte) PCSCFeatures.MODIFY_PIN_DIRECT, structData));
    controlIFD.setSlotHandle(slotHandle);
    return (ControlIFDResponse) dispatcher.safeDeliver(controlIFD);
}
Also used : PasswordAttributesType(iso.std.iso_iec._24727.tech.schema.PasswordAttributesType) ControlIFDResponse(iso.std.iso_iec._24727.tech.schema.ControlIFDResponse) ControlIFD(iso.std.iso_iec._24727.tech.schema.ControlIFD) PCSCPinModify(org.openecard.ifd.scio.reader.PCSCPinModify)

Aggregations

ControlIFDResponse (iso.std.iso_iec._24727.tech.schema.ControlIFDResponse)4 ControlIFD (iso.std.iso_iec._24727.tech.schema.ControlIFD)2 EstablishChannelResponse (iso.std.iso_iec._24727.tech.schema.EstablishChannelResponse)2 PasswordAttributesType (iso.std.iso_iec._24727.tech.schema.PasswordAttributesType)2 PCSCPinModify (org.openecard.ifd.scio.reader.PCSCPinModify)2 CardApplicationDisconnect (iso.std.iso_iec._24727.tech.schema.CardApplicationDisconnect)1 Connect (iso.std.iso_iec._24727.tech.schema.Connect)1 DestroyChannel (iso.std.iso_iec._24727.tech.schema.DestroyChannel)1 Disconnect (iso.std.iso_iec._24727.tech.schema.Disconnect)1 EstablishChannel (iso.std.iso_iec._24727.tech.schema.EstablishChannel)1 EstablishContext (iso.std.iso_iec._24727.tech.schema.EstablishContext)1 ListIFDs (iso.std.iso_iec._24727.tech.schema.ListIFDs)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 BigInteger (java.math.BigInteger)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)1 Result (oasis.names.tc.dss._1_0.core.schema.Result)1 WSHelper (org.openecard.common.WSHelper)1 APDUException (org.openecard.common.apdu.exception.APDUException)1 SCIOException (org.openecard.common.ifd.scio.SCIOException)1