use of org.openecard.common.apdu.exception.APDUException 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.exception.APDUException in project open-ecard by ecsec.
the class PACEImplementation method generalAuthenticateMapNonce.
/**
* Step 3: Mapping nonce
*/
private void generalAuthenticateMapNonce() throws Exception {
byte[] pkMapPCD = null;
PACEMapping mapping = cryptoSuite.getMapping();
if (mapping instanceof PACEGenericMapping) {
PACEGenericMapping gm = (PACEGenericMapping) mapping;
pkMapPCD = gm.getMappingKey().getEncodedPublicKey();
} else if (mapping instanceof PACEIntegratedMapping) {
throw new UnsupportedOperationException("Not implemented yet.");
}
CardCommandAPDU gaMapNonce = new GeneralAuthenticate((byte) 0x81, pkMapPCD);
gaMapNonce.setChaining();
try {
response = gaMapNonce.transmit(dispatcher, slotHandle);
} catch (APDUException e) {
LOG.error(e.getMessage(), e);
throw new ProtocolException(e.getResult());
}
if (mapping instanceof PACEGenericMapping) {
PACEGenericMapping gm = (PACEGenericMapping) mapping;
PACEKey keyMapPICC = new PACEKey(domainParameter);
keyMapPICC.decodePublicKey(response.getData());
byte[] pkMapPICC = keyMapPICC.getEncodedPublicKey();
if (ByteUtils.compare(pkMapPICC, pkMapPCD)) {
throw new GeneralSecurityException("PACE security violation: equal keys");
}
domainParameter = gm.map(pkMapPICC, s);
} else if (mapping instanceof PACEIntegratedMapping) {
throw new UnsupportedOperationException("Not implemented yet.");
}
// Continue with Step 4
generalAuthenticateKeyAgreement();
}
use of org.openecard.common.apdu.exception.APDUException in project open-ecard by ecsec.
the class PACEImplementation method generalAuthenticateEncryptedNonce.
/**
* Step 2: Encrypted nonce
*/
private void generalAuthenticateEncryptedNonce() throws Exception {
CardCommandAPDU gaEncryptedNonce = new GeneralAuthenticate();
gaEncryptedNonce.setChaining();
// Derive key PI
byte[] keyPI = kdf.derivePI(password);
try {
response = gaEncryptedNonce.transmit(dispatcher, slotHandle);
s = cryptoSuite.decryptNonce(keyPI, response.getData());
// Continue with Step 3
generalAuthenticateMapNonce();
} catch (APDUException e) {
LOG.error(e.getMessage(), e);
throw new ProtocolException(e.getResult());
} catch (GeneralSecurityException e) {
LOG.error(e.getMessage(), e);
throw new ProtocolException(e.getMessage());
}
}
use of org.openecard.common.apdu.exception.APDUException in project open-ecard by ecsec.
the class PACEImplementation method generalAuthenticateKeyAgreement.
/**
* Step 4: Key agreement
*
* @param mapPK_PICC
*/
private void generalAuthenticateKeyAgreement() throws Exception {
keyPCD = new PACEKey(domainParameter);
keyPCD.generateKeyPair();
byte[] keyPKPCD = keyPCD.getEncodedPublicKey();
CardCommandAPDU gaKeyAgreement = new GeneralAuthenticate((byte) 0x83, keyPKPCD);
gaKeyAgreement.setChaining();
try {
response = gaKeyAgreement.transmit(dispatcher, slotHandle);
keyPICC = new PACEKey(domainParameter);
byte[] keyPKPICC = keyPICC.decodePublicKey(response.getData());
if (!ByteUtils.compare(keyPKPCD, keyPKPICC)) {
// Continue with Step 5
generalAuthenticateMutualAuthentication();
} else {
throw new GeneralSecurityException("PACE security violation: equal keys");
}
} catch (APDUException e) {
LOG.error(e.getMessage(), e);
throw new ProtocolException(e.getResult());
} catch (GeneralSecurityException e) {
LOG.error(e.getMessage(), e);
throw new ProtocolException(e.getMessage());
}
}
use of org.openecard.common.apdu.exception.APDUException in project open-ecard by ecsec.
the class GenericPINAction method performUnblockPIN.
private StepActionResult performUnblockPIN(Map<String, ExecutionResults> oldResults) {
try {
EstablishChannelResponse pukResponse = performPACEWithPUK(oldResults);
if (pukResponse == null) {
gPINStep.setWrongPUKFormat(true);
gPINStep.setFailedPUKVerify(false);
// to reset the text fields
gPINStep.updateState(state);
return new StepActionResult(StepActionResultStatus.REPEAT);
}
if (pukResponse.getResult().getResultMajor().equals(ECardConstants.Major.ERROR)) {
if (pukResponse.getResult().getResultMinor().equals(ECardConstants.Minor.IFD.AUTHENTICATION_FAILED)) {
// i think we should not display the counter
// gPINStep.decreasePUKCounter();
gPINStep.setWrongPUKFormat(false);
gPINStep.setFailedPUKVerify(true);
// to reset the text fields
gPINStep.updateState(state);
return new StepActionResult(StepActionResultStatus.REPEAT);
} else {
WSHelper.checkResult(pukResponse);
}
}
// Here no exception is thrown so sent the ResetRetryCounter command
ResetRetryCounter resetRetryCounter = new ResetRetryCounter((byte) 0x03);
List<byte[]> responses = new ArrayList<>();
responses.add(new byte[] { (byte) 0x90, (byte) 0x00 });
responses.add(new byte[] { (byte) 0x69, (byte) 0x84 });
CardResponseAPDU resetCounterResponse = resetRetryCounter.transmit(dispatcher, slotHandle, responses);
if (Arrays.equals(resetCounterResponse.getTrailer(), new byte[] { (byte) 0x69, (byte) 0x84 })) {
gPINStep.updateState(RecognizedState.PUK_blocked);
return new StepActionResult(StepActionResultStatus.REPEAT);
} else if (Arrays.equals(resetCounterResponse.getTrailer(), new byte[] { (byte) 0x90, (byte) 0x00 })) {
gPINStep.updateState(RecognizedState.PIN_activated_RC3);
return new StepActionResult(StepActionResultStatus.REPEAT, generateSuccessStep(lang.translationForKey(PUK_SUCCESS)));
} else {
gPINStep.updateState(RecognizedState.UNKNOWN);
return new StepActionResult(StepActionResultStatus.REPEAT);
}
} catch (APDUException | ParserConfigurationException ex) {
LOG.error("An internal error occurred while trying to unblock the PIN.", ex);
return new StepActionResult(StepActionResultStatus.REPEAT, generateErrorStep(lang.translationForKey(ERROR_INTERNAL)));
} catch (WSHelper.WSException ex) {
// This is for PIN Pad Readers in case the user pressed the cancel button on the reader.
if (ex.getResultMinor().equals(ECardConstants.Minor.IFD.CANCELLATION_BY_USER)) {
LOG.error("User canceled the authentication manually or removed the card.", ex);
return new StepActionResult(StepActionResultStatus.REPEAT, generateErrorStep(lang.translationForKey(ERROR_USER_CANCELLATION_OR_CARD_REMOVED)));
}
// for users which forgot to type in something
if (ex.getResultMinor().equals(ECardConstants.Minor.IFD.TIMEOUT_ERROR)) {
LOG.error("The terminal timed out no password was entered.", ex);
return new StepActionResult(StepActionResultStatus.REPEAT, generateErrorStep(lang.translationForKey(ERROR_TIMEOUT)));
}
// for people which think they have to remove the card in the process
if (ex.getResultMinor().equals(ECardConstants.Minor.IFD.INVALID_SLOT_HANDLE)) {
LOG.error("The SlotHandle was invalid so probably the user removed the card or an reset occurred.", ex);
return new StepActionResult(StepActionResultStatus.REPEAT, generateErrorStep(lang.translationForKey(ERROR_CARD_REMOVED)));
}
// We don't know what happend so just show an general error message
LOG.error("An unknown error occurred while trying to verify the PUK.", ex);
return new StepActionResult(StepActionResultStatus.REPEAT, generateErrorStep(lang.translationForKey(ERROR_UNKNOWN)));
} finally {
// destroy the pace channel
DestroyChannel destChannel = new DestroyChannel();
destChannel.setSlotHandle(slotHandle);
dispatcher.safeDeliver(destChannel);
// For readers which do not support DestroyChannel but have generic pace support
Disconnect disconnect = new Disconnect();
disconnect.setSlotHandle(slotHandle);
disconnect.setAction(ActionType.RESET);
dispatcher.safeDeliver(disconnect);
}
}
Aggregations