use of org.openecard.common.apdu.exception.APDUException in project open-ecard by ecsec.
the class PACEImplementation method mseSetAT.
/**
* Initialize Chip Authentication. Sends an MSE:Set AT APDU. (S
* Step 1: Initialise PACE.
* See BSI-TR-03110, version 2.10, part 3, B.11.1.
*/
private void mseSetAT(byte passwordID, byte[] chat) throws Exception {
byte[] oID = ObjectIdentifierUtils.getValue(psip.getPACEInfo().getProtocol());
CardCommandAPDU mseSetAT = new MSESetATPACE(oID, passwordID, psip.getPACEInfo().getParameterID(), chat);
try {
response = mseSetAT.transmit(dispatcher, slotHandle);
// Continue with step 2
generalAuthenticateEncryptedNonce();
} catch (APDUException e) {
if (e.getResponseAPDU() == null) {
if (e.getCause() instanceof Exception) {
throw (Exception) e.getCause();
} else {
throw new ProtocolException(ECardConstants.Minor.IFD.UNKNOWN_ERROR, e.getMessage());
}
}
LOG.error(e.getMessage(), e);
short sw = e.getResponseAPDU().getSW();
if (sw == PACEConstants.PASSWORD_DEACTIVATED) {
// Password is deactivated
throw new ProtocolException(ECardConstants.Minor.IFD.PASSWORD_DEACTIVATED);
} else if ((sw & (short) 0xFFF0) == (short) 0x63C0) {
retryCounter = (byte) (sw & (short) 0x000F);
if (retryCounter == (byte) 0x00) {
// The password is blocked
LOG.warn("The password is blocked. The password MUST be unblocked.");
if (passwordID == PACEConstants.PASSWORD_PUK) {
generalAuthenticateEncryptedNonce();
} else {
throw new ProtocolException(ECardConstants.Minor.IFD.PASSWORD_BLOCKED, "The password is blocked. The password MUST be unblocked.");
}
} else if (retryCounter == (byte) 0x01) {
// The password is suspended
LOG.warn("The password is suspended. The password MUST be resumed.");
// TODO check for an existing SM-Channel with the CAN
// if (mseSetAT.isSecureMessaging()) {
generalAuthenticateEncryptedNonce();
/*} else {
throw new ProtocolException(
ECardConstants.Minor.IFD.PASSWORD_SUSPENDED,
"The password is suspended. The password MUST be resumed.");
}*/
} else if (retryCounter == (byte) 0x02) {
// The password is suspended
LOG.warn("The password is wrong.");
generalAuthenticateEncryptedNonce();
}
}
} catch (ProtocolException e) {
LOG.error(e.getMessage(), e);
throw e;
} catch (Exception e) {
LOG.error(e.getMessage(), e);
throw new ProtocolException(ECardConstants.Minor.IFD.UNKNOWN_ERROR, e.getMessage());
}
}
use of org.openecard.common.apdu.exception.APDUException in project open-ecard by ecsec.
the class PACEImplementation method generalAuthenticateMutualAuthentication.
/**
* Step 5: Mutual authentication
*/
private void generalAuthenticateMutualAuthentication() throws Exception {
// Calculate shared key k
byte[] k = cryptoSuite.generateSharedSecret(keyPCD.getEncodedPrivateKey(), keyPICC.getEncodedPublicKey());
// Derive key MAC
keyMAC = kdf.deriveMAC(k);
// Derive key ENC
keyENC = kdf.deriveENC(k);
// Calculate token T_PCD
AuthenticationToken tokenPCD = new AuthenticationToken(psip.getPACEInfo());
tokenPCD.generateToken(keyMAC, keyPICC.getEncodedPublicKey());
CardCommandAPDU gaMutualAuth = new GeneralAuthenticate((byte) 0x85, tokenPCD.toByteArray());
// Calculate token T_PICC
AuthenticationToken tokenPICC = new AuthenticationToken(psip.getPACEInfo());
tokenPICC.generateToken(keyMAC, keyPCD.getEncodedPublicKey());
try {
response = gaMutualAuth.transmit(dispatcher, slotHandle);
if (tokenPICC.verifyToken(response.getData(), specifiedCHAT)) {
currentCAR = tokenPICC.getCurrentCAR();
previousCAR = tokenPICC.getPreviousCAR();
} else {
throw new GeneralSecurityException("Cannot verify authentication token.");
}
} catch (APDUException e) {
if (e.getResponseAPDU() == null) {
if (e.getCause() instanceof Exception) {
throw (Exception) e.getCause();
} else {
throw new ProtocolException(ECardConstants.Minor.IFD.UNKNOWN_ERROR, e.getMessage());
}
}
LOG.error(e.getMessage(), e);
int sw = e.getResponseAPDU().getSW();
if ((sw & (short) 0xFFF0) == (short) 0x63C0) {
retryCounter = (byte) (sw & (short) 0x000F);
if (retryCounter == (byte) 0x00) {
// The password is blocked.
LOG.warn("The password is blocked. The password MUST be unblocked.");
throw new ProtocolException(ECardConstants.Minor.IFD.PASSWORD_BLOCKED, "The password is blocked. The password MUST be unblocked.");
} else if (retryCounter == (byte) 0x01) {
// The password is suspended.
LOG.warn("The password is suspended. The password MUST be resumed.");
throw new ProtocolException(ECardConstants.Minor.IFD.PASSWORD_SUSPENDED, "The password is suspended. The password MUST be resumed.");
} else if (retryCounter == (byte) 0x02) {
// The password is wrong.
LOG.warn("The password is wrong.");
throw new ProtocolException(ECardConstants.Minor.IFD.PASSWORD_ERROR, "The password is wrong.");
}
} else {
throw new ProtocolException(ECardConstants.Minor.IFD.AUTHENTICATION_FAILED, "Authentication failed.");
}
} catch (Exception e) {
LOG.error(e.getMessage(), e);
throw new ProtocolException(ECardConstants.Minor.IFD.UNKNOWN_ERROR, e.getMessage());
}
}
use of org.openecard.common.apdu.exception.APDUException in project open-ecard by ecsec.
the class TerminalAuthentication method mseSetAT.
/**
* Initializes the Terminal Authentication protocol.
* Sends an MSE:Set AT APDU. (Protocol step 2)
* See BSI-TR-03110, version 2.10, part 3, B.11.1.
*
* @param oID Terminal Authentication object identifier
* @param chr Certificate Holder Reference (CHR)
* @param key Ephemeral public key
* @param aad Authenticated Auxiliary Data (AAD)
* @throws ProtocolException
*/
public void mseSetAT(byte[] oID, byte[] chr, byte[] key, byte[] aad) throws ProtocolException {
try {
CardCommandAPDU mseSetAT = new MSESetATTA(oID, chr, key, aad);
mseSetAT.transmit(dispatcher, slotHandle);
} catch (APDUException e) {
throw new ProtocolException(e.getResult());
}
}
use of org.openecard.common.apdu.exception.APDUException in project open-ecard by ecsec.
the class TerminalAuthentication method verifyCertificates.
/**
* Verify certificates.
* Sends an MSE:Set DST APDU and PSO:Verify Certificate APDU per certificate. (Protocol step 1)
* See BSI-TR-03110, version 2.10, part 3, B.11.4.
* See BSI-TR-03110, version 2.10, part 3, B.11.5.
*
* @param certificateChain Certificate chain
* @throws ProtocolException
*/
public void verifyCertificates(CardVerifiableCertificateChain certificateChain) throws ProtocolException {
try {
for (CardVerifiableCertificate cvc : certificateChain.getCertificates()) {
// MSE:SetDST APDU
CardCommandAPDU mseSetDST = new MSESetDST(cvc.getCAR().toByteArray());
mseSetDST.transmit(dispatcher, slotHandle);
// PSO:Verify Certificate APDU
CardCommandAPDU psovc = new PSOVerifyCertificate(cvc.getCertificate().getValue());
psovc.transmit(dispatcher, slotHandle);
}
} catch (APDUException e) {
throw new ProtocolException(e.getResult());
}
}
use of org.openecard.common.apdu.exception.APDUException in project open-ecard by ecsec.
the class GenericPINAction method performPINChange.
private StepActionResult performPINChange(Map<String, ExecutionResults> oldResults) {
String newPINValue = null;
String newPINRepeatValue = null;
if (capturePin) {
try {
ExecutionResults executionResults = oldResults.get(getStepID());
PasswordField newPINField = (PasswordField) executionResults.getResult(GenericPINStep.NEW_PIN_FIELD);
newPINValue = new String(newPINField.getValue());
PasswordField newPINRepeatField = (PasswordField) executionResults.getResult(GenericPINStep.NEW_PIN_REPEAT_FIELD);
newPINRepeatValue = new String(newPINRepeatField.getValue());
byte[] pin1 = newPINValue.getBytes(ISO_8859_1);
byte[] pin2 = newPINRepeatValue.getBytes(ISO_8859_1);
if (!ByteUtils.compare(pin1, pin2)) {
LOG.warn("New PIN does not match the value from the confirmation field.");
// to reset the text fields
gPINStep.updateState(state);
return new StepActionResult(StepActionResultStatus.REPEAT);
}
} catch (UnsupportedEncodingException ex) {
LOG.error("ISO_8859_1 charset is not support.", ex);
// to reset the text fields
gPINStep.updateState(state);
return new StepActionResult(StepActionResultStatus.REPEAT);
}
}
try {
EstablishChannelResponse pinResponse = performPACEWithPIN(oldResults);
if (pinResponse == null) {
// the entered pin has a wrong format repeat the entering of the data
gPINStep.setFailedPINVerify(false);
gPINStep.setWrongPINFormat(true);
return new StepActionResult(StepActionResultStatus.REPEAT);
}
if (pinResponse.getResult().getResultMajor().equals(ECardConstants.Major.ERROR)) {
switch(pinResponse.getResult().getResultMinor()) {
case ECardConstants.Minor.IFD.PASSWORD_ERROR:
gPINStep.setFailedPINVerify(true);
gPINStep.setWrongPINFormat(false);
gPINStep.updateState(RecognizedState.PIN_activated_RC2);
state = RecognizedState.PIN_activated_RC2;
return new StepActionResult(StepActionResultStatus.REPEAT);
case ECardConstants.Minor.IFD.PASSWORD_SUSPENDED:
gPINStep.setFailedPINVerify(true);
gPINStep.setWrongPINFormat(false);
gPINStep.updateState(RecognizedState.PIN_suspended);
state = RecognizedState.PIN_suspended;
return new StepActionResult(StepActionResultStatus.REPEAT);
case ECardConstants.Minor.IFD.PASSWORD_BLOCKED:
gPINStep.setFailedPINVerify(true);
gPINStep.setWrongPINFormat(false);
gPINStep.updateState(RecognizedState.PIN_blocked);
state = RecognizedState.PIN_blocked;
return new StepActionResult(StepActionResultStatus.REPEAT);
default:
WSHelper.checkResult(pinResponse);
break;
}
}
if (capturePin) {
if (newPINValue.equals(newPINRepeatValue) && newPINValue.length() == 6) {
// no result check necessary everything except a 9000 leads to an APDU exception
sendResetRetryCounter(newPINValue.getBytes(ISO_8859_1));
}
} else {
ControlIFDResponse resp = sendModifyPIN();
evaluateControlIFDResponse(resp);
}
// PIN modified successfully, proceed with next step
return new StepActionResult(StepActionResultStatus.REPEAT, generateSuccessStep(lang.translationForKey(CHANGE_SUCCESS)));
} catch (APDUException | IFDException | ParserConfigurationException ex) {
LOG.error("An internal error occurred while trying to change the PIN", ex);
return new StepActionResult(StepActionResultStatus.REPEAT, generateErrorStep(lang.translationForKey(ERROR_INTERNAL)));
} catch (UnsupportedEncodingException ex) {
LOG.warn("The encoding of the PIN is wrong.", ex);
return new StepActionResult(StepActionResultStatus.REPEAT);
} 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 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)));
}
// 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)));
}
// the verification of the new pin failed
if (ex.getResultMinor().equals(ECardConstants.Minor.IFD.PASSWORDS_DONT_MATCH)) {
LOG.error("The verification of the new PIN failed.", ex);
return new StepActionResult(StepActionResultStatus.REPEAT, generateErrorStep(lang.translationForKey(ERROR_NON_MATCHING_PASSWORDS)));
}
// We don't know what happend so just show an general error message
LOG.error("An unknown error occurred while trying to change the PIN.", 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);
// Transaction based communication does not work on java 8 so the PACE channel is not closed after an
// EndTransaction call. So do a reset of the card to close the PACE channel.
Disconnect disconnect = new Disconnect();
disconnect.setSlotHandle(slotHandle);
disconnect.setAction(ActionType.RESET);
dispatcher.safeDeliver(disconnect);
}
}
Aggregations