Search in sources :

Example 1 with PasswordAttributesType

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

the class AbstractTerminal method verifyUser.

public VerifyUserResponse verifyUser(VerifyUser verify) throws SCIOException, IFDException {
    byte[] handle = verify.getSlotHandle();
    // get capabilities
    getCapabilities();
    // check if is possible to perform PinCompare protocol
    List<String> protoList = this.capabilities.getSlotCapability().get(0).getProtocol();
    if (!protoList.contains(ECardConstants.Protocol.PIN_COMPARE)) {
        throw new IFDException("PinCompare protocol is not supported by this IFD.");
    }
    // get values from requested command
    InputUnitType inputUnit = verify.getInputUnit();
    AltVUMessagesType allMsgs = getMessagesOrDefaults(verify.getAltVUMessages());
    BigInteger firstTimeout = verify.getTimeoutUntilFirstKey();
    firstTimeout = (firstTimeout == null) ? BigInteger.valueOf(60000) : firstTimeout;
    BigInteger otherTimeout = verify.getTimeoutAfterFirstKey();
    otherTimeout = (otherTimeout == null) ? BigInteger.valueOf(15000) : otherTimeout;
    final byte[] template = verify.getTemplate();
    VerifyUserResponse response;
    Result result;
    // check which type of authentication to perform
    if (inputUnit.getBiometricInput() != null) {
        // TODO: implement
        String msg = "Biometric authentication not supported by IFD.";
        IFDException ex = new IFDException(ECardConstants.Minor.IFD.IO.UNKNOWN_INPUT_UNIT, msg);
        LOG.warn(ex.getMessage(), ex);
        throw ex;
    } else if (inputUnit.getPinInput() != null) {
        final PinInputType pinInput = inputUnit.getPinInput();
        // we have a sophisticated card reader
        if (terminalInfo.supportsPinCompare()) {
            // create custom pinAction to submit pin to terminal
            NativePinStepAction pinAction = new NativePinStepAction("enter-pin", pinInput, channel, terminalInfo, template);
            // display message instructing user what to do
            UserConsentDescription uc = pinUserConsent("action.changepin.userconsent.pinstep.title", pinAction);
            UserConsentNavigator ucr = gui.obtainNavigator(uc);
            ExecutionEngine exec = new ExecutionEngine(ucr);
            // run gui
            ResultStatus status = exec.process();
            if (status == ResultStatus.CANCEL) {
                String msg = "PIN entry cancelled by user.";
                LOG.warn(msg);
                result = WSHelper.makeResultError(ECardConstants.Minor.IFD.CANCELLATION_BY_USER, msg);
                response = WSHelper.makeResponse(VerifyUserResponse.class, result);
            } else if (pinAction.exception != null) {
                LOG.warn(pinAction.exception.getMessage(), pinAction.exception);
                result = WSHelper.makeResultError(ECardConstants.Minor.IFD.AUTHENTICATION_FAILED, pinAction.exception.getMessage());
                response = WSHelper.makeResponse(VerifyUserResponse.class, result);
            } else {
                // input by user
                byte[] verifyResponse = pinAction.response;
                // evaluate result
                result = checkNativePinVerify(verifyResponse);
                response = WSHelper.makeResponse(VerifyUserResponse.class, result);
                response.setResponse(verifyResponse);
            }
            return response;
        } else if (isVirtual()) {
            // software method
            // get pin, encode and send
            int minLength = pinInput.getPasswordAttributes().getMinLength().intValue();
            int maxLength = pinInput.getPasswordAttributes().getMaxLength().intValue();
            UserConsentDescription uc = pinUserConsent("action.changepin.userconsent.pinstep.title", minLength, maxLength);
            UserConsentNavigator ucr = gui.obtainNavigator(uc);
            ExecutionEngine exec = new ExecutionEngine(ucr);
            ResultStatus status = exec.process();
            if (status == ResultStatus.CANCEL) {
                String msg = "PIN entry cancelled by user.";
                LOG.warn(msg);
                result = WSHelper.makeResultError(ECardConstants.Minor.IFD.CANCELLATION_BY_USER, msg);
                response = WSHelper.makeResponse(VerifyUserResponse.class, result);
                return response;
            }
            char[] rawPIN = getPinFromUserConsent(exec);
            PasswordAttributesType attributes = pinInput.getPasswordAttributes();
            Transmit verifyTransmit;
            try {
                verifyTransmit = PINUtils.buildVerifyTransmit(rawPIN, attributes, template, handle);
            } catch (UtilException e) {
                String msg = "Failed to create the verifyTransmit message.";
                LOG.error(msg, e);
                result = WSHelper.makeResultError(ECardConstants.Minor.IFD.UNKNOWN_ERROR, msg);
                response = WSHelper.makeResponse(VerifyUserResponse.class, result);
                return response;
            } finally {
                Arrays.fill(rawPIN, ' ');
            }
            // send to reader
            TransmitResponse transResp;
            try {
                transResp = ifd.transmit(verifyTransmit);
            } finally {
                // blank PIN APDU
                for (InputAPDUInfoType apdu : verifyTransmit.getInputAPDUInfo()) {
                    byte[] rawApdu = apdu.getInputAPDU();
                    if (rawApdu != null) {
                        Arrays.fill(rawApdu, (byte) 0);
                    }
                }
            }
            // produce messages
            if (transResp.getResult().getResultMajor().equals(ECardConstants.Major.ERROR)) {
                if (transResp.getOutputAPDU().isEmpty()) {
                    result = WSHelper.makeResultError(ECardConstants.Minor.IFD.AUTHENTICATION_FAILED, transResp.getResult().getResultMessage().getValue());
                    response = WSHelper.makeResponse(VerifyUserResponse.class, result);
                    return response;
                } else {
                    response = WSHelper.makeResponse(VerifyUserResponse.class, transResp.getResult());
                    response.setResponse(transResp.getOutputAPDU().get(0));
                    // TODO: move this code to the PIN Compare protocol
                    if (response.getResponse() != null) {
                        CardResponseAPDU resApdu = new CardResponseAPDU(response.getResponse());
                        byte[] statusBytes = resApdu.getStatusBytes();
                        boolean isMainStatus = statusBytes[0] == (byte) 0x63;
                        boolean isMinorStatus = (statusBytes[1] & (byte) 0xF0) == (byte) 0xC0;
                        int triesLeft = statusBytes[1] & 0x0F;
                        if (isMainStatus && isMinorStatus && triesLeft > 0) {
                            LOG.info("PIN not entered successful. There are {} tries left.", statusBytes[1] & 0x0F);
                            return verifyUser(verify);
                        }
                    }
                    return response;
                }
            } else {
                response = WSHelper.makeResponse(VerifyUserResponse.class, transResp.getResult());
                response.setResponse(transResp.getOutputAPDU().get(0));
                return response;
            }
        } else {
            IFDException ex = new IFDException("No input unit available to perform PinCompare protocol.");
            LOG.warn(ex.getMessage(), ex);
            throw ex;
        }
    } else {
        String msg = "Unsupported authentication input method requested.";
        IFDException ex = new IFDException(ECardConstants.Minor.IFD.IO.UNKNOWN_INPUT_UNIT, msg);
        LOG.warn(ex.getMessage(), ex);
        throw ex;
    }
}
Also used : Transmit(iso.std.iso_iec._24727.tech.schema.Transmit) PasswordAttributesType(iso.std.iso_iec._24727.tech.schema.PasswordAttributesType) ResultStatus(org.openecard.gui.ResultStatus) AltVUMessagesType(iso.std.iso_iec._24727.tech.schema.AltVUMessagesType) VerifyUserResponse(iso.std.iso_iec._24727.tech.schema.VerifyUserResponse) UtilException(org.openecard.common.util.UtilException) InputAPDUInfoType(iso.std.iso_iec._24727.tech.schema.InputAPDUInfoType) UserConsentNavigator(org.openecard.gui.UserConsentNavigator) Result(oasis.names.tc.dss._1_0.core.schema.Result) InputUnitType(iso.std.iso_iec._24727.tech.schema.InputUnitType) ExecutionEngine(org.openecard.gui.executor.ExecutionEngine) UserConsentDescription(org.openecard.gui.definition.UserConsentDescription) BigInteger(java.math.BigInteger) TransmitResponse(iso.std.iso_iec._24727.tech.schema.TransmitResponse) CardResponseAPDU(org.openecard.common.apdu.common.CardResponseAPDU) PinInputType(iso.std.iso_iec._24727.tech.schema.PinInputType)

