Search in sources :

Example 1 with BerTlv

use of es.gob.jmulticard.asn1.bertlv.BerTlv in project jmulticard by ctt-gob-es.

the class ApduEncrypterDes method decryptResponseApdu.

/**
 * Desencripta los datos de una APDU de respuesta protegida.
 * @param responseApdu APDU de respuesta cifrada.
 * @param keyCipher Clave para el descifrado de la respuesta.
 * @param ssc Código de secuencia correspondiente a la respuesta.
 * @param kMac Clave para la verificación de la respuesta.
 * @param cryptoHelper Manejador para el desencriptado.
 * @return APDU con la respuesta descifrada.
 * @throws IOException Cuando ocurre un error durante la desencriptación de los datos.
 */
@Override
public ResponseApdu decryptResponseApdu(final ResponseApdu responseApdu, final byte[] keyCipher, final byte[] ssc, final byte[] kMac, final CryptoHelper cryptoHelper) throws IOException {
    // Si el resultado es incorrecto, lo devolvemos para su evaluacion
    if (!responseApdu.isOk()) {
        return new ResponseApdu(responseApdu.getStatusWord().getBytes());
    }
    // Desciframos y validamos el resultado
    final ByteArrayInputStream recordOfTlvs = new ByteArrayInputStream(responseApdu.getData());
    BerTlv dataTlv = null;
    BerTlv swTlv = null;
    BerTlv macTlv = null;
    try {
        BerTlv tlv = BerTlv.getInstance(recordOfTlvs);
        if (tlv.getTag().getTagValue() == TAG_DATA_TLV) {
            dataTlv = tlv;
            tlv = BerTlv.getInstance(recordOfTlvs);
        }
        if (tlv.getTag().getTagValue() == TAG_SW_TLV) {
            swTlv = tlv;
            tlv = BerTlv.getInstance(recordOfTlvs);
        }
        if (tlv.getTag().getTagValue() == TAG_MAC_TLV) {
            macTlv = tlv;
        }
    } catch (final NegativeArraySizeException e) {
        // $NON-NLS-1$
        throw new ApduConnectionException("Error en el formato de la respuesta remitida por el canal seguro", e);
    }
    if (macTlv == null) {
        // $NON-NLS-1$
        throw new SecureChannelException("No se ha encontrado el TLV del MAC en la APDU");
    }
    if (swTlv == null) {
        // $NON-NLS-1$
        throw new SecureChannelException("No se ha encontrado el TLV del StatusWord en la APDU cifrada");
    }
    // Pasamos el TLV completo de datos y el del StatusWord concatenados
    final int tlvsLenght = // Tag (1 byte) + Lenght (1 byte + 1 por cada 128) + Value (Value.lenght bytes
    (dataTlv != null ? 1 + 1 + dataTlv.getValue().length / 128 + dataTlv.getValue().length : 0) + 1 + 1 + // Tag (1 byte) + Lenght (1 byte) + Value (Value.lenght bytes)
    swTlv.getValue().length;
    verifyMac(HexUtils.subArray(responseApdu.getData(), 0, tlvsLenght), macTlv.getValue(), ssc, kMac, cryptoHelper);
    if (dataTlv == null) {
        return new ResponseApdu(swTlv.getValue());
    }
    // Desencriptamos y eliminamos el padding de los datos, teniendo en cuenta que el primer byte
    // de los datos es fijo (0x01) y no cuenta dentro de los datos
    final byte[] decryptedData = removePadding7816(cryptoHelper.desedeDecrypt(HexUtils.subArray(dataTlv.getValue(), 1, dataTlv.getValue().length - 1), keyCipher));
    final byte[] responseApduBytes = new byte[decryptedData.length + swTlv.getValue().length];
    System.arraycopy(decryptedData, 0, responseApduBytes, 0, decryptedData.length);
    System.arraycopy(swTlv.getValue(), 0, responseApduBytes, decryptedData.length, swTlv.getValue().length);
    return new ResponseApdu(responseApduBytes);
}
Also used : SecureChannelException(es.gob.jmulticard.apdu.connection.cwa14890.SecureChannelException) ByteArrayInputStream(java.io.ByteArrayInputStream) ResponseApdu(es.gob.jmulticard.apdu.ResponseApdu) BerTlv(es.gob.jmulticard.asn1.bertlv.BerTlv)

Aggregations

ResponseApdu (es.gob.jmulticard.apdu.ResponseApdu)1 SecureChannelException (es.gob.jmulticard.apdu.connection.cwa14890.SecureChannelException)1 BerTlv (es.gob.jmulticard.asn1.bertlv.BerTlv)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1