use of org.openecard.common.apdu.common.CardCommandAPDU in project open-ecard by ecsec.
the class SecureMessaging method encrypt.
/**
* Encrypt the APDU.
*
* @param apdu APDU
* @param secureMessagingSSC Secure Messaging Send Sequence Counter
* @return Encrypted APDU
* @throws Exception
*/
private byte[] encrypt(byte[] apdu, byte[] secureMessagingSSC) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
CardCommandAPDU cAPDU = new CardCommandAPDU(apdu);
if (cAPDU.isSecureMessaging()) {
throw new IllegalArgumentException("Malformed APDU.");
}
byte[] data = cAPDU.getData();
byte[] header = cAPDU.getHeader();
int lc = cAPDU.getLC();
int le = cAPDU.getLE();
if (data.length > 0) {
data = pad(data, 16);
// Encrypt data
Cipher c = getCipher(secureMessagingSSC, Cipher.ENCRYPT_MODE);
byte[] dataEncrypted = c.doFinal(data);
// Add padding indicator 0x01
dataEncrypted = ByteUtils.concatenate((byte) 0x01, dataEncrypted);
TLV dataObject = new TLV();
dataObject.setTagNumWithClass((byte) 0x87);
dataObject.setValue(dataEncrypted);
baos.write(dataObject.toBER());
}
// Write protected LE
if (le >= 0) {
TLV leObject = new TLV();
leObject.setTagNumWithClass((byte) 0x97);
if (le == 0x100) {
leObject.setValue(NULL);
} else if (le > 0x100) {
leObject.setValue(new byte[] { (byte) ((le >> 8) & 0xFF), (byte) (le & 0xFF) });
} else {
leObject.setValue(new byte[] { (byte) le });
}
baos.write(leObject.toBER());
}
// Indicate Secure Messaging
// note: must be done before mac calculation
header[0] |= 0x0C;
/*
* Calculate MAC
*/
byte[] mac = new byte[16];
CMac cmac = getCMAC(secureMessagingSSC);
byte[] paddedHeader = pad(header, 16);
cmac.update(paddedHeader, 0, paddedHeader.length);
if (baos.size() > 0) {
byte[] paddedData = pad(baos.toByteArray(), 16);
cmac.update(paddedData, 0, paddedData.length);
}
cmac.doFinal(mac, 0);
mac = ByteUtils.copy(mac, 0, 8);
//
// Build APDU
TLV macStructure = new TLV();
macStructure.setTagNumWithClass((byte) 0x8E);
macStructure.setValue(mac);
byte[] secureData = ByteUtils.concatenate(baos.toByteArray(), macStructure.toBER());
CardCommandAPDU secureCommand = new CardCommandAPDU(header[0], header[1], header[2], header[3], secureData);
// set LE explicitely to 0x00 or in case of extended length 0x00 0x00
if ((lc > 0xFF) || (le > 0x100)) {
secureCommand.setLE(65536);
} else {
secureCommand.setLE(256);
}
return secureCommand.toByteArray();
}
use of org.openecard.common.apdu.common.CardCommandAPDU in project open-ecard by ecsec.
the class DecipherStep method perform.
@Override
public DecipherResponse perform(Decipher request, Map<String, Object> internalData) {
DecipherResponse response = WSHelper.makeResponse(DecipherResponse.class, WSHelper.makeResultOK());
try {
ConnectionHandleType connectionHandle = SALUtils.getConnectionHandle(request);
String didName = SALUtils.getDIDName(request);
byte[] applicationID = connectionHandle.getCardApplication();
CardStateEntry cardStateEntry = SALUtils.getCardStateEntry(internalData, connectionHandle);
Assert.securityConditionDID(cardStateEntry, applicationID, didName, CryptographicServiceActionName.DECIPHER);
DIDStructureType didStructure = SALUtils.getDIDStructure(request, didName, cardStateEntry, connectionHandle);
CryptoMarkerType cryptoMarker = new CryptoMarkerType(didStructure.getDIDMarker());
byte[] keyReference = cryptoMarker.getCryptoKeyInfo().getKeyRef().getKeyRef();
byte[] algorithmIdentifier = cryptoMarker.getAlgorithmInfo().getCardAlgRef();
byte[] slotHandle = connectionHandle.getSlotHandle();
// See eGK specification, part 1, version 2.2.0, section 15.9.6.
if (didStructure.getDIDScope().equals(DIDScopeType.LOCAL)) {
keyReference[0] = (byte) (0x80 | keyReference[0]);
}
TLV tagKeyReference = new TLV();
tagKeyReference.setTagNumWithClass(0x84);
tagKeyReference.setValue(keyReference);
TLV tagAlgorithmIdentifier = new TLV();
tagAlgorithmIdentifier.setTagNumWithClass(0x80);
tagAlgorithmIdentifier.setValue(algorithmIdentifier);
byte[] mseData = ByteUtils.concatenate(tagKeyReference.toBER(), tagAlgorithmIdentifier.toBER());
CardCommandAPDU apdu = new ManageSecurityEnvironment((byte) 0x41, ManageSecurityEnvironment.CT, mseData);
apdu.transmit(dispatcher, slotHandle);
byte[] ciphertext = request.getCipherText();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BigInteger bitKeySize = cryptoMarker.getCryptoKeyInfo().getKeySize();
int blocksize = bitKeySize.divide(new BigInteger("8")).intValue();
// check if the ciphertext length is divisible by the blocksize without rest
if ((ciphertext.length % blocksize) != 0) {
return WSHelper.makeResponse(DecipherResponse.class, WSHelper.makeResultError(ECardConstants.Minor.App.INCORRECT_PARM, "The length of the ciphertext should be a multiple of the blocksize."));
}
// decrypt the ciphertext block for block
for (int offset = 0; offset < ciphertext.length; offset += blocksize) {
byte[] ciphertextblock = ByteUtils.copy(ciphertext, offset, blocksize);
apdu = new PSODecipher(ByteUtils.concatenate(PADDING_INDICATOR_BYTE, ciphertextblock), (byte) blocksize);
CardResponseAPDU responseAPDU = apdu.transmit(dispatcher, slotHandle);
baos.write(responseAPDU.getData());
}
response.setPlainText(baos.toByteArray());
} catch (ECardException e) {
response.setResult(e.getResult());
} catch (Exception e) {
logger.error(e.getMessage(), e);
response.setResult(WSHelper.makeResult(e));
}
return response;
}
use of org.openecard.common.apdu.common.CardCommandAPDU in project open-ecard by ecsec.
the class TerminalAuthentication method externalAuthentication.
/**
* Performs an External Authentication.
* Sends an External Authentication APDU. (Protocol step 4)
* See BSI-TR-03110, version 2.10, part 3, B.11.7.
*
* @param terminalSignature Terminal signature
* @throws ProtocolException
*/
public void externalAuthentication(byte[] terminalSignature) throws ProtocolException {
try {
CardCommandAPDU externalAuthentication = new ExternalAuthentication(terminalSignature);
externalAuthentication.transmit(dispatcher, slotHandle);
} catch (APDUException e) {
throw new ProtocolException(e.getResult());
}
}
use of org.openecard.common.apdu.common.CardCommandAPDU in project open-ecard by ecsec.
the class TerminalAuthentication method getChallenge.
/**
* Gets a challenge from the PICC.
* Sends a Get Challenge APDU. (Protocol step 3)
* See BSI-TR-03110, version 2.10, part 3, B.11.6.
*
* @return Challenge
* @throws ProtocolException
*/
public byte[] getChallenge() throws ProtocolException {
try {
CardCommandAPDU getChallenge = new GetChallenge();
CardResponseAPDU response = getChallenge.transmit(dispatcher, slotHandle);
return response.getData();
} catch (APDUException e) {
throw new ProtocolException(e.getResult());
}
}
Aggregations