Search in sources :

Example 1 with CardCommandAPDU

use of org.openecard.common.apdu.common.CardCommandAPDU 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 CardCommandAPDU

use of org.openecard.common.apdu.common.CardCommandAPDU 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 CardCommandAPDU

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

the class TinySAL method cardApplicationConnect.

/**
 * The CardApplicationConnect function establishes an unauthenticated connection between the client
 * application and the card application.
 * See BSI-TR-03112-4, version 1.1.2, section 3.2.1.
 *
 * @param request CardApplicationConnect
 * @return CardApplicationConnectResponse
 */
@Override
public CardApplicationConnectResponse cardApplicationConnect(CardApplicationConnect request) {
    CardApplicationConnectResponse response = WSHelper.makeResponse(CardApplicationConnectResponse.class, WSHelper.makeResultOK());
    try {
        CardApplicationPathType cardAppPath = request.getCardApplicationPath();
        Assert.assertIncorrectParameter(cardAppPath, "The parameter CardAppPathRequest is empty.");
        Set<CardStateEntry> cardStateEntrySet = states.getMatchingEntries(cardAppPath, false);
        Assert.assertIncorrectParameter(cardStateEntrySet, "The given ConnectionHandle is invalid.");
        /*
	     * [TR-03112-4] If the provided path fragments are valid for more than one card application
	     * the eCard-API-Framework SHALL return any of the possible choices.
	     */
        CardStateEntry cardStateEntry = cardStateEntrySet.iterator().next();
        byte[] applicationID = cardAppPath.getCardApplication();
        if (applicationID == null) {
            if (cardStateEntry.getImplicitlySelectedApplicationIdentifier() != null) {
                applicationID = cardStateEntry.getImplicitlySelectedApplicationIdentifier();
            } else {
                applicationID = MF;
            }
        }
        Assert.securityConditionApplication(cardStateEntry, applicationID, ConnectionServiceActionName.CARD_APPLICATION_CONNECT);
        // Connect to the card
        ConnectionHandleType handle = cardStateEntry.handleCopy();
        cardStateEntry = cardStateEntry.derive(handle);
        Connect connect = new Connect();
        connect.setContextHandle(handle.getContextHandle());
        connect.setIFDName(handle.getIFDName());
        connect.setSlot(handle.getSlotIndex());
        ConnectResponse connectResponse = (ConnectResponse) env.getDispatcher().safeDeliver(connect);
        WSHelper.checkResult(connectResponse);
        // Select the card application
        CardCommandAPDU select;
        // TODO: proper determination of path, file and app id
        if (applicationID.length == 2) {
            select = new Select.File(applicationID);
            List<byte[]> responses = new ArrayList<>();
            responses.add(TrailerConstants.Success.OK());
            responses.add(TrailerConstants.Error.WRONG_P1_P2());
            CardResponseAPDU resp = select.transmit(env.getDispatcher(), connectResponse.getSlotHandle(), responses);
            if (Arrays.equals(resp.getTrailer(), TrailerConstants.Error.WRONG_P1_P2())) {
                select = new Select.AbsolutePath(applicationID);
                select.transmit(env.getDispatcher(), connectResponse.getSlotHandle());
            }
        } else {
            select = new Select.Application(applicationID);
            select.transmit(env.getDispatcher(), connectResponse.getSlotHandle());
        }
        cardStateEntry.setCurrentCardApplication(applicationID);
        cardStateEntry.setSlotHandle(connectResponse.getSlotHandle());
        // reset the ef FCP
        cardStateEntry.unsetFCPOfSelectedEF();
        states.addEntry(cardStateEntry);
        response.setConnectionHandle(cardStateEntry.handleCopy());
        response.getConnectionHandle().setCardApplication(applicationID);
    } catch (ECardException e) {
        response.setResult(e.getResult());
    }
    return response;
}
Also used : ConnectionHandleType(iso.std.iso_iec._24727.tech.schema.ConnectionHandleType) CardCommandAPDU(org.openecard.common.apdu.common.CardCommandAPDU) CardStateEntry(org.openecard.common.sal.state.CardStateEntry) ConnectResponse(iso.std.iso_iec._24727.tech.schema.ConnectResponse) CardApplicationConnectResponse(iso.std.iso_iec._24727.tech.schema.CardApplicationConnectResponse) CardApplicationConnect(iso.std.iso_iec._24727.tech.schema.CardApplicationConnect) Connect(iso.std.iso_iec._24727.tech.schema.Connect) ArrayList(java.util.ArrayList) CardApplicationConnectResponse(iso.std.iso_iec._24727.tech.schema.CardApplicationConnectResponse) CardApplicationPathType(iso.std.iso_iec._24727.tech.schema.CardApplicationPathType) ECardException(org.openecard.common.ECardException) Select(org.openecard.common.apdu.Select) CardApplicationSelect(iso.std.iso_iec._24727.tech.schema.CardApplicationSelect) DataSetSelect(iso.std.iso_iec._24727.tech.schema.DataSetSelect) CardResponseAPDU(org.openecard.common.apdu.common.CardResponseAPDU)

Example 4 with CardCommandAPDU

use of org.openecard.common.apdu.common.CardCommandAPDU 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 5 with CardCommandAPDU

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

Aggregations

CardCommandAPDU (org.openecard.common.apdu.common.CardCommandAPDU)19 APDUException (org.openecard.common.apdu.exception.APDUException)12 CardResponseAPDU (org.openecard.common.apdu.common.CardResponseAPDU)8 ProtocolException (org.openecard.common.sal.protocol.exception.ProtocolException)6 GeneralSecurityException (java.security.GeneralSecurityException)5 GeneralAuthenticate (org.openecard.common.apdu.GeneralAuthenticate)5 ProtocolException (org.openecard.common.ifd.protocol.exception.ProtocolException)5 ConnectionHandleType (iso.std.iso_iec._24727.tech.schema.ConnectionHandleType)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 ECardException (org.openecard.common.ECardException)3 CardStateEntry (org.openecard.common.sal.state.CardStateEntry)3 TLV (org.openecard.common.tlv.TLV)3 CardApplicationSelect (iso.std.iso_iec._24727.tech.schema.CardApplicationSelect)2 DataSetSelect (iso.std.iso_iec._24727.tech.schema.DataSetSelect)2 SignResponse (iso.std.iso_iec._24727.tech.schema.SignResponse)2 ArrayList (java.util.ArrayList)2 ManageSecurityEnvironment (org.openecard.common.apdu.ManageSecurityEnvironment)2 Select (org.openecard.common.apdu.Select)2 PACEKey (org.openecard.ifd.protocol.pace.crypto.PACEKey)2 CardApplicationConnect (iso.std.iso_iec._24727.tech.schema.CardApplicationConnect)1