Search in sources :

Example 16 with CardCommandAPDU

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

the class SecureMessaging method encrypt.

/**
 * Encrypt the APDU.
 *
 * @param apdu APDU
 * @param secureMessagingSSC Secure Messaging Send Sequence Counter
 * @return Encrypted APDU
 * @throws Exception
 */
private byte[] encrypt(byte[] apdu, byte[] secureMessagingSSC) throws Exception {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    CardCommandAPDU cAPDU = new CardCommandAPDU(apdu);
    if (cAPDU.isSecureMessaging()) {
        throw new IllegalArgumentException("Malformed APDU.");
    }
    byte[] data = cAPDU.getData();
    byte[] header = cAPDU.getHeader();
    int lc = cAPDU.getLC();
    int le = cAPDU.getLE();
    if (data.length > 0) {
        data = pad(data, 16);
        // Encrypt data
        Cipher c = getCipher(secureMessagingSSC, Cipher.ENCRYPT_MODE);
        byte[] dataEncrypted = c.doFinal(data);
        // Add padding indicator 0x01
        dataEncrypted = ByteUtils.concatenate((byte) 0x01, dataEncrypted);
        TLV dataObject = new TLV();
        dataObject.setTagNumWithClass((byte) 0x87);
        dataObject.setValue(dataEncrypted);
        baos.write(dataObject.toBER());
    }
    // Write protected LE
    if (le >= 0) {
        TLV leObject = new TLV();
        leObject.setTagNumWithClass((byte) 0x97);
        if (le == 0x100) {
            leObject.setValue(NULL);
        } else if (le > 0x100) {
            leObject.setValue(new byte[] { (byte) ((le >> 8) & 0xFF), (byte) (le & 0xFF) });
        } else {
            leObject.setValue(new byte[] { (byte) le });
        }
        baos.write(leObject.toBER());
    }
    // Indicate Secure Messaging
    // note: must be done before mac calculation
    header[0] |= 0x0C;
    /*
	 * Calculate MAC
	 */
    byte[] mac = new byte[16];
    CMac cmac = getCMAC(secureMessagingSSC);
    byte[] paddedHeader = pad(header, 16);
    cmac.update(paddedHeader, 0, paddedHeader.length);
    if (baos.size() > 0) {
        byte[] paddedData = pad(baos.toByteArray(), 16);
        cmac.update(paddedData, 0, paddedData.length);
    }
    cmac.doFinal(mac, 0);
    mac = ByteUtils.copy(mac, 0, 8);
    // 
    // Build APDU
    TLV macStructure = new TLV();
    macStructure.setTagNumWithClass((byte) 0x8E);
    macStructure.setValue(mac);
    byte[] secureData = ByteUtils.concatenate(baos.toByteArray(), macStructure.toBER());
    CardCommandAPDU secureCommand = new CardCommandAPDU(header[0], header[1], header[2], header[3], secureData);
    // set LE explicitely to 0x00 or in case of extended length 0x00 0x00
    if ((lc > 0xFF) || (le > 0x100)) {
        secureCommand.setLE(65536);
    } else {
        secureCommand.setLE(256);
    }
    return secureCommand.toByteArray();
}
Also used : CardCommandAPDU(org.openecard.common.apdu.common.CardCommandAPDU) CMac(org.openecard.bouncycastle.crypto.macs.CMac) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Cipher(javax.crypto.Cipher) TLV(org.openecard.common.tlv.TLV)

Example 17 with CardCommandAPDU

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

the class DecipherStep method perform.

