summaryrefslogtreecommitdiff
path: root/smcc/src/main/java/at/gv
diff options
context:
space:
mode:
Diffstat (limited to 'smcc/src/main/java/at/gv')
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java18
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java3
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java111
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/SWCard.java10
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java20
5 files changed, 115 insertions, 47 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 6d96599c..13c57686 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
@@ -30,6 +30,8 @@ package at.gv.egiz.smcc;
import java.nio.charset.Charset;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
import javax.smartcardio.CommandAPDU;
@@ -320,7 +322,12 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {
}
@Override
- protected int verifyPIN(String pin, byte kid) throws CardException, SignatureCardException {
+ public byte[] getKIDs() {
+ return new byte[] { KID_PIN_DEC, KID_PIN_INF, KID_PIN_SIG };
+ }
+
+ @Override
+ public int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException {
CardChannel channel = getCardChannel();
@@ -329,8 +336,13 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {
System.arraycopy(asciiPIN, 0, encodedPIN, 0, Math.min(asciiPIN.length,
encodedPIN.length));
- ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00,
- kid, encodedPIN), false);
+ ResponseAPDU resp;
+ try {
+ resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00, kid, encodedPIN), false);
+ } catch (CardException ex) {
+ log.error("smart card communication failed: " + ex.getMessage());
+ throw new SignatureCardException("smart card communication failed: " + ex.getMessage(), ex);
+ }
if (resp.getSW() == 0x63c0) {
throw new LockedException("PIN locked.");
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 633cc90d..67f090a5 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
@@ -112,7 +112,8 @@ public abstract class AbstractSignatureCard implements SignatureCard {
protected abstract ResponseAPDU selectFileFID(byte[] fid) throws CardException,
SignatureCardException;
- protected abstract int verifyPIN(String pin, byte kid) throws CardException, SignatureCardException;
+ // made public
+// protected abstract int verifyPIN(String pin, byte kid) throws CardException, SignatureCardException;
protected byte[] readRecord(int recordNumber) throws SignatureCardException, CardException {
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 2a6e90bf..e80c6683 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
@@ -29,8 +29,10 @@
package at.gv.egiz.smcc;
import java.math.BigInteger;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
import javax.smartcardio.CommandAPDU;
@@ -453,6 +455,11 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard
}
}
+ @Override
+ public byte[] getKIDs() {
+ return new byte[] { KID_PIN_CARD, KID_PIN_SS };
+ }
+
/**
* VERIFY PIN
* <p>
@@ -466,61 +473,81 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard
* the KID of the PIN to be verified
*
* @return -1 if VERIFY PIN was successful, or the number of possible retries
- *
- * @throws CardException
- * if communication with the smart card fails.
+ *
+ * @throws LockedException
+ * if the pin is locked
* @throws NotActivatedException
* if the card application has not been activated
* @throws SignatureCardException
- * if VERIFY PIN fails
+ * if VERIFY PIN fails for some other reason (card communication error)
*/
@Override
- protected int verifyPIN(String pin, byte kid) throws CardException, SignatureCardException {
-
- CardChannel channel = getCardChannel();
+ public int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException {
+ try {
+ CardChannel channel = getCardChannel();
- ResponseAPDU resp;
- if (pin == null) {
- resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00, kid));
- } else {
- // PIN length in bytes
- int len = (int) Math.ceil(pin.length() / 2);
-
- // BCD encode PIN and marshal PIN block
- byte[] pinBytes = new BigInteger(pin, 16).toByteArray();
- byte[] pinBlock = new byte[8];
- if (len < pinBytes.length) {
- System.arraycopy(pinBytes, pinBytes.length - len, pinBlock, 1, len);
+ ResponseAPDU resp;
+ if (pin == null) {
+ resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00, kid));
} else {
- System.arraycopy(pinBytes, 0, pinBlock, len - pinBytes.length + 1,
- pinBytes.length);
+ // PIN length in bytes
+ int len = (int) Math.ceil(pin.length() / 2);
+
+ // BCD encode PIN and marshal PIN block
+ byte[] pinBytes = new BigInteger(pin, 16).toByteArray();
+ byte[] pinBlock = new byte[8];
+ if (len < pinBytes.length) {
+ System.arraycopy(pinBytes, pinBytes.length - len, pinBlock, 1, len);
+ } else {
+ System.arraycopy(pinBytes, 0, pinBlock, len - pinBytes.length + 1,
+ pinBytes.length);
+ }
+ pinBlock[0] = (byte) (0x20 + len * 2);
+ Arrays.fill(pinBlock, len + 1, 8, (byte) 0xff);
+
+ resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00, kid, pinBlock), false);
+
}
- pinBlock[0] = (byte) (0x20 + len * 2);
- Arrays.fill(pinBlock, len + 1, 8, (byte) 0xff);
- resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00, kid, pinBlock), false);
-
+ if (resp.getSW() == 0x63c0) {
+ throw new LockedException("PIN locked.");
+ } else if (resp.getSW1() == 0x63 && resp.getSW2() >> 4 == 0xc) {
+ // return number of possible retries
+ return resp.getSW2() & 0x0f;
+ } else if (resp.getSW() == 0x6983) {
+ throw new LockedException();
+ } else if (resp.getSW() == 0x6984) {
+ // PIN LCS = "Initialized" (-> not activated)
+ throw new NotActivatedException("PIN not set.");
+ } else if (resp.getSW() == 0x9000) {
+ return -1; // success
+ } else {
+ throw new SignatureCardException("Failed to verify pin: SW="
+ + Integer.toHexString(resp.getSW()));
+ }
+ } catch (CardException ex) {
+ log.error("smart card communication failed: " + ex.getMessage());
+ throw new SignatureCardException("smart card communication failed: " + ex.getMessage(), ex);
}
+ }
- if (resp.getSW() == 0x63c0) {
- throw new LockedException("PIN locked.");
- } else if (resp.getSW1() == 0x63 && resp.getSW2() >> 4 == 0xc) {
- // return number of possible retries
- return resp.getSW2() & 0x0f;
- } else if (resp.getSW() == 0x6983) {
- throw new LockedException();
- } else if (resp.getSW() == 0x6984) {
- // PIN LCS = "Initialized" (-> not activated)
- throw new NotActivatedException("PIN not set.");
- } else if (resp.getSW() == 0x9000) {
- return -1; // success
- } else {
- throw new SignatureCardException("Failed to verify pin: SW="
- + Integer.toHexString(resp.getSW()));
+ @Override
+ public void reset() throws SignatureCardException {
+ try {
+ super.reset();
+ log.debug("select MF (e-card workaround)");
+ CardChannel channel = getCardChannel();
+ ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0xA4, 0x00, 0x0C));
+ if (resp.getSW() != 0x9000) {
+ throw new SignatureCardException("Failed to select MF after RESET: SW=" + Integer.toHexString(resp.getSW()) + ".");
+ }
+ } catch (CardException ex) {
+ log.error("Failed to select MF after RESET: " + ex.getMessage(), ex);
+ throw new SignatureCardException("Failed to select MF after RESET");
}
-
}
-
+
+
public String toString() {
return "e-card";
}
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 439be034..bad7ccf6 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java
@@ -389,4 +389,14 @@ public class SWCard implements SignatureCard {
public void reset() throws SignatureCardException {
}
+ @Override
+ public byte[] getKIDs() {
+ return null;
+ }
+
+ @Override
+ public int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException {
+ return -1;
+ }
+
}
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 d7e76dd8..1ec35b78 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java
@@ -28,6 +28,7 @@
//
package at.gv.egiz.smcc;
+import java.util.List;
import java.util.Locale;
import javax.smartcardio.Card;
@@ -115,7 +116,24 @@ public interface SignatureCard {
*/
public byte[] createSignature(byte[] hash, KeyboxName keyboxName,
PINProvider provider) throws SignatureCardException, InterruptedException;
-
+
+ /**
+ * get the KIDs for the availabel PINs
+ * @return array of KIDs
+ */
+ public byte[] getKIDs();
+
+ /**
+ *
+ * @param pin may be null to test the PIN status
+ * @param kid
+ * @return the number of remaining retries or -1
+ * @throws at.gv.egiz.smcc.LockedException
+ * @throws at.gv.egiz.smcc.NotActivatedException
+ * @throws at.gv.egiz.smcc.SignatureCardException
+ */
+ public int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException;
+
/**
* Sets the local for evtl. required callbacks (e.g. PINSpec)
* @param locale must not be null;