Search in sources :

Example 1 with TLV

use of org.openecard.common.tlv.TLV in project open-ecard by ecsec.

the class CardRecognitionImpl method checkDataObject.

private boolean checkDataObject(DataMaskType matcher, TLV result) {
    byte[] tag = matcher.getTag();
    DataMaskType nextMatcher = matcher.getDataObject();
    // this function only works with tag and dataobject
    if (tag == null || nextMatcher == null) {
        return false;
    }
    long tagNum = ByteUtils.toLong(tag);
    List<TLV> chunks = result.findNextTags(tagNum);
    for (TLV next : chunks) {
        boolean outcome;
        if (nextMatcher.getMatchingData() != null) {
            outcome = checkMatchingData(nextMatcher.getMatchingData(), next.getValue());
        } else {
            outcome = checkDataObject(nextMatcher, next.getChild());
        }
        // evaluate outcome
        if (outcome == true) {
            return true;
        }
    }
    // no match
    return false;
}
Also used : DataMaskType(iso.std.iso_iec._24727.tech.schema.DataMaskType) TLV(org.openecard.common.tlv.TLV)

Example 2 with TLV

use of org.openecard.common.tlv.TLV in project open-ecard by ecsec.

the class SecureMessaging method decrypt.

/**
 * Decrypt the APDU.
 *
 * @param response the response
 * @param secureMessagingSSC the secure messaging ssc
 * @return the byte[]
 * @throws Exception the exception
 */
private byte[] decrypt(byte[] response, byte[] secureMessagingSSC) throws Exception {
    ByteArrayInputStream bais = new ByteArrayInputStream(response);
    ByteArrayOutputStream baos = new ByteArrayOutputStream(response.length - 10);
    // Status bytes of the response APDU. MUST be 2 bytes.
    byte[] statusBytes = new byte[2];
    // Padding-content indicator followed by cryptogram 0x87.
    byte[] dataObject = null;
    // Cryptographic checksum 0x8E. MUST be 8 bytes.
    byte[] macObject = new byte[8];
    /*
	 * Read APDU structure
	 * Case 1: DO99|DO8E|SW1SW2
	 * Case 2: DO87|DO99|DO8E|SW1SW2
	 * Case 3: DO99|DO8E|SW1SW2
	 * Case 4: DO87|DO99|DO8E|SW1SW2
	 */
    byte tag = (byte) bais.read();
    // Read data object (OPTIONAL)
    if (tag == (byte) 0x87) {
        int size = bais.read();
        if (size > 0x80) {
            byte[] sizeBytes = new byte[size & 0x0F];
            bais.read(sizeBytes, 0, sizeBytes.length);
            size = new BigInteger(1, sizeBytes).intValue();
        }
        // Skip encryption header
        bais.skip(1);
        dataObject = new byte[size - 1];
        bais.read(dataObject, 0, dataObject.length);
        tag = (byte) bais.read();
    }
    // Read processing status (REQUIRED)
    if (tag == (byte) 0x99) {
        if (bais.read() == (byte) 0x02) {
            bais.read(statusBytes, 0, 2);
            tag = (byte) bais.read();
        }
    } else {
        throw new IOException("Malformed Secure Messaging APDU");
    }
    // Read MAC (REQUIRED)
    if (tag == (byte) 0x8E) {
        if (bais.read() == (byte) 0x08) {
            bais.read(macObject, 0, 8);
        }
    } else {
        throw new IOException("Malformed Secure Messaging APDU");
    }
    // Only 2 bytes status should remain
    if (bais.available() != 2) {
        throw new IOException("Malformed Secure Messaging APDU");
    }
    // Calculate MAC for verification
    CMac cmac = getCMAC(secureMessagingSSC);
    byte[] mac = new byte[16];
    synchronized (cmac) {
        ByteArrayOutputStream macData = new ByteArrayOutputStream();
        // Write padding-content
        if (dataObject != null) {
            TLV paddedDataObject = new TLV();
            paddedDataObject.setTagNumWithClass((byte) 0x87);
            paddedDataObject.setValue(ByteUtils.concatenate((byte) 0x01, dataObject));
            macData.write(paddedDataObject.toBER());
        }
        // Write status bytes
        TLV statusBytesObject = new TLV();
        statusBytesObject.setTagNumWithClass((byte) 0x99);
        statusBytesObject.setValue(statusBytes);
        macData.write(statusBytesObject.toBER());
        byte[] paddedData = pad(macData.toByteArray(), 16);
        cmac.update(paddedData, 0, paddedData.length);
        cmac.doFinal(mac, 0);
        mac = ByteUtils.copy(mac, 0, 8);
    }
    // Verify MAC
    if (!ByteUtils.compare(mac, macObject)) {
        throw new GeneralSecurityException("Secure Messaging MAC verification failed");
    }
    // Decrypt data
    if (dataObject != null) {
        Cipher c = getCipher(secureMessagingSSC, Cipher.DECRYPT_MODE);
        byte[] data_decrypted = c.doFinal(dataObject);
        baos.write(unpad(data_decrypted));
    }
    // Add status code
    baos.write(statusBytes);
    return baos.toByteArray();
}
Also used : CMac(org.openecard.bouncycastle.crypto.macs.CMac) ByteArrayInputStream(java.io.ByteArrayInputStream) GeneralSecurityException(java.security.GeneralSecurityException) BigInteger(java.math.BigInteger) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) Cipher(javax.crypto.Cipher) TLV(org.openecard.common.tlv.TLV)

