summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortkellner <tkellner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2012-07-10 12:17:07 +0000
committertkellner <tkellner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2012-07-10 12:17:07 +0000
commite126bd7af77b30710d9eec39cd08d1d63d605cec (patch)
tree9582f75bbe347fc648db0a72c2c0a9988a662332
parent10511e7cd7cc64b5d2ff115057ad31b84127f333 (diff)
downloadmocca-e126bd7af77b30710d9eec39cd08d1d63d605cec.tar.gz
mocca-e126bd7af77b30710d9eec39cd08d1d63d605cec.tar.bz2
mocca-e126bd7af77b30710d9eec39cd08d1d63d605cec.zip
Cypriotic EID implementation working
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@1094 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
-rw-r--r--BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUI.java429
-rw-r--r--BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java7
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/CypriotEID.java478
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/LogCardChannel.java1
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/pin/gui/ModifyPINProvider.java2
-rw-r--r--smcc/src/main/resources/at/gv/egiz/smcc/CypriotEID.properties5
-rw-r--r--smccSTALExt/src/main/java/at/gv/egiz/bku/pin/gui/ManagementPINProvider.java23
7 files changed, 766 insertions, 179 deletions
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 32fe207c..e3e0ec83 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
@@ -886,7 +886,436 @@ public class PINManagementGUI extends CardMgmtGUI implements
}
});
}
+
+ @Override
+ public void showPUKDialog(DIALOG type, PinInfo pinSpec, PinInfo pukSpec, int retries,
+ ActionListener okListener, String okCommand,
+ ActionListener cancelListener, String cancelCommand) {
+ showPUKDialog(type, pinSpec, pukSpec, retries, false, okListener, okCommand,
+ cancelListener, cancelCommand);
+ }
+
+ private void showPUKDialog(final DIALOG type, final PinInfo pinSpec, final PinInfo pukSpec,
+ final int retries, final boolean pinpad,
+ final ActionListener okListener, final String okCommand,
+ final ActionListener cancelListener, final String cancelCommand) {
+
+ log.debug("Scheduling puk dialog.");
+
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+
+ String HELP_TOPIC, TITLE, MESSAGE_MGMT, MESSAGE_MGMT_PARAM;
+ HELP_TOPIC = HELP_PINMGMT;
+
+ if (retries < 0) {
+ if (type == DIALOG.CHANGE) {
+ log.debug("Show change pin dialog.");
+ TITLE = TITLE_CHANGE_PIN;
+ MESSAGE_MGMT = MESSAGE_UNBLOCK_PIN;
+ } else if(type == DIALOG.UNBLOCK) {
+ log.debug("Show unblock pin dialog.");
+ TITLE = TITLE_UNBLOCK_PIN;
+ MESSAGE_MGMT = MESSAGE_UNBLOCK_PIN;
+ } else {
+ log.info("PUK Dialog may only be used for change and unblocking!");
+ return;
+ }
+ if (shortText) {
+ MESSAGE_MGMT_PARAM = "PIN";
+ } else {
+ MESSAGE_MGMT_PARAM = pinSpec.getLocalizedName();
+ }
+ } else {
+ log.debug("Show retry pin dialog.");
+ TITLE = TITLE_RETRY;
+ MESSAGE_MGMT = (retries < 2) ? MESSAGE_LAST_RETRY
+ : MESSAGE_RETRIES;
+ MESSAGE_MGMT_PARAM = String.valueOf(retries);
+ }
+
+ mainPanel.removeAll();
+ buttonPanel.removeAll();
+
+ helpListener.setHelpTopic(HELP_TOPIC);
+
+ mgmtLabel = new JLabel();
+ if (retries < 0) {
+ mgmtLabel.setFont(mgmtLabel.getFont().deriveFont(
+ mgmtLabel.getFont().getStyle() & ~Font.BOLD));
+ } else {
+ mgmtLabel.setFont(mgmtLabel.getFont().deriveFont(
+ mgmtLabel.getFont().getStyle() | Font.BOLD));
+ mgmtLabel.setForeground(ERROR_COLOR);
+ helpListener.setHelpTopic(HELP_RETRY);
+ }
+
+ if (renderHeaderPanel) {
+ titleLabel.setText(getMessage(TITLE));
+ String mgmtPattern = getMessage(MESSAGE_MGMT);
+ mgmtLabel.setText(MessageFormat.format(mgmtPattern,
+ MESSAGE_MGMT_PARAM));
+ } else {
+ mgmtLabel.setText(getMessage(TITLE));
+ }
+
+ // //////////////////////////////////////////////////////////////
+ // COMMON LAYOUT SECTION
+ // //////////////////////////////////////////////////////////////
+
+ GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
+ mainPanel.setLayout(mainPanelLayout);
+
+ GroupLayout.SequentialGroup infoHorizontal = mainPanelLayout
+ .createSequentialGroup().addComponent(mgmtLabel);
+ GroupLayout.ParallelGroup infoVertical = mainPanelLayout
+ .createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addComponent(mgmtLabel);
+
+ if (!renderHeaderPanel) {
+ infoHorizontal.addPreferredGap(
+ LayoutStyle.ComponentPlacement.UNRELATED, 0,
+ Short.MAX_VALUE)
+ .addComponent(switchFocusDummyLabel).addComponent(
+ helpLabel);
+ infoVertical.addComponent(switchFocusDummyLabel)
+ .addComponent(helpLabel);
+ }
+
+ GroupLayout.ParallelGroup pinHorizontal;
+ GroupLayout.SequentialGroup pinVertical;
+/* Currently not supporting pinpads!!
+ if (pinpad) {
+ pinpadLabel = new JLabel();
+ pinpadLabel.setFont(mgmtLabel.getFont().deriveFont(
+ mgmtLabel.getFont().getStyle() & ~Font.BOLD));
+ String pinpadPattern = getMessage(MESSAGE_ENTERPIN_PINPAD);
+ pinpadLabel.setText(MessageFormat.format(pinpadPattern,
+ new Object[] { pinSpec.getLocalizedName(),
+ pinSpec.getLocalizedLength() }));
+
+ pinHorizontal = mainPanelLayout.createParallelGroup(
+ GroupLayout.Alignment.LEADING).addComponent(
+ pinpadLabel);
+ pinVertical = mainPanelLayout.createSequentialGroup()
+ .addComponent(pinpadLabel);
+ } else {
+*/
+ okButton = new JButton();
+ okButton.setFont(okButton.getFont().deriveFont(
+ okButton.getFont().getStyle() & ~Font.BOLD));
+ okButton.setText(getMessage(BUTTON_OK));
+ okButton.setEnabled(pinSpec.getMinLength() <= 0);
+ okButton.setActionCommand(okCommand);
+ okButton.addActionListener(okListener);
+
+ pinLabel = new JLabel();
+ pinLabel.setFont(pinLabel.getFont().deriveFont(
+ pinLabel.getFont().getStyle() & ~Font.BOLD));
+ String pinLabelPattern = getMessage(LABEL_NEW_PIN);
+
+ pinLabel.setText(MessageFormat.format(pinLabelPattern,
+ new Object[] { pinSpec.getLocalizedName() }));
+
+ repeatPinField = new JPasswordField();
+ pinField = new JPasswordField();
+ pinField.setText("");
+ pinField.setActionCommand(okCommand);
+ pinField.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (pinField.getPassword().length >= pinSpec
+ .getMinLength()) {
+ if (type == DIALOG.VERIFY) {
+ okListener.actionPerformed(e);
+ } else {
+ repeatPinField.requestFocusInWindow();
+ }
+ }
+ }
+ });
+
+ repeatPinLabel = new JLabel();
+ repeatPinLabel.setFont(pinLabel.getFont());
+ String repeatPinLabelPattern = getMessage(LABEL_REPEAT_PIN);
+ repeatPinLabel.setText(MessageFormat.format(
+ repeatPinLabelPattern, new Object[] { pinSpec
+ .getLocalizedName() }));
+
+ repeatPinField.setText("");
+ repeatPinField.setActionCommand(okCommand);
+ repeatPinField.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (okButton.isEnabled()) {
+ okListener.actionPerformed(e);
+ }
+ }
+ });
+
+ oldPinLabel = new JLabel();
+ oldPinLabel.setFont(oldPinLabel.getFont()
+ .deriveFont(
+ oldPinLabel.getFont().getStyle()
+ & ~java.awt.Font.BOLD));
+ String oldPinLabelPattern = getMessage(LABEL_PUK);
+ oldPinLabel.setText(MessageFormat.format(
+ oldPinLabelPattern, new Object[] { pinSpec
+ .getLocalizedName() }));
+
+ oldPinField = new JPasswordField();
+ oldPinField.setText("");
+ oldPinField.setActionCommand(okCommand);
+ oldPinField.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (oldPinField.getPassword().length >= pinSpec
+ .getMinLength()) {
+ pinField.requestFocusInWindow();
+ }
+ }
+ });
+
+ ExtendedPinDocument oldPinDocument = new ExtendedPinDocument(
+ pukSpec.getMinLength(), pukSpec
+ .getMaxLength(), pukSpec
+ .getRegexpPattern(), okButton);
+ ComparePinDocument newPinDocument = new ComparePinDocument(
+ pinSpec.getRecMinLength(), pinSpec
+ .getRecMaxLength(), pinSpec
+ .getRegexpPattern(), okButton);
+ ComparePinDocument confirmPinDocument = new ComparePinDocument(
+ pinSpec.getRecMinLength(), pinSpec
+ .getRecMaxLength(), pinSpec
+ .getRegexpPattern(), 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);
+
+ primaryFocusHolder = oldPinField;
+
+
+
+
+ pinsizeLabel = new JLabel();
+ pinsizeLabel.setFont(pinsizeLabel.getFont().deriveFont(
+ pinsizeLabel.getFont().getStyle() & ~Font.BOLD,
+ pinsizeLabel.getFont().getSize() - 2));
+ String pinsizePattern = getMessage(LABEL_PINSIZE);
+ pinsizeLabel.setText(MessageFormat.format(pinsizePattern,
+ pinSpec.getLocalizedLength()));
+
+ // //////////////////////////////////////////////////////////////
+ // NON-PINPAD SPECIFIC LAYOUT SECTION
+ // //////////////////////////////////////////////////////////////
+
+ pinHorizontal = mainPanelLayout
+ .createParallelGroup(GroupLayout.Alignment.LEADING);
+ pinVertical = mainPanelLayout.createSequentialGroup();
+
+ if (type == DIALOG.CHANGE || type == DIALOG.UNBLOCK) {
+ pinHorizontal
+ .addGroup(mainPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ mainPanelLayout
+ .createParallelGroup(
+ GroupLayout.Alignment.LEADING)
+ .addComponent(
+ oldPinLabel,
+ GroupLayout.PREFERRED_SIZE,
+ GroupLayout.DEFAULT_SIZE,
+ GroupLayout.PREFERRED_SIZE)
+ .addComponent(
+ pinLabel,
+ GroupLayout.PREFERRED_SIZE,
+ GroupLayout.DEFAULT_SIZE,
+ GroupLayout.PREFERRED_SIZE)
+ .addComponent(
+ repeatPinLabel,
+ GroupLayout.PREFERRED_SIZE,
+ GroupLayout.DEFAULT_SIZE,
+ GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ mainPanelLayout
+ .createParallelGroup(
+ GroupLayout.Alignment.LEADING)
+ .addComponent(
+ oldPinField,
+ GroupLayout.PREFERRED_SIZE,
+ GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ pinField,
+ GroupLayout.PREFERRED_SIZE,
+ GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ repeatPinField,
+ GroupLayout.PREFERRED_SIZE,
+ GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)));
+//>>>>>>> .r684
+
+ pinVertical.addGroup(
+ mainPanelLayout.createParallelGroup(
+ GroupLayout.Alignment.BASELINE)
+ .addComponent(oldPinLabel)
+ .addComponent(oldPinField))
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ mainPanelLayout.createParallelGroup(
+ GroupLayout.Alignment.BASELINE)
+ .addComponent(pinLabel)
+ .addComponent(pinField))
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ mainPanelLayout.createParallelGroup(
+ GroupLayout.Alignment.BASELINE)
+ .addComponent(repeatPinLabel)
+ .addComponent(repeatPinField))
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED);
+ } else if (type == DIALOG.ACTIVATE) {
+ pinHorizontal
+ .addGroup(mainPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ mainPanelLayout
+ .createParallelGroup(
+ GroupLayout.Alignment.LEADING)
+ .addComponent(
+ pinLabel,
+ GroupLayout.PREFERRED_SIZE,
+ GroupLayout.DEFAULT_SIZE,
+ GroupLayout.PREFERRED_SIZE)
+ .addComponent(
+ repeatPinLabel,
+ GroupLayout.PREFERRED_SIZE,
+ GroupLayout.DEFAULT_SIZE,
+ GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ mainPanelLayout
+ .createParallelGroup(
+ GroupLayout.Alignment.LEADING)
+ .addComponent(
+ pinField,
+ GroupLayout.PREFERRED_SIZE,
+ GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ repeatPinField,
+ GroupLayout.PREFERRED_SIZE,
+ GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)));
+
+ pinVertical.addGroup(
+ mainPanelLayout.createParallelGroup(
+ GroupLayout.Alignment.BASELINE)
+ .addComponent(pinLabel).addComponent(
+ pinField)).addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ mainPanelLayout.createParallelGroup(
+ GroupLayout.Alignment.BASELINE)
+ .addComponent(repeatPinLabel)
+ .addComponent(repeatPinField))
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED);
+ } else { // VERIFY
+ pinHorizontal.addGroup(mainPanelLayout
+ .createSequentialGroup().addComponent(pinLabel,
+ GroupLayout.PREFERRED_SIZE,
+ GroupLayout.DEFAULT_SIZE,
+ GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pinField,
+ GroupLayout.PREFERRED_SIZE,
+ GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE));
+
+ pinVertical.addGroup(
+ mainPanelLayout.createParallelGroup(
+ GroupLayout.Alignment.BASELINE)
+ .addComponent(pinLabel).addComponent(
+ pinField)).addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED);
+ }
+ pinHorizontal.addGroup(mainPanelLayout
+ .createSequentialGroup().addPreferredGap(
+ LayoutStyle.ComponentPlacement.UNRELATED,
+ 0, Short.MAX_VALUE).addComponent(
+ pinsizeLabel, GroupLayout.PREFERRED_SIZE,
+ GroupLayout.DEFAULT_SIZE,
+ GroupLayout.PREFERRED_SIZE));
+ pinVertical.addComponent(pinsizeLabel);
+
+ 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);
+
+
+ updateMethodToRunAtResize("at.gv.egiz.bku.gui.PINManagementGUI", "renderPINDialogButtonPanel");
+
+ renderPINDialogButtonPanel();
+
+ if (oldPinField != null) {
+ oldPinField.requestFocusInWindow();
+ } else {
+ pinField.requestFocusInWindow();
+ }
+
+ //} // END NON-PINPAD SECTION
+
+ 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();
+
+ if (windowCloseAdapter != null) {
+ windowCloseAdapter.registerListener(cancelListener, cancelCommand);
+ }
+
+ resize();
+
+ }
+ });
+ }
+
+
public void renderPINDialogButtonPanel() {
GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel);
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 f1bf57ab..6f429456 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
@@ -117,6 +117,13 @@ public interface PINManagementGUIFacade extends BKUGUIFacade {
ActionListener cancelListener, String cancelCmd);
/**
+ * "software" puk and pin-entry dialog (change, unblock)
+ */
+ public void showPUKDialog(DIALOG type, PinInfo pinSpec, PinInfo pukSpec, int retries,
+ ActionListener okListener, String okCmd,
+ ActionListener cancelListener, String cancelCmd);
+
+ /**
* <b>direct</b> pinpad pin-entry dialog
*/
public void showModifyPINDirect(DIALOG type, PinInfo pinSpec, int retries);
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/CypriotEID.java b/smcc/src/main/java/at/gv/egiz/smcc/CypriotEID.java
index 35556049..c1695278 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/CypriotEID.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/CypriotEID.java
@@ -26,6 +26,7 @@ package at.gv.egiz.smcc;
import iaik.me.asn1.*;
import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -34,6 +35,7 @@ import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.util.Iterator;
import javax.smartcardio.Card;
import javax.smartcardio.CardChannel;
@@ -51,6 +53,8 @@ import at.gv.egiz.smcc.pin.gui.ModifyPINGUI;
import at.gv.egiz.smcc.pin.gui.PINGUI;
import at.gv.egiz.smcc.util.ISO7816Utils;
import at.gv.egiz.smcc.util.SMCCHelper;
+import at.gv.egiz.smcc.util.TLV;
+import at.gv.egiz.smcc.util.TLVSequence;
import at.gv.egiz.smcc.util.TransparentFileInputStream;
public class CypriotEID extends AbstractSignatureCard implements
@@ -63,7 +67,7 @@ public class CypriotEID extends AbstractSignatureCard implements
public static final byte KID_PIN_SIG = (byte) 0x01;
public static final byte[] CD_ID = new byte[] { (byte) 0x70, (byte) 0x05 };
-
+
public static final byte[] MF_ID = new byte[] { (byte) 0x3f, (byte) 0x00 };
public static final byte[] ADF_AWP_ID = new byte[] { (byte) 0xad,
@@ -79,32 +83,32 @@ public class CypriotEID extends AbstractSignatureCard implements
ObjectDirectory od;
protected byte[] cert_id;
-
+
@Override
public void init(Card card, CardTerminal cardTerminal) {
super.init(card, cardTerminal);
log.info("Cypriot EID found");
- pinPinInfo = new PinInfo(4, 8, "[0-9]", "at/gv/egiz/smcc/CypriotEID",
+ pinPinInfo = new PinInfo(4, 64, "[0-9]", "at/gv/egiz/smcc/CypriotEID",
"sig.pin", KID_PIN_SIG, AID_SIG, 3);
- //pinPinInfo.setActive(3);
-
- pukPinInfo = new PinInfo(4, 8, "[0-9]", "at/gv/egiz/smcc/CypriotEID",
+ // pinPinInfo.setActive(3);
+
+ pukPinInfo = new PinInfo(4, 64, "[0-9]", "at/gv/egiz/smcc/CypriotEID",
"sig.puk", KID_PUK_SIG, AID_SIG, 3);
-
+
try {
this.exec_readcd(getCardChannel());
} catch (CardException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ log.warn("Failed to read the certificate ID", e);
+ cert_id = null;
} catch (SignatureCardException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ log.warn("Failed to read the certificate ID", e);
+ cert_id = null;
} catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ log.warn("Failed to read the certificate ID", e);
+ cert_id = null;
}
}
@@ -116,14 +120,14 @@ public class CypriotEID extends AbstractSignatureCard implements
try {
return exec_readcert(channel);
} catch (CardException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ log.info("Failed to get the certificate.", e);
+ throw new SignatureCardException("Failed to get the certificate.",
+ e);
} catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ log.info("Failed to get the certificate.", e);
+ throw new SignatureCardException("Failed to get the certificate.",
+ e);
}
-
- return null;
}
@Override
@@ -137,58 +141,92 @@ public class CypriotEID extends AbstractSignatureCard implements
public byte[] createSignature(InputStream input, KeyboxName keyboxName,
PINGUI pinGUI, String alg) throws SignatureCardException,
InterruptedException, IOException {
-
+
byte AlgID = 0;
-
- MessageDigest md;
- try {
- if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)
- && (alg == null || "http://www.w3.org/2000/09/xmldsig#rsa-sha1".equals(alg))) {
- AlgID = (byte) 0x12; // SHA-1 with padding according to PKCS#1 block type 01
- md = MessageDigest.getInstance("SHA-1");
- } else if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)
- && "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256".equals(alg)) {
- AlgID = (byte) 0x41; // SHA-256 with padding according to PKCS#1
- md = MessageDigest.getInstance("SHA256");
- } else {
- throw new SignatureCardException("Card does not support signature algorithm " + alg + ".");
- }
- } catch (NoSuchAlgorithmException e) {
- log.error("Failed to get MessageDigest.", e);
- throw new SignatureCardException(e);
- }
-
- byte[] digest = new byte[md.getDigestLength()];
- for (int l; (l = input.read(digest)) != -1;) {
- md.update(digest, 0, l);
- }
- digest = md.digest();
-
- try
- {
- CardChannel channel = getCardChannel();
-
- // SELECT application
- exec_selectADF(channel);
-
- // MANAGE SECURITY ENVIRONMENT : SET DST
- exec_MSE(channel, AlgID);
- // VERIFY
- verifyPINLoop(channel, pinPinInfo, pinGUI);
-
- // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATRE
- return exec_sign(channel, digest);
- }
- catch (Exception e) {
- e.printStackTrace();
- return null;
+
+ MessageDigest md;
+ try {
+ if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)
+ && (alg == null || "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
+ .equals(alg))) {
+ AlgID = (byte) 0x12; // SHA-1 with padding according to PKCS#1
+ // block type 01
+ md = MessageDigest.getInstance("SHA-1");
+ } else if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)
+ && "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
+ .equals(alg)) {
+ AlgID = (byte) 0x41; // SHA-256 with padding according to PKCS#1
+ md = MessageDigest.getInstance("SHA256");
+ } else {
+ throw new SignatureCardException(
+ "Card does not support signature algorithm " + alg
+ + ".");
+ }
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to get MessageDigest.", e);
+ throw new SignatureCardException(e);
+ }
+
+ byte[] digest = new byte[md.getDigestLength()];
+ for (int l; (l = input.read(digest)) != -1;) {
+ md.update(digest, 0, l);
}
+ digest = md.digest();
+
+ CardChannel channel = getCardChannel();
+
+ try {
+ try {
+ // SELECT application
+ exec_selectADF(channel);
+
+ // MANAGE SECURITY ENVIRONMENT : SET DST
+ exec_MSE(channel, AlgID);
+
+ // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATRE
+ return exec_sign(channel, digest);
+ } catch (SecurityStatusNotSatisfiedException e) {
+ // NEED to provide PIN code ...
+
+ // SELECT application
+ exec_selectADF(channel);
+
+ // MANAGE SECURITY ENVIRONMENT : SET DST
+ exec_MSE(channel, AlgID);
+
+ // VERIFY
+ verifyPINLoop(channel, pinPinInfo, pinGUI);
+
+ // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATRE
+ return exec_sign(channel, digest);
+ }
+ } catch (CardException e) {
+ log.info("Failed to create digital signature", e);
+ throw new SignatureCardException("Failed to create digital signature", e);
+ }
+
}
@Override
public PinInfo[] getPinInfos() throws SignatureCardException {
- // TODO Auto-generated method stub
- return new PinInfo[] { pinPinInfo };
+ PinInfo[] pinInfos = new PinInfo[] { pinPinInfo, pukPinInfo };
+
+ CardChannel channel = getCardChannel();
+ for (PinInfo pinInfo : pinInfos) {
+ if (pinInfo.getState() == PinInfo.STATE.UNKNOWN ) {
+ try {
+ log.debug("Query pin status for {}.", pinInfo.getLocalizedName());
+ testPIN(channel, pinInfo);
+ } catch (Exception e) {
+ log.trace("Failed to execute command.", e);
+ // status already set by verifyPIN
+ }
+ } else if (log.isTraceEnabled()) {
+ log.trace("assume pin status {} to be up to date", pinInfo.getState());
+ }
+ }
+
+ return pinInfos;
}
@Override
@@ -209,12 +247,23 @@ public class CypriotEID extends AbstractSignatureCard implements
}
@Override
+ public String toString() {
+ return ("Oberthur Thechnologies ID-ONE Token SLIM");
+ }
+
+ @Override
public void changePIN(PinInfo pinInfo, ModifyPINGUI changePINGUI)
throws LockedException, NotActivatedException, CancelledException,
PINFormatException, SignatureCardException, InterruptedException {
+
CardChannel channel = getCardChannel();
- exec_unblockPIN(channel, changePINGUI);
+ try {
+ unblockPINLoop(channel, changePINGUI, pinInfo);
+ } catch (CardException e) {
+ log.info("Failed to change PIN.", e);
+ throw new SignatureCardException("Failed to change PIN.", e);
+ }
}
@Override
@@ -222,7 +271,8 @@ public class CypriotEID extends AbstractSignatureCard implements
throws CancelledException, SignatureCardException,
InterruptedException {
log.error("ACTIVATE PIN not supported by Cypriotic EID");
- throw new SignatureCardException("PIN activation not supported by this card.");
+ throw new SignatureCardException(
+ "PIN activation not supported by this card.");
}
@Override
@@ -231,7 +281,12 @@ public class CypriotEID extends AbstractSignatureCard implements
InterruptedException {
CardChannel channel = getCardChannel();
- exec_unblockPIN(channel, pukGUI);
+ try {
+ unblockPINLoop(channel, pukGUI, pinInfo);
+ } catch (CardException e) {
+ log.info("Failed to unblock PIN.", e);
+ throw new SignatureCardException("Failed to unblock PIN.", e);
+ }
}
// //////////////////////////////////////////////////////////////////////
@@ -248,16 +303,28 @@ public class CypriotEID extends AbstractSignatureCard implements
} while (retries > 0);
}
+ protected void unblockPINLoop(CardChannel channel,
+ ModifyPINGUI provider, PinInfo pin) throws InterruptedException, CardException, SignatureCardException{
+
+ int retries = -1;
+ do {
+ retries = exec_unblockPIN(channel, provider, pin);
+ } while (retries > 0);
+ }
+
+ /*
+ * Verify PIN/PUK entry
+ */
protected int verifyPIN(CardChannel channel, PinInfo pinInfo,
PINGUI provider, int retries) throws InterruptedException,
CardException, SignatureCardException {
char[] pin = provider.providePIN(pinInfo, pinInfo.retries);
-
+
byte[] ascii_pin = encodePIN(pin);
exec_selectADF(channel);
- ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0x20, 0x00,
+ ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0x20, 0x00,
pinInfo.getKID(), ascii_pin));
if (resp.getSW() == 0x9000) {
@@ -284,99 +351,149 @@ public class CypriotEID extends AbstractSignatureCard implements
}
}
+
+ protected int testPIN(CardChannel channel, PinInfo pinInfo) throws InterruptedException,
+ CardException, SignatureCardException {
+
+ exec_selectADF(channel);
+
+ ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0x20, 0x00,
+ pinInfo.getKID()));
+
+ if (resp.getSW() == 0x9000) {
+ pinInfo.setActive(pinInfo.maxRetries);
+ return -1;
+ }
+ if (resp.getSW() >> 4 == 0x63c) {
+ pinInfo.setActive(0x0f & resp.getSW());
+ return 0x0f & resp.getSW();
+ }
+
+ switch (resp.getSW()) {
+ case 0x6983:
+ // authentication method blocked
+ pinInfo.setBlocked();
+ throw new LockedException();
+
+ default:
+ String msg = "VERIFY failed. SW="
+ + Integer.toHexString(resp.getSW());
+ log.info(msg);
+ pinInfo.setUnknown();
+ throw new SignatureCardException(msg);
+ }
+
+ }
- private byte[] encodePIN(char[] pin)
- {
- return Charset.forName("ASCII").encode(
- CharBuffer.wrap(pin)).array();
+ private byte[] encodePIN(char[] pin) {
+ return Charset.forName("ASCII").encode(CharBuffer.wrap(pin)).array();
}
-
- protected void exec_unblockPIN(CardChannel channel, ModifyPINGUI changePINGUI) throws CancelledException, InterruptedException
- {
- char[] PUK = changePINGUI.provideCurrentPIN(pukPinInfo, pukPinInfo.retries);
- char[] newPIN = changePINGUI.provideNewPIN(pinPinInfo);
+
+ /*
+ * Unblock PIN with PUK code
+ */
+ protected int exec_unblockPIN(CardChannel channel, ModifyPINGUI changePINGUI, PinInfo pin)
+ throws InterruptedException, CardException, SignatureCardException {
- byte[] ascii_puk = encodePIN(PUK);
- byte[] ascii_pin = encodePIN(newPIN);
+ char[] PUK = changePINGUI.providePUK(pin, pukPinInfo,
+ pukPinInfo.retries);
- try {
- log.debug("PUK: " + new String(PUK) + "(" + getHexString(ascii_puk) + ") NEW PIN: " +
- new String(newPIN) + "(" + getHexString(ascii_pin) + ")");
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
+ char[] newPIN = changePINGUI.provideNewPIN(pin);
- // TODO: INPUT checking PIN SIZES etc.
- /*
- try {
- exec_selectADF(channel);
+ byte[] ascii_puk = encodePIN(PUK);
- ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0x20, 0x00,
- pukPinInfo.getKID(), ascii_puk));
-
- if (resp.getSW() == 0x9000) {
- pukPinInfo.setActive(pukPinInfo.maxRetries);
- }
- else
- {
- log.debug("WRONG PUK CODE!! SW=" + resp.getSW());
- return;
- }
-
- resp = channel.transmit(new CommandAPDU(0x00, 0x2C, 0x02,
- pinPinInfo.getKID(), ascii_pin));
-
- if (resp.getSW() == 0x9000) {
- pinPinInfo.setActive(pinPinInfo.maxRetries);
- }
- else
- {
- log.debug("FAILED TO SET PIN! SW=" + resp.getSW());
- }
-
- } catch (CardException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (SignatureCardException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ byte[] ascii_pin = encodePIN(newPIN);
+
+ exec_selectADF(channel);
+
+ ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0x20, 0x00,
+ pukPinInfo.getKID(), ascii_puk));
+
+ if (resp.getSW() == 0x9000) {
+ pukPinInfo.setActive(pukPinInfo.maxRetries);
+ } else if (resp.getSW() >> 4 == 0x63c) {
+ pukPinInfo.setActive(0x0f & resp.getSW());
+ return 0x0f & resp.getSW();
+ } else if (resp.getSW() == 0x6983) {
+ // authentication method blocked
+ pukPinInfo.setBlocked();
+ throw new LockedException();
+ } else {
+ String msg = "VERIFY failed. SW="
+ + Integer.toHexString(resp.getSW());
+ log.info(msg);
+ pukPinInfo.setUnknown();
+ throw new SignatureCardException(msg);
+ }
+
+ resp = channel.transmit(new CommandAPDU(0x00, 0x2C, 0x02, pin
+ .getKID(), ascii_pin));
+
+ if (resp.getSW() == 0x9000) {
+ pin.setActive(pin.maxRetries);
+ return -1;
+ } else {
+ String msg = "SET PIN failed. SW="
+ + Integer.toHexString(resp.getSW());
+ log.info(msg);
+ pin.setUnknown();
+ throw new SignatureCardException(msg);
}
- */
+
}
-
+
+ /*
+ * Read certificate based on certificate ID
+ */
protected byte[] exec_readcert(CardChannel channel) throws CardException,
- SignatureCardException, IOException {
- if(cert_id == null)
- {
+ SignatureCardException, IOException {
+ if (cert_id == null) {
exec_readcd(channel);
}
-
- /*if(cert_id == null)
- {
- throw CardException("Failed to read the certificate id");
- }*/
-
+
+ if (cert_id == null) {
+ throw new CardException("Failed to read the certificate id");
+ }
+
exec_selectADF(channel);
exec_selectFILE(channel, cert_id);
-
+
return exec_readBinary(channel);
}
-
+
+ /*
+ * Read and parse CD file to determine certificate ID
+ */
protected void exec_readcd(CardChannel channel) throws CardException,
- SignatureCardException, IOException
- {
+ SignatureCardException, IOException {
exec_selectADF(channel);
exec_selectFILE(channel, CD_ID);
-
+
byte[] cd_buffer = exec_readBinary(channel);
-
- // TODO interpret CD => get CERT ID
-
- cert_id = new byte[] { (byte) 0x34, (byte) 0x01 };
+
+ ASN1 asn = new ASN1(cd_buffer);
+
+ for (int i = 0; i < asn.getSize(); i++) {
+
+ ASN1 element = asn.getElementAt(i);
+
+ if (element.getTagClass() == ASN1.TAG_CONTEXT_SPECIFIC
+ && element.getTypeOnly() == ASN1.TYPE_BOOLEAN) {
+ ASN1 ele = element.gvASN1().getElementAt(0).getElementAt(0);
+ if (ele.getTypeOnly() == ASN1.TYPE_OCTET_STRING) {
+ cert_id = ele.gvByteArray();
+ return;
+ }
+ }
+ }
+ cert_id = null;
+ throw new CardException("Failed to read the certificate ID.");
}
-
+
+ /*
+ * Select the ADF application
+ */
protected void exec_selectADF(CardChannel channel) throws CardException,
SignatureCardException {
@@ -385,8 +502,9 @@ public class CypriotEID extends AbstractSignatureCard implements
}
-
-
+ /*
+ * Select a file in the current context by its id
+ */
protected byte[] exec_selectFILE(CardChannel channel, byte[] file_id)
throws CardException, SignatureCardException {
ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0xA4, 0x01,
@@ -403,23 +521,43 @@ public class CypriotEID extends AbstractSignatureCard implements
return resp.getBytes();
}
- protected void exec_MSE(CardChannel channel, byte algoID) throws CardException
- {
- byte[] secure_setup = new byte[] { (byte) 0x80, (byte) 0x01, algoID, // Algorithm setup
+ /*
+ * Setup Manage Security Environment (MSE) for cryptographic signatur !fixed
+ * key id
+ */
+ protected void exec_MSE(CardChannel channel, byte algoID)
+ throws CardException {
+ byte[] secure_setup = new byte[] { (byte) 0x80, (byte) 0x01, algoID, // Algorithm
+ // setup
(byte) 0x84, (byte) 0x01, (byte) 0x81 }; // Key setup
-
- ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0x22,
- 0x41, 0xB6, secure_setup));
+
+ ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0x22, 0x41,
+ 0xB6, secure_setup));
}
-
- protected byte[] exec_sign(CardChannel channel, byte[] hash) throws CardException
- {
- ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0x2A,
- 0x9E, 0x9A, hash));
-
- return resp.getData();
+
+ /*
+ * Execute signature command
+ */
+ protected byte[] exec_sign(CardChannel channel, byte[] hash)
+ throws CardException, SignatureCardException {
+ ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0x2A, 0x9E,
+ 0x9A, hash));
+
+ if (resp.getSW() == 0x6982) {
+ throw new SecurityStatusNotSatisfiedException();
+ }
+ if (resp.getSW() != 0x9000) {
+ throw new SignatureCardException(
+ "PSO - COMPUTE DIGITAL SIGNATRE failed: SW="
+ + Integer.toHexString(resp.getSW()));
+ } else {
+ return resp.getData();
+ }
}
+ /*
+ * Read current binary information
+ */
protected byte[] exec_readBinary(CardChannel channel) throws CardException,
IOException, SignatureCardException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@@ -428,8 +566,8 @@ public class CypriotEID extends AbstractSignatureCard implements
int offset = 0;
do {
- int offset_lo = offset % 0xFF;
- int offset_hi = offset / 0xFF;
+ int offset_lo = (byte) offset;
+ int offset_hi = (byte) (offset >> 8);
ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0xB0,
offset_hi, offset_lo, 0x00));
@@ -451,26 +589,8 @@ public class CypriotEID extends AbstractSignatureCard implements
} while (repeat);
byte[] buf = buffer.toByteArray();
-
- log.debug("BINARY READ: ");
-
- try {
- log.debug(getHexString(buf));
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
+
return buf;
}
-
-
- public static String getHexString(byte[] b) throws Exception {
- String result = "";
- for (int i=0; i < b.length; i++) {
- result += ":" +
- Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );
- }
- return result;
- }
+
}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/LogCardChannel.java b/smcc/src/main/java/at/gv/egiz/smcc/LogCardChannel.java
index c06c3296..1f0f5c4c 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/LogCardChannel.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/LogCardChannel.java
@@ -69,6 +69,7 @@ public class LogCardChannel extends CardChannel {
switch (command.getINS()) {
case 0x20: // VERIFY
case 0x21: // VERIFY
+ case 0x2C: // RESET RETRY COUNTER
case 0x24: { // CHANGE REFERENCE DATA
// Don't log possibly sensitive command data
StringBuilder sb = new StringBuilder();
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/ModifyPINProvider.java b/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/ModifyPINProvider.java
index 5a29e6ce..2d1ec970 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/ModifyPINProvider.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/ModifyPINProvider.java
@@ -53,4 +53,6 @@ public interface ModifyPINProvider {
public char[] provideNewPIN(PinInfo pinInfo)
throws CancelledException, InterruptedException;
+ public char[] providePUK(PinInfo pinInfo, PinInfo pukInfo, int retries)
+ throws CancelledException, InterruptedException;
}
diff --git a/smcc/src/main/resources/at/gv/egiz/smcc/CypriotEID.properties b/smcc/src/main/resources/at/gv/egiz/smcc/CypriotEID.properties
new file mode 100644
index 00000000..df5f05cc
--- /dev/null
+++ b/smcc/src/main/resources/at/gv/egiz/smcc/CypriotEID.properties
@@ -0,0 +1,5 @@
+sig.pin.name=PIN
+sig.pin.length=4-64
+
+sig.puk.name=PUK
+sig.puk.length=4-64 \ No newline at end of file
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
index 89a349b4..fb571495 100644
--- 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
@@ -94,4 +94,27 @@ public class ManagementPINProvider extends AbstractPINProvider implements Modify
}
return gui.getPin();
}
+
+@Override
+public char[] providePUK(PinInfo pinInfo, PinInfo pukInfo, int retries)
+ throws CancelledException, InterruptedException {
+ gui.showPUKDialog(type, pinInfo, pukInfo, (retry) ? retries : -1,
+ this, "change",
+ this, "cancel");
+
+ log.trace("[{}] wait for action.", Thread.currentThread().getName());
+ waitForAction();
+ log.trace("[{}] received action {}.", Thread.currentThread().getName(), action);
+
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT,
+ BKUGUIFacade.MESSAGE_WAIT);
+
+ if ("cancel".equals(action)) {
+ throw new CancelledException(pukInfo.getLocalizedName() +
+ " entry cancelled");
+ }
+ retry = true;
+ return gui.getOldPin();
+}
+
}