Search in sources :

Example 1 with AmCryptoException

use of es.gob.jmulticard.de.tsenger.androsmex.crypto.AmCryptoException in project jmulticard by ctt-gob-es.

the class SecureMessaging method unwrap.

/**
 * Obtiene la APDU de respuesta en claro a partir de una APDU protegida.
 * @param responseApduEncrypted APDU protegida.
 * @return APDU en claro.
 * @throws SecureMessagingException En cualquier error.
 */
public ResponseApdu unwrap(final ResponseApdu responseApduEncrypted) throws SecureMessagingException {
    DO87 do87 = null;
    DO99 do99 = null;
    DO8E do8E = null;
    incrementAtIndex(this.ssc);
    int pointer = 0;
    final byte[] rapduBytes = responseApduEncrypted.getData();
    final byte[] subArray = new byte[rapduBytes.length];
    while (pointer < rapduBytes.length) {
        System.arraycopy(rapduBytes, pointer, subArray, 0, rapduBytes.length - pointer);
        final byte[] encodedBytes;
        try (final ASN1InputStream asn1sp = new ASN1InputStream(subArray)) {
            encodedBytes = asn1sp.readObject().getEncoded();
        } catch (final IOException e) {
            throw new SecureMessagingException(e);
        }
        try (final ASN1InputStream asn1in = new ASN1InputStream(encodedBytes)) {
            switch(encodedBytes[0]) {
                case (byte) 0x87:
                    do87 = new DO87();
                    do87.fromByteArray(asn1in.readObject().getEncoded());
                    break;
                case (byte) 0x99:
                    do99 = new DO99();
                    do99.fromByteArray(asn1in.readObject().getEncoded());
                    break;
                case (byte) 0x8E:
                    do8E = new DO8E();
                    do8E.fromByteArray(asn1in.readObject().getEncoded());
                    break;
                default:
                    break;
            }
        } catch (final IOException e) {
            throw new SecureMessagingException(e);
        }
        pointer += encodedBytes.length;
    }
    if (do99 == null || do8E == null) {
        // DO99 es obligatorio //$NON-NLS-1$
        throw new SecureMessagingException("Error en SecureMessaging: DO99 o DO8E no encontrados");
    }
    // Construct K (SSC||DO87||DO99)
    final ByteArrayOutputStream bout = new ByteArrayOutputStream();
    try {
        if (do87 != null) {
            bout.write(do87.getEncoded());
        }
        bout.write(do99.getEncoded());
    } catch (final IOException e) {
        throw new SecureMessagingException(e);
    }
    this.crypto.init(this.kmac, this.ssc);
    final byte[] cc = this.crypto.getMAC(bout.toByteArray());
    final byte[] do8eData = do8E.getData();
    if (!java.util.Arrays.equals(cc, do8eData)) {
        throw new SecureMessagingException(// $NON-NLS-1$
        "Checksum incorrecto\n CC Calculado: " + HexUtils.hexify(cc, false) + // $NON-NLS-1$
        "\nCC en DO8E: " + HexUtils.hexify(do8eData, false));
    }
    // Desencriptar DO87
    final byte[] unwrappedAPDUBytes;
    if (do87 != null) {
        this.crypto.init(this.kenc, this.ssc);
        final byte[] do87Data = do87.getData();
        final byte[] data;
        try {
            data = this.crypto.decrypt(do87Data);
        } catch (final AmCryptoException e) {
            throw new SecureMessagingException(e);
        }
        // Construir la respuesta APDU desencriptada
        unwrappedAPDUBytes = new byte[data.length + 2];
        System.arraycopy(data, 0, unwrappedAPDUBytes, 0, data.length);
        final byte[] do99Data = do99.getData();
        System.arraycopy(do99Data, 0, unwrappedAPDUBytes, data.length, do99Data.length);
    } else {
        unwrappedAPDUBytes = do99.getData().clone();
    }
    return new ResponseApdu(unwrappedAPDUBytes);
}
Also used : ASN1InputStream(org.spongycastle.asn1.ASN1InputStream) ResponseApdu(es.gob.jmulticard.apdu.ResponseApdu) IOException(java.io.IOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) AmCryptoException(es.gob.jmulticard.de.tsenger.androsmex.crypto.AmCryptoException)

Aggregations

ResponseApdu (es.gob.jmulticard.apdu.ResponseApdu)1 AmCryptoException (es.gob.jmulticard.de.tsenger.androsmex.crypto.AmCryptoException)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 IOException (java.io.IOException)1 ASN1InputStream (org.spongycastle.asn1.ASN1InputStream)1