Search in sources :

Example 1 with UtilException

use of org.openecard.common.util.UtilException 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 UtilException

use of org.openecard.common.util.UtilException in project open-ecard by ecsec.

the class PCSCPinVerify method prepareStructure.

private void prepareStructure(PasswordAttributesType attributes, byte[] cmdTemplate) throws IFDException {
    // get apdu and pin template
    byte[] pinTemplate;
    try {
        pinTemplate = PINUtils.createPinMask(attributes);
    } catch (UtilException e) {
        IFDException ex = new IFDException(e);
        throw ex;
    }
    byte[] template = cmdTemplate;
    if (pinTemplate.length > 0) {
        template = ByteUtils.concatenate(cmdTemplate, (byte) pinTemplate.length);
        template = ByteUtils.concatenate(template, pinTemplate);
    }
    setData(template);
    boolean nibbleHandling = pwdType == PasswordTypeType.BCD || pwdType == PasswordTypeType.ISO_9564_1;
    boolean isoPin = pwdType == PasswordTypeType.ISO_9564_1;
    // pointer to byte containing pin length in iso encoding
    int pinLenIdx = template.length;
    int pinPos = isoPin ? pinLenIdx + 1 : pinLenIdx;
    // prepare bmFormatString
    // bytes
    byte bmSysUnits = 1;
    byte bmPinPos = (byte) (isoPin ? 1 : 0);
    // left
    byte bmJustify = 0;
    // binary
    byte bmPinType = 0;
    if (nibbleHandling) {
        bmPinType = 1;
    } else if (pwdType == PasswordTypeType.ASCII_NUMERIC || pwdType == PasswordTypeType.UTF_8) {
        bmPinType = 2;
    }
    this.bmFormatString = (byte) ((bmSysUnits << 7) | (bmPinPos << 3) | (bmJustify << 2) | bmPinType);
    // prepare pin block string
    // number of bits of the length field
    byte bmPinManagement = (byte) (isoPin ? 4 : 0);
    byte pinSize = (byte) (isoPin ? storedLen - 1 : storedLen);
    this.bmPINBlockString = (byte) ((bmPinManagement << 4) | pinSize);
    // pin length format
    // bits
    byte bmPinLengthUnit = 0;
    byte bmPinBytePos = (byte) (isoPin ? 4 : 0);
    bmPINLengthFormat = (byte) ((bmPinLengthUnit << 4) | bmPinBytePos);
    setMinPINSize((byte) minLen);
    setMaxPINSize((byte) maxLen);
}
Also used : UtilException(org.openecard.common.util.UtilException) IFDException(org.openecard.ifd.scio.IFDException)

Example 3 with UtilException

use of org.openecard.common.util.UtilException in project open-ecard by ecsec.

the class PINTest method testASCII.

@Test
public void testASCII() throws UtilException {
    PasswordAttributesType pwdAttr = create(false, ASCII_NUMERIC, 6, 6);
    byte[] pinResult = PINUtils.encodePin("123456".toCharArray(), pwdAttr);
    assertEquals(new byte[] { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 }, pinResult);
    try {
        pwdAttr = create(true, ASCII_NUMERIC, 6, 6);
        PINUtils.encodePin("123456".toCharArray(), pwdAttr);
        // padding needed, but no char given
        fail();
    } catch (UtilException ex) {
    }
// try {
// pwdAttr = create(false, ASCII_NUMERIC, 6, 7);
// PINUtils.encodePin("123456", pwdAttr);
// fail(); // padding inferred, but no char given
// } catch (UtilException ex) {
// }
}
Also used : PasswordAttributesType(iso.std.iso_iec._24727.tech.schema.PasswordAttributesType) UtilException(org.openecard.common.util.UtilException) Test(org.testng.annotations.Test)

Example 4 with UtilException

use of org.openecard.common.util.UtilException in project open-ecard by ecsec.

the class PCSCPinModify method prepareStructure.

private void prepareStructure(PasswordAttributesType attributes, byte[] cmdTemplate) throws IFDException {
    // get apdu and pin template
    byte[] pinTemplate;
    try {
        pinTemplate = PINUtils.createPinMask(attributes);
    } catch (UtilException e) {
        IFDException ex = new IFDException(e);
        throw ex;
    }
    byte[] template = cmdTemplate;
    if (pinTemplate.length > 0) {
        template = ByteUtils.concatenate(cmdTemplate, (byte) pinTemplate.length);
        template = ByteUtils.concatenate(template, pinTemplate);
    }
    setData(template);
    boolean nibbleHandling = pwdType == PasswordTypeType.BCD || pwdType == PasswordTypeType.ISO_9564_1;
    boolean isoPin = pwdType == PasswordTypeType.ISO_9564_1;
    // pointer to byte containing pin length in iso encoding
    int pinLenIdx = template.length;
    int pinPos = isoPin ? pinLenIdx + 1 : pinLenIdx;
    // prepare bmFormatString
    // bytes
    byte bmSysUnits = 1;
    byte bmPinPos = (byte) (isoPin ? 1 : 0);
    // left
    byte bmJustify = 0;
    // binary
    byte bmPinType = 0;
    if (nibbleHandling) {
        bmPinType = 1;
    } else if (pwdType == PasswordTypeType.ASCII_NUMERIC) {
        bmPinType = 2;
    }
    this.bmFormatString = (byte) ((bmSysUnits << 7) | (bmPinPos << 3) | (bmJustify << 2) | bmPinType);
    // prepare pin block string
    // number of bits of the length field
    byte bmPinManagement = (byte) (isoPin ? 4 : 0);
    byte pinSize = (byte) (isoPin ? storedLen - 1 : storedLen);
    this.bmPINBlockString = (byte) ((bmPinManagement << 4) | pinSize);
    // pin length format
    // bits
    byte bmPinLengthUnit = 0;
    byte bmPinBytePos = (byte) (isoPin ? 4 : 0);
    bmPINLengthFormat = (byte) ((bmPinLengthUnit << 4) | bmPinBytePos);
    setMinPINSize((byte) minLen);
    setMaxPINSize((byte) maxLen);
}
Also used : UtilException(org.openecard.common.util.UtilException) IFDException(org.openecard.ifd.scio.IFDException)

Aggregations

UtilException (org.openecard.common.util.UtilException)4 PasswordAttributesType (iso.std.iso_iec._24727.tech.schema.PasswordAttributesType)2 IFDException (org.openecard.ifd.scio.IFDException)2 AltVUMessagesType (iso.std.iso_iec._24727.tech.schema.AltVUMessagesType)1 InputAPDUInfoType (iso.std.iso_iec._24727.tech.schema.InputAPDUInfoType)1 InputUnitType (iso.std.iso_iec._24727.tech.schema.InputUnitType)1 PinInputType (iso.std.iso_iec._24727.tech.schema.PinInputType)1 Transmit (iso.std.iso_iec._24727.tech.schema.Transmit)1 TransmitResponse (iso.std.iso_iec._24727.tech.schema.TransmitResponse)1 VerifyUserResponse (iso.std.iso_iec._24727.tech.schema.VerifyUserResponse)1 BigInteger (java.math.BigInteger)1 Result (oasis.names.tc.dss._1_0.core.schema.Result)1 CardResponseAPDU (org.openecard.common.apdu.common.CardResponseAPDU)1 ResultStatus (org.openecard.gui.ResultStatus)1 UserConsentNavigator (org.openecard.gui.UserConsentNavigator)1 UserConsentDescription (org.openecard.gui.definition.UserConsentDescription)1 ExecutionEngine (org.openecard.gui.executor.ExecutionEngine)1 Test (org.testng.annotations.Test)1