Example 2 with PasswordAttributesType

use of iso.std.iso_iec._24727.tech.schema.PasswordAttributesType 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 3 with PasswordAttributesType

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

the class PINTest method testISO.

@Test
public void testISO() throws UtilException {
    PasswordAttributesType pwdAttr = create(true, ISO_9564_1, 4, 8, 12);
    byte[] pinMask = PINUtils.createPinMask(pwdAttr);
    assertEquals(new byte[] { 0x20, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF }, pinMask);
    byte[] pinResult = PINUtils.encodePin("123456789".toCharArray(), pwdAttr);
    assertEquals(new byte[] { 0x29, 0x12, 0x34, 0x56, 0x78, (byte) 0x9F, (byte) 0xFF, (byte) 0xFF }, pinResult);
}
Also used : PasswordAttributesType(iso.std.iso_iec._24727.tech.schema.PasswordAttributesType) Test(org.testng.annotations.Test)

Example 4 with PasswordAttributesType

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

the class PINTest method testBCD.

@Test
public void testBCD() throws UtilException {
    PasswordAttributesType pwdAttr = create(true, BCD, 4, 3, 6);
    pwdAttr.setPadChar(new byte[] { (byte) 0xFF });
    byte[] pinMask = PINUtils.createPinMask(pwdAttr);
    assertEquals(new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF }, pinMask);
    byte[] pinResult = PINUtils.encodePin("12345".toCharArray(), pwdAttr);
    assertEquals(new byte[] { (byte) 0x12, (byte) 0x34, (byte) 0x5F }, pinResult);
}
Also used : PasswordAttributesType(iso.std.iso_iec._24727.tech.schema.PasswordAttributesType) Test(org.testng.annotations.Test)

