summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2009-11-12 20:48:57 +0000
committermcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2009-11-12 20:48:57 +0000
commit68651bf67987905980734f5c2199f337a232f427 (patch)
treed3875d79cf555488824ca5e4455433c8e13ccd5d
parent68941b57df2caeead67a5bede2ef5a635d07db32 (diff)
downloadmocca-68651bf67987905980734f5c2199f337a232f427.tar.gz
mocca-68651bf67987905980734f5c2199f337a232f427.tar.bz2
mocca-68651bf67987905980734f5c2199f337a232f427.zip
Added support for enforcing a PIN length in a CHANGE REFERENCE DATA to match the recommended PIN length via Applet parameter.
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@541 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
-rw-r--r--BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/BKUApplet.java7
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java4
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/PinDocument.java94
-rw-r--r--BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties2
-rw-r--r--BKUGuiExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUI.java21
-rw-r--r--bkucommon/src/test/java/at/gv/egiz/bku/binding/SSLDataUrlConnectionTest.java4
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java16
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/PINSpec.java302
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java9
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java2
10 files changed, 302 insertions, 159 deletions
diff --git a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/BKUApplet.java b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/BKUApplet.java
index 895fdbb5..85612d6e 100644
--- a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/BKUApplet.java
+++ b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/BKUApplet.java
@@ -21,6 +21,7 @@ import at.gv.egiz.bku.gui.BKUGUIFacade.Style;
import at.gv.egiz.bku.gui.DefaultHelpListener;
import at.gv.egiz.bku.gui.AbstractHelpListener;
import at.gv.egiz.bku.gui.SwitchFocusListener;
+import at.gv.egiz.smcc.SignatureCardFactory;
import at.gv.egiz.stal.service.translator.STALTranslator;
import java.io.IOException;
@@ -71,6 +72,7 @@ public class BKUApplet extends JApplet {
public static final String REDIRECT_URL = "RedirectURL";
public static final String REDIRECT_TARGET = "RedirectTarget";
public static final String HASHDATA_DISPLAY_FRAME = "frame";
+ public static final String ENFORCE_RECOMMENDED_PIN_LENGTH = "EnforceRecommendedPINLength";
/**
* STAL WSDL namespace and service name
*/
@@ -157,6 +159,11 @@ public class BKUApplet extends JApplet {
log.trace("default locale: " + Locale.getDefault());
log.debug("setting locale: " + getLocale());
+ if (Boolean.parseBoolean(getParameter(ENFORCE_RECOMMENDED_PIN_LENGTH))) {
+ SignatureCardFactory.ENFORCE_RECOMMENDED_PIN_LENGTH = true;
+ log.debug("enforce recommended pin length = " + SignatureCardFactory.ENFORCE_RECOMMENDED_PIN_LENGTH);
+ }
+
BKUGUIFacade.Style guiStyle;
String guiStyleParam = getParameter(GUI_STYLE);
if ("advanced".equals(guiStyleParam)) {
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 34f278fb..20fe4f56 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
@@ -593,7 +593,7 @@ public class BKUGUIImpl implements BKUGUIFacade {
pinField = new JPasswordField();
pinField.setText("");
- pinField.setDocument(new PINDocument(pinSpec, okButton));
+ pinField.setDocument(new PINDocument(pinSpec.getMinLength(), pinSpec.getMaxLength(), pinSpec.getRexepPattern(), okButton));
pinField.setActionCommand(okCommand);
pinField.addActionListener(new ActionListener() {
@@ -1031,7 +1031,7 @@ public class BKUGUIImpl implements BKUGUIFacade {
pinField = new JPasswordField();
pinField.setText("");
- pinField.setDocument(new PINDocument(pinSpec, signButton));
+ pinField.setDocument(new PINDocument(pinSpec.getMinLength(), pinSpec.getMaxLength(), pinSpec.getRexepPattern(), signButton));
pinField.setActionCommand(signCommand);
pinField.addActionListener(new ActionListener() {
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 13aaf870..96032dc1 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
@@ -16,7 +16,6 @@
*/
package at.gv.egiz.bku.gui;
-import at.gv.egiz.smcc.PINSpec;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JButton;
@@ -31,49 +30,60 @@ import javax.swing.text.PlainDocument;
*/
class PINDocument extends PlainDocument {
- protected PINSpec pinSpec;
- protected Pattern pinPattern;
- protected JButton enterButton;
- protected Document compareTo;
- protected Document oldPin;
+ private static final long serialVersionUID = 1L;
+
+ protected Pattern pinPattern;
+ protected int minLength;
+ protected int maxLength;
- public PINDocument(PINSpec pinSpec, JButton enterButton) {
- this.pinSpec = pinSpec;
- if (pinSpec.getRexepPattern() != null) {
- pinPattern = Pattern.compile(pinSpec.getRexepPattern());
- } else {
- pinPattern = Pattern.compile(".");
- }
- this.enterButton = enterButton;
- }
+ protected JButton enterButton;
+ protected Document compareTo;
+ protected Document oldPin;
- /**
- *
- * @param pinSpec
- * @param enterButton
- * @param compareTo enable enterButton iff this pinDocument's pin equals to compareTo's pin. may be null
- */
- public PINDocument(PINSpec pinSpec, JButton enterButton, Document compareTo) {
- this(pinSpec, enterButton);
- this.compareTo = compareTo;
- }
+ public PINDocument(int minLength, int maxLength, String pattern, JButton enterButton) {
+ if (pattern != null) {
+ pinPattern = Pattern.compile(pattern);
+ } else {
+ pinPattern = Pattern.compile(".");
+ }
+ this.minLength = minLength;
+ this.maxLength = maxLength;
+ this.enterButton = enterButton;
+ }
- /**
- *
- * @param pinSpec
- * @param enterButton may be null
- * @param compareTo enable enterButton iff this pinDocument's pin equals to compareTo's pin. may be null
- * @param oldPin enable enterButton iff oldPin meets the pinSpec pin length requirements, may be null
- */
- public PINDocument(PINSpec pinSpec, JButton enterButton, Document compareTo, Document oldPin) {
- this(pinSpec, enterButton);
- this.compareTo = compareTo;
- this.oldPin = oldPin;
- }
+ /**
+ * @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;
+ }
+
+ /**
+ * @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 insertString(int offs, String str, AttributeSet a) throws BadLocationException {
- if (pinSpec.getMaxLength() < 0 || pinSpec.getMaxLength() >= (getLength() + str.length())) {
+ 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));
@@ -87,8 +97,8 @@ class PINDocument extends PlainDocument {
}
if (enterButton != null) {
enterButton.setEnabled(
- (oldPin == null || oldPin.getLength() >= pinSpec.getMinLength()) &&
- getLength() >= pinSpec.getMinLength() &&
+ (oldPin == null || oldPin.getLength() >= minLength) &&
+ getLength() >= minLength &&
compare());
}
}
@@ -98,8 +108,8 @@ class PINDocument extends PlainDocument {
super.remove(offs, len);
if (enterButton != null) {
enterButton.setEnabled(
- (oldPin == null || oldPin.getLength() >= pinSpec.getMinLength()) &&
- getLength() >= pinSpec.getMinLength() &&
+ (oldPin == null || oldPin.getLength() >= minLength) &&
+ getLength() >= minLength &&
compare());
}
}
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 22b9095c..ef643bfd 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
@@ -51,7 +51,7 @@ retries.pinpad=<html>Re-enter pin, {0} tries left</html>
overwrite=<html>Overwrite {0}?</html>
help=<html>Help topic {0}</html>
-warning.xhtml=<html>Remark: This is a preview of the data to-be signed. For standards compliant display see help.</html>
+warning.xhtml=<html>Remark: This is a preview of the data to-be signed. For standards complaint display see help.</html>
label.pin=<html>{0}:</html>
label.pinsize=<html>({0} digits)</html>
button.ok=OK
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 6699554e..5bbed096 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
@@ -436,14 +436,14 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
});
if (type != DIALOG.VERIFY) {
- pinField.setDocument(new PINDocument(pinSpec, null));
+ pinField.setDocument(
+ new PINDocument(pinSpec.getRecMinLength(), pinSpec.getRecMaxLength(), pinSpec.getRexepPattern(), null));
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.setDocument(new PINDocument(pinSpec, okButton, pinField.getDocument()));
repeatPinField.setActionCommand(okCommand);
repeatPinField.addActionListener(new ActionListener() {
@@ -463,7 +463,8 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
oldPinField = new JPasswordField();
oldPinField.setText("");
- oldPinField.setDocument(new PINDocument(pinSpec, null));
+ oldPinField.setDocument(
+ new PINDocument(pinSpec.getMinLength(), pinSpec.getMaxLength(), pinSpec.getRexepPattern(), null));
oldPinField.setActionCommand(okCommand);
oldPinField.addActionListener(new ActionListener() {
@@ -475,16 +476,18 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac
}
});
- repeatPinField.setDocument(new PINDocument(
- pinSpec, okButton,
- pinField.getDocument(), oldPinField.getDocument()));
+ repeatPinField.setDocument(
+ new PINDocument(pinSpec.getRecMinLength(), pinSpec.getRecMaxLength(), pinSpec.getRexepPattern(),
+ okButton, pinField.getDocument(), oldPinField.getDocument()));
} else {
// else -> ACTIVATE (not verify, not change)
- repeatPinField.setDocument(new PINDocument(
- pinSpec, okButton, pinField.getDocument()));
+ repeatPinField.setDocument(
+ new PINDocument(pinSpec.getRecMinLength(), pinSpec.getRecMaxLength(), pinSpec.getRexepPattern(),
+ okButton, pinField.getDocument()));
}
} else {
- pinField.setDocument(new PINDocument(pinSpec, okButton));
+ pinField.setDocument(
+ new PINDocument(pinSpec.getMinLength(), pinSpec.getMaxLength(), pinSpec.getRexepPattern(), okButton));
}
JLabel pinsizeLabel = new JLabel();
diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/binding/SSLDataUrlConnectionTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/binding/SSLDataUrlConnectionTest.java
index 407a556a..6cf0c9e7 100644
--- a/bkucommon/src/test/java/at/gv/egiz/bku/binding/SSLDataUrlConnectionTest.java
+++ b/bkucommon/src/test/java/at/gv/egiz/bku/binding/SSLDataUrlConnectionTest.java
@@ -21,12 +21,14 @@ import static org.junit.Assert.assertNotNull;
import java.io.IOException;
import java.net.URL;
+import org.junit.Ignore;
import org.junit.Test;
public class SSLDataUrlConnectionTest {
- @Test
+ @Test
+ @Ignore
public void testVerisign() throws IOException {
URL url = new URL("https://www.verisign.com:443");
DataUrlConnectionImpl uc = new DataUrlConnectionImpl();
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 a63d4076..1ed5a177 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
@@ -116,6 +116,14 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
private static final PINSpec INF_PIN_SPEC = new PINSpec(0, 8, "[0-9]",
"at/gv/egiz/smcc/ACOSCard", "inf.pin", KID_PIN_INF, AID_DEC);
+ static {
+ if (SignatureCardFactory.ENFORCE_RECOMMENDED_PIN_LENGTH) {
+ DEC_PIN_SPEC.setRecLength(4);
+ SIG_PIN_SPEC.setRecLength(6);
+ INF_PIN_SPEC.setRecLength(4);
+ }
+ }
+
/**
* The version of the card's digital signature application.
*/
@@ -390,10 +398,12 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
MessageDigest md;
try {
- if ("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1".equals(alg)) {
+ if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)
+ && (alg == null || "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1".equals(alg))) {
dst.write((byte) 0x14); // SHA-1/ECC
md = MessageDigest.getInstance("SHA-1");
- } else if ("http://www.w3.org/2000/09/xmldsig#rsa-sha1".equals(alg)) {
+ } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)
+ && (alg == null || "http://www.w3.org/2000/09/xmldsig#rsa-sha1".equals(alg))) {
dst.write((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)
@@ -401,7 +411,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
&& "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256".equals(alg)) {
dst.write((byte) 0x44); // SHA-256/ECC
md = MessageDigest.getInstance("SHA256");
- } else if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)
+ } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)
&& appVersion >= 2
&& "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256".equals(alg)) {
dst.write((byte) 0x41); // SHA-256 with padding according to PKCS#1
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/PINSpec.java b/smcc/src/main/java/at/gv/egiz/smcc/PINSpec.java
index 1812049c..f68edbed 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/PINSpec.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/PINSpec.java
@@ -17,6 +17,7 @@
package at.gv.egiz.smcc;
import java.util.Locale;
+import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
@@ -25,113 +26,214 @@ import java.util.ResourceBundle;
*/
public class PINSpec {
- int minLength_ = 0;
+ /**
+ * The minimum PIN length.
+ */
+ protected int minLength = 0;
- int maxLength_ = -1;
+ /**
+ * The maximum PIN length or -1 if not specified.
+ */
+ protected int maxLength = -1;
- String rexepPattern_;
-
- String resourceBundleName_;
-
- String nameKey_;
-
- /** the localized, i.e. configurable length */
- String lengthKey_;
-
- byte kid_;
-
- byte[] context_aid_;
-
- /**
- *
- * @param minLenght
- * @param maxLength
- * @param rexepPattern
- * @param resourceBundle
- * @param name
- * @param kid the keyId for this pin
- */
- public PINSpec(int minLenght, int maxLength, String rexepPattern,
- String resourceBundleName, String resourceKey, byte kid, byte[] contextAID) {
-
- minLength_ = minLenght;
- maxLength_ = maxLength;
- rexepPattern_ = rexepPattern;
- resourceBundleName_ = resourceBundleName;
- nameKey_ = resourceKey + ".name";
- lengthKey_ = resourceKey + ".length";
- kid_ = kid;
- context_aid_ = contextAID;
- }
-
- public PINSpec(int minLenght, int maxLength, String rexepPattern,
- String name, byte kid, byte[] contextAID) {
-
- minLength_ = minLenght;
- maxLength_ = maxLength;
- rexepPattern_ = rexepPattern;
- nameKey_ = name + ".name";
- lengthKey_ = name + ".length";
- kid_ = kid;
- context_aid_ = contextAID;
- }
-
- public String getLocalizedName() {
-
- if (resourceBundleName_ != null) {
- ResourceBundle resourceBundle = ResourceBundle.getBundle(resourceBundleName_);
- return resourceBundle.getString(nameKey_);
- } else {
- return nameKey_;
+ /**
+ * The recommended PIN length or -1 if not specified.
+ */
+ protected int recLength = -1;
+
+ /**
+ * The regular expression pattern of a single PIN digit or character.
+ */
+ protected String rexepPattern;
+
+ /**
+ * The name of the corresponding resource bundle.
+ */
+ protected String resourceBundleName;
+
+ /**
+ * The key of the PIN name in the resource bundle.
+ */
+ protected String nameKey;
+
+ /**
+ * The name of the PIN.
+ */
+ protected String name;
+
+ /**
+ * The key id to be used in VERIFY or CHANGE REFERENCE DATA APDUs.
+ */
+ protected byte kid;
+
+ /**
+ * The context AID of the key id.
+ */
+ protected byte[] context_aid;
+
+ /**
+ * Creates a new instance of this PINSpec with the given lengths, regular
+ * expression pattern, the ResourceBundle name and key to lookup the PIN name
+ * and the KID and AID.
+ *
+ * @param minLenght the minimum length of the PIN
+ * @param maxLength the maximum length of the PIN, or -1 if there is no maximum length
+ * @param rexepPattern the regular expression pattern of a single PIN digit or character
+ * @param resourceBundleName the name of a ResourceBundle for this PIN
+ * @param resourceKey the key to look up the (localized) name of this PIN
+ * @param kid the key id of the PIN
+ * @param contextAID the AID the KID is valid in
+ */
+ public PINSpec(int minLenght, int maxLength, String rexepPattern,
+ String resourceBundleName, String resourceKey, byte kid, byte[] contextAID) {
+
+ this.minLength = minLenght;
+ this.maxLength = maxLength;
+ this.rexepPattern = rexepPattern;
+ this.resourceBundleName = resourceBundleName;
+ this.nameKey = resourceKey + ".name";
+ this.kid = kid;
+ this.context_aid = contextAID;
+ }
+
+ /**
+ * Creates a new instance of this PINSpec with the given lengths, regular
+ * expression pattern, the name of the PIN and the KID and AID.
+ *
+ * @param minLenght the minimum length of the PIN
+ * @param maxLength the maximum length of the PIN, or -1 if there is no maximum length
+ * @param rexepPattern the regular expression pattern of a single PIN digit or character
+ * @param name the name of the PIN
+ * @param kid the key id of the PIN
+ * @param contextAID the AID the KID is valid in
+ */
+ public PINSpec(int minLenght, int maxLength, String rexepPattern,
+ String name, byte kid, byte[] contextAID) {
+
+ this.minLength = minLenght;
+ this.maxLength = maxLength;
+ this.rexepPattern = rexepPattern;
+ this.name = name;
+ this.kid = kid;
+ this.context_aid = contextAID;
+ }
+
+ /**
+ * This method sets the recommended PIN length.
+ *
+ * @param recLength the recommended PIN length
+ */
+ public void setRecLength(int recLength) {
+ this.recLength = recLength;
+ }
+
+ /**
+ * @return the localized (using the default locale) name of the PIN, or the
+ * name set by
+ * {@link #PINSpec(int, int, String, String, byte, byte[])}.
+ */
+ public String getLocalizedName() {
+ if (name != null) {
+ return name;
+ } else if (resourceBundleName != null){
+ try {
+ return ResourceBundle.getBundle(resourceBundleName).getString(nameKey);
+ } catch (MissingResourceException e) {
}
-
}
-
- public String getLocalizedName(Locale locale) {
-
- if (resourceBundleName_ != null) {
- ResourceBundle resourceBundle = ResourceBundle.getBundle(resourceBundleName_, locale);
- return resourceBundle.getString(nameKey_);
- } else {
- return nameKey_;
+ return nameKey;
+ }
+
+ /**
+ * @param locale the locale for which the name should be returned
+ * @return the localized name of the PIN, or the name set by
+ * {@link #PINSpec(int, int, String, String, byte, byte[])}
+ */
+ public String getLocalizedName(Locale locale) {
+ if (name != null) {
+ return name;
+ } else if (resourceBundleName != null) {
+ try {
+ return ResourceBundle.getBundle(resourceBundleName, locale).getString(nameKey);
+ } catch (MissingResourceException e) {
}
-
- }
-
- public String getLocalizedLength() {
-
- if (resourceBundleName_ != null) {
- ResourceBundle resourceBundle = ResourceBundle.getBundle(resourceBundleName_);
- return resourceBundle.getString(lengthKey_);
- } else {
- if (maxLength_ > minLength_) {
- return minLength_ + "-" + maxLength_;
- } else {
- return String.valueOf(minLength_);
- }
- }
-
}
-
- public int getMaxLength() {
- return maxLength_;
- }
-
- public int getMinLength() {
- return minLength_;
- }
-
- public String getRexepPattern() {
- return rexepPattern_;
- }
-
- public byte getKID() {
- return kid_;
+ return nameKey;
+ }
+
+ /**
+ * @return the recommended PIN length if specified and
+ * <code>recommended</code> is <code>true</code>, or
+ * <code>minLength</code>-<code>maxLength</code>
+ */
+ public String getLocalizedLength() {
+
+ if (recLength > 0) {
+ return "" + recLength;
+ } else if (maxLength == minLength) {
+ return "" + minLength;
+ } else if (maxLength > minLength) {
+ return minLength + "-" + maxLength;
+ } else {
+ return minLength + "+";
}
- public byte[] getContextAID() {
- return context_aid_;
- }
-
+ }
+
+ /**
+ * @return the minimum length of the PIN
+ */
+ public int getMinLength() {
+ return minLength;
+ }
+
+ /**
+ * @return the maximum length of the PIN, or -1 if not specified.
+ */
+ public int getMaxLength() {
+ return maxLength;
+ }
+
+ /**
+ * @return the minimum length of the PIN
+ */
+ public int getRecMinLength() {
+ return (recLength >= minLength) ? recLength : minLength;
+ }
+
+ /**
+ * @return the maximum length of the PIN
+ */
+ public int getRecMaxLength() {
+ return (recLength >= minLength) ? recLength : maxLength;
+ }
+
+ /**
+ * @return the recommended length of the PIN, or -1 if not specified
+ */
+ public int getRecLength() {
+ return recLength;
+ }
+
+ /**
+ * @return the regular expression pattern of one single digit or character
+ */
+ public String getRexepPattern() {
+ return rexepPattern;
+ }
+
+ /**
+ * @return the key id of the PIN
+ */
+ public byte getKID() {
+ return kid;
+ }
+
+ /**
+ * @return the AID the KID is valid in, or <code>null</code> if KID is global
+ */
+ public byte[] getContextAID() {
+ return context_aid;
+ }
}
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 01de8a77..880cab4b 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
@@ -137,6 +137,13 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
new PINSpec(6, 12, "[0-9]",
"at/gv/egiz/smcc/STARCOSCard", "sig.pin", KID_PIN_SS, AID_DF_SS);
+ static {
+ if (SignatureCardFactory.ENFORCE_RECOMMENDED_PIN_LENGTH) {
+ CARD_PIN_SPEC.setRecLength(4);
+ SS_PIN_SPEC.setRecLength(6);
+ }
+ }
+
protected double version = 1.1;
/**
@@ -301,7 +308,7 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
MessageDigest md = null;
try {
- if (version < 1.2 && "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1".equals(alg)) {
+ if (version < 1.2 && (alg == null || "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1".equals(alg))) {
// local key ID '02' version '00'
dst.write(new byte[] {(byte) 0x84, (byte) 0x03, (byte) 0x80, (byte) 0x02, (byte) 0x00});
// algorithm ID ECDSA with SHA-1
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java
index 47053f98..405da7c0 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java
@@ -32,6 +32,8 @@ import org.apache.commons.logging.LogFactory;
* A factory for creating {@link SignatureCard}s from {@link Card}s.
*/
public class SignatureCardFactory {
+
+ public static boolean ENFORCE_RECOMMENDED_PIN_LENGTH = false;
/**
* This class represents a supported smart card.