use of org.openecard.common.apdu.common.CardResponseAPDU in project open-ecard by ecsec.
the class CardUtils method readFile.
/**
* Selects and reads a file.
*
* @param dispatcher Dispatcher
* @param slotHandle Slot handle
* @param fileID File ID
* @return File content
* @throws APDUException
*/
@Deprecated
public static byte[] readFile(Dispatcher dispatcher, byte[] slotHandle, byte[] fileID) throws APDUException {
CardResponseAPDU selectResponse = selectFileWithOptions(dispatcher, slotHandle, fileID, null, FCP_RESPONSE_DATA);
FCP fcp = null;
try {
fcp = new FCP(selectResponse.getData());
} catch (TLVException e) {
LOG.warn("Couldn't get File Control Parameters from Select response.", e);
}
return readFile(fcp, dispatcher, slotHandle);
}
use of org.openecard.common.apdu.common.CardResponseAPDU in project open-ecard by ecsec.
the class CardUtils method selectFileWithOptions.
/**
* Select a file with different options.
*
* @param dispatcher The Dispatcher for dispatching of the card commands.
* @param slotHandle The SlotHandle which identifies the card terminal.
* @param fileIdOrPath File identifier or path to the file to select.
* @param responses List of byte arrays with the trailers which should not thrown as errors.
* @param resultType Int value which indicates whether the select should be performed with a request of the FCP, FCI,
* FMD or without any data. There are four public variables available in this class to use.
* @return A CardResponseAPDU object with the requested response data.
* @throws APDUException Thrown if the selection of a file failed.
*/
public static CardResponseAPDU selectFileWithOptions(Dispatcher dispatcher, byte[] slotHandle, byte[] fileIdOrPath, List<byte[]> responses, int resultType) throws APDUException {
Select selectFile;
CardResponseAPDU result = null;
// respect the possibility that fileID could be a path
int i = 0;
while (i < fileIdOrPath.length) {
if (fileIdOrPath[i] == (byte) 0x3F && fileIdOrPath[i + 1] == (byte) 0x00 && i == 0 && i + 1 == 1) {
selectFile = new MasterFile();
i = i + 2;
} else if (i == fileIdOrPath.length - 2) {
selectFile = new Select.ChildFile(new byte[] { fileIdOrPath[i], fileIdOrPath[i + 1] });
switch(resultType) {
case 0:
// do nothing except of break 0x0C is the initialization value of P2
break;
case 1:
selectFile.setFCP();
break;
case 2:
selectFile.setFCI();
break;
case 3:
selectFile.setFMD();
break;
default:
throw new APDUException("There is no value assoziated with the returnType value " + resultType);
}
i = i + 2;
} else {
selectFile = new Select.ChildDirectory(new byte[] { fileIdOrPath[i], fileIdOrPath[i + 1] });
i = i + 2;
}
if (responses == null) {
// not all cards, e.g. Estonian id card, support P1 = 00 and DataFile filled with MF Fid so work around this
if (i == 2 && fileIdOrPath[0] == (byte) 0x3F && fileIdOrPath[1] == (byte) 0x00) {
responses = new ArrayList<>();
responses.add(new byte[] { (byte) 0x90, (byte) 0x00 });
responses.add(new byte[] { (byte) 0x67, (byte) 0x00 });
responses.add(new byte[] { (byte) 0x6A, (byte) 0x86 });
}
result = selectFile.transmit(dispatcher, slotHandle, responses);
if (!Arrays.equals(result.getTrailer(), new byte[] { (byte) 0x90, (byte) 0x00 }) && i == 2 && fileIdOrPath[0] == (byte) 0x3F && fileIdOrPath[1] == (byte) 0x00) {
selectFile = new Select((byte) 0x00, (byte) 0x0c);
result = selectFile.transmit(dispatcher, slotHandle, responses);
// so lets try selection by path
if (!Arrays.equals(result.getTrailer(), new byte[] { (byte) 0x90, (byte) 0x00 }) && fileIdOrPath.length > 2) {
selectFile = new Select.AbsolutePath(fileIdOrPath);
result = selectFile.transmit(dispatcher, slotHandle);
if (Arrays.equals(result.getTrailer(), TrailerConstants.Success.OK())) {
return result;
}
}
}
} else {
result = selectFile.transmit(dispatcher, slotHandle, responses);
}
}
return result;
}
use of org.openecard.common.apdu.common.CardResponseAPDU in project open-ecard by ecsec.
the class CardUtils method writeFile.
public static void writeFile(Dispatcher dispatcher, byte[] slotHandle, byte[] fileID, byte[] data) throws APDUException {
CardResponseAPDU selectResponse = selectFile(dispatcher, slotHandle, fileID);
FCP fcp = null;
try {
fcp = new FCP(selectResponse.getData());
} catch (TLVException e) {
LOG.warn("Couldn't get File Control Parameters from Select response.", e);
}
writeFile(fcp, dispatcher, slotHandle, data);
}
use of org.openecard.common.apdu.common.CardResponseAPDU in project open-ecard by ecsec.
the class SignStep method performSignature.
/**
* This method performs the signature creation according to BSI TR-03112 part 7.
*
* @param cryptoMarker The {@link CryptoMarkerType} containing the SignatureCreationInfo for creating the signature.
* @param keyReference A byte array containing the reference of the key to use.
* @param algorithmIdentifier A byte array containing the identifier of the signing algorithm.
* @param message The message to sign.
* @param slotHandle The slotHandle identifying the card.
* @param hashRef The variable contains the reference for the hash algorithm which have to be used.
* @param hashInfo A HashGenerationInfo object which indicates how the hash computation is to perform.
* @return A {@link SignResponse} object containing the signature of the <b>message</b>.
* @throws TLVException Thrown if the TLV creation for the key identifier or algorithm identifier failed.
* @throws IncorrectParameterException Thrown if the SignatureGenerationInfo does not contain PSO_CDS or INT_AUTH
* after an MSE_KEY command.
* @throws APDUException Thrown if one of the command to create the signature failed.
* @throws org.openecard.common.WSHelper.WSException Thrown if the checkResults method of WSHelper failed.
*/
private SignResponse performSignature(CryptoMarkerType cryptoMarker, byte[] keyReference, byte[] algorithmIdentifier, byte[] message, byte[] slotHandle, byte[] hashRef, HashGenerationInfoType hashInfo) throws TLVException, IncorrectParameterException, APDUException, WSHelper.WSException {
SignResponse response = WSHelper.makeResponse(SignResponse.class, WSHelper.makeResultOK());
TLV tagAlgorithmIdentifier = new TLV();
tagAlgorithmIdentifier.setTagNumWithClass(CARD_ALG_REF);
tagAlgorithmIdentifier.setValue(algorithmIdentifier);
TLV tagKeyReference = new TLV();
tagKeyReference.setTagNumWithClass(KEY_REFERENCE_PRIVATE_KEY);
tagKeyReference.setValue(keyReference);
CardCommandAPDU cmdAPDU = null;
CardResponseAPDU responseAPDU = null;
String[] signatureGenerationInfo = cryptoMarker.getSignatureGenerationInfo();
for (String command : signatureGenerationInfo) {
HashSet<String> signGenInfo = new HashSet<>(java.util.Arrays.asList(signatureGenerationInfo));
if (command.equals("MSE_KEY")) {
byte[] mseData = tagKeyReference.toBER();
if (signGenInfo.contains("PSO_CDS")) {
cmdAPDU = new ManageSecurityEnvironment(SET_COMPUTATION, ManageSecurityEnvironment.DST, mseData);
} else if (signGenInfo.contains("INT_AUTH") && !signGenInfo.contains("PSO_CDS")) {
cmdAPDU = new ManageSecurityEnvironment(SET_COMPUTATION, ManageSecurityEnvironment.AT, mseData);
} else {
String msg = "The command 'MSE_KEY' followed by 'INT_AUTH' and 'PSO_CDS' is currently not supported.";
LOG.error(msg);
throw new IncorrectParameterException(msg);
}
} else if (command.equals("PSO_CDS")) {
cmdAPDU = new PSOComputeDigitalSignature(message, BLOCKSIZE);
} else if (command.equals("INT_AUTH")) {
cmdAPDU = new InternalAuthenticate(message, BLOCKSIZE);
} else if (command.equals("MSE_RESTORE")) {
cmdAPDU = new ManageSecurityEnvironment.Restore(ManageSecurityEnvironment.DST);
} else if (command.equals("MSE_HASH")) {
cmdAPDU = new ManageSecurityEnvironment.Set(SET_COMPUTATION, ManageSecurityEnvironment.HT);
TLV mseDataTLV = new TLV();
mseDataTLV.setTagNumWithClass((byte) 0x80);
mseDataTLV.setValue(hashRef);
cmdAPDU.setData(mseDataTLV.toBER());
} else if (command.equals("PSO_HASH")) {
if (hashInfo == HashGenerationInfoType.LAST_ROUND_ON_CARD || hashInfo == HashGenerationInfoType.NOT_ON_CARD) {
cmdAPDU = new PSOHash(PSOHash.P2_SET_HASH_OR_PART, message);
} else {
cmdAPDU = new PSOHash(PSOHash.P2_HASH_MESSAGE, message);
}
} else if (command.equals("MSE_DS")) {
byte[] mseData = tagAlgorithmIdentifier.toBER();
cmdAPDU = new ManageSecurityEnvironment(SET_COMPUTATION, ManageSecurityEnvironment.DST, mseData);
} else if (command.equals("MSE_KEY_DS")) {
byte[] mseData = ByteUtils.concatenate(tagKeyReference.toBER(), tagAlgorithmIdentifier.toBER());
cmdAPDU = new ManageSecurityEnvironment(SET_COMPUTATION, ManageSecurityEnvironment.DST, mseData);
} else if (command.equals("MSE_INT_AUTH")) {
byte[] mseData = tagKeyReference.toBER();
cmdAPDU = new ManageSecurityEnvironment(SET_COMPUTATION, ManageSecurityEnvironment.AT, mseData);
} else if (command.equals("MSE_KEY_INT_AUTH")) {
byte[] mseData = ByteUtils.concatenate(tagKeyReference.toBER(), tagAlgorithmIdentifier.toBER());
cmdAPDU = new ManageSecurityEnvironment(SET_COMPUTATION, ManageSecurityEnvironment.AT, mseData);
} else {
String msg = "The signature generation command '" + command + "' is unknown.";
throw new IncorrectParameterException(msg);
}
responseAPDU = cmdAPDU.transmit(dispatcher, slotHandle, Collections.<byte[]>emptyList());
}
byte[] signedMessage = responseAPDU.getData();
// check if further response data is available
while (responseAPDU.getTrailer()[0] == (byte) 0x61) {
GetResponse getResponseData = new GetResponse();
responseAPDU = getResponseData.transmit(dispatcher, slotHandle, Collections.<byte[]>emptyList());
signedMessage = Arrays.concatenate(signedMessage, responseAPDU.getData());
}
if (!Arrays.areEqual(responseAPDU.getTrailer(), new byte[] { (byte) 0x90, (byte) 0x00 })) {
String minor = SALErrorUtils.getMinor(responseAPDU.getTrailer());
response.setResult(WSHelper.makeResultError(minor, responseAPDU.getStatusMessage()));
return response;
}
response.setSignature(signedMessage);
return response;
}
use of org.openecard.common.apdu.common.CardResponseAPDU in project open-ecard by ecsec.
the class SignStep method performLegacySignature.
/**
* The method performs the SignatureCreation if no standard commands are possible.
* This method creates a signature with APDUs which are not covered by the methods defined in TR-03112 part 7.
*
* @param cryptoMarker A {@link CryptoMarkerType} object containing the information about the creation of a signature
* in a legacy way.
* @param slotHandle A slotHandle identifying the current card.
* @param templateCTX A Map containing the context data for the evaluation of the template variables. This object
* contains per default the message to sign and the {@link TLVFunction}.
* @return A {@link SignResponse} object containing the signature of the <b>message</b>.
* @throws APDUTemplateException Thrown if the evaluation of the {@link CardCommandTemplate} failed.
* @throws APDUException Thrown if one of the commands to execute failed.
* @throws WSHelper.WSException Thrown if the checkResult method of WSHelper failed.
*/
private SignResponse performLegacySignature(CryptoMarkerType cryptoMarker, ConnectionHandleType connectionHandle, BaseTemplateContext templateCTX) throws APDUTemplateException, APDUException, WSHelper.WSException {
SignResponse response = WSHelper.makeResponse(SignResponse.class, WSHelper.makeResultOK());
List<Object> legacyCommands = cryptoMarker.getLegacySignatureGenerationInfo();
CardCommandAPDU cmdAPDU;
CardResponseAPDU responseAPDU = null;
byte[] slotHandle = connectionHandle.getSlotHandle();
byte[] signedMessage;
for (Object next : legacyCommands) {
if (next instanceof CardCallTemplateType) {
CardCallTemplateType cctt = (CardCallTemplateType) next;
CardCommandTemplate template = new CardCommandTemplate(cctt);
cmdAPDU = template.evaluate(templateCTX);
responseAPDU = cmdAPDU.transmit(dispatcher, slotHandle, Collections.<byte[]>emptyList());
} else if (next instanceof APICommand) {
sendAPICommand(connectionHandle, (APICommand) next);
}
}
signedMessage = responseAPDU.getData();
// check if further response data is available
while (responseAPDU.getTrailer()[0] == (byte) 0x61) {
CardCommandAPDU getResponseData = new CardCommandAPDU((byte) 0x00, (byte) 0xC0, (byte) 0x00, (byte) 0x00, responseAPDU.getTrailer()[1]);
responseAPDU = getResponseData.transmit(dispatcher, slotHandle, Collections.<byte[]>emptyList());
signedMessage = Arrays.concatenate(signedMessage, responseAPDU.getData());
}
if (!Arrays.areEqual(responseAPDU.getTrailer(), new byte[] { (byte) 0x90, (byte) 0x00 })) {
String minor = SALErrorUtils.getMinor(responseAPDU.getTrailer());
response.setResult(WSHelper.makeResultError(minor, responseAPDU.getStatusMessage()));
return response;
}
// fix output format
String outForm = cryptoMarker.getLegacyOutputFormat();
if (outForm != null) {
switch(outForm) {
case "rawRS":
signedMessage = encodeRawRS(signedMessage);
break;
default:
LOG.warn("Unsupport outputFormat={} specified in LegacySignatureGenerationInfo.", outForm);
}
}
response.setSignature(signedMessage);
return response;
}
Aggregations