Example 5 with PasswordAttributesType

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

the class CIFCreator method createPinDID.

private DIDInfoType createPinDID() throws WSMarshallerException {
    LOG.debug("Creating PinCompare DID object.");
    DIDInfoType di = new DIDInfoType();
    // create differential identity
    DifferentialIdentityType did = new DifferentialIdentityType();
    di.setDifferentialIdentity(did);
    String didName = PIN_NAME;
    did.setDIDName(didName);
    did.setDIDProtocol("urn:oid:1.3.162.15480.3.0.9");
    did.setDIDScope(DIDScopeType.GLOBAL);
    // create pin compare marker
    PinMarkerBuilder markerBuilder = new PinMarkerBuilder();
    KeyRefType kr = new KeyRefType();
    // value is irrelevant
    kr.setKeyRef(new byte[] { 0x01 });
    markerBuilder.setPinRef(kr);
    try {
        PasswordAttributesType pw = new PasswordAttributesType();
        MwToken tok = session.getSlot().getTokenInfo();
        long minPinLen = tok.getUlMinPinLen();
        long maxPinLen = tok.getUlMinPinLen();
        pw.setMinLength(BigInteger.valueOf(minPinLen));
        pw.setMaxLength(BigInteger.valueOf(maxPinLen));
        markerBuilder.setPwAttributes(pw);
    } catch (CryptokiException | NullPointerException ex) {
        LOG.warn("Unable to read min and max PIN length from middleware.");
    }
    // wrap pin compare marker and add to parent
    PinCompareMarkerType marker = markerBuilder.build();
    DIDMarkerType markerWrapper = new DIDMarkerType();
    markerWrapper.setPinCompareMarker(marker);
    did.setDIDMarker(markerWrapper);
    // create acl
    AccessControlListType acl = new AccessControlListType();
    di.setDIDACL(acl);
    List<AccessRuleType> rules = acl.getAccessRule();
    rules.add(createRuleTrue(AuthorizationServiceActionName.ACL_LIST));
    rules.add(createRuleTrue(DifferentialIdentityServiceActionName.DID_LIST));
    rules.add(createRuleTrue(DifferentialIdentityServiceActionName.DID_GET));
    rules.add(createRuleTrue(DifferentialIdentityServiceActionName.DID_AUTHENTICATE));
    return di;
}
Also used : KeyRefType(iso.std.iso_iec._24727.tech.schema.KeyRefType) PasswordAttributesType(iso.std.iso_iec._24727.tech.schema.PasswordAttributesType) AccessControlListType(iso.std.iso_iec._24727.tech.schema.AccessControlListType) PinMarkerBuilder(org.openecard.mdlw.sal.didfactory.PinMarkerBuilder) DIDMarkerType(iso.std.iso_iec._24727.tech.schema.DIDMarkerType) DifferentialIdentityType(iso.std.iso_iec._24727.tech.schema.DifferentialIdentityType) PinCompareMarkerType(iso.std.iso_iec._24727.tech.schema.PinCompareMarkerType) DIDInfoType(iso.std.iso_iec._24727.tech.schema.DIDInfoType) CryptokiException(org.openecard.mdlw.sal.exceptions.CryptokiException) AccessRuleType(iso.std.iso_iec._24727.tech.schema.AccessRuleType)

