summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclemenso <clemenso@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2010-01-05 10:06:47 +0000
committerclemenso <clemenso@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2010-01-05 10:06:47 +0000
commit3da4655d011dfc2f04f9e4ac28b38aee42d01bc0 (patch)
treed9b524ca4ccfd6e48573dfecf5191ccba48278af
parentecc11bdb13ae27385486ad1c944ee01ffd0440e7 (diff)
downloadmocca-3da4655d011dfc2f04f9e4ac28b38aee42d01bc0.tar.gz
mocca-3da4655d011dfc2f04f9e4ac28b38aee42d01bc0.tar.bz2
mocca-3da4655d011dfc2f04f9e4ac28b38aee42d01bc0.zip
Features
[#437] Handle pinpad [64:03] response apdu correctly [#445] pin entry feedback for VERIFY_PIN_START/FINISH [#471] Provide SecureViewer Link before Pinpad PinEntry timeout starts Bugs [#479] PIN Managment Applet allows unmatching new pin and pin confirmation [#480] PIN Management displays blocked PINs as ACTIVE [#486] Not possible to select 3 times in series the same item from signedReferencesList for display in secureViewer [#506] change pin dialog (gui) issues [#508] e-card G3 PIN activation (with TransportPIN) not supported [#509] closing secure viewer window (WINDOW_CLOSING) leaves "signature data is displayed in viewer" dialog in applet git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@565 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java28
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java765
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/PinDocument.java125
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SecureViewerDialog.java118
-rw-r--r--BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties9
-rw-r--r--BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties9
-rw-r--r--BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java13
-rw-r--r--BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/ComparePinDocument.java102
-rw-r--r--BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/ExtendedPinDocument.java108
-rw-r--r--BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUI.java163
-rw-r--r--BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java66
-rw-r--r--BKUGuiExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties36
-rw-r--r--BKUGuiExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties34
-rw-r--r--BKUOnline/src/main/resources/log4j.properties2
-rw-r--r--BKUOnline/src/main/webapp/META-INF/context.xml2
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java44
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java14
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/BELPICCard.java11
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ITCard.java11
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/PINConfirmationException.java19
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/PINFormatException.java19
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/PINMgmtSignatureCard.java11
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ResetRetryCounterAPDUSpec.java38
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java208
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/SWCard.java106
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java9
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/pin/gui/ModifyPINGUI.java36
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/pin/gui/ModifyPINProvider.java (renamed from smcc/src/main/java/at/gv/egiz/smcc/ChangePINProvider.java)20
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/pin/gui/PINGUI.java42
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/pin/gui/PINProvider.java (renamed from smcc/src/main/java/at/gv/egiz/smcc/PINProvider.java)8
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/reader/CardReader.java92
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/reader/DefaultCardReader.java106
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java703
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/reader/ReaderFactory.java128
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/AbstractAppl.java1
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/CardEmul.java14
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/CardTest.java171
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/PIN.java10
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/acos/A03ApplDEC.java2
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/acos/A03CardEmul.java7
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/acos/A03CardTest.java9
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/acos/A04CardEmul.java7
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/acos/A04CardTest.java12
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSApplDEC.java2
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSApplSIG.java2
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSCardTest.java21
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/pin/gui/CancelChangePINProvider.java39
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/pin/gui/CancelPINProvider.java29
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/pin/gui/ChangePINProvider.java49
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/pin/gui/DummyChangePINGUI.java68
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/pin/gui/DummyPINGUI.java48
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InterruptPINProvider.java34
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InvalidChangePINProvider.java56
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InvalidPINProvider.java48
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/pin/gui/SMCCTestPINProvider.java43
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSAppl.java23
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplGewoehnlicheSignatur.java27
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplInfobox.java5
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplSichereSignatur.java36
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardChannelEmul.java105
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardEmul.java24
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardTest.java132
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSG3CardChannelEmul.java46
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSG3CardEmul.java57
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSG3CardTest.java119
-rw-r--r--smccSTAL/src/main/java/META-INF/MANIFEST.MF3
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/AbstractPINProvider.java (renamed from smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractPINProvider.java)15
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINGUI.java136
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINProvider.java105
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/VerifyPINGUI.java76
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/VerifyPINProvider.java72
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/InfoBoxReadRequestHandler.java9
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PINProviderFactory.java327
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java4
-rw-r--r--smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java13
-rw-r--r--smccSTALExt/src/main/java/at/gv/egiz/bku/pin/gui/ManagementPINGUI.java88
-rw-r--r--smccSTALExt/src/main/java/at/gv/egiz/bku/pin/gui/ManagementPINProvider.java89
-rw-r--r--smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/ManagementPINProviderFactory.java246
-rw-r--r--smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/PINManagementRequestHandler.java210
79 files changed, 3880 insertions, 1964 deletions
diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java
index 91c91dcb..1e23c64c 100644
--- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java
+++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java
@@ -16,7 +16,7 @@
*/
package at.gv.egiz.bku.gui;
-import at.gv.egiz.stal.HashDataInput;
+ import at.gv.egiz.stal.HashDataInput;
import at.gv.egiz.smcc.PINSpec;
import java.awt.Color;
import java.awt.event.ActionListener;
@@ -53,14 +53,15 @@ public interface BKUGUIFacade {
public static final String TITLE_WELCOME = "title.welcome";
public static final String TITLE_INSERTCARD = "title.insertcard";
public static final String TITLE_CARD_NOT_SUPPORTED = "title.cardnotsupported";
- public static final String TITLE_CARDPIN = "title.cardpin";
+ public static final String TITLE_VERIFY_PIN = "title.verify.pin";
public static final String TITLE_SIGN = "title.sign";
+ public static final String TITLE_VERIFY_PINPAD = "title.verify.pinpad";
public static final String TITLE_ERROR = "title.error";
public static final String TITLE_WARNING = "title.warning";
public static final String TITLE_ENTRY_TIMEOUT = "title.entry.timeout";
public static final String TITLE_RETRY = "title.retry";
public static final String TITLE_WAIT = "title.wait";
- public static final String TITLE_HASHDATA = "title.hashdata";
+ public static final String TITLE_SIGNATURE_DATA = "title.signature.data";
public static final String WINDOWTITLE_SAVE = "windowtitle.save";
public static final String WINDOWTITLE_ERROR = "windowtitle.error";
public static final String WINDOWTITLE_SAVEDIR = "windowtitle.savedir";
@@ -75,6 +76,7 @@ public interface BKUGUIFacade {
public static final String MESSAGE_CARD_NOT_SUPPORTED = "cardnotsupported";
public static final String MESSAGE_ENTERPIN = "enterpin";
public static final String MESSAGE_ENTERPIN_PINPAD = "enterpin.pinpad";
+ public static final String MESSAGE_ENTERPIN_PINPAD_DIRECT = "enterpin.pinpad.direct";
public static final String MESSAGE_HASHDATALINK = "hashdatalink";
public static final String MESSAGE_HASHDATALINK_TINY = "hashdatalink.tiny";
public static final String MESSAGE_HASHDATALINK_FOCUS = "hashdatalink.focus";
@@ -96,8 +98,9 @@ public interface BKUGUIFacade {
public static final String HELP_WAIT = "help.wait";
public static final String HELP_CARDNOTSUPPORTED = "help.cardnotsupported";
public static final String HELP_INSERTCARD = "help.insertcard";
- public static final String HELP_CARDPIN = "help.cardpin";
+ public static final String HELP_VERIFY_PIN = "help.cardpin";
public static final String HELP_SIGNPIN = "help.signpin";
+ public static final String HELP_PINPAD = "help.pinpad";
public static final String HELP_RETRY = "help.retry";
public static final String HELP_HASHDATA = "help.hashdata";
public static final String HELP_HASHDATALIST = "help.hashdatalist";
@@ -111,6 +114,18 @@ public interface BKUGUIFacade {
public static final String SAVE_HASHDATAINPUT_PREFIX = "save.hashdatainput.prefix";
public static final String ALT_HELP = "alt.help";
+ public void showEnterPINDirect(PINSpec spec, int retries);
+
+ public void showEnterPIN(PINSpec spec, int retries);
+
+ public void showSignatureDataDialog(PINSpec spec, ActionListener listener, String string, ActionListener aThis0, String string0, ActionListener aThis1, String string1);
+
+ public void correctionButtonPressed();
+
+ public void allKeysCleared();
+
+ public void validKeyPressed();
+
public enum Style { tiny, simple, advanced };
/**
@@ -119,7 +134,7 @@ public interface BKUGUIFacade {
*/
public Locale getLocale();
- public void showCardPINDialog(PINSpec pinSpec, int numRetries,
+ public void showVerifyPINDialog(PINSpec pinSpec, int numRetries,
ActionListener okListener, String okCommand,
ActionListener cancelListener, String cancelCommand);
@@ -128,9 +143,6 @@ public interface BKUGUIFacade {
ActionListener cancelListener, String cancelCommand,
ActionListener viewerListener, String viewerCommand);
- public void showPinpadSignaturePINDialog(PINSpec pinSpec, int numRetries,
- ActionListener viewerListener, String viewerCommand);
-
public char[] getPin();
/**
diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java
index baffb3fd..3fc631c3 100644
--- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java
+++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java
@@ -93,6 +93,7 @@ public class BKUGUIImpl implements BKUGUIFacade {
protected JLabel switchFocusDummyLabel;
/** remember the pinfield to return to worker */
protected JPasswordField pinField;
+ protected JPasswordField pinpadPINField;
protected int buttonSize;
@@ -360,221 +361,27 @@ public class BKUGUIImpl implements BKUGUIFacade {
return messages.containsKey(key);
}
-// @Override
-// public void showWelcomeDialog() {
-//
-// log.debug("scheduling welcome dialog");
-//
-// SwingUtilities.invokeLater(new Runnable() {
-//
-// @Override
-// public void run() {
-//
-// log.debug("show welcome dialog");
-//
-// mainPanel.removeAll();
-// buttonPanel.removeAll();
-//
-// helpListener.setHelpTopic(HELP_WELCOME);
-//
-// JLabel welcomeMsgLabel = new JLabel();
-// welcomeMsgLabel.setFont(welcomeMsgLabel.getFont().deriveFont(welcomeMsgLabel.getFont().getStyle() & ~java.awt.Font.BOLD));
-//
-// if (renderHeaderPanel) {
-// titleLabel.setText(getMessage(TITLE_WELCOME));
-// welcomeMsgLabel.setText(getMessage(MESSAGE_WAIT));
-// } else {
-// welcomeMsgLabel.setText(getMessage(TITLE_WELCOME));
-// }
-//
-// GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
-// mainPanel.setLayout(mainPanelLayout);
-//
-// GroupLayout.SequentialGroup messageHorizontal = mainPanelLayout.createSequentialGroup()
-// .addComponent(welcomeMsgLabel);
-// GroupLayout.Group messageVertical = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
-// .addComponent(welcomeMsgLabel);
-// if (!renderHeaderPanel) {
-// messageHorizontal
-// .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE)
-// .addComponent(helpLabel);
-// messageVertical
-// .addComponent(helpLabel);
-// }
-//
-// mainPanelLayout.setHorizontalGroup(messageHorizontal);
-// mainPanelLayout.setVerticalGroup(messageVertical);
-//
-// contentPanel.validate();
-//
-// }
-// });
-// }
-
-// @Override
-// public void showInsertCardDialog(
-// final ActionListener cancelListener, final String cancelCommand) {
-//
-// log.debug("scheduling insert card dialog");
-//
-// SwingUtilities.invokeLater(new Runnable() {
-//
-// @Override
-// public void run() {
-//
-// log.debug("show insert card dialog");
-//
-// mainPanel.removeAll();
-// buttonPanel.removeAll();
-//
-// if (renderHeaderPanel) {
-// titleLabel.setText(getMessage(TITLE_INSERTCARD));
-// }
-//
-// helpListener.setHelpTopic(HELP_INSERTCARD);
-//
-// JLabel insertCardMsgLabel = new JLabel();
-// insertCardMsgLabel.setFont(insertCardMsgLabel.getFont().deriveFont(insertCardMsgLabel.getFont().getStyle() & ~java.awt.Font.BOLD));
-// insertCardMsgLabel.setText(getMessage(MESSAGE_INSERTCARD));
-//
-// GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
-// mainPanel.setLayout(mainPanelLayout);
-//
-// GroupLayout.SequentialGroup messageHorizontal = mainPanelLayout.createSequentialGroup()
-// .addComponent(insertCardMsgLabel);
-// GroupLayout.ParallelGroup messageVertical = mainPanelLayout.createParallelGroup()
-// .addComponent(insertCardMsgLabel);
-//
-// if (!renderHeaderPanel) {
-// messageHorizontal
-// .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE)
-// .addComponent(helpLabel);
-// messageVertical
-// .addComponent(helpLabel);
-// }
-//
-// mainPanelLayout.setHorizontalGroup(messageHorizontal);
-// mainPanelLayout.setVerticalGroup(messageVertical);
-//
-// if (renderCancelButton) {
-// JButton cancelButton = new JButton();
-// cancelButton.setFont(cancelButton.getFont().deriveFont(cancelButton.getFont().getStyle() & ~java.awt.Font.BOLD));
-// cancelButton.setText(getMessage(BUTTON_CANCEL));
-// cancelButton.addActionListener(cancelListener);
-// cancelButton.setActionCommand(cancelCommand);
-//
-// GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel);
-// buttonPanel.setLayout(buttonPanelLayout);
-//
-// buttonPanelLayout.setHorizontalGroup(
-// buttonPanelLayout.createSequentialGroup()
-// .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-// .addComponent(cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE));
-// buttonPanelLayout.setVerticalGroup(
-// buttonPanelLayout.createSequentialGroup()
-// .addComponent(cancelButton));
-// }
-//
-// contentPanel.validate();
-// }
-// });
-// }
-
- /**
- * only difference to showInsertCard: title text: card not supported
- * @param cancelListener
- * @param cancelCommand
- */
-// @Override
-// public void showCardNotSupportedDialog(final ActionListener cancelListener, final String cancelCommand) {
-//
-// log.debug("scheduling card not supported dialog");
-//
-// SwingUtilities.invokeLater(new Runnable() {
-//
-// @Override
-// public void run() {
-//
-// log.debug("show card not supported dialog");
-//
-// mainPanel.removeAll();
-// buttonPanel.removeAll();
-//
-// JLabel insertCardMsgLabel = new JLabel();
-// insertCardMsgLabel.setFont(insertCardMsgLabel.getFont().deriveFont(insertCardMsgLabel.getFont().getStyle() & ~java.awt.Font.BOLD));
-//
-// if (renderHeaderPanel) {
-// titleLabel.setText(getMessage(TITLE_CARD_NOT_SUPPORTED));
-// insertCardMsgLabel.setText(getMessage(MESSAGE_INSERTCARD));
-// } else {
-// insertCardMsgLabel.setText(getMessage(TITLE_CARD_NOT_SUPPORTED));
-// }
-//
-// helpListener.setHelpTopic(HELP_CARDNOTSUPPORTED);
-//
-// GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
-// mainPanel.setLayout(mainPanelLayout);
-//
-// GroupLayout.SequentialGroup messageHorizontal = mainPanelLayout.createSequentialGroup()
-// .addComponent(insertCardMsgLabel);
-// GroupLayout.Group messageVertical = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
-// .addComponent(insertCardMsgLabel);
-// if (!renderHeaderPanel) {
-// messageHorizontal
-// .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE)
-// .addComponent(helpLabel);
-// messageVertical
-// .addComponent(helpLabel);
-// }
-//
-// mainPanelLayout.setHorizontalGroup(messageHorizontal);
-// mainPanelLayout.setVerticalGroup(messageVertical);
-//
-// if (renderCancelButton) {
-// JButton cancelButton = new JButton();
-// cancelButton.setFont(cancelButton.getFont().deriveFont(cancelButton.getFont().getStyle() & ~java.awt.Font.BOLD));
-// cancelButton.setText(getMessage(BUTTON_CANCEL));
-// cancelButton.addActionListener(cancelListener);
-// cancelButton.setActionCommand(cancelCommand);
-//
-// GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel);
-// buttonPanel.setLayout(buttonPanelLayout);
-//
-// buttonPanelLayout.setHorizontalGroup(
-// buttonPanelLayout.createSequentialGroup()
-// .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-// .addComponent(cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE));
-// buttonPanelLayout.setVerticalGroup(
-// buttonPanelLayout.createSequentialGroup()
-// .addComponent(cancelButton));
-// }
-//
-// contentPanel.validate();
-// }
-// });
-// }
-
@Override
- public void showCardPINDialog(final PINSpec pinSpec, final int numRetries,
+ public void showVerifyPINDialog(final PINSpec pinSpec, final int numRetries,
final ActionListener okListener, final String okCommand,
final ActionListener cancelListener, final String cancelCommand) {
- log.debug("scheduling card-pin dialog");
+ log.debug("scheduling verify pin dialog");
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
- log.debug("[" + Thread.currentThread().getName() + "] show card-pin dialog");
+ log.debug("[" + Thread.currentThread().getName() + "] show verify pin dialog");
mainPanel.removeAll();
buttonPanel.removeAll();
if (renderHeaderPanel) {
if (numRetries < 0) {
- String cardpinTitle = getMessage(TITLE_CARDPIN);
- titleLabel.setText(MessageFormat.format(cardpinTitle, new Object[]{pinSpec.getLocalizedName()}));
+ String verifyTitle = getMessage(TITLE_VERIFY_PIN);
+ titleLabel.setText(MessageFormat.format(verifyTitle, new Object[]{pinSpec.getLocalizedName()}));
} else {
titleLabel.setText(getMessage(TITLE_RETRY));
}
@@ -615,8 +422,8 @@ public class BKUGUIImpl implements BKUGUIFacade {
} else {
infoLabel.setText(MessageFormat.format(infoPattern, new Object[] {pinSpec.getLocalizedName()}));
}
- helpMouseListener.setHelpTopic(HELP_CARDPIN);
- helpKeyListener.setHelpTopic(HELP_CARDPIN);
+ helpMouseListener.setHelpTopic(HELP_VERIFY_PIN);
+ helpKeyListener.setHelpTopic(HELP_VERIFY_PIN);
} else {
String retryPattern;
if (numRetries < 2) {
@@ -732,194 +539,346 @@ public class BKUGUIImpl implements BKUGUIFacade {
});
}
-// @Override
-// public void showCardPINDialog(PINSpec pinSpec, ActionListener okListener, String okCommand, ActionListener cancelListener, String cancelCommand) {
-// showCardPINDialog(pinSpec, -1, okListener, okCommand, cancelListener, cancelCommand);
-// }
-//
-// @Override
-// public void showCardPINRetryDialog(PINSpec pinSpec, int numRetries, ActionListener okListener, String okCommand, ActionListener cancelListener, String cancelCommand) {
-// showCardPINDialog(pinSpec, numRetries, okListener, okCommand, cancelListener, cancelCommand);
-// }
+ @Override
+ public void showEnterPINDirect(PINSpec pinSpec, int retries) {
+ if (retries < 0) {
+ showMessageDialog(TITLE_VERIFY_PINPAD, MESSAGE_ENTERPIN_PINPAD_DIRECT, new Object[] {
+ pinSpec.getLocalizedName(), pinSpec.getLocalizedLength() });
+ } else {
+ showMessageDialog(TITLE_RETRY, MESSAGE_RETRIES, new Object[]{String.valueOf(retries) });
+ }
+ }
-// @Override
-// public void showSignaturePINDialog(PINSpec pinSpec, ActionListener signListener, String signCommand, ActionListener cancelListener, String cancelCommand, ActionListener hashdataListener, String hashdataCommand) {
-// showSignaturePINDialog(pinSpec, -1, signListener, signCommand, cancelListener, cancelCommand, hashdataListener, hashdataCommand);
-// }
+ @Override
+ public void showEnterPIN(final PINSpec pinSpec, final int retries) {
+ showEnterPIN(pinSpec, retries, TITLE_VERIFY_PINPAD, MESSAGE_ENTERPIN_PINPAD, null);
+ }
- @Override
- public void showPinpadSignaturePINDialog(final PINSpec pinSpec, final int numRetries,
-// final ActionListener cancelListener, final String cancelCommand,
- final ActionListener hashdataListener, final String hashdataCommand) {
+ protected void showEnterPIN(final PINSpec pinSpec, final int retries, final String titleKey, final String messageKey, final Object[] messageParams) {
+ log.debug("scheduling pinpad dialog");
- log.debug("scheduling pinpad signature-pin dialog");
+ SwingUtilities.invokeLater(new Runnable() {
- SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
- @Override
- public void run() {
+ log.debug("[" + Thread.currentThread().getName() + "] show pinpad dialog");
- log.debug("[" + Thread.currentThread().getName() + "] show pinpad signature-pin dialog");
+ mainPanel.removeAll();
+ buttonPanel.removeAll();
- mainPanel.removeAll();
- buttonPanel.removeAll();
+ if (renderHeaderPanel) {
+ if (retries < 0) {
+ titleLabel.setText(getMessage(titleKey));
+ } else {
+ titleLabel.setText(getMessage(TITLE_RETRY));
+ }
+ }
- if (renderHeaderPanel) {
- if (numRetries < 0) {
- titleLabel.setText(getMessage(TITLE_SIGN));
- } else {
- titleLabel.setText(getMessage(TITLE_RETRY));
- }
- }
+ final JLabel infoLabel = new JLabel();
+ if (retries < 0) {
+ infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() & ~java.awt.Font.BOLD));
+ infoLabel.setText(MessageFormat.format(getMessage(messageKey), messageParams));
+ helpMouseListener.setHelpTopic(HELP_PINPAD);
+ helpKeyListener.setHelpTopic(HELP_PINPAD);
+ } else {
+ String retryPattern;
+ if (retries == 1) {
+ retryPattern = getMessage(MESSAGE_LAST_RETRY);
+ } else {
+ retryPattern = getMessage(MESSAGE_RETRIES);
+ }
+ infoLabel.setText(MessageFormat.format(retryPattern, new Object[]{String.valueOf(retries)}));
+ infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() | java.awt.Font.BOLD));
+ infoLabel.setForeground(ERROR_COLOR);
+ helpMouseListener.setHelpTopic(HELP_RETRY);
+ helpKeyListener.setHelpTopic(HELP_RETRY);
+ }
+
+ JLabel pinLabel = new JLabel();
+ pinLabel.setFont(pinLabel.getFont().deriveFont(pinLabel.getFont().getStyle() & ~java.awt.Font.BOLD));
+ String pinName = getMessage(LABEL_PIN);
+ pinLabel.setText(MessageFormat.format(pinName, new Object[]{pinSpec.getLocalizedName()}));
+
+ pinpadPINField = new JPasswordField();
+ pinpadPINField.setText("");
+ pinpadPINField.setEnabled(false);
+
+ JLabel pinsizeLabel = new JLabel();
+ pinsizeLabel.setFont(pinsizeLabel.getFont().deriveFont(pinsizeLabel.getFont().getStyle() & ~java.awt.Font.BOLD, pinsizeLabel.getFont().getSize()-2));
+ pinsizeLabel.setText(MessageFormat.format(getMessage(LABEL_PINSIZE), pinSpec.getLocalizedLength()));
+
+ GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
+ mainPanel.setLayout(mainPanelLayout);
+
+ GroupLayout.SequentialGroup infoHorizontal = mainPanelLayout.createSequentialGroup()
+ .addComponent(infoLabel);
+ GroupLayout.ParallelGroup infoVertical = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addComponent(infoLabel);
+
+ if (!renderHeaderPanel) {
+ infoHorizontal
+ .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE)
+ .addComponent(switchFocusDummyLabel)
+ .addComponent(helpLabel)
+ ;
+ infoVertical
+ .addComponent(switchFocusDummyLabel)
+ .addComponent(helpLabel)
+ ;
+ }
+
+ // align pinfield and pinsize to the right
+ GroupLayout.Group pinHorizontal = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.TRAILING);
+ GroupLayout.SequentialGroup pinVertical = mainPanelLayout.createSequentialGroup();
+
+ if (pinLabelPos == PinLabelPosition.ABOVE) {
+ pinHorizontal
+ .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addComponent(pinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+ .addComponent(pinpadPINField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addComponent(pinsizeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE);
+ pinVertical
+ .addComponent(pinLabel)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pinpadPINField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pinsizeLabel);
+ } else { // PinLabelPosition.LEFT
+ pinHorizontal
+ .addGroup(mainPanelLayout.createSequentialGroup()
+ .addComponent(pinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pinpadPINField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addComponent(pinsizeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE);
+ pinVertical
+ .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
+ .addComponent(pinLabel)
+ .addComponent(pinpadPINField))
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pinsizeLabel);
+ }
+
+ mainPanelLayout.setHorizontalGroup(
+ mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addGroup(infoHorizontal)
+ .addGroup(pinHorizontal));
+
+ mainPanelLayout.setVerticalGroup(
+ mainPanelLayout.createSequentialGroup()
+ .addGroup(infoVertical)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pinVertical));
+
+ contentPanel.validate();
+ }
+ });
+ }
+
+ @Override
+ public void showSignatureDataDialog(PINSpec spec,
+ final ActionListener enterPINListener, final String enterPINCommand,
+ final ActionListener cancelListener, final String cancelCommand,
+ final ActionListener hashdataListener, final String hashdataCommand) {
+
+ log.debug("scheduling signature-data dialog");
+
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+
+ log.debug("[" + Thread.currentThread().getName() + "] show signature-data dialog");
+
+ mainPanel.removeAll();
+ buttonPanel.removeAll();
+
+ if (renderHeaderPanel) {
+ titleLabel.setText(getMessage(TITLE_SIGNATURE_DATA));
+ }
+
+ final JLabel infoLabel = new JLabel();
+ infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() & ~java.awt.Font.BOLD));
+ if (shortText) {
+ infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY));
+ } else {
+ infoLabel.setText(getMessage(MESSAGE_HASHDATALINK));
+ }
+ infoLabel.setFocusable(true);
+ infoLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ infoLabel.setForeground(HYPERLINK_COLOR);
+ infoLabel.addMouseListener(new MouseAdapter() {
+
+ @Override
+ public void mouseClicked(MouseEvent me) {
+ ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, hashdataCommand);
+ hashdataListener.actionPerformed(e);
+ }
+ });
+
+ infoLabel.addKeyListener(new KeyAdapter() {
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+
+ if(e.getKeyCode() == KeyEvent.VK_ENTER) {
+ ActionEvent e1 = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, hashdataCommand);
+ hashdataListener.actionPerformed(e1);
+ }
+ }
+
+ });
+
+ infoLabel.addFocusListener(new FocusAdapter() {
+
+ @Override
+ public void focusGained(FocusEvent e) {
- final JLabel infoLabel = new JLabel();
- if (numRetries < 0) {
- infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() & ~java.awt.Font.BOLD));
if (shortText) {
- infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY));
- } else {
- infoLabel.setText(getMessage(MESSAGE_HASHDATALINK));
- }
- infoLabel.setFocusable(true);
- infoLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
- infoLabel.setForeground(HYPERLINK_COLOR);
- infoLabel.addMouseListener(new MouseAdapter() {
+ infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY_FOCUS));
+ } else {
+ infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_FOCUS));
+ }
+ }
- @Override
- public void mouseClicked(MouseEvent me) {
- ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, hashdataCommand);
- hashdataListener.actionPerformed(e);
- }
- });
-
- infoLabel.addKeyListener(new KeyAdapter() {
-
- @Override
- public void keyPressed(KeyEvent e) {
-
- if(e.getKeyCode() == KeyEvent.VK_ENTER) {
- ActionEvent e1 = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, hashdataCommand);
- hashdataListener.actionPerformed(e1);
- }
- }
-
- });
-
- infoLabel.addFocusListener(new FocusAdapter() {
-
- @Override
- public void focusGained(FocusEvent e) {
-
- if (shortText) {
- infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY_FOCUS));
- } else {
- infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_FOCUS));
- }
- }
-
- @Override
- public void focusLost(FocusEvent e) {
-
- if (shortText) {
- infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY));
- } else {
- infoLabel.setText(getMessage(MESSAGE_HASHDATALINK));
- }
-
- }
-
- });
-
- helpMouseListener.setHelpTopic(HELP_SIGNPIN);
- helpKeyListener.setHelpTopic(HELP_SIGNPIN);
- } else {
- String retryPattern;
- if (numRetries < 2) {
- retryPattern = getMessage(MESSAGE_LAST_RETRY);
- } else {
- retryPattern = getMessage(MESSAGE_RETRIES);
- }
- infoLabel.setFocusable(true);
- infoLabel.setText(MessageFormat.format(retryPattern, new Object[]{String.valueOf(numRetries)}));
- infoLabel.setFont(infoLabel.getFont().deriveFont(infoLabel.getFont().getStyle() | java.awt.Font.BOLD));
- infoLabel.setForeground(ERROR_COLOR);
- helpMouseListener.setHelpTopic(HELP_RETRY);
- helpKeyListener.setHelpTopic(HELP_RETRY);
- }
+ @Override
+ public void focusLost(FocusEvent e) {
- String msgPattern = getMessage(MESSAGE_ENTERPIN_PINPAD);
- String msg = MessageFormat.format(msgPattern, new Object[] {
- pinSpec.getLocalizedName(), pinSpec.getLocalizedLength() });
+ if (shortText) {
+ infoLabel.setText(getMessage(MESSAGE_HASHDATALINK_TINY));
+ } else {
+ infoLabel.setText(getMessage(MESSAGE_HASHDATALINK));
+ }
- JLabel msgLabel = new JLabel();
- msgLabel.setFont(msgLabel.getFont().deriveFont(msgLabel.getFont().getStyle() & ~Font.BOLD));
- msgLabel.setText(msg);
+ }
- GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
- mainPanel.setLayout(mainPanelLayout);
+ });
- GroupLayout.SequentialGroup infoHorizontal = mainPanelLayout.createSequentialGroup()
- .addComponent(infoLabel);
- GroupLayout.ParallelGroup infoVertical = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
- .addComponent(infoLabel);
+ helpMouseListener.setHelpTopic(HELP_SIGNPIN);
+ helpKeyListener.setHelpTopic(HELP_SIGNPIN);
- if (!renderHeaderPanel) {
- infoHorizontal
- .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE)
- .addComponent(switchFocusDummyLabel)
- .addComponent(helpLabel)
- ;
- infoVertical
- .addComponent(switchFocusDummyLabel)
- .addComponent(helpLabel)
- ;
- }
+ //TODO message panel
- mainPanelLayout.setHorizontalGroup(
- mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
- .addGroup(infoHorizontal)
- .addComponent(msgLabel));
+// String msgPattern = getMessage(MESSAGE_ENTERPIN_PINPAD);
+// String msg = MessageFormat.format(msgPattern, new Object[] {
+// pinSpec.getLocalizedName(), pinSpec.getLocalizedLength() });
+//
+// JLabel msgLabel = new JLabel();
+// msgLabel.setFont(msgLabel.getFont().deriveFont(msgLabel.getFont().getStyle() & ~Font.BOLD));
+// msgLabel.setText(msg);
- mainPanelLayout.setVerticalGroup(
- mainPanelLayout.createSequentialGroup()
- .addGroup(infoVertical)
+ GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
+ mainPanel.setLayout(mainPanelLayout);
+
+ GroupLayout.SequentialGroup infoHorizontal = mainPanelLayout.createSequentialGroup()
+ .addComponent(infoLabel);
+ GroupLayout.ParallelGroup infoVertical = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addComponent(infoLabel);
+
+ if (!renderHeaderPanel) {
+ infoHorizontal
+ .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE)
+ .addComponent(switchFocusDummyLabel)
+ .addComponent(helpLabel)
+ ;
+ infoVertical
+ .addComponent(switchFocusDummyLabel)
+ .addComponent(helpLabel)
+ ;
+ }
+
+ mainPanelLayout.setHorizontalGroup(
+ infoHorizontal);
+// mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
+// .addGroup(infoHorizontal)
+// .addComponent(msgLabel));
+
+ mainPanelLayout.setVerticalGroup(
+ infoVertical);
+// mainPanelLayout.createSequentialGroup()
+// .addGroup(infoVertical)
+// .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+// .addComponent(msgLabel));
+
+
+ GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel);
+ buttonPanel.setLayout(buttonPanelLayout);
+
+ GroupLayout.SequentialGroup buttonHorizontal = buttonPanelLayout.createSequentialGroup();
+ GroupLayout.Group buttonVertical;
+
+ JButton enterPINButton = new JButton();
+ enterPINButton.setFont(enterPINButton.getFont().deriveFont(enterPINButton.getFont().getStyle() & ~java.awt.Font.BOLD));
+ enterPINButton.setText(getMessage(BUTTON_SIGN));
+ enterPINButton.setActionCommand(enterPINCommand);
+ enterPINButton.addActionListener(enterPINListener);
+
+ if (renderCancelButton) {
+ JButton cancelButton = new JButton();
+ cancelButton.setFont(cancelButton.getFont().deriveFont(cancelButton.getFont().getStyle() & ~java.awt.Font.BOLD));
+ cancelButton.setText(getMessage(BUTTON_CANCEL));
+ cancelButton.setActionCommand(cancelCommand);
+ cancelButton.addActionListener(cancelListener);
+
+ buttonHorizontal
+ .addComponent(enterPINButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(msgLabel));
-
- //no cancel button (cancel via pinpad)
-// if (renderCancelButton) {
-// JButton cancelButton = new JButton();
-// cancelButton.setFont(cancelButton.getFont().deriveFont(cancelButton.getFont().getStyle() & ~java.awt.Font.BOLD));
-// cancelButton.setText(getMessage(BUTTON_CANCEL));
-// cancelButton.setActionCommand(cancelCommand);
-// cancelButton.addActionListener(cancelListener);
-//
-// GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel);
-// buttonPanel.setLayout(buttonPanelLayout);
-//
-// GroupLayout.SequentialGroup buttonHorizontal = buttonPanelLayout.createSequentialGroup()
-// .addComponent(cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE);
-// GroupLayout.SequentialGroup buttonVertical = buttonPanelLayout.createSequentialGroup()
-// .addComponent(cancelButton);
-//
-// buttonPanelLayout.setHorizontalGroup(buttonHorizontal);
-// buttonPanelLayout.setVerticalGroup(buttonVertical);
-// }
+ .addComponent(cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE)
+ ;
+ buttonVertical = buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
+ .addComponent(enterPINButton)
+ .addComponent(cancelButton)
+ ;
+ } else {
+ buttonHorizontal
+ .addComponent(enterPINButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE)
+ ;
+ buttonVertical = buttonPanelLayout.createSequentialGroup()
+ .addComponent(enterPINButton)
+ ;
+ }
- contentPanel.validate();
- }
- });
+ buttonPanelLayout.setHorizontalGroup(buttonHorizontal);
+ buttonPanelLayout.setVerticalGroup(buttonVertical);
+
+ contentPanel.validate();
+ }
+ });
+ }
+
+ @Override
+ public void correctionButtonPressed() {
+ log.debug("[" + Thread.currentThread().getName() + "] correction button pressed");
+
+ if (pinpadPINField != null) {
+ String maskedPIN = pinpadPINField.getText();
+ pinpadPINField.setText(maskedPIN.substring(0, maskedPIN.length() - 1));
+ }
+ }
+
+ @Override
+ public void allKeysCleared() {
+ log.debug("[" + Thread.currentThread().getName() + "] all keys cleared");
+
+ if (pinpadPINField != null) {
+ pinpadPINField.setText("");
+ }
+ }
+
+ @Override
+ public void validKeyPressed() {
+ log.debug("[" + Thread.currentThread().getName() + "] valid key pressed");
+
+ if (pinpadPINField != null) {
+ pinpadPINField.setText(pinpadPINField.getText() + '*');
}
+ }
@Override
public void showSignaturePINDialog(final PINSpec pinSpec, final int numRetries,
final ActionListener signListener, final String signCommand,
final ActionListener cancelListener, final String cancelCommand,
final ActionListener hashdataListener, final String hashdataCommand) {
-// showSignaturePINDialog(pinSpec, numRetries, okListener, okCommand, cancelListener, cancelCommand, hashdataListener, hashdataCommand);
-// }
-//
-// private void showSignaturePINDialog(final PINSpec pinSpec, final int numRetries, final ActionListener signListener, final String signCommand, final ActionListener cancelListener, final String cancelCommand, final ActionListener hashdataListener, final String hashdataCommand) {
log.debug("scheduling signature-pin dialog");
@@ -1302,57 +1261,6 @@ public class BKUGUIImpl implements BKUGUIFacade {
});
}
-// @Override
-// public void showWaitDialog(final String waitMessage) {
-//
-// log.debug("scheduling wait dialog");
-//
-// SwingUtilities.invokeLater(new Runnable() {
-//
-// @Override
-// public void run() {
-//
-// log.debug("show wait dialog");
-//
-// mainPanel.removeAll();
-// buttonPanel.removeAll();
-//
-// if (renderHeaderPanel) {
-// titleLabel.setText(getMessage(TITLE_WAIT));
-// }
-//
-// helpListener.setHelpTopic(HELP_WAIT);
-//
-// JLabel waitMsgLabel = new JLabel();
-// waitMsgLabel.setFont(waitMsgLabel.getFont().deriveFont(waitMsgLabel.getFont().getStyle() & ~java.awt.Font.BOLD));
-// if (waitMessage != null) {
-// waitMsgLabel.setText("<html>" + waitMessage + "</html>");
-// } else {
-// waitMsgLabel.setText(getMessage(MESSAGE_WAIT));
-// }
-//
-// GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
-// mainPanel.setLayout(mainPanelLayout);
-//
-// GroupLayout.SequentialGroup messageHorizontal = mainPanelLayout.createSequentialGroup()
-// .addComponent(waitMsgLabel);
-// GroupLayout.ParallelGroup messageVertical = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
-// .addComponent(waitMsgLabel);
-//
-// if (!renderHeaderPanel) {
-// messageHorizontal
-// .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE)
-// .addComponent(helpLabel);
-// messageVertical
-// .addComponent(helpLabel);
-// }
-// mainPanelLayout.setHorizontalGroup(messageHorizontal);
-// mainPanelLayout.setVerticalGroup(messageVertical);
-//
-// contentPanel.validate();
-// }
-// });
-// }
@Override
public char[] getPin() {
@@ -1395,7 +1303,7 @@ public class BKUGUIImpl implements BKUGUIFacade {
@Override
public void run() {
try {
- showMessageDialog(TITLE_HASHDATA, MESSAGE_HASHDATA_VIEWER);
+ showMessageDialog(TITLE_SIGNATURE_DATA, MESSAGE_HASHDATA_VIEWER);
showSecureViewer(dataToBeSigned.get(0), backListener, backCommand);
} catch (FontProviderException ex) {
log.error("failed to display secure viewer", ex);
@@ -1411,7 +1319,7 @@ public class BKUGUIImpl implements BKUGUIFacade {
}
} else {
log.debug("[" + Thread.currentThread().getName() + "] mime-type not supported by secure viewer, scheduling save dialog");
- showMessageDialog(TITLE_HASHDATA, MESSAGE_UNSUPPORTED_MIMETYPE);
+ showMessageDialog(TITLE_SIGNATURE_DATA, MESSAGE_UNSUPPORTED_MIMETYPE);
SecureViewerSaveDialog.showSaveDialog(dataToBeSigned.get(0), messages, backListener, backCommand);
}
} else {
@@ -1421,28 +1329,7 @@ public class BKUGUIImpl implements BKUGUIFacade {
/**
* has to be called from event dispatcher thread
- * @param hashDataText
- * @param saveListener
- * @param saveCommand
*/
-// private void showSecureViewer(HashDataInput dataToBeSigned) throws FontProviderException {
-//
-// log.debug("[" + Thread.currentThread().getName() + "] show secure viewer");
-// if (secureViewer == null) {
-// secureViewer = new SecureViewerDialog(null, messages,
-// fontProvider, helpMouseListener.getActionListener());
-//
-// // workaround for [#439]
-// // avoid AlwaysOnTop at least in applet, otherwise make secureViewer AlwaysOnTop since MOCCA Dialog (JFrame created in LocalSTALFactory) is always on top.
-// Window window = SwingUtilities.getWindowAncestor(contentPane);
-// if (window != null && window.isAlwaysOnTop()) {
-// log.debug("make secureViewer alwaysOnTop");
-// secureViewer.setAlwaysOnTop(true);
-// }
-// }
-// secureViewer.setContent(dataToBeSigned);
-// log.trace("show secure viewer returned");
-// }
private void showSecureViewer(HashDataInput dataToBeSigned, ActionListener closeListener, String closeCommand) throws FontProviderException {
log.debug("[" + Thread.currentThread().getName() + "] show secure viewer");
@@ -1479,7 +1366,7 @@ public class BKUGUIImpl implements BKUGUIFacade {
buttonPanel.removeAll();
if (renderHeaderPanel) {
- titleLabel.setText(getMessage(TITLE_HASHDATA));
+ titleLabel.setText(getMessage(TITLE_SIGNATURE_DATA));
}
helpMouseListener.setHelpTopic(HELP_HASHDATALIST);
@@ -1613,7 +1500,7 @@ public class BKUGUIImpl implements BKUGUIFacade {
@Override
public void run() {
try {
- showMessageDialog(TITLE_HASHDATA, MESSAGE_HASHDATA_VIEWER);
+ showMessageDialog(TITLE_SIGNATURE_DATA, MESSAGE_HASHDATA_VIEWER);
showSecureViewer(selection, backToListListener, null);
// SecureViewerDialog.showSecureViewer(selection, messages, fontProvider, helpMouseListener.getActionListener(), false);
} catch (FontProviderException ex) {
@@ -1625,7 +1512,7 @@ public class BKUGUIImpl implements BKUGUIFacade {
});
} else {
log.debug("[" + Thread.currentThread().getName() + "] mime-type not supported by secure viewer, scheduling save dialog");
- showMessageDialog(BKUGUIFacade.TITLE_HASHDATA, BKUGUIFacade.MESSAGE_UNSUPPORTED_MIMETYPE);
+ showMessageDialog(BKUGUIFacade.TITLE_SIGNATURE_DATA, BKUGUIFacade.MESSAGE_UNSUPPORTED_MIMETYPE);
SecureViewerSaveDialog.showSaveDialog(selection, messages, backToListListener, null);
}
}
diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/PinDocument.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/PinDocument.java
index 96032dc1..52a3d5fe 100644
--- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/PinDocument.java
+++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/PinDocument.java
@@ -1,19 +1,19 @@
/*
-* 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.
-*/
+ * 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.gui;
import java.util.regex.Matcher;
@@ -21,7 +21,6 @@ import java.util.regex.Pattern;
import javax.swing.JButton;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
-import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
/**
@@ -31,16 +30,15 @@ import javax.swing.text.PlainDocument;
class PINDocument extends PlainDocument {
private static final long serialVersionUID = 1L;
-
protected Pattern pinPattern;
protected int minLength;
protected int maxLength;
-
protected JButton enterButton;
- protected Document compareTo;
- protected Document oldPin;
public PINDocument(int minLength, int maxLength, String pattern, JButton enterButton) {
+ if (enterButton == null) {
+ throw new NullPointerException("OK button null");
+ }
if (pattern != null) {
pinPattern = Pattern.compile(pattern);
} else {
@@ -51,73 +49,26 @@ class PINDocument extends PlainDocument {
this.enterButton = enterButton;
}
- /**
- * @param pinSpec
- * @param enterButton
- * @param compareTo
- * enable enterButton if this pinDocument's pin equals to
- * compareTo's pin. may be null
- */
- public PINDocument(int minLength, int maxLength, String pattern, JButton enterButton, Document compareTo) {
- this(minLength, maxLength, pattern, enterButton);
- this.compareTo = compareTo;
+ @Override
+ public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
+ if (maxLength < 0 || maxLength >= (getLength() + str.length())) {
+ boolean matches = true;
+ for (int i = 0; i < str.length(); i++) {
+ Matcher m = pinPattern.matcher(str.substring(i, i + 1));
+ if (!m.matches()) {
+ matches = false;
+ }
+ }
+ if (matches) {
+ super.insertString(offs, str, a);
+ enterButton.setEnabled(getLength() >= minLength);
+ }
+ }
}
- /**
- * @param pinSpec
- * @param enterButton
- * may be null
- * @param compareTo
- * enable enterButton if this pinDocument's pin equals to
- * compareTo's pin. may be null
- * @param oldPin
- * enable enterButton if oldPin meets the pinSpec pin length
- * requirements, may be null
- */
- public PINDocument(int minLength, int maxLength, String pattern,
- JButton enterButton, Document compareTo, Document oldPin) {
- this(minLength, maxLength, pattern, enterButton);
- this.compareTo = compareTo;
- this.oldPin = oldPin;
+ @Override
+ public void remove(int offs, int len) throws BadLocationException {
+ super.remove(offs, len);
+ enterButton.setEnabled(getLength() >= minLength);
}
-
- @Override
- public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
- if (maxLength < 0 || maxLength >= (getLength() + str.length())) {
- boolean matches = true;
- for (int i = 0; i < str.length(); i++) {
- Matcher m = pinPattern.matcher(str.substring(i, i + 1));
- if (!m.matches()) {
- matches = false;
- }
- }
- if (matches) {
- super.insertString(offs, str, a);
- }
- }
- if (enterButton != null) {
- enterButton.setEnabled(
- (oldPin == null || oldPin.getLength() >= minLength) &&
- getLength() >= minLength &&
- compare());
- }
- }
-
- @Override
- public void remove(int offs, int len) throws BadLocationException {
- super.remove(offs, len);
- if (enterButton != null) {
- enterButton.setEnabled(
- (oldPin == null || oldPin.getLength() >= minLength) &&
- getLength() >= minLength &&
- compare());
- }
- }
-
- private boolean compare() throws BadLocationException {
- if (compareTo == null) {
- return true;
- }
- return compareTo.getText(0, compareTo.getLength()).equals(getText(0, getLength()));
- }
- } \ No newline at end of file
+}
diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SecureViewerDialog.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SecureViewerDialog.java
index 7bae4673..7db70c46 100644
--- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SecureViewerDialog.java
+++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SecureViewerDialog.java
@@ -17,7 +17,6 @@
package at.gv.egiz.bku.gui;
import at.gv.egiz.bku.gui.viewer.FontProvider;
-import at.gv.egiz.bku.gui.viewer.FontProviderException;
import at.gv.egiz.bku.gui.viewer.SecureViewerSaveDialog;
import at.gv.egiz.stal.HashDataInput;
import java.awt.Container;
@@ -25,7 +24,6 @@ import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
-import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
@@ -34,32 +32,26 @@ import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
-import java.io.BufferedOutputStream;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
-import java.util.Locale;
import java.util.ResourceBundle;
import javax.swing.GroupLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
-import javax.swing.JFileChooser;
import javax.swing.JLabel;
-import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.LayoutStyle;
-import javax.swing.SwingUtilities;
+import javax.swing.WindowConstants;
import javax.swing.text.Document;
import javax.swing.text.EditorKit;
import javax.swing.text.StyledEditorKit;
@@ -71,7 +63,7 @@ import org.apache.commons.logging.LogFactory;
*
* @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
*/
-public class SecureViewerDialog extends JDialog implements ActionListener {
+public class SecureViewerDialog extends JDialog {
/** don't import BKUFonts in order not to load BKUFonts.jar
* BKUApplet includes BKUFonts as runtime dependency only, the jar is copied to the applet dir in BKUOnline with dependency-plugin
@@ -100,19 +92,6 @@ public class SecureViewerDialog extends JDialog implements ActionListener {
* @param owner, dialog is positioned relative to its owner
* (if null, at default location of native windowing system)
*/
-// public static void showDataToBeSigned(HashDataInput dataToBeSigned,
-// ResourceBundle messages,
-// ActionListener saveListener, String saveCommand,
-// ActionListener helpListener) {
-//
-//// Frame ownerFrame = (owner != null) ?
-//// JOptionPane.getFrameForComponent(owner) :
-//// null;
-// dialog = new SecureViewerDialog(null, messages,
-// saveListener, saveCommand, helpListener);
-// dialog.setContent(dataToBeSigned);
-// dialog.setVisible(true);
-// }
public SecureViewerDialog(Frame owner, ResourceBundle messages,
ActionListener closeListener, String closeCommand,
FontProvider fontProvider, ActionListener helpListener) {
@@ -125,6 +104,10 @@ public class SecureViewerDialog extends JDialog implements ActionListener {
createViewerPanel(helpListener),
createButtonPanel(closeListener, closeCommand));
+ // also leave defaultWindowClosing HIDE_ON_CLOSE
+ this.addWindowListener(new WindowCloseListener(closeListener, closeCommand));
+ this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+
pack();
if (owner != null) {
setLocationRelativeTo(owner);
@@ -305,19 +288,11 @@ public class SecureViewerDialog extends JDialog implements ActionListener {
JButton closeButton = new JButton();
closeButton.setText(messages.getString(BKUGUIFacade.BUTTON_CLOSE));
closeButton.setActionCommand(closeCommand);
- closeButton.addActionListener(closeListener);
- closeButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- log.trace("[" + Thread.currentThread().getName() + "] closing secure viewer");
- setVisible(false);
- }
- });
+ closeButton.addActionListener(new CloseButtonListener(closeListener));
JButton saveButton = new JButton();
saveButton.setText(messages.getString(BKUGUIFacade.BUTTON_SAVE));
- saveButton.setActionCommand("save"); //TODO ensure unequal to closeCommand
- saveButton.addActionListener(this);
+ saveButton.addActionListener(new SaveButtonListener());
int buttonSize = closeButton.getPreferredSize().width;
if (saveButton.getPreferredSize().width > buttonSize) {
@@ -336,39 +311,50 @@ public class SecureViewerDialog extends JDialog implements ActionListener {
return buttonPanel;
}
- @Override
- public void actionPerformed(ActionEvent e) {
- if ("save".equals(e.getActionCommand())) {
+ public class WindowCloseListener extends WindowAdapter {
+
+ ActionListener closeListener;
+ String closeCommand;
+
+ public WindowCloseListener(ActionListener closeListener, String closeCommand) {
+ this.closeListener = closeListener;
+ this.closeCommand = closeCommand;
+ }
+
+ @Override
+ public void windowClosing(WindowEvent e) {
+ log.trace("[" + Thread.currentThread().getName() + "] closing secure viewer");
+ setVisible(false);
+ if (closeListener != null) {
+ closeListener.actionPerformed(new ActionEvent(e.getSource(), e.getID(), closeCommand));
+ }
+ }
+ }
+
+ public class CloseButtonListener implements ActionListener {
+
+ ActionListener closeListener;
+
+ public CloseButtonListener(ActionListener closeListener) {
+ this.closeListener = closeListener;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ log.trace("[" + Thread.currentThread().getName() + "] closing secure viewer");
+ setVisible(false);
+ if (closeListener != null) {
+ closeListener.actionPerformed(e);
+ }
+ }
+ }
+
+ public class SaveButtonListener implements ActionListener {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
log.trace("[" + Thread.currentThread().getName() + "] display secure viewer save dialog");
SecureViewerSaveDialog.showSaveDialog(content, messages, null, null);
- log.trace("done secure viewer save");
- } else {
- log.warn("unknown action command " + e.getActionCommand());
}
}
-
-
-// //TEST
-// private static SecureViewerDialog secureViewer;
-// public static void showSecureViewerXXX(HashDataInput dataToBeSigned, ResourceBundle messages, FontProvider fontProvider, ActionListener helpListener, boolean alwaysOnTop) throws FontProviderException {
-//
-//// ResourceBundle messages = ResourceBundle.getBundle(BKUGUIFacade.MESSAGES_BUNDLE, locale);
-//
-// log.debug("[" + Thread.currentThread().getName() + "] show secure viewer");
-// if (secureViewer == null) {
-// secureViewer = new SecureViewerDialog(null, messages,
-// fontProvider, helpListener);
-//
-// // workaround for [#439]
-// // avoid AlwaysOnTop at least in applet, otherwise make secureViewer AlwaysOnTop since MOCCA Dialog (JFrame created in LocalSTALFactory) is always on top.
-//// Window window = SwingUtilities.getWindowAncestor(contentPane);
-//// if (window != null && window.isAlwaysOnTop()) {
-//// log.debug("make secureViewer alwaysOnTop");
-// secureViewer.setAlwaysOnTop(alwaysOnTop);
-//// }
-// }
-// secureViewer.setContent(dataToBeSigned);
-// log.trace("show secure viewer returned");
-// }
-
}
diff --git a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties
index 3e483fc8..c09433de 100644
--- a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties
+++ b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties
@@ -16,15 +16,15 @@
title.welcome=<html>Willkommen</html>
title.insertcard=<html>Keine B\u00FCrgerkarte gefunden</html>
title.cardnotsupported=<html>Die Karte wird nicht unterst\u00FCtzt</html>
-#title.cardpin=<html>{0} eingeben</html>
-title.cardpin=<html>Karte wird gelesen</html>
+title.verify.pin=<html>Karte wird gelesen</html>
title.sign=<html>Signatur erstellen</html>
+title.verify.pinpad=<html>PIN eingeben
title.error=<html>Fehler</html>
title.warning=<html>Achtung
title.entry.timeout=<html>Zeit\u00FCberschreitung</html>
title.retry=<html>Falsche PIN</html>
title.wait=<html>Bitte warten</html>
-title.hashdata=<html>Signaturdaten</html>
+title.signature.data=<html>Signaturdaten</html>
windowtitle.save=Signaturdaten speichern
windowtitle.error=Fehler
windowtitle.savedir=Signaturdaten in Verzeichnis speichern
@@ -38,7 +38,8 @@ wait=<html>Bitte warten...</html>
cardnotsupported=<html>Bitte die B\u00FCrgerkarte in den Kartenleser stecken</html>
insertcard=<html>Bitte die B\u00FCrgerkarte in den Kartenleser stecken</html>
enterpin=<html>{0} eingeben</html>
-enterpin.pinpad=<html>{0} ({1} stellig) am Kartenleser eingeben</html>
+enterpin.pinpad=<html>PIN am Kartenleser eingeben</html>
+enterpin.pinpad.direct=<html>{0} ({1} stellig) am Kartenleser eingeben</html>
hashdatalink=<html><a href=\"anzeige\">Signaturdaten anzeigen</a></html>
hashdatalink.tiny=<html><a href=\"anzeige\">Signaturdaten</a></html>
hashdatalink.focus=<html><a href=\"anzeige\">[Signaturdaten anzeigen]</a></html>
diff --git a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties
index c553bcb5..4d86d21b 100644
--- a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties
+++ b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties
@@ -16,15 +16,15 @@
title.welcome=<html>Welcome</html>
title.insertcard=<html>No citizen card found</html>
title.cardnotsupported=<html>This card is not supported</html>
-#title.cardpin=<html>Enter {0}</html>
-title.cardpin=<html>Reading card</html>
+title.verify.pin=<html>Reading card</html>
title.sign=<html>Create signature</html>
+title.verify.pinpad=<html>Enter PIN
title.error=<html>Error</html>
title.warning=<html>Warning
title.entry.timeout=<html>Timeout</html>
title.retry=<html>Wrong PIN</html>
title.wait=<html>Please wait</html>
-title.hashdata=<html>Signature data</html>
+title.signature.data=<html>Signature data</html>
windowtitle.save=Save signature data
windowtitle.error=Error
windowtitle.savedir=Save signature data to directory
@@ -38,7 +38,8 @@ wait=<html>Please wait...</html>
insertcard=<html>Please insert your citizen card into the reader</html>
cardnotsupported=<html>Please insert your citizen card into the reader</html>
enterpin=<html>Enter {0}</html>
-enterpin.pinpad=<html>Enter {0} ({1} digits) on card reader pinpad</html>
+enterpin.pinpad=<html>Enter PIN on card reader pinpad</html>
+enterpin.pinpad.direct=<html>Enter {0} ({1} digits) on card reader pinpad</html>
hashdatalink=<html><a href=\"anzeige\">Display signature data</a></html>
hashdatalink.tiny=<html><a href=\"anzeige\">signature data</a></html>
hashdatalink.focus=<html><a href=\"anzeige\">[Display signature data]</a></html>
diff --git a/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java b/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java
index 6e345ee3..a2a84d6e 100644
--- a/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java
+++ b/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java
@@ -45,7 +45,7 @@ public class BKUGUIWorker implements Runnable {
@Override
public void run() {
-// try {
+ try {
final PINSpec signPinSpec = new PINSpec(6, 10, "[0-9]", "Test-PIN", (byte) 0x81, null);
final PINSpec cardPinSpec = new PINSpec(4, 4, "[0-9]", "Test-PIN", (byte) 0x01, null);
@@ -155,7 +155,10 @@ public class BKUGUIWorker implements Runnable {
//
// gui.showSignaturePINDialog(signPinSpec, -1, signListener, "sign", cancelListener, "cancel", hashdataListener, "hashdata");
- gui.showPinpadSignaturePINDialog(signPinSpec, -1, hashdataListener, "hashdata");
+ gui.showSignatureDataDialog(signPinSpec, signListener, "sign", cancelListener, "cancel", hashdataListener, "hashdata");
+ Thread.sleep(2000);
+
+ gui.showEnterPINDirect(signPinSpec, -1);
//
// Thread.sleep(4000);
//
@@ -189,8 +192,8 @@ public class BKUGUIWorker implements Runnable {
// gui.showTextPlainHashDataInput("hallo,\n welt!", "12345", null, "cancel", null, "save");
// Thread.sleep(2000);
-// } catch (InterruptedException ex) {
-// ex.printStackTrace();
-// }
+ } catch (InterruptedException ex) {
+ ex.printStackTrace();
+ }
}
}
diff --git a/BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/ComparePinDocument.java b/BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/ComparePinDocument.java
new file mode 100644
index 00000000..623f6fad
--- /dev/null
+++ b/BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/ComparePinDocument.java
@@ -0,0 +1,102 @@
+/*
+ * 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.gui;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.swing.JButton;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.PlainDocument;
+
+/**
+ * Checks if the pin confirmation (compareTo) corresponds to this pin.
+ * Additionally, checks if currentPIN (optional) meets the requirements before enabling the OK button.
+ * @author clemens
+ */
+class ComparePinDocument extends PlainDocument {
+
+ private static final long serialVersionUID = 1L;
+ protected Pattern pinPattern;
+ protected int minLength;
+ protected int maxLength;
+ protected JButton enterButton;
+ protected Document compareTo;
+ protected Document currentPIN;
+
+ /**
+ * Constructor without compareTo Document parameter (allow null and set later to avoid cyclic dependencies)
+ */
+ public ComparePinDocument(int minLength, int maxLength, String pattern, JButton enterButton) {
+ if (enterButton == null) {
+ throw new NullPointerException("OK button null");
+ }
+ if (pattern != null) {
+ pinPattern = Pattern.compile(pattern);
+ } else {
+ pinPattern = Pattern.compile(".");
+ }
+ this.minLength = minLength;
+ this.maxLength = maxLength;
+ this.enterButton = enterButton;
+ }
+
+ /**
+ * @param compareTo should not be null (allow null and set later to avoid cyclic dependencies)
+ */
+ public ComparePinDocument(int minLength, int maxLength, String pattern,
+ JButton enterButton, Document compareTo) {
+ this(minLength, maxLength, pattern, enterButton);
+ this.compareTo = compareTo;
+ }
+
+ public ComparePinDocument(int minLength, int maxLength, String pattern,
+ JButton enterButton, Document compareTo, Document currentPIN) {
+ this(minLength, maxLength, pattern, enterButton, compareTo);
+ this.currentPIN = currentPIN;
+ }
+
+ @Override
+ public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
+ if (maxLength < 0 || maxLength >= (getLength() + str.length())) {
+ boolean matches = true;
+ for (int i = 0; i < str.length(); i++) {
+ Matcher m = pinPattern.matcher(str.substring(i, i + 1));
+ if (!m.matches()) {
+ matches = false;
+ }
+ }
+ if (matches) {
+ super.insertString(offs, str, a);
+ enterButton.setEnabled(
+ getLength() >= minLength
+ && (currentPIN == null || currentPIN.getLength() >= minLength)
+ && compareTo.getText(0, compareTo.getLength()).equals(getText(0, getLength())));
+ }
+ }
+ }
+
+ @Override
+ public void remove(int offs, int len) throws BadLocationException {
+ super.remove(offs, len);
+ enterButton.setEnabled(
+ getLength() >= minLength
+ && (currentPIN == null || currentPIN.getLength() >= minLength)
+ && compareTo.getText(0, compareTo.getLength()).equals(getText(0, getLength())));
+ }
+}
diff --git a/BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/ExtendedPinDocument.java b/BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/ExtendedPinDocument.java
new file mode 100644
index 00000000..3a0d7a66
--- /dev/null
+++ b/BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/ExtendedPinDocument.java
@@ -0,0 +1,108 @@
+/*
+ * 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.gui;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.swing.JButton;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.PlainDocument;
+
+/**
+ * This PINDocument also checks if the additional (optional) pinDocuments also meet the requirements
+ * to enable the OK button.
+ * Checks if (optional) newPIN and confirmPIN correspond
+ *
+ * @author clemens
+ */
+class ExtendedPinDocument extends PlainDocument {
+
+ private static final long serialVersionUID = 1L;
+ protected Pattern pinPattern;
+ protected int minLength;
+ protected int maxLength;
+ protected JButton enterButton;
+ protected Document newPIN;
+ protected Document confirmPIN;
+
+ public ExtendedPinDocument(int minLength, int maxLength, String pattern, JButton enterButton) {
+ if (enterButton == null) {
+ throw new NullPointerException("OK Button null");
+ }
+ if (pattern != null) {
+ pinPattern = Pattern.compile(pattern);
+ } else {
+ pinPattern = Pattern.compile(".");
+ }
+ this.minLength = minLength;
+ this.maxLength = maxLength;
+ this.enterButton = enterButton;
+ }
+
+ /**
+ * @param pinSpec
+ * @param enterButton
+ * @param newPIN, confirmPIN
+ */
+ public ExtendedPinDocument(int minLength, int maxLength, String pattern, JButton enterButton, Document newPIN, Document confirmPIN) {
+ this(minLength, maxLength, pattern, enterButton);
+ this.newPIN = newPIN;
+ this.confirmPIN = confirmPIN;
+ }
+
+ @Override
+ public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
+ if (maxLength < 0 || maxLength >= (getLength() + str.length())) {
+ boolean matches = true;
+ for (int i = 0; i < str.length(); i++) {
+ Matcher m = pinPattern.matcher(str.substring(i, i + 1));
+ if (!m.matches()) {
+ matches = false;
+ }
+ }
+ if (matches) {
+ super.insertString(offs, str, a);
+ enterButton.setEnabled(
+ getLength() >= minLength
+ && (newPIN == null || newPIN.getLength() >= minLength)
+ && (confirmPIN == null || compare()));
+ }
+ }
+ }
+
+ @Override
+ public void remove(int offs, int len) throws BadLocationException {
+ super.remove(offs, len);
+ enterButton.setEnabled(
+ getLength() >= minLength
+ && (newPIN == null || newPIN.getLength() >= minLength)
+ && (confirmPIN == null || compare()));
+ }
+
+ /**
+ * assume confirmPIN != null
+ * @return
+ */
+ private boolean compare() throws BadLocationException {
+ if (newPIN != null) {
+ return confirmPIN.getText(0, confirmPIN.getLength()).equals(newPIN.getText(0, newPIN.getLength()));
+ }
+ return false;
+ }
+}
diff --git a/BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUI.java b/BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUI.java
index 5bbed096..4dcc388f 100644
--- a/BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUI.java
+++ b/BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUI.java
@@ -239,23 +239,7 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
}
@Override
- public void showPINDialog(DIALOG type, PINSpec pinSpec,
- ActionListener okListener, String okCommand,
- ActionListener cancelListener, String cancelCommand) {
- showPINDialog(type, pinSpec, -1, false,
- okListener, okCommand, cancelListener, cancelCommand);
- }
-
- @Override
- public void showPINDialog(DIALOG type, PINSpec pinSpec, int retries,
- ActionListener okListener, String okCommand,
- ActionListener cancelListener, String cancelCommand) {
- showPINDialog(type, pinSpec, retries, false,
- okListener, okCommand, cancelListener, cancelCommand);
- }
-
- @Override
- public void showPinpadPINDialog(DIALOG type, PINSpec pinSpec, int retries) {
+ public void showModifyPINDirect(DIALOG type, PINSpec pinSpec, int retries) {
String title, msg;
Object[] params;
if (retries < 0) {
@@ -269,19 +253,19 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
if (type == DIALOG.CHANGE) {
log.debug("show change pin dialog");
title = TITLE_CHANGE_PIN;
- msg = MESSAGE_CHANGEPIN_PINPAD;
+ msg = MESSAGE_CHANGE_PINPAD_DIREKT;
} else if (type == DIALOG.ACTIVATE) {
log.debug("show activate pin dialog");
title = TITLE_ACTIVATE_PIN;
- msg = MESSAGE_ENTERPIN_PINPAD;
+ msg = MESSAGE_ACTIVATE_PINPAD_DIREKT;
} else if (type == DIALOG.VERIFY) {
log.debug("show verify pin dialog");
- title = TITLE_VERIFY_PIN;
- msg = MESSAGE_ENTERPIN_PINPAD;
+ title = TITLE_VERIFY_PINPAD;
+ msg = MESSAGE_ENTERPIN_PINPAD_DIRECT;
} else {
log.debug("show unblock pin dialog");
title = TITLE_UNBLOCK_PIN;
- msg = MESSAGE_ENTERPIN_PINPAD;
+ msg = MESSAGE_UNBLOCK_PINPAD_DIREKT;
}
} else {
@@ -294,6 +278,15 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
showMessageDialog(title, msg, params);
}
+ @Override
+ public void showPINDialog(DIALOG type, PINSpec pinSpec, int retries,
+ ActionListener okListener, String okCommand,
+ ActionListener cancelListener, String cancelCommand) {
+ showPINDialog(type, pinSpec, retries, false,
+ okListener, okCommand, cancelListener, cancelCommand);
+ }
+
+
private void showPINDialog(final DIALOG type, final PINSpec pinSpec,
final int retries, final boolean pinpad,
final ActionListener okListener, final String okCommand,
@@ -322,7 +315,7 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
} else if (type == DIALOG.VERIFY) {
log.debug("show verify pin dialog");
TITLE = TITLE_VERIFY_PIN;
- MESSAGE_MGMT = MESSAGE_VERIFY_PIN;
+ MESSAGE_MGMT = MESSAGE_ENTERPIN;
} else {
log.debug("show unblock pin dialog");
TITLE = TITLE_UNBLOCK_PIN;
@@ -393,7 +386,7 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
if (pinpad) {
JLabel pinpadLabel = new JLabel();
pinpadLabel.setFont(mgmtLabel.getFont().deriveFont(mgmtLabel.getFont().getStyle() & ~Font.BOLD));
- String pinpadPattern = getMessage(MESSAGE_VERIFYPIN_PINPAD);
+ String pinpadPattern = getMessage(MESSAGE_ENTERPIN_PINPAD);
pinpadLabel.setText(MessageFormat.format(pinpadPattern,
new Object[] { pinSpec.getLocalizedName(), pinSpec.getLocalizedLength() }));
@@ -403,7 +396,7 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
.addComponent(pinpadLabel);
} else {
- JButton okButton = new JButton();
+ final JButton okButton = new JButton();
okButton.setFont(okButton.getFont().deriveFont(okButton.getFont().getStyle() & ~Font.BOLD));
okButton.setText(getMessage(BUTTON_OK));
okButton.setEnabled(pinSpec.getMinLength() <= 0);
@@ -414,7 +407,7 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
JLabel repeatPinLabel = null;
JLabel pinLabel = new JLabel();
pinLabel.setFont(pinLabel.getFont().deriveFont(pinLabel.getFont().getStyle() & ~Font.BOLD));
- String pinLabelPattern = (type == DIALOG.CHANGE) ? getMessage(LABEL_NEW_PIN) : getMessage(LABEL_PIN);
+ String pinLabelPattern = (type == DIALOG.CHANGE || type == DIALOG.UNBLOCK) ? getMessage(LABEL_NEW_PIN) : getMessage(LABEL_PIN);
pinLabel.setText(MessageFormat.format(pinLabelPattern, new Object[]{pinSpec.getLocalizedName()}));
final JPasswordField repeatPinField = new JPasswordField();
@@ -436,8 +429,6 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
});
if (type != DIALOG.VERIFY) {
- pinField.setDocument(
- new PINDocument(pinSpec.getRecMinLength(), pinSpec.getRecMaxLength(), pinSpec.getRexepPattern(), null));
repeatPinLabel = new JLabel();
repeatPinLabel.setFont(pinLabel.getFont());
String repeatPinLabelPattern = getMessage(LABEL_REPEAT_PIN);
@@ -449,22 +440,20 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
@Override
public void actionPerformed(ActionEvent e) {
- if (pinField.getPassword().length >= pinSpec.getMinLength()) {
+ if (okButton.isEnabled()) {
okListener.actionPerformed(e);
}
}
});
- if (type == DIALOG.CHANGE) {
+ if (type == DIALOG.CHANGE || type == DIALOG.UNBLOCK) {
oldPinLabel = new JLabel();
oldPinLabel.setFont(oldPinLabel.getFont().deriveFont(oldPinLabel.getFont().getStyle() & ~java.awt.Font.BOLD));
- String oldPinLabelPattern = getMessage(LABEL_OLD_PIN);
+ String oldPinLabelPattern = getMessage((type == DIALOG.CHANGE) ? LABEL_OLD_PIN : LABEL_PUK);
oldPinLabel.setText(MessageFormat.format(oldPinLabelPattern, new Object[]{pinSpec.getLocalizedName()}));
oldPinField = new JPasswordField();
oldPinField.setText("");
- oldPinField.setDocument(
- new PINDocument(pinSpec.getMinLength(), pinSpec.getMaxLength(), pinSpec.getRexepPattern(), null));
oldPinField.setActionCommand(okCommand);
oldPinField.addActionListener(new ActionListener() {
@@ -476,16 +465,45 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
}
});
- repeatPinField.setDocument(
- new PINDocument(pinSpec.getRecMinLength(), pinSpec.getRecMaxLength(), pinSpec.getRexepPattern(),
- okButton, pinField.getDocument(), oldPinField.getDocument()));
+ ExtendedPinDocument oldPinDocument =
+ new ExtendedPinDocument(pinSpec.getMinLength(), pinSpec.getMaxLength(),
+ pinSpec.getRexepPattern(), okButton);
+ ComparePinDocument newPinDocument =
+ new ComparePinDocument(pinSpec.getRecMinLength(), pinSpec.getRecMaxLength(), pinSpec.getRexepPattern(),
+ okButton);
+ ComparePinDocument confirmPinDocument =
+ new ComparePinDocument(pinSpec.getRecMinLength(), pinSpec.getRecMaxLength(), pinSpec.getRexepPattern(),
+ okButton);
+
+ oldPinDocument.newPIN = newPinDocument;
+ oldPinDocument.confirmPIN = confirmPinDocument;
+
+ newPinDocument.compareTo = confirmPinDocument;
+ newPinDocument.currentPIN = oldPinDocument;
+ confirmPinDocument.compareTo = newPinDocument;
+ confirmPinDocument.currentPIN = oldPinDocument;
+
+ oldPinField.setDocument(oldPinDocument);
+ pinField.setDocument(newPinDocument);
+ repeatPinField.setDocument(confirmPinDocument);
+
} else {
// else -> ACTIVATE (not verify, not change)
- repeatPinField.setDocument(
- new PINDocument(pinSpec.getRecMinLength(), pinSpec.getRecMaxLength(), pinSpec.getRexepPattern(),
- okButton, pinField.getDocument()));
+ ComparePinDocument newPinDocument =
+ new ComparePinDocument(pinSpec.getRecMinLength(), pinSpec.getRecMaxLength(), pinSpec.getRexepPattern(),
+ okButton);
+ ComparePinDocument confirmPinDocument =
+ new ComparePinDocument(pinSpec.getRecMinLength(), pinSpec.getRecMaxLength(), pinSpec.getRexepPattern(),
+ okButton);
+
+ newPinDocument.compareTo = confirmPinDocument;
+ confirmPinDocument.compareTo = newPinDocument;
+
+ pinField.setDocument(newPinDocument);
+ repeatPinField.setDocument(confirmPinDocument);
}
} else {
+ // VERIFY
pinField.setDocument(
new PINDocument(pinSpec.getMinLength(), pinSpec.getMaxLength(), pinSpec.getRexepPattern(), okButton));
}
@@ -534,7 +552,7 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
// } else {
- if (type == DIALOG.CHANGE) {
+ if (type == DIALOG.CHANGE || type == DIALOG.UNBLOCK) {
pinHorizontal
.addGroup(mainPanelLayout.createSequentialGroup()
.addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
@@ -675,4 +693,69 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
return bs;
}
+ @Override
+ public void showEnterCurrentPIN(DIALOG type, PINSpec pinSpec, int retries) {
+ String title, message;
+// Object[] params = null;
+
+ if (type == PINManagementGUIFacade.DIALOG.VERIFY) {
+ title = PINManagementGUIFacade.TITLE_VERIFY_PINPAD;
+ message = BKUGUIFacade.MESSAGE_ENTERPIN_PINPAD;
+// params = new Object[]{pinSpec.getLocalizedName(), pinSpec.getLocalizedLength()};
+ } else if (type == PINManagementGUIFacade.DIALOG.ACTIVATE) {
+ title = PINManagementGUIFacade.TITLE_ACTIVATE_PIN;
+ message = PINManagementGUIFacade.MESSAGE_ACTIVATE_PINPAD_CURRENT;
+// params = new Object[]{pinSpec.getLocalizedName(), pinSpec.getLocalizedLength()};
+ } else if (type == PINManagementGUIFacade.DIALOG.CHANGE) {
+ title = PINManagementGUIFacade.TITLE_CHANGE_PIN;
+ message = PINManagementGUIFacade.MESSAGE_CHANGE_PINPAD_CURRENT;
+// params = new Object[]{pinSpec.getLocalizedName(), pinSpec.getLocalizedLength()};
+ } else { //if (type == DIALOG.UNBLOCK) {
+ title = PINManagementGUIFacade.TITLE_UNBLOCK_PIN;
+ message = PINManagementGUIFacade.MESSAGE_UNBLOCK_PINPAD_CURRENT;
+// params = new Object[]{pinSpec.getLocalizedName(), pinSpec.getLocalizedLength()};
+ }
+ showEnterPIN(pinSpec, retries, title, message, null);
+ }
+
+ @Override
+ public void showEnterNewPIN(DIALOG type, PINSpec pinSpec) {
+ String title, message;
+ if (type == PINManagementGUIFacade.DIALOG.ACTIVATE) {
+ title = PINManagementGUIFacade.TITLE_ACTIVATE_PIN;
+ message = PINManagementGUIFacade.MESSAGE_ACTIVATE_PINPAD_NEW;
+ } else if (type == PINManagementGUIFacade.DIALOG.CHANGE) {
+ title = PINManagementGUIFacade.TITLE_CHANGE_PIN;
+ message = PINManagementGUIFacade.MESSAGE_CHANGE_PINPAD_NEW;
+ } else if (type == DIALOG.UNBLOCK) {
+ title = PINManagementGUIFacade.TITLE_UNBLOCK_PIN;
+ message = PINManagementGUIFacade.MESSAGE_UNBLOCK_PINPAD_NEW;
+ } else {
+ log.error("enterNewPIN not supported for dialog type " + type);
+ showErrorDialog(ERR_UNKNOWN, null);
+ return;
+ }
+ showEnterPIN(pinSpec, -1, title, message, null);
+ }
+
+ @Override
+ public void showConfirmNewPIN(DIALOG type, PINSpec pinSpec) {
+ String title, message;
+ if (type == PINManagementGUIFacade.DIALOG.ACTIVATE) {
+ title = PINManagementGUIFacade.TITLE_ACTIVATE_PIN;
+ message = PINManagementGUIFacade.MESSAGE_ACTIVATE_PINPAD_CONFIRM;
+ } else if (type == PINManagementGUIFacade.DIALOG.CHANGE) {
+ title = PINManagementGUIFacade.TITLE_CHANGE_PIN;
+ message = PINManagementGUIFacade.MESSAGE_CHANGE_PINPAD_CONFIRM;
+ } else if (type == DIALOG.UNBLOCK) {
+ title = PINManagementGUIFacade.TITLE_UNBLOCK_PIN;
+ message = PINManagementGUIFacade.MESSAGE_UNBLOCK_PINPAD_CONFIRM;
+ } else {
+ log.error("enterNewPIN not supported for dialog type " + type);
+ showErrorDialog(ERR_UNKNOWN, null);
+ return;
+ }
+ showEnterPIN(pinSpec, -1, title, message, null);
+ }
+
}
diff --git a/BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java b/BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java
index f99bcfd1..46ae18b9 100644
--- a/BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java
+++ b/BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java
@@ -32,26 +32,39 @@ public interface PINManagementGUIFacade extends BKUGUIFacade {
public static final String TITLE_PINMGMT = "title.pin.mgmt";
public static final String TITLE_ACTIVATE_PIN = "title.activate.pin";
public static final String TITLE_CHANGE_PIN = "title.change.pin";
- public static final String TITLE_VERIFY_PIN = "title.verify.pin";
+// public static final String TITLE_VERIFY_PIN = "title.verify.pin";
public static final String TITLE_UNBLOCK_PIN = "title.unblock.pin";
public static final String TITLE_ACTIVATE_SUCCESS = "title.activate.success";
+ public static final String TITLE_UNBLOCK_SUCCESS = "title.unblock.success";
public static final String TITLE_CHANGE_SUCCESS = "title.change.success";
// removed message.* prefix to reuse keys as help keys
public static final String MESSAGE_ACTIVATE_SUCCESS = "activate.success";
public static final String MESSAGE_CHANGE_SUCCESS = "change.success";
+ public static final String MESSAGE_UNBLOCK_SUCCESS = "unblock.success";
public static final String MESSAGE_PINMGMT = "pin.mgmt";
// public static final String MESSAGE_PINPAD = "pinpad";
+
public static final String MESSAGE_ACTIVATE_PIN = "activate.pin";
public static final String MESSAGE_CHANGE_PIN = "change.pin";
- public static final String MESSAGE_VERIFY_PIN = "verify.pin";
public static final String MESSAGE_UNBLOCK_PIN = "unblock.pin";
- public static final String MESSAGE_ACTIVATEPIN_PINPAD = "activate.pinpad";
- public static final String MESSAGE_CHANGEPIN_PINPAD = "change.pinpad";
- public static final String MESSAGE_VERIFYPIN_PINPAD = "verify.pinpad";
- public static final String MESSAGE_UNBLOCKPIN_PINPAD = "unblock.pinpad";
+
+ public static final String MESSAGE_ACTIVATE_PINPAD_CURRENT = "activate.pinpad.current";
+ public static final String MESSAGE_CHANGE_PINPAD_CURRENT = "change.pinpad.current";
+ public static final String MESSAGE_UNBLOCK_PINPAD_CURRENT = "unblock.pinpad.current";
+ public static final String MESSAGE_ACTIVATE_PINPAD_NEW = "activate.pinpad.new";
+ public static final String MESSAGE_CHANGE_PINPAD_NEW = "change.pinpad.new";
+ public static final String MESSAGE_UNBLOCK_PINPAD_NEW = "unblock.pinpad.new";
+ public static final String MESSAGE_ACTIVATE_PINPAD_CONFIRM = "activate.pinpad.confirm";
+ public static final String MESSAGE_CHANGE_PINPAD_CONFIRM = "change.pinpad.confirm";
+ public static final String MESSAGE_UNBLOCK_PINPAD_CONFIRM = "unblock.pinpad.confirm";
+
+ public static final String MESSAGE_ACTIVATE_PINPAD_DIREKT = "activate.pinpad.direct";
+ public static final String MESSAGE_CHANGE_PINPAD_DIREKT = "change.pinpad.direct";
+ public static final String MESSAGE_UNBLOCK_PINPAD_DIREKT = "unblock.pinpad.direct";
public static final String LABEL_OLD_PIN = "label.old.pin";
+ public static final String LABEL_PUK = "label.puk";
public static final String LABEL_NEW_PIN = "label.new.pin";
public static final String LABEL_REPEAT_PIN = "label.repeat.pin";
@@ -81,35 +94,34 @@ public interface PINManagementGUIFacade extends BKUGUIFacade {
public enum STATUS { ACTIV, NOT_ACTIV, BLOCKED, UNKNOWN };
public enum DIALOG { VERIFY, ACTIVATE, CHANGE, UNBLOCK };
+ /**
+ * list pins
+ */
public void showPINManagementDialog(Map<PINSpec, STATUS> pins,
ActionListener activateListener, String activateCmd, String changeCmd, String unblockCmd, String verifyCmd,
ActionListener cancelListener, String cancelCmd);
- public void showPINDialog(DIALOG type, PINSpec pin,
+ /**
+ * "software" pin-entry dialog (activate, change, unblock, verify)
+ */
+ public void showPINDialog(DIALOG type, PINSpec pinSpec, int retries,
ActionListener okListener, String okCmd,
ActionListener cancelListener, String cancelCmd);
- public void showPINDialog(DIALOG type, PINSpec pin, int retries,
- ActionListener okListener, String okCmd,
- ActionListener cancelListener, String cancelCmd);
+ /**
+ * <b>direct</b> pinpad pin-entry dialog
+ */
+ public void showModifyPINDirect(DIALOG type, PINSpec pinSpec, int retries);
+
+ /**
+ * <b>start/finish</b> pinpad pin-entry dialog
+ */
+ public void showEnterCurrentPIN(DIALOG type, PINSpec pinSpec, int retries);
+
+ public void showEnterNewPIN(DIALOG type, PINSpec pinSpec);
+
+ public void showConfirmNewPIN(DIALOG type, PINSpec pinSpec);
- public void showPinpadPINDialog(DIALOG type, PINSpec pin, int retries);
-
-// public void showActivatePINDialog(PINSpec pin,
-// ActionListener okListener, String okCmd,
-// ActionListener cancelListener, String cancelCmd);
-//
-// public void showChangePINDialog(PINSpec pin,
-// ActionListener okListener, String okCmd,
-// ActionListener cancelListener, String cancelCmd);
-//
-// public void showUnblockPINDialog(PINSpec pin,
-// ActionListener okListener, String okCmd,
-// ActionListener cancelListener, String cancelCmd);
-//
-// public void showVerifyPINDialog(PINSpec pin,
-// ActionListener okListener, String okCmd,
-// ActionListener cancelListener, String cancelCmd);
public char[] getOldPin();
diff --git a/BKUGuiExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties b/BKUGuiExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties
index 977d6e3a..5ef3edee 100644
--- a/BKUGuiExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties
+++ b/BKUGuiExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties
@@ -15,30 +15,44 @@
title.activation=<html>Aktivierung</html>
title.pin.mgmt=<html>PIN Verwaltung</html>
-title.activate.pin=<html>PIN Aktivieren</html>
-title.change.pin=<html>PIN \u00C4ndern</html>
-title.unblock.pin=<html>PIN Entsperren</html>
-title.verify.pin=<html>PIN Eingeben</html>
+title.activate.pin=<html>PIN aktivieren</html>
+title.change.pin=<html>PIN \u00E4ndern</html>
+title.unblock.pin=<html>PIN entsperren</html>
+#title.verify.pin=<html>PIN Eingeben</html>
title.activate.success=<html>Erfolg</html>
title.change.success=<html>Erfolg</html>
+title.unblock.success=<html>Erfolg</html>
# removed message.* prefix to reuse keys as help keys
pin.mgmt=<html>Die Karte verf\u00FCgt \u00FCber {0} PINs</html>
+# software pin-entry messages
activate.pin=<html>{0} eingeben und best\u00E4tigen</html>
change.pin=<html>{0} eingeben und best\u00E4tigen</html>
unblock.pin=<html>PUK zu {0} eingeben</html>
-verify.pin=<html>{0} eingeben</html>
-verify.pinpad=<html>{0} ({1} stellig) am Kartenleser eingeben (und best\u00E4tigen).</html>
-activate.pinpad=<html>{0} ({1} stellig) am Kartenleser eingeben und wiederholen (jeweils best\u00E4tigen).</html>
-change.pinpad=<html>Alte {0} ({1} stellig) am Kartenleser eingeben, danach neue {0} eingeben und wiederholen (jeweils best\u00E4tigen). </html>
-unblock.pinpad=<html>{0} ({1} stellig) am Kartenleser eingeben (und best\u00E4tigen).</html>
-activate.success=<html>{0} wurde erfolgreich aktiviert.</html>
-change.success=<html>{0} wurde erfolgreich ge\u00E4ndert.</html>
+# start/finish pin-entry messages
+activate.pinpad.current=<html>Transport-PIN am Kartenleser eingeben
+activate.pinpad.new=<html>Neue PIN am Kartenleser eingeben
+activate.pinpad.confirm=<html>Neue PIN am Kartenleser best\u00E4tigen
+change.pinpad.current=<html>Alte PIN am Kartenleser eingeben
+change.pinpad.new=<html>Neue PIN am Kartenleser eingeben
+change.pinpad.confirm=<html>Neue PIN am Kartenleser best\u00E4tigen
+unblock.pinpad.current=<html>PUK am Kartenleser eingeben
+unblock.pinpad.new=<html>Neue PIN am Kartenleser eingeben
+unblock.pinpad.confirm=<html>Neue PIN am Kartenleser best\u00E4tigen
+# direct pin-entry messages
+activate.pinpad.direct=<html>{0} ({1} stellig) am Kartenleser eingeben und wiederholen (jeweils best\u00E4tigen).</html>
+change.pinpad.direct=<html>Alte {0} ({1} stellig) am Kartenleser eingeben, danach neue {0} eingeben und wiederholen (jeweils best\u00E4tigen). </html>
+unblock.pinpad.direct=<html>{0} ({1} stellig) am Kartenleser eingeben (und best\u00E4tigen).</html>
+# response messages
+activate.success=<html>{0} wurde erfolgreich aktiviert
+change.success=<html>{0} wurde erfolgreich ge\u00E4ndert
+unblock.success=<html>{0} wurde erfolgreich entsperrt
label.activation=<html>e-card Aktivierungsprozess</html>
label.activation.step=<html>Schritt {0}</html>
label.activation.idle=<html>Warte auf Server...</html>
label.old.pin=<html>Alte {0}:</html>
+label.puk=<html>{0} PUK:</html>
label.new.pin=<html>Neue {0}:</html>
label.repeat.pin=<html>Best\u00E4tigung:</html>
diff --git a/BKUGuiExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties b/BKUGuiExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties
index 7f01971b..87e3f181 100644
--- a/BKUGuiExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties
+++ b/BKUGuiExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties
@@ -16,29 +16,43 @@
title.activation=<html>Activation</html>
title.pin.mgmt=<html>PIN Management</html>
title.activate.pin=<html>Activate PIN</html>
-title.verify.pin=<html>Enter PIN</html>
+#title.verify.pin=<html>Enter PIN</html>
title.change.pin=<html>Change PIN</html>
title.unblock.pin=<html>Unblock PIN</html>
title.activate.success=<html>Success</html>
title.change.success=<html>Success</html>
+title.unblock.success=<html>Success</html>
# removed message.* prefix to reuse keys as help keys
-pin.mgmt=<html>The smartcard has {0} PINs</html>
-activate.pin=<html>Enter and confirm {0}</html>
-change.pin=<html>Enter and confirm {0}</html>
-unblock.pin=<html>Enter PUK for {0}</html>
-verify.pin=<html>Enter {0}</html>
-verify.pinpad=<html>Enter {0} ({1} digits) on cardreader (and confirm).</html>
-activate.pinpad=<html>Enter {0} ({1} digits) on cardreader and repeat (confirm in each case).</html>
-change.pinpad=<html>Enter old {0} ({1} digits) on cardreader, then enter new {0} and repeat (confirm in each case).</html>
-unblock.pinpad=<html>Enter {0} ({1} digits) on cardreader (and confirm).</html>
+pin.mgmt=<html>{0} PINs available
+# software pin-entry messages
+activate.pin=<html>Enter and confirm {0}
+change.pin=<html>Enter and confirm {0}
+unblock.pin=<html>Enter PUK for {0}
+# start/finish pin-entry messages
+activate.pinpad.current=<html>Enter transport-PIN on cardreader
+activate.pinpad.new=<html>Enter new PIN on cardreader
+activate.pinpad.confirm=<html>Confirm new PIN on cardreader
+change.pinpad.current=<html>Enter old PIN on cardreader
+change.pinpad.new=<html>Enter new PIN on cardreader
+change.pinpad.confirm=<html>Confirm new PIN on cardreader
+unblock.pinpad.current=<html>Enter PUK on cardreader
+unblock.pinpad.new=<html>Enter new PIN on cardreader
+unblock.pinpad.confirm=<html>Confirm new PIN on cardreader
+# direct pin-entry messages
+activate.pinpad.direct=<html>Enter {0} ({1} digits) on cardreader and repeat (confirm in each case)
+change.pinpad.direct=<html>Enter old {0} ({1} digits) on cardreader, then enter new {0} and repeat (confirm in each case)
+unblock.pinpad.direct=<html>Enter {0} ({1} digits) on cardreader, then enter new {0} and repeat (confirm in each case)
+# response messages
activate.success=<html>{0} successfully activated</html>
change.success=<html>{0} successfully changed</html>
+unblock.success=<html>{0} successfully unblocked
label.activation=<html>e-card activation process</html>
label.activation.step=<html>Step {0}</html>
label.activation.idle=<html>Wait for server...</html>
label.old.pin=<html>Old {0}:</html>
+label.puk=<html>{0} PUK:</html>
label.new.pin=<html>New {0}:</html>
label.repeat.pin=<html>Confirmation:</html>
diff --git a/BKUOnline/src/main/resources/log4j.properties b/BKUOnline/src/main/resources/log4j.properties
index 3eab8604..40133c83 100644
--- a/BKUOnline/src/main/resources/log4j.properties
+++ b/BKUOnline/src/main/resources/log4j.properties
@@ -15,7 +15,7 @@
#log4j.rootLogger=DEBUG, STDOUT, file
-log4j.rootLogger=INFO, file
+log4j.rootLogger=TRACE, file
#log4j.logger.at.gv = INFO
diff --git a/BKUOnline/src/main/webapp/META-INF/context.xml b/BKUOnline/src/main/webapp/META-INF/context.xml
index 2a2da79e..f38215a1 100644
--- a/BKUOnline/src/main/webapp/META-INF/context.xml
+++ b/BKUOnline/src/main/webapp/META-INF/context.xml
@@ -16,4 +16,4 @@
limitations under the License.
-->
<!--Context path="/bkuonline"/-->
-<Context path="/bkuonline"/>
+<Context path=""/>
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 1ed5a177..b8cdb208 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
@@ -16,6 +16,8 @@
*/
package at.gv.egiz.smcc;
+import at.gv.egiz.smcc.pin.gui.ModifyPINGUI;
+import at.gv.egiz.smcc.pin.gui.PINGUI;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -79,10 +81,16 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
public static final byte KID_PIN_SIG = (byte) 0x81;
+ public static final byte KID_PUK_SIG = (byte) 0x83;
+
public static final byte KID_PIN_DEC = (byte) 0x81;
+ public static final byte KID_PUK_DEC = (byte) 0x82;
+
public static final byte KID_PIN_INF = (byte) 0x83;
+ public static final byte KID_PUK_INF = (byte) 0x84;
+
public static final byte[] DST_SIG = new byte[] { (byte) 0x84, (byte) 0x01, // tag
// ,
// length
@@ -217,7 +225,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
@Override
@Exclusive
- public byte[] getInfobox(String infobox, PINProvider provider, String domainId)
+ public byte[] getInfobox(String infobox, PINGUI provider, String domainId)
throws SignatureCardException, InterruptedException {
if ("IdentityLink".equals(infobox)) {
@@ -233,7 +241,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
}
- protected byte[] getIdentityLinkV1(PINProvider provider, String domainId)
+ protected byte[] getIdentityLinkV1(PINGUI provider, String domainId)
throws SignatureCardException, InterruptedException {
try {
@@ -262,7 +270,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
}
- protected byte[] getIdentityLinkV2(PINProvider provider, String domainId)
+ protected byte[] getIdentityLinkV2(PINGUI provider, String domainId)
throws SignatureCardException, InterruptedException {
try {
@@ -388,7 +396,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
@Override
@Exclusive
public byte[] createSignature(InputStream input, KeyboxName keyboxName,
- PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException {
+ PINGUI provider, String alg) throws SignatureCardException, InterruptedException, IOException {
ByteArrayOutputStream dst = new ByteArrayOutputStream();
// key ID
@@ -487,7 +495,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
* @see at.gv.egiz.smcc.AbstractSignatureCard#verifyPIN(at.gv.egiz.smcc.PINSpec, at.gv.egiz.smcc.PINProvider)
*/
@Override
- public void verifyPIN(PINSpec pinSpec, PINProvider pinProvider)
+ public void verifyPIN(PINSpec pinSpec, PINGUI pinProvider)
throws LockedException, NotActivatedException, CancelledException,
TimeoutException, SignatureCardException, InterruptedException {
@@ -509,7 +517,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
* @see at.gv.egiz.smcc.AbstractSignatureCard#changePIN(at.gv.egiz.smcc.PINSpec, at.gv.egiz.smcc.ChangePINProvider)
*/
@Override
- public void changePIN(PINSpec pinSpec, ChangePINProvider pinProvider)
+ public void changePIN(PINSpec pinSpec, ModifyPINGUI pinProvider)
throws LockedException, NotActivatedException, CancelledException,
TimeoutException, SignatureCardException, InterruptedException {
@@ -528,7 +536,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
}
@Override
- public void activatePIN(PINSpec pinSpec, PINProvider pinProvider)
+ public void activatePIN(PINSpec pinSpec, ModifyPINGUI pinGUI)
throws CancelledException, SignatureCardException, CancelledException,
TimeoutException, InterruptedException {
log.error("ACTIVATE PIN not supported by ACOS");
@@ -536,7 +544,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
}
@Override
- public void unblockPIN(PINSpec pinSpec, PINProvider pinProvider)
+ public void unblockPIN(PINSpec pinSpec, ModifyPINGUI pinGUI)
throws CancelledException, SignatureCardException, InterruptedException {
throw new SignatureCardException("Unblock PIN not supported.");
}
@@ -570,10 +578,8 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
// PROTECTED METHODS (assume exclusive card access)
////////////////////////////////////////////////////////////////////////
- protected void verifyPINLoop(CardChannel channel, PINSpec spec, PINProvider provider)
- throws InterruptedException, LockedException, NotActivatedException,
- TimeoutException, PINFormatException, PINOperationAbortedException,
- SignatureCardException, CardException {
+ protected void verifyPINLoop(CardChannel channel, PINSpec spec, PINGUI provider)
+ throws InterruptedException, CardException, SignatureCardException {
int retries = -1;
do {
@@ -581,10 +587,8 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
} while (retries > 0);
}
- protected void changePINLoop(CardChannel channel, PINSpec spec, ChangePINProvider provider)
- throws InterruptedException, LockedException, NotActivatedException,
- TimeoutException, PINFormatException, PINOperationAbortedException,
- SignatureCardException, CardException {
+ protected void changePINLoop(CardChannel channel, PINSpec spec, ModifyPINGUI provider)
+ throws InterruptedException, CardException, SignatureCardException {
int retries = -1;
do {
@@ -593,7 +597,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
}
protected int verifyPIN(CardChannel channel, PINSpec pinSpec,
- PINProvider provider, int retries) throws InterruptedException, CardException, SignatureCardException {
+ PINGUI provider, int retries) throws InterruptedException, CardException, SignatureCardException {
VerifyAPDUSpec apduSpec = new VerifyAPDUSpec(
new byte[] {
@@ -602,7 +606,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 },
0, VerifyAPDUSpec.PIN_FORMAT_ASCII, 8);
- ResponseAPDU resp = reader.verify(channel, apduSpec, pinSpec, provider, retries);
+ ResponseAPDU resp = reader.verify(channel, apduSpec, provider, pinSpec, retries);
if (resp.getSW() == 0x9000) {
return -1;
@@ -625,7 +629,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
}
protected int changePIN(CardChannel channel, PINSpec pinSpec,
- ChangePINProvider pinProvider, int retries) throws CancelledException, InterruptedException, CardException, SignatureCardException {
+ ModifyPINGUI pinProvider, int retries) throws CancelledException, InterruptedException, CardException, SignatureCardException {
ChangeReferenceDataAPDUSpec apduSpec = new ChangeReferenceDataAPDUSpec(
new byte[] {
@@ -639,7 +643,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
- ResponseAPDU resp = reader.modify(channel, apduSpec, pinSpec, pinProvider, retries);
+ ResponseAPDU resp = reader.modify(channel, apduSpec, pinProvider, pinSpec, retries);
if (resp.getSW() == 0x9000) {
return -1;
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 54b4c7fe..fcb94fc6 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
@@ -16,6 +16,8 @@
*/
package at.gv.egiz.smcc;
+import at.gv.egiz.smcc.reader.CardReader;
+import at.gv.egiz.smcc.reader.ReaderFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@@ -29,9 +31,6 @@ import javax.smartcardio.CardTerminal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import at.gv.egiz.smcc.ccid.CCID;
-import at.gv.egiz.smcc.ccid.ReaderFactory;
-
public abstract class AbstractSignatureCard implements SignatureCard {
private static Log log = LogFactory.getLog(AbstractSignatureCard.class);
@@ -45,7 +44,7 @@ public abstract class AbstractSignatureCard implements SignatureCard {
private Card card_;
- protected CCID reader;
+ protected CardReader reader;
protected AbstractSignatureCard(String resourceBundleName) {
this.resourceBundleName = resourceBundleName;
@@ -68,7 +67,7 @@ public abstract class AbstractSignatureCard implements SignatureCard {
@Override
public void init(Card card, CardTerminal cardTerminal) {
this.card_ = card;
- this.reader = ReaderFactory.getInstance().getReader(card, cardTerminal);
+ this.reader = ReaderFactory.getReader(card, cardTerminal);
}
@Override
@@ -81,11 +80,6 @@ public abstract class AbstractSignatureCard implements SignatureCard {
}
@Override
- public CCID getReader() {
- return reader;
- }
-
- @Override
public void setLocale(Locale locale) {
if (locale == null) {
throw new NullPointerException("Locale must not be set to null");
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/BELPICCard.java b/smcc/src/main/java/at/gv/egiz/smcc/BELPICCard.java
index e02a55d4..41358bb5 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/BELPICCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/BELPICCard.java
@@ -18,6 +18,7 @@
package at.gv.egiz.smcc;
+import at.gv.egiz.smcc.pin.gui.PINGUI;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
@@ -110,7 +111,7 @@ public class BELPICCard extends AbstractSignatureCard implements SignatureCard {
@Override
@Exclusive
- public byte[] getInfobox(String infobox, PINProvider provider, String domainId)
+ public byte[] getInfobox(String infobox, PINGUI provider, String domainId)
throws SignatureCardException, InterruptedException {
throw new IllegalArgumentException("Infobox '" + infobox
@@ -120,7 +121,7 @@ public class BELPICCard extends AbstractSignatureCard implements SignatureCard {
@Override
@Exclusive
public byte[] createSignature(InputStream input, KeyboxName keyboxName,
- PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException {
+ PINGUI provider, String alg) throws SignatureCardException, InterruptedException, IOException {
if (KeyboxName.SECURE_SIGNATURE_KEYPAIR != keyboxName) {
throw new SignatureCardException("Card does not support key " + keyboxName + ".");
@@ -176,7 +177,7 @@ public class BELPICCard extends AbstractSignatureCard implements SignatureCard {
}
protected void verifyPINLoop(CardChannel channel, PINSpec spec,
- PINProvider provider) throws LockedException, NotActivatedException,
+ PINGUI provider) throws LockedException, NotActivatedException,
SignatureCardException, InterruptedException, CardException {
int retries = -1; //verifyPIN(channel, spec, null, -1);
@@ -186,7 +187,7 @@ public class BELPICCard extends AbstractSignatureCard implements SignatureCard {
}
protected int verifyPIN(CardChannel channel, PINSpec pinSpec,
- PINProvider provider, int retries) throws SignatureCardException,
+ PINGUI provider, int retries) throws SignatureCardException,
LockedException, NotActivatedException, InterruptedException,
CardException {
@@ -197,7 +198,7 @@ public class BELPICCard extends AbstractSignatureCard implements SignatureCard {
(byte) 0xff, (byte) 0xff, (byte) 0xff },
1, VerifyAPDUSpec.PIN_FORMAT_BCD, 7, 4, 4);
- ResponseAPDU resp = reader.verify(channel, apduSpec, pinSpec, provider, retries);
+ ResponseAPDU resp = reader.verify(channel, apduSpec, provider, pinSpec, retries);
if (resp.getSW() == 0x9000) {
return -1;
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ITCard.java b/smcc/src/main/java/at/gv/egiz/smcc/ITCard.java
index 831a1f9b..64389190 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/ITCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ITCard.java
@@ -17,6 +17,7 @@
package at.gv.egiz.smcc;
+import at.gv.egiz.smcc.pin.gui.PINGUI;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -96,7 +97,7 @@ public class ITCard extends AbstractSignatureCard {
@Override
@Exclusive
- public byte[] getInfobox(String infobox, PINProvider provider, String domainId)
+ public byte[] getInfobox(String infobox, PINGUI provider, String domainId)
throws SignatureCardException, InterruptedException {
throw new IllegalArgumentException("Infobox '" + infobox
@@ -106,7 +107,7 @@ public class ITCard extends AbstractSignatureCard {
@Override
@Exclusive
public byte[] createSignature(InputStream input, KeyboxName keyboxName,
- PINProvider provider, String alg) throws SignatureCardException,
+ PINGUI provider, String alg) throws SignatureCardException,
InterruptedException, IOException {
if (KeyboxName.SECURE_SIGNATURE_KEYPAIR != keyboxName) {
@@ -159,7 +160,7 @@ public class ITCard extends AbstractSignatureCard {
}
protected void verifyPINLoop(CardChannel channel, PINSpec spec,
- PINProvider provider) throws LockedException, NotActivatedException,
+ PINGUI provider) throws LockedException, NotActivatedException,
SignatureCardException, InterruptedException, CardException {
int retries = -1;
@@ -169,7 +170,7 @@ public class ITCard extends AbstractSignatureCard {
}
protected int verifyPIN(CardChannel channel, PINSpec pinSpec,
- PINProvider provider, int retries) throws SignatureCardException,
+ PINGUI provider, int retries) throws SignatureCardException,
LockedException, NotActivatedException, InterruptedException,
CardException {
@@ -180,7 +181,7 @@ public class ITCard extends AbstractSignatureCard {
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff },
0, VerifyAPDUSpec.PIN_FORMAT_ASCII, 8);
- ResponseAPDU resp = reader.verify(channel, apduSpec, pinSpec, provider, retries);
+ ResponseAPDU resp = reader.verify(channel, apduSpec, provider, pinSpec, retries);
if (resp.getSW() == 0x9000) {
return -2;
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/PINConfirmationException.java b/smcc/src/main/java/at/gv/egiz/smcc/PINConfirmationException.java
index eaf38435..24dfa53c 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/PINConfirmationException.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/PINConfirmationException.java
@@ -23,23 +23,4 @@ package at.gv.egiz.smcc;
* @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
*/
public class PINConfirmationException extends SignatureCardException {
-
- private static final long serialVersionUID = 1L;
-
- 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
index 774fcdf5..721c63e2 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/PINFormatException.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/PINFormatException.java
@@ -23,23 +23,4 @@ package at.gv.egiz.smcc;
* @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
*/
public class PINFormatException extends SignatureCardException {
-
- private static final long serialVersionUID = 1L;
-
- 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/PINMgmtSignatureCard.java b/smcc/src/main/java/at/gv/egiz/smcc/PINMgmtSignatureCard.java
index 53738612..5091c10f 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/PINMgmtSignatureCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/PINMgmtSignatureCard.java
@@ -16,6 +16,9 @@
*/
package at.gv.egiz.smcc;
+import at.gv.egiz.smcc.pin.gui.ModifyPINGUI;
+
+import at.gv.egiz.smcc.pin.gui.PINGUI;
import java.util.List;
public interface PINMgmtSignatureCard extends SignatureCard {
@@ -26,16 +29,16 @@ public interface PINMgmtSignatureCard extends SignatureCard {
public PIN_STATE getPINState(PINSpec pinSpec) throws SignatureCardException;
- public void verifyPIN(PINSpec pinSpec, PINProvider pinProvider)
+ public void verifyPIN(PINSpec pinSpec, PINGUI pinGUI)
throws LockedException, NotActivatedException, CancelledException, SignatureCardException, InterruptedException;
- public void changePIN(PINSpec pinSpec, ChangePINProvider pinProvider)
+ public void changePIN(PINSpec pinSpec, ModifyPINGUI changePINGUI)
throws LockedException, NotActivatedException, CancelledException, PINFormatException, SignatureCardException, InterruptedException;
- public void activatePIN(PINSpec pinSpec, PINProvider pinProvider)
+ public void activatePIN(PINSpec pinSpec, ModifyPINGUI activatePINGUI)
throws CancelledException, SignatureCardException, InterruptedException;
- public void unblockPIN(PINSpec pinSpec, PINProvider pukProvider)
+ public void unblockPIN(PINSpec pinSpec, ModifyPINGUI pukGUI)
throws CancelledException, SignatureCardException, InterruptedException;
}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ResetRetryCounterAPDUSpec.java b/smcc/src/main/java/at/gv/egiz/smcc/ResetRetryCounterAPDUSpec.java
new file mode 100644
index 00000000..7e71eb7e
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ResetRetryCounterAPDUSpec.java
@@ -0,0 +1,38 @@
+/*
+* 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;
+
+public class ResetRetryCounterAPDUSpec extends ChangeReferenceDataAPDUSpec {
+
+ /**
+ * @param apdu
+ * @param pukPosition
+ * @param pukFormat
+ * @param pukLength
+ * @param pukLengthSize
+ * @param pukLengthPos
+ * @param pinInsertionOffsetNew
+ */
+ public ResetRetryCounterAPDUSpec(byte[] apdu, int pukPosition,
+ int pukFormat, int pukLength, int pukLengthSize, int pukLengthPos,
+ int pinInsertionOffsetNew) {
+ super(apdu, pukPosition, pukFormat, pukLength, pukLengthSize, pukLengthPos);
+ this.pinInsertionOffsetNew = pinInsertionOffsetNew;
+ }
+
+
+}
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 79a4cc69..ad05352f 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
@@ -17,6 +17,8 @@
package at.gv.egiz.smcc;
+import at.gv.egiz.smcc.pin.gui.ModifyPINGUI;
+import at.gv.egiz.smcc.pin.gui.PINGUI;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -225,7 +227,7 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
@Override
@Exclusive
- public byte[] getInfobox(String infobox, PINProvider provider, String domainId)
+ public byte[] getInfobox(String infobox, PINGUI pinGUI, String domainId)
throws SignatureCardException, InterruptedException {
try {
@@ -243,7 +245,7 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
try {
return ISO7816Utils.readTransparentFileTLV(channel, -1, (byte) 0x30);
} catch (SecurityStatusNotSatisfiedException e) {
- verifyPINLoop(channel, spec, provider);
+ verifyPINLoop(channel, spec, pinGUI);
}
}
@@ -301,7 +303,7 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
@Override
@Exclusive
public byte[] createSignature(InputStream input, KeyboxName keyboxName,
- PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException {
+ PINGUI provider, String alg) throws SignatureCardException, InterruptedException, IOException {
ByteArrayOutputStream dst = new ByteArrayOutputStream();
byte[] ht = null;
@@ -431,7 +433,7 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
*/
@Override
@Exclusive
- public void verifyPIN(PINSpec pinSpec, PINProvider pinProvider)
+ public void verifyPIN(PINSpec pinSpec, PINGUI pinProvider)
throws LockedException, NotActivatedException, CancelledException,
TimeoutException, SignatureCardException, InterruptedException {
@@ -442,12 +444,7 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
// SELECT application
execSELECT_AID(channel, pinSpec.getContextAID());
}
- log.debug("*** verifyPIN loop");
verifyPINLoop(channel, pinSpec, pinProvider);
-// log.debug("*** verifyPIN 0");
-// int retries = verifyPIN(channel, pinSpec, null, 0);
-// log.debug("*** verifyPIN " + retries + " tries");
-// verifyPIN(channel, pinSpec, pinProvider, retries);
} catch (CardException e) {
log.info("Failed to verify PIN.", e);
throw new SignatureCardException("Failed to verify PIN.", e);
@@ -460,7 +457,7 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
*/
@Override
@Exclusive
- public void changePIN(PINSpec pinSpec, ChangePINProvider pinProvider)
+ public void changePIN(PINSpec pinSpec, ModifyPINGUI pinGUI)
throws LockedException, NotActivatedException, CancelledException,
TimeoutException, SignatureCardException, InterruptedException {
@@ -471,9 +468,7 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
// SELECT application
execSELECT_AID(channel, pinSpec.getContextAID());
}
- changePINLoop(channel, pinSpec, pinProvider);
-// int retries = verifyPIN(channel, pinSpec, null, 0);
-// changePIN(channel, pinSpec, pinProvider, retries);
+ changePINLoop(channel, pinSpec, pinGUI);
} catch (CardException e) {
log.info("Failed to change PIN.", e);
throw new SignatureCardException("Failed to change PIN.", e);
@@ -486,7 +481,7 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
*/
@Override
@Exclusive
- public void activatePIN(PINSpec pinSpec, PINProvider pinProvider)
+ public void activatePIN(PINSpec pinSpec, ModifyPINGUI activatePINGUI)
throws CancelledException, SignatureCardException, CancelledException,
TimeoutException, InterruptedException {
@@ -497,7 +492,7 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
// SELECT application
execSELECT_AID(channel, pinSpec.getContextAID());
}
- activatePIN(channel, pinSpec, pinProvider);
+ activatePIN(channel, pinSpec, activatePINGUI);
} catch (CardException e) {
log.info("Failed to activate PIN.", e);
throw new SignatureCardException("Failed to activate PIN.", e);
@@ -509,9 +504,16 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
* @see at.gv.egiz.smcc.PINMgmtSignatureCard#unblockPIN(at.gv.egiz.smcc.PINSpec, at.gv.egiz.smcc.PINProvider)
*/
@Override
- public void unblockPIN(PINSpec pinSpec, PINProvider pukProvider)
+ public void unblockPIN(PINSpec pinSpec, ModifyPINGUI pukProvider)
throws CancelledException, SignatureCardException, InterruptedException {
- throw new SignatureCardException("Unblock PIN is not supported.");
+ CardChannel channel = getCardChannel();
+
+ try {
+ unblockPINLoop(channel, pinSpec, pukProvider);
+ } catch (CardException e) {
+ log.info("Failed to activate PIN.", e);
+ throw new SignatureCardException("Failed to activate PIN.", e);
+ }
}
@Override
@@ -574,7 +576,7 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
// PROTECTED METHODS (assume exclusive card access)
////////////////////////////////////////////////////////////////////////
- protected void verifyPINLoop(CardChannel channel, PINSpec spec, PINProvider provider)
+ protected void verifyPINLoop(CardChannel channel, PINSpec spec, PINGUI provider)
throws LockedException, NotActivatedException, SignatureCardException,
InterruptedException, CardException {
@@ -584,7 +586,7 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
} while (retries > 0);
}
- protected void changePINLoop(CardChannel channel, PINSpec spec, ChangePINProvider provider)
+ protected void changePINLoop(CardChannel channel, PINSpec spec, ModifyPINGUI provider)
throws LockedException, NotActivatedException, SignatureCardException,
InterruptedException, CardException {
@@ -594,8 +596,19 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
} while (retries > 0);
}
+ protected void unblockPINLoop(CardChannel channel, PINSpec spec, ModifyPINGUI provider)
+ throws LockedException, NotActivatedException, SignatureCardException,
+ InterruptedException, CardException {
+
+ //TODO get PUK retry counter from EF FID 0036 in MF
+ int retries = -1;
+ do {
+ retries = unblockPIN(channel, spec, provider, retries);
+ } while (retries > 0);
+ }
+
protected int verifyPIN(CardChannel channel, PINSpec pinSpec,
- PINProvider provider, int retries) throws SignatureCardException,
+ PINGUI provider, int retries) throws SignatureCardException,
LockedException, NotActivatedException, InterruptedException,
CardException {
@@ -608,108 +621,135 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
ResponseAPDU resp;
if (provider != null) {
- resp = reader.verify(channel, apduSpec, pinSpec, provider, retries);
+ resp = reader.verify(channel, apduSpec, provider, pinSpec, retries);
} else {
resp = channel.transmit(new CommandAPDU(0x00, 0x20, 0x00, pinSpec.getKID()));
}
-
+
+
if (resp.getSW() == 0x9000) {
return -1;
- }
- if (resp.getSW() == 0x63c0) {
- // returned by the 'short' VERIFY
+ } else if (resp.getSW() == 0x6983 || resp.getSW() == 0x63c0) {
+ // authentication method blocked (0x63c0 returned by 'short' VERIFY)
throw new LockedException();
- }
- if (resp.getSW() >> 4 == 0x63c) {
- return 0x0f & resp.getSW();
- }
-
- switch (resp.getSW()) {
- case 0x6983:
- // authentication method blocked
- // returned by the 'long' VERIFY
- throw new LockedException();
- case 0x6984:
- // reference data not usable
+ } else if (resp.getSW() == 0x6984 || resp.getSW() == 0x6985) {
+ // reference data not usable; conditions of use not satisfied
throw new NotActivatedException();
- case 0x6985:
- // conditions of use not satisfied
+ } else if (resp.getSW() >> 4 == 0x63c) {
+ return 0x0f & resp.getSW();
+ } else if (version > 1.2 && resp.getSW() == 0x6400) {
+ log.warn("cannot query pin status prior to card activation");
throw new NotActivatedException();
-
- default:
+ } else {
String msg = "VERIFY failed. SW=" + Integer.toHexString(resp.getSW());
log.info(msg);
throw new SignatureCardException(msg);
}
-
}
protected int changePIN(CardChannel channel, PINSpec pinSpec,
- ChangePINProvider pinProvider, int retries) throws CancelledException,
+ ModifyPINGUI pinProvider, int retries) throws CancelledException,
InterruptedException, CardException, SignatureCardException {
-
- ChangeReferenceDataAPDUSpec apduSpec = new ChangeReferenceDataAPDUSpec(
- new byte[] {
- (byte) 0x00, (byte) 0x24, (byte) 0x00, pinSpec.getKID(), (byte) 0x10,
- (byte) 0x20, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0x20, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff },
+
+ ChangeReferenceDataAPDUSpec apduSpec = new ChangeReferenceDataAPDUSpec(
+ new byte[] {
+ (byte) 0x00, (byte) 0x24, (byte) 0x00, pinSpec.getKID(), (byte) 0x10,
+ (byte) 0x20, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0x20, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff },
1, VerifyAPDUSpec.PIN_FORMAT_BCD, 7, 4, 4, 8);
-
- ResponseAPDU resp = reader.modify(channel, apduSpec, pinSpec, pinProvider, retries);
-
+
+ ResponseAPDU resp = reader.modify(channel, apduSpec, pinProvider, pinSpec, retries);
+
if (resp.getSW() == 0x9000) {
return -1;
- }
- if (resp.getSW() >> 4 == 0x63c) {
- return 0x0f & resp.getSW();
- }
-
- switch (resp.getSW()) {
- case 0x6983:
+ } else if (resp.getSW() == 0x6983) {
// authentication method blocked
throw new LockedException();
-
- default:
+ } else if (resp.getSW() == 0x6984) {
+ throw new NotActivatedException();
+ } else if (resp.getSW() >> 4 == 0x63c) {
+ return 0x0f & resp.getSW();
+ } else {
String msg = "CHANGE REFERENCE DATA failed. SW=" + Integer.toHexString(resp.getSW());
log.info(msg);
throw new SignatureCardException(msg);
}
-
-
}
protected int activatePIN(CardChannel channel, PINSpec pinSpec,
- PINProvider provider) throws SignatureCardException,
+ ModifyPINGUI provider) throws SignatureCardException,
InterruptedException, CardException {
- NewReferenceDataAPDUSpec apduSpec = new NewReferenceDataAPDUSpec(
+ ResponseAPDU resp;
+ if (version < 1.2) {
+ NewReferenceDataAPDUSpec apduSpec = new NewReferenceDataAPDUSpec(
+ new byte[] {
+ (byte) 0x00, (byte) 0x24, (byte) 0x01, pinSpec.getKID(), (byte) 0x08,
+ (byte) 0x20, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff },
+ 1, VerifyAPDUSpec.PIN_FORMAT_BCD, 7, 4, 4);
+
+ resp = reader.modify(channel, apduSpec, provider, pinSpec);
+ } else {
+ NewReferenceDataAPDUSpec apduSpec = new NewReferenceDataAPDUSpec(
+ new byte[] {
+ (byte) 0x00, (byte) 0x24, (byte) 0x00, pinSpec.getKID(), (byte) 0x10,
+ (byte) 0x26, (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0x20, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff },
+ 1, VerifyAPDUSpec.PIN_FORMAT_BCD, 7, 4, 4);
+ apduSpec.setPinInsertionOffsetNew(8);
+ resp = reader.modify(channel, apduSpec, provider, pinSpec);
+ }
+
+ if (resp.getSW() == 0x9000) {
+ return -1;
+ } else {
+ String msg = "CHANGE REFERENCE DATA failed. SW=" + Integer.toHexString(resp.getSW());
+ log.info(msg);
+ throw new SignatureCardException(msg);
+ }
+ }
+
+ protected int unblockPIN(CardChannel channel, PINSpec pinSpec,
+ ModifyPINGUI provider, int retries) throws SignatureCardException,
+ InterruptedException, CardException {
+
+ if (version < 1.2) {
+ // would return 0x6982 (Security status not satisfied)
+ throw new SignatureCardException("RESET RETRY COUNTER is not supported by this card.");
+ }
+
+ ResetRetryCounterAPDUSpec apduSpec = new ResetRetryCounterAPDUSpec(
new byte[] {
- (byte) 0x00, (byte) 0x24, (byte) 0x01, pinSpec.getKID(), (byte) 0x08,
+ (byte) 0x00, (byte) 0x2c, (byte) 0x00, pinSpec.getKID(), (byte) 0x10,
(byte) 0x20, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff },
- 1, VerifyAPDUSpec.PIN_FORMAT_BCD, 7, 4, 4);
-
- ResponseAPDU resp = reader.activate(channel, apduSpec, pinSpec, provider);
-
- switch (resp.getSW()) {
-
- case 0x9000:
- return -1;
+ (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0x20, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff },
+ 1, VerifyAPDUSpec.PIN_FORMAT_BCD, 7, 4, 4, 8);
- case 0x6983:
- // authentication method blocked
- throw new LockedException();
+ ResponseAPDU resp = reader.modify(channel, apduSpec, provider, pinSpec, retries);
- default:
- String msg = "CHANGE REFERENCE DATA failed. SW=" + Integer.toHexString(resp.getSW());
+ if (resp.getSW() == 0x9000) {
+ return -1;
+ } else if (resp.getSW() == 0x6983) {
+ // PUK blocked
+ throw new LockedException();
+ } else if (resp.getSW() == 0x6984) {
+ throw new NotActivatedException();
+ } else if (resp.getSW() >> 4 == 0x63c) {
+ return 0x0f & resp.getSW();
+ } else {
+ String msg = "RESET RETRY COUNTER failed. SW=" + Integer.toHexString(resp.getSW());
log.info(msg);
throw new SignatureCardException(msg);
}
-
}
-
+
protected void execSELECT_MF(CardChannel channel) throws CardException, SignatureCardException {
ResponseAPDU resp = channel.transmit(
new CommandAPDU(0x00, 0xA4, 0x00, 0x0C));
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 670704d5..73c7faa8 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java
@@ -40,15 +40,12 @@ import java.util.Enumeration;
import java.util.Locale;
import javax.smartcardio.Card;
-import javax.smartcardio.CardChannel;
-import javax.smartcardio.CardException;
import javax.smartcardio.CardTerminal;
-import javax.smartcardio.ResponseAPDU;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import at.gv.egiz.smcc.ccid.CCID;
+import at.gv.egiz.smcc.pin.gui.PINGUI;
/**
*
@@ -280,7 +277,7 @@ public class SWCard implements SignatureCard {
}
- public byte[] getInfobox(String infobox, PINProvider provider, String domainId) throws SignatureCardException {
+ public byte[] getInfobox(String infobox, PINGUI provider, String domainId) throws SignatureCardException {
String fileName = getFileName(infobox + ".ibx");
FileInputStream file;
@@ -309,7 +306,7 @@ public class SWCard implements SignatureCard {
}
@Override
- public byte[] createSignature(InputStream input, KeyboxName keyboxName, PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException {
+ public byte[] createSignature(InputStream input, KeyboxName keyboxName, PINGUI provider, String alg) throws SignatureCardException, InterruptedException, IOException {
// KeyStore password
char[] password = getPassword(keyboxName);
@@ -396,101 +393,4 @@ public class SWCard implements SignatureCard {
@Override
public void reset() throws SignatureCardException {
}
-
- @Override
- public CCID getReader() {
- return new CCID() {
-
- @Override
- public boolean hasFeature(Byte feature) {
- return false;
- }
-
- @Override
- public byte getbTimeOut() {
- return 0;
- }
-
- @Override
- public byte getbTimeOut2() {
- return 0;
- }
-
- @Override
- public byte getwPINMaxExtraDigitL() {
- return 0x12;
- }
-
- @Override
- public byte getwPINMaxExtraDigitH() {
- return 0x00;
- }
-
- @Override
- public byte getbEntryValidationCondition() {
- return 0x02;
- }
-
- @Override
- 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.");
- }
-
- @Override
- public void setDisablePinpad(boolean disable) {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public ResponseAPDU verify(CardChannel channel, VerifyAPDUSpec apduSpec,
- PINSpec pinSpec, PINProvider provider, int retries)
- throws CancelledException, InterruptedException, CardException,
- SignatureCardException {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public ResponseAPDU activate(CardChannel channel,
- NewReferenceDataAPDUSpec apduSpec, PINSpec pinSpec,
- PINProvider provider) throws CancelledException,
- InterruptedException, CardException, SignatureCardException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public ResponseAPDU modify(CardChannel channel,
- ChangeReferenceDataAPDUSpec apduSpec, PINSpec pinSpec,
- ChangePINProvider provider, int retries) throws CancelledException,
- InterruptedException, CardException, SignatureCardException {
- // TODO Auto-generated method stub
- return null;
- }
- };
- }
}
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 3d56f97b..fa589b84 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java
@@ -17,8 +17,7 @@
package at.gv.egiz.smcc;
-import at.gv.egiz.smcc.ccid.CCID;
-
+import at.gv.egiz.smcc.pin.gui.PINGUI;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
@@ -99,7 +98,7 @@ public interface SignatureCard {
* @throws SignatureCardException
* @throws InterruptedException if applet is destroyed while in pin dialog
*/
- public byte[] getInfobox(String infobox, PINProvider provider, String domainId)
+ public byte[] getInfobox(String infobox, PINGUI pinGUI, String domainId)
throws SignatureCardException, InterruptedException;
/**
@@ -114,9 +113,7 @@ public interface SignatureCard {
* @throws IOException
*/
public byte[] createSignature(InputStream input, KeyboxName keyboxName,
- PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException;
-
- public CCID getReader();
+ PINGUI pinGUI, String alg) throws SignatureCardException, InterruptedException, IOException;
/**
* Sets the local for evtl. required callbacks (e.g. PINSpec)
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/ModifyPINGUI.java b/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/ModifyPINGUI.java
new file mode 100644
index 00000000..00dc2d0e
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/ModifyPINGUI.java
@@ -0,0 +1,36 @@
+/*
+* 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.pin.gui;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+
+
+public interface ModifyPINGUI extends ModifyPINProvider {
+
+ void modifyPINDirect(PINSpec spec, int retries) throws CancelledException, InterruptedException;
+ void finishDirect();
+
+ void enterCurrentPIN(PINSpec spec, int retries);
+ void enterNewPIN(PINSpec spec);
+ void confirmNewPIN(PINSpec spec);
+ void validKeyPressed();
+ void correctionButtonPressed();
+ void allKeysCleared();
+ /** called prior to MODIFY_PIN_FINISH control command transmission (clear display or display wait message) */
+ void finish();
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ChangePINProvider.java b/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/ModifyPINProvider.java
index 41010551..36f0097d 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/ChangePINProvider.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/ModifyPINProvider.java
@@ -14,13 +14,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package at.gv.egiz.smcc;
+package at.gv.egiz.smcc.pin.gui;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+
/**
- *
+ * user interface for "software pin-entry" of
+ * <ul>
+ * <li> current pin and new pin (change pin)
+ * <li> new pin (pin activation, no current pin)
+ * <li> puk and new pin (probably verify only?)
+ * </ul>
* @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
*/
-public interface ChangePINProvider extends PINProvider {
+public interface ModifyPINProvider {
/**
*
@@ -30,7 +39,10 @@ public interface ChangePINProvider extends PINProvider {
* @throws at.gv.egiz.smcc.CancelledException if cancelled by user
* @throws java.lang.InterruptedException
*/
- public char[] provideOldPIN(PINSpec spec, int retries)
+ public char[] provideCurrentPIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException;
+
+ public char[] provideNewPIN(PINSpec spec)
throws CancelledException, InterruptedException;
}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/PINGUI.java b/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/PINGUI.java
new file mode 100644
index 00000000..5199977b
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/PINGUI.java
@@ -0,0 +1,42 @@
+/*
+* 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.pin.gui;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+
+
+/**
+ * Display messages for pinpad pin-entry.
+ * Provides an interface for two types of pinpad pin-entry: pinpad-direct and pinpad-start/finish
+ * @author clemens.orthacker@iaik.tugraz.at
+ */
+public interface PINGUI extends PINProvider {
+
+ void enterPINDirect(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException;
+
+ /**
+ * @throws CancelledException, InterruptedException if signature-data dialog is interrupted or cancelled
+ */
+ void enterPIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException;
+ void validKeyPressed();
+ void correctionButtonPressed();
+ void allKeysCleared();
+
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/PINProvider.java b/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/PINProvider.java
index 5c294b5b..3bf49888 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/PINProvider.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/PINProvider.java
@@ -14,7 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package at.gv.egiz.smcc;
+package at.gv.egiz.smcc.pin.gui;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+
/**
* The number of retries is not fixed and there is no way (?) to obtain this value.
@@ -39,7 +43,7 @@ public interface PINProvider {
* @throws at.gv.egiz.smcc.CancelledException
* @throws java.lang.InterruptedException
*/
- public char[] providePIN(PINSpec spec, int retries)
+ char[] providePIN(PINSpec pinSpec, int retries)
throws CancelledException, InterruptedException;
}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/reader/CardReader.java b/smcc/src/main/java/at/gv/egiz/smcc/reader/CardReader.java
new file mode 100644
index 00000000..a1246dd6
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/reader/CardReader.java
@@ -0,0 +1,92 @@
+/*
+ * 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.reader;
+
+import javax.smartcardio.CardChannel;
+import javax.smartcardio.CardException;
+import javax.smartcardio.ResponseAPDU;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.ChangeReferenceDataAPDUSpec;
+import at.gv.egiz.smcc.NewReferenceDataAPDUSpec;
+import at.gv.egiz.smcc.PINSpec;
+import at.gv.egiz.smcc.ResetRetryCounterAPDUSpec;
+import at.gv.egiz.smcc.SignatureCardException;
+import at.gv.egiz.smcc.VerifyAPDUSpec;
+import at.gv.egiz.smcc.pin.gui.ModifyPINGUI;
+import at.gv.egiz.smcc.pin.gui.PINGUI;
+import javax.smartcardio.Card;
+
+/**
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public interface CardReader {
+
+
+ String[] FEATURES = new String[]{"NO_FEATURE",
+ "FEATURE_VERIFY_PIN_START",
+ "FEATURE_VERIFY_PIN_FINISH",
+ "FEATURE_MODIFY_PIN_START",
+ "FEATURE_MODIFY_PIN_FINISH",
+ "FEATURE_GET_KEY_PRESSED",
+ "FEATURE_VERIFY_PIN_DIRECT",
+ "FEATURE_MODIFY_PIN_DIRECT",
+ "FEATURE_MCT_READER_DIRECT",
+ "FEATURE_MCT_UNIVERSAL",
+ "FEATURE_IFD_PIN_PROPERTIES",
+ "FEATURE_ABORT",
+ "FEATURE_SET_SPE_MESSAGE",
+ "FEATURE_VERIFY_PIN_DIRECT_APP_ID",
+ "FEATURE_MODIFY_PIN_DIRECT_APP_ID",
+ "FEATURE_WRITE_DISPLAY",
+ "FEATURE_GET_KEY",
+ "FEATURE_IFD_DISPLAY_PROPERTIES"};
+
+ 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
+
+
+ Card connect() throws CardException;
+
+ boolean hasFeature(Byte feature);
+
+ ResponseAPDU verify(CardChannel channel, VerifyAPDUSpec apduSpec,
+ PINGUI pinGUI, PINSpec pinSpec, int retries)
+ throws CancelledException, InterruptedException, CardException, SignatureCardException;
+
+ ResponseAPDU modify(CardChannel channel, ChangeReferenceDataAPDUSpec apduSpec,
+ ModifyPINGUI pinGUI, PINSpec pinSpec, int retries)
+ throws CancelledException, InterruptedException, CardException, SignatureCardException;
+
+ ResponseAPDU modify(CardChannel channel, NewReferenceDataAPDUSpec apduSpec,
+ ModifyPINGUI pinGUI, PINSpec pinSpec)
+ throws CancelledException, InterruptedException, CardException, SignatureCardException;
+
+ ResponseAPDU modify(CardChannel channel, ResetRetryCounterAPDUSpec apduSpec,
+ ModifyPINGUI pinGUI, PINSpec pinSpec, int retries)
+ throws CancelledException, InterruptedException, CardException, SignatureCardException;
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/reader/DefaultCardReader.java b/smcc/src/main/java/at/gv/egiz/smcc/reader/DefaultCardReader.java
new file mode 100644
index 00000000..45ea7a5a
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/reader/DefaultCardReader.java
@@ -0,0 +1,106 @@
+/*
+ * 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.reader;
+
+
+import javax.smartcardio.Card;
+import javax.smartcardio.CardChannel;
+import javax.smartcardio.CardException;
+import javax.smartcardio.CardTerminal;
+import javax.smartcardio.ResponseAPDU;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.smcc.ChangeReferenceDataAPDUSpec;
+import at.gv.egiz.smcc.NewReferenceDataAPDUSpec;
+import at.gv.egiz.smcc.PINSpec;
+import at.gv.egiz.smcc.ResetRetryCounterAPDUSpec;
+import at.gv.egiz.smcc.SignatureCardException;
+import at.gv.egiz.smcc.VerifyAPDUSpec;
+import at.gv.egiz.smcc.pin.gui.ModifyPINGUI;
+import at.gv.egiz.smcc.pin.gui.PINGUI;
+import at.gv.egiz.smcc.util.ISO7816Utils;
+
+/**
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public class DefaultCardReader implements CardReader {
+
+ protected final static Log log = LogFactory.getLog(DefaultCardReader.class);
+
+ protected CardTerminal ct;
+ protected String name;
+
+ public DefaultCardReader(CardTerminal ct) {
+ if (ct == null) {
+ throw new NullPointerException("no card or card terminal provided");
+ }
+ this.ct = ct;
+ this.name = ct.getName();
+ }
+
+ @Override
+ public ResponseAPDU verify(CardChannel channel, VerifyAPDUSpec apduSpec,
+ PINGUI pinGUI, PINSpec pinSpec, int retries)
+ throws SignatureCardException, CardException, InterruptedException {
+
+ log.debug("VERIFY");
+ return channel.transmit(ISO7816Utils.createVerifyAPDU(apduSpec, pinGUI.providePIN(pinSpec, retries)));
+ }
+
+ @Override
+ public ResponseAPDU modify(CardChannel channel, ChangeReferenceDataAPDUSpec apduSpec,
+ ModifyPINGUI pinGUI, PINSpec pinSpec, int retries)
+ throws SignatureCardException, CardException, InterruptedException {
+ log.debug("MODIFY (CHANGE_REFERENCE_DATA)");
+ char[] oldPin = pinGUI.provideCurrentPIN(pinSpec, retries);
+ char[] newPin = pinGUI.provideNewPIN(pinSpec);
+ return channel.transmit(ISO7816Utils.createChangeReferenceDataAPDU(apduSpec, oldPin, newPin));
+ }
+
+ @Override
+ public ResponseAPDU modify(CardChannel channel, NewReferenceDataAPDUSpec apduSpec,
+ ModifyPINGUI pinGUI, PINSpec pinSpec)
+ throws SignatureCardException, CardException, InterruptedException {
+ log.debug("MODIFY (NEW_REFERENCE_DATA)");
+ char[] newPIN = pinGUI.provideNewPIN(pinSpec);
+ return channel.transmit(ISO7816Utils.createNewReferenceDataAPDU(apduSpec, newPIN));
+ }
+
+ @Override
+ public ResponseAPDU modify(CardChannel channel, ResetRetryCounterAPDUSpec apduSpec,
+ ModifyPINGUI pinGUI, PINSpec pinSpec, int retries)
+ throws InterruptedException, CardException, SignatureCardException {
+ log.debug("MODIFY (RESET_RETRY_COUNTER)");
+ //TODO
+ return modify(channel, (ChangeReferenceDataAPDUSpec) apduSpec, pinGUI, pinSpec, retries);
+ }
+
+ @Override
+ public Card connect() throws CardException {
+ log.debug("connect icc");
+ return ct.connect("*");
+ }
+
+ @Override
+ public boolean hasFeature(Byte feature) {
+ return false;
+ }
+
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java b/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java
new file mode 100644
index 00000000..c2537af8
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java
@@ -0,0 +1,703 @@
+/*
+ * 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.reader;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Map;
+
+import javax.smartcardio.Card;
+import javax.smartcardio.CardChannel;
+import javax.smartcardio.CardException;
+import javax.smartcardio.CardTerminal;
+import javax.smartcardio.ResponseAPDU;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.ChangeReferenceDataAPDUSpec;
+import at.gv.egiz.smcc.NewReferenceDataAPDUSpec;
+import at.gv.egiz.smcc.PINConfirmationException;
+import at.gv.egiz.smcc.PINFormatException;
+import at.gv.egiz.smcc.PINOperationAbortedException;
+import at.gv.egiz.smcc.PINSpec;
+import at.gv.egiz.smcc.ResetRetryCounterAPDUSpec;
+import at.gv.egiz.smcc.SignatureCardException;
+import at.gv.egiz.smcc.TimeoutException;
+import at.gv.egiz.smcc.VerifyAPDUSpec;
+import at.gv.egiz.smcc.pin.gui.ModifyPINGUI;
+import at.gv.egiz.smcc.pin.gui.PINGUI;
+import at.gv.egiz.smcc.util.SMCCHelper;
+
+/**
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public class PinpadCardReader extends DefaultCardReader {
+
+ public static final int PIN_ENTRY_POLLING_INTERVAL = 10;
+
+ protected final static Log log = LogFactory.getLog(PinpadCardReader.class);
+
+ protected byte bEntryValidationCondition = 0x02; // validation key pressed
+ protected byte bTimeOut = 0x3c; // 60sec (= max on ReinerSCT)
+ protected byte bTimeOut2 = 0x00; // default (attention with SCM)
+ protected byte wPINMaxExtraDigitH = 0x00; // min pin length zero digits
+ protected byte wPINMaxExtraDigitL = 0x0c; // max pin length 12 digits
+
+ /**
+ * supported features and respective control codes
+ */
+ protected Map<Byte, Integer> features;
+ protected boolean VERIFY, MODIFY, VERIFY_DIRECT, MODIFY_DIRECT;
+
+ public PinpadCardReader(CardTerminal ct, Map<Byte, Integer> features) {
+ super(ct);
+ if (features == null) {
+ throw new NullPointerException("Pinpad card reader does not support any features");
+ }
+ this.features = features;
+
+ if (features.containsKey(FEATURE_VERIFY_PIN_START) &&
+ features.containsKey(FEATURE_GET_KEY_PRESSED) &&
+ features.containsKey(FEATURE_VERIFY_PIN_FINISH)) {
+ VERIFY = true;
+ }
+ if (features.containsKey(FEATURE_MODIFY_PIN_START) &&
+ features.containsKey(FEATURE_GET_KEY_PRESSED) &&
+ features.containsKey(FEATURE_MODIFY_PIN_FINISH)) {
+ MODIFY = true;
+ }
+ if (features.containsKey(FEATURE_VERIFY_PIN_DIRECT)) {
+ VERIFY_DIRECT = true;
+ }
+ if (features.containsKey(FEATURE_MODIFY_PIN_DIRECT)) {
+ MODIFY_DIRECT = true;
+ }
+
+ if (name != null) {
+ name = name.toLowerCase();
+ //ReinerSCT: http://support.reiner-sct.de/downloads/LINUX
+ // http://www.linux-club.de/viewtopic.php?f=61&t=101287&start=0
+ //old: REINER SCT CyberJack 00 00
+ //new (CCID): 0C4B/0300 Reiner-SCT cyberJack pinpad(a) 00 00
+ //Snow Leopard: Reiner-SCT cyberJack pinpad(a) 00 00
+ //display: REINER SCT CyberJack 00 00
+ if(name.startsWith("gemplus gempc pinpad") || name.startsWith("gemalto gempc pinpad")) {
+ log.debug("setting custom wPINMaxExtraDigitH (0x04) for " + name);
+ wPINMaxExtraDigitH = 0x04;
+ log.debug("setting custom wPINMaxExtraDigitL (0x08) for " + name);
+ wPINMaxExtraDigitL = 0x08;
+ } else if (name.startsWith("omnikey cardman 3621")) {
+ log.debug("setting custom wPINMaxExtraDigitH (0x01) for " + name);
+ wPINMaxExtraDigitH = 0x01;
+ } else if (name.startsWith("scm spr 532") || name.startsWith("scm microsystems inc. sprx32 usb smart card reader")) {
+ log.debug("setting custom bTimeOut (0x3c) for " + name);
+ bTimeOut = 0x3c;
+ log.debug("setting custom bTimeOut2 (0x0f) for " + name);
+ bTimeOut2 = 0x0f;
+ } else if (name.startsWith("cherry smartboard xx44")) {
+ log.debug("setting custom wPINMaxExtraDigitH (0x01) for " + name);
+ wPINMaxExtraDigitH = 0x01;
+ }
+ }
+
+ }
+
+ @Override
+ public boolean hasFeature(Byte feature) {
+ return features.containsKey(feature);
+ }
+
+ private void VERIFY_PIN_START(Card icc, byte[] PIN_VERIFY) throws CardException {
+ 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));
+ }
+ }
+ }
+
+ private byte GET_KEY_PRESSED(Card icc) throws CardException {
+ int ioctl = features.get(FEATURE_GET_KEY_PRESSED);
+ 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));
+ }
+
+ private byte[] VERIFY_PIN_FINISH(Card icc) throws CardException {
+ 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));
+ }
+
+ private void MODIFY_PIN_START(Card icc, byte[] PIN_MODIFY) throws CardException {
+ 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));
+ }
+ }
+ }
+
+ private byte[] MODIFY_PIN_FINISH(Card icc) throws CardException {
+ 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));
+ }
+
+ private byte[] VERIFY_PIN_DIRECT(Card icc, byte[] PIN_VERIFY) throws CardException {
+ 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;
+ }
+
+ private byte[] verifyPin(Card icc, byte[] PIN_VERIFY, PINGUI pinGUI)
+ throws SignatureCardException, CardException, InterruptedException {
+
+// pinGUI.enterPIN(pinSpec, retries);
+
+ log.debug("VERIFY_PIN_START [" + FEATURES[FEATURE_VERIFY_PIN_START] + "]");
+ VERIFY_PIN_START(icc, PIN_VERIFY);
+
+ byte resp;
+ do {
+ resp = GET_KEY_PRESSED(icc);
+ if (resp == (byte) 0x00) {
+ synchronized(this) {
+ try {
+ wait(PIN_ENTRY_POLLING_INTERVAL);
+ } catch (InterruptedException ex) {
+ log.error("interrupted in VERIFY_PIN");
+ }
+ }
+ } else if (resp == (byte) 0x0d) {
+ log.debug("GET_KEY_PRESSED: 0x0d (user confirmed)");
+ break;
+ } else if (resp == (byte) 0x2b) {
+ log.trace("GET_KEY_PRESSED: 0x2b (user entered valid key 0-9)");
+ pinGUI.validKeyPressed();
+ } else if (resp == (byte) 0x1b) {
+ log.debug("GET_KEY_PRESSED: 0x1b (user cancelled VERIFY_PIN via cancel button)");
+ break; // returns 0x6401
+ } else if (resp == (byte) 0x08) {
+ log.debug("GET_KEY_PRESSED: 0x08 (user pressed correction/backspace button)");
+ pinGUI.correctionButtonPressed();
+ } else if (resp == (byte) 0x0e) {
+ log.debug("GET_KEY_PRESSED: 0x0e (timeout occured)");
+ break; // return 0x6400
+ } else if (resp == (byte) 0x40) {
+ log.debug("GET_KEY_PRESSED: 0x40 (PIN_Operation_Aborted)");
+ throw new PINOperationAbortedException("PIN_Operation_Aborted (0x40)");
+ } else if (resp == (byte) 0x0a) {
+ log.debug("GET_KEY_PRESSED: 0x0a (all keys cleared");
+ pinGUI.allKeysCleared();
+ } 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);
+
+ return VERIFY_PIN_FINISH(icc);
+ }
+
+ /**
+ * does not display the first pin dialog (enterCurrentPIN or enterNewPIN, depends on bConfirmPIN),
+ * since this is easier to do in calling modify()
+ */
+ private byte[] modifyPin(Card icc, byte[] PIN_MODIFY, ModifyPINGUI pinGUI, PINSpec pINSpec)
+ throws PINOperationAbortedException, CardException {
+
+ byte pinConfirmations = (byte) 0x00; //b0: new pin not entered (0) / entered (1)
+ //b1: current pin not entered (0) / entered (1)
+ byte bConfirmPIN = PIN_MODIFY[9];
+
+// if ((bConfirmPIN & (byte) 0x02) == 0) {
+// log.debug("no current PIN entry requested");
+// pinGUI.enterNewPIN(pINSpec);
+// } else {
+// log.debug("current PIN entry requested");
+// pinGUI.enterCurrentPIN(pINSpec, retries);
+// }
+
+ log.debug("MODIFY_PIN_START [" + FEATURES[FEATURE_MODIFY_PIN_START] + "]");
+ MODIFY_PIN_START(icc, PIN_MODIFY);
+
+ byte resp;
+ while (true) {
+ resp = GET_KEY_PRESSED(icc);
+ if (resp == (byte) 0x00) {
+ synchronized(this) {
+ try {
+ wait(PIN_ENTRY_POLLING_INTERVAL);
+ } catch (InterruptedException ex) {
+ log.error("interrupted in MODIFY_PIN");
+ }
+ }
+ } else if (resp == (byte) 0x0d) {
+ if (log.isTraceEnabled()) {
+ log.trace("requested pin confirmations: 0b" + Integer.toBinaryString(bConfirmPIN & 0xff));
+ log.trace("performed pin confirmations: 0b" + Integer.toBinaryString(pinConfirmations & 0xff));
+ }
+ log.debug("GET_KEY_PRESSED: 0x0d (user confirmed)");
+ if (pinConfirmations == bConfirmPIN) {
+ break;
+ } else if ((bConfirmPIN & (byte) 0x02) == 0 ||
+ (pinConfirmations & (byte) 0x02) == (byte) 0x02) {
+ // no current pin entry or current pin entry already performed
+ if ((pinConfirmations & (byte) 0x01) == 0) {
+ // new pin
+ pinConfirmations |= (byte) 0x01;
+ pinGUI.confirmNewPIN(pINSpec);
+ } // else: new pin confirmed
+ } else {
+ // current pin entry
+ pinConfirmations |= (byte) 0x02;
+ pinGUI.enterNewPIN(pINSpec);
+ }
+ } else if (resp == (byte) 0x2b) {
+ log.trace("GET_KEY_PRESSED: 0x2b (user entered valid key 0-9)");
+ pinGUI.validKeyPressed();
+ } else if (resp == (byte) 0x1b) {
+ log.debug("GET_KEY_PRESSED: 0x1b (user cancelled VERIFY_PIN via cancel button)");
+ break; // returns 0x6401
+ } else if (resp == (byte) 0x08) {
+ log.debug("GET_KEY_PRESSED: 0x08 (user pressed correction/backspace button)");
+ pinGUI.correctionButtonPressed();
+ } else if (resp == (byte) 0x0e) {
+ log.debug("GET_KEY_PRESSED: 0x0e (timeout occured)");
+ break; // return 0x6400
+ } else if (resp == (byte) 0x40) {
+ log.debug("GET_KEY_PRESSED: 0x40 (PIN_Operation_Aborted)");
+ throw new PINOperationAbortedException("PIN_Operation_Aborted (0x40)");
+ } else if (resp == (byte) 0x0a) {
+ log.debug("GET_KEY_PRESSED: 0x0a (all keys cleared");
+ pinGUI.allKeysCleared();
+ } else {
+ log.error("unexpected response to GET_KEY_PRESSED: " +
+ Integer.toHexString(resp));
+ throw new CardException("unexpected response to GET_KEY_PRESSED: " +
+ Integer.toHexString(resp));
+ }
+
+ }
+
+ pinGUI.finish();
+ return MODIFY_PIN_FINISH(icc);
+ }
+
+ private byte[] MODIFY_PIN_DIRECT(Card icc, byte[] PIN_MODIFY) throws CardException {
+ 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;
+ }
+
+ protected byte[] createPINModifyStructure(NewReferenceDataAPDUSpec apduSpec, PINSpec pinSpec) {
+
+ ByteArrayOutputStream s = new ByteArrayOutputStream();
+ // bTimeOut
+ s.write(bTimeOut);
+ // bTimeOut2
+ s.write(bTimeOut2);
+ // bmFormatString
+ s.write(1 << 7 // system unit = byte
+ | (0xF & apduSpec.getPinPosition()) << 3
+ | (0x1 & apduSpec.getPinJustification() << 2)
+ | (0x3 & apduSpec.getPinFormat()));
+ // bmPINBlockString
+ s.write((0xF & apduSpec.getPinLengthSize()) << 4
+ | (0xF & apduSpec.getPinLength()));
+ // bmPINLengthFormat
+ s.write(// system unit = bit
+ (0xF & apduSpec.getPinLengthPos()));
+ // bInsertionOffsetOld
+ s.write(0x00);
+ // bInsertionOffsetNew
+ s.write(apduSpec.getPinInsertionOffsetNew());
+ // wPINMaxExtraDigit
+ s.write(Math.min(pinSpec.getMaxLength(), wPINMaxExtraDigitL));
+ s.write(Math.max(pinSpec.getMinLength(), wPINMaxExtraDigitH));
+ // bConfirmPIN
+ s.write(0x01);
+ // bEntryValidationCondition
+ s.write(bEntryValidationCondition);
+ // bNumberMessage
+ s.write(0x02);
+ // wLangId English (United States), see http://www.usb.org/developers/docs/USB_LANGIDs.pdf
+ s.write(0x09);
+ s.write(0x04);
+ // bMsgIndex1
+ s.write(0x01);
+ // bMsgIndex2
+ s.write(0x02);
+ // bMsgIndex3
+ s.write(0x00);
+
+ // bTeoPrologue
+ s.write(0x00);
+ s.write(0x00);
+ s.write(0x00);
+ // ulDataLength
+ s.write(apduSpec.getApdu().length);
+ s.write(0x00);
+ s.write(0x00);
+ s.write(0x00);
+ // abData
+ try {
+ s.write(apduSpec.getApdu());
+ } catch (IOException e) {
+ // As we are dealing with ByteArrayOutputStreams no exception is to be
+ // expected.
+ throw new RuntimeException(e);
+ }
+
+ return s.toByteArray();
+
+ }
+
+ protected byte[] createPINModifyStructure(ChangeReferenceDataAPDUSpec apduSpec, PINSpec pinSpec) {
+ //TODO bInsertionOffsetOld (0x00), bConfirmPIN (0x01), bNumberMessage (0x02), bMsgIndex1/2/3
+
+ ByteArrayOutputStream s = new ByteArrayOutputStream();
+ // bTimeOut
+ s.write(bTimeOut);
+ // bTimeOut2
+ s.write(bTimeOut2);
+ // bmFormatString
+ s.write(1 << 7 // system unit = byte
+ | (0xF & apduSpec.getPinPosition()) << 3
+ | (0x1 & apduSpec.getPinJustification() << 2)
+ | (0x3 & apduSpec.getPinFormat()));
+ // bmPINBlockString
+ s.write((0xF & apduSpec.getPinLengthSize()) << 4
+ | (0xF & apduSpec.getPinLength()));
+ // bmPINLengthFormat
+ s.write(// system unit = bit
+ (0xF & apduSpec.getPinLengthPos()));
+ // bInsertionOffsetOld (0x00 for no old pin?)
+ s.write(apduSpec.getPinInsertionOffsetOld());
+ // bInsertionOffsetNew
+ s.write(apduSpec.getPinInsertionOffsetNew());
+ // wPINMaxExtraDigit
+ s.write(Math.min(pinSpec.getMaxLength(), wPINMaxExtraDigitL));
+ s.write(Math.max(pinSpec.getMinLength(), wPINMaxExtraDigitH));
+ // bConfirmPIN
+ s.write(0x03);
+ // bEntryValidationCondition
+ s.write(bEntryValidationCondition);
+ // bNumberMessage
+ s.write(0x03);
+ // wLangId English (United States), see http://www.usb.org/developers/docs/USB_LANGIDs.pdf
+ s.write(0x09);
+ s.write(0x04);
+ // bMsgIndex1
+ s.write(0x00);
+ // bMsgIndex2
+ s.write(0x01);
+ // bMsgIndex3
+ s.write(0x02);
+
+ // bTeoPrologue
+ s.write(0x00);
+ s.write(0x00);
+ s.write(0x00);
+ // ulDataLength
+ s.write(apduSpec.getApdu().length);
+ s.write(0x00);
+ s.write(0x00);
+ s.write(0x00);
+ // abData
+ try {
+ s.write(apduSpec.getApdu());
+ } catch (IOException e) {
+ // As we are dealing with ByteArrayOutputStreams no exception is to be
+ // expected.
+ throw new RuntimeException(e);
+ }
+
+ return s.toByteArray();
+
+ }
+
+ protected byte[] createPINVerifyStructure(VerifyAPDUSpec apduSpec, PINSpec pinSpec) {
+
+ ByteArrayOutputStream s = new ByteArrayOutputStream();
+ // bTimeOut
+ s.write(bTimeOut);
+ // bTimeOut2
+ s.write(bTimeOut2);
+ // bmFormatString
+ s.write(1 << 7 // system unit = byte
+ | (0xF & apduSpec.getPinPosition()) << 3
+ | (0x1 & apduSpec.getPinJustification() << 2)
+ | (0x3 & apduSpec.getPinFormat()));
+ // bmPINBlockString
+ s.write((0xF & apduSpec.getPinLengthSize()) << 4
+ | (0xF & apduSpec.getPinLength()));
+ // bmPINLengthFormat
+ s.write(// system unit = bit
+ (0xF & apduSpec.getPinLengthPos()));
+ // wPINMaxExtraDigit
+ s.write(Math.min(pinSpec.getMaxLength(), wPINMaxExtraDigitL)); // max PIN length
+ s.write(Math.max(pinSpec.getMinLength(), wPINMaxExtraDigitH)); // min PIN length
+ // bEntryValidationCondition
+ s.write(bEntryValidationCondition);
+ // bNumberMessage
+ s.write(0x01);
+ // wLangId
+ s.write(0x09);
+ s.write(0x04);
+ // bMsgIndex
+ s.write(0x00);
+ // bTeoPrologue
+ s.write(0x00);
+ s.write(0x00);
+ s.write(0x00);
+ // ulDataLength
+ s.write(apduSpec.getApdu().length);
+ s.write(0x00);
+ s.write(0x00);
+ s.write(0x00);
+ // abData
+ try {
+ s.write(apduSpec.getApdu());
+ } catch (IOException e) {
+ // As we are dealing with ByteArrayOutputStreams no exception is to be
+ // expected.
+ throw new RuntimeException(e);
+ }
+
+ return s.toByteArray();
+
+ }
+
+ @Override
+ public ResponseAPDU verify(CardChannel channel, VerifyAPDUSpec apduSpec,
+ PINGUI pinGUI, PINSpec pinSpec, int retries)
+ throws SignatureCardException, CardException, InterruptedException {
+
+ ResponseAPDU resp = null;
+
+ byte[] s = createPINVerifyStructure(apduSpec, pinSpec);
+ Card icc = channel.getCard();
+
+ if (VERIFY) {
+ pinGUI.enterPIN(pinSpec, retries);
+ resp = new ResponseAPDU(verifyPin(icc, s, pinGUI));
+ } else if (VERIFY_DIRECT) {
+ pinGUI.enterPINDirect(pinSpec, retries);
+ log.debug("VERIFY_PIN_DIRECT [" + FEATURES[FEATURE_VERIFY_PIN_DIRECT] + "]");
+ resp = new ResponseAPDU(VERIFY_PIN_DIRECT(icc, s));
+ } else {
+ log.warn("falling back to default pin-entry");
+ return super.verify(channel, apduSpec, pinGUI, pinSpec, retries);
+ }
+
+ switch (resp.getSW()) {
+ case 0x6400:
+ log.debug("SPE operation timed out.");
+ throw new TimeoutException();
+ case 0x6401:
+ log.debug("SPE operation was cancelled by the 'Cancel' button.");
+ throw new CancelledException();
+ case 0x6403:
+ log.debug("User entered too short or too long PIN "
+ + "regarding MIN/MAX PIN length.");
+ throw new PINFormatException();
+ case 0x6480:
+ log.debug("SPE operation was aborted by the 'Cancel' operation "
+ + "at the host system.");
+ case 0x6b80:
+ log.info("Invalid parameter in passed structure.");
+ default:
+ return resp;
+ }
+ }
+
+ @Override
+ public ResponseAPDU modify(CardChannel channel, ChangeReferenceDataAPDUSpec apduSpec,
+ ModifyPINGUI pinGUI, PINSpec pinSpec, int retries)
+ throws SignatureCardException, CardException, InterruptedException {
+
+ ResponseAPDU resp = null;
+
+ byte[] s = createPINModifyStructure(apduSpec, pinSpec);
+ Card icc = channel.getCard();
+
+ if (MODIFY) {
+ pinGUI.enterCurrentPIN(pinSpec, retries);
+ resp = new ResponseAPDU(modifyPin(icc, s, pinGUI, pinSpec));
+ } else if (MODIFY_DIRECT) {
+ pinGUI.modifyPINDirect(pinSpec, retries);
+ log.debug("MODIFY_PIN_DIRECT [" + FEATURES[FEATURE_MODIFY_PIN_DIRECT] + "]");
+ resp = new ResponseAPDU(MODIFY_PIN_DIRECT(icc, s));
+ } else {
+ log.warn("falling back to default pin-entry");
+ return super.modify(channel, apduSpec, pinGUI, pinSpec, retries);
+ }
+
+ switch (resp.getSW()) {
+ case 0x6400:
+ log.debug("SPE operation timed out.");
+ throw new TimeoutException();
+ case 0x6401:
+ log.debug("SPE operation was cancelled by the 'Cancel' button.");
+ throw new CancelledException();
+ case 0x6402:
+ log.debug("Modify PIN operation failed because two 'new PIN' " +
+ "entries do not match");
+ throw new PINConfirmationException();
+ case 0x6403:
+ log.debug("User entered too short or too long PIN "
+ + "regarding MIN/MAX PIN length.");
+ throw new PINFormatException();
+ case 0x6480:
+ log.debug("SPE operation was aborted by the 'Cancel' operation "
+ + "at the host system.");
+ case 0x6b80:
+ log.info("Invalid parameter in passed structure.");
+ default:
+ return resp;
+ }
+ }
+
+ @Override
+ public ResponseAPDU modify(CardChannel channel, NewReferenceDataAPDUSpec apduSpec,
+ ModifyPINGUI pinGUI, PINSpec pinSpec)
+ throws SignatureCardException, CardException, InterruptedException {
+
+ ResponseAPDU resp = null;
+
+ byte[] s = createPINModifyStructure(apduSpec, pinSpec);
+ Card icc = channel.getCard();
+
+ if (MODIFY) {
+ pinGUI.enterNewPIN(pinSpec);
+ resp = new ResponseAPDU(modifyPin(icc, s, pinGUI, pinSpec));
+ } else if (MODIFY_DIRECT) {
+ pinGUI.modifyPINDirect(pinSpec, -1);
+ log.debug("MODIFY_PIN_DIRECT [" + FEATURES[FEATURE_MODIFY_PIN_DIRECT] + "]");
+ resp = new ResponseAPDU(MODIFY_PIN_DIRECT(icc, s));
+ } else {
+ log.warn("falling back to default pin-entry");
+ return super.modify(channel, apduSpec, pinGUI, pinSpec);
+ }
+
+ switch (resp.getSW()) {
+ case 0x6400:
+ log.debug("SPE operation timed out.");
+ throw new TimeoutException();
+ case 0x6401:
+ log.debug("SPE operation was cancelled by the 'Cancel' button.");
+ throw new CancelledException();
+ case 0x6402:
+ log.debug("Modify PIN operation failed because two 'new PIN' " +
+ "entries do not match");
+ throw new PINConfirmationException();
+ case 0x6403:
+ log.debug("User entered too short or too long PIN "
+ + "regarding MIN/MAX PIN length.");
+ throw new PINFormatException();
+ case 0x6480:
+ log.debug("SPE operation was aborted by the 'Cancel' operation "
+ + "at the host system.");
+ case 0x6b80:
+ log.info("Invalid parameter in passed structure.");
+ default:
+ return resp;
+ }
+ }
+
+ @Override
+ public ResponseAPDU modify(CardChannel channel, ResetRetryCounterAPDUSpec apduSpec,
+ ModifyPINGUI pinGUI, PINSpec pinSpec, int retries)
+ throws InterruptedException, CardException, SignatureCardException {
+ //TODO
+ return modify(channel, (ChangeReferenceDataAPDUSpec) apduSpec, pinGUI, pinSpec, retries);
+ }
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/reader/ReaderFactory.java b/smcc/src/main/java/at/gv/egiz/smcc/reader/ReaderFactory.java
new file mode 100644
index 00000000..eb197d9f
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/reader/ReaderFactory.java
@@ -0,0 +1,128 @@
+/*
+ * 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.reader;
+
+import at.gv.egiz.smcc.conf.SMCCConfiguration;
+import at.gv.egiz.smcc.util.SMCCHelper;
+import java.util.HashMap;
+import java.util.Map;
+import javax.smartcardio.Card;
+import javax.smartcardio.CardException;
+import javax.smartcardio.CardTerminal;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public class ReaderFactory {
+
+ protected final static Log log = LogFactory.getLog(ReaderFactory.class);
+
+ protected SMCCConfiguration configuration;
+
+ private ReaderFactory() {
+ }
+
+ /**
+ * @param configuration the configuration to set
+ */
+ public void setConfiguration(SMCCConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+ public static CardReader getReader(Card icc, CardTerminal ct) {
+
+ String name = ct.getName();
+ log.info("creating reader " + name);
+
+ Map<Byte, Integer> features = queryFeatures(icc);
+ boolean disablePinpad = false;
+ CardReader reader;
+
+ //TODO query application context for reader config
+// if (configuration != null) {
+// String disablePinpad = configuration.getProperty(SMCCConfiguration.DISABLE_PINPAD_P);
+// log.debug("setting disablePinpad to " + Boolean.parseBoolean(disablePinpad));
+// reader.setDisablePinpad(Boolean.parseBoolean(disablePinpad));
+// }
+ log.warn("card reader configuration is not considered");
+
+ if (features.isEmpty() || disablePinpad) {
+ reader = new DefaultCardReader(ct);
+ } else {
+ reader = new PinpadCardReader(ct, features);
+ }
+
+ return reader;
+ }
+
+ private static int CTL_CODE(int 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);
+ }
+
+ static int IOCTL_GET_FEATURE_REQUEST = CTL_CODE(3400);
+
+ private static Map<Byte, Integer> queryFeatures(Card icc) {
+ Map<Byte, Integer> features = new HashMap<Byte, Integer>();
+
+ if (icc == null) {
+ log.warn("invalid card handle, cannot query ifd features");
+ } else {
+ try {
+ if (log.isTraceEnabled()) {
+ log.trace("GET_FEATURE_REQUEST " + Integer.toHexString(IOCTL_GET_FEATURE_REQUEST));
+ }
+ byte[] resp = icc.transmitControlCommand(IOCTL_GET_FEATURE_REQUEST,
+ new byte[0]);
+
+ if (log.isTraceEnabled()) {
+ log.trace("Response TLV " + SMCCHelper.toString(resp));
+ }
+ // tag
+ // length in bytes (always 4)
+ // control code value for supported feature (in big endian)
+ for (int i = 0; i < resp.length; i += 6) {
+ Byte feature = new Byte(resp[i]);
+ Integer ioctl = new Integer((0xff & resp[i + 2]) << 24) |
+ ((0xff & resp[i + 3]) << 16) |
+ ((0xff & resp[i + 4]) << 8) |
+ (0xff & resp[i + 5]);
+ if (log.isInfoEnabled()) {
+ log.info("IFD supports " + CardReader.FEATURES[feature.intValue()] +
+ ": " + Integer.toHexString(ioctl.intValue()));
+ }
+ features.put(feature, ioctl);
+ }
+ } catch (CardException ex) {
+ log.debug("Failed to query IFD features: " + ex.getMessage());
+ log.trace(ex);
+ log.info("IFD does not support secure pin entry");
+ }
+ }
+ return features;
+ }
+
+}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/AbstractAppl.java b/smcc/src/test/java/at/gv/egiz/smcc/AbstractAppl.java
index 137de509..affb06ff 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/AbstractAppl.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/AbstractAppl.java
@@ -51,6 +51,7 @@ public abstract class AbstractAppl implements CardAppl {
return files;
}
+ @Override
public abstract void setPin(int kid, char[] value);
} \ No newline at end of file
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/CardEmul.java b/smcc/src/test/java/at/gv/egiz/smcc/CardEmul.java
index 6017bcce..3dfc8510 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/CardEmul.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/CardEmul.java
@@ -28,15 +28,15 @@ import javax.smartcardio.CardException;
@SuppressWarnings("restriction")
public abstract class CardEmul extends Card {
- protected Thread exclThread = null;
- protected CardChannel channel = newCardChannel(this);
+ protected Thread exclThread; // = null;
+ protected CardChannel channel; // = newCardChannel(this);
protected List<AbstractAppl> applications = new ArrayList<AbstractAppl>();
public CardEmul() {
super();
}
- protected abstract CardChannelEmul newCardChannel(CardEmul cardEmul);
+// protected abstract CardChannelEmul newCardChannel(CardEmul cardEmul);
@Override
public void beginExclusive() throws CardException {
@@ -71,9 +71,9 @@ public abstract class CardEmul extends Card {
@Override
public void disconnect(boolean reset) throws CardException {
- if (reset) {
- channel = newCardChannel(this);
- }
+// if (reset) {
+// channel = newCardChannel(this);
+// }
}
@Override
@@ -93,7 +93,7 @@ public abstract class CardEmul extends Card {
}
public AbstractAppl getApplication(byte[] fid) {
-
+
for(AbstractAppl appl : applications) {
if (Arrays.equals(appl.getAID(), fid) || Arrays.equals(appl.getFID(), fid)) {
return appl;
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/CardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/CardTest.java
index b3bd07ab..44e48836 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/CardTest.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/CardTest.java
@@ -16,12 +16,14 @@
*/
package at.gv.egiz.smcc;
+import at.gv.egiz.smcc.pin.gui.CancelPINProvider;
+import at.gv.egiz.smcc.pin.gui.InterruptPINProvider;
+import at.gv.egiz.smcc.pin.gui.CancelChangePINProvider;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;
@@ -32,119 +34,15 @@ import org.junit.Test;
import at.gv.egiz.smcc.SignatureCard.KeyboxName;
import at.gv.egiz.smcc.acos.A04ApplDEC;
+import at.gv.egiz.smcc.pin.gui.DummyPINGUI;
+import at.gv.egiz.smcc.pin.gui.ModifyPINGUI;
+import at.gv.egiz.smcc.pin.gui.PINGUI;
+import at.gv.egiz.smcc.pin.gui.SMCCTestPINProvider;
+import org.junit.Ignore;
@SuppressWarnings("restriction")
public abstract class CardTest {
- public class TestPINProvider implements PINProvider {
-
- int provided = 0;
-
- char[] pin;
-
- public TestPINProvider(char[] pin) {
- super();
- this.pin = pin;
- }
-
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
- provided++;
- return pin;
- }
-
- public int getProvided() {
- return provided;
- }
-
- }
-
- public class TestChangePINProvider extends TestPINProvider implements
- ChangePINProvider {
-
- char[] oldPin;
-
- public TestChangePINProvider(char[] oldPin, char[] pin) {
- super(pin);
- this.oldPin = oldPin;
- }
-
- @Override
- public char[] provideOldPIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
- return oldPin;
- }
-
- }
-
- public class TestInvalidPINProvider implements PINProvider {
-
- int provided = 0;
- int numWrongTries = 0;
-
- char[] pin;
-
- public TestInvalidPINProvider(char[] pin, int numWrongTries) {
- super();
- this.pin = pin;
- this.numWrongTries = numWrongTries;
- }
-
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
- if (provided >= numWrongTries) {
- throw new CancelledException("Number of wrong tries reached: " + provided);
- } else {
- provided++;
- return pin;
- }
- }
-
- public int getProvided() {
- return provided;
- }
- }
-
- public class TestInvalidChangePINProvider implements ChangePINProvider {
-
- int provided = 0;
- int numWrongTries = 0;
-
- char[] pin;
- char[] oldPin;
-
- /** emulate ChangePinProvider */
- public TestInvalidChangePINProvider(char[] oldPin, char[] newPin, int numWrongTries) {
- super();
- this.pin = newPin;
- this.oldPin = oldPin;
- this.numWrongTries = numWrongTries;
- }
-
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
- return pin;
- }
-
- public int getProvided() {
- return provided;
- }
-
- @Override
- public char[] provideOldPIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
- if (provided >= numWrongTries) {
- throw new CancelledException("Number of wrong tries reached: " + provided);
- } else {
- provided++;
- return oldPin;
- }
- }
- }
-
public CardTest() {
super();
}
@@ -167,7 +65,7 @@ public abstract class CardTest {
SignatureCard signatureCard = createSignatureCard();
- TestPINProvider pinProvider = new TestPINProvider(pin);
+ SMCCTestPINProvider pinProvider = new SMCCTestPINProvider(pin);
byte[] idlink = signatureCard.getInfobox("IdentityLink",
pinProvider, null);
@@ -184,13 +82,7 @@ public abstract class CardTest {
SignatureCard signatureCard = createSignatureCard();
- PINProvider pinProvider = new PINProvider() {
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
- throw new CancelledException();
- }
- };
+ PINGUI pinProvider = new CancelPINProvider();
signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR, pinProvider,
@@ -205,13 +97,7 @@ public abstract class CardTest {
SignatureCard signatureCard = createSignatureCard();
- PINProvider pinProvider = new PINProvider() {
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
- throw new CancelledException();
- }
- };
+ PINGUI pinProvider = new CancelPINProvider();
signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR,
@@ -226,13 +112,7 @@ public abstract class CardTest {
SignatureCard signatureCard = createSignatureCard();
- PINProvider pinProvider = new PINProvider() {
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
- throw new InterruptedException();
- }
- };
+ PINGUI pinProvider = new InterruptPINProvider();
signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR,
@@ -247,13 +127,7 @@ public abstract class CardTest {
SignatureCard signatureCard = createSignatureCard();
- PINProvider pinProvider = new PINProvider() {
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
- throw new InterruptedException();
- }
- };
+ PINGUI pinProvider = new InterruptPINProvider();
signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR,
@@ -268,11 +142,11 @@ public abstract class CardTest {
final SignatureCard signatureCard = createSignatureCard();
- PINProvider pinProvider = new PINProvider() {
+ PINGUI pinProvider = new DummyPINGUI() {
@Override
public char[] providePIN(PINSpec spec, int retries)
throws CancelledException, InterruptedException {
-
+
try {
signatureCard.getCertificate(KeyboxName.SECURE_SIGNATURE_KEYPAIR);
assertTrue(false);
@@ -281,10 +155,10 @@ public abstract class CardTest {
// expected
throw new CancelledException();
}
-
+
}
};
-
+
signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR,
pinProvider, null);
@@ -298,7 +172,7 @@ public abstract class CardTest {
final SignatureCard signatureCard = createSignatureCard();
- PINProvider pinProvider = new PINProvider() {
+ PINGUI pinProvider = new DummyPINGUI() {
@Override
public char[] providePIN(PINSpec spec, int retries)
throws CancelledException, InterruptedException {
@@ -311,7 +185,6 @@ public abstract class CardTest {
// expected
throw new CancelledException();
}
-
}
};
@@ -339,13 +212,7 @@ public abstract class CardTest {
PINMgmtSignatureCard signatureCard = (PINMgmtSignatureCard) createSignatureCard();
- PINProvider pinProvider = new PINProvider() {
- @Override
- public char[] providePIN(PINSpec spec, int retries)
- throws CancelledException, InterruptedException {
- throw new CancelledException();
- }
- };
+ ModifyPINGUI pinProvider = new CancelChangePINProvider();
List<PINSpec> specs = signatureCard.getPINSpecs();
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/PIN.java b/smcc/src/test/java/at/gv/egiz/smcc/PIN.java
index ae883727..2cda0c2f 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/PIN.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/PIN.java
@@ -23,19 +23,23 @@ public class PIN {
public static final int STATE_PIN_VERIFIED = 1;
public static final int STATE_PIN_BLOCKED = -1;
+
+ public static final int STATE_PIN_NOTACTIVE = 2;
public byte[] pin;
public int kid;
- public int state = STATE_RESET;
+ public int state; // = STATE_RESET;
- public int kfpc = 10;
+ public int kfpc; // = 10;
- public PIN(byte[] pin, int kid, int kfpc) {
+ //TODO also provde default constructor without state param
+ public PIN(byte[] pin, int kid, int kfpc, int state) {
this.pin = pin;
this.kid = kid;
this.kfpc = kfpc;
+ this.state = state;
}
}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/acos/A03ApplDEC.java b/smcc/src/test/java/at/gv/egiz/smcc/acos/A03ApplDEC.java
index 9fd96d73..f4ac5c35 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/acos/A03ApplDEC.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/acos/A03ApplDEC.java
@@ -40,7 +40,7 @@ public class A03ApplDEC extends ACOSApplDEC {
putFile(new File(FID_EF_INFOBOX, EF_INFOBOX, FCI_EF_INFOBOX, KID_PIN_INF));
try {
- pins.put(KID_PIN_INF, new PIN("0000\0\0\0\0".getBytes("ASCII"), KID_PIN_INF, 10));
+ pins.put(KID_PIN_INF, new PIN("0000\0\0\0\0".getBytes("ASCII"), KID_PIN_INF, 10, PIN.STATE_RESET));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/acos/A03CardEmul.java b/smcc/src/test/java/at/gv/egiz/smcc/acos/A03CardEmul.java
index 58216b6b..7394bae7 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/acos/A03CardEmul.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/acos/A03CardEmul.java
@@ -24,13 +24,8 @@ import at.gv.egiz.smcc.CardEmul;
public class A03CardEmul extends ACOSCardEmul {
public A03CardEmul(A03ApplSIG applSIG, A03ApplDEC applDEC) {
+ channel = new A03CardChannelEmul(this);
applications.add(applSIG);
applications.add(applDEC);
}
-
- @Override
- protected CardChannelEmul newCardChannel(CardEmul cardEmul) {
- return new A03CardChannelEmul(this);
- }
-
}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/acos/A03CardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/acos/A03CardTest.java
index 776c0370..3a8ac41c 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/acos/A03CardTest.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/acos/A03CardTest.java
@@ -22,15 +22,16 @@ import java.util.Arrays;
import org.junit.Test;
-import at.gv.egiz.smcc.ACOSCard;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.CardEmul;
import at.gv.egiz.smcc.CardNotSupportedException;
import at.gv.egiz.smcc.CardTerminalEmul;
+import at.gv.egiz.smcc.pin.gui.ChangePINProvider;
import at.gv.egiz.smcc.LockedException;
import at.gv.egiz.smcc.NotActivatedException;
import at.gv.egiz.smcc.PINFormatException;
import at.gv.egiz.smcc.PINMgmtSignatureCard;
+import at.gv.egiz.smcc.pin.gui.SMCCTestPINProvider;
import at.gv.egiz.smcc.PINSpec;
import at.gv.egiz.smcc.SignatureCard;
import at.gv.egiz.smcc.SignatureCardException;
@@ -74,12 +75,12 @@ public class A03CardTest extends ACOSCardTest {
char[] pin = defaultPin;
for (int i = pinSpec.getMinLength(); i <= pinSpec.getMaxLength(); i++) {
- signatureCard.verifyPIN(pinSpec, new TestPINProvider(pin));
+ signatureCard.verifyPIN(pinSpec, new SMCCTestPINProvider(pin));
char[] newPin = new char[i];
Arrays.fill(newPin, '0');
signatureCard
- .changePIN(pinSpec, new TestChangePINProvider(pin, newPin));
- signatureCard.verifyPIN(pinSpec, new TestPINProvider(newPin));
+ .changePIN(pinSpec, new ChangePINProvider(pin, newPin));
+ signatureCard.verifyPIN(pinSpec, new SMCCTestPINProvider(newPin));
pin = newPin;
}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/acos/A04CardEmul.java b/smcc/src/test/java/at/gv/egiz/smcc/acos/A04CardEmul.java
index 70925aa6..dd44d05b 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/acos/A04CardEmul.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/acos/A04CardEmul.java
@@ -24,14 +24,9 @@ import at.gv.egiz.smcc.CardEmul;
public class A04CardEmul extends ACOSCardEmul {
public A04CardEmul(A04ApplSIG applSIG, A04ApplDEC applDEC) {
+ channel = new A04CardChannelEmul(this);
applications.add(applSIG);
applications.add(applDEC);
}
-
- @Override
- protected CardChannelEmul newCardChannel(CardEmul cardEmul) {
- return new A04CardChannelEmul(this);
- }
-
}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/acos/A04CardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/acos/A04CardTest.java
index d15e80d7..1cbea1b3 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/acos/A04CardTest.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/acos/A04CardTest.java
@@ -28,7 +28,6 @@ import java.util.Arrays;
import org.junit.BeforeClass;
import org.junit.Test;
-import at.gv.egiz.smcc.ACOSCard;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.CardEmul;
import at.gv.egiz.smcc.CardNotSupportedException;
@@ -41,7 +40,8 @@ import at.gv.egiz.smcc.PINSpec;
import at.gv.egiz.smcc.SignatureCard;
import at.gv.egiz.smcc.SignatureCardException;
import at.gv.egiz.smcc.SignatureCardFactory;
-import at.gv.egiz.smcc.CardTest.TestPINProvider;
+import at.gv.egiz.smcc.pin.gui.ChangePINProvider;
+import at.gv.egiz.smcc.pin.gui.SMCCTestPINProvider;
public class A04CardTest extends ACOSCardTest {
@@ -88,8 +88,8 @@ public class A04CardTest extends ACOSCardTest {
char[] newPin = new char[i];
Arrays.fill(newPin, '0');
signatureCard
- .changePIN(pinSpec, new TestChangePINProvider(pin, newPin));
- signatureCard.verifyPIN(pinSpec, new TestPINProvider(newPin));
+ .changePIN(pinSpec, new ChangePINProvider(pin, newPin));
+ signatureCard.verifyPIN(pinSpec, new SMCCTestPINProvider(newPin));
pin = newPin;
}
@@ -111,7 +111,7 @@ public class A04CardTest extends ACOSCardTest {
SignatureCard signatureCard = factory.createSignatureCard(card,
new CardTerminalEmul(card));
- TestPINProvider pinProvider = new TestPINProvider(pin);
+ SMCCTestPINProvider pinProvider = new SMCCTestPINProvider(pin);
byte[] idlink = signatureCard.getInfobox("IdentityLink",
pinProvider, null);
@@ -129,7 +129,7 @@ public class A04CardTest extends ACOSCardTest {
SignatureCard signatureCard = createSignatureCard();
- TestPINProvider pinProvider = new TestPINProvider(pin);
+ SMCCTestPINProvider pinProvider = new SMCCTestPINProvider(pin);
byte[] idlink = signatureCard.getInfobox("IdentityLink",
pinProvider, null);
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSApplDEC.java b/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSApplDEC.java
index 08979536..09a754f3 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSApplDEC.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSApplDEC.java
@@ -297,7 +297,7 @@ public abstract class ACOSApplDEC extends ACOSAppl {
System.arraycopy(C_CH_EKEY, 0, EF_C_CH_EKEY, 0, C_CH_EKEY.length);
putFile(new File(FID_EF_C_CH_EKEY, EF_C_CH_EKEY, FCI_EF_C_CH_EKEY));
try {
- pins.put(KID_PIN_DEC, new PIN("1234\0\0\0\0".getBytes("ASCII"), KID_PIN_DEC, 10));
+ pins.put(KID_PIN_DEC, new PIN("1234\0\0\0\0".getBytes("ASCII"), KID_PIN_DEC, 10, PIN.STATE_RESET));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSApplSIG.java b/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSApplSIG.java
index e476b434..6ab5903a 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSApplSIG.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSApplSIG.java
@@ -221,7 +221,7 @@ public abstract class ACOSApplSIG extends ACOSAppl {
// PINs
try {
- pins.put(KID_PIN_SIG, new PIN(Arrays.copyOf("123456".getBytes("ASCII"), 8), KID_PIN_SIG, 3));
+ pins.put(KID_PIN_SIG, new PIN(Arrays.copyOf("123456".getBytes("ASCII"), 8), KID_PIN_SIG, 3, PIN.STATE_RESET));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSCardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSCardTest.java
index 56d1e4b2..4f012739 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSCardTest.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSCardTest.java
@@ -16,26 +16,23 @@
*/
package at.gv.egiz.smcc.acos;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import org.junit.Test;
-import at.gv.egiz.smcc.ACOSCard;
import at.gv.egiz.smcc.CardEmul;
import at.gv.egiz.smcc.CardNotSupportedException;
import at.gv.egiz.smcc.CardTest;
import at.gv.egiz.smcc.LockedException;
import at.gv.egiz.smcc.NotActivatedException;
+import at.gv.egiz.smcc.pin.gui.SMCCTestPINProvider;
import at.gv.egiz.smcc.SignatureCard;
import at.gv.egiz.smcc.SignatureCardException;
import at.gv.egiz.smcc.SignatureCard.KeyboxName;
@@ -60,7 +57,7 @@ public abstract class ACOSCardTest extends CardTest {
appl.clearInfobox();
byte[] idlink = signatureCard.getInfobox("IdentityLink",
- new TestPINProvider(pin), null);
+ new SMCCTestPINProvider(pin), null);
assertNull(idlink);
}
@@ -76,7 +73,7 @@ public abstract class ACOSCardTest extends CardTest {
ACOSApplDEC appl = (ACOSApplDEC) card.getApplication(ACOSAppl.AID_DEC);
appl.setInfoboxHeader((byte) 0xFF);
- signatureCard.getInfobox("IdentityLink", new TestPINProvider(pin), null);
+ signatureCard.getInfobox("IdentityLink", new SMCCTestPINProvider(pin), null);
}
@@ -138,7 +135,7 @@ public abstract class ACOSCardTest extends CardTest {
byte[] signature = signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")),
- KeyboxName.SECURE_SIGNATURE_KEYPAIR, new TestPINProvider(pin), null);
+ KeyboxName.SECURE_SIGNATURE_KEYPAIR, new SMCCTestPINProvider(pin), null);
assertNotNull(signature);
@@ -158,7 +155,7 @@ public abstract class ACOSCardTest extends CardTest {
byte[] signature = signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")),
- KeyboxName.CERITIFIED_KEYPAIR, new TestPINProvider(pin), null);
+ KeyboxName.CERITIFIED_KEYPAIR, new SMCCTestPINProvider(pin), null);
assertNotNull(signature);
@@ -171,7 +168,7 @@ public abstract class ACOSCardTest extends CardTest {
SignatureCard signatureCard = createSignatureCard();
- TestPINProvider pinProvider = new TestPINProvider("000000".toCharArray());
+ SMCCTestPINProvider pinProvider = new SMCCTestPINProvider("000000".toCharArray());
signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR,
@@ -186,7 +183,7 @@ public abstract class ACOSCardTest extends CardTest {
SignatureCard signatureCard = createSignatureCard();
- TestPINProvider pinProvider = new TestPINProvider("0000".toCharArray());
+ SMCCTestPINProvider pinProvider = new SMCCTestPINProvider("0000".toCharArray());
signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR,
@@ -204,7 +201,7 @@ public abstract class ACOSCardTest extends CardTest {
ACOSApplSIG appl = (ACOSApplSIG) card.getApplication(ACOSAppl.AID_SIG);
appl.setPin(ACOSApplSIG.KID_PIN_SIG, null);
- TestPINProvider pinProvider = new TestPINProvider("000000".toCharArray());
+ SMCCTestPINProvider pinProvider = new SMCCTestPINProvider("000000".toCharArray());
signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR,
@@ -222,7 +219,7 @@ public abstract class ACOSCardTest extends CardTest {
ACOSApplDEC appl = (ACOSApplDEC) card.getApplication(ACOSAppl.AID_DEC);
appl.setPin(ACOSApplDEC.KID_PIN_DEC, null);
- TestPINProvider pinProvider = new TestPINProvider("0000".toCharArray());
+ SMCCTestPINProvider pinProvider = new SMCCTestPINProvider("0000".toCharArray());
signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR,
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/CancelChangePINProvider.java b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/CancelChangePINProvider.java
new file mode 100644
index 00000000..dffe7e29
--- /dev/null
+++ b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/CancelChangePINProvider.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.pin.gui;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+
+public class CancelChangePINProvider extends DummyChangePINGUI implements ModifyPINGUI {
+
+ public CancelChangePINProvider() {
+ }
+
+ @Override
+ public char[] provideCurrentPIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+ throw new CancelledException("cancelled by cancelPINProvider");
+ }
+
+ @Override
+ public char[] provideNewPIN(PINSpec spec)
+ throws CancelledException, InterruptedException {
+ throw new CancelledException("cancelled by cancelPINProvider");
+ }
+
+} \ No newline at end of file
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/CancelPINProvider.java b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/CancelPINProvider.java
new file mode 100644
index 00000000..77f19345
--- /dev/null
+++ b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/CancelPINProvider.java
@@ -0,0 +1,29 @@
+/*
+ * 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.pin.gui;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+
+public class CancelPINProvider extends DummyPINGUI implements PINGUI {
+
+ @Override
+ public char[] providePIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+ throw new CancelledException("cancelled by cancelPINProvider");
+ }
+} \ No newline at end of file
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/ChangePINProvider.java b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/ChangePINProvider.java
new file mode 100644
index 00000000..5eb8b9a1
--- /dev/null
+++ b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/ChangePINProvider.java
@@ -0,0 +1,49 @@
+/*
+ * 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.pin.gui;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+
+public class ChangePINProvider extends DummyChangePINGUI implements ModifyPINGUI {
+
+ int provided = 0;
+ char[] pin;
+ char[] oldPin;
+
+ public ChangePINProvider(char[] oldPin, char[] pin) {
+ this.pin = pin;
+ this.oldPin = oldPin;
+ }
+
+ public int getProvided() {
+ return provided;
+ }
+
+ @Override
+ public char[] provideCurrentPIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+ provided++;
+ return oldPin;
+ }
+
+ @Override
+ public char[] provideNewPIN(PINSpec spec) {
+ return pin;
+ }
+
+}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/DummyChangePINGUI.java b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/DummyChangePINGUI.java
new file mode 100644
index 00000000..fff89409
--- /dev/null
+++ b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/DummyChangePINGUI.java
@@ -0,0 +1,68 @@
+/*
+ * 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.pin.gui;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+
+public abstract class DummyChangePINGUI implements ModifyPINGUI {
+
+ @Override
+ public void validKeyPressed() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void correctionButtonPressed() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void allKeysCleared() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void finish() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void finishDirect() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void modifyPINDirect(PINSpec spec, int retries) throws CancelledException, InterruptedException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void enterCurrentPIN(PINSpec spec, int retries) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void enterNewPIN(PINSpec spec) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void confirmNewPIN(PINSpec spec) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+} \ No newline at end of file
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/DummyPINGUI.java b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/DummyPINGUI.java
new file mode 100644
index 00000000..4d99b5c1
--- /dev/null
+++ b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/DummyPINGUI.java
@@ -0,0 +1,48 @@
+/*
+ * 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.pin.gui;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+
+public abstract class DummyPINGUI implements PINGUI {
+
+ @Override
+ public void enterPINDirect(PINSpec spec, int retries) throws CancelledException, InterruptedException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void enterPIN(PINSpec spec, int retries) throws CancelledException, InterruptedException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void validKeyPressed() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void correctionButtonPressed() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void allKeysCleared() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+} \ No newline at end of file
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InterruptPINProvider.java b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InterruptPINProvider.java
new file mode 100644
index 00000000..5706b888
--- /dev/null
+++ b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InterruptPINProvider.java
@@ -0,0 +1,34 @@
+/*
+ * 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.pin.gui;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+
+@SuppressWarnings("restriction")
+public class InterruptPINProvider extends DummyPINGUI implements PINGUI {
+
+ public InterruptPINProvider() {
+ }
+
+ @Override
+ public char[] providePIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+ throw new InterruptedException("interrupted by cancelPINProvider");
+ }
+
+} \ No newline at end of file
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InvalidChangePINProvider.java b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InvalidChangePINProvider.java
new file mode 100644
index 00000000..69c9f42a
--- /dev/null
+++ b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InvalidChangePINProvider.java
@@ -0,0 +1,56 @@
+/*
+ * 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.pin.gui;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+
+public class InvalidChangePINProvider extends DummyChangePINGUI implements ModifyPINGUI {
+
+ int provided = 0;
+ int numWrongTries = 0;
+ char[] pin;
+ char[] oldPin;
+
+ /** emulate ChangePinProvider */
+ public InvalidChangePINProvider(char[] oldPin, char[] newPin, int numWrongTries) {
+ super();
+ this.pin = newPin;
+ this.oldPin = oldPin;
+ this.numWrongTries = numWrongTries;
+ }
+
+ @Override
+ public char[] provideCurrentPIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+ if (provided >= numWrongTries) {
+ throw new CancelledException("Number of wrong tries reached: " + provided);
+ } else {
+ provided++;
+ return oldPin;
+ }
+ }
+
+ public int getProvided() {
+ return provided;
+ }
+
+ @Override
+ public char[] provideNewPIN(PINSpec spec) {
+ return pin;
+ }
+}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InvalidPINProvider.java b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InvalidPINProvider.java
new file mode 100644
index 00000000..db01fd0d
--- /dev/null
+++ b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InvalidPINProvider.java
@@ -0,0 +1,48 @@
+/*
+ * 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.pin.gui;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+
+public class InvalidPINProvider extends DummyPINGUI implements PINGUI {
+
+ int provided = 0;
+ int numWrongTries = 0;
+ char[] pin;
+
+ public InvalidPINProvider(char[] pin, int numWrongTries) {
+ super();
+ this.pin = pin;
+ this.numWrongTries = numWrongTries;
+ }
+
+ @Override
+ public char[] providePIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+ if (provided >= numWrongTries) {
+ throw new CancelledException("Number of wrong tries reached: " + provided);
+ } else {
+ provided++;
+ return pin;
+ }
+ }
+
+ public int getProvided() {
+ return provided;
+ }
+}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/SMCCTestPINProvider.java b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/SMCCTestPINProvider.java
new file mode 100644
index 00000000..dffc90d7
--- /dev/null
+++ b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/SMCCTestPINProvider.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.pin.gui;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+
+public class SMCCTestPINProvider extends DummyPINGUI implements PINGUI {
+
+ public int provided = 0;
+ char[] pin;
+
+ public SMCCTestPINProvider(char[] pin) {
+ this.pin = pin;
+ }
+
+ @Override
+ public char[] providePIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+ provided++;
+ return pin;
+ }
+
+ public int getProvided() {
+ return provided;
+ }
+
+
+} \ No newline at end of file
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSAppl.java b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSAppl.java
index 2ca63eea..62528e6e 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSAppl.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSAppl.java
@@ -69,27 +69,4 @@ public abstract class STARCOSAppl extends AbstractAppl implements CardAppl {
pin.next().state = PIN.STATE_RESET;
}
}
-
- public void setPin(int kid, char[] value) {
- PIN pin = pins.get(kid);
- if (pin != null) {
- if (value == null) {
- pin.pin = null;
- } else {
- byte[] b = new byte[8];
- b[0] = (byte) (0x20 | value.length);
- for(int i = 1, j = 0; i < b.length; i++) {
- int h = ((j < value.length)
- ? Character.digit(value[j++], 10)
- : 0x0F);
- int l = ((j < value.length)
- ? Character.digit(value[j++], 10)
- : 0x0F);
- b[i] = (byte) ((h << 4) | l);
- }
- pin.pin = b;
- }
- }
- }
-
}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplGewoehnlicheSignatur.java b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplGewoehnlicheSignatur.java
index cec305da..8741dd2d 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplGewoehnlicheSignatur.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplGewoehnlicheSignatur.java
@@ -16,7 +16,6 @@
*/
package at.gv.egiz.smcc.starcos;
-import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Random;
@@ -200,12 +199,18 @@ public class STARCOSApplGewoehnlicheSignatur extends STARCOSAppl {
protected byte[] EF_C_X509_CH_AUT = new byte[2000];
-
- public STARCOSApplGewoehnlicheSignatur(STARCOSCardChannelEmul channel) {
+
+ protected byte[] dst;
+
+ public static final byte[] DST = new byte[] { (byte) 0x84, (byte) 0x03, (byte) 0x80, (byte) 0x02, (byte) 0x00, (byte) 0x89, (byte) 0x03, (byte) 0x13, (byte) 0x35, (byte) 0x10};
+ public static final byte[] DST_G3 = new byte[] { (byte) 0x84, (byte) 0x03, (byte) 0x80, (byte) 0x02, (byte) 0x00, (byte) 0x80, (byte) 0x01, (byte) 0x04 };
+
+ public STARCOSApplGewoehnlicheSignatur(STARCOSCardChannelEmul channel, byte[] dst) {
super(channel);
// Files
System.arraycopy(C_X509_CH_AUT, 0, EF_C_X509_CH_AUT, 0, C_X509_CH_AUT.length);
putFile(new File(FID_EF_C_X509_CH_AUT, EF_C_X509_CH_AUT, FCI_EF_C_X509_CH_AUT));
+ this.dst = dst;
}
@Override
@@ -240,12 +245,19 @@ public class STARCOSApplGewoehnlicheSignatur extends STARCOSAppl {
case 0x81:
// EXTERNAL AUTHENTICATE
}
+ case 0xAA:
+ switch (command.getP1()) {
+ case 0x41:
+ if (Arrays.equals(new byte[] {(byte) 0x80, (byte) 0x01, (byte) 0x10}, command.getData())) {
+ return new ResponseAPDU(new byte[] {(byte) 0x90, (byte) 0x00});
+ }
+ default:
+ return new ResponseAPDU(new byte[] {(byte) 0x6A, (byte) 0x80});
+ }
case 0xB6:
switch (command.getP1()) {
case 0x41: {
// PSO - COMPUTE DIGITAL SIGNATURE
- byte[] dst = new byte[] { (byte) 0x84, (byte) 0x03, (byte) 0x80,
- (byte) 0x02, (byte) 0x00, (byte) 0x89, (byte) 0x03, (byte) 0x13, (byte) 0x35, (byte) 0x10};
if (Arrays.equals(dst, command.getData())) {
securityEnv = command.getData();
return new ResponseAPDU(new byte[] {(byte) 0x90, (byte) 0x00});
@@ -328,5 +340,10 @@ public class STARCOSApplGewoehnlicheSignatur extends STARCOSAppl {
}
+ @Override
+ public void setPin(int kid, char[] value) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
} \ No newline at end of file
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplInfobox.java b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplInfobox.java
index b7835a43..c470351a 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplInfobox.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplInfobox.java
@@ -156,5 +156,10 @@ public class STARCOSApplInfobox extends STARCOSAppl {
throw new CardException("Not supported.");
}
+ @Override
+ public void setPin(int kid, char[] value) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
} \ No newline at end of file
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplSichereSignatur.java b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplSichereSignatur.java
index 9fb5ad37..4036ca41 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplSichereSignatur.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSApplSichereSignatur.java
@@ -213,16 +213,14 @@ public class STARCOSApplSichereSignatur extends STARCOSAppl {
protected byte[] EF_C_X509_CH_DS = new byte[2000];
- public STARCOSApplSichereSignatur(STARCOSCardChannelEmul channel) {
+ public STARCOSApplSichereSignatur(STARCOSCardChannelEmul channel, byte[] SS_pin, int pinState) {
super(channel);
// Files
System.arraycopy(C_X509_CH_DS, 0, EF_C_X509_CH_DS, 0, C_X509_CH_DS.length);
putFile(new File(FID_EF_C_X509_CH_DS, EF_C_X509_CH_DS, FCI_EF_C_X509_CH_DS));
// PINs
- pins.put(KID_PIN_SS, new PIN(new byte[] { (byte) 0x24, (byte) 0x12,
- (byte) 0x34, (byte) 0x56, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
- (byte) 0xFF }, KID_PIN_SS, 3));
+ pins.put(KID_PIN_SS, new PIN(SS_pin, KID_PIN_SS, 3, pinState));
}
@Override
@@ -344,4 +342,34 @@ public class STARCOSApplSichereSignatur extends STARCOSAppl {
}
+ /**
+ * set and activate pin
+ * @param value if null, pin will be set to NOTACTIVE
+ */
+ @Override
+ public void setPin(int kid, char[] value) {
+ PIN pin = pins.get(kid);
+ if (pin != null) {
+ if (value == null) {
+// pin.pin = null;
+ //TransportPIN
+// pin.pin = new byte[] { (byte) 0x26, (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+ pin.state = PIN.STATE_PIN_NOTACTIVE;
+ } else {
+ byte[] b = new byte[8];
+ b[0] = (byte) (0x20 | value.length);
+ for(int i = 1, j = 0; i < b.length; i++) {
+ int h = ((j < value.length)
+ ? Character.digit(value[j++], 10)
+ : 0x0F);
+ int l = ((j < value.length)
+ ? Character.digit(value[j++], 10)
+ : 0x0F);
+ b[i] = (byte) ((h << 4) | l);
+ }
+ pin.pin = b;
+ pin.state = PIN.STATE_RESET;
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardChannelEmul.java b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardChannelEmul.java
index 89030894..2e0c54eb 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardChannelEmul.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardChannelEmul.java
@@ -16,7 +16,6 @@
*/
package at.gv.egiz.smcc.starcos;
-import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.HashMap;
@@ -30,6 +29,8 @@ import at.gv.egiz.smcc.CardChannelEmul;
import at.gv.egiz.smcc.CardEmul;
import at.gv.egiz.smcc.File;
import at.gv.egiz.smcc.PIN;
+import java.util.ArrayList;
+import java.util.List;
@SuppressWarnings("restriction")
public class STARCOSCardChannelEmul extends CardChannelEmul {
@@ -40,14 +41,13 @@ public class STARCOSCardChannelEmul extends CardChannelEmul {
*
*/
protected CardEmul cardEmul;
-
+
+ public final List<File> globalFiles = new ArrayList<File>();
public final HashMap<Integer, PIN> globalPins = new HashMap<Integer, PIN>();
- public STARCOSCardChannelEmul(CardEmul cardEmul) {
+ public STARCOSCardChannelEmul(CardEmul cardEmul, byte[] Glob_PIN, int PIN_STATE) {
this.cardEmul = cardEmul;
- globalPins.put(KID_PIN_Glob, new PIN(new byte[] { (byte) 0x24, (byte) 0x00,
- (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
- (byte) 0xFF }, KID_PIN_Glob, 10));
+ globalPins.put(KID_PIN_Glob, new PIN(Glob_PIN, KID_PIN_Glob, 10, PIN_STATE));
}
@Override
@@ -88,6 +88,21 @@ public class STARCOSCardChannelEmul extends CardChannelEmul {
}
}
return new ResponseAPDU(new byte[] {(byte) 0x6A, (byte) 0x82});
+ } else if (globalFiles != null) {
+ if (command.getP2() != 0x04) {
+ throw new CardException("Not supported.");
+ }
+ for (File file : globalFiles) {
+ if (Arrays.equals(fid, file.fid)) {
+ currentFile = file;
+ byte[] response = new byte[file.fcx.length + 2];
+ System.arraycopy(file.fcx, 0, response, 0, file.fcx.length);
+ response[file.fcx.length] = (byte) 0x90;
+ response[file.fcx.length + 1] = (byte) 0x00;
+ return new ResponseAPDU(response);
+ }
+ }
+ return new ResponseAPDU(new byte[] {(byte) 0x6A, (byte) 0x82});
} else {
throw new CardException("Not supported.");
}
@@ -121,6 +136,23 @@ public class STARCOSCardChannelEmul extends CardChannelEmul {
}
+ protected ResponseAPDU cmdREAD_RECORD(CommandAPDU command) throws CardException {
+ if (command.getINS() != 0xB2) {
+ throw new IllegalArgumentException("INS has to be 0xB2");
+ }
+ if (currentFile == null) {
+ return new ResponseAPDU(new byte[]{ (byte) 0x69, (byte) 0x86 });
+ }
+ if (command.getP1() != 0x01 || command.getP2() != 0x04) {
+ throw new CardException("Not implemented.");
+ }
+ byte[] response = new byte[currentFile.file.length + 2];
+ System.arraycopy(currentFile.file, 0, response, 0, currentFile.file.length);
+ response[currentFile.file.length] = (byte) 0x90;
+ response[currentFile.file.length + 1] = (byte) 0x00;
+ return new ResponseAPDU(response);
+ }
+
protected ResponseAPDU cmdREAD_BINARY(CommandAPDU command) throws CardException {
if (command.getINS() != 0xB0) {
@@ -192,6 +224,10 @@ public class STARCOSCardChannelEmul extends CardChannelEmul {
case 0xB0:
return cmdREAD_BINARY(command);
+ // READ RECORD
+ case 0xB2:
+ return cmdREAD_RECORD(command);
+
// VERIFY
case 0x20:
return cmdVERIFY(command);
@@ -248,9 +284,15 @@ public class STARCOSCardChannelEmul extends CardChannelEmul {
}
if (pin != null) {
-
- if (reference.length == 0) {
- return new ResponseAPDU(new byte[] { (byte) 0x63, (byte) (pin.kfpc | 0xC0)});
+
+ if (reference == null || reference.length == 0) {
+ if (pin.state == PIN.STATE_PIN_NOTACTIVE) {
+ return new ResponseAPDU(new byte[] { (byte) 0x69, (byte) 0x84 });
+ } else if (pin.state == PIN.STATE_PIN_BLOCKED) {
+ return new ResponseAPDU(new byte[] { (byte) 0x63, (byte) 0xc0 });
+ } else {
+ return new ResponseAPDU(new byte[] { (byte) 0x63, (byte) (pin.kfpc | 0xC0)});
+ }
}
if (reference.length != 8) {
@@ -264,7 +306,7 @@ public class STARCOSCardChannelEmul extends CardChannelEmul {
case PIN.STATE_RESET:
pin.state = PIN.STATE_PIN_VERIFIED;
-
+
default:
pin.kfpc = 10;
return new ResponseAPDU(new byte[] { (byte) 0x90, (byte) 0x00 });
@@ -321,7 +363,20 @@ public class STARCOSCardChannelEmul extends CardChannelEmul {
return new ResponseAPDU(new byte[] {(byte) 0x67, (byte) 0x00});
}
- response = verifyPin(0xFF & command.getP2(), data);
+ PIN pin;
+ if (currentAppl != null) {
+ pin = currentAppl.pins.get(command.getP2());
+ } else {
+ pin = globalPins.get(command.getP2());
+ }
+ if (pin.state == PIN.STATE_PIN_NOTACTIVE) {
+ pin.pin = data;
+ pin.state = PIN.STATE_RESET;
+ response = new ResponseAPDU(new byte[] { (byte) 0x90, (byte) 0x00 });
+ } else {
+ // P1 == 0x01 not allowed on active pin (?)
+ response = new ResponseAPDU(new byte[] { (byte) 0x6A, (byte) 0x86});
+ }
} else if (command.getP1() == 0x00) {
@@ -330,21 +385,22 @@ public class STARCOSCardChannelEmul extends CardChannelEmul {
}
response = verifyPin(0xFF & command.getP2(), Arrays.copyOf(data, 8));
-
+
+ if (response.getSW() == 0x9000) {
+ PIN pin;
+ if (currentAppl != null) {
+ pin = currentAppl.pins.get(command.getP2());
+ } else {
+ pin = globalPins.get(command.getP2());
+ }
+ pin.pin = Arrays.copyOfRange(data, 8, 16);
+ pin.state = PIN.STATE_PIN_VERIFIED;
+ }
+
} else {
return new ResponseAPDU(new byte[] { (byte) 0x6A, (byte) 0x81 });
}
- if (response.getSW() == 0x9000) {
- PIN pin;
- if (currentAppl != null) {
- pin = currentAppl.pins.get(command.getP2());
- } else {
- pin = globalPins.get(command.getP2());
- }
- pin.pin = Arrays.copyOfRange(data, 8, 16);
- }
-
return response;
}
@@ -353,7 +409,10 @@ public class STARCOSCardChannelEmul extends CardChannelEmul {
PIN pin = globalPins.get(kid);
if (pin != null) {
if (value == null) {
- pin.pin = null;
+// pin.pin = null;
+ //TransportPIN
+// pin.pin = new byte[] { (byte) 0x24, (byte) 0x12, (byte) 0x34, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+ pin.state = PIN.STATE_PIN_NOTACTIVE;
} else {
byte[] b = new byte[8];
b[0] = (byte) (0x20 | value.length);
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardEmul.java b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardEmul.java
index 7b2f3fbe..5963fb63 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardEmul.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardEmul.java
@@ -21,30 +21,34 @@ import javax.smartcardio.ATR;
import at.gv.egiz.smcc.CardChannelEmul;
import at.gv.egiz.smcc.CardEmul;
+import at.gv.egiz.smcc.PIN;
@SuppressWarnings("restriction")
public class STARCOSCardEmul extends CardEmul {
-
+
+ public static byte[] DEFAULT_SS_PIN = new byte[] { (byte) 0x26, (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+ public static byte[] DEFAULT_Glob_PIN = new byte[] { (byte) 0x24, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+
protected static ATR ATR = new ATR(new byte[] {
(byte) 0x3b, (byte) 0xbd, (byte) 0x18, (byte) 0x00, (byte) 0x81, (byte) 0x31, (byte) 0xfe, (byte) 0x45,
(byte) 0x80, (byte) 0x51, (byte) 0x02, (byte) 0x67, (byte) 0x05, (byte) 0x18, (byte) 0xb1, (byte) 0x02,
(byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x81, (byte) 0x05, (byte) 0x31
});
-
+
public STARCOSCardEmul() {
- applications.add(new STARCOSApplSichereSignatur((STARCOSCardChannelEmul) channel));
+ this(DEFAULT_SS_PIN, DEFAULT_Glob_PIN, PIN.STATE_RESET);
+ }
+
+ public STARCOSCardEmul(byte[] SS_PIN, byte[] Glob_PIN, int PIN_STATE) {
+ channel = new STARCOSCardChannelEmul(this, Glob_PIN, PIN_STATE);
+ applications.add(new STARCOSApplSichereSignatur((STARCOSCardChannelEmul) channel, SS_PIN, PIN_STATE));
applications.add(new STARCOSApplInfobox((STARCOSCardChannelEmul) channel));
- applications.add(new STARCOSApplGewoehnlicheSignatur((STARCOSCardChannelEmul) channel));
+ applications.add(new STARCOSApplGewoehnlicheSignatur((STARCOSCardChannelEmul) channel,
+ STARCOSApplGewoehnlicheSignatur.DST));
}
@Override
public ATR getATR() {
return ATR;
}
-
- @Override
- protected CardChannelEmul newCardChannel(CardEmul cardEmul) {
- return new STARCOSCardChannelEmul(this);
- }
-
} \ No newline at end of file
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardTest.java
index b7dc9a0c..154884d4 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardTest.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardTest.java
@@ -22,12 +22,9 @@ import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
-import javax.smartcardio.CardChannel;
import org.junit.Test;
@@ -36,25 +33,20 @@ import at.gv.egiz.smcc.CardEmul;
import at.gv.egiz.smcc.CardNotSupportedException;
import at.gv.egiz.smcc.CardTerminalEmul;
import at.gv.egiz.smcc.CardTest;
+import at.gv.egiz.smcc.pin.gui.ChangePINProvider;
+import at.gv.egiz.smcc.pin.gui.InvalidChangePINProvider;
+import at.gv.egiz.smcc.pin.gui.InvalidPINProvider;
import at.gv.egiz.smcc.LockedException;
import at.gv.egiz.smcc.NotActivatedException;
+import at.gv.egiz.smcc.PIN;
import at.gv.egiz.smcc.PINFormatException;
import at.gv.egiz.smcc.PINMgmtSignatureCard;
import at.gv.egiz.smcc.PINSpec;
-import at.gv.egiz.smcc.STARCOSCard;
import at.gv.egiz.smcc.SignatureCard;
import at.gv.egiz.smcc.SignatureCardException;
import at.gv.egiz.smcc.SignatureCardFactory;
-import at.gv.egiz.smcc.CardTest.TestChangePINProvider;
-import at.gv.egiz.smcc.CardTest.TestPINProvider;
-import at.gv.egiz.smcc.PINProvider;
+import at.gv.egiz.smcc.pin.gui.SMCCTestPINProvider;
import at.gv.egiz.smcc.SignatureCard.KeyboxName;
-import at.gv.egiz.smcc.acos.A03ApplDEC;
-import at.gv.egiz.smcc.acos.A04ApplDEC;
-import at.gv.egiz.smcc.acos.A04ApplSIG;
-import at.gv.egiz.smcc.acos.ACOSAppl;
-import at.gv.egiz.smcc.acos.ACOSApplDEC;
-import at.gv.egiz.smcc.acos.ACOSApplSIG;
import org.junit.Ignore;
public class STARCOSCardTest extends CardTest {
@@ -69,7 +61,17 @@ public class STARCOSCardTest extends CardTest {
assertTrue(signatureCard instanceof PINMgmtSignatureCard);
return signatureCard;
}
-
+
+ protected SignatureCard createSignatureCard(byte[] SS_PIN, byte[] Glob_PIN, int pinState)
+ throws CardNotSupportedException {
+ SignatureCardFactory factory = SignatureCardFactory.getInstance();
+ STARCOSCardEmul card = new STARCOSCardEmul(SS_PIN, Glob_PIN, pinState);
+ SignatureCard signatureCard = factory.createSignatureCard(card,
+ new CardTerminalEmul(card));
+ assertTrue(signatureCard instanceof PINMgmtSignatureCard);
+ return signatureCard;
+ }
+
@Test
public void testGetInfoboxIdentityLinkEmpty() throws SignatureCardException,
InterruptedException, CardNotSupportedException {
@@ -82,7 +84,7 @@ public class STARCOSCardTest extends CardTest {
appl.clearInfobox();
byte[] idlink = signatureCard.getInfobox("IdentityLink",
- new TestPINProvider(pin), null);
+ new SMCCTestPINProvider(pin), null);
assertNull(idlink);
}
@@ -98,10 +100,10 @@ public class STARCOSCardTest extends CardTest {
STARCOSApplInfobox appl = (STARCOSApplInfobox) card.getApplication(STARCOSAppl.AID_Infobox);
appl.setInfoboxHeader((byte) 0xFF);
- signatureCard.getInfobox("IdentityLink", new TestPINProvider(pin), null);
+ signatureCard.getInfobox("IdentityLink", new SMCCTestPINProvider(pin), null);
}
-
+
@Test
public void testGetCerts() throws SignatureCardException,
InterruptedException, CardNotSupportedException {
@@ -145,7 +147,7 @@ public class STARCOSCardTest extends CardTest {
signatureCard.getCertificate(KeyboxName.CERITIFIED_KEYPAIR);
}
-
+
@Test
public void testSignSichereSignatur() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
@@ -160,7 +162,7 @@ public class STARCOSCardTest extends CardTest {
byte[] signature = signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")),
- KeyboxName.SECURE_SIGNATURE_KEYPAIR, new TestPINProvider(pin), null);
+ KeyboxName.SECURE_SIGNATURE_KEYPAIR, new SMCCTestPINProvider(pin), null);
assertNotNull(signature);
@@ -180,12 +182,12 @@ public class STARCOSCardTest extends CardTest {
byte[] signature = signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")),
- KeyboxName.CERITIFIED_KEYPAIR, new TestPINProvider(pin), null);
+ KeyboxName.CERITIFIED_KEYPAIR, new SMCCTestPINProvider(pin), null);
assertNotNull(signature);
}
-
+
@Test(expected = LockedException.class)
public void testSignSichereSignaturInvalidPin() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
@@ -193,7 +195,7 @@ public class STARCOSCardTest extends CardTest {
SignatureCard signatureCard = createSignatureCard();
- TestPINProvider pinProvider = new TestPINProvider("000000".toCharArray());
+ SMCCTestPINProvider pinProvider = new SMCCTestPINProvider("000000".toCharArray());
signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR,
@@ -208,7 +210,7 @@ public class STARCOSCardTest extends CardTest {
SignatureCard signatureCard = createSignatureCard();
- TestPINProvider pinProvider = new TestPINProvider("1234".toCharArray());
+ SMCCTestPINProvider pinProvider = new SMCCTestPINProvider("1234".toCharArray());
signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR,
@@ -221,12 +223,9 @@ public class STARCOSCardTest extends CardTest {
InterruptedException, CardNotSupportedException,
NoSuchAlgorithmException, IOException {
- SignatureCard signatureCard = createSignatureCard();
- CardEmul card = (CardEmul) signatureCard.getCard();
- STARCOSApplSichereSignatur appl = (STARCOSApplSichereSignatur) card.getApplication(STARCOSApplSichereSignatur.AID_SichereSignatur);
- appl.setPin(STARCOSApplSichereSignatur.KID_PIN_SS, null);
+ SignatureCard signatureCard = createSignatureCard(null, null, PIN.STATE_PIN_BLOCKED);
- TestPINProvider pinProvider = new TestPINProvider("000000".toCharArray());
+ SMCCTestPINProvider pinProvider = new SMCCTestPINProvider("000000".toCharArray());
assertTrue(pinProvider.getProvided() <= 0);
signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
@@ -240,68 +239,79 @@ public class STARCOSCardTest extends CardTest {
InterruptedException, CardNotSupportedException,
NoSuchAlgorithmException, IOException {
- SignatureCard signatureCard = createSignatureCard();
- CardEmul card = (CardEmul) signatureCard.getCard();
- STARCOSCardChannelEmul channel = (STARCOSCardChannelEmul) card.getBasicChannel();
- channel.setPin(STARCOSCardChannelEmul.KID_PIN_Glob, null);
-
- TestPINProvider pinProvider = new TestPINProvider("0000".toCharArray());
+ SignatureCard signatureCard = createSignatureCard(null, null, PIN.STATE_PIN_BLOCKED);
+
+ SMCCTestPINProvider pinProvider = new SMCCTestPINProvider("0000".toCharArray());
signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
.getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR,
pinProvider, null);
}
-
+
@Test
public void testChangePin() throws CardNotSupportedException,
LockedException, NotActivatedException, CancelledException,
PINFormatException, SignatureCardException, InterruptedException {
- char[] defaultPin = "123456".toCharArray();
-
- PINMgmtSignatureCard signatureCard = (PINMgmtSignatureCard) createSignatureCard();
- CardEmul card = (CardEmul) signatureCard.getCard();
- STARCOSCardChannelEmul channel = (STARCOSCardChannelEmul) card.getBasicChannel();
- channel.setPin(STARCOSCardChannelEmul.KID_PIN_Glob, defaultPin);
- STARCOSApplSichereSignatur appl = (STARCOSApplSichereSignatur) card.getApplication(STARCOSApplSichereSignatur.AID_SichereSignatur);
- appl.setPin(STARCOSApplSichereSignatur.KID_PIN_SS, defaultPin);
+ // set all initial pins to DEFAULT_SS_PIN (123456)
+ PINMgmtSignatureCard signatureCard = (PINMgmtSignatureCard) createSignatureCard(
+ STARCOSCardEmul.DEFAULT_SS_PIN, STARCOSCardEmul.DEFAULT_SS_PIN, PIN.STATE_RESET);
for (PINSpec pinSpec : signatureCard.getPINSpecs()) {
- char[] pin = defaultPin;
+ char[] pin = "123456".toCharArray();
for (int i = pinSpec.getMinLength(); i <= pinSpec.getMaxLength(); i++) {
- signatureCard.verifyPIN(pinSpec, new TestPINProvider(pin));
+ signatureCard.verifyPIN(pinSpec, new SMCCTestPINProvider(pin));
char[] newPin = new char[i];
Arrays.fill(newPin, '0');
signatureCard
- .changePIN(pinSpec, new TestChangePINProvider(pin, newPin));
- signatureCard.verifyPIN(pinSpec, new TestPINProvider(newPin));
+ .changePIN(pinSpec, new ChangePINProvider(pin, newPin));
+ signatureCard.verifyPIN(pinSpec, new SMCCTestPINProvider(newPin));
pin = newPin;
}
}
}
@Test
- public void testVerifyInvalidPin() throws CardNotSupportedException,
+ @Override
+ public void testActivatePin() throws CardNotSupportedException,
LockedException, NotActivatedException, CancelledException,
PINFormatException, SignatureCardException, InterruptedException {
- char[] defaultPin = "123456".toCharArray();
+ PINMgmtSignatureCard signatureCard = (PINMgmtSignatureCard) createSignatureCard(
+ null, null, PIN.STATE_PIN_NOTACTIVE);
+
+ for (PINSpec pinSpec : signatureCard.getPINSpecs()) {
+
+ char[] pin = "1234567890".substring(0, pinSpec.getMinLength()).toCharArray();
+
+ boolean notActive = false;
+ try {
+ signatureCard.verifyPIN(pinSpec, new SMCCTestPINProvider(pin));
+ } catch (NotActivatedException ex) {
+ notActive = true;
+ }
+ assertTrue(notActive);
+
+ signatureCard.activatePIN(pinSpec, new ChangePINProvider(null, pin));
+ signatureCard.verifyPIN(pinSpec, new SMCCTestPINProvider(pin));
+ }
+ }
+
+ @Test
+ public void testVerifyInvalidPin() throws CardNotSupportedException,
+ LockedException, NotActivatedException, CancelledException,
+ PINFormatException, SignatureCardException, InterruptedException {
PINMgmtSignatureCard signatureCard = (PINMgmtSignatureCard) createSignatureCard();
- CardEmul card = (CardEmul) signatureCard.getCard();
- STARCOSCardChannelEmul channel = (STARCOSCardChannelEmul) card.getBasicChannel();
- channel.setPin(STARCOSCardChannelEmul.KID_PIN_Glob, defaultPin);
- STARCOSApplSichereSignatur appl = (STARCOSApplSichereSignatur) card.getApplication(STARCOSApplSichereSignatur.AID_SichereSignatur);
- appl.setPin(STARCOSApplSichereSignatur.KID_PIN_SS, defaultPin);
for (PINSpec pinSpec : signatureCard.getPINSpecs()) {
char[] invalidPin = "999999".toCharArray();
int numInvalidTries = 2;
- TestInvalidPINProvider invalidPinProvider = new TestInvalidPINProvider(invalidPin, numInvalidTries);
+ InvalidPINProvider invalidPinProvider = new InvalidPINProvider(invalidPin, numInvalidTries);
try {
signatureCard.verifyPIN(pinSpec, invalidPinProvider);
} catch (CancelledException ex) {
@@ -315,21 +325,15 @@ public class STARCOSCardTest extends CardTest {
public void testChangeInvalidPin() throws CardNotSupportedException,
LockedException, NotActivatedException, CancelledException,
PINFormatException, SignatureCardException, InterruptedException {
- char[] defaultPin = "123456".toCharArray();
PINMgmtSignatureCard signatureCard = (PINMgmtSignatureCard) createSignatureCard();
- CardEmul card = (CardEmul) signatureCard.getCard();
- STARCOSCardChannelEmul channel = (STARCOSCardChannelEmul) card.getBasicChannel();
- channel.setPin(STARCOSCardChannelEmul.KID_PIN_Glob, defaultPin);
- STARCOSApplSichereSignatur appl = (STARCOSApplSichereSignatur) card.getApplication(STARCOSApplSichereSignatur.AID_SichereSignatur);
- appl.setPin(STARCOSApplSichereSignatur.KID_PIN_SS, defaultPin);
-
+
for (PINSpec pinSpec : signatureCard.getPINSpecs()) {
char[] invalidPin = "999999".toCharArray();
int numInvalidTries = 2;
- TestInvalidChangePINProvider invalidPinProvider =
- new TestInvalidChangePINProvider(invalidPin, defaultPin, numInvalidTries);
+ InvalidChangePINProvider invalidPinProvider =
+ new InvalidChangePINProvider(invalidPin, invalidPin, numInvalidTries);
try {
signatureCard.changePIN(pinSpec, invalidPinProvider);
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSG3CardChannelEmul.java b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSG3CardChannelEmul.java
new file mode 100644
index 00000000..dc6836ae
--- /dev/null
+++ b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSG3CardChannelEmul.java
@@ -0,0 +1,46 @@
+/*
+ * 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.starcos;
+
+import at.gv.egiz.smcc.CardEmul;
+import at.gv.egiz.smcc.File;
+import at.gv.egiz.smcc.PIN;
+
+/**
+ *
+ * @author clemens
+ */
+public class STARCOSG3CardChannelEmul extends STARCOSCardChannelEmul {
+
+ public STARCOSG3CardChannelEmul(CardEmul cardEmul, byte[] Glob_PIN, int PIN_STATE) {
+ super(cardEmul, Glob_PIN, PIN_STATE);
+
+ // G3 version file
+ byte[] versionFileFID = new byte[]{(byte) 0x00, (byte) 0x32};
+ byte[] versionFile = new byte[]{
+ (byte) 0xa5, (byte) 0x0e, (byte) 0x53, (byte) 0x02, (byte) 0x01, (byte) 0x20, (byte) 0x54, (byte) 0x08,
+ (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x04, (byte) 0x01, (byte) 0x70, (byte) 0x01};
+ byte[] versionFileFCX = new byte[]{
+ (byte) 0x62, (byte) 0x1a, (byte) 0x80, (byte) 0x02, (byte) 0x00, (byte) 0x14, (byte) 0x82, (byte) 0x05,
+ (byte) 0x44, (byte) 0x41, (byte) 0x00, (byte) 0x14, (byte) 0x01, (byte) 0x83, (byte) 0x02, (byte) 0x00,
+ (byte) 0x32, (byte) 0x88, (byte) 0x01, (byte) 0xd8, (byte) 0x8a, (byte) 0x01, (byte) 0x05, (byte) 0xa1,
+ (byte) 0x03, (byte) 0x8b, (byte) 0x01, (byte) 0x03};
+
+ globalFiles.add(new File(versionFileFID, versionFile, versionFileFCX));
+
+ }
+ }
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSG3CardEmul.java b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSG3CardEmul.java
new file mode 100644
index 00000000..7583b3ad
--- /dev/null
+++ b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSG3CardEmul.java
@@ -0,0 +1,57 @@
+/*
+ * 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.starcos;
+
+import at.gv.egiz.smcc.CardEmul;
+import javax.smartcardio.ATR;
+
+import at.gv.egiz.smcc.PIN;
+
+@SuppressWarnings("restriction")
+public class STARCOSG3CardEmul extends CardEmul {
+
+ public static byte[] TRANSPORT_SS_PIN = new byte[] { (byte) 0x26, (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+ public static byte[] TRANSPORT_Glob_PIN = new byte[] { (byte) 0x24, (byte) 0x12, (byte) 0x34, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+
+ public static byte[] DEFAULT_SS_PIN = TRANSPORT_SS_PIN;
+ public static byte[] DEFAULT_Glob_PIN = new byte[] { (byte) 0x24, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+
+ protected static ATR ATR = new ATR(new byte[] {
+ (byte) 0x3b, (byte) 0xbd, (byte) 0x18, (byte) 0x00, (byte) 0x81, (byte) 0x31, (byte) 0xfe, (byte) 0x45,
+ (byte) 0x80, (byte) 0x51, (byte) 0x02, (byte) 0x67, (byte) 0x05, (byte) 0x18, (byte) 0xb1, (byte) 0x02,
+ (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x81, (byte) 0x05, (byte) 0x31
+ });
+
+ public STARCOSG3CardEmul(byte[] SS_PIN, byte[] Glob_PIN, int PIN_STATE){
+ channel = new STARCOSG3CardChannelEmul(this, Glob_PIN, PIN_STATE);
+ applications.add(new STARCOSApplSichereSignatur((STARCOSCardChannelEmul) channel,
+ SS_PIN, PIN_STATE));
+ applications.add(new STARCOSApplInfobox((STARCOSCardChannelEmul) channel));
+ applications.add(new STARCOSApplGewoehnlicheSignatur((STARCOSCardChannelEmul) channel,
+ STARCOSApplGewoehnlicheSignatur.DST_G3));
+ }
+
+
+ public STARCOSG3CardEmul() {
+ this(DEFAULT_SS_PIN, DEFAULT_Glob_PIN, PIN.STATE_RESET);
+ }
+
+ @Override
+ public ATR getATR() {
+ return ATR;
+ }
+}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSG3CardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSG3CardTest.java
new file mode 100644
index 00000000..06744c82
--- /dev/null
+++ b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSG3CardTest.java
@@ -0,0 +1,119 @@
+/*
+* 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.starcos;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+
+import org.junit.Test;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.CardEmul;
+import at.gv.egiz.smcc.CardNotSupportedException;
+import at.gv.egiz.smcc.CardTerminalEmul;
+import at.gv.egiz.smcc.CardTest;
+import at.gv.egiz.smcc.pin.gui.ChangePINProvider;
+import at.gv.egiz.smcc.LockedException;
+import at.gv.egiz.smcc.NotActivatedException;
+import at.gv.egiz.smcc.PIN;
+import at.gv.egiz.smcc.PINFormatException;
+import at.gv.egiz.smcc.PINMgmtSignatureCard;
+import at.gv.egiz.smcc.PINSpec;
+import at.gv.egiz.smcc.SignatureCard;
+import at.gv.egiz.smcc.SignatureCardException;
+import at.gv.egiz.smcc.SignatureCardFactory;
+import at.gv.egiz.smcc.pin.gui.SMCCTestPINProvider;
+import org.junit.Ignore;
+
+public class STARCOSG3CardTest extends CardTest {
+
+ @Override
+ protected SignatureCard createSignatureCard()
+ throws CardNotSupportedException {
+ SignatureCardFactory factory = SignatureCardFactory.getInstance();
+ STARCOSG3CardEmul card = new STARCOSG3CardEmul();
+ SignatureCard signatureCard = factory.createSignatureCard(card,
+ new CardTerminalEmul(card));
+ assertTrue(signatureCard instanceof PINMgmtSignatureCard);
+ return signatureCard;
+ }
+
+ protected SignatureCard createSignatureCard(byte[] SS_PIN, byte[] Glob_PIN, int pinState)
+ throws CardNotSupportedException {
+ SignatureCardFactory factory = SignatureCardFactory.getInstance();
+ STARCOSG3CardEmul card = new STARCOSG3CardEmul(SS_PIN, Glob_PIN, pinState);
+ SignatureCard signatureCard = factory.createSignatureCard(card,
+ new CardTerminalEmul(card));
+ assertTrue(signatureCard instanceof PINMgmtSignatureCard);
+ return signatureCard;
+ }
+
+ @Test
+ public void testChangePin() throws CardNotSupportedException,
+ LockedException, NotActivatedException, CancelledException,
+ PINFormatException, SignatureCardException, InterruptedException {
+
+ PINMgmtSignatureCard signatureCard = (PINMgmtSignatureCard) createSignatureCard(
+ STARCOSG3CardEmul.DEFAULT_SS_PIN, STARCOSG3CardEmul.DEFAULT_SS_PIN, PIN.STATE_RESET);
+
+ for (PINSpec pinSpec : signatureCard.getPINSpecs()) {
+
+ char[] pin = "123456".toCharArray();
+
+ for (int i = pinSpec.getMinLength(); i <= pinSpec.getMaxLength(); i++) {
+ signatureCard.verifyPIN(pinSpec, new SMCCTestPINProvider(pin));
+ char[] newPin = new char[i];
+ Arrays.fill(newPin, '0');
+ signatureCard
+ .changePIN(pinSpec, new ChangePINProvider(pin, newPin));
+ signatureCard.verifyPIN(pinSpec, new SMCCTestPINProvider(newPin));
+ pin = newPin;
+ }
+ }
+ }
+
+ @Test
+ @Override
+ public void testActivatePin() throws CardNotSupportedException,
+ LockedException, NotActivatedException, CancelledException,
+ PINFormatException, SignatureCardException, InterruptedException {
+
+ PINMgmtSignatureCard signatureCard = (PINMgmtSignatureCard) createSignatureCard(
+ STARCOSG3CardEmul.TRANSPORT_SS_PIN, STARCOSG3CardEmul.TRANSPORT_SS_PIN, PIN.STATE_PIN_NOTACTIVE);
+
+ for (PINSpec pinSpec : signatureCard.getPINSpecs()) {
+
+ char[] pin = "123456789".substring(0, pinSpec.getMinLength()).toCharArray();
+ char[] transportPIN = "123456".toCharArray();
+
+ boolean notActive = false;
+ try {
+ signatureCard.verifyPIN(pinSpec, new SMCCTestPINProvider(pin));
+ } catch (NotActivatedException ex) {
+ notActive = true;
+ }
+ assertTrue(notActive);
+
+ signatureCard.activatePIN(pinSpec, new ChangePINProvider(transportPIN, pin));
+ signatureCard.verifyPIN(pinSpec, new SMCCTestPINProvider(pin));
+ }
+ }
+
+
+}
diff --git a/smccSTAL/src/main/java/META-INF/MANIFEST.MF b/smccSTAL/src/main/java/META-INF/MANIFEST.MF
deleted file mode 100644
index 5e949512..00000000
--- a/smccSTAL/src/main/java/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,3 +0,0 @@
-Manifest-Version: 1.0
-Class-Path:
-
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractPINProvider.java b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/AbstractPINProvider.java
index bc52c955..00738188 100644
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractPINProvider.java
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/AbstractPINProvider.java
@@ -15,32 +15,25 @@
* limitations under the License.
*/
-package at.gv.egiz.bku.smccstal;
+package at.gv.egiz.bku.pin.gui;
-import at.gv.egiz.smcc.PINProvider;
+import at.gv.egiz.smcc.pin.gui.PINProvider;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
- *
+ * common super class providing action listener for all PIN GUIs
* @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
*/
-public abstract class AbstractPINProvider implements PINProvider, ActionListener {
+public abstract class AbstractPINProvider implements ActionListener {
protected static final Log log = LogFactory.getLog(AbstractPINProvider.class);
- protected boolean retry = false;
-
protected String action;
-
protected boolean actionPerformed;
-// protected void waitForAction() throws InterruptedException {
-// super.wait();
-// }
-
protected synchronized void waitForAction() throws InterruptedException {
try {
while (!actionPerformed) {
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINGUI.java b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINGUI.java
new file mode 100644
index 00000000..81db0e90
--- /dev/null
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINGUI.java
@@ -0,0 +1,136 @@
+/*
+ * 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.pin.gui;
+
+import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.bku.smccstal.SecureViewer;
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+import at.gv.egiz.smcc.pin.gui.PINGUI;
+import at.gv.egiz.stal.signedinfo.SignedInfoType;
+import java.security.DigestException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * The number of retries is not fixed and there is no way (?) to obtain this value.
+ * A PINProvider should therefore maintain an internal retry counter or flag
+ * to decide whether or not to warn the user (num retries passed in providePIN).
+ *
+ * Therefore PINProvider objects should not be reused.
+ *
+ * (ACOS: reload counter: between 0 and 15, where 15 meens deactivated)
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public class SignPINGUI extends SignPINProvider implements PINGUI {
+
+ protected static final Log log = LogFactory.getLog(SignPINGUI.class);
+
+ private boolean retry = false;
+
+ public SignPINGUI(BKUGUIFacade gui, SecureViewer viewer, SignedInfoType signedInfo) {
+ super(gui, viewer, signedInfo);
+ }
+
+ @Override
+ public void enterPINDirect(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+ if (retry) {
+ gui.showEnterPINDirect(spec, retries);
+ } else {
+ showSignatureData(spec);
+ gui.showEnterPINDirect(spec, -1);
+ retry = true;
+ }
+ }
+
+ @Override
+ public void enterPIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+ if (retry) {
+ gui.showEnterPIN(spec, retries);
+ } else {
+ showSignatureData(spec);
+ gui.showEnterPIN(spec, -1);
+ retry = true;
+ }
+ }
+
+ private void showSignatureData(PINSpec spec)
+ throws CancelledException, InterruptedException {
+
+ gui.showSignatureDataDialog(spec,
+ this, "enterPIN",
+ this, "cancel",
+ this, "secureViewer");
+
+ do {
+ log.trace("[" + Thread.currentThread().getName() + "] wait for action");
+ waitForAction();
+ log.trace("[" + Thread.currentThread().getName() + "] received action " + action);
+
+ if ("secureViewer".equals(action)) {
+ try {
+ viewer.displayDataToBeSigned(signedInfo, this, "signatureData");
+ } 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 ("signatureData".equals(action)) {
+ gui.showSignatureDataDialog(spec,
+ this, "enterPIN",
+ this, "cancel",
+ this, "secureViewer");
+ } else if ("enterPIN".equals(action)) {
+ return;
+ } 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);
+ }
+
+ @Override
+ public void validKeyPressed() {
+ gui.validKeyPressed();
+ }
+
+ @Override
+ public void correctionButtonPressed() {
+ gui.correctionButtonPressed();
+ }
+
+ @Override
+ public void allKeysCleared() {
+ gui.allKeysCleared();
+ }
+
+}
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINProvider.java b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINProvider.java
new file mode 100644
index 00000000..fc1d39af
--- /dev/null
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINProvider.java
@@ -0,0 +1,105 @@
+/*
+ * 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.pin.gui;
+
+import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.bku.smccstal.SecureViewer;
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+import at.gv.egiz.smcc.pin.gui.PINProvider;
+import at.gv.egiz.stal.signedinfo.SignedInfoType;
+import java.security.DigestException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * The number of retries is not fixed and there is no way (?) to obtain this value.
+ * A PINProvider should therefore maintain an internal retry counter or flag
+ * to decide whether or not to warn the user (num retries passed in providePIN).
+ *
+ * Therefore PINProvider objects should not be reused.
+ *
+ * (ACOS: reload counter: between 0 and 15, where 15 meens deactivated)
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public class SignPINProvider extends AbstractPINProvider implements PINProvider {
+
+ protected static final Log log = LogFactory.getLog(SignPINProvider.class);
+
+ protected BKUGUIFacade gui;
+ protected SecureViewer viewer;
+ protected SignedInfoType signedInfo;
+ private boolean retry = false;
+
+ public SignPINProvider(BKUGUIFacade gui, SecureViewer viewer, SignedInfoType signedInfo) {
+ this.gui = gui;
+ 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 {
+ log.trace("[" + Thread.currentThread().getName() + "] wait for action");
+ waitForAction();
+ log.trace("[" + Thread.currentThread().getName() + "] received action " + action);
+
+ 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);
+ }
+}
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/VerifyPINGUI.java b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/VerifyPINGUI.java
new file mode 100644
index 00000000..dc21492e
--- /dev/null
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/VerifyPINGUI.java
@@ -0,0 +1,76 @@
+/*
+ * 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.pin.gui;
+
+import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+import at.gv.egiz.smcc.pin.gui.PINGUI;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * The number of retries is not fixed and there is no way (?) to obtain this value.
+ * A PINProvider should therefore maintain an internal retry counter or flag
+ * to decide whether or not to warn the user (num retries passed in providePIN).
+ *
+ * Therefore PINProvider objects should not be reused.
+ *
+ * (ACOS: reload counter: between 0 and 15, where 15 meens deactivated)
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public class VerifyPINGUI extends VerifyPINProvider implements PINGUI {
+
+ protected static final Log log = LogFactory.getLog(VerifyPINGUI.class);
+
+ private boolean retry = false;
+
+ public VerifyPINGUI(BKUGUIFacade gui) {
+ super(gui);
+ }
+
+ @Override
+ public void enterPINDirect(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+ gui.showEnterPINDirect(spec, (retry) ? retries : -1);
+ retry = true;
+ }
+
+ @Override
+ public void enterPIN(PINSpec spec, int retries) {
+ gui.showEnterPIN(spec, (retry) ? retries : -1);
+ retry = true;
+ }
+
+
+ @Override
+ public void validKeyPressed() {
+ gui.validKeyPressed();
+ }
+
+ @Override
+ public void correctionButtonPressed() {
+ gui.correctionButtonPressed();
+ }
+
+ @Override
+ public void allKeysCleared() {
+ gui.allKeysCleared();
+ }
+
+}
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/VerifyPINProvider.java b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/VerifyPINProvider.java
new file mode 100644
index 00000000..fda1e402
--- /dev/null
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/VerifyPINProvider.java
@@ -0,0 +1,72 @@
+/*
+ * 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.pin.gui;
+
+import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+import at.gv.egiz.smcc.pin.gui.PINProvider;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * The number of retries is not fixed and there is no way (?) to obtain this value.
+ * A PINProvider should therefore maintain an internal retry counter or flag
+ * to decide whether or not to warn the user (num retries passed in providePIN).
+ *
+ * Therefore PINProvider objects should not be reused.
+ *
+ * (ACOS: reload counter: between 0 and 15, where 15 meens deactivated)
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public class VerifyPINProvider extends AbstractPINProvider implements PINProvider {
+
+ protected static final Log log = LogFactory.getLog(VerifyPINProvider.class);
+
+ protected BKUGUIFacade gui;
+ private boolean retry = false;
+
+ public VerifyPINProvider(BKUGUIFacade gui) {
+ this.gui = gui;
+ }
+
+ @Override
+ public char[] providePIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+
+ gui.showVerifyPINDialog(spec, (retry) ? retries : -1,
+ this, "verify",
+ this, "cancel");
+
+ log.trace("[" + Thread.currentThread().getName() + "] wait for action");
+ waitForAction();
+ log.trace("[" + Thread.currentThread().getName() + "] received action " + action);
+
+ if ("cancel".equals(action)) {
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
+ BKUGUIFacade.MESSAGE_WAIT);
+ throw new CancelledException(spec.getLocalizedName() +
+ " entry cancelled");
+ }
+
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
+ BKUGUIFacade.MESSAGE_WAIT);
+ retry = true;
+ return gui.getPin();
+ }
+}
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 32e990c5..b34ab862 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
@@ -17,14 +17,13 @@
package at.gv.egiz.bku.smccstal;
import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.bku.pin.gui.VerifyPINGUI;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.LockedException;
import at.gv.egiz.smcc.NotActivatedException;
-import at.gv.egiz.smcc.PINProvider;
-import at.gv.egiz.smcc.PINSpec;
import at.gv.egiz.smcc.SignatureCard;
import at.gv.egiz.smcc.SignatureCardException;
import at.gv.egiz.stal.ErrorResponse;
@@ -49,8 +48,7 @@ public class InfoBoxReadRequestHandler extends AbstractRequestHandler {
newSTALMessage("Message.RequestCaption", "Message.IdentityLink");
log.debug("Handling identitylink infobox");
byte[] resp = card.getInfobox(infoBox.getInfoboxIdentifier(),
- new PINProviderFactory(card.getReader(), gui)
- .getCardPINProvider(),
+ new VerifyPINGUI(gui),
infoBox.getDomainIdentifier());
if (resp == null) {
log.info("Infobox doesn't contain any data. Assume card is not activated.");
@@ -97,8 +95,7 @@ public class InfoBoxReadRequestHandler extends AbstractRequestHandler {
log.warn("Unknown infobox identifier: "
+ infoBox.getInfoboxIdentifier() + " trying generic request");
byte[] resp = card.getInfobox(infoBox.getInfoboxIdentifier(),
- new PINProviderFactory(card.getReader(), gui)
- .getCardPINProvider(),
+ new VerifyPINGUI(gui),
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
deleted file mode 100644
index e5afe0ae..00000000
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PINProviderFactory.java
+++ /dev/null
@@ -1,327 +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.ccid.CCID;
-import at.gv.egiz.smcc.PINProvider;
-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;
-
-/**
- * don't reuse the instance if the card reader might have changed!
- * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
- */
-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;
- }
-
-
-
-// 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 {
- log.debug("software signature-pin provider");
- return new SoftwareSignaturePinProvider(viewer, signedInfo);
- }
- }
-
- 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 {
- log.debug("[" + Thread.currentThread().getName() + "] wait for action");
- waitForAction();
- log.debug("[" + Thread.currentThread().getName() + "] received action");
-
- 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");
-
- log.debug("[" + Thread.currentThread().getName() + "] wait for action");
- 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) {
- log.debug("[" + Thread.currentThread().getName() + "] wait for action");
- waitForAction();
- log.debug("[" + Thread.currentThread().getName() + "] received action");
-
- 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/SignRequestHandler.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java
index 58d7b305..5b436d16 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
@@ -17,6 +17,7 @@
package at.gv.egiz.bku.smccstal;
import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.bku.pin.gui.SignPINGUI;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -78,8 +79,7 @@ public class SignRequestHandler extends AbstractRequestHandler {
KeyboxName kb = SignatureCard.KeyboxName.getKeyboxName(signReq.getKeyIdentifier());
byte[] resp = card.createSignature(new ByteArrayInputStream(signReq.getSignedInfo()), kb,
- new PINProviderFactory(card.getReader(), gui)
- .getSignaturePINProvider(secureViewer, si.getValue()), signatureMethod);
+ new SignPINGUI(gui, secureViewer, si.getValue()), signatureMethod);
if (resp == null) {
return new ErrorResponse(6001);
}
diff --git a/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java b/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java
index 16d3efa9..bf57b0a6 100644
--- a/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java
+++ b/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java
@@ -16,7 +16,7 @@ import org.junit.Test;
import at.gv.egiz.bku.gui.BKUGUIFacade;
import at.gv.egiz.bku.smccstal.AbstractSMCCSTAL;
import at.gv.egiz.bku.smccstal.SMCCSTALRequestHandler;
-import at.gv.egiz.smcc.ccid.CCID;
+import at.gv.egiz.smcc.pin.gui.PINGUI;
import at.gv.egiz.stal.ErrorResponse;
import at.gv.egiz.stal.InfoboxReadRequest;
import at.gv.egiz.stal.InfoboxReadResponse;
@@ -39,7 +39,7 @@ public class AbstractSMCCSTALTest extends AbstractSMCCSTAL implements
@Override
public byte[] createSignature(InputStream input, KeyboxName keyboxName,
- PINProvider provider, String alg) throws SignatureCardException {
+ PINGUI provider, String alg) throws SignatureCardException {
// TODO Auto-generated method stub
return null;
}
@@ -58,7 +58,7 @@ public class AbstractSMCCSTALTest extends AbstractSMCCSTAL implements
}
@Override
- public byte[] getInfobox(String infobox, PINProvider provider,
+ public byte[] getInfobox(String infobox, PINGUI provider,
String domainId) throws SignatureCardException {
// TODO Auto-generated method stub
return null;
@@ -87,13 +87,6 @@ public class AbstractSMCCSTALTest extends AbstractSMCCSTAL implements
// TODO Auto-generated method stub
}
-
- @Override
- public CCID getReader() {
- // TODO Auto-generated method stub
- return null;
- }
-
};
return false;
}
diff --git a/smccSTALExt/src/main/java/at/gv/egiz/bku/pin/gui/ManagementPINGUI.java b/smccSTALExt/src/main/java/at/gv/egiz/bku/pin/gui/ManagementPINGUI.java
new file mode 100644
index 00000000..26a24609
--- /dev/null
+++ b/smccSTALExt/src/main/java/at/gv/egiz/bku/pin/gui/ManagementPINGUI.java
@@ -0,0 +1,88 @@
+/*
+ * 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.pin.gui;
+
+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.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+import at.gv.egiz.smcc.pin.gui.ModifyPINGUI;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class ManagementPINGUI extends ManagementPINProvider implements ModifyPINGUI {
+
+ protected static final Log log = LogFactory.getLog(ManagementPINGUI.class);
+
+ private boolean retry = false;
+
+ public ManagementPINGUI(PINManagementGUIFacade gui, DIALOG type) {
+ super(gui, type);
+ }
+
+ @Override
+ public void modifyPINDirect(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+ gui.showModifyPINDirect(type, spec, (retry) ? retries : -1);
+ retry = true;
+ }
+
+ @Override
+ public void finishDirect() {
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, BKUGUIFacade.MESSAGE_WAIT);
+ }
+
+ @Override
+ public void enterCurrentPIN(PINSpec spec, int retries) {
+ gui.showEnterCurrentPIN(type, spec, (retry) ? retries : -1);
+ retry = true;
+ }
+
+ @Override
+ public void enterNewPIN(PINSpec spec) {
+ gui.showEnterNewPIN(type, spec);
+ retry = true;
+ }
+
+ @Override
+ public void confirmNewPIN(PINSpec spec) {
+ gui.showConfirmNewPIN(type, spec);
+ retry = true;
+ }
+
+
+ @Override
+ public void validKeyPressed() {
+ gui.validKeyPressed();
+ }
+
+ @Override
+ public void correctionButtonPressed() {
+ gui.correctionButtonPressed();
+ }
+
+ @Override
+ public void allKeysCleared() {
+ gui.allKeysCleared();
+ }
+
+ @Override
+ public void finish() {
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, BKUGUIFacade.MESSAGE_WAIT);
+ }
+}
diff --git a/smccSTALExt/src/main/java/at/gv/egiz/bku/pin/gui/ManagementPINProvider.java b/smccSTALExt/src/main/java/at/gv/egiz/bku/pin/gui/ManagementPINProvider.java
new file mode 100644
index 00000000..8d842d13
--- /dev/null
+++ b/smccSTALExt/src/main/java/at/gv/egiz/bku/pin/gui/ManagementPINProvider.java
@@ -0,0 +1,89 @@
+/*
+ * 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.pin.gui;
+
+import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.bku.gui.PINManagementGUIFacade;
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINSpec;
+import at.gv.egiz.smcc.pin.gui.ModifyPINProvider;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class ManagementPINProvider extends AbstractPINProvider implements ModifyPINProvider {
+
+ protected static final Log log = LogFactory.getLog(ManagementPINProvider.class);
+ protected PINManagementGUIFacade gui;
+ protected PINManagementGUIFacade.DIALOG type;
+ private boolean retry = false;
+
+ public ManagementPINProvider(PINManagementGUIFacade gui, PINManagementGUIFacade.DIALOG type) {
+ this.gui = gui;
+ this.type = type;
+ }
+
+ @Override
+ public char[] provideCurrentPIN(PINSpec spec, int retries)
+ throws CancelledException, InterruptedException {
+
+ gui.showPINDialog(type, spec, (retry) ? retries : -1,
+ this, "change",
+ this, "cancel");
+
+ log.trace("[" + Thread.currentThread().getName() + "] wait for action");
+ waitForAction();
+ log.trace("[" + Thread.currentThread().getName() + "] received action " + action);
+
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
+ BKUGUIFacade.MESSAGE_WAIT);
+
+ if ("cancel".equals(action)) {
+ throw new CancelledException(spec.getLocalizedName() +
+ " entry cancelled");
+ }
+ retry = true;
+ return gui.getOldPin();
+ }
+
+ @Override
+ public char[] provideNewPIN(PINSpec spec)
+ throws CancelledException, InterruptedException {
+
+ char[] pin = gui.getPin();
+ if (pin != null) {
+ // change pin dialog also returns new pin
+ return pin;
+ }
+
+ gui.showPINDialog(type, spec, -1,
+ this, "activate",
+ this, "cancel");
+
+ log.trace("[" + Thread.currentThread().getName() + "] wait for action");
+ waitForAction();
+ log.trace("[" + Thread.currentThread().getName() + "] received action " + action);
+
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
+ BKUGUIFacade.MESSAGE_WAIT);
+
+ if ("cancel".equals(action)) {
+ throw new CancelledException(spec.getLocalizedName() +
+ " entry cancelled");
+ }
+ return gui.getPin();
+ }
+}
diff --git a/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/ManagementPINProviderFactory.java b/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/ManagementPINProviderFactory.java
deleted file mode 100644
index 493733b8..00000000
--- a/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/ManagementPINProviderFactory.java
+++ /dev/null
@@ -1,246 +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.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 class ManagementPINProviderFactory extends PINProviderFactory {
-
- 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)) {
-// 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 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) {
- if (retries == 1) {
- message = BKUGUIFacade.MESSAGE_LAST_RETRY_PINPAD;
- } else {
- message = BKUGUIFacade.MESSAGE_RETRIES_PINPAD;
- }
- title = BKUGUIFacade.TITLE_RETRY;
- params = new Object[]{String.valueOf(retries)};
- } else if (type == PINManagementGUIFacade.DIALOG.VERIFY) {
- title = PINManagementGUIFacade.TITLE_VERIFY_PIN;
- message = BKUGUIFacade.MESSAGE_ENTERPIN_PINPAD;
- params = new Object[]{pinSpec.getLocalizedName(), pinSpec.getLocalizedLength()};
- } else if (type == PINManagementGUIFacade.DIALOG.ACTIVATE) {
- title = PINManagementGUIFacade.TITLE_ACTIVATE_PIN;
- message = PINManagementGUIFacade.MESSAGE_ACTIVATEPIN_PINPAD;
- params = new Object[]{pinSpec.getLocalizedName(), pinSpec.getLocalizedLength()};
- } else if (type == PINManagementGUIFacade.DIALOG.CHANGE) {
- title = PINManagementGUIFacade.TITLE_CHANGE_PIN;
- message = PINManagementGUIFacade.MESSAGE_CHANGEPIN_PINPAD;
- params = new Object[]{pinSpec.getLocalizedName(), pinSpec.getLocalizedLength()};
- } else { //if (type == DIALOG.UNBLOCK) {
- title = PINManagementGUIFacade.TITLE_UNBLOCK_PIN;
- message = PINManagementGUIFacade.MESSAGE_UNBLOCKPIN_PINPAD;
- params = new Object[]{pinSpec.getLocalizedName(), pinSpec.getLocalizedLength()};
- }
- gui.showMessageDialog(title, message, params);
- }
- }
-
-
- 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 {
-
-// 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 {
-
- ((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/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/PINManagementRequestHandler.java b/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/PINManagementRequestHandler.java
index bfeb90b0..0d49afd0 100644
--- a/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/PINManagementRequestHandler.java
+++ b/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/PINManagementRequestHandler.java
@@ -23,9 +23,11 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.bku.gui.PINManagementGUI;
import at.gv.egiz.bku.gui.PINManagementGUIFacade;
import at.gv.egiz.bku.gui.PINManagementGUIFacade.STATUS;
-import at.gv.egiz.bku.smccstal.AbstractRequestHandler;
+import at.gv.egiz.bku.pin.gui.ManagementPINGUI;
+import at.gv.egiz.bku.pin.gui.VerifyPINGUI;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.LockedException;
import at.gv.egiz.smcc.NotActivatedException;
@@ -96,40 +98,15 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {
throw new NullPointerException("no PIN selected for activation/change");
}
- ManagementPINProviderFactory ppfac =
- new ManagementPINProviderFactory(card.getReader(), gui);
-
try {
if ("activate_enterpin".equals(actionCommand)) {
- log.info("activate " + selectedPIN.getLocalizedName());
- ((PINMgmtSignatureCard) card).activatePIN(selectedPIN,
- ppfac.getActivatePINProvider());
- updatePINState(selectedPIN, STATUS.ACTIV);
- gui.showMessageDialog(PINManagementGUIFacade.TITLE_ACTIVATE_SUCCESS,
- PINManagementGUIFacade.MESSAGE_ACTIVATE_SUCCESS,
- new Object[] {selectedPIN.getLocalizedName()},
- BKUGUIFacade.BUTTON_OK, this, "ok");
- waitForAction();
+ activatePIN(selectedPIN);
} else if ("change_enterpin".equals(actionCommand)) {
- log.info("change " + selectedPIN.getLocalizedName());
- ((PINMgmtSignatureCard) card).changePIN(selectedPIN,
- ppfac.getChangePINProvider());
- updatePINState(selectedPIN, STATUS.ACTIV);
- gui.showMessageDialog(PINManagementGUIFacade.TITLE_CHANGE_SUCCESS,
- PINManagementGUIFacade.MESSAGE_CHANGE_SUCCESS,
- new Object[] {selectedPIN.getLocalizedName()},
- BKUGUIFacade.BUTTON_OK, this, "ok");
- waitForAction();
-
+ changePIN(selectedPIN);
} else if ("unblock_enterpuk".equals(actionCommand)) {
- log.info("unblock " + selectedPIN.getLocalizedName());
- ((PINMgmtSignatureCard) card).unblockPIN(selectedPIN,
- ppfac.getUnblockPINProvider());
+ unblockPIN(selectedPIN);
} else if ("verify_enterpin".equals(actionCommand)) {
- log.info("verify " + selectedPIN.getLocalizedName());
- ((PINMgmtSignatureCard) card).verifyPIN(selectedPIN,
- ppfac.getVerifyPINProvider());
- updatePINState(selectedPIN, STATUS.ACTIV);
+ verifyPIN(selectedPIN);
}
} catch (CancelledException ex) {
log.trace("cancelled");
@@ -154,29 +131,17 @@ 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();
+
+ // inner loop for pinConfirmation and pinFormat ex
+// } catch (PINConfirmationException ex) {
+// } catch (PINFormatException ex) {
+
} 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
@@ -206,6 +171,157 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {
}
}
+ private void activatePIN(PINSpec selectedPIN)
+ throws InterruptedException, SignatureCardException, GetPINStatusException {
+
+ log.info("activate " + selectedPIN.getLocalizedName());
+ ManagementPINGUI pinGUI = new ManagementPINGUI((PINManagementGUI) gui,
+ PINManagementGUIFacade.DIALOG.ACTIVATE);
+
+ boolean reentry;
+ do {
+ try {
+ reentry = false;
+ ((PINMgmtSignatureCard) card).activatePIN(selectedPIN, pinGUI);
+ } catch (PINConfirmationException ex) {
+ reentry = true;
+ log.error("confirmation pin does not match new " + selectedPIN.getLocalizedName());
+ gui.showErrorDialog(PINManagementGUIFacade.ERR_PIN_CONFIRMATION,
+ new Object[] {selectedPIN.getLocalizedName()},
+ this, null);
+ waitForAction();
+ } catch (PINFormatException ex) {
+ reentry = true;
+ log.error("wrong format of new " + selectedPIN.getLocalizedName());
+ 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();
+ }
+ } while (reentry);
+
+ updatePINState(selectedPIN, STATUS.ACTIV);
+ gui.showMessageDialog(PINManagementGUIFacade.TITLE_ACTIVATE_SUCCESS,
+ PINManagementGUIFacade.MESSAGE_ACTIVATE_SUCCESS,
+ new Object[]{selectedPIN.getLocalizedName()},
+ BKUGUIFacade.BUTTON_OK, this, "ok");
+ waitForAction();
+ }
+
+ private void verifyPIN(PINSpec selectedPIN)
+ throws InterruptedException, SignatureCardException, GetPINStatusException {
+
+ log.info("verify " + selectedPIN.getLocalizedName());
+ VerifyPINGUI pinGUI = new VerifyPINGUI(gui);
+
+ boolean reentry;
+ do {
+ try {
+ reentry = false;
+ ((PINMgmtSignatureCard) card).verifyPIN(selectedPIN, pinGUI);
+ } catch (PINFormatException ex) {
+ reentry = true;
+ log.error("wrong format of new " + selectedPIN.getLocalizedName());
+ 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();
+ }
+ } while (reentry);
+
+ updatePINState(selectedPIN, STATUS.ACTIV);
+ }
+
+ private void changePIN(PINSpec selectedPIN)
+ throws SignatureCardException, GetPINStatusException, InterruptedException {
+
+ log.info("change " + selectedPIN.getLocalizedName());
+ ManagementPINGUI pinGUI = new ManagementPINGUI((PINManagementGUI) gui,
+ PINManagementGUIFacade.DIALOG.CHANGE);
+
+ boolean reentry;
+ do {
+ try {
+ reentry = false;
+ ((PINMgmtSignatureCard) card).changePIN(selectedPIN, pinGUI);
+ } catch (PINConfirmationException ex) {
+ reentry = true;
+ log.error("confirmation pin does not match new " + selectedPIN.getLocalizedName());
+ gui.showErrorDialog(PINManagementGUIFacade.ERR_PIN_CONFIRMATION,
+ new Object[] {selectedPIN.getLocalizedName()},
+ this, null);
+ waitForAction();
+ } catch (PINFormatException ex) {
+ reentry = true;
+ log.error("wrong format of new " + selectedPIN.getLocalizedName());
+ 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();
+ }
+ } while (reentry);
+
+ updatePINState(selectedPIN, STATUS.ACTIV);
+ gui.showMessageDialog(PINManagementGUIFacade.TITLE_CHANGE_SUCCESS,
+ PINManagementGUIFacade.MESSAGE_CHANGE_SUCCESS,
+ new Object[]{selectedPIN.getLocalizedName()},
+ BKUGUIFacade.BUTTON_OK, this, "ok");
+ waitForAction();
+ }
+
+ private void unblockPIN(PINSpec selectedPIN)
+ throws SignatureCardException, GetPINStatusException, InterruptedException {
+
+ log.info("unblock " + selectedPIN.getLocalizedName());
+ ManagementPINGUI pinGUI = new ManagementPINGUI((PINManagementGUI) gui,
+ PINManagementGUIFacade.DIALOG.UNBLOCK);
+
+ boolean reentry;
+ do {
+ try {
+ reentry = false;
+ ((PINMgmtSignatureCard) card).unblockPIN(selectedPIN, pinGUI);
+ } catch (PINConfirmationException ex) {
+ reentry = true;
+ log.error("confirmation pin does not match new " + selectedPIN.getLocalizedName());
+ gui.showErrorDialog(PINManagementGUIFacade.ERR_PIN_CONFIRMATION,
+ new Object[] {selectedPIN.getLocalizedName()},
+ this, null);
+ waitForAction();
+ } catch (PINFormatException ex) {
+ reentry = true;
+ log.error("wrong format of new " + selectedPIN.getLocalizedName());
+ 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();
+ }
+ } while (reentry);
+
+ updatePINState(selectedPIN, STATUS.ACTIV);
+ gui.showMessageDialog(PINManagementGUIFacade.TITLE_UNBLOCK_SUCCESS,
+ PINManagementGUIFacade.MESSAGE_UNBLOCK_SUCCESS,
+ new Object[]{selectedPIN.getLocalizedName()},
+ BKUGUIFacade.BUTTON_OK, this, "ok");
+ waitForAction();
+ }
+
@Override
public boolean requireCard() {
return true;