Example 3 with TLV

use of org.openecard.common.tlv.TLV in project open-ecard by ecsec.

the class AuthenticationToken method getMACObject.

/**
 * Calculates the data for the authentication token.
 *
 * @param key Key
 * @return data object for token
 */
private byte[] getMACObject(byte[] key) throws GeneralSecurityException {
    byte[] ret = null;
    try {
        TLV keyObject = new TLV();
        keyObject.setTagNumWithClass((byte) 0x86);
        keyObject.setValue(ByteUtils.cutLeadingNullBytes(key));
        TLV oidObject = new TLV();
        oidObject.setTagNumWithClass((byte) 0x06);
        oidObject.setValue(ObjectIdentifierUtils.getValue(pi.getProtocol()));
        oidObject.addToEnd(keyObject);
        TLV macObject = new TLV();
        macObject.setTagNum((byte) 0x49);
        macObject.setTagClass(TagClass.APPLICATION);
        macObject.setChild(oidObject);
        ret = macObject.toBER(true);
    } catch (Throwable e) {
        logger.error(e.getMessage(), e);
        throw new GeneralSecurityException(e);
    }
    return ret;
}
Also used : GeneralSecurityException(java.security.GeneralSecurityException) TLV(org.openecard.common.tlv.TLV)

Example 4 with TLV

use of org.openecard.common.tlv.TLV in project open-ecard by ecsec.

the class AuthenticationToken method verifyToken.

/**
 * Verify the authentication token by the PICC and extract Certificate Authority Reference (CAR).
 *
 * @param T_PICC Token from the PICC
 * @param specifiedCHAT true if PACE is used with a CHAT
 * @return true if T_PICC is equal to my T_PICC
 * @throws GeneralSecurityException
 */
public boolean verifyToken(byte[] T_PICC, boolean specifiedCHAT) throws GeneralSecurityException {
    try {
        TLV dataSet = TLV.fromBER(T_PICC);
        // set of dynamic authentication data
        if (dataSet.getTagNumWithClass() != 0x7C) {
            throw new GeneralSecurityException("The returned object is not a set of dynamic authentication data.");
        }
        // Authentication Token
        List<TLV> authTokens = dataSet.findChildTags(0x86);
        if (authTokens.isEmpty()) {
            String msg = "Authentication Token is missing in set of dynamic authentication data.";
            throw new GeneralSecurityException(msg);
        } else if (authTokens.size() > 1) {
            String msg = "Authentication Token is present multiple times in set of dynamic authentication data.";
            throw new GeneralSecurityException(msg);
        } else {
            byte[] newToken = authTokens.get(0).getValue();
            if (!ByteUtils.compare(newToken, token)) {
                throw new GeneralSecurityException("Can not verify authentication token.");
            }
        }
        // CAR
        if (specifiedCHAT) {
            // current CAR
            List<TLV> car1 = dataSet.findChildTags(0x87);
            if (car1.isEmpty()) {
                String msg = "Current CAR is missing in set of dynamic authentication data.";
                throw new GeneralSecurityException(msg);
            } else if (car1.size() > 1) {
                String msg = "Current CAR is present multiple times in set of dynamic authentication data.";
                throw new GeneralSecurityException(msg);
            } else {
                currentCAR = car1.get(0).getValue();
                verifyCAR("Current CAR", currentCAR);
            }
            // last CAR
            List<TLV> car2 = dataSet.findChildTags(0x88);
            if (car2.size() > 1) {
                String msg = "Previous CAR is present multiple times in set of dynamic authentication data.";
                throw new GeneralSecurityException(msg);
            } else if (car2.size() == 1) {
                previousCAR = car2.get(0).getValue();
                verifyCAR("Previous CAR", previousCAR);
            }
        }
    } catch (TLVException ex) {
        throw new GeneralSecurityException("Given data is not a valid ASN.1 object.", ex);
    }
    return true;
}
Also used : GeneralSecurityException(java.security.GeneralSecurityException) TLVException(org.openecard.common.tlv.TLVException) TLV(org.openecard.common.tlv.TLV)

