use of org.openecard.ifd.scio.IFDException in project open-ecard by ecsec.
the class PCSCPinVerify method prepareStructure.
private void prepareStructure(PasswordAttributesType attributes, byte[] cmdTemplate) throws IFDException {
// get apdu and pin template
byte[] pinTemplate;
try {
pinTemplate = PINUtils.createPinMask(attributes);
} catch (UtilException e) {
IFDException ex = new IFDException(e);
throw ex;
}
byte[] template = cmdTemplate;
if (pinTemplate.length > 0) {
template = ByteUtils.concatenate(cmdTemplate, (byte) pinTemplate.length);
template = ByteUtils.concatenate(template, pinTemplate);
}
setData(template);
boolean nibbleHandling = pwdType == PasswordTypeType.BCD || pwdType == PasswordTypeType.ISO_9564_1;
boolean isoPin = pwdType == PasswordTypeType.ISO_9564_1;
// pointer to byte containing pin length in iso encoding
int pinLenIdx = template.length;
int pinPos = isoPin ? pinLenIdx + 1 : pinLenIdx;
// prepare bmFormatString
// bytes
byte bmSysUnits = 1;
byte bmPinPos = (byte) (isoPin ? 1 : 0);
// left
byte bmJustify = 0;
// binary
byte bmPinType = 0;
if (nibbleHandling) {
bmPinType = 1;
} else if (pwdType == PasswordTypeType.ASCII_NUMERIC || pwdType == PasswordTypeType.UTF_8) {
bmPinType = 2;
}
this.bmFormatString = (byte) ((bmSysUnits << 7) | (bmPinPos << 3) | (bmJustify << 2) | bmPinType);
// prepare pin block string
// number of bits of the length field
byte bmPinManagement = (byte) (isoPin ? 4 : 0);
byte pinSize = (byte) (isoPin ? storedLen - 1 : storedLen);
this.bmPINBlockString = (byte) ((bmPinManagement << 4) | pinSize);
// pin length format
// bits
byte bmPinLengthUnit = 0;
byte bmPinBytePos = (byte) (isoPin ? 4 : 0);
bmPINLengthFormat = (byte) ((bmPinLengthUnit << 4) | bmPinBytePos);
setMinPINSize((byte) minLen);
setMaxPINSize((byte) maxLen);
}
use of org.openecard.ifd.scio.IFDException 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);
}
}
use of org.openecard.ifd.scio.IFDException in project open-ecard by ecsec.
the class PCSCPinModify method prepareStructure.
private void prepareStructure(PasswordAttributesType attributes, byte[] cmdTemplate) throws IFDException {
// get apdu and pin template
byte[] pinTemplate;
try {
pinTemplate = PINUtils.createPinMask(attributes);
} catch (UtilException e) {
IFDException ex = new IFDException(e);
throw ex;
}
byte[] template = cmdTemplate;
if (pinTemplate.length > 0) {
template = ByteUtils.concatenate(cmdTemplate, (byte) pinTemplate.length);
template = ByteUtils.concatenate(template, pinTemplate);
}
setData(template);
boolean nibbleHandling = pwdType == PasswordTypeType.BCD || pwdType == PasswordTypeType.ISO_9564_1;
boolean isoPin = pwdType == PasswordTypeType.ISO_9564_1;
// pointer to byte containing pin length in iso encoding
int pinLenIdx = template.length;
int pinPos = isoPin ? pinLenIdx + 1 : pinLenIdx;
// prepare bmFormatString
// bytes
byte bmSysUnits = 1;
byte bmPinPos = (byte) (isoPin ? 1 : 0);
// left
byte bmJustify = 0;
// binary
byte bmPinType = 0;
if (nibbleHandling) {
bmPinType = 1;
} else if (pwdType == PasswordTypeType.ASCII_NUMERIC) {
bmPinType = 2;
}
this.bmFormatString = (byte) ((bmSysUnits << 7) | (bmPinPos << 3) | (bmJustify << 2) | bmPinType);
// prepare pin block string
// number of bits of the length field
byte bmPinManagement = (byte) (isoPin ? 4 : 0);
byte pinSize = (byte) (isoPin ? storedLen - 1 : storedLen);
this.bmPINBlockString = (byte) ((bmPinManagement << 4) | pinSize);
// pin length format
// bits
byte bmPinLengthUnit = 0;
byte bmPinBytePos = (byte) (isoPin ? 4 : 0);
bmPINLengthFormat = (byte) ((bmPinLengthUnit << 4) | bmPinBytePos);
setMinPINSize((byte) minLen);
setMaxPINSize((byte) maxLen);
}
use of org.openecard.ifd.scio.IFDException in project open-ecard by ecsec.
the class OpeneCardContext method initialize.
// /
// / Initialization & Shutdown
// /
void initialize() throws UnableToInitialize, NfcUnavailable, NfcDisabled, ApduExtLengthNotSupported {
String errorMsg = SERVICE_RESPONSE_FAILED;
if (initialized) {
throw new UnableToInitialize(SERVICE_ALREADY_INITIALIZED);
}
if (appCtx == null) {
throw new IllegalStateException(NO_APPLICATION_CONTEXT);
}
// initialize gui
eacNavFac = new EacNavigatorFactory();
List<UserConsentNavigatorFactory<?>> factories = Arrays.asList(eacNavFac, new InsertCardNavigatorFactory());
gui = new AndroidUserConsent(factories);
// set up nfc and android marshaller
IFDProperties.setProperty(IFD_FACTORY_KEY, IFD_FACTORY_VALUE);
WsdefProperties.setProperty(WSDEF_MARSHALLER_KEY, WSDEF_MARSHALLER_VALUE);
NFCFactory.setContext(appCtx);
try {
boolean nfcAvailable = NFCFactory.isNFCAvailable();
boolean nfcEnabled = NFCFactory.isNFCEnabled();
boolean nfcExtendedLengthSupport = NfcUtils.supportsExtendedLength(appCtx);
if (!nfcAvailable) {
throw new NfcUnavailable();
} else if (!nfcEnabled) {
throw new NfcDisabled();
} else if (!nfcExtendedLengthSupport) {
throw new ApduExtLengthNotSupported(NFC_NO_EXTENDED_LENGTH_SUPPORT);
}
terminalFactory = IFDTerminalFactory.getInstance();
LOG.info("Terminal factory initialized.");
} catch (IFDException ex) {
errorMsg = UNABLE_TO_INITIALIZE_TF;
throw new UnableToInitialize(errorMsg, ex);
}
try {
// set up client environment
env = new ClientEnv();
// set up dispatcher
dispatcher = new MessageDispatcher(env);
env.setDispatcher(dispatcher);
LOG.info("Message Dispatcher initialized.");
// set up management
management = new TinyManagement(env);
env.setManagement(management);
LOG.info("Management initialized.");
// set up event dispatcher
eventDispatcher = new EventDispatcherImpl();
env.setEventDispatcher(eventDispatcher);
LOG.info("Event Dispatcher initialized.");
// set up SALStateCallback
cardStates = new CardStateMap();
SALStateCallback salCallback = new SALStateCallback(env, cardStates);
eventDispatcher.add(salCallback);
// set up ifd
ifd = new IFD();
ifd.addProtocol(ECardConstants.Protocol.PACE, new PACEProtocolFactory());
ifd.setGUI(gui);
ifd.setEnvironment(env);
env.setIFD(ifd);
LOG.info("IFD initialized.");
// set up card recognition
try {
recognition = new CardRecognitionImpl(env);
recognition.setGUI(gui);
env.setRecognition(recognition);
LOG.info("CardRecognition initialized.");
} catch (Exception ex) {
errorMsg = CARD_REC_INIT_FAILED;
throw ex;
}
// set up SAL
TinySAL mainSAL = new TinySAL(env, cardStates);
mainSAL.setGUI(gui);
sal = new SelectorSAL(mainSAL, env);
env.setSAL(sal);
env.setCIFProvider(sal);
LOG.info("SAL initialized.");
ViewController viewController = new ViewController() {
@Override
public void showSettingsUI() {
}
@Override
public void showDefaultViewUI() {
}
};
// set up addon manager
try {
manager = new AddonManager(env, gui, cardStates, viewController, new ClasspathRegistry());
mainSAL.setAddonManager(manager);
} catch (Exception ex) {
errorMsg = ADD_ON_INIT_FAILED;
throw ex;
}
// Initialize the Event Dispatcher
eventDispatcher.add(this, EventType.TERMINAL_ADDED, EventType.TERMINAL_REMOVED, EventType.CARD_INSERTED, EventType.CARD_RECOGNIZED, EventType.CARD_REMOVED);
// start event dispatcher
eventDispatcher.start();
LOG.info("Event dispatcher started.");
// initialize SAL
try {
WSHelper.checkResult(sal.initialize(new Initialize()));
} catch (WSHelper.WSException ex) {
errorMsg = ex.getMessage();
throw ex;
}
// establish context
try {
EstablishContext establishContext = new EstablishContext();
EstablishContextResponse establishContextResponse = ifd.establishContext(establishContext);
WSHelper.checkResult(establishContextResponse);
contextHandle = establishContextResponse.getContextHandle();
LOG.info("ContextHandle: {}", ByteUtils.toHexString(contextHandle));
} catch (WSHelper.WSException ex) {
errorMsg = ESTABLISH_IFD_CONTEXT_FAILED;
throw ex;
}
initialized = true;
} catch (Exception ex) {
LOG.error(errorMsg, ex);
throw new UnableToInitialize(errorMsg, ex);
}
}
use of org.openecard.ifd.scio.IFDException in project open-ecard by ecsec.
the class PINStepAction method perform.
@Override
public StepActionResult perform(Map<String, ExecutionResults> oldResults, StepResult result) {
if (result.isBack()) {
return new StepActionResult(StepActionResultStatus.BACK);
}
DIDAuthenticationDataType paceInput = new DIDAuthenticationDataType();
paceInput.setProtocol(ECardConstants.Protocol.PACE);
AuthDataMap tmp;
try {
tmp = new AuthDataMap(paceInput);
} catch (ParserConfigurationException ex) {
LOG.error("Failed to read empty Protocol data.", ex);
return new StepActionResult(StepActionResultStatus.CANCEL);
}
AuthDataResponse paceInputMap = tmp.createResponse(paceInput);
if (capturePin) {
ExecutionResults executionResults = oldResults.get(getStepID());
if (!verifyUserInput(executionResults)) {
// let the user enter the pin again, when input verification failed
return new StepActionResult(StepActionResultStatus.REPEAT, createPINReplacementStep(false, true));
} else {
paceInputMap.addElement(PACEInputType.PIN, oldPIN);
}
}
paceInputMap.addElement(PACEInputType.PIN_ID, PIN_ID_PIN);
// perform PACE by EstablishChannel
EstablishChannel establishChannel = new EstablishChannel();
establishChannel.setSlotHandle(conHandle.getSlotHandle());
establishChannel.setAuthenticationProtocolData(paceInputMap.getResponse());
establishChannel.getAuthenticationProtocolData().setProtocol(ECardConstants.Protocol.PACE);
try {
EstablishChannelResponse establishChannelResponse = (EstablishChannelResponse) dispatcher.safeDeliver(establishChannel);
WSHelper.checkResult(establishChannelResponse);
// PACE completed successfully, we now modify the pin
if (capturePin) {
sendResetRetryCounter();
} else {
sendModifyPIN();
}
// PIN modified successfully, proceed with next step
return new StepActionResult(StepActionResultStatus.NEXT);
} catch (WSException ex) {
if (capturePin) {
retryCounter--;
LOG.info("Wrong PIN entered, trying again (remaining tries {}).", retryCounter);
if (retryCounter == 1) {
Step replacementStep = createCANReplacementStep();
return new StepActionResult(StepActionResultStatus.BACK, replacementStep);
} else {
Step replacementStep = createPINReplacementStep(true, false);
return new StepActionResult(StepActionResultStatus.REPEAT, replacementStep);
}
} else {
LOG.warn("PIN not entered successfully in terminal.");
return new StepActionResult(StepActionResultStatus.CANCEL);
}
} catch (APDUException ex) {
LOG.error("Failed to transmit Reset Retry Counter APDU.", ex);
return new StepActionResult(StepActionResultStatus.CANCEL);
} catch (IllegalArgumentException ex) {
LOG.error("Failed to transmit Reset Retry Counter APDU.", ex);
return new StepActionResult(StepActionResultStatus.CANCEL);
} catch (IFDException ex) {
LOG.error("Failed to transmit Reset Retry Counter APDU.", ex);
return new StepActionResult(StepActionResultStatus.CANCEL);
}
}
Aggregations