use of es.gob.jmulticard.apdu.ResponseApdu in project jmulticard by ctt-gob-es.
the class TuiR5 method verifyPin.
@Override
public void verifyPin(final PasswordCallback pinPc) throws ApduConnectionException, BadPinException {
final VerifyApduCommand verifyPinApduCommand = new VerifyApduCommand(CLA, this.passwordCallback);
final ResponseApdu verifyResponse = getConnection().transmit(verifyPinApduCommand);
if (!verifyResponse.isOk()) {
throw new BadPinException(verifyResponse.getStatusWord().getLsb() - (byte) 0xC0);
}
}
use of es.gob.jmulticard.apdu.ResponseApdu 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);
}
use of es.gob.jmulticard.apdu.ResponseApdu 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);
}
use of es.gob.jmulticard.apdu.ResponseApdu in project jmulticard by ctt-gob-es.
the class Cwa14890OneV1Connection method transmit.
/**
* {@inheritDoc}
*/
@Override
public ResponseApdu transmit(final CommandApdu command) throws ApduConnectionException {
final CommandApdu protectedApdu;
try {
this.ssc = increment(this.ssc);
protectedApdu = this.apduEncrypter.protectAPDU(command, this.kenc, this.kmac, this.ssc, this.cryptoHelper);
} catch (final IOException e) {
throw new SecureChannelException(// $NON-NLS-1$
"Error en la encriptacion de la APDU para su envio por el canal seguro: " + e, // $NON-NLS-1$
e);
}
final ResponseApdu responseApdu = this.subConnection.transmit(protectedApdu);
if (INVALID_CRYPTO_CHECKSUM.equals(responseApdu.getStatusWord())) {
throw new InvalidCryptographicChecksum();
}
// Desencriptamos la respuesta
try {
this.ssc = increment(this.ssc);
final ResponseApdu decipherApdu = this.apduEncrypter.decryptResponseApdu(responseApdu, this.kenc, this.ssc, this.kmac, this.cryptoHelper);
// a enviar el comando indicando la longitud correcta
if (decipherApdu.getStatusWord().getMsb() == MSB_INCORRECT_LE) {
command.setLe(decipherApdu.getStatusWord().getLsb());
return transmit(command);
} else if (decipherApdu.getStatusWord().getMsb() == MSB_INCORRECT_LE_PACE) {
command.setLe(command.getLe().intValue() - 1);
return transmit(command);
}
return decipherApdu;
} catch (final Exception e) {
throw new ApduConnectionException(// $NON-NLS-1$
"Error en la desencriptacion de la APDU de respuesta recibida por el canal seguro: " + e, // $NON-NLS-1$
e);
}
}
use of es.gob.jmulticard.apdu.ResponseApdu in project jmulticard by ctt-gob-es.
the class Dnie method signOperation.
/**
* Realiza la operación de firma.
* @param data Datos que se desean firmar.
* @param signAlgorithm Algoritmo de firma (por ejemplo, <code>SHA512withRSA</code>, <code>SHA1withRSA</code>, etc.).
* @param privateKeyReference Referencia a la clave privada para la firma.
* @return Firma de los datos.
* @throws CryptoCardException Cuando se produce un error durante la operación de firma.
* @throws PinException Si el PIN proporcionado en la <i>PasswordCallback</i>
* es incorrecto y no estaba habilitado el reintento automático.
* @throws es.gob.jmulticard.card.AuthenticationModeLockedException Cuando el DNIe está bloqueado.
*/
protected byte[] signOperation(final byte[] data, final String signAlgorithm, final PrivateKeyReference privateKeyReference) throws CryptoCardException, PinException {
openSecureChannelIfNotAlreadyOpened();
ResponseApdu res;
try {
CommandApdu apdu = new MseSetComputationApduCommand((byte) 0x00, ((DniePrivateKeyReference) privateKeyReference).getKeyPath().getLastFilePath(), null);
res = getConnection().transmit(apdu);
if (!res.isOk()) {
throw new DnieCardException(// $NON-NLS-1$
"Error en el establecimiento de las clave de firma con respuesta: " + res.getStatusWord(), // $NON-NLS-1$
res.getStatusWord());
}
final byte[] digestInfo;
try {
digestInfo = DigestInfo.encode(signAlgorithm, data, this.cryptoHelper);
} catch (final IOException e) {
// $NON-NLS-1$
throw new DnieCardException("Error en el calculo de la huella para firmar: " + e, e);
}
apdu = new PsoSignHashApduCommand((byte) 0x00, digestInfo);
res = getConnection().transmit(apdu);
if (!res.isOk()) {
throw new DnieCardException(// $NON-NLS-1$
"Error durante la operacion de firma con respuesta: " + res.getStatusWord(), res.getStatusWord());
}
} catch (final LostChannelException e) {
try {
getConnection().close();
if (getConnection() instanceof Cwa14890Connection) {
setConnection(((Cwa14890Connection) getConnection()).getSubConnection());
}
} catch (final Exception ex) {
// $NON-NLS-1$
throw new DnieCardException("No se pudo recuperar el canal seguro para firmar: " + ex, ex);
}
return signOperation(data, signAlgorithm, privateKeyReference);
} catch (final ApduConnectionException e) {
// $NON-NLS-1$
throw new DnieCardException("Error en la transmision de comandos a la tarjeta: " + e, e);
}
return res.getData();
}
Aggregations