use of org.openecard.common.apdu.Select in project open-ecard by ecsec.
the class TinySAL method cardApplicationConnect.
/**
* The CardApplicationConnect function establishes an unauthenticated connection between the client
* application and the card application.
* See BSI-TR-03112-4, version 1.1.2, section 3.2.1.
*
* @param request CardApplicationConnect
* @return CardApplicationConnectResponse
*/
@Override
public CardApplicationConnectResponse cardApplicationConnect(CardApplicationConnect request) {
CardApplicationConnectResponse response = WSHelper.makeResponse(CardApplicationConnectResponse.class, WSHelper.makeResultOK());
try {
CardApplicationPathType cardAppPath = request.getCardApplicationPath();
Assert.assertIncorrectParameter(cardAppPath, "The parameter CardAppPathRequest is empty.");
Set<CardStateEntry> cardStateEntrySet = states.getMatchingEntries(cardAppPath, false);
Assert.assertIncorrectParameter(cardStateEntrySet, "The given ConnectionHandle is invalid.");
/*
* [TR-03112-4] If the provided path fragments are valid for more than one card application
* the eCard-API-Framework SHALL return any of the possible choices.
*/
CardStateEntry cardStateEntry = cardStateEntrySet.iterator().next();
byte[] applicationID = cardAppPath.getCardApplication();
if (applicationID == null) {
if (cardStateEntry.getImplicitlySelectedApplicationIdentifier() != null) {
applicationID = cardStateEntry.getImplicitlySelectedApplicationIdentifier();
} else {
applicationID = MF;
}
}
Assert.securityConditionApplication(cardStateEntry, applicationID, ConnectionServiceActionName.CARD_APPLICATION_CONNECT);
// Connect to the card
ConnectionHandleType handle = cardStateEntry.handleCopy();
cardStateEntry = cardStateEntry.derive(handle);
Connect connect = new Connect();
connect.setContextHandle(handle.getContextHandle());
connect.setIFDName(handle.getIFDName());
connect.setSlot(handle.getSlotIndex());
ConnectResponse connectResponse = (ConnectResponse) env.getDispatcher().safeDeliver(connect);
WSHelper.checkResult(connectResponse);
// Select the card application
CardCommandAPDU select;
// TODO: proper determination of path, file and app id
if (applicationID.length == 2) {
select = new Select.File(applicationID);
List<byte[]> responses = new ArrayList<>();
responses.add(TrailerConstants.Success.OK());
responses.add(TrailerConstants.Error.WRONG_P1_P2());
CardResponseAPDU resp = select.transmit(env.getDispatcher(), connectResponse.getSlotHandle(), responses);
if (Arrays.equals(resp.getTrailer(), TrailerConstants.Error.WRONG_P1_P2())) {
select = new Select.AbsolutePath(applicationID);
select.transmit(env.getDispatcher(), connectResponse.getSlotHandle());
}
} else {
select = new Select.Application(applicationID);
select.transmit(env.getDispatcher(), connectResponse.getSlotHandle());
}
cardStateEntry.setCurrentCardApplication(applicationID);
cardStateEntry.setSlotHandle(connectResponse.getSlotHandle());
// reset the ef FCP
cardStateEntry.unsetFCPOfSelectedEF();
states.addEntry(cardStateEntry);
response.setConnectionHandle(cardStateEntry.handleCopy());
response.getConnectionHandle().setCardApplication(applicationID);
} catch (ECardException e) {
response.setResult(e.getResult());
}
return response;
}
use of org.openecard.common.apdu.Select 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.Select in project open-ecard by ecsec.
the class CardUtils method selectApplicationByAID.
/**
* Select an application by the application identifier.
* This method requests the FCP of the application.
*
* @param dispatcher
* @param slotHandle
* @param aid Application identifier
* @return Response APDU of the select command.
* @throws APDUException Thrown in case there was an error while processing the command APDU.
*/
public static CardResponseAPDU selectApplicationByAID(Dispatcher dispatcher, byte[] slotHandle, byte[] aid) throws APDUException {
Select selectApp = new Select((byte) 0x04, (byte) 0x04);
selectApp.setData(aid);
selectApp.setLE((byte) 0xFF);
CardResponseAPDU result = selectApp.transmit(dispatcher, slotHandle);
return result;
}
use of org.openecard.common.apdu.Select in project open-ecard by ecsec.
the class CardUtils method selectApplicationByFID.
/**
* Select an application by it's file identifier.
*
* @param dispatcher The message dispatcher for the interaction with the card.
* @param slotHandle
* @param fileID File identitfier of an application or a path to the application.
* @return The {@link CardResponseAPDU} from the last select which means the select of the application to select.
* @throws APDUException
*/
public static CardResponseAPDU selectApplicationByFID(Dispatcher dispatcher, byte[] slotHandle, byte[] fileID) throws APDUException {
Select selectApp;
CardResponseAPDU result = null;
// respect the possibility that fileID could be a path
int i = 0;
while (i < fileID.length) {
if (fileID[i] == (byte) 0x3F && fileID[i + 1] == (byte) 0x00 && i == 0 && i + 1 == 1) {
selectApp = new MasterFile();
i = i + 2;
} else {
selectApp = new Select.ChildDirectory(new byte[] { fileID[i], fileID[i + 1] });
selectApp.setLE((byte) 0xFF);
selectApp.setFCP();
i = i + 2;
}
result = selectApp.transmit(dispatcher, slotHandle);
}
return result;
}
use of org.openecard.common.apdu.Select in project open-ecard by ecsec.
the class TinySAL method cardApplicationSelect.
@Override
public CardApplicationSelectResponse cardApplicationSelect(CardApplicationSelect request) {
CardApplicationSelectResponse response = WSHelper.makeResponse(CardApplicationSelectResponse.class, WSHelper.makeResultOK());
try {
byte[] slotHandle = request.getSlotHandle();
ConnectionHandleType connectionHandle = SALUtils.createConnectionHandle(slotHandle);
CardStateEntry cardStateEntry = SALUtils.getCardStateEntry(states, connectionHandle);
byte[] reqApplicationID = request.getCardApplication();
Assert.assertIncorrectParameter(reqApplicationID, "The parameter CardApplication is empty.");
CardInfoWrapper cardInfoWrapper = cardStateEntry.getInfo();
CardApplicationWrapper appInfo = cardInfoWrapper.getCardApplication(reqApplicationID);
Assert.assertNamedEntityNotFound(appInfo, "The given Application cannot be found.");
Assert.securityConditionApplication(cardStateEntry, reqApplicationID, ConnectionServiceActionName.CARD_APPLICATION_CONNECT);
// check if the currently selected application is already what the caller wants
byte[] curApplicationID = cardStateEntry.getCurrentCardApplication().getApplicationIdentifier();
if (!ByteUtils.compare(reqApplicationID, curApplicationID)) {
// Select the card application
CardCommandAPDU select;
// TODO: proper determination of path, file and app id
if (reqApplicationID.length == 2) {
select = new Select.File(reqApplicationID);
List<byte[]> responses = new ArrayList<>();
responses.add(TrailerConstants.Success.OK());
responses.add(TrailerConstants.Error.WRONG_P1_P2());
CardResponseAPDU resp = select.transmit(env.getDispatcher(), slotHandle, responses);
if (Arrays.equals(resp.getTrailer(), TrailerConstants.Error.WRONG_P1_P2())) {
select = new Select.AbsolutePath(reqApplicationID);
select.transmit(env.getDispatcher(), slotHandle);
}
} else {
select = new Select.Application(reqApplicationID);
select.transmit(env.getDispatcher(), slotHandle);
}
cardStateEntry.setCurrentCardApplication(reqApplicationID);
// reset the ef FCP
cardStateEntry.unsetFCPOfSelectedEF();
}
response.setConnectionHandle(cardStateEntry.handleCopy());
} catch (ECardException e) {
response.setResult(e.getResult());
}
return response;
}
Aggregations