Search in sources :

Example 1 with InputUnitType

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

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

the class DIDAuthenticateStep method perform.

@Override
public DIDAuthenticateResponse perform(DIDAuthenticate request, Map<String, Object> internalData) {
    DIDAuthenticateResponse response = WSHelper.makeResponse(DIDAuthenticateResponse.class, WSHelper.makeResultOK());
    char[] rawPIN = null;
    try {
        ConnectionHandleType connectionHandle = SALUtils.getConnectionHandle(request);
        String didName = SALUtils.getDIDName(request);
        CardStateEntry cardStateEntry = SALUtils.getCardStateEntry(internalData, connectionHandle);
        PINCompareDIDAuthenticateInputType pinCompareInput = new PINCompareDIDAuthenticateInputType(request.getAuthenticationProtocolData());
        PINCompareDIDAuthenticateOutputType pinCompareOutput = pinCompareInput.getOutputType();
        byte[] cardApplication;
        if (request.getDIDScope() != null && request.getDIDScope().equals(DIDScopeType.GLOBAL)) {
            cardApplication = cardStateEntry.getInfo().getApplicationIdByDidName(request.getDIDName(), request.getDIDScope());
        } else {
            cardApplication = connectionHandle.getCardApplication();
        }
        Assert.securityConditionDID(cardStateEntry, cardApplication, didName, DifferentialIdentityServiceActionName.DID_AUTHENTICATE);
        DIDStructureType didStructure = cardStateEntry.getDIDStructure(didName, cardApplication);
        PINCompareMarkerType pinCompareMarker = new PINCompareMarkerType(didStructure.getDIDMarker());
        byte keyRef = pinCompareMarker.getPINRef().getKeyRef()[0];
        byte[] slotHandle = connectionHandle.getSlotHandle();
        PasswordAttributesType attributes = pinCompareMarker.getPasswordAttributes();
        rawPIN = pinCompareInput.getPIN();
        // delete pin from memory of the structure
        pinCompareInput.setPIN(null);
        byte[] template = new byte[] { 0x00, 0x20, 0x00, keyRef };
        byte[] responseCode;
        // with [ISO7816-4] (Section 7.5.6).
        if (rawPIN == null || rawPIN.length == 0) {
            VerifyUser verify = new VerifyUser();
            verify.setSlotHandle(slotHandle);
            InputUnitType inputUnit = new InputUnitType();
            verify.setInputUnit(inputUnit);
            PinInputType pinInput = new PinInputType();
            inputUnit.setPinInput(pinInput);
            pinInput.setIndex(BigInteger.ZERO);
            pinInput.setPasswordAttributes(attributes);
            verify.setTemplate(template);
            VerifyUserResponse verifyR = (VerifyUserResponse) dispatcher.safeDeliver(verify);
            WSHelper.checkResult(verifyR);
            responseCode = verifyR.getResponse();
        } else {
            Transmit verifyTransmit = PINUtils.buildVerifyTransmit(rawPIN, attributes, template, slotHandle);
            try {
                TransmitResponse transResp = (TransmitResponse) dispatcher.safeDeliver(verifyTransmit);
                WSHelper.checkResult(transResp);
                responseCode = transResp.getOutputAPDU().get(0);
            } finally {
                // blank PIN APDU
                for (InputAPDUInfoType apdu : verifyTransmit.getInputAPDUInfo()) {
                    byte[] rawApdu = apdu.getInputAPDU();
                    if (rawApdu != null) {
                        java.util.Arrays.fill(rawApdu, (byte) 0);
                    }
                }
            }
        }
        CardResponseAPDU verifyResponseAPDU = new CardResponseAPDU(responseCode);
        if (verifyResponseAPDU.isWarningProcessed()) {
            pinCompareOutput.setRetryCounter(new BigInteger(Integer.toString((verifyResponseAPDU.getSW2() & 0x0F))));
        }
        cardStateEntry.addAuthenticated(didName, cardApplication);
        response.setAuthenticationProtocolData(pinCompareOutput.getAuthDataType());
    } catch (ECardException e) {
        LOG.error(e.getMessage(), e);
        response.setResult(e.getResult());
    } catch (Exception e) {
        if (e instanceof RuntimeException) {
            throw (RuntimeException) e;
        }
        LOG.error(e.getMessage(), e);
        response.setResult(WSHelper.makeResult(e));
    } finally {
        if (rawPIN != null) {
            Arrays.fill(rawPIN, ' ');
        }
    }
    return response;
}
Also used : ConnectionHandleType(iso.std.iso_iec._24727.tech.schema.ConnectionHandleType) CardStateEntry(org.openecard.common.sal.state.CardStateEntry) Transmit(iso.std.iso_iec._24727.tech.schema.Transmit) PasswordAttributesType(iso.std.iso_iec._24727.tech.schema.PasswordAttributesType) VerifyUserResponse(iso.std.iso_iec._24727.tech.schema.VerifyUserResponse) PINCompareMarkerType(org.openecard.common.anytype.pin.PINCompareMarkerType) InputAPDUInfoType(iso.std.iso_iec._24727.tech.schema.InputAPDUInfoType) PINCompareDIDAuthenticateInputType(org.openecard.common.anytype.pin.PINCompareDIDAuthenticateInputType) ECardException(org.openecard.common.ECardException) ECardException(org.openecard.common.ECardException) DIDAuthenticateResponse(iso.std.iso_iec._24727.tech.schema.DIDAuthenticateResponse) InputUnitType(iso.std.iso_iec._24727.tech.schema.InputUnitType) TransmitResponse(iso.std.iso_iec._24727.tech.schema.TransmitResponse) BigInteger(java.math.BigInteger) DIDStructureType(iso.std.iso_iec._24727.tech.schema.DIDStructureType) VerifyUser(iso.std.iso_iec._24727.tech.schema.VerifyUser) CardResponseAPDU(org.openecard.common.apdu.common.CardResponseAPDU) PINCompareDIDAuthenticateOutputType(org.openecard.common.anytype.pin.PINCompareDIDAuthenticateOutputType) PinInputType(iso.std.iso_iec._24727.tech.schema.PinInputType)

