summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java3
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/ManagementPINProviderFactory.java230
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PINManagementRequestHandler.java43
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PinpadPINProviderFactory.java133
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/SoftwarePINProviderFactory.java148
-rw-r--r--BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties5
-rw-r--r--BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties3
-rw-r--r--nbactions.xml13
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java34
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java16
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/PINConfirmationException.java43
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/PINFormatException.java43
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/PINOperationAbortedException.java43
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java59
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/SWCard.java32
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java2
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ccid/CCID.java45
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ccid/DefaultReader.java345
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ccid/OMNIKEYCardMan3621.java39
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ccid/ReaderFactory.java2
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/InfoBoxReadRequestHandler.java12
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PINProviderFactory.java298
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PinpadPINProviderFactory.java186
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java10
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SoftwarePINProviderFactory.java137
25 files changed, 1174 insertions, 750 deletions
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java
index f0cc0a27..848cd17f 100644
--- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java
+++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java
@@ -62,6 +62,9 @@ public interface PINManagementGUIFacade extends BKUGUIFacade {
public static final String ERR_RETRIES = "err.retries";
public static final String ERR_LOCKED = "err.locked";
public static final String ERR_NOT_ACTIVE = "err.not.active";
+ public static final String ERR_PIN_FORMAT = "err.pin.format";
+ public static final String ERR_PIN_CONFIRMATION = "err.pin.confirmation";
+ public static final String ERR_PIN_OPERATION_ABORTED = "err.pin.operation.aborted";
public static final String BUTTON_ACTIVATE = "button.activate";
public static final String BUTTON_UNBLOCK = "button.unblock";
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/ManagementPINProviderFactory.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/ManagementPINProviderFactory.java
index d635b8df..090caf50 100644
--- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/ManagementPINProviderFactory.java
+++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/ManagementPINProviderFactory.java
@@ -17,38 +17,242 @@
package at.gv.egiz.bku.smccstal.ext;
+import at.gv.egiz.bku.gui.BKUGUIFacade;
import at.gv.egiz.smcc.ChangePINProvider;
import at.gv.egiz.bku.gui.PINManagementGUIFacade;
+import at.gv.egiz.bku.smccstal.AbstractPINProvider;
+import at.gv.egiz.bku.smccstal.PINProviderFactory;
+import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.ccid.CCID;
import at.gv.egiz.smcc.PINProvider;
+import at.gv.egiz.smcc.PINSpec;
import at.gv.egiz.smcc.SignatureCard;
/**
*
* @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
*/
-public abstract class ManagementPINProviderFactory {
-// extends at.gv.egiz.bku.smccstal.PINProviderFactory {
+public class ManagementPINProviderFactory extends PINProviderFactory {
- PINManagementGUIFacade gui;
+ public ManagementPINProviderFactory(CCID reader, PINManagementGUIFacade gui) {
+ super(reader, gui);
+ }
- public static ManagementPINProviderFactory getInstance(SignatureCard forCard,
- PINManagementGUIFacade gui) {
- if (forCard.getReader().hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) {
-// forCard.ifdSupportsFeature(SignatureCard.FEATURE_MODIFY_PIN_DIRECT)
- return new PinpadPINProviderFactory(gui);
+// public static ManagementPINProviderFactory getInstance(SignatureCard forCard,
+// PINManagementGUIFacade gui) {
+// if (forCard.getReader().hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) {
+// return new PinpadPINProviderFactory(gui);
+//
+// } else {
+// return new SoftwarePINProviderFactory(gui);
+// }
+// }
+
+ public PINProvider getVerifyPINProvider() {
+ if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_START)) {
+ return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.VERIFY);
+ } else if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) {
+ return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.VERIFY);
+ } else {
+ return new SoftwareGenericPinProvider(PINManagementGUIFacade.DIALOG.VERIFY);
+ }
+ }
+
+ public PINProvider getActivatePINProvider() {
+ if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_START)) {
+ return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.ACTIVATE);
+ } else if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_DIRECT)) {
+ return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.ACTIVATE);
+ } else {
+ return new SoftwareGenericPinProvider(PINManagementGUIFacade.DIALOG.ACTIVATE);
+ }
+ }
+ public ChangePINProvider getChangePINProvider() {
+ if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_START)) {
+ return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.CHANGE);
+ } else if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_DIRECT)) {
+ return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.CHANGE);
} else {
- return new SoftwarePINProviderFactory(gui);
+ return new ChangePinProvider();
+ }
+ }
+
+ public PINProvider getUnblockPINProvider() {
+ if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_START)) {
+ return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.UNBLOCK);
+ } else if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) {
+ return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.UNBLOCK);
+ } else {
+ return new SoftwareGenericPinProvider(PINManagementGUIFacade.DIALOG.UNBLOCK);
+ }
+ }
+
+ class PinpadGenericPinProvider extends AbstractPINProvider
+ implements ChangePINProvider {
+
+ protected PINManagementGUIFacade.DIALOG type;
+
+ private PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG type) {
+ this.type = type;
+ }
+
+ @Override
+ public char[] providePIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+
+ showPinpadPINDialog(retries, spec);
+ retry = true;
+ return null;
+ }
+
+ /**
+ * do not call this method without calling providePIN()
+ * (no message is displayed)
+ * @param spec
+ * @param retries
+ * @return
+ */
+ @Override
+ public char[] provideOldPIN(PINSpec spec, int retries) {
+ return null;
+ }
+
+ private void showPinpadPINDialog(int retries, PINSpec pinSpec) {
+ String title, message;
+ Object[] params;
+ if (retry) {
+ title = BKUGUIFacade.TITLE_RETRY;
+ message = BKUGUIFacade.MESSAGE_RETRIES;
+ params = new Object[]{String.valueOf(retries)};
+ } else if (type == PINManagementGUIFacade.DIALOG.VERIFY) {
+ title = PINManagementGUIFacade.TITLE_VERIFY_PIN;
+ message = BKUGUIFacade.MESSAGE_ENTERPIN_PINPAD;
+ String pinSize = String.valueOf(pinSpec.getMinLength());
+ if (pinSpec.getMinLength() != pinSpec.getMaxLength()) {
+ pinSize += "-" + pinSpec.getMaxLength();
+ }
+ params = new Object[]{pinSpec.getLocalizedName(), pinSize};
+ } else if (type == PINManagementGUIFacade.DIALOG.ACTIVATE) {
+ title = PINManagementGUIFacade.TITLE_ACTIVATE_PIN;
+ message = PINManagementGUIFacade.MESSAGE_ACTIVATEPIN_PINPAD;
+ String pinSize = String.valueOf(pinSpec.getMinLength());
+ if (pinSpec.getMinLength() != pinSpec.getMaxLength()) {
+ pinSize += "-" + pinSpec.getMaxLength();
+ }
+ params = new Object[]{pinSpec.getLocalizedName(), pinSize};
+ } else if (type == PINManagementGUIFacade.DIALOG.CHANGE) {
+ title = PINManagementGUIFacade.TITLE_CHANGE_PIN;
+ message = PINManagementGUIFacade.MESSAGE_CHANGEPIN_PINPAD;
+ String pinSize = String.valueOf(pinSpec.getMinLength());
+ if (pinSpec.getMinLength() != pinSpec.getMaxLength()) {
+ pinSize += "-" + pinSpec.getMaxLength();
+ }
+ params = new Object[]{pinSpec.getLocalizedName(), pinSize};
+ } else { //if (type == DIALOG.UNBLOCK) {
+ title = PINManagementGUIFacade.TITLE_UNBLOCK_PIN;
+ message = PINManagementGUIFacade.MESSAGE_UNBLOCKPIN_PINPAD;
+ String pinSize = String.valueOf(pinSpec.getMinLength());
+ if (pinSpec.getMinLength() != pinSpec.getMaxLength()) {
+ pinSize += "-" + pinSpec.getMaxLength();
+ }
+ params = new Object[]{pinSpec.getLocalizedName(), pinSize};
+ }
+ gui.showMessageDialog(title, message, params);
}
}
- public abstract PINProvider getVerifyPINProvider();
- public abstract PINProvider getActivatePINProvider();
+ class SoftwareGenericPinProvider extends AbstractPINProvider {
+
+// protected PINManagementGUIFacade gui;
+ protected PINManagementGUIFacade.DIALOG type;
+
+ private SoftwareGenericPinProvider(PINManagementGUIFacade.DIALOG type) {
+ this.type = type;
+ }
+
+ @Override
+ public char[] providePIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+
+ ((PINManagementGUIFacade) gui).showPINDialog(type, spec,
+ (retry) ? retries : -1,
+ this, "exec",
+ this, "back");
+
+ waitForAction();
+
+ if ("exec".equals(action)) {
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
+ BKUGUIFacade.MESSAGE_WAIT);
+ retry = true;
+ return gui.getPin();
+ } else if ("back".equals(action)) {
+ throw new CancelledException();
+ } else {
+ log.error("unsupported command " + action);
+ throw new CancelledException();
+ }
+ }
+ }
+
+ class ChangePinProvider extends AbstractPINProvider
+ implements ChangePINProvider {
- public abstract ChangePINProvider getChangePINProvider();
+// protected PINManagementGUIFacade gui;
- public abstract PINProvider getUnblockPINProvider();
+ private char[] oldPin;
+ private char[] newPin;
+ private ChangePinProvider() {
+ }
+
+ @Override
+ public char[] providePIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+ if (newPin == null) {
+ getPINs(spec, retries);
+ }
+ char[] pin = newPin;
+ newPin = null;
+ return pin;
+ }
+
+ @Override
+ public char[] provideOldPIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+ if (oldPin == null) {
+ getPINs(spec, retries);
+ }
+ char[] pin = oldPin;
+ oldPin = null;
+ return pin;
+ }
+
+ private void getPINs(PINSpec spec, int retries)
+ throws InterruptedException, CancelledException {
+
+ ((PINManagementGUIFacade) gui).showPINDialog(
+ PINManagementGUIFacade.DIALOG.CHANGE, spec,
+ (retry) ? retries : -1,
+ this, "exec",
+ this, "back");
+
+ waitForAction();
+
+ if ("exec".equals(action)) {
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
+ BKUGUIFacade.MESSAGE_WAIT);
+ retry = true;
+ oldPin = ((PINManagementGUIFacade) gui).getOldPin();
+ newPin = gui.getPin();
+ } else if ("back".equals(action)) {
+ throw new CancelledException();
+ } else {
+ log.error("unsupported command " + action);
+ throw new CancelledException();
+ }
+ }
+ }
}
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PINManagementRequestHandler.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PINManagementRequestHandler.java
index 6b565b26..72a7c4cc 100644
--- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PINManagementRequestHandler.java
+++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PINManagementRequestHandler.java
@@ -25,6 +25,9 @@ import at.gv.egiz.bku.smccstal.PINProviderFactory;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.LockedException;
import at.gv.egiz.smcc.NotActivatedException;
+import at.gv.egiz.smcc.PINConfirmationException;
+import at.gv.egiz.smcc.PINFormatException;
+import at.gv.egiz.smcc.PINOperationAbortedException;
import at.gv.egiz.smcc.PINProvider;
import at.gv.egiz.smcc.PINSpec;
import at.gv.egiz.smcc.STARCOSCard;
@@ -58,7 +61,6 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {
protected static final Log log = LogFactory.getLog(PINManagementRequestHandler.class);
protected Map<PINSpec, STATUS> pinStatuses;
- private ManagementPINProviderFactory pinProviderFactory;
@Override
public STALResponse handleRequest(STALRequest request) throws InterruptedException {
@@ -89,16 +91,14 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {
throw new NullPointerException("no PIN selected for activation/change");
}
- if (pinProviderFactory == null) {
- pinProviderFactory =
- ManagementPINProviderFactory.getInstance(card, gui);
- }
+ ManagementPINProviderFactory ppfac =
+ new ManagementPINProviderFactory(card.getReader(), gui);
try {
if ("activate_enterpin".equals(actionCommand)) {
log.info("activate " + selectedPIN.getLocalizedName());
- card.activatePIN(selectedPIN,
- pinProviderFactory.getActivatePINProvider());
+ card.activatePIN(selectedPIN,
+ ppfac.getActivatePINProvider());
updatePINStatus(selectedPIN, STATUS.ACTIV);
gui.showMessageDialog(PINManagementGUIFacade.TITLE_ACTIVATE_SUCCESS,
PINManagementGUIFacade.MESSAGE_ACTIVATE_SUCCESS,
@@ -108,7 +108,7 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {
} else if ("change_enterpin".equals(actionCommand)) {
log.info("change " + selectedPIN.getLocalizedName());
card.changePIN(selectedPIN,
- pinProviderFactory.getChangePINProvider());
+ ppfac.getChangePINProvider());
updatePINStatus(selectedPIN, STATUS.ACTIV);
gui.showMessageDialog(PINManagementGUIFacade.TITLE_CHANGE_SUCCESS,
PINManagementGUIFacade.MESSAGE_CHANGE_SUCCESS,
@@ -119,11 +119,11 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {
} else if ("unblock_enterpuk".equals(actionCommand)) {
log.info("unblock " + selectedPIN.getLocalizedName());
card.unblockPIN(selectedPIN,
- pinProviderFactory.getUnblockPINProvider());
+ ppfac.getUnblockPINProvider());
} else if ("verify_enterpin".equals(actionCommand)) {
log.info("verify " + selectedPIN.getLocalizedName());
card.verifyPIN(selectedPIN,
- pinProviderFactory.getVerifyPINProvider());
+ ppfac.getVerifyPINProvider());
updatePINStatus(selectedPIN, STATUS.ACTIV);
}
} catch (CancelledException ex) {
@@ -149,6 +149,29 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {
new Object[] {selectedPIN.getLocalizedName()},
this, null);
waitForAction();
+ } catch (PINConfirmationException ex) {
+ log.error("confirmation pin does not match new " + selectedPIN.getLocalizedName());
+ gui.showErrorDialog(PINManagementGUIFacade.ERR_PIN_CONFIRMATION,
+ new Object[] {selectedPIN.getLocalizedName()},
+ this, null);
+ waitForAction();
+ } catch (PINOperationAbortedException ex) {
+ log.error("pin operation aborted without further details");
+ gui.showErrorDialog(PINManagementGUIFacade.ERR_PIN_OPERATION_ABORTED,
+ new Object[] {selectedPIN.getLocalizedName()},
+ this, null);
+ waitForAction();
+ } catch (PINFormatException ex) {
+ log.error("wrong format of new " + selectedPIN.getLocalizedName());
+// updatePINStatus(selectedPIN, STATUS.NOT_ACTIV);
+ String pinSize = String.valueOf(selectedPIN.getMinLength());
+ if (selectedPIN.getMinLength() != selectedPIN.getMaxLength()) {
+ pinSize += "-" + selectedPIN.getMaxLength();
+ }
+ gui.showErrorDialog(PINManagementGUIFacade.ERR_PIN_FORMAT,
+ new Object[] {selectedPIN.getLocalizedName(), pinSize},
+ this, null);
+ waitForAction();
}
} // end if
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PinpadPINProviderFactory.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PinpadPINProviderFactory.java
deleted file mode 100644
index a9ad5ef8..00000000
--- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PinpadPINProviderFactory.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2008 Federal Chancellery Austria and
- * Graz University of Technology
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package at.gv.egiz.bku.smccstal.ext;
-
-import at.gv.egiz.smcc.ChangePINProvider;
-import at.gv.egiz.bku.gui.BKUGUIFacade;
-import at.gv.egiz.bku.gui.PINManagementGUIFacade;
-import at.gv.egiz.bku.gui.PINManagementGUIFacade.DIALOG;
-import at.gv.egiz.bku.smccstal.AbstractPINProvider;
-import at.gv.egiz.smcc.CancelledException;
-import at.gv.egiz.smcc.PINProvider;
-import at.gv.egiz.smcc.PINSpec;
-
-/**
- *
- * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
- */
-public class PinpadPINProviderFactory extends ManagementPINProviderFactory {
-
- protected PinpadPINProviderFactory(PINManagementGUIFacade gui) {
- this.gui = gui;
- }
-
- @Override
- public PINProvider getVerifyPINProvider() {
- return new SimplePinProvider(DIALOG.VERIFY);
- }
-
- @Override
- public PINProvider getActivatePINProvider() {
- return new SimplePinProvider(DIALOG.ACTIVATE);
- }
-
- @Override
- public ChangePINProvider getChangePINProvider() {
- return new SimplePinProvider(DIALOG.CHANGE);
- }
-
- @Override
- public PINProvider getUnblockPINProvider() {
- return new SimplePinProvider(DIALOG.UNBLOCK);
- }
-
-
- class SimplePinProvider extends AbstractPINProvider
- implements ChangePINProvider {
-
-// protected PINManagementGUIFacade gui;
- protected PINManagementGUIFacade.DIALOG type;
-
- private SimplePinProvider(PINManagementGUIFacade.DIALOG type) {
- this.type = type;
- }
-
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
-
- showPinpadPINDialog(retries, spec);
- retry = true;
- return null;
- }
-
- /**
- * do not call this method without calling providePIN()
- * (no message is displayed)
- * @param spec
- * @param retries
- * @return
- */
- @Override
- public char[] provideOldPIN(PINSpec spec, int retries) {
- return null;
- }
-
- private void showPinpadPINDialog(int retries, PINSpec pinSpec) {
- String title, message;
- Object[] params;
- if (retry) {
- title = BKUGUIFacade.TITLE_RETRY;
- message = BKUGUIFacade.MESSAGE_RETRIES;
- params = new Object[]{String.valueOf(retries)};
- } else if (type == DIALOG.VERIFY) {
- title = PINManagementGUIFacade.TITLE_VERIFY_PIN;
- message = BKUGUIFacade.MESSAGE_ENTERPIN_PINPAD;
- String pinSize = String.valueOf(pinSpec.getMinLength());
- if (pinSpec.getMinLength() != pinSpec.getMaxLength()) {
- pinSize += "-" + pinSpec.getMaxLength();
- }
- params = new Object[]{pinSpec.getLocalizedName(), pinSize};
- } else if (type == DIALOG.ACTIVATE) {
- title = PINManagementGUIFacade.TITLE_ACTIVATE_PIN;
- message = PINManagementGUIFacade.MESSAGE_ACTIVATEPIN_PINPAD;
- String pinSize = String.valueOf(pinSpec.getMinLength());
- if (pinSpec.getMinLength() != pinSpec.getMaxLength()) {
- pinSize += "-" + pinSpec.getMaxLength();
- }
- params = new Object[]{pinSpec.getLocalizedName(), pinSize};
- } else if (type == DIALOG.CHANGE) {
- title = PINManagementGUIFacade.TITLE_CHANGE_PIN;
- message = PINManagementGUIFacade.MESSAGE_CHANGEPIN_PINPAD;
- String pinSize = String.valueOf(pinSpec.getMinLength());
- if (pinSpec.getMinLength() != pinSpec.getMaxLength()) {
- pinSize += "-" + pinSpec.getMaxLength();
- }
- params = new Object[]{pinSpec.getLocalizedName(), pinSize};
- } else { //if (type == DIALOG.UNBLOCK) {
- title = PINManagementGUIFacade.TITLE_UNBLOCK_PIN;
- message = PINManagementGUIFacade.MESSAGE_UNBLOCKPIN_PINPAD;
- String pinSize = String.valueOf(pinSpec.getMinLength());
- if (pinSpec.getMinLength() != pinSpec.getMaxLength()) {
- pinSize += "-" + pinSpec.getMaxLength();
- }
- params = new Object[]{pinSpec.getLocalizedName(), pinSize};
- }
- gui.showMessageDialog(title, message, params);
- }
- }
-}
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/SoftwarePINProviderFactory.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/SoftwarePINProviderFactory.java
deleted file mode 100644
index e87512d0..00000000
--- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/SoftwarePINProviderFactory.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright 2008 Federal Chancellery Austria and
- * Graz University of Technology
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package at.gv.egiz.bku.smccstal.ext;
-
-import at.gv.egiz.bku.gui.BKUGUIFacade;
-import at.gv.egiz.smcc.ChangePINProvider;
-import at.gv.egiz.bku.gui.PINManagementGUIFacade;
-import at.gv.egiz.bku.gui.PINManagementGUIFacade.DIALOG;
-import at.gv.egiz.bku.smccstal.AbstractPINProvider;
-import at.gv.egiz.smcc.CancelledException;
-import at.gv.egiz.smcc.PINProvider;
-import at.gv.egiz.smcc.PINSpec;
-
-/**
- *
- * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
- */
-public class SoftwarePINProviderFactory extends ManagementPINProviderFactory {
-
- protected SoftwarePINProviderFactory(PINManagementGUIFacade gui) {
- this.gui = gui;
- }
-
- @Override
- public PINProvider getVerifyPINProvider() {
- return new SimplePinProvider(DIALOG.VERIFY);
- }
-
- @Override
- public PINProvider getActivatePINProvider() {
- return new SimplePinProvider(DIALOG.ACTIVATE);
- }
-
- @Override
- public ChangePINProvider getChangePINProvider() {
- return new ChangePinProvider();
- }
-
- @Override
- public PINProvider getUnblockPINProvider() {
- return new SimplePinProvider(DIALOG.UNBLOCK);
- }
-
- class SimplePinProvider extends AbstractPINProvider {
-
-// protected PINManagementGUIFacade gui;
- protected PINManagementGUIFacade.DIALOG type;
-
- private SimplePinProvider(DIALOG type) {
- this.type = type;
- }
-
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
-
- gui.showPINDialog(type, spec, (retry) ? retries : -1,
- this, "exec",
- this, "back");
-
- waitForAction();
-
- if ("exec".equals(action)) {
- gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
- BKUGUIFacade.MESSAGE_WAIT);
- retry = true;
- return gui.getPin();
- } else if ("back".equals(action)) {
- throw new CancelledException();
- } else {
- log.error("unsupported command " + action);
- throw new CancelledException();
- }
- }
- }
-
- class ChangePinProvider extends AbstractPINProvider
- implements ChangePINProvider {
-
-// protected PINManagementGUIFacade gui;
-
- private char[] oldPin;
- private char[] newPin;
-
- private ChangePinProvider() {
- }
-
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
- if (newPin == null) {
- getPINs(spec, retries);
- }
- char[] pin = newPin;
- newPin = null;
- return pin;
- }
-
- @Override
- public char[] provideOldPIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
- if (oldPin == null) {
- getPINs(spec, retries);
- }
- char[] pin = oldPin;
- oldPin = null;
- return pin;
- }
-
- private void getPINs(PINSpec spec, int retries)
- throws InterruptedException, CancelledException {
-
- gui.showPINDialog(PINManagementGUIFacade.DIALOG.CHANGE, spec,
- (retry) ? retries : -1,
- this, "exec",
- this, "back");
-
- waitForAction();
-
- if ("exec".equals(action)) {
- gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
- BKUGUIFacade.MESSAGE_WAIT);
- retry = true;
- oldPin = gui.getOldPin();
- newPin = gui.getPin();
- } else if ("back".equals(action)) {
- throw new CancelledException();
- } else {
- log.error("unsupported command " + action);
- throw new CancelledException();
- }
- }
- }
-}
diff --git a/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties b/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties
index c6d219d4..15fc2827 100644
--- a/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties
+++ b/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties
@@ -55,9 +55,12 @@ err.activate=<html>Beim Aktivieren der {0} trat ein Fehler auf.</html>
err.change=<html>Beim \u00C4ndern der {0} trat ein Fehler auf.</html>
err.unblock=<html>Das Entsperren der {0} wird nicht unterst\u00FCtzt.</html>
err.verify=<html>VERIFY ERROR (TODO)</html>
-err.retries=<html>Falscher {0}, noch {1} Versuche</html>
+err.retries=<html>Falsche {0}, noch {1} Versuche</html>
err.locked=<html>{0} gesperrt.</html>
err.not.active=<html>{0} nicht aktiviert.</html>
+err.pin.format=<html>Ung\u00FCltige {0} L\u00E4nge, verlangt sind {1} Stellen.</html>
+err.pin.confirmation=<html>{0} und Best\u00E4tigung stimmen nicht \u00FCberein.</html>
+err.pin.operation.aborted=<html>Der Vorgang f\u00FCr {0} wurde abgebrochen.</html>
status.not.active=NICHT AKTIV
status.active=AKTIV
diff --git a/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties b/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties
index b4bededf..8cc9d01a 100644
--- a/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties
+++ b/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties
@@ -55,6 +55,9 @@ err.unblock=<html>Unblocking of {0} is not supported.</html>
err.retries=<html>Wrong {0}, {1} tries remaining</html>
err.locked=<html>{0} locked</html>
err.not.active=<html>{0} not activated.</html>
+err.pin.format=<html>Invalid {0} length, {1} digit(s) required.</html>
+err.pin.confirmation=<html>{0} and confirmation do not match.</html>
+err.pin.operation.aborted=<html>The operation on {0} was aborted.</html>
status.not.active=NOT ACTIVE
status.active=ACTIVE
diff --git a/nbactions.xml b/nbactions.xml
new file mode 100644
index 00000000..4c3d57a9
--- /dev/null
+++ b/nbactions.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<actions>
+ <action>
+ <actionName>CUSTOM-Install_SkipTest</actionName>
+ <displayName>Install_SkipTest</displayName>
+ <goals>
+ <goal>install</goal>
+ </goals>
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ </properties>
+ </action>
+ </actions>
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
index 06e4a018..d064b821 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
@@ -401,15 +401,16 @@ public class ACOSCard extends AbstractSignatureCard {
@Override
protected int verifyPIN(byte kid, char[] pin)
- throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException {
+ throws LockedException, NotActivatedException, CancelledException, TimeoutException, PINFormatException, PINOperationAbortedException, SignatureCardException {
try {
byte[] sw;
if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) {
- log.debug("verify PIN on IFD");
- sw = reader.transmitControlCommand(
- CCID.FEATURE_VERIFY_PIN_DIRECT,
- getPINVerifyStructure(kid));
+ log.debug("verify pin on cardreader");
+ sw = reader.verifyPinDirect(getPINVerifyStructure(kid));
// int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff;
+ } else if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_START)) {
+ log.debug("verify pin on cardreader");
+ sw = reader.verifyPin(getPINVerifyStructure(kid));
} else {
byte[] pinBlock = encodePINBlock(pin);
CardChannel channel = getCardChannel();
@@ -442,6 +443,8 @@ public class ACOSCard extends AbstractSignatureCard {
throw new TimeoutException("[64:00]");
} else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) {
throw new CancelledException("[64:01]");
+ } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x03) {
+ throw new PINFormatException("[64:03]");
}
log.error("Failed to verify pin: SW="
+ SMCCHelper.toString(sw));
@@ -465,15 +468,15 @@ public class ACOSCard extends AbstractSignatureCard {
*/
@Override
protected int changePIN(byte kid, char[] oldPin, char[] newPin)
- throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException {
+ throws LockedException, NotActivatedException, CancelledException, PINFormatException, PINConfirmationException, TimeoutException, PINOperationAbortedException, SignatureCardException {
try {
byte[] sw;
if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_DIRECT)) {
- log.debug("modify PIN on IFD");
- sw = reader.transmitControlCommand(
- CCID.FEATURE_MODIFY_PIN_DIRECT,
- getPINModifyStructure(kid));
-// int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff;
+ log.debug("modify pin on cardreader");
+ sw = reader.modifyPinDirect(getPINModifyStructure(kid));
+ } else if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_START)) {
+ log.debug("modify pin on cardreader");
+ sw = reader.modifyPin(getPINModifyStructure(kid));
} else {
byte[] cmd = new byte[16];
System.arraycopy(encodePINBlock(oldPin), 0, cmd, 0, 8);
@@ -504,6 +507,13 @@ public class ACOSCard extends AbstractSignatureCard {
throw new TimeoutException("[64:00]");
} else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) {
throw new CancelledException("[64:01]");
+ } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x02) {
+ throw new PINConfirmationException("[64:02]");
+ } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x03) {
+ throw new PINFormatException("[64:03]");
+ } else if (sw[0] == (byte) 0x6a && sw[1] == (byte) 0x80) {
+ log.info("invalid parameter, assume wrong pin size");
+ throw new PINFormatException("[6a:80]");
}
log.error("Failed to change pin: SW="
+ SMCCHelper.toString(sw));
@@ -559,7 +569,7 @@ public class ACOSCard extends AbstractSignatureCard {
byte bmPINLengthFormat = (byte) 0x00; // 000 0 0000
// ^-------- System bit units is bit
// ^^^^--- no PIN length
- byte wPINMaxExtraDigitL =
+ byte wPINMaxExtraDigitL = //TODO compare ints, not bytes
(reader.getwPINMaxExtraDigitL() < (byte) 0x08) ?
reader.getwPINMaxExtraDigitL() : (byte) 0x08;
byte wPINMaxExtraDigitH =
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
index 47c27369..7dd3ee78 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
@@ -29,21 +29,16 @@
package at.gv.egiz.smcc;
import at.gv.egiz.smcc.ccid.CCID;
-import at.gv.egiz.smcc.ccid.DefaultReader;
import at.gv.egiz.smcc.ccid.ReaderFactory;
import at.gv.egiz.smcc.util.SMCCHelper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
import java.util.ResourceBundle;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import javax.smartcardio.ATR;
import javax.smartcardio.Card;
import javax.smartcardio.CardChannel;
@@ -152,8 +147,8 @@ public abstract class AbstractSignatureCard implements SignatureCard {
* @throws at.gv.egiz.smcc.SignatureCardException
*/
protected abstract int verifyPIN(byte kid, char[] pin)
- throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException;
-
+ throws LockedException, NotActivatedException, CancelledException, PINFormatException, TimeoutException, PINOperationAbortedException, SignatureCardException;
+
/**
* CHANGE(?) APDU
* If IFD supports VERIFY_PIN on pinpad, parameter pin may be empty.
@@ -162,7 +157,7 @@ public abstract class AbstractSignatureCard implements SignatureCard {
* @throws at.gv.egiz.smcc.SignatureCardException if activation fails
*/
protected abstract void activatePIN(byte kid, char[] pin)
- throws CancelledException, TimeoutException, SignatureCardException;
+ throws CancelledException, PINFormatException, PINConfirmationException, TimeoutException, PINOperationAbortedException, SignatureCardException;
/**
* CHANGE(?) APDU
@@ -173,7 +168,7 @@ public abstract class AbstractSignatureCard implements SignatureCard {
* @throws at.gv.egiz.smcc.SignatureCardException if change fails
*/
protected abstract int changePIN(byte kid, char[] oldPin, char[] newPin)
- throws CancelledException, TimeoutException, SignatureCardException;
+ throws LockedException, NotActivatedException, CancelledException, PINFormatException, PINConfirmationException, TimeoutException, PINOperationAbortedException, SignatureCardException;
/**
* encode the pin as needed in VERIFY/CHANGE APDUs
@@ -595,7 +590,8 @@ public abstract class AbstractSignatureCard implements SignatureCard {
*/
@Override
public void changePIN(PINSpec pinSpec, ChangePINProvider pinProvider)
- throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException, InterruptedException {
+ throws LockedException, NotActivatedException, CancelledException,
+ TimeoutException, SignatureCardException, InterruptedException {
try {
getCard().beginExclusive();
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/PINConfirmationException.java b/smcc/src/main/java/at/gv/egiz/smcc/PINConfirmationException.java
new file mode 100644
index 00000000..115e6d5f
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/PINConfirmationException.java
@@ -0,0 +1,43 @@
+/*
+* Copyright 2008 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package at.gv.egiz.smcc;
+
+/**
+ * TODO check whether card readers distinguish specific reason (pin too short?)
+ * and add getters/setters
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public class PINConfirmationException extends SignatureCardException {
+
+ public PINConfirmationException() {
+ super();
+ }
+
+ public PINConfirmationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public PINConfirmationException(String message) {
+ super(message);
+ }
+
+ public PINConfirmationException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/PINFormatException.java b/smcc/src/main/java/at/gv/egiz/smcc/PINFormatException.java
new file mode 100644
index 00000000..28a13fdb
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/PINFormatException.java
@@ -0,0 +1,43 @@
+/*
+* Copyright 2008 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package at.gv.egiz.smcc;
+
+/**
+ * TODO check whether card readers distinguish specific reason (pin too short?)
+ * and add getters/setters
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public class PINFormatException extends SignatureCardException {
+
+ public PINFormatException() {
+ super();
+ }
+
+ public PINFormatException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public PINFormatException(String message) {
+ super(message);
+ }
+
+ public PINFormatException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/PINOperationAbortedException.java b/smcc/src/main/java/at/gv/egiz/smcc/PINOperationAbortedException.java
new file mode 100644
index 00000000..7337f59e
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/PINOperationAbortedException.java
@@ -0,0 +1,43 @@
+/*
+* Copyright 2008 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package at.gv.egiz.smcc;
+
+/**
+ * TODO check whether card readers distinguish specific reason (pin too short?)
+ * and add getters/setters
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public class PINOperationAbortedException extends SignatureCardException {
+
+ public PINOperationAbortedException() {
+ super();
+ }
+
+ public PINOperationAbortedException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public PINOperationAbortedException(String message) {
+ super(message);
+ }
+
+ public PINOperationAbortedException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
index bc6a2316..b9c68b06 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
@@ -28,7 +28,7 @@
//
package at.gv.egiz.smcc;
-import at.gv.egiz.smcc.ccid.DefaultReader;
+import at.gv.egiz.smcc.ccid.CCID;
import at.gv.egiz.smcc.util.SMCCHelper;
import java.util.Arrays;
import javax.smartcardio.CardChannel;
@@ -319,6 +319,8 @@ public class STARCOSCard extends AbstractSignatureCard {
return createSignature(hash, AID_DF_SS, pin, KID_PIN_SS, DST_SS);
} catch (VerificationFailedException e) {
retries = e.getRetries();
+ } catch (PINFormatException e) {
+ log.debug("wrong pin size entered, retry");
} finally {
getCard().endExclusive();
}
@@ -454,15 +456,16 @@ public class STARCOSCard extends AbstractSignatureCard {
@Override
protected int verifyPIN(byte kid, char[] pin)
- throws LockedException, NotActivatedException, SignatureCardException {
+ throws LockedException, NotActivatedException, TimeoutException, CancelledException, PINFormatException, PINOperationAbortedException, SignatureCardException {
try {
byte[] sw;
- if (reader.hasFeature(DefaultReader.FEATURE_VERIFY_PIN_DIRECT)) {
- log.debug("verify PIN on IFD");
- sw = reader.transmitControlCommand(
- DefaultReader.FEATURE_VERIFY_PIN_DIRECT,
- getPINVerifyStructure(kid));
+ if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) {
+ log.debug("verify pin on cardreader");
+ sw = reader.verifyPinDirect(getPINVerifyStructure(kid));
// int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff;
+ } else if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_START)) {
+ log.debug("verify pin on cardreader");
+ sw = reader.verifyPin(getPINVerifyStructure(kid));
} else {
byte[] pinBlock = encodePINBlock(pin);
CardChannel channel = getCardChannel();
@@ -492,6 +495,8 @@ public class STARCOSCard extends AbstractSignatureCard {
throw new TimeoutException("[64:00]");
} else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) {
throw new CancelledException("[64:01]");
+ } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x03) {
+ throw new PINFormatException("[64:03]");
}
log.error("Failed to verify pin: SW="
+ SMCCHelper.toString(sw));
@@ -539,15 +544,15 @@ public class STARCOSCard extends AbstractSignatureCard {
@Override
protected int changePIN(byte kid, char[] oldPin, char[] newPin)
- throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException {
+ throws LockedException, CancelledException, PINFormatException, PINConfirmationException, TimeoutException, PINOperationAbortedException, SignatureCardException {
try {
byte[] sw;
- if (reader.hasFeature(DefaultReader.FEATURE_MODIFY_PIN_DIRECT)) {
- log.debug("modify PIN on IFD");
- sw = reader.transmitControlCommand(
- DefaultReader.FEATURE_MODIFY_PIN_DIRECT,
- getPINModifyStructure(kid));
-// int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff;
+ if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_DIRECT)) {
+ log.debug("modify pin on cardreader");
+ sw = reader.modifyPinDirect(getPINModifyStructure(kid));
+ } else if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_START)) {
+ log.debug("modify pin on cardreader");
+ sw = reader.modifyPin(getPINModifyStructure(kid));
} else {
byte[] cmd = new byte[16];
System.arraycopy(encodePINBlock(oldPin), 0, cmd, 0, 8);
@@ -583,6 +588,13 @@ public class STARCOSCard extends AbstractSignatureCard {
throw new TimeoutException("[64:00]");
} else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) {
throw new CancelledException("[64:01]");
+ } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x02) {
+ throw new PINConfirmationException("[64:02]");
+ } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x03) {
+ throw new PINFormatException("[64:03]");
+ } else if (sw[0] == (byte) 0x6a && sw[1] == (byte) 0x80) {
+ log.info("invalid parameter, assume wrong pin size");
+ throw new PINFormatException("[6a:80]");
}
log.error("Failed to change pin: SW="
+ SMCCHelper.toString(sw));
@@ -595,15 +607,15 @@ public class STARCOSCard extends AbstractSignatureCard {
@Override
protected void activatePIN(byte kid, char[] pin)
- throws CancelledException, TimeoutException, SignatureCardException {
+ throws CancelledException, PINFormatException, PINConfirmationException, TimeoutException, PINOperationAbortedException, SignatureCardException {
try {
byte[] sw;
- if (reader.hasFeature(DefaultReader.FEATURE_MODIFY_PIN_DIRECT)) {
- log.debug("activate PIN on IFD");
- sw = reader.transmitControlCommand(
- DefaultReader.FEATURE_MODIFY_PIN_DIRECT,
- getActivatePINModifyStructure(kid));
-// int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff;
+ if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_DIRECT)) {
+ log.debug("activate pin on cardreader");
+ sw = reader.modifyPinDirect(getActivatePINModifyStructure(kid));
+ } else if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_START)) {
+ log.debug("activate pin on cardreader");
+ sw = reader.modifyPin(getActivatePINModifyStructure(kid));
} else {
CardChannel channel = getCardChannel();
ResponseAPDU resp = transmit(channel,
@@ -630,6 +642,10 @@ public class STARCOSCard extends AbstractSignatureCard {
throw new TimeoutException("[64:00]");
} else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) {
throw new CancelledException("[64:01]");
+ } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x02) {
+ throw new PINConfirmationException("[64:02]");
+ } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x03) {
+ throw new PINFormatException("[64:03]");
}
log.error("Failed to activate pin: SW="
+ SMCCHelper.toString(sw));
@@ -683,6 +699,7 @@ public class STARCOSCard extends AbstractSignatureCard {
byte bmPINLengthFormat = (byte) 0x04; // 000 0 0100
// ^-------- System bit units is bit
// ^^^^--- PIN length is at the 4th position bit
+ //TODO compare ints, not bytes
byte wPINMaxExtraDigitL = // Max=12 digits (Gemplus support max 8)
(reader.getwPINMaxExtraDigitL() < (byte) 0x12) ?
reader.getwPINMaxExtraDigitL() : (byte) 0x12;
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java
index 253ac7a0..2ed1fe64 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java
@@ -430,13 +430,6 @@ public class SWCard implements SignatureCard {
}
@Override
- public byte[] transmitControlCommand(Byte feature, byte[] ctrlCommand)
- throws SignatureCardException {
- throw new SignatureCardException(CCID.FEATURES[feature.intValue()] +
- " not supported");
- }
-
- @Override
public byte getbTimeOut() {
return 0;
}
@@ -465,6 +458,31 @@ public class SWCard implements SignatureCard {
public Card connect() {
return null;
}
+
+ @Override
+ public String getName() {
+ return "Software CardReader";
+ }
+
+ @Override
+ public byte[] verifyPin(byte[] PIN_VERIFY) throws CardException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public byte[] verifyPinDirect(byte[] PIN_VERIFY) throws CardException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public byte[] modifyPin(byte[] PIN_MODIFY) throws CardException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public byte[] modifyPinDirect(byte[] PIN_MODIFY) throws CardException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
};
}
}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java
index ad530ad5..c06074f2 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java
@@ -128,7 +128,7 @@ public interface SignatureCard {
throws LockedException, NotActivatedException, CancelledException, SignatureCardException, InterruptedException;
public void changePIN(PINSpec pinSpec, ChangePINProvider pinProvider)
- throws LockedException, NotActivatedException, CancelledException, SignatureCardException, InterruptedException;
+ throws LockedException, NotActivatedException, CancelledException, PINFormatException, SignatureCardException, InterruptedException;
public void activatePIN(PINSpec pinSpec, PINProvider pinProvider)
throws CancelledException, SignatureCardException, InterruptedException;
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ccid/CCID.java b/smcc/src/main/java/at/gv/egiz/smcc/ccid/CCID.java
index 2c56ce98..56ebaffe 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/ccid/CCID.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ccid/CCID.java
@@ -45,17 +45,48 @@ public interface CCID {
"FEATURE_WRITE_DISPLAY",
"FEATURE_GET_KEY",
"FEATURE_IFD_DISPLAY_PROPERTIES"};
-
- Byte FEATURE_IFD_PIN_PROPERTIES = new Byte((byte) 10);
- Byte FEATURE_MCT_READER_DIRECT = new Byte((byte) 8);
- Byte FEATURE_MODIFY_PIN_DIRECT = new Byte((byte) 7);
- Byte FEATURE_VERIFY_PIN_DIRECT = new Byte((byte) 6);
-
+
+ Byte FEATURE_VERIFY_PIN_START = new Byte((byte) 0x01);
+ Byte FEATURE_VERIFY_PIN_FINISH = new Byte((byte) 0x02);
+ Byte FEATURE_MODIFY_PIN_START = new Byte((byte) 0x03);
+ Byte FEATURE_MODIFY_PIN_FINISH = new Byte((byte) 0x04);
+ Byte FEATURE_GET_KEY_PRESSED = new Byte((byte) 0x05);
+ Byte FEATURE_VERIFY_PIN_DIRECT = new Byte((byte) 0x06);
+ Byte FEATURE_MODIFY_PIN_DIRECT = new Byte((byte) 0x07);
+ Byte FEATURE_MCT_READER_DIRECT = new Byte((byte) 0x08);
+ Byte FEATURE_MCT_UNIVERSAL = new Byte((byte) 0x09);
+ Byte FEATURE_IFD_PIN_PROPERTIES = new Byte((byte) 0x0a);
+ //TODO continue list
+
+ String getName();
+
Card connect() throws CardException;
boolean hasFeature(Byte feature);
/**
+ * not supported by OMNIKEY CardMan 3621 with ACOS card
+ * @param PIN_VERIFY
+ * @return
+ * @throws at.gv.egiz.smcc.PINOperationAbortedException
+ * @throws javax.smartcardio.CardException
+ */
+ byte[] verifyPin(byte[] PIN_VERIFY) throws PINOperationAbortedException, CardException;
+
+ byte[] verifyPinDirect(byte[] PIN_VERIFY) throws CardException;
+
+ /**
+ * not supported by OMNIKEY CardMan 3621 with ACOS card
+ * @param PIN_MODIFY
+ * @return
+ * @throws at.gv.egiz.smcc.PINOperationAbortedException
+ * @throws javax.smartcardio.CardException
+ */
+ byte[] modifyPin(byte[] PIN_MODIFY) throws PINOperationAbortedException, CardException;
+
+ byte[] modifyPinDirect(byte[] PIN_MODIFY) throws CardException;
+
+ /**
*
* @param feature the corresponding control code will be transmitted
* @param ctrlCommand
@@ -63,7 +94,7 @@ public interface CCID {
* @throws at.gv.egiz.smcc.SignatureCardException if feature is not supported
* or card communication fails
*/
- byte[] transmitControlCommand(Byte feature, byte[] ctrlCommand) throws SignatureCardException;
+// byte[] transmitControlCommand(Byte feature, byte[] ctrlCommand) throws SignatureCardException;
/**
* allow subclasses to override default (deal with reader bugs)
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ccid/DefaultReader.java b/smcc/src/main/java/at/gv/egiz/smcc/ccid/DefaultReader.java
index 2cc77dc9..9b1787a0 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/ccid/DefaultReader.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ccid/DefaultReader.java
@@ -20,6 +20,8 @@ import at.gv.egiz.smcc.*;
import at.gv.egiz.smcc.util.SMCCHelper;
import java.util.HashMap;
import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.smartcardio.Card;
import javax.smartcardio.CardException;
import javax.smartcardio.CardTerminal;
@@ -35,12 +37,17 @@ public class DefaultReader implements CCID {
protected final static Log log = LogFactory.getLog(DefaultReader.class);
private static int CTL_CODE(int code) {
- return 0x42000000 + code;
+ String os_name = System.getProperty("os.name").toLowerCase();
+ if (os_name.indexOf("windows") > -1) {
+ // cf. WinIOCTL.h
+ return (0x31 << 16 | (code) << 2);
+ }
+ // cf. reader.h
+ return 0x42000000 + (code);
}
int IOCTL_GET_FEATURE_REQUEST = CTL_CODE(3400);
-
protected Card icc;
protected CardTerminal ct;
@@ -58,14 +65,19 @@ public class DefaultReader implements CCID {
features = queryFeatures();
}
- public Card connect() throws CardException { //SignatureCardException {
-// try {
+ /**
+ *
+ * @return the card terminals name
+ */
+ @Override
+ public String getName() {
+ return ct.getName();
+ }
+
+ @Override
+ public Card connect() throws CardException {
icc = ct.connect("*");
return icc;
-// } catch (CardException ex) {
-// log.error(ex.getMessage(), ex);
-// throw new SignatureCardException("Failed to connect to card: " + ex.getMessage());
-// }
}
Map<Byte, Integer> queryFeatures() {
@@ -81,7 +93,7 @@ public class DefaultReader implements CCID {
" on " + ct.getName());
}
byte[] resp = icc.transmitControlCommand(IOCTL_GET_FEATURE_REQUEST,
- new byte[]{});
+ new byte[0]);
if (log.isTraceEnabled()) {
log.trace("Response TLV " + SMCCHelper.toString(resp));
@@ -91,8 +103,10 @@ public class DefaultReader implements CCID {
// control code value for supported feature (in big endian)
for (int i = 0; i < resp.length; i += 6) {
Byte feature = new Byte(resp[i]);
- int ioctlBigEndian = (resp[i + 2] << 24) |
- (resp[i + 3] << 16) | (resp[i + 4] << 8) | resp[i + 5];
+ int ioctlBigEndian = ((0xff & resp[i + 2]) << 24) |
+ ((0xff & resp[i + 3]) << 16) |
+ ((0xff & resp[i + 4]) << 8) |
+ (0xff & resp[i + 5]);
Integer ioctl = new Integer(ioctlBigEndian);
if (log.isInfoEnabled()) {
log.info("CCID supports " + FEATURES[feature.intValue()] +
@@ -117,37 +131,29 @@ public class DefaultReader implements CCID {
return false;
}
-// public Integer getIOCTL(Byte feature) {
-// if (features != null) {
-// return features.get(feature);
+// protected byte[] transmitControlCommand(Byte feature, byte[] ctrlCommand)
+// throws CardException {
+// try {
+// if (!features.containsKey(feature)) {
+// throw new CardException(FEATURES[feature.intValue()] + " not supported");
+// }
+// int ioctl = features.get(feature);
+// if (log.isTraceEnabled()) {
+// log.trace("CtrlCommand (" + Integer.toHexString(ioctl) +
+// ") " + SMCCHelper.toString(ctrlCommand));
+// }
+// byte[] resp = icc.transmitControlCommand(ioctl, ctrlCommand);
+// if (log.isTraceEnabled()) {
+// log.trace("CtrlCommand Response " + SMCCHelper.toString(resp));
+// }
+// return resp;
+// } catch (CardException ex) {
+// log.error(ex.getMessage());
+// throw new SignatureCardException("Failed to transmit CtrlCommand for " +
+// FEATURES[feature.intValue()]);
// }
-// return null;
// }
- @Override
- public byte[] transmitControlCommand(Byte feature, byte[] ctrlCommand)
- throws SignatureCardException {
- try {
- if (!features.containsKey(feature)) {
- throw new SignatureCardException(FEATURES[feature.intValue()] + " not supported");
- }
- int ioctl = features.get(feature);
- if (log.isTraceEnabled()) {
- log.trace("CtrlCommand (" + Integer.toHexString(ioctl) +
- ") " + SMCCHelper.toString(ctrlCommand));
- }
- byte[] resp = icc.transmitControlCommand(ioctl, ctrlCommand);
- if (log.isTraceEnabled()) {
- log.trace("CtrlCommand Response " + SMCCHelper.toString(resp));
- }
- return resp;
- } catch (CardException ex) {
- log.error(ex.getMessage());
- throw new SignatureCardException("Failed to transmit CtrlCommand for " +
- FEATURES[feature.intValue()]);
- }
- }
-
@Override
public byte getbTimeOut() {
@@ -162,7 +168,7 @@ public class DefaultReader implements CCID {
@Override
public byte getwPINMaxExtraDigitL() {
- return (byte) 0x12;
+ return (byte) 0x12; // signed int
}
@Override
@@ -175,6 +181,265 @@ public class DefaultReader implements CCID {
return (byte) 0x02; // validation key pressed
}
+ void verifyPinStart(byte[] PIN_VERIFY) throws CardException {
+ if (!features.containsKey(FEATURE_VERIFY_PIN_START)) {
+ throw new CardException("FEATURE_VERIFY_PIN_START not supported");
+ }
+ int ioctl = features.get(FEATURE_VERIFY_PIN_START);
+ if (log.isTraceEnabled()) {
+ log.trace("VERIFY_PIN_START (" + Integer.toHexString(ioctl) +
+ ") " + SMCCHelper.toString(PIN_VERIFY));
+ }
+ byte[] resp = icc.transmitControlCommand(ioctl, PIN_VERIFY);
+ if (resp != null && resp.length > 0) {
+ if (resp[0] == (byte) 0x57) {
+ log.error("Invalid parameter in PIN_VERIFY structure");
+ throw new CardException("ERROR_INVALID_PARAMETER");
+ } else {
+ log.error("unexpected response to VERIFY_PIN_START: " +
+ SMCCHelper.toString(resp));
+ throw new CardException("unexpected response to VERIFY_PIN_START: " +
+ SMCCHelper.toString(resp));
+ }
+ }
+ }
+
+ byte[] verifyPinFinish() throws CardException {
+ if (!features.containsKey(FEATURE_VERIFY_PIN_FINISH)) {
+ throw new CardException("FEATURE_VERIFY_FINISH_FINISH not supported");
+ }
+ int ioctl = features.get(FEATURE_VERIFY_PIN_FINISH);
+ if (log.isTraceEnabled()) {
+ log.trace("VERIFY_PIN_FINISH (" + Integer.toHexString(ioctl) + ")");
+ }
+ byte[] resp = icc.transmitControlCommand(ioctl, new byte[0]);
+ if (resp != null && resp.length == 2) {
+ if (log.isTraceEnabled()) {
+ log.trace("response " + SMCCHelper.toString(resp));
+ }
+ return resp;
+ }
+ log.error("unexpected response to VERIFY_PIN_FINISH: " +
+ SMCCHelper.toString(resp));
+ throw new CardException("unexpected response to VERIFY_PIN_FINISH: " +
+ SMCCHelper.toString(resp));
+ }
+
+ void modifyPinStart(byte[] PIN_MODIFY) throws CardException {
+ if (!features.containsKey(FEATURE_MODIFY_PIN_START)) {
+ throw new CardException("FEATURE_MODIFY_PIN_START not supported");
+ }
+ int ioctl = features.get(FEATURE_MODIFY_PIN_START);
+ if (log.isTraceEnabled()) {
+ log.trace("MODFIY_PIN_START (" + Integer.toHexString(ioctl) +
+ ") " + SMCCHelper.toString(PIN_MODIFY));
+ }
+ byte[] resp = icc.transmitControlCommand(ioctl, PIN_MODIFY);
+ if (resp != null && resp.length > 0) {
+ if (resp[0] == (byte) 0x57) {
+ log.error("Invalid parameter in PIN_MODIFY structure");
+ throw new CardException("ERROR_INVALID_PARAMETER");
+ } else {
+ log.error("unexpected response to MODIFY_PIN_START: " +
+ SMCCHelper.toString(resp));
+ throw new CardException("unexpected response to MODIFY_PIN_START: " +
+ SMCCHelper.toString(resp));
+ }
+ }
+ }
+
+ byte[] modifyPinFinish() throws CardException {
+ if (!features.containsKey(FEATURE_MODIFY_PIN_FINISH)) {
+ throw new CardException("FEATURE_MODIFY_FINISH_FINISH not supported");
+ }
+ int ioctl = features.get(FEATURE_MODIFY_PIN_FINISH);
+ if (log.isTraceEnabled()) {
+ log.trace("MODIFY_PIN_FINISH (" + Integer.toHexString(ioctl) + ")");
+ }
+ byte[] resp = icc.transmitControlCommand(ioctl, new byte[0]);
+ if (resp != null && resp.length == 2) {
+ if (log.isTraceEnabled()) {
+ log.trace("response " + SMCCHelper.toString(resp));
+ }
+ return resp;
+ }
+ log.error("unexpected response to MODIFY_PIN_FINISH: " +
+ SMCCHelper.toString(resp));
+ throw new CardException("unexpected response to MODIFY_PIN_FINISH: " +
+ SMCCHelper.toString(resp));
+ }
+
+
+ byte getKeyPressed() throws CardException {
+ if (!features.containsKey(FEATURE_GET_KEY_PRESSED)) {
+ throw new CardException("FEATURE_GET_KEY_PRESSED not supported");
+ }
+ int ioctl = features.get(FEATURE_GET_KEY_PRESSED);
+// if (log.isTraceEnabled()) {
+// log.trace("GET_KEY_PRESSED (" + Integer.toHexString(ioctl) + ")");
+// }
+ byte[] resp = icc.transmitControlCommand(ioctl, new byte[0]);
+ if (resp != null && resp.length == 1) {
+// if (log.isTraceEnabled()) {
+// log.trace("response " + SMCCHelper.toString(resp));
+// }
+ return resp[0];
+ }
+ log.error("unexpected response to GET_KEY_PRESSED: " +
+ SMCCHelper.toString(resp));
+ throw new CardException("unexpected response to GET_KEY_PRESSED: " +
+ SMCCHelper.toString(resp));
+ }
+
+
+
+ @Override
+ public byte[] verifyPinDirect(byte[] PIN_VERIFY) throws CardException {
+ if (!features.containsKey(FEATURE_VERIFY_PIN_DIRECT)) {
+ throw new CardException("FEATURE_VERIFY_PIN_DIRECT not supported");
+ }
+ int ioctl = features.get(FEATURE_VERIFY_PIN_DIRECT);
+ if (log.isTraceEnabled()) {
+ log.trace("VERIFY_PIN_DIRECT (" + Integer.toHexString(ioctl) +
+ ") " + SMCCHelper.toString(PIN_VERIFY));
+ }
+ byte[] resp = icc.transmitControlCommand(ioctl, PIN_VERIFY);
+ if (log.isTraceEnabled()) {
+ log.trace("response " + SMCCHelper.toString(resp));
+ }
+ return resp;
+ }
+
+ @Override
+ public byte[] verifyPin(byte[] PIN_VERIFY) throws PINOperationAbortedException, CardException {
+ verifyPinStart(PIN_VERIFY);
+ byte resp;
+ do {
+ resp = getKeyPressed();
+ if (resp == (byte) 0x00) {
+ synchronized(this) {
+ try {
+ wait(200);
+ } catch (InterruptedException ex) {
+ log.error("interrupted in VERIFY_PIN");
+ }
+ }
+ } else if (resp == (byte) 0x0d) {
+ log.trace("user confirmed");
+ break;
+ } else if (resp == (byte) 0x2b) {
+ log.trace("user entered valid key (0-9)");
+ } else if (resp == (byte) 0x1b) {
+ log.info("user cancelled VERIFY_PIN via cancel button");
+ return verifyPinFinish();
+// return new byte[] { (byte) 0x64, (byte) 0x01 };
+ } else if (resp == (byte) 0x08) {
+ log.trace("user pressed correction/backspace button");
+ } else if (resp == (byte) 0x0e) {
+ log.trace("timeout occured");
+ return verifyPinFinish(); // return 0x64 0x00
+ } else if (resp == (byte) 0x40) {
+ log.trace("PIN_Operation_Aborted");
+ throw new PINOperationAbortedException("PIN_Operation_Aborted");
+ } else if (resp == (byte) 0x0a) {
+ log.trace("all keys cleared");
+ } else {
+ log.error("unexpected response to GET_KEY_PRESSED: " +
+ Integer.toHexString(resp));
+ throw new CardException("unexpected response to GET_KEY_PRESSED: " +
+ Integer.toHexString(resp));
+ }
+ } while (true); //resp != (byte) 0x0d);
+
+ return verifyPinFinish();
+ }
+
+ @Override
+ public byte[] modifyPin(byte[] PIN_MODIFY) throws PINOperationAbortedException, CardException {
+ modifyPinStart(PIN_MODIFY);
+ log.debug(PIN_MODIFY[9] + " pin confirmations expected");
+
+ byte resp;
+ short pinConfirmations = 0;
+ do {
+ resp = getKeyPressed();
+ if (resp == (byte) 0x00) {
+ synchronized(this) {
+ try {
+ wait(200);
+ } catch (InterruptedException ex) {
+ log.error("interrupted in MODIFY_PIN");
+ }
+ }
+ } else if (resp == (byte) 0x0d) {
+ log.trace("user confirmed");
+ pinConfirmations++;
+ continue;
+ } else if (resp == (byte) 0x2b) {
+ log.trace("user entered valid key (0-9)");
+ } else if (resp == (byte) 0x1b) {
+ log.info("user cancelled MODIFY_PIN via cancel button");
+// return verifyPinFinish();
+ return new byte[] { (byte) 0x64, (byte) 0x01 };
+ } else if (resp == (byte) 0x08) {
+ log.trace("user pressed correction/backspace button");
+ } else if (resp == (byte) 0x0e) {
+ log.trace("timeout occured");
+ return new byte[] { (byte) 0x64, (byte) 0x00 };
+// return verifyPinFinish(); // return 0x64 0x00
+ } else if (resp == (byte) 0x40) {
+ log.trace("PIN_Operation_Aborted");
+ throw new PINOperationAbortedException("PIN_Operation_Aborted");
+ } else if (resp == (byte) 0x0a) {
+ log.trace("all keys cleared");
+ } else {
+ log.error("unexpected response to GET_KEY_PRESSED: " +
+ Integer.toHexString(resp));
+ throw new CardException("unexpected response to GET_KEY_PRESSED: " +
+ Integer.toHexString(resp));
+ }
+ } while (pinConfirmations < PIN_MODIFY[9]);
+
+ return modifyPinFinish();
+ }
+
+ /**
+ * NOT SUPPORTED FOR ACOS ON OMNIKEY CardMan 3621
+ *
+ * @param PIN_MODIFY
+ * @return
+ * @throws javax.smartcardio.CardException
+ */
+ @Override
+ public byte[] modifyPinDirect(byte[] PIN_MODIFY) throws CardException {
+ if (!features.containsKey(FEATURE_MODIFY_PIN_DIRECT)) {
+ throw new CardException("FEATURE_MODIFY_PIN_DIRECT not supported");
+ }
+ int ioctl = features.get(FEATURE_MODIFY_PIN_DIRECT);
+ if (log.isTraceEnabled()) {
+ log.trace("MODIFY_PIN_DIRECT (" + Integer.toHexString(ioctl) +
+ ") " + SMCCHelper.toString(PIN_MODIFY));
+ }
+ byte[] resp = icc.transmitControlCommand(ioctl, PIN_MODIFY);
+ if (log.isTraceEnabled()) {
+ log.trace("response " + SMCCHelper.toString(resp));
+ }
+ return resp;
+ }
+
+
+//[TRACE] SmartCardIO - terminal 'PC/SC terminal OMNIKEY CardMan 3621 0' card inserted : PC/SC card in OMNIKEY CardMan 3621 0, protocol T=1, state OK
+//[TRACE] DefaultReader - GET_FEATURE_REQUEST 313520 on OMNIKEY CardMan 3621 0
+//[TRACE] DefaultReader - Response TLV [01:04:00:31:30:00:02:04:00:31:2f:d4:03:04:00:31:30:04:04:04:00:31:2f:dc:05:04:00:31:2f:e0:0a:04
+//00:31:30:08]
+//[INFO] DefaultReader - CCID supports FEATURE_VERIFY_PIN_START: 313000
+//[INFO] DefaultReader - CCID supports FEATURE_VERIFY_PIN_FINISH: ffffffd4
+//[INFO] DefaultReader - CCID supports FEATURE_MODIFY_PIN_START: 313004
+//[INFO] DefaultReader - CCID supports FEATURE_MODIFY_PIN_FINISH: ffffffdc
+//[INFO] DefaultReader - CCID supports FEATURE_GET_KEY_PRESSED: ffffffe0
+//[INFO] DefaultReader - CCID supports FEATURE_IFD_PIN_PROPERTIES: 313008
+//[TRACE] AbstractSignatureCard - Setting IFS (information field size) to 254
+
// protected byte ifdGetKeyPressed() throws CardException {
// if (ifdSupportsFeature(FEATURE_VERIFY_PIN_DIRECT)) {
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ccid/OMNIKEYCardMan3621.java b/smcc/src/main/java/at/gv/egiz/smcc/ccid/OMNIKEYCardMan3621.java
new file mode 100644
index 00000000..35dd4f99
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ccid/OMNIKEYCardMan3621.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.gv.egiz.smcc.ccid;
+
+import javax.smartcardio.Card;
+import javax.smartcardio.CardTerminal;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Fails with ACOS cards (Problem might be 'short' VERIFY which is not supported by ACOS)
+ * TODO
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public class OMNIKEYCardMan3621 extends DefaultReader {
+
+ protected static final Log log = LogFactory.getLog(OMNIKEYCardMan3621.class);
+
+ public OMNIKEYCardMan3621(Card icc, CardTerminal ct) {
+ super(icc, ct);
+ log.warn("This card reader does not support ACOS cards.");
+ log.debug("TODO: fall back to software pin entry");
+ }
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ccid/ReaderFactory.java b/smcc/src/main/java/at/gv/egiz/smcc/ccid/ReaderFactory.java
index 2cfcef19..07c16c3e 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/ccid/ReaderFactory.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ccid/ReaderFactory.java
@@ -29,6 +29,8 @@ public class ReaderFactory {
public static CCID getReader(Card icc, CardTerminal ct) {
if ("Gemplus GemPC Pinpad 00 00".equals(ct.getName())) {
return new GemplusGemPCPinpad(icc, ct);
+ } else if ("OmniKey CardMan 3621 00 00".equals(ct.getName())) {
+ return new OMNIKEYCardMan3621(icc, ct);
}
return new DefaultReader(icc, ct);
}
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/InfoBoxReadRequestHandler.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/InfoBoxReadRequestHandler.java
index 94444922..eeb97290 100644
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/InfoBoxReadRequestHandler.java
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/InfoBoxReadRequestHandler.java
@@ -37,21 +37,20 @@ public class InfoBoxReadRequestHandler extends AbstractRequestHandler {
private static Log log = LogFactory.getLog(InfoBoxReadRequestHandler.class);
- protected PINProviderFactory pinProviderFactory;
+// protected PINProviderFactory pinProviderFactory;
@Override
public STALResponse handleRequest(STALRequest request) throws InterruptedException {
if (request instanceof InfoboxReadRequest) {
InfoboxReadRequest infoBox = (InfoboxReadRequest) request;
- if (pinProviderFactory == null) {
- pinProviderFactory = PINProviderFactory.getInstance(card, gui);
- }
+
try {
if (infoBox.getInfoboxIdentifier().equals("IdentityLink")) {
newSTALMessage("Message.RequestCaption", "Message.IdentityLink");
log.debug("Handling identitylink infobox");
byte[] resp = card.getInfobox(infoBox.getInfoboxIdentifier(),
- pinProviderFactory.getCardPINProvider(),
+ new PINProviderFactory(card.getReader(), gui)
+ .getCardPINProvider(),
infoBox.getDomainIdentifier());
if (resp == null) {
log.info("Got null as result->user cancelled");
@@ -98,7 +97,8 @@ public class InfoBoxReadRequestHandler extends AbstractRequestHandler {
log.warn("Unknown infobox identifier: "
+ infoBox.getInfoboxIdentifier() + " trying generic request");
byte[] resp = card.getInfobox(infoBox.getInfoboxIdentifier(),
- pinProviderFactory.getCardPINProvider(),
+ new PINProviderFactory(card.getReader(), gui)
+ .getCardPINProvider(),
infoBox.getDomainIdentifier());
if (resp == null) {
return new ErrorResponse(6001);
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PINProviderFactory.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PINProviderFactory.java
index ce1b2d00..78ae6c2b 100644
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PINProviderFactory.java
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PINProviderFactory.java
@@ -18,31 +18,305 @@
package at.gv.egiz.bku.smccstal;
import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.ccid.CCID;
import at.gv.egiz.smcc.PINProvider;
-import at.gv.egiz.smcc.SignatureCard;
+import at.gv.egiz.smcc.PINSpec;
import at.gv.egiz.stal.signedinfo.SignedInfoType;
+import java.security.DigestException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
*
* @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
*/
-public abstract class PINProviderFactory {
+public class PINProviderFactory {
+
+ protected static final Log log = LogFactory.getLog(PINProviderFactory.class);
+
+ protected CCID reader;
+ protected BKUGUIFacade gui;
+
+ /**
+ * don't reuse the instance if the card reader might have changed!
+ * @param reader
+ * @param gui
+ */
+ public PINProviderFactory(CCID reader, BKUGUIFacade gui) {
+ log.trace("PINProviderFactory for " + reader.getName());
+ this.reader = reader;
+ this.gui = gui;
+ }
+
- BKUGUIFacade gui;
- public static PINProviderFactory getInstance(SignatureCard forCard,
- BKUGUIFacade gui) {
- if (forCard.getReader().hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) {
- return new PinpadPINProviderFactory(gui);
+// public static PINProviderFactory getInstance(SignatureCard forCard,
+// BKUGUIFacade gui) {
+// if (forCard.getReader().hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT) ||
+// forCard.getReader().hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) {
+// return new PinpadPINProviderFactory(gui);
+// } else {
+// return new SoftwarePINProviderFactory(gui);
+// }
+// }
+
+ /**
+ * don't reuse the instance if the card reader might have changed!
+ * @param reader
+ * @param gui
+ * @return
+ */
+// public static PINProviderFactory getInstance(CCID reader, BKUGUIFacade gui) {
+// log.trace("PINProviderFactory for " + reader.getName());
+// return new PINProviderFactory(reader, gui);
+// }
+
+ public PINProvider getSignaturePINProvider(SecureViewer viewer,
+ SignedInfoType signedInfo) {
+ if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_START) ||
+ reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) {
+ log.debug("pinpad signature-pin provider");
+ return new PinpadSignaturePinProvider(viewer, signedInfo);
} else {
- return new SoftwarePINProviderFactory(gui);
+ log.debug("software signature-pin provider");
+ return new SoftwareSignaturePinProvider(viewer, signedInfo);
}
}
- public abstract PINProvider getSignaturePINProvider(SecureViewer viewer,
- SignedInfoType signedInfo);
-
- public abstract PINProvider getCardPINProvider();
+ public PINProvider getCardPINProvider() {
+ if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_START) ||
+ reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) {
+ log.debug("pinpad card-pin provider");
+ return new PinpadCardPinProvider();
+ } else {
+ log.debug("software card-pin provider");
+ return new SoftwareCardPinProvider();
+ }
+ }
+
+ class SoftwareSignaturePinProvider extends AbstractPINProvider {
+
+ protected SecureViewer viewer;
+ protected SignedInfoType signedInfo;
+
+ private SoftwareSignaturePinProvider(SecureViewer viewer,
+ SignedInfoType signedInfo) {
+ this.viewer = viewer;
+ this.signedInfo = signedInfo;
+ }
+
+ @Override
+ public char[] providePIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+
+ gui.showSignaturePINDialog(spec, (retry) ? retries : -1,
+ this, "sign",
+ this, "cancel",
+ this, "secureViewer");
+
+ do {
+ waitForAction();
+
+ if ("secureViewer".equals(action)) {
+ try {
+ viewer.displayDataToBeSigned(signedInfo, this, "pinEntry");
+ } catch (DigestException ex) {
+ log.error("Bad digest value: " + ex.getMessage());
+ gui.showErrorDialog(BKUGUIFacade.ERR_INVALID_HASH,
+ new Object[]{ex.getMessage()},
+ this, "error");
+ } catch (Exception ex) {
+ log.error("Could not display hashdata inputs: " +
+ ex.getMessage());
+ gui.showErrorDialog(BKUGUIFacade.ERR_DISPLAY_HASHDATA,
+ new Object[]{ex.getMessage()},
+ this, "error");
+ }
+ } else if ("sign".equals(action)) {
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
+ BKUGUIFacade.MESSAGE_WAIT);
+ retry = true;
+ return gui.getPin();
+ } else if ("pinEntry".equals(action)) {
+ gui.showSignaturePINDialog(spec, (retry) ? retries : -1,
+ this, "sign",
+ this, "cancel",
+ this, "secureViewer");
+ } else if ("cancel".equals(action) ||
+ "error".equals(action)) {
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
+ BKUGUIFacade.MESSAGE_WAIT);
+ throw new CancelledException(spec.getLocalizedName() +
+ " entry cancelled");
+ } else {
+ log.error("unknown action command " + action);
+ }
+ } while (true);
+ }
+ }
+
+ class SoftwareCardPinProvider extends AbstractPINProvider {
+
+ private SoftwareCardPinProvider() {
+ }
+
+ @Override
+ public char[] providePIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+
+ gui.showCardPINDialog(spec, (retry) ? retries : -1,
+ this, "ok",
+ this, "cancel");
+
+ waitForAction();
+
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
+ BKUGUIFacade.MESSAGE_WAIT);
+
+ if ("cancel".equals(action)) {
+ throw new CancelledException(spec.getLocalizedName() +
+ " entry cancelled");
+ }
+ retry = true;
+ return gui.getPin();
+ }
+ }
+
+ class PinpadSignaturePinProvider extends AbstractPINProvider {
+// protected BKUGUIFacade gui;
+ protected SecureViewer viewer;
+ protected ViewerThread viewerThread;
+ protected SignedInfoType signedInfo;
+
+
+ private PinpadSignaturePinProvider(SecureViewer viewer,
+ SignedInfoType signedInfo) {
+ this.viewer = viewer;
+ this.signedInfo = signedInfo;
+ }
+
+ protected class ViewerThread extends Thread {
+
+ PINSpec pinSpec;
+ int retries;
+
+ public ViewerThread(PINSpec pinSpec, int retries) {
+ this.pinSpec = pinSpec;
+ this.retries = retries;
+ }
+
+ @Override
+ public void run() {
+
+ try {
+
+ gui.showPinpadSignaturePINDialog(pinSpec, retries,
+ PinpadSignaturePinProvider.this, "secureViewer");
+
+ while (true) {
+ waitForAction();
+
+ if ("secureViewer".equals(action)) {
+ viewer.displayDataToBeSigned(signedInfo,
+ PinpadSignaturePinProvider.this, "pinEntry");
+ } else if ("pinEntry".equals(action)) {
+ gui.showPinpadSignaturePINDialog(pinSpec, retries,
+ PinpadSignaturePinProvider.this, "secureViewer");
+ } else {
+ log.error("unsupported action command: " + action);
+ }
+ }
+
+ } catch (DigestException ex) {
+ log.error("Bad digest value: " + ex.getMessage());
+ gui.showErrorDialog(BKUGUIFacade.ERR_INVALID_HASH,
+ new Object[]{ex.getMessage()});
+ } catch (InterruptedException ex) {
+ log.info("pinpad secure viewer thread interrupted");
+ } catch (Exception ex) {
+ log.error("Could not display hashdata inputs: " +
+ ex.getMessage());
+ gui.showErrorDialog(BKUGUIFacade.ERR_DISPLAY_HASHDATA,
+ new Object[]{ex.getMessage()});
+ }
+ }
+ }
+
+ @Override
+ public char[] providePIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+
+ if (viewerThread != null) {
+ updateViewerThread(retries);
+ } else {
+ viewerThread = new ViewerThread(spec, -1);
+ viewerThread.start();
+ }
+// if (viewerThread != null) {
+// log.trace("interrupt old secure viewer thread");
+// viewerThread.interrupt();
+// }
+// viewerThread = new ViewerThread(spec, (retry) ? retries : -1);
+// log.trace("start new secure viewer thread");
+// viewerThread.start();
+
+ retry = true;
+ return null;
+ }
+
+ private synchronized void updateViewerThread(int retries) {
+ log.trace("update viewer thread");
+ viewerThread.retries = retries;
+ action = "pinEntry";
+ actionPerformed = true;
+ notify();
+ }
+
+
+// @Override
+// protected void finalize() throws Throwable {
+// if (viewerThread != null) {
+// viewerThread.interrupt();
+// }
+// log.info("finalizing Pinpad SignaturePinProvider");
+// super.finalize();
+// }
+ }
+
+ class PinpadCardPinProvider extends AbstractPINProvider {
+
+ private PinpadCardPinProvider() {
+ }
+
+ @Override
+ public char[] providePIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+
+ showPinpadPINDialog(retries, spec);
+ retry = true;
+ return null;
+
+ }
+
+ private void showPinpadPINDialog(int retries, PINSpec pinSpec) {
+ String title, message;
+ Object[] params;
+ if (retry) {
+ title = BKUGUIFacade.TITLE_RETRY;
+ message = BKUGUIFacade.MESSAGE_RETRIES;
+ params = new Object[]{String.valueOf(retries)};
+ } else {
+ title = BKUGUIFacade.TITLE_CARDPIN;
+ message = BKUGUIFacade.MESSAGE_ENTERPIN_PINPAD;
+ String pinSize = String.valueOf(pinSpec.getMinLength());
+ if (pinSpec.getMinLength() != pinSpec.getMaxLength()) {
+ pinSize += "-" + pinSpec.getMaxLength();
+ }
+ params = new Object[]{pinSpec.getLocalizedName(), pinSize};
+ }
+ gui.showMessageDialog(title, message, params);
+ }
+ }
}
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PinpadPINProviderFactory.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PinpadPINProviderFactory.java
deleted file mode 100644
index c109ceba..00000000
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PinpadPINProviderFactory.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright 2008 Federal Chancellery Austria and
- * Graz University of Technology
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package at.gv.egiz.bku.smccstal;
-
-import at.gv.egiz.bku.gui.BKUGUIFacade;
-import at.gv.egiz.smcc.CancelledException;
-import at.gv.egiz.smcc.PINProvider;
-import at.gv.egiz.smcc.PINSpec;
-import at.gv.egiz.stal.signedinfo.SignedInfoType;
-import java.security.DigestException;
-
-/**
- *
- * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
- */
-public class PinpadPINProviderFactory extends PINProviderFactory {
-
- protected PinpadPINProviderFactory(BKUGUIFacade gui) {
- this.gui = gui;
- }
-
- @Override
- public PINProvider getSignaturePINProvider(SecureViewer viewer,
- SignedInfoType signedInfo) {
-
- return new SignaturePinProvider(viewer, signedInfo);
- }
-
- @Override
- public PINProvider getCardPINProvider() {
- return new CardPinProvider();
- }
-
- class SignaturePinProvider extends AbstractPINProvider {
-
-// protected BKUGUIFacade gui;
- protected SecureViewer viewer;
- protected ViewerThread viewerThread;
- protected SignedInfoType signedInfo;
-
-
- private SignaturePinProvider(SecureViewer viewer,
- SignedInfoType signedInfo) {
- this.viewer = viewer;
- this.signedInfo = signedInfo;
- }
-
- protected class ViewerThread extends Thread {
-
- PINSpec pinSpec;
- int retries;
-
- public ViewerThread(PINSpec pinSpec, int retries) {
- this.pinSpec = pinSpec;
- this.retries = retries;
- }
-
- @Override
- public void run() {
-
- try {
-
- gui.showPinpadSignaturePINDialog(pinSpec, retries,
- SignaturePinProvider.this, "secureViewer");
-
- while (true) {
- waitForAction();
-
- if ("secureViewer".equals(action)) {
- viewer.displayDataToBeSigned(signedInfo,
- SignaturePinProvider.this, "pinEntry");
- } else if ("pinEntry".equals(action)) {
- gui.showPinpadSignaturePINDialog(pinSpec, retries,
- SignaturePinProvider.this, "secureViewer");
- } else {
- log.error("unsupported action command: " + action);
- }
- }
-
- } catch (DigestException ex) {
- log.error("Bad digest value: " + ex.getMessage());
- gui.showErrorDialog(BKUGUIFacade.ERR_INVALID_HASH,
- new Object[]{ex.getMessage()});
- } catch (InterruptedException ex) {
- log.info("pinpad secure viewer thread interrupted");
- } catch (Exception ex) {
- log.error("Could not display hashdata inputs: " +
- ex.getMessage());
- gui.showErrorDialog(BKUGUIFacade.ERR_DISPLAY_HASHDATA,
- new Object[]{ex.getMessage()});
- }
- }
- }
-
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
-
- if (viewerThread != null) {
- updateViewerThread(retries);
- } else {
- viewerThread = new ViewerThread(spec, -1);
- viewerThread.start();
- }
-// if (viewerThread != null) {
-// log.trace("interrupt old secure viewer thread");
-// viewerThread.interrupt();
-// }
-// viewerThread = new ViewerThread(spec, (retry) ? retries : -1);
-// log.trace("start new secure viewer thread");
-// viewerThread.start();
-
- retry = true;
- return null;
- }
-
- private synchronized void updateViewerThread(int retries) {
- log.trace("update viewer thread");
- viewerThread.retries = retries;
- action = "pinEntry";
- actionPerformed = true;
- notify();
- }
-
-
-// @Override
-// protected void finalize() throws Throwable {
-// if (viewerThread != null) {
-// viewerThread.interrupt();
-// }
-// log.info("finalizing Pinpad SignaturePinProvider");
-// super.finalize();
-// }
- }
-
- class CardPinProvider extends AbstractPINProvider {
-
- private CardPinProvider() {
- }
-
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
-
- showPinpadPINDialog(retries, spec);
- retry = true;
- return null;
-
- }
-
- private void showPinpadPINDialog(int retries, PINSpec pinSpec) {
- String title, message;
- Object[] params;
- if (retry) {
- title = BKUGUIFacade.TITLE_RETRY;
- message = BKUGUIFacade.MESSAGE_RETRIES;
- params = new Object[]{String.valueOf(retries)};
- } else {
- title = BKUGUIFacade.TITLE_CARDPIN;
- message = BKUGUIFacade.MESSAGE_ENTERPIN_PINPAD;
- String pinSize = String.valueOf(pinSpec.getMinLength());
- if (pinSpec.getMinLength() != pinSpec.getMaxLength()) {
- pinSize += "-" + pinSpec.getMaxLength();
- }
- params = new Object[]{pinSpec.getLocalizedName(), pinSize};
- }
- gui.showMessageDialog(title, message, params);
- }
- }
- }
-
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java
index 7a4f6572..56fc8804 100644
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java
@@ -50,7 +50,7 @@ public class SignRequestHandler extends AbstractRequestHandler {
private static Log log = LogFactory.getLog(SignRequestHandler.class);
private static JAXBContext jaxbContext;
- private PINProviderFactory pinProviderFactory;
+// private PINProviderFactory pinProviderFactory;
private SecureViewer secureViewer;
static {
@@ -86,11 +86,9 @@ public class SignRequestHandler extends AbstractRequestHandler {
md.update(signReq.getSignedInfo());
KeyboxName kb = SignatureCard.KeyboxName.getKeyboxName(signReq.getKeyIdentifier());
- if (pinProviderFactory == null) {
- pinProviderFactory = PINProviderFactory.getInstance(card, gui);
- }
- byte[] resp = card.createSignature(md.digest(), kb,
- pinProviderFactory.getSignaturePINProvider(secureViewer, si.getValue()));
+ byte[] resp = card.createSignature(md.digest(), kb,
+ new PINProviderFactory(card.getReader(), gui)
+ .getSignaturePINProvider(secureViewer, si.getValue()));
if (resp == null) {
return new ErrorResponse(6001);
}
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SoftwarePINProviderFactory.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SoftwarePINProviderFactory.java
deleted file mode 100644
index 7d36c2c3..00000000
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SoftwarePINProviderFactory.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2008 Federal Chancellery Austria and
- * Graz University of Technology
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package at.gv.egiz.bku.smccstal;
-
-import at.gv.egiz.bku.gui.BKUGUIFacade;
-import at.gv.egiz.smcc.*;
-import at.gv.egiz.stal.HashDataInput;
-import at.gv.egiz.stal.signedinfo.SignedInfoType;
-import java.security.DigestException;
-import java.util.List;
-
-/**
- *
- * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
- */
-public class SoftwarePINProviderFactory extends PINProviderFactory {
-
- protected SoftwarePINProviderFactory(BKUGUIFacade gui) {
- this.gui = gui;
- }
-
- @Override
- public PINProvider getSignaturePINProvider(SecureViewer viewer,
- SignedInfoType signedInfo) {
- return new SignaturePinProvider(viewer, signedInfo);
- }
-
- @Override
- public PINProvider getCardPINProvider() {
- return new CardPinProvider();
- }
-
- class SignaturePinProvider extends AbstractPINProvider {
-
-// protected BKUGUIFacade gui;
- protected SecureViewer viewer;
- protected SignedInfoType signedInfo;
-
- private SignaturePinProvider(SecureViewer viewer,
- SignedInfoType signedInfo) {
- this.viewer = viewer;
- this.signedInfo = signedInfo;
- }
-
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
-
- gui.showSignaturePINDialog(spec, (retry) ? retries : -1,
- this, "sign",
- this, "cancel",
- this, "secureViewer");
-
- do {
- waitForAction();
-
- if ("secureViewer".equals(action)) {
- try {
- viewer.displayDataToBeSigned(signedInfo, this, "pinEntry");
- } catch (DigestException ex) {
- log.error("Bad digest value: " + ex.getMessage());
- gui.showErrorDialog(BKUGUIFacade.ERR_INVALID_HASH,
- new Object[]{ex.getMessage()},
- this, "error");
- } catch (Exception ex) {
- log.error("Could not display hashdata inputs: " +
- ex.getMessage());
- gui.showErrorDialog(BKUGUIFacade.ERR_DISPLAY_HASHDATA,
- new Object[]{ex.getMessage()},
- this, "error");
- }
- } else if ("sign".equals(action)) {
- gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
- BKUGUIFacade.MESSAGE_WAIT);
- retry = true;
- return gui.getPin();
- } else if ("pinEntry".equals(action)) {
- gui.showSignaturePINDialog(spec, (retry) ? retries : -1,
- this, "sign",
- this, "cancel",
- this, "secureViewer");
- } else if ("cancel".equals(action) ||
- "error".equals(action)) {
- gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
- BKUGUIFacade.MESSAGE_WAIT);
- throw new CancelledException(spec.getLocalizedName() +
- " entry cancelled");
- } else {
- log.error("unknown action command " + action);
- }
- } while (true);
- }
- }
-
- class CardPinProvider extends AbstractPINProvider {
-
-// protected BKUGUIFacade gui;
-
- private CardPinProvider() {
- }
-
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
-
- gui.showCardPINDialog(spec, (retry) ? retries : -1,
- this, "ok",
- this, "cancel");
-
- waitForAction();
-
- gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
- BKUGUIFacade.MESSAGE_WAIT);
-
- if ("cancel".equals(action)) {
- throw new CancelledException(spec.getLocalizedName() +
- " entry cancelled");
- }
- retry = true;
- return gui.getPin();
- }
- }
-}