@Override
public DecipherResponse perform(Decipher request, Map<String, Object> internalData) {
    DecipherResponse response = WSHelper.makeResponse(DecipherResponse.class, WSHelper.makeResultOK());
    try {
        ConnectionHandleType connectionHandle = SALUtils.getConnectionHandle(request);
        String didName = SALUtils.getDIDName(request);
        byte[] applicationID = connectionHandle.getCardApplication();
        CardStateEntry cardStateEntry = SALUtils.getCardStateEntry(internalData, connectionHandle);
        Assert.securityConditionDID(cardStateEntry, applicationID, didName, CryptographicServiceActionName.DECIPHER);
        DIDStructureType didStructure = SALUtils.getDIDStructure(request, didName, cardStateEntry, connectionHandle);
        CryptoMarkerType cryptoMarker = new CryptoMarkerType(didStructure.getDIDMarker());
        byte[] keyReference = cryptoMarker.getCryptoKeyInfo().getKeyRef().getKeyRef();
        byte[] algorithmIdentifier = cryptoMarker.getAlgorithmInfo().getCardAlgRef();
        byte[] slotHandle = connectionHandle.getSlotHandle();
        // See eGK specification, part 1, version 2.2.0, section 15.9.6.
        if (didStructure.getDIDScope().equals(DIDScopeType.LOCAL)) {
            keyReference[0] = (byte) (0x80 | keyReference[0]);
        }
        TLV tagKeyReference = new TLV();
        tagKeyReference.setTagNumWithClass(0x84);
        tagKeyReference.setValue(keyReference);
        TLV tagAlgorithmIdentifier = new TLV();
        tagAlgorithmIdentifier.setTagNumWithClass(0x80);
        tagAlgorithmIdentifier.setValue(algorithmIdentifier);
        byte[] mseData = ByteUtils.concatenate(tagKeyReference.toBER(), tagAlgorithmIdentifier.toBER());
        CardCommandAPDU apdu = new ManageSecurityEnvironment((byte) 0x41, ManageSecurityEnvironment.CT, mseData);
        apdu.transmit(dispatcher, slotHandle);
        byte[] ciphertext = request.getCipherText();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BigInteger bitKeySize = cryptoMarker.getCryptoKeyInfo().getKeySize();
        int blocksize = bitKeySize.divide(new BigInteger("8")).intValue();
        // check if the ciphertext length is divisible by the blocksize without rest
        if ((ciphertext.length % blocksize) != 0) {
            return WSHelper.makeResponse(DecipherResponse.class, WSHelper.makeResultError(ECardConstants.Minor.App.INCORRECT_PARM, "The length of the ciphertext should be a multiple of the blocksize."));
        }
        // decrypt the ciphertext block for block
        for (int offset = 0; offset < ciphertext.length; offset += blocksize) {
            byte[] ciphertextblock = ByteUtils.copy(ciphertext, offset, blocksize);
            apdu = new PSODecipher(ByteUtils.concatenate(PADDING_INDICATOR_BYTE, ciphertextblock), (byte) blocksize);
            CardResponseAPDU responseAPDU = apdu.transmit(dispatcher, slotHandle);
            baos.write(responseAPDU.getData());
        }
        response.setPlainText(baos.toByteArray());
    } catch (ECardException e) {
        response.setResult(e.getResult());
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
        response.setResult(WSHelper.makeResult(e));
    }
    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) CryptoMarkerType(org.openecard.crypto.common.sal.did.CryptoMarkerType) ByteArrayOutputStream(java.io.ByteArrayOutputStream) PSODecipher(org.openecard.sal.protocol.genericcryptography.apdu.PSODecipher) ECardException(org.openecard.common.ECardException) ECardException(org.openecard.common.ECardException) BigInteger(java.math.BigInteger) DecipherResponse(iso.std.iso_iec._24727.tech.schema.DecipherResponse) DIDStructureType(iso.std.iso_iec._24727.tech.schema.DIDStructureType) CardResponseAPDU(org.openecard.common.apdu.common.CardResponseAPDU) ManageSecurityEnvironment(org.openecard.common.apdu.ManageSecurityEnvironment) TLV(org.openecard.common.tlv.TLV)

Example 18 with CardCommandAPDU

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

the class TerminalAuthentication method externalAuthentication.

/**
 * Performs an External Authentication.
 * Sends an External Authentication APDU. (Protocol step 4)
 * See BSI-TR-03110, version 2.10, part 3, B.11.7.
 *
 * @param terminalSignature Terminal signature
 * @throws ProtocolException
 */
public void externalAuthentication(byte[] terminalSignature) throws ProtocolException {
    try {
        CardCommandAPDU externalAuthentication = new ExternalAuthentication(terminalSignature);
        externalAuthentication.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) ExternalAuthentication(org.openecard.common.apdu.ExternalAuthentication)

Example 19 with CardCommandAPDU

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

the class TerminalAuthentication method getChallenge.

/**
 * Gets a challenge from the PICC.
 * Sends a Get Challenge APDU. (Protocol step 3)
 * See BSI-TR-03110, version 2.10, part 3, B.11.6.
 *
 * @return Challenge
 * @throws ProtocolException
 */
public byte[] getChallenge() throws ProtocolException {
    try {
        CardCommandAPDU getChallenge = new GetChallenge();
        CardResponseAPDU response = getChallenge.transmit(dispatcher, slotHandle);
        return response.getData();
    } 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) CardResponseAPDU(org.openecard.common.apdu.common.CardResponseAPDU) GetChallenge(org.openecard.common.apdu.GetChallenge)

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