Search in sources :

Example 1 with APDUException

use of org.openecard.common.apdu.exception.APDUException in project open-ecard by ecsec.

the class PACEImplementation method mseSetAT.

/**
 * Initialize Chip Authentication. Sends an MSE:Set AT APDU. (S
 * Step 1: Initialise PACE.
 * See BSI-TR-03110, version 2.10, part 3, B.11.1.
 */
private void mseSetAT(byte passwordID, byte[] chat) throws Exception {
    byte[] oID = ObjectIdentifierUtils.getValue(psip.getPACEInfo().getProtocol());
    CardCommandAPDU mseSetAT = new MSESetATPACE(oID, passwordID, psip.getPACEInfo().getParameterID(), chat);
    try {
        response = mseSetAT.transmit(dispatcher, slotHandle);
        // Continue with step 2
        generalAuthenticateEncryptedNonce();
    } catch (APDUException e) {
        if (e.getResponseAPDU() == null) {
            if (e.getCause() instanceof Exception) {
                throw (Exception) e.getCause();
            } else {
                throw new ProtocolException(ECardConstants.Minor.IFD.UNKNOWN_ERROR, e.getMessage());
            }
        }
        LOG.error(e.getMessage(), e);
        short sw = e.getResponseAPDU().getSW();
        if (sw == PACEConstants.PASSWORD_DEACTIVATED) {
            // Password is deactivated
            throw new ProtocolException(ECardConstants.Minor.IFD.PASSWORD_DEACTIVATED);
        } else if ((sw & (short) 0xFFF0) == (short) 0x63C0) {
            retryCounter = (byte) (sw & (short) 0x000F);
            if (retryCounter == (byte) 0x00) {
                // The password is blocked
                LOG.warn("The password is blocked. The password MUST be unblocked.");
                if (passwordID == PACEConstants.PASSWORD_PUK) {
                    generalAuthenticateEncryptedNonce();
                } else {
                    throw new ProtocolException(ECardConstants.Minor.IFD.PASSWORD_BLOCKED, "The password is blocked. The password MUST be unblocked.");
                }
            } else if (retryCounter == (byte) 0x01) {
                // The password is suspended
                LOG.warn("The password is suspended. The password MUST be resumed.");
                // TODO check for an existing SM-Channel with the CAN
                // if (mseSetAT.isSecureMessaging()) {
                generalAuthenticateEncryptedNonce();
            /*} else {
			throw new ProtocolException(
				ECardConstants.Minor.IFD.PASSWORD_SUSPENDED,
				"The password is suspended. The password MUST be resumed.");
		    }*/
            } else if (retryCounter == (byte) 0x02) {
                // The password is suspended
                LOG.warn("The password is wrong.");
                generalAuthenticateEncryptedNonce();
            }
        }
    } catch (ProtocolException e) {
        LOG.error(e.getMessage(), e);
        throw e;
    } catch (Exception e) {
        LOG.error(e.getMessage(), e);
        throw new ProtocolException(ECardConstants.Minor.IFD.UNKNOWN_ERROR, e.getMessage());
    }
}
Also used : CardCommandAPDU(org.openecard.common.apdu.common.CardCommandAPDU) MSESetATPACE(org.openecard.ifd.protocol.pace.apdu.MSESetATPACE) ProtocolException(org.openecard.common.ifd.protocol.exception.ProtocolException) APDUException(org.openecard.common.apdu.exception.APDUException) APDUException(org.openecard.common.apdu.exception.APDUException) GeneralSecurityException(java.security.GeneralSecurityException) ProtocolException(org.openecard.common.ifd.protocol.exception.ProtocolException)

Example 2 with APDUException

use of org.openecard.common.apdu.exception.APDUException in project open-ecard by ecsec.

the class PACEImplementation method generalAuthenticateMutualAuthentication.

/**
 * Step 5: Mutual authentication
 */
