use of es.gob.jmulticard.asn1.Tlv in project jmulticard by ctt-gob-es.
the class TestAsn1SimpleTypes method testBitStringCreationWithBadData.
/**
* Prueba la creació de un tipo <code>BitString</code> con datos incorrectos.
* @throws TlvException Si no se puede crear el TLV.
*/
@Test
@SuppressWarnings("static-method")
public void testBitStringCreationWithBadData() throws TlvException {
final BitString u = new AccessFlags();
try {
u.setDerValue(new byte[] { (byte) 0x00, (byte) 0x01, (byte) 0xff });
} catch (final Asn1Exception e) {
// $NON-NLS-1$
System.out.println("Fallo esperado: " + e);
return;
}
// $NON-NLS-1$
Assert.fail("Tendria que haber saltado un Asn1Exception");
}
use of es.gob.jmulticard.asn1.Tlv in project jmulticard by ctt-gob-es.
the class ApduEncrypter method getDataTlv.
private byte[] getDataTlv(final byte[] data, final byte[] keyCipher, final byte[] sendSequenceCounter, final CryptoHelper cryptoHelper, final int paddingSize) throws IOException {
// Si hay datos calculamos el TLV con estos datos cifrados
if (data != null && data.length > 0) {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(TLV_VALUE_PREFIX_TO_MAC);
final byte[] paddedData = addPadding7816(data, paddingSize);
baos.write(encryptData(paddedData, keyCipher, sendSequenceCounter, cryptoHelper));
// Sobrescribimos los datos de la APDU inmediatamente despues de cifrarla, para que este
// el minimo tiempo en memoria. Como los arrays son mutables con escribir esta copia se
// sobreescriben todas las referencias.
wipeByteArray(paddedData);
wipeByteArray(data);
return new Tlv(TAG_DATA_TLV, baos.toByteArray()).getBytes();
}
return new byte[0];
}
use of es.gob.jmulticard.asn1.Tlv 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.asn1.Tlv in project jmulticard by ctt-gob-es.
the class Sequence method decodeValue.
@Override
protected void decodeValue() throws Asn1Exception, TlvException {
final Tlv mainTlv = new Tlv(getRawDerValue());
checkTag(mainTlv.getTag());
int offset = 0;
Tlv tlv;
byte[] remainingBytes;
DecoderObject tmpDo;
final byte[] rawValue = mainTlv.getValue();
for (int i = 0; i < this.elementsTypes.length; i++) {
remainingBytes = new byte[rawValue.length - offset];
System.arraycopy(rawValue, offset, remainingBytes, 0, remainingBytes.length);
try {
tlv = new Tlv(remainingBytes);
tmpDo = this.elementsTypes[i].getElementType().getConstructor().newInstance();
tmpDo.checkTag(tlv.getTag());
tmpDo.setDerValue(tlv.getBytes());
} catch (final Exception e) {
if (this.elementsTypes[i].isOptional()) {
// Como no ha avanzado el offset, se reutilizara el tipo en el proximo elemento
continue;
}
// $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
throw new Asn1Exception("Error en el elemento " + i + " (" + this.elementsTypes[i].getElementType().getName() + ") de la secuencia ASN.1: " + e, e);
}
// El offset se avanza antes del continue de la opcionalidad
offset = offset + tlv.getBytes().length;
this.elements.add(tmpDo);
}
}
use of es.gob.jmulticard.asn1.Tlv in project jmulticard by ctt-gob-es.
the class SequenceOf method decodeValue.
@Override
protected void decodeValue() throws Asn1Exception, TlvException {
Tlv tlv = new Tlv(getRawDerValue());
checkTag(tlv.getTag());
int offset = 0;
byte[] remainingBytes;
DecoderObject tmpDo;
final byte[] valueBytes = tlv.getValue();
this.sequenceObjects = new Vector<>();
while (offset < valueBytes.length) {
remainingBytes = new byte[valueBytes.length - offset];
System.arraycopy(valueBytes, offset, remainingBytes, 0, remainingBytes.length);
tlv = new Tlv(remainingBytes);
try {
tmpDo = this.elementsType.getConstructor().newInstance();
} catch (final Exception e) {
throw new Asn1Exception(// $NON-NLS-1$
"No se ha podido instanciar un " + this.elementsType.getName() + " en la secuencia: " + // $NON-NLS-1$
e, // $NON-NLS-1$
e);
}
offset = offset + tlv.getBytes().length;
tmpDo.checkTag(tlv.getTag());
tmpDo.setDerValue(tlv.getBytes());
this.sequenceObjects.add(tmpDo);
}
}
Aggregations