diff options
Diffstat (limited to 'smcc/src/main/java/at/gv')
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; |