private void generalAuthenticateMutualAuthentication() throws Exception {
    // Calculate shared key k
    byte[] k = cryptoSuite.generateSharedSecret(keyPCD.getEncodedPrivateKey(), keyPICC.getEncodedPublicKey());
    // Derive key MAC
    keyMAC = kdf.deriveMAC(k);
    // Derive key ENC
    keyENC = kdf.deriveENC(k);
    // Calculate token T_PCD
    AuthenticationToken tokenPCD = new AuthenticationToken(psip.getPACEInfo());
    tokenPCD.generateToken(keyMAC, keyPICC.getEncodedPublicKey());
    CardCommandAPDU gaMutualAuth = new GeneralAuthenticate((byte) 0x85, tokenPCD.toByteArray());
    // Calculate token T_PICC
    AuthenticationToken tokenPICC = new AuthenticationToken(psip.getPACEInfo());
    tokenPICC.generateToken(keyMAC, keyPCD.getEncodedPublicKey());
    try {
        response = gaMutualAuth.transmit(dispatcher, slotHandle);
        if (tokenPICC.verifyToken(response.getData(), specifiedCHAT)) {
            currentCAR = tokenPICC.getCurrentCAR();
            previousCAR = tokenPICC.getPreviousCAR();
        } else {
            throw new GeneralSecurityException("Cannot verify authentication token.");
        }
    } catch (APDUException e) {
        if (e.getResponseAPDU() == null) {
            if (e.getCause() instanceof Exception) {
                throw (Exception) e.getCause();
            } else {
                throw new ProtocolException(ECardConstants.Minor.IFD.UNKNOWN_ERROR, e.getMessage());
            }
        }
        LOG.error(e.getMessage(), e);
        int sw = e.getResponseAPDU().getSW();
        if ((sw & (short) 0xFFF0) == (short) 0x63C0) {
            retryCounter = (byte) (sw & (short) 0x000F);
            if (retryCounter == (byte) 0x00) {
                // The password is blocked.
                LOG.warn("The password is blocked. The password MUST be unblocked.");
                throw new ProtocolException(ECardConstants.Minor.IFD.PASSWORD_BLOCKED, "The password is blocked. The password MUST be unblocked.");
            } else if (retryCounter == (byte) 0x01) {
                // The password is suspended.
                LOG.warn("The password is suspended. The password MUST be resumed.");
                throw new ProtocolException(ECardConstants.Minor.IFD.PASSWORD_SUSPENDED, "The password is suspended. The password MUST be resumed.");
            } else if (retryCounter == (byte) 0x02) {
                // The password is wrong.
                LOG.warn("The password is wrong.");
                throw new ProtocolException(ECardConstants.Minor.IFD.PASSWORD_ERROR, "The password is wrong.");
            }
        } else {
            throw new ProtocolException(ECardConstants.Minor.IFD.AUTHENTICATION_FAILED, "Authentication failed.");
        }
    } catch (Exception e) {
        LOG.error(e.getMessage(), e);
        throw new ProtocolException(ECardConstants.Minor.IFD.UNKNOWN_ERROR, e.getMessage());
    }
}
Also used : CardCommandAPDU(org.openecard.common.apdu.common.CardCommandAPDU) ProtocolException(org.openecard.common.ifd.protocol.exception.ProtocolException) AuthenticationToken(org.openecard.ifd.protocol.pace.crypto.AuthenticationToken) APDUException(org.openecard.common.apdu.exception.APDUException) GeneralSecurityException(java.security.GeneralSecurityException) GeneralAuthenticate(org.openecard.common.apdu.GeneralAuthenticate) APDUException(org.openecard.common.apdu.exception.APDUException) GeneralSecurityException(java.security.GeneralSecurityException) ProtocolException(org.openecard.common.ifd.protocol.exception.ProtocolException)

Example 3 with APDUException

use of org.openecard.common.apdu.exception.APDUException in project open-ecard by ecsec.

the class TerminalAuthentication method mseSetAT.

/**
 * Initializes the Terminal Authentication protocol.
 * Sends an MSE:Set AT APDU. (Protocol step 2)
 * See BSI-TR-03110, version 2.10, part 3, B.11.1.
 *
 * @param oID Terminal Authentication object identifier
 * @param chr Certificate Holder Reference (CHR)
 * @param key Ephemeral public key
 * @param aad Authenticated Auxiliary Data (AAD)
 * @throws ProtocolException
 */