Aggregations

PasswordAttributesType (iso.std.iso_iec._24727.tech.schema.PasswordAttributesType)17 Test (org.testng.annotations.Test)7 ControlIFD (iso.std.iso_iec._24727.tech.schema.ControlIFD)3 InputAPDUInfoType (iso.std.iso_iec._24727.tech.schema.InputAPDUInfoType)3 Transmit (iso.std.iso_iec._24727.tech.schema.Transmit)3 ControlIFDResponse (iso.std.iso_iec._24727.tech.schema.ControlIFDResponse)2 InputUnitType (iso.std.iso_iec._24727.tech.schema.InputUnitType)2 KeyRefType (iso.std.iso_iec._24727.tech.schema.KeyRefType)2 PasswordTypeType (iso.std.iso_iec._24727.tech.schema.PasswordTypeType)2 PinCompareMarkerType (iso.std.iso_iec._24727.tech.schema.PinCompareMarkerType)2 PinInputType (iso.std.iso_iec._24727.tech.schema.PinInputType)2 TransmitResponse (iso.std.iso_iec._24727.tech.schema.TransmitResponse)2 VerifyUserResponse (iso.std.iso_iec._24727.tech.schema.VerifyUserResponse)2 BigInteger (java.math.BigInteger)2 CardResponseAPDU (org.openecard.common.apdu.common.CardResponseAPDU)2 PCSCPinModify (org.openecard.ifd.scio.reader.PCSCPinModify)2 PCSCPinVerify (org.openecard.ifd.scio.reader.PCSCPinVerify)2 AccessControlListType (iso.std.iso_iec._24727.tech.schema.AccessControlListType)1 AccessRuleType (iso.std.iso_iec._24727.tech.schema.AccessRuleType)1 AltVUMessagesType (iso.std.iso_iec._24727.tech.schema.AltVUMessagesType)1