summaryrefslogtreecommitdiff
path: root/smcc/src
diff options
context:
space:
mode:
Diffstat (limited to 'smcc/src')
-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
50 files changed, 2262 insertions, 609 deletions
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));
+ }
+ }
+
+
+}