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);
}
Aggregations