summaryrefslogtreecommitdiff
path: root/smcc
diff options
context:
space:
mode:
Diffstat (limited to 'smcc')
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java82
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java57
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java96
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/SWCard.java13
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java13
5 files changed, 193 insertions, 68 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 57925240..c2c62fd8 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
@@ -31,6 +31,7 @@ package at.gv.egiz.smcc;
import at.gv.egiz.smcc.util.SMCCHelper;
import java.nio.charset.Charset;
+import javax.smartcardio.Card;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
import javax.smartcardio.CommandAPDU;
@@ -334,8 +335,8 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {
}
@Override
- public int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException {
-
+ protected int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException {
+
CardChannel channel = getCardChannel();
ResponseAPDU resp;
@@ -343,13 +344,17 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {
if (pin != null) {
resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00, kid, encodePINBlock(pin)), false);
} else {
+ //TODO this is not supported
resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00, kid), false);
}
} catch (CardException ex) {
log.error("smart card communication failed: " + ex.getMessage());
throw new SignatureCardException("smart card communication failed: " + ex.getMessage(), ex);
}
-
+
+ //6A 00 (falshe P1/P2) nicht in contextAID
+ //69 85 (nutzungsbedingungen nicht erfüllt) in DF_Sig und nicht sigpin
+
if (resp.getSW() == 0x63c0) {
throw new LockedException("PIN locked.");
} else if (resp.getSW1() == 0x63 && resp.getSW2() >> 4 == 0xc) {
@@ -363,7 +368,6 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {
throw new SignatureCardException("Failed to verify pin: SW="
+ Integer.toHexString(resp.getSW()) + ".");
}
-
}
private void mseSetDST(int p1, int p2, byte[] dst) throws CardException, SignatureCardException {
@@ -432,8 +436,7 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {
* @param pin
* @return a 8 byte pin block
*/
- @Override
- public byte[] encodePINBlock(String pin) {
+ private byte[] encodePINBlock(String pin) {
byte[] asciiPIN = pin.getBytes(Charset.forName("ASCII"));
byte[] encodedPIN = new byte[8];
System.arraycopy(asciiPIN, 0, encodedPIN, 0, Math.min(asciiPIN.length,
@@ -443,7 +446,72 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {
}
@Override
- public void activatePIN(byte kid, byte[] contextAID, String pin) throws SignatureCardException {
+ public void activatePIN(PINSpec pinSpec, String pin) throws SignatureCardException {
throw new SignatureCardException("PIN activation not supported by this card");
}
+
+ /**
+ * SCARD_E_NOT_TRANSACTED inf/dec PIN not active (pcsc crash)
+ * @param pinSpec
+ * @param oldPIN
+ * @param newPIN
+ * @throws at.gv.egiz.smcc.LockedException
+ * @throws at.gv.egiz.smcc.VerificationFailedException
+ * @throws at.gv.egiz.smcc.NotActivatedException
+ * @throws at.gv.egiz.smcc.SignatureCardException
+ */
+ @Override
+ public void changePIN(PINSpec pinSpec, String oldPIN, String newPIN)
+ throws LockedException, VerificationFailedException, NotActivatedException, SignatureCardException {
+ Card icc = getCard();
+ try {
+ icc.beginExclusive();
+ CardChannel channel = icc.getBasicChannel();
+
+ if (pinSpec.getContextAID() != null) {
+ ResponseAPDU responseAPDU = transmit(channel,
+ new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, pinSpec.getContextAID()));
+ if (responseAPDU.getSW() != 0x9000) {
+ icc.endExclusive();
+ String msg = "Select AID " + SMCCHelper.toString(pinSpec.getContextAID()) +
+ ": SW=" + Integer.toHexString(responseAPDU.getSW());
+ log.error(msg);
+ throw new SignatureCardException(msg);
+ }
+ }
+
+ byte[] cmd = new byte[16];
+ System.arraycopy(encodePINBlock(oldPIN), 0, cmd, 0, 8);
+ System.arraycopy(encodePINBlock(newPIN), 0, cmd, 8, 8);
+
+ ResponseAPDU responseAPDU = transmit(channel,
+ new CommandAPDU(0x00, 0x24, 0x00, pinSpec.getKID(), cmd), false);
+
+ icc.endExclusive();
+
+ log.debug("change pin returned SW=" + Integer.toHexString(responseAPDU.getSW()));
+
+ if (responseAPDU.getSW() == 0x63c0) {
+ log.error(pinSpec.getLocalizedName() + " locked");
+ throw new LockedException();
+ } else if (responseAPDU.getSW1() == 0x63 && responseAPDU.getSW2() >> 4 == 0xc) {
+ int retries = responseAPDU.getSW2() & 0x0f;
+ log.error("wrong " + pinSpec.getLocalizedName() + ", " + retries + " retries");
+ throw new VerificationFailedException(retries);
+ } else if (responseAPDU.getSW() == 0x6983) {
+ // sig-pin only (card not transacted for inf/dec pin)
+ log.error(pinSpec.getLocalizedName() + " not activated");
+ throw new NotActivatedException();
+ } else if (responseAPDU.getSW() != 0x9000) {
+ String msg = "Failed to change " + pinSpec.getLocalizedName() +
+ ": SW=" + Integer.toHexString(responseAPDU.getSW());
+ log.error(msg);
+ throw new SignatureCardException(msg);
+ }
+ } catch (CardException ex) {
+ log.error("Failed to change " + pinSpec.getLocalizedName() +
+ ": " + ex.getMessage());
+ throw new SignatureCardException(ex.getMessage(), ex);
+ }
+ }
}
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 63301bd1..39952bb9 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
@@ -37,6 +37,8 @@ import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.smartcardio.ATR;
import javax.smartcardio.Card;
import javax.smartcardio.CardChannel;
@@ -117,8 +119,8 @@ public abstract class AbstractSignatureCard implements SignatureCard {
protected abstract ResponseAPDU selectFileFID(byte[] fid) throws CardException,
SignatureCardException;
- // made public
-// protected abstract int verifyPIN(String pin, byte kid) throws CardException, SignatureCardException;
+ protected abstract int verifyPIN(String pin, byte kid)
+ throws LockedException, NotActivatedException, SignatureCardException;
protected byte[] readRecord(int recordNumber) throws SignatureCardException, CardException {
@@ -321,7 +323,7 @@ public abstract class AbstractSignatureCard implements SignatureCard {
throw new VerificationFailedException(retries);
}
}
-
+
return readBinaryTLV(maxLength, (byte) 0x30);
@@ -443,53 +445,40 @@ public abstract class AbstractSignatureCard implements SignatureCard {
return pinSpecs;
}
- public void changePIN(byte kid, byte[] contextAID, String oldPIN, String newPIN) throws SignatureCardException, VerificationFailedException {
+ @Override
+ public int verifyPIN(PINSpec pinSpec, String pin) throws LockedException, NotActivatedException, SignatureCardException {
+
Card icc = getCard();
try {
icc.beginExclusive();
CardChannel channel = icc.getBasicChannel();
- if (contextAID != null) {
+ if (pinSpec.getContextAID() != null) {
ResponseAPDU responseAPDU = transmit(channel,
- new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, contextAID));
+ new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, pinSpec.getContextAID()));
if (responseAPDU.getSW() != 0x9000) {
icc.endExclusive();
- String msg = "Failed to change PIN " + SMCCHelper.toString(new byte[]{kid}) +
- ": Failed to select AID " + SMCCHelper.toString(contextAID) +
+ String msg = "Failed to verify PIN " +
+ SMCCHelper.toString(new byte[]{pinSpec.getKID()}) +
+ ": Failed to verify AID " +
+ SMCCHelper.toString(pinSpec.getContextAID()) +
": " + SMCCHelper.toString(responseAPDU.getBytes());
log.error(msg);
throw new SignatureCardException(msg);
}
}
+ return verifyPIN(pin, pinSpec.getKID());
- byte[] cmd = new byte[16];
- System.arraycopy(encodePINBlock(oldPIN), 0, cmd, 0, 8);
- System.arraycopy(encodePINBlock(newPIN), 0, cmd, 8, 8);
-
- ResponseAPDU responseAPDU = transmit(channel,
- new CommandAPDU(0x00, 0x24, 0x00, kid, cmd), false);
-
- icc.endExclusive();
-
- if (responseAPDU.getSW1() == 0x63 && responseAPDU.getSW2() >> 4 == 0xc) {
- int retries = responseAPDU.getSW2() & 0x0f;
- log.error("Failed VERIFY PIN, " + retries + " tries left");
- throw new VerificationFailedException(retries);
- }
- if (responseAPDU.getSW() != 0x9000) {
- String msg = "Failed to change PIN "
- + SMCCHelper.toString(new byte[]{kid}) + ": "
- + SMCCHelper.toString(responseAPDU.getBytes());
- log.error(msg);
- throw new SignatureCardException(msg);
+ } catch (CardException ex) {
+ log.error("failed to verify pinspec: " + ex.getMessage(), ex);
+ throw new SignatureCardException(ex);
+ } finally {
+ try {
+ icc.endExclusive();
+ } catch (CardException ex) {
+ log.trace("failed to end exclusive card access: " + ex.getMessage());
}
- } catch (CardException ex) {
- log.error("Failed to change PIN: " + ex.getMessage());
- throw new SignatureCardException(ex.getMessage(), ex);
}
}
-
- abstract byte[] encodePINBlock(String pin);
-
}
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 b1288f74..3c5f38a2 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
@@ -512,7 +512,7 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard
throw new LockedException();
} else if (resp.getSW() == 0x6984) {
// PIN LCS = "Initialized" (-> not activated)
- throw new NotActivatedException("PIN not set.");
+ throw new NotActivatedException();
} else if (resp.getSW() == 0x9000) {
return -1; // success
} else {
@@ -552,8 +552,7 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard
* @return a 8 byte pin block consisting of length byte (0x2X),
* the BCD encoded pin and a 0xFF padding
*/
- @Override
- public byte[] encodePINBlock(String pin) {
+ private byte[] encodePINBlock(String pin) {
char[] pinChars = pin.toCharArray();
int numDigits = pinChars.length;
int numBytes = (int) Math.ceil(numDigits/2.0);
@@ -572,37 +571,108 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard
return pinBlock;
}
- public void activatePIN(byte kid, byte[] contextAID, String pin) throws SignatureCardException {
+ @Override
+ public void activatePIN(PINSpec pinSpec, String pin)
+ throws SignatureCardException {
Card icc = getCard();
try {
icc.beginExclusive();
CardChannel channel = icc.getBasicChannel();
- if (contextAID != null) {
+ if (pinSpec.getContextAID() != null) {
ResponseAPDU responseAPDU = transmit(channel,
- new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, contextAID));
+ new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, pinSpec.getContextAID()));
if (responseAPDU.getSW() != 0x9000) {
icc.endExclusive();
- String msg = "Failed to activate PIN " + SMCCHelper.toString(new byte[]{kid}) +
- ": Failed to select AID " + SMCCHelper.toString(contextAID) +
- ": " + SMCCHelper.toString(responseAPDU.getBytes());
+ String msg = "Select AID " + SMCCHelper.toString(pinSpec.getContextAID()) +
+ ": SW=" + Integer.toHexString(responseAPDU.getSW());
log.error(msg);
throw new SignatureCardException(msg);
}
}
ResponseAPDU responseAPDU = transmit(channel,
- new CommandAPDU(0x00, 0x24, 0x01, kid, encodePINBlock(pin)), false);
+ new CommandAPDU(0x00, 0x24, 0x01, pinSpec.getKID(), encodePINBlock(pin)),
+ false);
icc.endExclusive();
- if (responseAPDU.getSW() != 0x9000) {
- String msg = "Failed to activate PIN " + SMCCHelper.toString(new byte[]{kid}) + ": " + SMCCHelper.toString(responseAPDU.getBytes());
+ log.debug("activate pin returned SW=" + Integer.toHexString(responseAPDU.getSW()));
+
+ if (responseAPDU.getSW() != 0x9000) {
+ String msg = "Failed to activate " + pinSpec.getLocalizedName() +
+ ": SW=" + Integer.toHexString(responseAPDU.getSW());
+ log.error(msg);
+ throw new SignatureCardException(msg);
+ }
+ } catch (CardException ex) {
+ log.error("Failed to activate " + pinSpec.getLocalizedName() +
+ ": " + ex.getMessage());
+ throw new SignatureCardException(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * activates pin (newPIN) if not active
+ * @param pinSpec
+ * @param oldPIN
+ * @param newPIN
+ * @throws at.gv.egiz.smcc.LockedException
+ * @throws at.gv.egiz.smcc.VerificationFailedException
+ * @throws at.gv.egiz.smcc.NotActivatedException
+ * @throws at.gv.egiz.smcc.SignatureCardException
+ */
+ @Override
+ public void changePIN(PINSpec pinSpec, String oldPIN, String newPIN)
+ throws LockedException, VerificationFailedException, NotActivatedException, SignatureCardException {
+ Card icc = getCard();
+ try {
+ icc.beginExclusive();
+ CardChannel channel = icc.getBasicChannel();
+
+ if (pinSpec.getContextAID() != null) {
+ ResponseAPDU responseAPDU = transmit(channel,
+ new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, pinSpec.getContextAID()));
+ if (responseAPDU.getSW() != 0x9000) {
+ icc.endExclusive();
+ String msg = "Select AID " + SMCCHelper.toString(pinSpec.getContextAID()) +
+ ": SW=" + Integer.toHexString(responseAPDU.getSW());
+ log.error(msg);
+ throw new SignatureCardException(msg);
+ }
+ }
+
+ byte[] cmd = new byte[16];
+ System.arraycopy(encodePINBlock(oldPIN), 0, cmd, 0, 8);
+ System.arraycopy(encodePINBlock(newPIN), 0, cmd, 8, 8);
+
+ ResponseAPDU responseAPDU = transmit(channel,
+ new CommandAPDU(0x00, 0x24, 0x00, pinSpec.getKID(), cmd), false);
+
+ icc.endExclusive();
+
+ log.debug("change pin returned SW=" + Integer.toHexString(responseAPDU.getSW()));
+
+ // activates pin (newPIN) if not active
+ if (responseAPDU.getSW() == 0x63c0) {
+ log.error(pinSpec.getLocalizedName() + " locked");
+ throw new LockedException();
+ } else if (responseAPDU.getSW1() == 0x63 && responseAPDU.getSW2() >> 4 == 0xc) {
+ int retries = responseAPDU.getSW2() & 0x0f;
+ log.error("wrong " + pinSpec.getLocalizedName() + ", " + retries + " retries");
+ throw new VerificationFailedException(retries);
+ } else if (responseAPDU.getSW() == 0x6983) {
+ log.error(pinSpec.getLocalizedName() + " locked");
+ throw new LockedException();
+ } else if (responseAPDU.getSW() != 0x9000) {
+ String msg = "Failed to change " + pinSpec.getLocalizedName() +
+ ": SW=" + Integer.toHexString(responseAPDU.getSW());
log.error(msg);
throw new SignatureCardException(msg);
}
} catch (CardException ex) {
- log.error("Failed to activate PIN: " + ex.getMessage());
+ log.error("Failed to change " + pinSpec.getLocalizedName() +
+ ": " + ex.getMessage());
throw new SignatureCardException(ex.getMessage(), ex);
}
}
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 57aeb994..d7763be0 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java
@@ -394,21 +394,20 @@ public class SWCard implements SignatureCard {
}
@Override
- public int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException {
- return -1;
- }
-
- @Override
public List<PINSpec> getPINSpecs() {
return new ArrayList<PINSpec>();
}
@Override
- public void changePIN(byte kid, byte[] contextAID, String oldPIN, String newPIN) throws SignatureCardException, VerificationFailedException {
+ public int verifyPIN(PINSpec pinSpec, String pin) throws LockedException, NotActivatedException, SignatureCardException {
+ return -1;
}
@Override
- public void activatePIN(byte kid, byte[] contextAID, String pin) throws SignatureCardException {
+ public void changePIN(PINSpec pinSpec, String oldPIN, String newPIN) throws LockedException, VerificationFailedException, NotActivatedException, SignatureCardException {
}
+ @Override
+ public void activatePIN(PINSpec pinSpec, String pin) throws SignatureCardException {
+ }
}
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 a88593bc..3c2273b9 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java
@@ -125,21 +125,20 @@ public interface SignatureCard {
/**
*
+ * @param pinSpec descriptor which pin to verify
* @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;
+ public int verifyPIN(PINSpec pinSpec, String pin)
+ throws LockedException, NotActivatedException, SignatureCardException;
- public void changePIN(byte kid, byte[] contextAID,
- String oldPIN, String newPIN)
- throws SignatureCardException, VerificationFailedException;
+ public void changePIN(PINSpec pinSpec, String oldPIN, String newPIN)
+ throws LockedException, VerificationFailedException, NotActivatedException, SignatureCardException;
- public void activatePIN(byte kid, byte[] contextAID,
- String pin)
+ public void activatePIN(PINSpec pinSpec, String pin)
throws SignatureCardException;
/**