public void mseSetAT(byte[] oID, byte[] chr, byte[] key, byte[] aad) throws ProtocolException {
    try {
        CardCommandAPDU mseSetAT = new MSESetATTA(oID, chr, key, aad);
        mseSetAT.transmit(dispatcher, slotHandle);
    } catch (APDUException e) {
        throw new ProtocolException(e.getResult());
    }
}
Also used : CardCommandAPDU(org.openecard.common.apdu.common.CardCommandAPDU) ProtocolException(org.openecard.common.sal.protocol.exception.ProtocolException) APDUException(org.openecard.common.apdu.exception.APDUException) MSESetATTA(org.openecard.sal.protocol.eac.apdu.MSESetATTA)

Example 4 with APDUException

use of org.openecard.common.apdu.exception.APDUException in project open-ecard by ecsec.

the class TerminalAuthentication method verifyCertificates.

/**
 * Verify certificates.
 * Sends an MSE:Set DST APDU and PSO:Verify Certificate APDU per certificate. (Protocol step 1)
 * See BSI-TR-03110, version 2.10, part 3, B.11.4.
 * See BSI-TR-03110, version 2.10, part 3, B.11.5.
 *
 * @param certificateChain Certificate chain
 * @throws ProtocolException
 */
public void verifyCertificates(CardVerifiableCertificateChain certificateChain) throws ProtocolException {
    try {
        for (CardVerifiableCertificate cvc : certificateChain.getCertificates()) {
            // MSE:SetDST APDU
            CardCommandAPDU mseSetDST = new MSESetDST(cvc.getCAR().toByteArray());
            mseSetDST.transmit(dispatcher, slotHandle);
            // PSO:Verify Certificate  APDU
            CardCommandAPDU psovc = new PSOVerifyCertificate(cvc.getCertificate().getValue());
            psovc.transmit(dispatcher, slotHandle);
        }
    } catch (APDUException e) {
        throw new ProtocolException(e.getResult());
    }
}
Also used : CardCommandAPDU(org.openecard.common.apdu.common.CardCommandAPDU) ProtocolException(org.openecard.common.sal.protocol.exception.ProtocolException) APDUException(org.openecard.common.apdu.exception.APDUException) CardVerifiableCertificate(org.openecard.crypto.common.asn1.cvc.CardVerifiableCertificate) PSOVerifyCertificate(org.openecard.sal.protocol.eac.apdu.PSOVerifyCertificate) MSESetDST(org.openecard.sal.protocol.eac.apdu.MSESetDST)

Example 5 with APDUException

use of org.openecard.common.apdu.exception.APDUException 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)

Aggregations

APDUException (org.openecard.common.apdu.exception.APDUException)18 CardCommandAPDU (org.openecard.common.apdu.common.CardCommandAPDU)12 ProtocolException (org.openecard.common.sal.protocol.exception.ProtocolException)7 CardResponseAPDU (org.openecard.common.apdu.common.CardResponseAPDU)6 GeneralSecurityException (java.security.GeneralSecurityException)5 GeneralAuthenticate (org.openecard.common.apdu.GeneralAuthenticate)5 ProtocolException (org.openecard.common.ifd.protocol.exception.ProtocolException)5 EstablishChannelResponse (iso.std.iso_iec._24727.tech.schema.EstablishChannelResponse)3 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)3 StepActionResult (org.openecard.gui.executor.StepActionResult)3 CardApplicationDisconnect (iso.std.iso_iec._24727.tech.schema.CardApplicationDisconnect)2 DestroyChannel (iso.std.iso_iec._24727.tech.schema.DestroyChannel)2 Disconnect (iso.std.iso_iec._24727.tech.schema.Disconnect)2 IOException (java.io.IOException)2 WSHelper (org.openecard.common.WSHelper)2 WSException (org.openecard.common.WSHelper.WSException)2 ExecutionResults (org.openecard.gui.executor.ExecutionResults)2 PACEKey (org.openecard.ifd.protocol.pace.crypto.PACEKey)2 IFDException (org.openecard.ifd.scio.IFDException)2 ControlIFDResponse (iso.std.iso_iec._24727.tech.schema.ControlIFDResponse)1