Example 5 with TLV

use of org.openecard.common.tlv.TLV in project open-ecard by ecsec.

the class FCP method toString.

// TODO: implement further tags in FCP
/**
 * Create a string from the object which contains all collected information.
 *
 * @param prefix
 * @return A string containing all collected information.
 */
public String toString(String prefix) {
    StringBuilder b = new StringBuilder(4096);
    String indent = prefix + " ";
    String subindent = indent + " ";
    b.append(prefix);
    b.append("FCP:\n");
    b.append(indent);
    b.append("num-bytes=");
    b.append(numBytes);
    b.append(" num-bytes-structure=");
    b.append(numBytesStructure);
    b.append("\n");
    b.append(dataElements.toString(indent));
    b.append("\n");
    b.append(indent);
    b.append("File-Identifiers:\n");
    for (byte[] next : fileIdentifiers) {
        b.append(subindent);
        b.append(ByteUtils.toHexString(next));
        b.append("\n");
    }
    b.append("DF-Names:\n");
    for (byte[] next : dfNames) {
        b.append(subindent);
        b.append(ByteUtils.toHexString(next));
        b.append("\n");
    }
    // shortEfIdentifier
    if (shortEfIdentifier != null) {
        b.append(indent);
        b.append("short-EF-identifier: ");
        b.append(ByteUtils.toHexString(shortEfIdentifier));
        b.append("\n");
    }
    // lifeCycleStatusByte
    // securityAttributeReferenceExpanded
    // securityAttributeCompact
    // securityEnvironmentTemplateEfs
    // channelSecurityAttribute
    // securityAttributeTemplateForDataObject
    // securityAttributeTemplateProprietary
    // dataObjectTemplates
    b.append(indent);
    b.append("DataObjectTemplates:\n");
    for (TLV next : dataObjectTemplates) {
        b.append(subindent);
        b.append("DataObjectTemplate:");
        b.append(next.toString(subindent + " "));
        b.append("\n");
    }
    return b.toString();
}
Also used : TLV(org.openecard.common.tlv.TLV)

Aggregations

TLV (org.openecard.common.tlv.TLV)21 Test (org.testng.annotations.Test)5 ByteArrayOutputStream (java.io.ByteArrayOutputStream)4 GeneralSecurityException (java.security.GeneralSecurityException)3 CardCommandAPDU (org.openecard.common.apdu.common.CardCommandAPDU)3 TLVException (org.openecard.common.tlv.TLVException)3 BigInteger (java.math.BigInteger)2 Cipher (javax.crypto.Cipher)2 CMac (org.openecard.bouncycastle.crypto.macs.CMac)2 ManageSecurityEnvironment (org.openecard.common.apdu.ManageSecurityEnvironment)2 CardResponseAPDU (org.openecard.common.apdu.common.CardResponseAPDU)2 ConnectionHandleType (iso.std.iso_iec._24727.tech.schema.ConnectionHandleType)1 DIDStructureType (iso.std.iso_iec._24727.tech.schema.DIDStructureType)1 DataMaskType (iso.std.iso_iec._24727.tech.schema.DataMaskType)1 DecipherResponse (iso.std.iso_iec._24727.tech.schema.DecipherResponse)1 SignResponse (iso.std.iso_iec._24727.tech.schema.SignResponse)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 MessageDigest (java.security.MessageDigest)1