Example 3 with InputUnitType

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

the class PINTest method verifyeGK.

@Test(enabled = false)
public void verifyeGK() {
    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();
    VerifyUser verify = new VerifyUser();
    verify.setSlotHandle(slotHandle);
    InputUnitType inputUnit = new InputUnitType();
    verify.setInputUnit(inputUnit);
    PinInputType pinInput = new PinInputType();
    inputUnit.setPinInput(pinInput);
    pinInput.setIndex(BigInteger.ZERO);
    pinInput.setPasswordAttributes(create(true, ISO_9564_1, 6, 8, 8));
    verify.setTemplate(StringUtils.toByteArray("00 20 00 01", true));
    VerifyUserResponse verifyR = ifd.verifyUser(verify);
    byte[] responseCode = verifyR.getResponse();
}
Also used : SwingDialogWrapper(org.openecard.gui.swing.SwingDialogWrapper) ListIFDs(iso.std.iso_iec._24727.tech.schema.ListIFDs) InputUnitType(iso.std.iso_iec._24727.tech.schema.InputUnitType) ControlIFD(iso.std.iso_iec._24727.tech.schema.ControlIFD) VerifyUserResponse(iso.std.iso_iec._24727.tech.schema.VerifyUserResponse) Connect(iso.std.iso_iec._24727.tech.schema.Connect) SwingUserConsent(org.openecard.gui.swing.SwingUserConsent) VerifyUser(iso.std.iso_iec._24727.tech.schema.VerifyUser) EstablishContext(iso.std.iso_iec._24727.tech.schema.EstablishContext) PinInputType(iso.std.iso_iec._24727.tech.schema.PinInputType) Test(org.testng.annotations.Test)

Aggregations

InputUnitType (iso.std.iso_iec._24727.tech.schema.InputUnitType)3 PinInputType (iso.std.iso_iec._24727.tech.schema.PinInputType)3 VerifyUserResponse (iso.std.iso_iec._24727.tech.schema.VerifyUserResponse)3 InputAPDUInfoType (iso.std.iso_iec._24727.tech.schema.InputAPDUInfoType)2 PasswordAttributesType (iso.std.iso_iec._24727.tech.schema.PasswordAttributesType)2 Transmit (iso.std.iso_iec._24727.tech.schema.Transmit)2 TransmitResponse (iso.std.iso_iec._24727.tech.schema.TransmitResponse)2 VerifyUser (iso.std.iso_iec._24727.tech.schema.VerifyUser)2 BigInteger (java.math.BigInteger)2 CardResponseAPDU (org.openecard.common.apdu.common.CardResponseAPDU)2 AltVUMessagesType (iso.std.iso_iec._24727.tech.schema.AltVUMessagesType)1 Connect (iso.std.iso_iec._24727.tech.schema.Connect)1 ConnectionHandleType (iso.std.iso_iec._24727.tech.schema.ConnectionHandleType)1 ControlIFD (iso.std.iso_iec._24727.tech.schema.ControlIFD)1 DIDAuthenticateResponse (iso.std.iso_iec._24727.tech.schema.DIDAuthenticateResponse)1 DIDStructureType (iso.std.iso_iec._24727.tech.schema.DIDStructureType)1 EstablishContext (iso.std.iso_iec._24727.tech.schema.EstablishContext)1 ListIFDs (iso.std.iso_iec._24727.tech.schema.ListIFDs)1 Result (oasis.names.tc.dss._1_0.core.schema.Result)1 ECardException (org.openecard.common.ECardException)1