From 32d17447a258188b2d534bcb0bf65a659ba7b7d0 Mon Sep 17 00:00:00 2001 From: mcentner Date: Fri, 29 Aug 2008 12:11:34 +0000 Subject: Initial import. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@1 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 310 +++++++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java new file mode 100644 index 00000000..7269ba7f --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -0,0 +1,310 @@ +//Copyright (C) 2002 IAIK +//http://jce.iaik.at +// +//Copyright (C) 2003 Stiftung Secure Information and +// Communication Technologies SIC +//http://www.sic.st +// +//All rights reserved. +// +//This source is provided for inspection purposes and recompilation only, +//unless specified differently in a contract with IAIK. This source has to +//be kept in strict confidence and must not be disclosed to any third party +//under any circumstances. Redistribution in source and binary forms, with +//or without modification, are permitted in any case! +// +//THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +//FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +//DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +//OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +//OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +//SUCH DAMAGE. +// +// +package at.gv.egiz.smcc; + +import java.nio.charset.Charset; + +import javax.smartcardio.CardChannel; +import javax.smartcardio.CardException; +import javax.smartcardio.CommandAPDU; +import javax.smartcardio.ResponseAPDU; + +public class ACOSCard extends AbstractSignatureCard implements SignatureCard { + + public static final byte[] AID_DEC = new byte[] { (byte) 0xA0, (byte) 0x00, + (byte) 0x00, (byte) 0x01, (byte) 0x18, (byte) 0x45, (byte) 0x4E }; + + public static final byte[] DF_DEC = new byte[] { (byte) 0xdf, (byte) 0x71 }; + + public static final byte[] AID_SIG = new byte[] { (byte) 0xA0, (byte) 0x00, + (byte) 0x00, (byte) 0x01, (byte) 0x18, (byte) 0x45, (byte) 0x43 }; + + public static final byte[] DF_SIG = new byte[] { (byte) 0xdf, (byte) 0x70 }; + + public static final byte[] EF_C_CH_EKEY = new byte[] { (byte) 0xc0, + (byte) 0x01 }; + + public static final int EF_C_CH_EKEY_MAX_SIZE = 2000; + + public static final byte[] EF_C_CH_DS = new byte[] { (byte) 0xc0, (byte) 0x02 }; + + public static final int EF_C_CH_DS_MAX_SIZE = 2000; + + public static final byte[] EF_PK_CH_EKEY = new byte[] { (byte) 0xb0, + (byte) 0x01 }; + + public static final byte[] EF_INFOBOX = new byte[] { (byte) 0xc0, (byte) 0x02 }; + + public static final int EF_INFOBOX_MAX_SIZE = 1500; + + public static final byte KID_PIN_SIG = (byte) 0x81; + + public static final byte KID_PIN_DEC = (byte) 0x81; + + public static final byte KID_PIN_INF = (byte) 0x83; + + public static final byte[] DST_SIG = new byte[] { (byte) 0x84, (byte) 0x01, // tag + // , + // length + // ( + // key + // ID + // ) + (byte) 0x88, // SK.CH.SIGN + (byte) 0x80, (byte) 0x01, // tag, length (algorithm ID) + (byte) 0x14 // ECDSA + }; + + public static final byte[] DST_DEC = new byte[] { (byte) 0x84, (byte) 0x01, // tag + // , + // length + // ( + // key + // ID + // ) + (byte) 0x88, // SK.CH.EKEY + (byte) 0x80, (byte) 0x01, // tag, length (algorithm ID) + (byte) 0x01 // RSA // TODO: Not verified yet + }; + + public ACOSCard() { + super("at/gv/egiz/smcc/ACOSCard"); + } + + byte[] selectFileAID(byte[] fid) throws CardException, SignatureCardException { + CardChannel channel = getCardChannel(); + ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0xA4, 0x04, + 0x00, fid, 256)); + if (resp.getSW() != 0x9000) { + throw new SignatureCardException("Failed to select file (AID=" + + toString(fid) + "): SW=" + Integer.toHexString(resp.getSW()) + "."); + } else { + return resp.getBytes(); + } + } + + byte[] selectFileFID(byte[] fid) throws CardException, SignatureCardException { + CardChannel channel = getCardChannel(); + ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0xA4, 0x00, + 0x00, fid, 256)); + if (resp.getSW() == 0x6a82) { + throw new SignatureCardException("Failed to select file (FID=" + + toString(fid) + "): SW=" + Integer.toHexString(resp.getSW()) + ")"); + } else { + return resp.getBytes(); + } + } + + /** + * + * @param pinProvider + * @param spec + * the PIN spec to be given to the pinProvider + * @param kid + * the KID (key identifier) of the PIN to be verified + * @param kfpc + * acutal value of the KFCP (key fault presentation counter) or less + * than 0 if actual value is unknown + * + * @return -1 if the PIN has been verifyed successfully, or else the new value + * of the KFCP (key fault presentation counter) + * + * @throws CancelledException + * if the user canceld the operation + * @throws javax.smartcardio.CardException + * @throws at.gv.egiz.smcc.SignatureCardException + */ + int verifyPIN(PINProvider pinProvider, PINSpec spec, byte kid, int kfpc) + throws CardException, CancelledException, SignatureCardException { + + CardChannel channel = getCardChannel(); + + // get PIN + String pin = pinProvider.providePIN(spec, kfpc); + if (pin == null) { + // User canceld operation + // throw new CancelledException("User canceld PIN entry"); + return -2; + } + + logger.finest("PIN=" + pin); + + byte[] asciiPIN = pin.getBytes(Charset.forName("ASCII")); + byte[] encodedPIN = new byte[8]; + System.arraycopy(asciiPIN, 0, encodedPIN, 0, Math.min(asciiPIN.length, + encodedPIN.length)); + + ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00, + kid, encodedPIN)); + if (resp.getSW1() == (byte) 0x63 && resp.getSW2() >> 4 == (byte) 0xc) { + return resp.getSW2() & (byte) 0x0f; + } else if (resp.getSW() == 0x6983) { + // PIN blocked + throw new SignatureCardException(spec.getLocalizedName() + " blocked."); + } else if (resp.getSW() != 0x9000) { + throw new SignatureCardException("Failed to verify pin: SW=" + + Integer.toHexString(resp.getSW()) + "."); + } else { + return -1; + } + + } + + void mseSetDST(byte[] dst) throws CardException, SignatureCardException { + CardChannel channel = getCardChannel(); + ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x22, 0x81, + 0xB6, dst)); + if (resp.getSW() != 0x9000) { + throw new SignatureCardException("MSE:SET DST failed: SW=" + + Integer.toHexString(resp.getSW())); + } + } + + void psoHash(byte[] hash) throws CardException, SignatureCardException { + CardChannel channel = getCardChannel(); + ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x2A, 0x90, + 0x81, hash)); + if (resp.getSW() != 0x9000) { + throw new SignatureCardException("PSO:HASH failed: SW=" + + Integer.toHexString(resp.getSW())); + } + } + + byte[] psoComputDigitalSiganture() throws CardException, + SignatureCardException { + CardChannel channel = getCardChannel(); + ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x2A, 0x9E, + 0x9A, 256)); + if (resp.getSW() != 0x9000) { + throw new SignatureCardException( + "PSO: COMPUTE DIGITAL SIGNATRE failed: SW=" + + Integer.toHexString(resp.getSW())); + } else { + return resp.getData(); + } + } + + public byte[] getCertificate(KeyboxName keyboxName) + throws SignatureCardException { + + if (keyboxName == KeyboxName.SECURE_SIGNATURE_KEYPAIR) { + return readTLVFile(AID_SIG, EF_C_CH_DS, EF_C_CH_DS_MAX_SIZE); + } else if (keyboxName == KeyboxName.CERITIFIED_KEYPAIR) { + return readTLVFile(AID_DEC, EF_C_CH_EKEY, EF_C_CH_EKEY_MAX_SIZE); + } else { + throw new IllegalArgumentException("Keybox " + keyboxName + + " not supported."); + } + + } + + public byte[] getInfobox(String infobox, PINProvider provider, String domainId) + throws SignatureCardException { + + if ("IdentityLink".equals(infobox)) { + + PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString( + "inf.pin.name")); + try { + byte[] res = readTLVFilePIN(AID_DEC, EF_INFOBOX, KID_PIN_INF, provider, + spec, EF_INFOBOX_MAX_SIZE); + return res; + } catch (Exception e) { + throw new SecurityException(e); + } + + } else { + throw new IllegalArgumentException("Infobox '" + infobox + + "' not supported."); + } + + } + + public String toString() { + return "a-sign premium"; + } + + public byte[] createSignature(byte[] hash, KeyboxName keyboxName, + PINProvider provider) throws SignatureCardException { + + if (hash.length != 20) { + throw new IllegalArgumentException("Hash value must be of length 20"); + } + + byte[] fid; + byte kid; + byte[] dst; + PINSpec spec; + if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) { + fid = DF_SIG; + kid = KID_PIN_SIG; + dst = DST_SIG; + spec = new PINSpec(6, 10, "[0-9]", getResourceBundle().getString( + "sig.pin.name")); + + } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) { + fid = DF_DEC; + kid = KID_PIN_DEC; + dst = DST_DEC; + spec = new PINSpec(6, 10, "[0-9]", getResourceBundle().getString( + "dec.pin.name")); + + } else { + throw new IllegalArgumentException("KeyboxName '" + keyboxName + + "' not supported."); + } + + try { + + // SELECT DF + selectFileFID(fid); + // VERIFY + int kfpc = -1; + while (true) { + kfpc = verifyPIN(provider, spec, kid, kfpc); + if (kfpc < -1) { + return null; + } else if (kfpc < 0) { + break; + } + } + // MSE: SET DST + mseSetDST(dst); + // PSO: HASH + psoHash(hash); + // PSO: COMPUTE DIGITAL SIGNATURE + byte[] rs = psoComputDigitalSiganture(); + + return rs; + + } catch (CardException e) { + throw new SignatureCardException("Failed to create signature.", e); + } + } +} -- cgit v1.2.3 From 62dffe15b09010e64a886a936d549239f441cd31 Mon Sep 17 00:00:00 2001 From: wbauer Date: Fri, 10 Oct 2008 09:12:11 +0000 Subject: added a reset command git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@96 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 2 -- 1 file changed, 2 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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 7269ba7f..abe086ee 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -153,8 +153,6 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { return -2; } - logger.finest("PIN=" + pin); - byte[] asciiPIN = pin.getBytes(Charset.forName("ASCII")); byte[] encodedPIN = new byte[8]; System.arraycopy(asciiPIN, 0, encodedPIN, 0, Math.min(asciiPIN.length, -- cgit v1.2.3 From c2ae3db1bc6dcb8ba3eb3461c05e293917c004ca Mon Sep 17 00:00:00 2001 From: mcentner Date: Thu, 30 Oct 2008 10:33:29 +0000 Subject: Updated SMCC to use exclusive access and to throw exceptions upon locked or not activated cards. Improved locale support in the security layer request and response processing. Fixed issue in STAL which prevented the use of RSA-SHA1 signatures. Added additional parameters to the applet test pages. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@128 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 348 ++++++++++++++--------- 1 file changed, 208 insertions(+), 140 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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 abe086ee..9e56701f 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -30,12 +30,18 @@ package at.gv.egiz.smcc; import java.nio.charset.Charset; +import javax.smartcardio.Card; import javax.smartcardio.CardChannel; import javax.smartcardio.CardException; import javax.smartcardio.CommandAPDU; import javax.smartcardio.ResponseAPDU; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + public class ACOSCard extends AbstractSignatureCard implements SignatureCard { + + private static Log log = LogFactory.getLog(ACOSCard.class); public static final byte[] AID_DEC = new byte[] { (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x18, (byte) 0x45, (byte) 0x4E }; @@ -97,7 +103,145 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { super("at/gv/egiz/smcc/ACOSCard"); } - byte[] selectFileAID(byte[] fid) throws CardException, SignatureCardException { + /* (non-Javadoc) + * @see at.gv.egiz.smcc.SignatureCard#getCertificate(at.gv.egiz.smcc.SignatureCard.KeyboxName) + */ + public byte[] getCertificate(KeyboxName keyboxName) + throws SignatureCardException { + + byte[] aid; + byte[] efc; + int maxsize; + if (keyboxName == KeyboxName.SECURE_SIGNATURE_KEYPAIR) { + aid = AID_SIG; + efc = EF_C_CH_DS; + maxsize = EF_C_CH_DS_MAX_SIZE; + } else if (keyboxName == KeyboxName.CERITIFIED_KEYPAIR) { + aid = AID_DEC; + efc = EF_C_CH_EKEY; + maxsize = EF_C_CH_EKEY_MAX_SIZE; + } else { + throw new IllegalArgumentException("Keybox " + keyboxName + + " not supported."); + } + + log.debug("Get certificate for keybox '" + keyboxName.getKeyboxName() + "'" + + " (AID=" + toString(aid) + " EF=" + toString(efc) + ")."); + + try { + Card card = getCardChannel().getCard(); + try { + card.beginExclusive(); + return readTLVFile(aid, efc, maxsize + 15000); + } catch (FileNotFoundException e) { + // if certificate is not present, + // the citizen card application has not been activated + throw new NotActivatedException(); + } finally { + card.endExclusive(); + } + } catch (CardException e) { + throw new SignatureCardException("Failed to get exclusive card access."); + } + + + } + + /* (non-Javadoc) + * @see at.gv.egiz.smcc.SignatureCard#getInfobox(java.lang.String, at.gv.egiz.smcc.PINProvider, java.lang.String) + */ + public byte[] getInfobox(String infobox, PINProvider provider, String domainId) + throws SignatureCardException { + + if ("IdentityLink".equals(infobox)) { + + PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name")); + + try { + Card card = getCardChannel().getCard(); + try { + card.beginExclusive(); + return readTLVFilePIN(AID_DEC, EF_INFOBOX, KID_PIN_INF, provider, + spec, EF_INFOBOX_MAX_SIZE); + } catch (FileNotFoundException e) { + // if certificate is not present, + // the citizen card application has not been activated + throw new NotActivatedException(); + } finally { + card.endExclusive(); + } + } catch (CardException e) { + throw new SignatureCardException("Failed to get exclusive card access."); + } + + } else { + throw new IllegalArgumentException("Infobox '" + infobox + + "' not supported."); + } + + } + + public byte[] createSignature(byte[] hash, KeyboxName keyboxName, + PINProvider provider) throws SignatureCardException { + + if (hash.length != 20) { + throw new IllegalArgumentException("Hash value must be of length 20."); + } + + try { + Card card = getCardChannel().getCard(); + try { + card.beginExclusive(); + + if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) { + + // SELECT DF + selectFileFID(DF_SIG); + // VERIFY + verifyPIN(provider, new PINSpec(6, 10, "[0-9]", getResourceBundle() + .getString("sig.pin.name")), KID_PIN_SIG); + // MSE: SET DST + mseSetDST(0x81, 0xb6, DST_SIG); + // PSO: HASH + psoHash(hash); + // PSO: COMPUTE DIGITAL SIGNATURE + return psoComputDigitalSiganture(); + + } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) { + + // SELECT DF + selectFileFID(DF_DEC); + // VERIFY + verifyPIN(provider, new PINSpec(4, 4, "[0-9]", getResourceBundle() + .getString("dec.pin.name")), KID_PIN_DEC); + // MSE: SET DST + mseSetDST(0x41, 0xa4, DST_DEC); + // INTERNAL AUTHENTICATE + return internalAuthenticate(hash); + + + // 00 88 10 00 23 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 54 26 F0 EA AF EA F0 4E D4 A1 AD BF 66 D4 A5 9B 45 6F AF 79 00 + // 00 88 10 00 23 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 DF 8C AB 8F E2 AD AC 7B 5A AF BE E9 44 5E 95 99 FA AF 2F 48 00 + + } else { + throw new IllegalArgumentException("KeyboxName '" + keyboxName + + "' not supported."); + } + + } catch (FileNotFoundException e) { + // if certificate is not present, + // the citizen card application has not been activated + throw new NotActivatedException(); + } finally { + card.endExclusive(); + } + } catch (CardException e) { + throw new SignatureCardException("Failed to get exclusive card access."); + } + + } + + protected byte[] selectFileAID(byte[] fid) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0xA4, 0x04, 0x00, fid, 256)); @@ -109,18 +253,40 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } } - byte[] selectFileFID(byte[] fid) throws CardException, SignatureCardException { + protected ResponseAPDU selectFileFID(byte[] fid) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); - ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0xA4, 0x00, + return transmit(channel, new CommandAPDU(0x00, 0xA4, 0x00, 0x00, fid, 256)); - if (resp.getSW() == 0x6a82) { - throw new SignatureCardException("Failed to select file (FID=" - + toString(fid) + "): SW=" + Integer.toHexString(resp.getSW()) + ")"); + } + + protected int verifyPIN(String pin, byte kid) throws CardException, SignatureCardException { + + CardChannel channel = getCardChannel(); + + byte[] asciiPIN = pin.getBytes(Charset.forName("ASCII")); + byte[] encodedPIN = new byte[8]; + System.arraycopy(asciiPIN, 0, encodedPIN, 0, Math.min(asciiPIN.length, + encodedPIN.length)); + + ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00, + kid, encodedPIN), 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 NotActivatedException(); + } else if (resp.getSW() == 0x9000) { + return -1; } else { - return resp.getBytes(); + throw new SignatureCardException("Failed to verify pin: SW=" + + Integer.toHexString(resp.getSW()) + "."); } - } + } + /** * * @param pinProvider @@ -128,56 +294,30 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { * the PIN spec to be given to the pinProvider * @param kid * the KID (key identifier) of the PIN to be verified - * @param kfpc - * acutal value of the KFCP (key fault presentation counter) or less - * than 0 if actual value is unknown - * - * @return -1 if the PIN has been verifyed successfully, or else the new value - * of the KFCP (key fault presentation counter) - * * @throws CancelledException * if the user canceld the operation * @throws javax.smartcardio.CardException * @throws at.gv.egiz.smcc.SignatureCardException */ - int verifyPIN(PINProvider pinProvider, PINSpec spec, byte kid, int kfpc) + protected void verifyPIN(PINProvider pinProvider, PINSpec spec, byte kid) throws CardException, CancelledException, SignatureCardException { - CardChannel channel = getCardChannel(); - - // get PIN - String pin = pinProvider.providePIN(spec, kfpc); - if (pin == null) { - // User canceld operation - // throw new CancelledException("User canceld PIN entry"); - return -2; - } - - byte[] asciiPIN = pin.getBytes(Charset.forName("ASCII")); - byte[] encodedPIN = new byte[8]; - System.arraycopy(asciiPIN, 0, encodedPIN, 0, Math.min(asciiPIN.length, - encodedPIN.length)); - - ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00, - kid, encodedPIN)); - if (resp.getSW1() == (byte) 0x63 && resp.getSW2() >> 4 == (byte) 0xc) { - return resp.getSW2() & (byte) 0x0f; - } else if (resp.getSW() == 0x6983) { - // PIN blocked - throw new SignatureCardException(spec.getLocalizedName() + " blocked."); - } else if (resp.getSW() != 0x9000) { - throw new SignatureCardException("Failed to verify pin: SW=" - + Integer.toHexString(resp.getSW()) + "."); - } else { - return -1; - } - + int retries = -1; + do { + String pin = pinProvider.providePIN(spec, retries); + if (pin == null) { + // user canceled operation + throw new CancelledException("User canceled operation"); + } + retries = verifyPIN(pin, kid); + } while (retries > 0); + } - - void mseSetDST(byte[] dst) throws CardException, SignatureCardException { + + void mseSetDST(int p1, int p2, byte[] dst) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); - ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x22, 0x81, - 0xB6, dst)); + ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x22, p1, + p2, dst)); if (resp.getSW() != 0x9000) { throw new SignatureCardException("MSE:SET DST failed: SW=" + Integer.toHexString(resp.getSW())); @@ -207,102 +347,30 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { return resp.getData(); } } - - public byte[] getCertificate(KeyboxName keyboxName) - throws SignatureCardException { - - if (keyboxName == KeyboxName.SECURE_SIGNATURE_KEYPAIR) { - return readTLVFile(AID_SIG, EF_C_CH_DS, EF_C_CH_DS_MAX_SIZE); - } else if (keyboxName == KeyboxName.CERITIFIED_KEYPAIR) { - return readTLVFile(AID_DEC, EF_C_CH_EKEY, EF_C_CH_EKEY_MAX_SIZE); - } else { - throw new IllegalArgumentException("Keybox " + keyboxName - + " not supported."); - } - - } - - public byte[] getInfobox(String infobox, PINProvider provider, String domainId) - throws SignatureCardException { - - if ("IdentityLink".equals(infobox)) { - - PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString( - "inf.pin.name")); - try { - byte[] res = readTLVFilePIN(AID_DEC, EF_INFOBOX, KID_PIN_INF, provider, - spec, EF_INFOBOX_MAX_SIZE); - return res; - } catch (Exception e) { - throw new SecurityException(e); - } - + + byte[] internalAuthenticate(byte[] hash) throws CardException, SignatureCardException { + byte[] digestInfo = new byte[] { + (byte) 0x30, (byte) 0x21, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x05, (byte) 0x2B, (byte) 0x0E, + (byte) 0x03, (byte) 0x02, (byte) 0x1A, (byte) 0x05, (byte) 0x00, (byte) 0x04 + }; + + byte[] data = new byte[digestInfo.length + hash.length + 1]; + + System.arraycopy(digestInfo, 0, data, 0, digestInfo.length); + data[digestInfo.length] = (byte) hash.length; + System.arraycopy(hash, 0, data, digestInfo.length + 1, hash.length); + + CardChannel channel = getCardChannel(); + + ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x88, 0x10, 0x00, data, 256)); + if (resp.getSW() != 0x9000) { + throw new SignatureCardException("INTERNAL AUTHENTICATE failed: SW=" + Integer.toHexString(resp.getSW())); } else { - throw new IllegalArgumentException("Infobox '" + infobox - + "' not supported."); + return resp.getData(); } - } public String toString() { return "a-sign premium"; } - - public byte[] createSignature(byte[] hash, KeyboxName keyboxName, - PINProvider provider) throws SignatureCardException { - - if (hash.length != 20) { - throw new IllegalArgumentException("Hash value must be of length 20"); - } - - byte[] fid; - byte kid; - byte[] dst; - PINSpec spec; - if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) { - fid = DF_SIG; - kid = KID_PIN_SIG; - dst = DST_SIG; - spec = new PINSpec(6, 10, "[0-9]", getResourceBundle().getString( - "sig.pin.name")); - - } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) { - fid = DF_DEC; - kid = KID_PIN_DEC; - dst = DST_DEC; - spec = new PINSpec(6, 10, "[0-9]", getResourceBundle().getString( - "dec.pin.name")); - - } else { - throw new IllegalArgumentException("KeyboxName '" + keyboxName - + "' not supported."); - } - - try { - - // SELECT DF - selectFileFID(fid); - // VERIFY - int kfpc = -1; - while (true) { - kfpc = verifyPIN(provider, spec, kid, kfpc); - if (kfpc < -1) { - return null; - } else if (kfpc < 0) { - break; - } - } - // MSE: SET DST - mseSetDST(dst); - // PSO: HASH - psoHash(hash); - // PSO: COMPUTE DIGITAL SIGNATURE - byte[] rs = psoComputDigitalSiganture(); - - return rs; - - } catch (CardException e) { - throw new SignatureCardException("Failed to create signature.", e); - } - } } -- cgit v1.2.3 From e4a47aa9393d74647f4f0c66b54dc4519fed492f Mon Sep 17 00:00:00 2001 From: clemenso Date: Tue, 11 Nov 2008 12:16:00 +0000 Subject: Interrupt in waitForAction (applet closed) git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@162 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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 9e56701f..2baff834 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -106,8 +106,9 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { /* (non-Javadoc) * @see at.gv.egiz.smcc.SignatureCard#getCertificate(at.gv.egiz.smcc.SignatureCard.KeyboxName) */ + @Override public byte[] getCertificate(KeyboxName keyboxName) - throws SignatureCardException { + throws SignatureCardException, InterruptedException { byte[] aid; byte[] efc; @@ -150,8 +151,9 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { /* (non-Javadoc) * @see at.gv.egiz.smcc.SignatureCard#getInfobox(java.lang.String, at.gv.egiz.smcc.PINProvider, java.lang.String) */ + @Override public byte[] getInfobox(String infobox, PINProvider provider, String domainId) - throws SignatureCardException { + throws SignatureCardException, InterruptedException { if ("IdentityLink".equals(infobox)) { @@ -181,8 +183,9 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } + @Override public byte[] createSignature(byte[] hash, KeyboxName keyboxName, - PINProvider provider) throws SignatureCardException { + PINProvider provider) throws SignatureCardException, InterruptedException { if (hash.length != 20) { throw new IllegalArgumentException("Hash value must be of length 20."); @@ -299,8 +302,9 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { * @throws javax.smartcardio.CardException * @throws at.gv.egiz.smcc.SignatureCardException */ + @Override protected void verifyPIN(PINProvider pinProvider, PINSpec spec, byte kid) - throws CardException, CancelledException, SignatureCardException { + throws CardException, CancelledException, SignatureCardException, InterruptedException { int retries = -1; do { -- cgit v1.2.3 From 887f6727479f3ae3d89a08ba619f9382b450e4c1 Mon Sep 17 00:00:00 2001 From: mcentner Date: Fri, 12 Dec 2008 11:48:47 +0000 Subject: Updated SMCC to support non-blocking PIN entry. Added SV-Personendaten infobox implementation. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@248 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 320 +++++++++++++---------- 1 file changed, 175 insertions(+), 145 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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 2baff834..6d96599c 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -30,7 +30,6 @@ package at.gv.egiz.smcc; import java.nio.charset.Charset; -import javax.smartcardio.Card; import javax.smartcardio.CardChannel; import javax.smartcardio.CardException; import javax.smartcardio.CommandAPDU; @@ -110,41 +109,47 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { public byte[] getCertificate(KeyboxName keyboxName) throws SignatureCardException, InterruptedException { - byte[] aid; - byte[] efc; - int maxsize; - if (keyboxName == KeyboxName.SECURE_SIGNATURE_KEYPAIR) { - aid = AID_SIG; - efc = EF_C_CH_DS; - maxsize = EF_C_CH_DS_MAX_SIZE; - } else if (keyboxName == KeyboxName.CERITIFIED_KEYPAIR) { - aid = AID_DEC; - efc = EF_C_CH_EKEY; - maxsize = EF_C_CH_EKEY_MAX_SIZE; - } else { - throw new IllegalArgumentException("Keybox " + keyboxName - + " not supported."); - } - - log.debug("Get certificate for keybox '" + keyboxName.getKeyboxName() + "'" + - " (AID=" + toString(aid) + " EF=" + toString(efc) + ")."); - try { - Card card = getCardChannel().getCard(); - try { - card.beginExclusive(); - return readTLVFile(aid, efc, maxsize + 15000); - } catch (FileNotFoundException e) { - // if certificate is not present, - // the citizen card application has not been activated - throw new NotActivatedException(); - } finally { - card.endExclusive(); + + if (keyboxName == KeyboxName.SECURE_SIGNATURE_KEYPAIR) { + + try { + getCard().beginExclusive(); + byte[] certificate = readTLVFile(AID_SIG, EF_C_CH_DS, EF_C_CH_DS_MAX_SIZE); + if (certificate == null) { + throw new NotActivatedException(); + } + return certificate; + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } finally { + getCard().endExclusive(); + } + + } else if (keyboxName == KeyboxName.CERITIFIED_KEYPAIR) { + + try { + getCard().beginExclusive(); + byte[] certificate = readTLVFile(AID_DEC, EF_C_CH_EKEY, EF_C_CH_EKEY_MAX_SIZE); + if (certificate == null) { + throw new NotActivatedException(); + } + return certificate; + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } finally { + getCard().endExclusive(); + } + + } else { + throw new IllegalArgumentException("Keybox " + keyboxName + + " not supported."); } + } catch (CardException e) { - throw new SignatureCardException("Failed to get exclusive card access."); + log.warn(e); + throw new SignatureCardException("Failed to access card.", e); } - } @@ -155,30 +160,47 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { public byte[] getInfobox(String infobox, PINProvider provider, String domainId) throws SignatureCardException, InterruptedException { - if ("IdentityLink".equals(infobox)) { - - PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name")); - - try { - Card card = getCardChannel().getCard(); - try { - card.beginExclusive(); - return readTLVFilePIN(AID_DEC, EF_INFOBOX, KID_PIN_INF, provider, - spec, EF_INFOBOX_MAX_SIZE); - } catch (FileNotFoundException e) { - // if certificate is not present, - // the citizen card application has not been activated - throw new NotActivatedException(); - } finally { - card.endExclusive(); - } - } catch (CardException e) { - throw new SignatureCardException("Failed to get exclusive card access."); + try { + if ("IdentityLink".equals(infobox)) { + + PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name")); + + int retries = -1; + String pin = null; + boolean pinRequiered = false; + + do { + if (pinRequiered) { + pin = provider.providePIN(spec, retries); + if (pin == null) { + throw new CancelledException(); + } + } + try { + getCard().beginExclusive(); + return readTLVFile(AID_DEC, EF_INFOBOX, pin, KID_PIN_INF, EF_INFOBOX_MAX_SIZE); + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } catch (SecurityStatusNotSatisfiedException e) { + pinRequiered = true; + } catch (VerificationFailedException e) { + pinRequiered = true; + retries = e.getRetries(); + } finally { + getCard().endExclusive(); + } + } while (retries != 0); + + throw new LockedException(); + + } else { + throw new IllegalArgumentException("Infobox '" + infobox + + "' not supported."); } - - } else { - throw new IllegalArgumentException("Infobox '" + infobox - + "' not supported."); + + } catch (CardException e) { + log.warn(e); + throw new SignatureCardException("Failed to access card.", e); } } @@ -192,68 +214,103 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } try { - Card card = getCardChannel().getCard(); - try { - card.beginExclusive(); - - if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) { - - // SELECT DF - selectFileFID(DF_SIG); - // VERIFY - verifyPIN(provider, new PINSpec(6, 10, "[0-9]", getResourceBundle() - .getString("sig.pin.name")), KID_PIN_SIG); - // MSE: SET DST - mseSetDST(0x81, 0xb6, DST_SIG); - // PSO: HASH - psoHash(hash); - // PSO: COMPUTE DIGITAL SIGNATURE - return psoComputDigitalSiganture(); - } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) { - - // SELECT DF - selectFileFID(DF_DEC); - // VERIFY - verifyPIN(provider, new PINSpec(4, 4, "[0-9]", getResourceBundle() - .getString("dec.pin.name")), KID_PIN_DEC); - // MSE: SET DST - mseSetDST(0x41, 0xa4, DST_DEC); - // INTERNAL AUTHENTICATE - return internalAuthenticate(hash); - - - // 00 88 10 00 23 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 54 26 F0 EA AF EA F0 4E D4 A1 AD BF 66 D4 A5 9B 45 6F AF 79 00 - // 00 88 10 00 23 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 DF 8C AB 8F E2 AD AC 7B 5A AF BE E9 44 5E 95 99 FA AF 2F 48 00 - - } else { - throw new IllegalArgumentException("KeyboxName '" + keyboxName - + "' not supported."); - } + if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) { + + PINSpec spec = new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name")); + + int retries = -1; + String pin = null; + + do { + pin = provider.providePIN(spec, retries); + if (pin == null) { + throw new CancelledException(); + } + try { + getCard().beginExclusive(); + + // SELECT DF + selectFileFID(DF_SIG); + // VERIFY + retries = verifyPIN(pin, KID_PIN_SIG); + if (retries != -1) { + throw new VerificationFailedException(retries); + } + // MSE: SET DST + mseSetDST(0x81, 0xb6, DST_SIG); + // PSO: HASH + psoHash(hash); + // PSO: COMPUTE DIGITAL SIGNATURE + return psoComputDigitalSiganture(); + + } catch (SecurityStatusNotSatisfiedException e) { + retries = verifyPIN(null, KID_PIN_SIG); + } catch (VerificationFailedException e) { + retries = e.getRetries(); + } finally { + getCard().endExclusive(); + } + } while (retries != 0); + + throw new LockedException(); + + + } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) { - } catch (FileNotFoundException e) { - // if certificate is not present, - // the citizen card application has not been activated - throw new NotActivatedException(); - } finally { - card.endExclusive(); + PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("dec.pin.name")); + + int retries = -1; + String pin = null; + boolean pinRequiered = false; + + do { + if (pinRequiered) { + pin = provider.providePIN(spec, retries); + if (pin == null) { + throw new CancelledException(); + } + } + try { + getCard().beginExclusive(); + + // SELECT DF + selectFileFID(DF_DEC); + // VERIFY + retries = verifyPIN(pin, KID_PIN_DEC); + if (retries != -1) { + throw new VerificationFailedException(retries); + } + // MSE: SET DST + mseSetDST(0x41, 0xa4, DST_DEC); + // INTERNAL AUTHENTICATE + return internalAuthenticate(hash); + + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } catch (SecurityStatusNotSatisfiedException e) { + pinRequiered = true; + retries = verifyPIN(null, KID_PIN_DEC); + } catch (VerificationFailedException e) { + pinRequiered = true; + retries = e.getRetries(); + } finally { + getCard().endExclusive(); + } + } while (retries != 0); + + throw new LockedException(); + + } else { + throw new IllegalArgumentException("KeyboxName '" + keyboxName + + "' not supported."); } + } catch (CardException e) { - throw new SignatureCardException("Failed to get exclusive card access."); - } - - } - - protected byte[] selectFileAID(byte[] fid) throws CardException, SignatureCardException { - CardChannel channel = getCardChannel(); - ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0xA4, 0x04, - 0x00, fid, 256)); - if (resp.getSW() != 0x9000) { - throw new SignatureCardException("Failed to select file (AID=" - + toString(fid) + "): SW=" + Integer.toHexString(resp.getSW()) + "."); - } else { - return resp.getBytes(); - } + log.warn(e); + throw new SignatureCardException("Failed to access card.", e); + } + } protected ResponseAPDU selectFileFID(byte[] fid) throws CardException, SignatureCardException { @@ -262,6 +319,7 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { 0x00, fid, 256)); } + @Override protected int verifyPIN(String pin, byte kid) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); @@ -290,35 +348,7 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } - /** - * - * @param pinProvider - * @param spec - * the PIN spec to be given to the pinProvider - * @param kid - * the KID (key identifier) of the PIN to be verified - * @throws CancelledException - * if the user canceld the operation - * @throws javax.smartcardio.CardException - * @throws at.gv.egiz.smcc.SignatureCardException - */ - @Override - protected void verifyPIN(PINProvider pinProvider, PINSpec spec, byte kid) - throws CardException, CancelledException, SignatureCardException, InterruptedException { - - int retries = -1; - do { - String pin = pinProvider.providePIN(spec, retries); - if (pin == null) { - // user canceled operation - throw new CancelledException("User canceled operation"); - } - retries = verifyPIN(pin, kid); - } while (retries > 0); - - } - - void mseSetDST(int p1, int p2, byte[] dst) throws CardException, SignatureCardException { + private void mseSetDST(int p1, int p2, byte[] dst) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x22, p1, p2, dst)); @@ -328,7 +358,7 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } } - void psoHash(byte[] hash) throws CardException, SignatureCardException { + private void psoHash(byte[] hash) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x2A, 0x90, 0x81, hash)); @@ -338,7 +368,7 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } } - byte[] psoComputDigitalSiganture() throws CardException, + private byte[] psoComputDigitalSiganture() throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x2A, 0x9E, @@ -352,7 +382,7 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } } - byte[] internalAuthenticate(byte[] hash) throws CardException, SignatureCardException { + private byte[] internalAuthenticate(byte[] hash) throws CardException, SignatureCardException { byte[] digestInfo = new byte[] { (byte) 0x30, (byte) 0x21, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x05, (byte) 0x2B, (byte) 0x0E, (byte) 0x03, (byte) 0x02, (byte) 0x1A, (byte) 0x05, (byte) 0x00, (byte) 0x04 -- cgit v1.2.3 From 8596426d5daf291618b5e407bc9f804aa217b24a Mon Sep 17 00:00:00 2001 From: clemenso Date: Wed, 11 Feb 2009 20:10:15 +0000 Subject: prepare for pin management git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@301 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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."); -- cgit v1.2.3 From 6576428966f1e3d688269a407b072fb01f9f7647 Mon Sep 17 00:00:00 2001 From: clemenso Date: Thu, 26 Feb 2009 19:39:00 +0000 Subject: 1.1 candidate (activation) git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@309 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 25 +++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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 13c57686..86223854 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -30,8 +30,6 @@ 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; @@ -41,7 +39,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class ACOSCard extends AbstractSignatureCard implements SignatureCard { - + private static Log log = LogFactory.getLog(ACOSCard.class); public static final byte[] AID_DEC = new byte[] { (byte) 0xA0, (byte) 0x00, @@ -100,8 +98,15 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { (byte) 0x01 // RSA // TODO: Not verified yet }; + private static final int PINSPEC_INF = 0; + private static final int PINSPEC_DEC = 1; + private static final int PINSPEC_SIG = 2; + public ACOSCard() { super("at/gv/egiz/smcc/ACOSCard"); + pinSpecs.add(PINSPEC_INF, new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name"), KID_PIN_INF, null)); + pinSpecs.add(PINSPEC_DEC, new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("dec.pin.name"), KID_PIN_DEC, null)); + pinSpecs.add(PINSPEC_SIG, new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name"), KID_PIN_SIG, null)); } /* (non-Javadoc) @@ -165,7 +170,8 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { try { if ("IdentityLink".equals(infobox)) { - PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name")); + PINSpec spec = pinSpecs.get(PINSPEC_INF); + //new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name")); int retries = -1; String pin = null; @@ -219,7 +225,8 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) { - PINSpec spec = new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name")); + PINSpec spec = pinSpecs.get(PINSPEC_SIG); + //new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name")); int retries = -1; String pin = null; @@ -260,7 +267,8 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) { - PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("dec.pin.name")); + PINSpec spec = pinSpecs.get(PINSPEC_DEC); + //new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("dec.pin.name")); int retries = -1; String pin = null; @@ -321,11 +329,6 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { 0x00, fid, 256)); } - @Override - 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 { -- cgit v1.2.3 From a8690cc956924e1d83b0c45d21995ee2e10fbba2 Mon Sep 17 00:00:00 2001 From: clemenso Date: Wed, 4 Mar 2009 16:44:34 +0000 Subject: 1.1-rc3 git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@311 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 42 +++++++++++++++++++----- 1 file changed, 33 insertions(+), 9 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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 86223854..57925240 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -28,6 +28,7 @@ // package at.gv.egiz.smcc; +import at.gv.egiz.smcc.util.SMCCHelper; import java.nio.charset.Charset; import javax.smartcardio.CardChannel; @@ -104,9 +105,12 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { public ACOSCard() { super("at/gv/egiz/smcc/ACOSCard"); - pinSpecs.add(PINSPEC_INF, new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name"), KID_PIN_INF, null)); - pinSpecs.add(PINSPEC_DEC, new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("dec.pin.name"), KID_PIN_DEC, null)); - pinSpecs.add(PINSPEC_SIG, new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name"), KID_PIN_SIG, null)); + pinSpecs.add(PINSPEC_INF, + new PINSpec(0, 8, "[0-9]", getResourceBundle().getString("inf.pin.name"), KID_PIN_INF, AID_DEC)); + pinSpecs.add(PINSPEC_DEC, + new PINSpec(0, 8, "[0-9]", getResourceBundle().getString("dec.pin.name"), KID_PIN_DEC, AID_DEC)); + pinSpecs.add(PINSPEC_SIG, + new PINSpec(0, 8, "[0-9]", getResourceBundle().getString("sig.pin.name"), KID_PIN_SIG, AID_SIG)); } /* (non-Javadoc) @@ -334,14 +338,13 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { CardChannel channel = getCardChannel(); - byte[] asciiPIN = pin.getBytes(Charset.forName("ASCII")); - byte[] encodedPIN = new byte[8]; - System.arraycopy(asciiPIN, 0, encodedPIN, 0, Math.min(asciiPIN.length, - encodedPIN.length)); - ResponseAPDU resp; try { - resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00, kid, encodedPIN), false); + if (pin != null) { + resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00, kid, encodePINBlock(pin)), false); + } else { + 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); @@ -419,7 +422,28 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } } + @Override public String toString() { return "a-sign premium"; } + + /** + * ASCII encoded pin, padded with 0x00 + * @param pin + * @return a 8 byte pin block + */ + @Override + public 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, + encodedPIN.length)); +// System.out.println("ASCII encoded PIN block: " + SMCCHelper.toString(encodedPIN)); + return encodedPIN; + } + + @Override + public void activatePIN(byte kid, byte[] contextAID, String pin) throws SignatureCardException { + throw new SignatureCardException("PIN activation not supported by this card"); + } } -- cgit v1.2.3 From e177419331b8849497d25d3eb1866c5dc715bc88 Mon Sep 17 00:00:00 2001 From: clemenso Date: Fri, 6 Mar 2009 14:53:37 +0000 Subject: 1.1-rc4 git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@312 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 82 ++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 7 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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); + } + } } -- cgit v1.2.3 From 2a1df5e58e44f8d77f34eb80df74e8c0d27caceb Mon Sep 17 00:00:00 2001 From: clemenso Date: Wed, 18 Mar 2009 22:27:28 +0000 Subject: 1.1-rc5 (pinProviderFactories, gui refactoring, signatureCard, secureViewer) git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@322 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 410 ++++++++++++++++------- 1 file changed, 286 insertions(+), 124 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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 c2c62fd8..01b9155b 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -29,9 +29,10 @@ package at.gv.egiz.smcc; import at.gv.egiz.smcc.util.SMCCHelper; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; import java.nio.charset.Charset; -import javax.smartcardio.Card; import javax.smartcardio.CardChannel; import javax.smartcardio.CardException; import javax.smartcardio.CommandAPDU; @@ -100,9 +101,9 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { (byte) 0x01 // RSA // TODO: Not verified yet }; - private static final int PINSPEC_INF = 0; - private static final int PINSPEC_DEC = 1; - private static final int PINSPEC_SIG = 2; + protected static final int PINSPEC_INF = 0; + protected static final int PINSPEC_DEC = 1; + protected static final int PINSPEC_SIG = 2; public ACOSCard() { super("at/gv/egiz/smcc/ACOSCard"); @@ -179,15 +180,12 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { //new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name")); int retries = -1; - String pin = null; + char[] pin = null; boolean pinRequiered = false; do { if (pinRequiered) { pin = provider.providePIN(spec, retries); - if (pin == null) { - throw new CancelledException(); - } } try { getCard().beginExclusive(); @@ -234,20 +232,17 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { //new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name")); int retries = -1; - String pin = null; + char[] pin = null; do { pin = provider.providePIN(spec, retries); - if (pin == null) { - throw new CancelledException(); - } try { getCard().beginExclusive(); // SELECT DF selectFileFID(DF_SIG); // VERIFY - retries = verifyPIN(pin, KID_PIN_SIG); + retries = verifyPIN(KID_PIN_SIG, pin); if (retries != -1) { throw new VerificationFailedException(retries); } @@ -259,7 +254,7 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { return psoComputDigitalSiganture(); } catch (SecurityStatusNotSatisfiedException e) { - retries = verifyPIN(null, KID_PIN_SIG); + retries = verifyPIN(KID_PIN_SIG); } catch (VerificationFailedException e) { retries = e.getRetries(); } finally { @@ -276,15 +271,12 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { //new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("dec.pin.name")); int retries = -1; - String pin = null; - boolean pinRequiered = false; + char[] pin = null; + boolean pinRequired = false; do { - if (pinRequiered) { + if (pinRequired) { pin = provider.providePIN(spec, retries); - if (pin == null) { - throw new CancelledException(); - } } try { getCard().beginExclusive(); @@ -292,7 +284,7 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { // SELECT DF selectFileFID(DF_DEC); // VERIFY - retries = verifyPIN(pin, KID_PIN_DEC); + retries = verifyPIN(KID_PIN_DEC, pin); if (retries != -1) { throw new VerificationFailedException(retries); } @@ -304,10 +296,10 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } catch (FileNotFoundException e) { throw new NotActivatedException(); } catch (SecurityStatusNotSatisfiedException e) { - pinRequiered = true; - retries = verifyPIN(null, KID_PIN_DEC); + pinRequired = true; + retries = verifyPIN(KID_PIN_DEC); } catch (VerificationFailedException e) { - pinRequiered = true; + pinRequired = true; retries = e.getRetries(); } finally { getCard().endExclusive(); @@ -328,48 +320,16 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } + //////////////////////////////////////////////////////////////////////// + // PROTECTED METHODS (assume exclusive card access) + //////////////////////////////////////////////////////////////////////// + protected ResponseAPDU selectFileFID(byte[] fid) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); return transmit(channel, new CommandAPDU(0x00, 0xA4, 0x00, 0x00, fid, 256)); } - @Override - protected int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException { - - CardChannel channel = getCardChannel(); - - ResponseAPDU resp; - try { - 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) { - // return number of possible retries - return resp.getSW2() & 0x0f; - } else if (resp.getSW() == 0x6983) { - throw new NotActivatedException(); - } else if (resp.getSW() == 0x9000) { - return -1; - } else { - throw new SignatureCardException("Failed to verify pin: SW=" - + Integer.toHexString(resp.getSW()) + "."); - } - } - private void mseSetDST(int p1, int p2, byte[] dst) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x22, p1, @@ -426,92 +386,294 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } } - @Override - public String toString() { - return "a-sign premium"; - } - /** - * ASCII encoded pin, padded with 0x00 - * @param pin - * @return a 8 byte pin block + * + * @param kid + * @return -1 */ - 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, - encodedPIN.length)); -// System.out.println("ASCII encoded PIN block: " + SMCCHelper.toString(encodedPIN)); - return encodedPIN; + @Override + protected int verifyPIN(byte kid) { + log.debug("VERIFY PIN without PIN BLOCK not supported by ACOS"); + return -1; } @Override - public void activatePIN(PINSpec pinSpec, String pin) throws SignatureCardException { - throw new SignatureCardException("PIN activation not supported by this card"); + protected int verifyPIN(byte kid, char[] pin) + throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException { + try { + byte[] sw; + if (ifdSupportsFeature(FEATURE_VERIFY_PIN_DIRECT)) { + log.debug("verify PIN on IFD"); + sw = transmitControlCommand( + ifdCtrlCmds.get(FEATURE_VERIFY_PIN_DIRECT), + getPINVerifyStructure(kid)); +// int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff; + } else { + byte[] pinBlock = encodePINBlock(pin); + CardChannel channel = getCardChannel(); + ResponseAPDU resp = transmit(channel, + new CommandAPDU(0x00, 0x20, 0x00, kid, pinBlock), false); + sw = new byte[2]; + sw[0] = (byte) resp.getSW1(); + sw[1] = (byte) resp.getSW2(); + } + + //6A 00 (falshe P1/P2) nicht in contextAID + //69 85 (nutzungsbedingungen nicht erfüllt) in DF_Sig und nicht sigpin + + if (sw[0] == (byte) 0x90 && sw[1] == (byte) 0x00) { + return -1; + } else if (sw[0] == (byte) 0x63 && sw[1] == (byte) 0xc0) { + throw new LockedException("[63:c0]"); + } else if (sw[0] == (byte) 0x63 && (sw[1] & 0xf0) >> 4 == 0xc) { + return sw[1] & 0x0f; + } else if (sw[0] == (byte) 0x69 && sw[1] == (byte) 0x83) { + //Authentisierungsmethode gesperrt + throw new NotActivatedException("[69:83]"); +// } else if (sw[0] == (byte) 0x69 && sw[1] == (byte) 0x84) { +// //referenzierte Daten sind reversibel gesperrt (invalidated) +// throw new NotActivatedException("[69:84]"); +// } else if (sw[0] == (byte) 0x69 && sw[1] == (byte) 0x85) { +// //Benutzungsbedingungen nicht erfüllt +// throw new NotActivatedException("[69:85]"); + } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x00) { + throw new TimeoutException("[64:00]"); + } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) { + throw new CancelledException("[64:01]"); + } + log.error("Failed to verify pin: SW=" + + SMCCHelper.toString(sw)); + throw new SignatureCardException(SMCCHelper.toString(sw)); + + } catch (CardException ex) { + log.error("smart card communication failed: " + ex.getMessage()); + throw new SignatureCardException("smart card communication failed: " + ex.getMessage(), ex); + } } /** * SCARD_E_NOT_TRANSACTED inf/dec PIN not active (pcsc crash) - * @param pinSpec - * @param oldPIN - * @param newPIN + * @param kid + * @param oldPin + * @param newPin + * @return * @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(); + protected int changePIN(byte kid, char[] oldPin, char[] newPin) + throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException { 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); + byte[] sw; + if (ifdSupportsFeature(FEATURE_MODIFY_PIN_DIRECT)) { + log.debug("modify PIN on IFD"); + sw = transmitControlCommand( + ifdCtrlCmds.get(FEATURE_MODIFY_PIN_DIRECT), + getPINModifyStructure(kid)); +// int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff; + } else { + 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); + CardChannel channel = getCardChannel(); - icc.endExclusive(); + ResponseAPDU resp = transmit(channel, + new CommandAPDU(0x00, 0x24, 0x00, kid, cmd), false); - log.debug("change pin returned SW=" + Integer.toHexString(responseAPDU.getSW())); + sw = new byte[2]; + sw[0] = (byte) resp.getSW1(); + sw[1] = (byte) resp.getSW2(); + } - 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) { + // activates pin (newPIN) if not active + if (sw[0] == (byte) 0x90 && sw[1] == (byte) 0x00) { + return -1; + } else if (sw[0] == (byte) 0x63 && sw[1] == (byte) 0xc0) { + throw new LockedException("[63:c0]"); + } else if (sw[0] == (byte) 0x63 && (sw[1] & 0xf0) >> 4 == 0xc) { + return sw[1] & 0x0f; + } else if (sw[0] == (byte) 0x69 && sw[1] == (byte) 0x83) { + //Authentisierungsmethode gesperrt // 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); + throw new NotActivatedException("[69:83]"); + } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x00) { + throw new TimeoutException("[64:00]"); + } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) { + throw new CancelledException("[64:01]"); } + log.error("Failed to change pin: SW=" + + SMCCHelper.toString(sw)); + throw new SignatureCardException(SMCCHelper.toString(sw)); + } catch (CardException ex) { - log.error("Failed to change " + pinSpec.getLocalizedName() + - ": " + ex.getMessage()); - throw new SignatureCardException(ex.getMessage(), ex); + log.error("smart card communication failed: " + ex.getMessage()); + throw new SignatureCardException("smart card communication failed: " + ex.getMessage(), ex); } } + + /** + * throws SignatureCardException (PIN activation not supported by ACOS) + * @throws at.gv.egiz.smcc.SignatureCardException + */ + @Override + public void activatePIN(byte kid, char[] pin) + throws SignatureCardException { + log.error("ACTIVATE PIN not supported by ACOS"); + throw new SignatureCardException("PIN activation not supported by this card"); + } + + /** + * ASCII encoded pin, padded with 0x00 + * @param pin + * @return a 8 byte pin block + */ + @Override + protected byte[] encodePINBlock(char[] pin) { +// byte[] asciiPIN = new String(pin).getBytes(Charset.forName("ASCII")); + CharBuffer chars = CharBuffer.wrap(pin); + ByteBuffer bytes = Charset.forName("ASCII").encode(chars); + byte[] asciiPIN = bytes.array(); + byte[] encodedPIN = new byte[8]; + System.arraycopy(asciiPIN, 0, encodedPIN, 0, Math.min(asciiPIN.length, + encodedPIN.length)); +// System.out.println("ASCII encoded PIN block: " + SMCCHelper.toString(encodedPIN)); + return encodedPIN; + } + + private byte[] getPINVerifyStructure(byte kid) { + + byte bTimeOut = (byte) 00; // Default time out + byte bTimeOut2 = (byte) 00; // Default time out + byte bmFormatString = (byte) 0x82; // 1 0001 0 01 + // ^------------ System unit = byte + // ^^^^------- PIN position in the frame = 1 byte + // ^----- PIN justification left + // ^^-- BCD format + // 1 0000 0 10 + // ^^-- ASCII format + byte bmPINBlockString = (byte) 0x08; // 0100 0111 + // ^^^^--------- PIN length size: 4 bits + // ^^^^---- Length PIN = 7 bytes + byte bmPINLengthFormat = (byte) 0x04; // 000 0 0100 + // ^-------- System bit units is bit + // ^^^^--- PIN length is at the 4th position bit + byte wPINMaxExtraDigitL = (byte) 0x04; // Max=4 digits + byte wPINMaxExtraDigitH = (byte) 0x04; // Min=4 digits + byte bEntryValidationCondition = 0x02; // Max size reach or Validation key pressed + byte bNumberMessage = (byte) 0x00; // No message + byte wLangIdL = (byte) 0x0C; // - English? + byte wLangIdH = (byte) 0x04; // \ + byte bMsgIndex = (byte) 0x00; // Default Msg + + byte[] apdu = new byte[] { + (byte) 0x00, (byte) 0x20, (byte) 0x00, kid, (byte) 0x08, // CLA INS P1 P2 LC + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // Data + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 // Data + }; + + int offset = 0; + byte[] pinVerifyStructure = new byte[offset + 19 + apdu.length]; + pinVerifyStructure[offset++] = bTimeOut; + pinVerifyStructure[offset++] = bTimeOut2; + pinVerifyStructure[offset++] = bmFormatString; + pinVerifyStructure[offset++] = bmPINBlockString; + pinVerifyStructure[offset++] = bmPINLengthFormat; + pinVerifyStructure[offset++] = wPINMaxExtraDigitL; + pinVerifyStructure[offset++] = wPINMaxExtraDigitH; + pinVerifyStructure[offset++] = bEntryValidationCondition; + pinVerifyStructure[offset++] = bNumberMessage; + pinVerifyStructure[offset++] = wLangIdL; + pinVerifyStructure[offset++] = wLangIdH; + pinVerifyStructure[offset++] = bMsgIndex; + + pinVerifyStructure[offset++] = 0x00; + pinVerifyStructure[offset++] = 0x00; + pinVerifyStructure[offset++] = 0x00; + + pinVerifyStructure[offset++] = (byte) apdu.length; + pinVerifyStructure[offset++] = 0x00; + pinVerifyStructure[offset++] = 0x00; + pinVerifyStructure[offset++] = 0x00; + System.arraycopy(apdu, 0, pinVerifyStructure, offset, apdu.length); + + return pinVerifyStructure; + } + + public byte[] getPINModifyStructure(byte kid) { + + byte bTimeOut = (byte) 00; // Default time out + byte bTimeOut2 = (byte) 00; // Default time out + byte bmFormatString = (byte) 0x82; // 1 0001 0 01 + // ^------------ System unit = byte + // ^^^^------- PIN position in the frame = 1 byte + // ^----- PIN justification left + // ^^-- BCD format + // 1 0000 0 10 + // ^^-- ASCII format + byte bmPINBlockString = (byte) 0x08; // 0100 0111 + // ^^^^--------- PIN length size: 4 bits + // ^^^^---- Length PIN = 7 bytes + byte bmPINLengthFormat = (byte) 0x00; // 000 0 0100 + // ^-------- System bit units is bit + // ^^^^--- PIN length is at the 4th position bit + byte bInsertionOffsetOld = (byte) 0x00; // insertion position offset in bytes + byte bInsertionOffsetNew = (byte) 0x00; // insertion position offset in bytes + byte wPINMaxExtraDigitL = (byte) 0x04; // Min=4 digits + byte wPINMaxExtraDigitH = (byte) 0x04; // Max=12 digits + byte bConfirmPIN = (byte) 0x00; // ??? need for confirm pin + byte bEntryValidationCondition = 0x02; // Max size reach or Validation key pressed + byte bNumberMessage = (byte) 0x00; // No message + byte wLangIdL = (byte) 0x0C; // - English? + byte wLangIdH = (byte) 0x04; // \ + byte bMsgIndex1 = (byte) 0x00; // Default Msg + byte bMsgIndex2 = (byte) 0x00; // Default Msg + byte bMsgIndex3 = (byte) 0x00; // Default Msg + + byte[] apdu = new byte[] { + (byte) 0x00, (byte) 0x24, (byte) 0x00, kid, (byte) 0x10, // CLA INS P1 P2 LC + (byte) 0x20, (byte) 0xff, (byte) 0xff, (byte) 0xff, // Data + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, // ... + (byte) 0x20, (byte) 0xff, (byte) 0xff, (byte) 0xff, // Data + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff // ... + }; + + int offset = 0; + byte[] pinModifyStructure = new byte[offset + 24 + apdu.length]; + pinModifyStructure[offset++] = bTimeOut; + pinModifyStructure[offset++] = bTimeOut2; + pinModifyStructure[offset++] = bmFormatString; + pinModifyStructure[offset++] = bmPINBlockString; + pinModifyStructure[offset++] = bmPINLengthFormat; + pinModifyStructure[offset++] = bInsertionOffsetOld; + pinModifyStructure[offset++] = bInsertionOffsetNew; + pinModifyStructure[offset++] = wPINMaxExtraDigitL; + pinModifyStructure[offset++] = wPINMaxExtraDigitH; + pinModifyStructure[offset++] = bConfirmPIN; + pinModifyStructure[offset++] = bEntryValidationCondition; + pinModifyStructure[offset++] = bNumberMessage; + pinModifyStructure[offset++] = wLangIdL; + pinModifyStructure[offset++] = wLangIdH; + pinModifyStructure[offset++] = bMsgIndex1; + pinModifyStructure[offset++] = bMsgIndex2; + pinModifyStructure[offset++] = bMsgIndex3; + + pinModifyStructure[offset++] = 0x00; + pinModifyStructure[offset++] = 0x00; + pinModifyStructure[offset++] = 0x00; + + pinModifyStructure[offset++] = (byte) apdu.length; + pinModifyStructure[offset++] = 0x00; + pinModifyStructure[offset++] = 0x00; + pinModifyStructure[offset++] = 0x00; + System.arraycopy(apdu, 0, pinModifyStructure, offset, apdu.length); + + return pinModifyStructure; + } + + @Override + public String toString() { + return "a-sign premium"; + } } -- cgit v1.2.3 From 616e06910051528674165319a1d6d161dff5859c Mon Sep 17 00:00:00 2001 From: clemenso Date: Fri, 27 Mar 2009 17:33:11 +0000 Subject: 1.1-RC6 (pinpad, pinmgmt, secureviewer) git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@323 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 130 ++++++++++++----------- 1 file changed, 69 insertions(+), 61 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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 01b9155b..06e4a018 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -28,6 +28,7 @@ // package at.gv.egiz.smcc; +import at.gv.egiz.smcc.ccid.CCID; import at.gv.egiz.smcc.util.SMCCHelper; import java.nio.ByteBuffer; import java.nio.CharBuffer; @@ -41,7 +42,7 @@ import javax.smartcardio.ResponseAPDU; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -public class ACOSCard extends AbstractSignatureCard implements SignatureCard { +public class ACOSCard extends AbstractSignatureCard { private static Log log = LogFactory.getLog(ACOSCard.class); @@ -180,22 +181,23 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { //new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name")); int retries = -1; - char[] pin = null; - boolean pinRequiered = false; + boolean pinRequired = false; do { - if (pinRequiered) { - pin = provider.providePIN(spec, retries); - } try { getCard().beginExclusive(); - return readTLVFile(AID_DEC, EF_INFOBOX, pin, KID_PIN_INF, EF_INFOBOX_MAX_SIZE); + if (pinRequired) { + char[] pin = provider.providePIN(spec, retries); + return readTLVFile(AID_DEC, EF_INFOBOX, pin, spec.getKID(), EF_INFOBOX_MAX_SIZE); + } else { + return readTLVFile(AID_DEC, EF_INFOBOX, EF_INFOBOX_MAX_SIZE); + } } catch (FileNotFoundException e) { throw new NotActivatedException(); } catch (SecurityStatusNotSatisfiedException e) { - pinRequiered = true; + pinRequired = true; } catch (VerificationFailedException e) { - pinRequiered = true; + pinRequired = true; retries = e.getRetries(); } finally { getCard().endExclusive(); @@ -402,10 +404,10 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException { try { byte[] sw; - if (ifdSupportsFeature(FEATURE_VERIFY_PIN_DIRECT)) { + if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) { log.debug("verify PIN on IFD"); - sw = transmitControlCommand( - ifdCtrlCmds.get(FEATURE_VERIFY_PIN_DIRECT), + sw = reader.transmitControlCommand( + CCID.FEATURE_VERIFY_PIN_DIRECT, getPINVerifyStructure(kid)); // int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff; } else { @@ -466,10 +468,10 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException { try { byte[] sw; - if (ifdSupportsFeature(FEATURE_MODIFY_PIN_DIRECT)) { + if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_DIRECT)) { log.debug("modify PIN on IFD"); - sw = transmitControlCommand( - ifdCtrlCmds.get(FEATURE_MODIFY_PIN_DIRECT), + sw = reader.transmitControlCommand( + CCID.FEATURE_MODIFY_PIN_DIRECT, getPINModifyStructure(kid)); // int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff; } else { @@ -543,34 +545,37 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } private byte[] getPINVerifyStructure(byte kid) { - - byte bTimeOut = (byte) 00; // Default time out - byte bTimeOut2 = (byte) 00; // Default time out - byte bmFormatString = (byte) 0x82; // 1 0001 0 01 + + byte bTimeOut = reader.getbTimeOut(); + byte bTimeOut2 = reader.getbTimeOut2(); + byte bmFormatString = (byte) 0x82; // 1 0000 0 10 // ^------------ System unit = byte // ^^^^------- PIN position in the frame = 1 byte // ^----- PIN justification left - // ^^-- BCD format - // 1 0000 0 10 // ^^-- ASCII format - byte bmPINBlockString = (byte) 0x08; // 0100 0111 - // ^^^^--------- PIN length size: 4 bits - // ^^^^---- Length PIN = 7 bytes - byte bmPINLengthFormat = (byte) 0x04; // 000 0 0100 + byte bmPINBlockString = (byte) 0x08; // 0000 1000 + // ^^^^--------- PIN length size: 0 bits + // ^^^^---- Length PIN = 8 bytes + byte bmPINLengthFormat = (byte) 0x00; // 000 0 0000 // ^-------- System bit units is bit - // ^^^^--- PIN length is at the 4th position bit - byte wPINMaxExtraDigitL = (byte) 0x04; // Max=4 digits - byte wPINMaxExtraDigitH = (byte) 0x04; // Min=4 digits - byte bEntryValidationCondition = 0x02; // Max size reach or Validation key pressed + // ^^^^--- no PIN length + byte wPINMaxExtraDigitL = + (reader.getwPINMaxExtraDigitL() < (byte) 0x08) ? + reader.getwPINMaxExtraDigitL() : (byte) 0x08; + byte wPINMaxExtraDigitH = + (reader.getwPINMaxExtraDigitH() > (byte) 0x00) ? + reader.getwPINMaxExtraDigitH() : (byte) 0x00; + byte bEntryValidationCondition = + reader.getbEntryValidationCondition(); byte bNumberMessage = (byte) 0x00; // No message - byte wLangIdL = (byte) 0x0C; // - English? - byte wLangIdH = (byte) 0x04; // \ - byte bMsgIndex = (byte) 0x00; // Default Msg + byte wLangIdL = (byte) 0x0C; + byte wLangIdH = (byte) 0x04; + byte bMsgIndex = (byte) 0x00; byte[] apdu = new byte[] { - (byte) 0x00, (byte) 0x20, (byte) 0x00, kid, (byte) 0x08, // CLA INS P1 P2 LC - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // Data - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 // Data + (byte) 0x00, (byte) 0x20, (byte) 0x00, kid, (byte) 0x08, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; int offset = 0; @@ -603,40 +608,43 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { public byte[] getPINModifyStructure(byte kid) { - byte bTimeOut = (byte) 00; // Default time out - byte bTimeOut2 = (byte) 00; // Default time out - byte bmFormatString = (byte) 0x82; // 1 0001 0 01 + byte bTimeOut = reader.getbTimeOut(); + byte bTimeOut2 = reader.getbTimeOut2(); + byte bmFormatString = (byte) 0x82; // 1 0000 0 10 // ^------------ System unit = byte // ^^^^------- PIN position in the frame = 1 byte // ^----- PIN justification left - // ^^-- BCD format - // 1 0000 0 10 // ^^-- ASCII format - byte bmPINBlockString = (byte) 0x08; // 0100 0111 - // ^^^^--------- PIN length size: 4 bits - // ^^^^---- Length PIN = 7 bytes - byte bmPINLengthFormat = (byte) 0x00; // 000 0 0100 + byte bmPINBlockString = (byte) 0x08; // 0000 1000 + // ^^^^--------- PIN length size: 0 bits + // ^^^^---- Length PIN = 8 bytes + byte bmPINLengthFormat = (byte) 0x00; // 000 0 0000 // ^-------- System bit units is bit - // ^^^^--- PIN length is at the 4th position bit + // ^^^^--- no PIN length byte bInsertionOffsetOld = (byte) 0x00; // insertion position offset in bytes - byte bInsertionOffsetNew = (byte) 0x00; // insertion position offset in bytes - byte wPINMaxExtraDigitL = (byte) 0x04; // Min=4 digits - byte wPINMaxExtraDigitH = (byte) 0x04; // Max=12 digits - byte bConfirmPIN = (byte) 0x00; // ??? need for confirm pin - byte bEntryValidationCondition = 0x02; // Max size reach or Validation key pressed - byte bNumberMessage = (byte) 0x00; // No message - byte wLangIdL = (byte) 0x0C; // - English? - byte wLangIdH = (byte) 0x04; // \ - byte bMsgIndex1 = (byte) 0x00; // Default Msg - byte bMsgIndex2 = (byte) 0x00; // Default Msg - byte bMsgIndex3 = (byte) 0x00; // Default Msg + byte bInsertionOffsetNew = (byte) 0x08; + byte wPINMaxExtraDigitL = + (reader.getwPINMaxExtraDigitL() < (byte) 0x08) ? + reader.getwPINMaxExtraDigitL() : (byte) 0x08; + byte wPINMaxExtraDigitH = + (reader.getwPINMaxExtraDigitH() > (byte) 0x00) ? + reader.getwPINMaxExtraDigitH() : (byte) 0x00; + byte bConfirmPIN = (byte) 0x03; + byte bEntryValidationCondition = + reader.getbEntryValidationCondition(); + byte bNumberMessage = (byte) 0x03; + byte wLangIdL = (byte) 0x0C; + byte wLangIdH = (byte) 0x04; + byte bMsgIndex1 = (byte) 0x00; + byte bMsgIndex2 = (byte) 0x01; + byte bMsgIndex3 = (byte) 0x02; byte[] apdu = new byte[] { - (byte) 0x00, (byte) 0x24, (byte) 0x00, kid, (byte) 0x10, // CLA INS P1 P2 LC - (byte) 0x20, (byte) 0xff, (byte) 0xff, (byte) 0xff, // Data - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, // ... - (byte) 0x20, (byte) 0xff, (byte) 0xff, (byte) 0xff, // Data - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff // ... + (byte) 0x00, (byte) 0x24, (byte) 0x00, kid, (byte) 0x10, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; int offset = 0; -- cgit v1.2.3 From 2dbf2347bc78fd835c857ad438514fb6251f6f7a Mon Sep 17 00:00:00 2001 From: clemenso Date: Thu, 2 Apr 2009 19:13:48 +0000 Subject: 1.1-RC7 (pinpad revisited) git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@325 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 34 +++++++++++++++--------- 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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 06e4a018..d064b821 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -401,15 +401,16 @@ public class ACOSCard extends AbstractSignatureCard { @Override protected int verifyPIN(byte kid, char[] pin) - throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException { + throws LockedException, NotActivatedException, CancelledException, TimeoutException, PINFormatException, PINOperationAbortedException, SignatureCardException { try { byte[] sw; if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) { - log.debug("verify PIN on IFD"); - sw = reader.transmitControlCommand( - CCID.FEATURE_VERIFY_PIN_DIRECT, - getPINVerifyStructure(kid)); + log.debug("verify pin on cardreader"); + sw = reader.verifyPinDirect(getPINVerifyStructure(kid)); // int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff; + } else if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_START)) { + log.debug("verify pin on cardreader"); + sw = reader.verifyPin(getPINVerifyStructure(kid)); } else { byte[] pinBlock = encodePINBlock(pin); CardChannel channel = getCardChannel(); @@ -442,6 +443,8 @@ public class ACOSCard extends AbstractSignatureCard { throw new TimeoutException("[64:00]"); } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) { throw new CancelledException("[64:01]"); + } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x03) { + throw new PINFormatException("[64:03]"); } log.error("Failed to verify pin: SW=" + SMCCHelper.toString(sw)); @@ -465,15 +468,15 @@ public class ACOSCard extends AbstractSignatureCard { */ @Override protected int changePIN(byte kid, char[] oldPin, char[] newPin) - throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException { + throws LockedException, NotActivatedException, CancelledException, PINFormatException, PINConfirmationException, TimeoutException, PINOperationAbortedException, SignatureCardException { try { byte[] sw; if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_DIRECT)) { - log.debug("modify PIN on IFD"); - sw = reader.transmitControlCommand( - CCID.FEATURE_MODIFY_PIN_DIRECT, - getPINModifyStructure(kid)); -// int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff; + log.debug("modify pin on cardreader"); + sw = reader.modifyPinDirect(getPINModifyStructure(kid)); + } else if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_START)) { + log.debug("modify pin on cardreader"); + sw = reader.modifyPin(getPINModifyStructure(kid)); } else { byte[] cmd = new byte[16]; System.arraycopy(encodePINBlock(oldPin), 0, cmd, 0, 8); @@ -504,6 +507,13 @@ public class ACOSCard extends AbstractSignatureCard { throw new TimeoutException("[64:00]"); } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) { throw new CancelledException("[64:01]"); + } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x02) { + throw new PINConfirmationException("[64:02]"); + } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x03) { + throw new PINFormatException("[64:03]"); + } else if (sw[0] == (byte) 0x6a && sw[1] == (byte) 0x80) { + log.info("invalid parameter, assume wrong pin size"); + throw new PINFormatException("[6a:80]"); } log.error("Failed to change pin: SW=" + SMCCHelper.toString(sw)); @@ -559,7 +569,7 @@ public class ACOSCard extends AbstractSignatureCard { byte bmPINLengthFormat = (byte) 0x00; // 000 0 0000 // ^-------- System bit units is bit // ^^^^--- no PIN length - byte wPINMaxExtraDigitL = + byte wPINMaxExtraDigitL = //TODO compare ints, not bytes (reader.getwPINMaxExtraDigitL() < (byte) 0x08) ? reader.getwPINMaxExtraDigitL() : (byte) 0x08; byte wPINMaxExtraDigitH = -- cgit v1.2.3 From 6cb4a071eab9a3b8cf78b8ec7e407aa148f2d038 Mon Sep 17 00:00:00 2001 From: mcentner Date: Wed, 1 Jul 2009 13:03:41 +0000 Subject: Major refactoring of SMCC git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@381 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 1089 +++++++++++----------- 1 file changed, 566 insertions(+), 523 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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 d064b821..9825978c 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -1,48 +1,47 @@ -//Copyright (C) 2002 IAIK -//http://jce.iaik.at -// -//Copyright (C) 2003 Stiftung Secure Information and -// Communication Technologies SIC -//http://www.sic.st -// -//All rights reserved. -// -//This source is provided for inspection purposes and recompilation only, -//unless specified differently in a contract with IAIK. This source has to -//be kept in strict confidence and must not be disclosed to any third party -//under any circumstances. Redistribution in source and binary forms, with -//or without modification, are permitted in any case! -// -//THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -//FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -//DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -//OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -//OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -//SUCH DAMAGE. -// -// +/* +* 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; -import at.gv.egiz.smcc.ccid.CCID; -import at.gv.egiz.smcc.util.SMCCHelper; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.Charset; - +import java.io.IOException; +import java.security.AlgorithmParameters; +import java.security.GeneralSecurityException; +import java.util.Arrays; +import java.util.List; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESedeKeySpec; +import javax.crypto.spec.IvParameterSpec; +import javax.smartcardio.Card; import javax.smartcardio.CardChannel; import javax.smartcardio.CardException; +import javax.smartcardio.CardTerminal; import javax.smartcardio.CommandAPDU; import javax.smartcardio.ResponseAPDU; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -public class ACOSCard extends AbstractSignatureCard { +import at.gv.egiz.smcc.util.ISO7816Utils; +import at.gv.egiz.smcc.util.SMCCHelper; +import at.gv.egiz.smcc.util.TransparentFileInputStream; + +public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureCard { private static Log log = LogFactory.getLog(ACOSCard.class); @@ -69,6 +68,8 @@ public class ACOSCard extends AbstractSignatureCard { (byte) 0x01 }; public static final byte[] EF_INFOBOX = new byte[] { (byte) 0xc0, (byte) 0x02 }; + + public static final byte[] EF_INFO = new byte[] { (byte) 0xd0, (byte) 0x02 }; public static final int EF_INFOBOX_MAX_SIZE = 1500; @@ -90,7 +91,7 @@ public class ACOSCard extends AbstractSignatureCard { (byte) 0x14 // ECDSA }; - public static final byte[] DST_DEC = new byte[] { (byte) 0x84, (byte) 0x01, // tag + public static final byte[] AT_DEC = new byte[] { (byte) 0x84, (byte) 0x01, // tag // , // length // ( @@ -102,123 +103,278 @@ public class ACOSCard extends AbstractSignatureCard { (byte) 0x01 // RSA // TODO: Not verified yet }; - protected static final int PINSPEC_INF = 0; - protected static final int PINSPEC_DEC = 1; - protected static final int PINSPEC_SIG = 2; + private static final PINSpec DEC_PIN_SPEC = new PINSpec(0, 8, "[0-9]", + "at/gv/egiz/smcc/ACOSCard", "dec.pin.name", KID_PIN_DEC, AID_DEC); + + private static final PINSpec SIG_PIN_SPEC = new PINSpec(0, 8, "[0-9]", + "at/gv/egiz/smcc/ACOSCard", "sig.pin.name", KID_PIN_SIG, AID_SIG); + + private static final PINSpec INF_PIN_SPEC = new PINSpec(0, 8, "[0-9]", + "at/gv/egiz/smcc/ACOSCard", "inf.pin.name", KID_PIN_INF, AID_DEC); + + /** + * The version of the card's digital signature application. + */ + protected int appVersion = -1; public ACOSCard() { super("at/gv/egiz/smcc/ACOSCard"); - pinSpecs.add(PINSPEC_INF, - new PINSpec(0, 8, "[0-9]", getResourceBundle().getString("inf.pin.name"), KID_PIN_INF, AID_DEC)); - pinSpecs.add(PINSPEC_DEC, - new PINSpec(0, 8, "[0-9]", getResourceBundle().getString("dec.pin.name"), KID_PIN_DEC, AID_DEC)); - pinSpecs.add(PINSPEC_SIG, - new PINSpec(0, 8, "[0-9]", getResourceBundle().getString("sig.pin.name"), KID_PIN_SIG, AID_SIG)); } - /* (non-Javadoc) - * @see at.gv.egiz.smcc.SignatureCard#getCertificate(at.gv.egiz.smcc.SignatureCard.KeyboxName) - */ @Override + public void init(Card card, CardTerminal cardTerminal) { + super.init(card, cardTerminal); + + // determine application version + try { + CardChannel channel = getCardChannel(); + // SELECT application + execSELECT_AID(channel, AID_SIG); + // SELECT file + execSELECT_FID(channel, EF_INFO); + // READ BINARY + TransparentFileInputStream is = ISO7816Utils.openTransparentFileInputStream(channel, 8); + appVersion = is.read(); + log.info("a-sign premium application version = " + appVersion); + } catch (FileNotFoundException e) { + appVersion = 1; + log.info("a-sign premium application version = " + appVersion); + } catch (SignatureCardException e) { + log.warn(e); + appVersion = 0; + } catch (IOException e) { + log.warn(e); + appVersion = 0; + } catch (CardException e) { + log.warn(e); + appVersion = 0; + } + + pinSpecs.add(DEC_PIN_SPEC); + pinSpecs.add(SIG_PIN_SPEC); + if (appVersion < 2) { + pinSpecs.add(INF_PIN_SPEC); + } + + } + + @Override + @Exclusive public byte[] getCertificate(KeyboxName keyboxName) throws SignatureCardException, InterruptedException { - - try { - + + byte[] aid; + byte[] fid; if (keyboxName == KeyboxName.SECURE_SIGNATURE_KEYPAIR) { - - try { - getCard().beginExclusive(); - byte[] certificate = readTLVFile(AID_SIG, EF_C_CH_DS, EF_C_CH_DS_MAX_SIZE); - if (certificate == null) { - throw new NotActivatedException(); - } - return certificate; - } catch (FileNotFoundException e) { - throw new NotActivatedException(); - } finally { - getCard().endExclusive(); - } - + aid = AID_SIG; + fid = EF_C_CH_DS; } else if (keyboxName == KeyboxName.CERITIFIED_KEYPAIR) { - - try { - getCard().beginExclusive(); - byte[] certificate = readTLVFile(AID_DEC, EF_C_CH_EKEY, EF_C_CH_EKEY_MAX_SIZE); - if (certificate == null) { - throw new NotActivatedException(); - } - return certificate; - } catch (FileNotFoundException e) { - throw new NotActivatedException(); - } finally { - getCard().endExclusive(); - } - + aid = AID_DEC; + fid = EF_C_CH_EKEY; } else { throw new IllegalArgumentException("Keybox " + keyboxName + " not supported."); } - } catch (CardException e) { - log.warn(e); - throw new SignatureCardException("Failed to access card.", e); - } - + try { + CardChannel channel = getCardChannel(); + // SELECT application + execSELECT_AID(channel, aid); + // SELECT file + byte[] fcx = execSELECT_FID(channel, fid); + int maxSize = -1; + if (getAppVersion() < 2) { + maxSize = ISO7816Utils.getLengthFromFCx(fcx); + log.debug("Size of selected file = " + maxSize); + } + // READ BINARY + byte[] certificate = ISO7816Utils.readTransparentFileTLV(channel, maxSize, (byte) 0x30); + if (certificate == null) { + throw new NotActivatedException(); + } + return certificate; + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } catch (CardException e) { + log.info("Failed to get certificate.", e); + throw new SignatureCardException(e); + } + + } - /* (non-Javadoc) - * @see at.gv.egiz.smcc.SignatureCard#getInfobox(java.lang.String, at.gv.egiz.smcc.PINProvider, java.lang.String) - */ @Override + @Exclusive public byte[] getInfobox(String infobox, PINProvider provider, String domainId) throws SignatureCardException, InterruptedException { + + if ("IdentityLink".equals(infobox)) { + if (getAppVersion() < 2) { + return getIdentityLinkV1(provider, domainId); + } else { + return getIdentityLinkV2(provider, domainId); + } + } else { + throw new IllegalArgumentException("Infobox '" + infobox + + "' not supported."); + } + + } + + protected byte[] getIdentityLinkV1(PINProvider provider, String domainId) + throws SignatureCardException, InterruptedException { + + try { + CardChannel channel = getCardChannel(); + // SELECT application + execSELECT_AID(channel, AID_DEC); + // SELECT file + byte[] fcx = execSELECT_FID(channel, EF_INFOBOX); + int maxSize = ISO7816Utils.getLengthFromFCx(fcx); + log.debug("Size of selected file = " + maxSize); + // READ BINARY + while(true) { + try { + return ISO7816Utils.readTransparentFileTLV(channel, maxSize, (byte) 0x30); + } catch (SecurityStatusNotSatisfiedException e) { + verifyPINLoop(channel, INF_PIN_SPEC, provider); + } + } + + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } catch (CardException e) { + log.info("Faild to get infobox.", e); + throw new SignatureCardException(e); + } + + } + protected byte[] getIdentityLinkV2(PINProvider provider, String domainId) + throws SignatureCardException, InterruptedException { + try { - if ("IdentityLink".equals(infobox)) { - - PINSpec spec = pinSpecs.get(PINSPEC_INF); - //new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name")); + CardChannel channel = getCardChannel(); + // SELECT application + execSELECT_AID(channel, AID_DEC); + // SELECT file + execSELECT_FID(channel, EF_INFOBOX); + + // READ BINARY + TransparentFileInputStream is = ISO7816Utils.openTransparentFileInputStream(channel, -1); + + int b = is.read(); + if (b == 0x00) { + return null; + } + if (b != 0x41 || is.read() != 0x49 || is.read() != 0x4b) { + String msg = "Infobox structure invalid."; + log.info(msg); + throw new SignatureCardException(msg); + } - int retries = -1; - boolean pinRequired = false; + b = is.read(); + if (b != 0x01) { + String msg = "Infobox structure v" + b + " not supported."; + log.info(msg); + throw new SignatureCardException(msg); + } + + while ((b = is.read()) != 0x01 && b != 00) { + is.read(); // modifiers + is.skip(is.read() + (is.read() << 8)); // length + } + + if (b != 0x01) { + return null; + } + + int modifiers = is.read(); + int length = is.read() + (is.read() << 8); - do { - try { - getCard().beginExclusive(); - if (pinRequired) { - char[] pin = provider.providePIN(spec, retries); - return readTLVFile(AID_DEC, EF_INFOBOX, pin, spec.getKID(), EF_INFOBOX_MAX_SIZE); - } else { - return readTLVFile(AID_DEC, EF_INFOBOX, EF_INFOBOX_MAX_SIZE); - } - } catch (FileNotFoundException e) { - throw new NotActivatedException(); - } catch (SecurityStatusNotSatisfiedException e) { - pinRequired = true; - } catch (VerificationFailedException e) { - pinRequired = true; - retries = e.getRetries(); - } finally { - getCard().endExclusive(); - } - } while (retries != 0); + byte[] bytes; + byte[] key = null; + + switch (modifiers) { + case 0x00: + bytes = new byte[length]; + break; + case 0x01: + key = new byte[is.read() + (is.read() << 8)]; + is.read(key); + bytes = new byte[length - key.length - 2]; + break; + default: + String msg = "Compressed infobox structure not yet supported."; + log.info(msg); + throw new SignatureCardException(msg); + } + + is.read(bytes); + + if (key == null) { + return bytes; + } - throw new LockedException(); + execMSE(channel, 0x41, 0xb8, new byte[] { + (byte) 0x84, (byte) 0x01, (byte) 0x88, (byte) 0x80, (byte) 0x01, + (byte) 0x02 }); - } else { - throw new IllegalArgumentException("Infobox '" + infobox - + "' not supported."); - } + byte[] plainKey = null; + + while (true) { + try { + plainKey = execPSO_DECIPHER(channel, key); + break; + } catch(SecurityStatusNotSatisfiedException e) { + verifyPINLoop(channel, DEC_PIN_SPEC, provider); + } + } + + try { + Cipher cipher = Cipher + .getInstance("DESede/CBC/PKCS5Padding"); + byte[] iv = new byte[8]; + Arrays.fill(iv, (byte) 0x00); + IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); + AlgorithmParameters parameters = AlgorithmParameters + .getInstance("DESede"); + parameters.init(ivParameterSpec); + + DESedeKeySpec keySpec = new DESedeKeySpec(plainKey); + SecretKeyFactory keyFactory = SecretKeyFactory + .getInstance("DESede"); + SecretKey secretKey = keyFactory.generateSecret(keySpec); + + cipher.init(Cipher.DECRYPT_MODE, secretKey, parameters); + + return cipher.doFinal(bytes); + + } catch (GeneralSecurityException e) { + String msg = "Failed to decrypt infobox."; + log.info(msg, e); + throw new SignatureCardException(msg, e); + } + + + } catch (FileNotFoundException e) { + throw new NotActivatedException(); } catch (CardException e) { - log.warn(e); - throw new SignatureCardException("Failed to access card.", e); + log.info("Faild to get infobox.", e); + throw new SignatureCardException(e); + } catch (IOException e) { + if (e.getCause() instanceof SignatureCardException) { + throw (SignatureCardException) e.getCause(); + } else { + throw new SignatureCardException(e); + } } - + } - + @Override + @Exclusive public byte[] createSignature(byte[] hash, KeyboxName keyboxName, PINProvider provider) throws SignatureCardException, InterruptedException { @@ -228,87 +384,40 @@ public class ACOSCard extends AbstractSignatureCard { try { - if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) { - - PINSpec spec = pinSpecs.get(PINSPEC_SIG); - //new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name")); - - int retries = -1; - char[] pin = null; - - do { - pin = provider.providePIN(spec, retries); - try { - getCard().beginExclusive(); - - // SELECT DF - selectFileFID(DF_SIG); - // VERIFY - retries = verifyPIN(KID_PIN_SIG, pin); - if (retries != -1) { - throw new VerificationFailedException(retries); - } - // MSE: SET DST - mseSetDST(0x81, 0xb6, DST_SIG); - // PSO: HASH - psoHash(hash); - // PSO: COMPUTE DIGITAL SIGNATURE - return psoComputDigitalSiganture(); + CardChannel channel = getCardChannel(); - } catch (SecurityStatusNotSatisfiedException e) { - retries = verifyPIN(KID_PIN_SIG); - } catch (VerificationFailedException e) { - retries = e.getRetries(); - } finally { - getCard().endExclusive(); - } - } while (retries != 0); + if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) { - throw new LockedException(); + PINSpec spec = SIG_PIN_SPEC; + // SELECT application + execSELECT_AID(channel, AID_SIG); + // MANAGE SECURITY ENVIRONMENT : SET DST + execMSE(channel, 0x41, 0xb6, DST_SIG); + // VERIFY + verifyPINLoop(channel, spec, provider); + // PERFORM SECURITY OPERATION : HASH + execPSO_HASH(channel, hash); + // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATRE + return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel); } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) { - PINSpec spec = pinSpecs.get(PINSPEC_DEC); - //new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("dec.pin.name")); - - int retries = -1; - char[] pin = null; - boolean pinRequired = false; + PINSpec spec = DEC_PIN_SPEC; - do { - if (pinRequired) { - pin = provider.providePIN(spec, retries); - } + // SELECT application + execSELECT_AID(channel, AID_DEC); + // MANAGE SECURITY ENVIRONMENT : SET AT + execMSE(channel, 0x41, 0xa4, AT_DEC); + + while (true) { try { - getCard().beginExclusive(); - - // SELECT DF - selectFileFID(DF_DEC); - // VERIFY - retries = verifyPIN(KID_PIN_DEC, pin); - if (retries != -1) { - throw new VerificationFailedException(retries); - } - // MSE: SET DST - mseSetDST(0x41, 0xa4, DST_DEC); // INTERNAL AUTHENTICATE - return internalAuthenticate(hash); - - } catch (FileNotFoundException e) { - throw new NotActivatedException(); + return execINTERNAL_AUTHENTICATE(channel, hash); } catch (SecurityStatusNotSatisfiedException e) { - pinRequired = true; - retries = verifyPIN(KID_PIN_DEC); - } catch (VerificationFailedException e) { - pinRequired = true; - retries = e.getRetries(); - } finally { - getCard().endExclusive(); + verifyPINLoop(channel, spec, provider); } - } while (retries != 0); - - throw new LockedException(); + } } else { throw new IllegalArgumentException("KeyboxName '" + keyboxName @@ -321,377 +430,311 @@ public class ACOSCard extends AbstractSignatureCard { } } + + public int getAppVersion() { + return appVersion; + } - //////////////////////////////////////////////////////////////////////// - // PROTECTED METHODS (assume exclusive card access) - //////////////////////////////////////////////////////////////////////// + /* (non-Javadoc) + * @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) + throws LockedException, NotActivatedException, CancelledException, + TimeoutException, SignatureCardException, InterruptedException { - protected ResponseAPDU selectFileFID(byte[] fid) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); - return transmit(channel, new CommandAPDU(0x00, 0xA4, 0x00, - 0x00, fid, 256)); + + try { + // SELECT application + execSELECT_AID(channel, pinSpec.getContextAID()); + // VERIFY + verifyPIN(channel, pinSpec, pinProvider, -1); + } catch (CardException e) { + log.info("Failed to verify PIN.", e); + throw new SignatureCardException("Failed to verify PIN.", e); + } + } + + /* (non-Javadoc) + * @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) + throws LockedException, NotActivatedException, CancelledException, + TimeoutException, SignatureCardException, InterruptedException { - private void mseSetDST(int p1, int p2, byte[] dst) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); - ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x22, p1, - p2, dst)); - if (resp.getSW() != 0x9000) { - throw new SignatureCardException("MSE:SET DST failed: SW=" - + Integer.toHexString(resp.getSW())); + + try { + // SELECT application + execSELECT_AID(channel, pinSpec.getContextAID()); + // CHANGE REFERENCE DATA + changePIN(channel, pinSpec, pinProvider, -1); + } catch (CardException e) { + log.info("Failed to change PIN.", e); + throw new SignatureCardException("Failed to change PIN.", e); } + } - private void psoHash(byte[] hash) throws CardException, SignatureCardException { - CardChannel channel = getCardChannel(); - ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x2A, 0x90, - 0x81, hash)); - if (resp.getSW() != 0x9000) { - throw new SignatureCardException("PSO:HASH failed: SW=" - + Integer.toHexString(resp.getSW())); - } + @Override + public void activatePIN(PINSpec pinSpec, PINProvider pinProvider) + throws CancelledException, SignatureCardException, CancelledException, + TimeoutException, InterruptedException { + log.error("ACTIVATE PIN not supported by ACOS"); + throw new SignatureCardException("PIN activation not supported by this card."); } - private byte[] psoComputDigitalSiganture() throws CardException, - SignatureCardException { - CardChannel channel = getCardChannel(); - ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x2A, 0x9E, - 0x9A, 256)); - if (resp.getSW() != 0x9000) { - throw new SignatureCardException( - "PSO: COMPUTE DIGITAL SIGNATRE failed: SW=" - + Integer.toHexString(resp.getSW())); - } else { - return resp.getData(); - } + @Override + public void unblockPIN(PINSpec pinSpec, PINProvider pinProvider) + throws CancelledException, SignatureCardException, InterruptedException { + throw new SignatureCardException("Unblock PIN not supported."); } - private byte[] internalAuthenticate(byte[] hash) throws CardException, SignatureCardException { - byte[] digestInfo = new byte[] { - (byte) 0x30, (byte) 0x21, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x05, (byte) 0x2B, (byte) 0x0E, - (byte) 0x03, (byte) 0x02, (byte) 0x1A, (byte) 0x05, (byte) 0x00, (byte) 0x04 - }; - - byte[] data = new byte[digestInfo.length + hash.length + 1]; - - System.arraycopy(digestInfo, 0, data, 0, digestInfo.length); - data[digestInfo.length] = (byte) hash.length; - System.arraycopy(hash, 0, data, digestInfo.length + 1, hash.length); - - CardChannel channel = getCardChannel(); - - ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x88, 0x10, 0x00, data, 256)); - if (resp.getSW() != 0x9000) { - throw new SignatureCardException("INTERNAL AUTHENTICATE failed: SW=" + Integer.toHexString(resp.getSW())); + /* (non-Javadoc) + * @see at.gv.egiz.smcc.PINMgmtSignatureCard#getPINSpecs() + */ + @Override + public List getPINSpecs() { + if (getAppVersion() < 2) { + return Arrays.asList(new PINSpec[] {DEC_PIN_SPEC, SIG_PIN_SPEC, INF_PIN_SPEC}); } else { - return resp.getData(); + return Arrays.asList(new PINSpec[] {DEC_PIN_SPEC, SIG_PIN_SPEC}); } } - /** - * - * @param kid - * @return -1 + /* (non-Javadoc) + * @see at.gv.egiz.smcc.PINMgmtSignatureCard#getPINStatus(at.gv.egiz.smcc.PINSpec) */ @Override - protected int verifyPIN(byte kid) { - log.debug("VERIFY PIN without PIN BLOCK not supported by ACOS"); - return -1; + public PIN_STATE getPINState(PINSpec pinSpec) throws SignatureCardException { + return PIN_STATE.UNKNOWN; } @Override - protected int verifyPIN(byte kid, char[] pin) - throws LockedException, NotActivatedException, CancelledException, TimeoutException, PINFormatException, PINOperationAbortedException, SignatureCardException { - try { - byte[] sw; - if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) { - log.debug("verify pin on cardreader"); - sw = reader.verifyPinDirect(getPINVerifyStructure(kid)); -// int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff; - } else if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_START)) { - log.debug("verify pin on cardreader"); - sw = reader.verifyPin(getPINVerifyStructure(kid)); - } else { - byte[] pinBlock = encodePINBlock(pin); - CardChannel channel = getCardChannel(); - ResponseAPDU resp = transmit(channel, - new CommandAPDU(0x00, 0x20, 0x00, kid, pinBlock), false); - sw = new byte[2]; - sw[0] = (byte) resp.getSW1(); - sw[1] = (byte) resp.getSW2(); - } + public String toString() { + return "a-sign premium"; + } - //6A 00 (falshe P1/P2) nicht in contextAID - //69 85 (nutzungsbedingungen nicht erfüllt) in DF_Sig und nicht sigpin - - if (sw[0] == (byte) 0x90 && sw[1] == (byte) 0x00) { - return -1; - } else if (sw[0] == (byte) 0x63 && sw[1] == (byte) 0xc0) { - throw new LockedException("[63:c0]"); - } else if (sw[0] == (byte) 0x63 && (sw[1] & 0xf0) >> 4 == 0xc) { - return sw[1] & 0x0f; - } else if (sw[0] == (byte) 0x69 && sw[1] == (byte) 0x83) { - //Authentisierungsmethode gesperrt - throw new NotActivatedException("[69:83]"); -// } else if (sw[0] == (byte) 0x69 && sw[1] == (byte) 0x84) { -// //referenzierte Daten sind reversibel gesperrt (invalidated) -// throw new NotActivatedException("[69:84]"); -// } else if (sw[0] == (byte) 0x69 && sw[1] == (byte) 0x85) { -// //Benutzungsbedingungen nicht erfüllt -// throw new NotActivatedException("[69:85]"); - } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x00) { - throw new TimeoutException("[64:00]"); - } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) { - throw new CancelledException("[64:01]"); - } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x03) { - throw new PINFormatException("[64:03]"); - } - log.error("Failed to verify pin: SW=" - + SMCCHelper.toString(sw)); - throw new SignatureCardException(SMCCHelper.toString(sw)); + //////////////////////////////////////////////////////////////////////// + // PROTECTED METHODS (assume exclusive card access) + //////////////////////////////////////////////////////////////////////// - } catch (CardException ex) { - log.error("smart card communication failed: " + ex.getMessage()); - throw new SignatureCardException("smart card communication failed: " + ex.getMessage(), ex); - } + protected void verifyPINLoop(CardChannel channel, PINSpec spec, PINProvider provider) + throws InterruptedException, LockedException, NotActivatedException, + TimeoutException, PINFormatException, PINOperationAbortedException, + SignatureCardException, CardException { + + int retries = -1; + do { + retries = verifyPIN(channel, spec, provider, retries); + } while (retries > 0); + } - /** - * SCARD_E_NOT_TRANSACTED inf/dec PIN not active (pcsc crash) - * @param kid - * @param oldPin - * @param newPin - * @return - * @throws at.gv.egiz.smcc.LockedException - * @throws at.gv.egiz.smcc.NotActivatedException - * @throws at.gv.egiz.smcc.SignatureCardException - */ - @Override - protected int changePIN(byte kid, char[] oldPin, char[] newPin) - throws LockedException, NotActivatedException, CancelledException, PINFormatException, PINConfirmationException, TimeoutException, PINOperationAbortedException, SignatureCardException { - try { - byte[] sw; - if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_DIRECT)) { - log.debug("modify pin on cardreader"); - sw = reader.modifyPinDirect(getPINModifyStructure(kid)); - } else if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_START)) { - log.debug("modify pin on cardreader"); - sw = reader.modifyPin(getPINModifyStructure(kid)); - } else { - byte[] cmd = new byte[16]; - System.arraycopy(encodePINBlock(oldPin), 0, cmd, 0, 8); - System.arraycopy(encodePINBlock(newPin), 0, cmd, 8, 8); - - CardChannel channel = getCardChannel(); + protected int verifyPIN(CardChannel channel, PINSpec pinSpec, + PINProvider provider, int retries) throws InterruptedException, CardException, SignatureCardException { + + VerifyAPDUSpec apduSpec = new VerifyAPDUSpec( + new byte[] { + (byte) 0x00, (byte) 0x20, (byte) 0x00, pinSpec.getKID(), (byte) 0x08, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }, + 0, VerifyAPDUSpec.PIN_FORMAT_ASCII, 8); + + ResponseAPDU resp = reader.verify(channel, apduSpec, pinSpec, provider, retries); + + if (resp.getSW() == 0x9000) { + return -1; + } + if (resp.getSW() >> 4 == 0x63c) { + return 0x0f & resp.getSW(); + } - ResponseAPDU resp = transmit(channel, - new CommandAPDU(0x00, 0x24, 0x00, kid, cmd), false); + switch (resp.getSW()) { + case 0x6983: + // authentication method blocked + throw new LockedException(); + + default: + String msg = "VERIFY failed. SW=" + Integer.toHexString(resp.getSW()); + log.info(msg); + throw new SignatureCardException(msg); + } - sw = new byte[2]; - sw[0] = (byte) resp.getSW1(); - sw[1] = (byte) resp.getSW2(); - } + } - // activates pin (newPIN) if not active - if (sw[0] == (byte) 0x90 && sw[1] == (byte) 0x00) { - return -1; - } else if (sw[0] == (byte) 0x63 && sw[1] == (byte) 0xc0) { - throw new LockedException("[63:c0]"); - } else if (sw[0] == (byte) 0x63 && (sw[1] & 0xf0) >> 4 == 0xc) { - return sw[1] & 0x0f; - } else if (sw[0] == (byte) 0x69 && sw[1] == (byte) 0x83) { - //Authentisierungsmethode gesperrt - // sig-pin only (card not transacted for inf/dec pin) - throw new NotActivatedException("[69:83]"); - } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x00) { - throw new TimeoutException("[64:00]"); - } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) { - throw new CancelledException("[64:01]"); - } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x02) { - throw new PINConfirmationException("[64:02]"); - } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x03) { - throw new PINFormatException("[64:03]"); - } else if (sw[0] == (byte) 0x6a && sw[1] == (byte) 0x80) { - log.info("invalid parameter, assume wrong pin size"); - throw new PINFormatException("[6a:80]"); - } - log.error("Failed to change pin: SW=" - + SMCCHelper.toString(sw)); - throw new SignatureCardException(SMCCHelper.toString(sw)); + protected int changePIN(CardChannel channel, PINSpec pinSpec, + ChangePINProvider 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) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 + }, + 0, VerifyAPDUSpec.PIN_FORMAT_ASCII, 8); + + + + ResponseAPDU resp = reader.modify(channel, apduSpec, pinSpec, pinProvider, retries); + + if (resp.getSW() == 0x9000) { + return -1; + } + if (resp.getSW() >> 4 == 0x63c) { + return 0x0f & resp.getSW(); + } + + switch (resp.getSW()) { + case 0x6983: + // authentication method blocked + throw new LockedException(); + + default: + String msg = "CHANGE REFERENCE DATA failed. SW=" + Integer.toHexString(resp.getSW()); + log.info(msg); + throw new SignatureCardException(msg); + } + + } - } catch (CardException ex) { - log.error("smart card communication failed: " + ex.getMessage()); - throw new SignatureCardException("smart card communication failed: " + ex.getMessage(), ex); + protected byte[] execSELECT_AID(CardChannel channel, byte[] aid) + throws SignatureCardException, CardException { + + ResponseAPDU resp = channel.transmit( + new CommandAPDU(0x00, 0xA4, 0x04, 0x00, aid, 256)); + + if (resp.getSW() == 0x6A82) { + String msg = "File or application not found AID=" + + SMCCHelper.toString(aid) + " SW=" + + Integer.toHexString(resp.getSW()) + "."; + log.info(msg); + throw new FileNotFoundException(msg); + } else if (resp.getSW() != 0x9000) { + String msg = "Failed to select application AID=" + + SMCCHelper.toString(aid) + " SW=" + + Integer.toHexString(resp.getSW()) + "."; + log.info(msg); + throw new SignatureCardException(msg); + } else { + return resp.getBytes(); } + } + + protected byte[] execSELECT_FID(CardChannel channel, byte[] fid) + throws SignatureCardException, CardException { + + ResponseAPDU resp = channel.transmit( + new CommandAPDU(0x00, 0xA4, 0x00, 0x00, fid, 256)); + + if (resp.getSW() == 0x6A82) { + String msg = "File or application not found FID=" + + SMCCHelper.toString(fid) + " SW=" + + Integer.toHexString(resp.getSW()) + "."; + log.info(msg); + throw new FileNotFoundException(msg); + } else if (resp.getSW() != 0x9000) { + String msg = "Failed to select application FID=" + + SMCCHelper.toString(fid) + " SW=" + + Integer.toHexString(resp.getSW()) + "."; + log.error(msg); + throw new SignatureCardException(msg); + } else { + return resp.getBytes(); + } - /** - * throws SignatureCardException (PIN activation not supported by ACOS) - * @throws at.gv.egiz.smcc.SignatureCardException - */ - @Override - public void activatePIN(byte kid, char[] pin) - throws SignatureCardException { - log.error("ACTIVATE PIN not supported by ACOS"); - throw new SignatureCardException("PIN activation not supported by this card"); + } + + protected void execMSE(CardChannel channel, int p1, + int p2, byte[] data) throws SignatureCardException, CardException { - /** - * ASCII encoded pin, padded with 0x00 - * @param pin - * @return a 8 byte pin block - */ - @Override - protected byte[] encodePINBlock(char[] pin) { -// byte[] asciiPIN = new String(pin).getBytes(Charset.forName("ASCII")); - CharBuffer chars = CharBuffer.wrap(pin); - ByteBuffer bytes = Charset.forName("ASCII").encode(chars); - byte[] asciiPIN = bytes.array(); - byte[] encodedPIN = new byte[8]; - System.arraycopy(asciiPIN, 0, encodedPIN, 0, Math.min(asciiPIN.length, - encodedPIN.length)); -// System.out.println("ASCII encoded PIN block: " + SMCCHelper.toString(encodedPIN)); - return encodedPIN; + ResponseAPDU resp = channel.transmit( + new CommandAPDU(0x00, 0x22, p1, p2, data)); + + if (resp.getSW() != 0x9000) { + String msg = "MSE failed: SW=" + + Integer.toHexString(resp.getSW()); + log.error(msg); + throw new SignatureCardException(msg); + } + } - private byte[] getPINVerifyStructure(byte kid) { - - byte bTimeOut = reader.getbTimeOut(); - byte bTimeOut2 = reader.getbTimeOut2(); - byte bmFormatString = (byte) 0x82; // 1 0000 0 10 - // ^------------ System unit = byte - // ^^^^------- PIN position in the frame = 1 byte - // ^----- PIN justification left - // ^^-- ASCII format - byte bmPINBlockString = (byte) 0x08; // 0000 1000 - // ^^^^--------- PIN length size: 0 bits - // ^^^^---- Length PIN = 8 bytes - byte bmPINLengthFormat = (byte) 0x00; // 000 0 0000 - // ^-------- System bit units is bit - // ^^^^--- no PIN length - byte wPINMaxExtraDigitL = //TODO compare ints, not bytes - (reader.getwPINMaxExtraDigitL() < (byte) 0x08) ? - reader.getwPINMaxExtraDigitL() : (byte) 0x08; - byte wPINMaxExtraDigitH = - (reader.getwPINMaxExtraDigitH() > (byte) 0x00) ? - reader.getwPINMaxExtraDigitH() : (byte) 0x00; - byte bEntryValidationCondition = - reader.getbEntryValidationCondition(); - byte bNumberMessage = (byte) 0x00; // No message - byte wLangIdL = (byte) 0x0C; - byte wLangIdH = (byte) 0x04; - byte bMsgIndex = (byte) 0x00; - - byte[] apdu = new byte[] { - (byte) 0x00, (byte) 0x20, (byte) 0x00, kid, (byte) 0x08, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 - }; - - int offset = 0; - byte[] pinVerifyStructure = new byte[offset + 19 + apdu.length]; - pinVerifyStructure[offset++] = bTimeOut; - pinVerifyStructure[offset++] = bTimeOut2; - pinVerifyStructure[offset++] = bmFormatString; - pinVerifyStructure[offset++] = bmPINBlockString; - pinVerifyStructure[offset++] = bmPINLengthFormat; - pinVerifyStructure[offset++] = wPINMaxExtraDigitL; - pinVerifyStructure[offset++] = wPINMaxExtraDigitH; - pinVerifyStructure[offset++] = bEntryValidationCondition; - pinVerifyStructure[offset++] = bNumberMessage; - pinVerifyStructure[offset++] = wLangIdL; - pinVerifyStructure[offset++] = wLangIdH; - pinVerifyStructure[offset++] = bMsgIndex; - - pinVerifyStructure[offset++] = 0x00; - pinVerifyStructure[offset++] = 0x00; - pinVerifyStructure[offset++] = 0x00; - - pinVerifyStructure[offset++] = (byte) apdu.length; - pinVerifyStructure[offset++] = 0x00; - pinVerifyStructure[offset++] = 0x00; - pinVerifyStructure[offset++] = 0x00; - System.arraycopy(apdu, 0, pinVerifyStructure, offset, apdu.length); - - return pinVerifyStructure; + protected byte[] execPSO_DECIPHER(CardChannel channel, byte [] cipher) throws CardException, SignatureCardException { + + byte[] data = new byte[cipher.length + 1]; + data[0] = 0x00; + System.arraycopy(cipher, 0, data, 1, cipher.length); + ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0x2A, 0x80, 0x86, data, 256)); + if (resp.getSW() == 0x6982) { + throw new SecurityStatusNotSatisfiedException(); + } else if (resp.getSW() != 0x9000) { + throw new SignatureCardException( + "PSO - DECIPHER failed: SW=" + + Integer.toHexString(resp.getSW())); + } + + return resp.getData(); + } - public byte[] getPINModifyStructure(byte kid) { - - byte bTimeOut = reader.getbTimeOut(); - byte bTimeOut2 = reader.getbTimeOut2(); - byte bmFormatString = (byte) 0x82; // 1 0000 0 10 - // ^------------ System unit = byte - // ^^^^------- PIN position in the frame = 1 byte - // ^----- PIN justification left - // ^^-- ASCII format - byte bmPINBlockString = (byte) 0x08; // 0000 1000 - // ^^^^--------- PIN length size: 0 bits - // ^^^^---- Length PIN = 8 bytes - byte bmPINLengthFormat = (byte) 0x00; // 000 0 0000 - // ^-------- System bit units is bit - // ^^^^--- no PIN length - byte bInsertionOffsetOld = (byte) 0x00; // insertion position offset in bytes - byte bInsertionOffsetNew = (byte) 0x08; - byte wPINMaxExtraDigitL = - (reader.getwPINMaxExtraDigitL() < (byte) 0x08) ? - reader.getwPINMaxExtraDigitL() : (byte) 0x08; - byte wPINMaxExtraDigitH = - (reader.getwPINMaxExtraDigitH() > (byte) 0x00) ? - reader.getwPINMaxExtraDigitH() : (byte) 0x00; - byte bConfirmPIN = (byte) 0x03; - byte bEntryValidationCondition = - reader.getbEntryValidationCondition(); - byte bNumberMessage = (byte) 0x03; - byte wLangIdL = (byte) 0x0C; - byte wLangIdH = (byte) 0x04; - byte bMsgIndex1 = (byte) 0x00; - byte bMsgIndex2 = (byte) 0x01; - byte bMsgIndex3 = (byte) 0x02; - - byte[] apdu = new byte[] { - (byte) 0x00, (byte) 0x24, (byte) 0x00, kid, (byte) 0x10, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 - }; - - int offset = 0; - byte[] pinModifyStructure = new byte[offset + 24 + apdu.length]; - pinModifyStructure[offset++] = bTimeOut; - pinModifyStructure[offset++] = bTimeOut2; - pinModifyStructure[offset++] = bmFormatString; - pinModifyStructure[offset++] = bmPINBlockString; - pinModifyStructure[offset++] = bmPINLengthFormat; - pinModifyStructure[offset++] = bInsertionOffsetOld; - pinModifyStructure[offset++] = bInsertionOffsetNew; - pinModifyStructure[offset++] = wPINMaxExtraDigitL; - pinModifyStructure[offset++] = wPINMaxExtraDigitH; - pinModifyStructure[offset++] = bConfirmPIN; - pinModifyStructure[offset++] = bEntryValidationCondition; - pinModifyStructure[offset++] = bNumberMessage; - pinModifyStructure[offset++] = wLangIdL; - pinModifyStructure[offset++] = wLangIdH; - pinModifyStructure[offset++] = bMsgIndex1; - pinModifyStructure[offset++] = bMsgIndex2; - pinModifyStructure[offset++] = bMsgIndex3; - - pinModifyStructure[offset++] = 0x00; - pinModifyStructure[offset++] = 0x00; - pinModifyStructure[offset++] = 0x00; - - pinModifyStructure[offset++] = (byte) apdu.length; - pinModifyStructure[offset++] = 0x00; - pinModifyStructure[offset++] = 0x00; - pinModifyStructure[offset++] = 0x00; - System.arraycopy(apdu, 0, pinModifyStructure, offset, apdu.length); - - return pinModifyStructure; + protected void execPSO_HASH(CardChannel channel, byte[] hash) throws CardException, SignatureCardException { + + ResponseAPDU resp = channel.transmit( + new CommandAPDU(0x00, 0x2A, 0x90, 0x81, hash)); + if (resp.getSW() != 0x9000) { + throw new SignatureCardException("PSO - HASH failed: SW=" + + Integer.toHexString(resp.getSW())); + } + } + + protected byte[] execPSO_COMPUTE_DIGITAL_SIGNATURE(CardChannel channel) throws CardException, + SignatureCardException { - @Override - public String toString() { - return "a-sign premium"; + ResponseAPDU resp = channel.transmit( + new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, 256)); + if (resp.getSW() != 0x9000) { + throw new SignatureCardException( + "PSO - COMPUTE DIGITAL SIGNATRE failed: SW=" + + Integer.toHexString(resp.getSW())); + } else { + return resp.getData(); + } + + } + + protected byte[] execINTERNAL_AUTHENTICATE(CardChannel channel, byte[] hash) throws CardException, + SignatureCardException { + + byte[] digestInfo = new byte[] { (byte) 0x30, (byte) 0x21, (byte) 0x30, + (byte) 0x09, (byte) 0x06, (byte) 0x05, (byte) 0x2B, (byte) 0x0E, + (byte) 0x03, (byte) 0x02, (byte) 0x1A, (byte) 0x05, (byte) 0x00, + (byte) 0x04 }; + + byte[] data = new byte[digestInfo.length + hash.length + 1]; + + System.arraycopy(digestInfo, 0, data, 0, digestInfo.length); + data[digestInfo.length] = (byte) hash.length; + System.arraycopy(hash, 0, data, digestInfo.length + 1, hash.length); + + ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0x88, 0x10, 0x00, data, 256)); + if (resp.getSW() == 0x6982) { + throw new SecurityStatusNotSatisfiedException(); + } else if (resp.getSW() == 0x6983) { + throw new LockedException(); + } else if (resp.getSW() != 0x9000) { + throw new SignatureCardException("INTERNAL AUTHENTICATE failed: SW=" + + Integer.toHexString(resp.getSW())); + } else { + return resp.getData(); + } } } -- cgit v1.2.3 From a6575ed68434ead1b2ebdfe1563d9cd11a2d4007 Mon Sep 17 00:00:00 2001 From: clemenso Date: Thu, 6 Aug 2009 14:00:38 +0000 Subject: FIX [462] PINMgmtSignatureCard changePIN silently ignores wrong pin entry [63cX] git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@413 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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 9825978c..99aadebd 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -449,7 +449,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC // SELECT application execSELECT_AID(channel, pinSpec.getContextAID()); // VERIFY - verifyPIN(channel, pinSpec, pinProvider, -1); + verifyPINLoop(channel, pinSpec, pinProvider); } catch (CardException e) { log.info("Failed to verify PIN.", e); throw new SignatureCardException("Failed to verify PIN.", e); @@ -471,7 +471,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC // SELECT application execSELECT_AID(channel, pinSpec.getContextAID()); // CHANGE REFERENCE DATA - changePIN(channel, pinSpec, pinProvider, -1); + changePINLoop(channel, pinSpec, pinProvider); } catch (CardException e) { log.info("Failed to change PIN.", e); throw new SignatureCardException("Failed to change PIN.", e); @@ -531,7 +531,17 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC do { retries = verifyPIN(channel, spec, provider, retries); } while (retries > 0); - + } + + protected void changePINLoop(CardChannel channel, PINSpec spec, ChangePINProvider provider) + throws InterruptedException, LockedException, NotActivatedException, + TimeoutException, PINFormatException, PINOperationAbortedException, + SignatureCardException, CardException { + + int retries = -1; + do { + retries = changePIN(channel, spec, provider, retries); + } while (retries > 0); } protected int verifyPIN(CardChannel channel, PINSpec pinSpec, -- cgit v1.2.3 From 497f6336cc96cd3b2b4cd760774ec4c2ed892df2 Mon Sep 17 00:00:00 2001 From: clemenso Date: Thu, 13 Aug 2009 09:09:06 +0000 Subject: [#436] resolve "#PIN digits" message via message resource bundle git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@418 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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 99aadebd..414d4678 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -104,13 +104,13 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC }; private static final PINSpec DEC_PIN_SPEC = new PINSpec(0, 8, "[0-9]", - "at/gv/egiz/smcc/ACOSCard", "dec.pin.name", KID_PIN_DEC, AID_DEC); + "at/gv/egiz/smcc/ACOSCard", "dec.pin", KID_PIN_DEC, AID_DEC); private static final PINSpec SIG_PIN_SPEC = new PINSpec(0, 8, "[0-9]", - "at/gv/egiz/smcc/ACOSCard", "sig.pin.name", KID_PIN_SIG, AID_SIG); + "at/gv/egiz/smcc/ACOSCard", "sig.pin", KID_PIN_SIG, AID_SIG); private static final PINSpec INF_PIN_SPEC = new PINSpec(0, 8, "[0-9]", - "at/gv/egiz/smcc/ACOSCard", "inf.pin.name", KID_PIN_INF, AID_DEC); + "at/gv/egiz/smcc/ACOSCard", "inf.pin", KID_PIN_INF, AID_DEC); /** * The version of the card's digital signature application. -- cgit v1.2.3 From 68941b57df2caeead67a5bede2ef5a635d07db32 Mon Sep 17 00:00:00 2001 From: mcentner Date: Wed, 11 Nov 2009 15:51:08 +0000 Subject: Added support for SHA-256 and partial support for e-card G3, BELPIC and Italian cards. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@540 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 55 +++++++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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 414d4678..a63d4076 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -16,9 +16,13 @@ */ package at.gv.egiz.smcc; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.List; @@ -375,12 +379,46 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC @Override @Exclusive - public byte[] createSignature(byte[] hash, KeyboxName keyboxName, - PINProvider provider) throws SignatureCardException, InterruptedException { + public byte[] createSignature(InputStream input, KeyboxName keyboxName, + PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException { - if (hash.length != 20) { - throw new IllegalArgumentException("Hash value must be of length 20."); + ByteArrayOutputStream dst = new ByteArrayOutputStream(); + // key ID + dst.write(new byte[]{(byte) 0x84, (byte) 0x01, (byte) 0x88}); + // algorithm ID + dst.write(new byte[]{(byte) 0x80, (byte) 0x01}); + + MessageDigest md; + try { + if ("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1".equals(alg)) { + dst.write((byte) 0x14); // SHA-1/ECC + md = MessageDigest.getInstance("SHA-1"); + } else if ("http://www.w3.org/2000/09/xmldsig#rsa-sha1".equals(alg)) { + dst.write((byte) 0x12); // SHA-1 with padding according to PKCS#1 block type 01 + md = MessageDigest.getInstance("SHA-1"); + } else if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName) + && appVersion >= 2 + && "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256".equals(alg)) { + dst.write((byte) 0x44); // SHA-256/ECC + md = MessageDigest.getInstance("SHA256"); + } else if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName) + && appVersion >= 2 + && "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256".equals(alg)) { + dst.write((byte) 0x41); // SHA-256 with padding according to PKCS#1 + md = MessageDigest.getInstance("SHA256"); + } else { + throw new SignatureCardException("Card does not support signature algorithm " + alg + "."); + } + } catch (NoSuchAlgorithmException e) { + log.error("Failed to get MessageDigest.", e); + throw new SignatureCardException(e); } + + byte[] digest = new byte[md.getDigestLength()]; + for (int l; (l = input.read(digest)) != -1;) { + md.update(digest, 0, l); + } + digest = md.digest(); try { @@ -393,11 +431,11 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC // SELECT application execSELECT_AID(channel, AID_SIG); // MANAGE SECURITY ENVIRONMENT : SET DST - execMSE(channel, 0x41, 0xb6, DST_SIG); + execMSE(channel, 0x41, 0xb6, dst.toByteArray()); // VERIFY verifyPINLoop(channel, spec, provider); // PERFORM SECURITY OPERATION : HASH - execPSO_HASH(channel, hash); + execPSO_HASH(channel, digest); // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATRE return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel); @@ -413,7 +451,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC while (true) { try { // INTERNAL AUTHENTICATE - return execINTERNAL_AUTHENTICATE(channel, hash); + return execINTERNAL_AUTHENTICATE(channel, digest); } catch (SecurityStatusNotSatisfiedException e) { verifyPINLoop(channel, spec, provider); } @@ -711,6 +749,9 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC ResponseAPDU resp = channel.transmit( new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, 256)); + if (resp.getSW() == 0x6982) { + throw new SecurityStatusNotSatisfiedException(); + } if (resp.getSW() != 0x9000) { throw new SignatureCardException( "PSO - COMPUTE DIGITAL SIGNATRE failed: SW=" -- cgit v1.2.3 From 68651bf67987905980734f5c2199f337a232f427 Mon Sep 17 00:00:00 2001 From: mcentner Date: Thu, 12 Nov 2009 20:48:57 +0000 Subject: Added support for enforcing a PIN length in a CHANGE REFERENCE DATA to match the recommended PIN length via Applet parameter. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@541 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java index a63d4076..1ed5a177 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -116,6 +116,14 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC private static final PINSpec INF_PIN_SPEC = new PINSpec(0, 8, "[0-9]", "at/gv/egiz/smcc/ACOSCard", "inf.pin", KID_PIN_INF, AID_DEC); + static { + if (SignatureCardFactory.ENFORCE_RECOMMENDED_PIN_LENGTH) { + DEC_PIN_SPEC.setRecLength(4); + SIG_PIN_SPEC.setRecLength(6); + INF_PIN_SPEC.setRecLength(4); + } + } + /** * The version of the card's digital signature application. */ @@ -390,10 +398,12 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC MessageDigest md; try { - if ("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1".equals(alg)) { + if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName) + && (alg == null || "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1".equals(alg))) { dst.write((byte) 0x14); // SHA-1/ECC md = MessageDigest.getInstance("SHA-1"); - } else if ("http://www.w3.org/2000/09/xmldsig#rsa-sha1".equals(alg)) { + } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName) + && (alg == null || "http://www.w3.org/2000/09/xmldsig#rsa-sha1".equals(alg))) { dst.write((byte) 0x12); // SHA-1 with padding according to PKCS#1 block type 01 md = MessageDigest.getInstance("SHA-1"); } else if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName) @@ -401,7 +411,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC && "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256".equals(alg)) { dst.write((byte) 0x44); // SHA-256/ECC md = MessageDigest.getInstance("SHA256"); - } else if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName) + } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName) && appVersion >= 2 && "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256".equals(alg)) { dst.write((byte) 0x41); // SHA-256 with padding according to PKCS#1 -- cgit v1.2.3 From 3da4655d011dfc2f04f9e4ac28b38aee42d01bc0 Mon Sep 17 00:00:00 2001 From: clemenso Date: Tue, 5 Jan 2010 10:06:47 +0000 Subject: Features [#437] Handle pinpad [64:03] response apdu correctly [#445] pin entry feedback for VERIFY_PIN_START/FINISH [#471] Provide SecureViewer Link before Pinpad PinEntry timeout starts Bugs [#479] PIN Managment Applet allows unmatching new pin and pin confirmation [#480] PIN Management displays blocked PINs as ACTIVE [#486] Not possible to select 3 times in series the same item from signedReferencesList for display in secureViewer [#506] change pin dialog (gui) issues [#508] e-card G3 PIN activation (with TransportPIN) not supported [#509] closing secure viewer window (WINDOW_CLOSING) leaves "signature data is displayed in viewer" dialog in applet git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@565 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 44 +++++++++++++----------- 1 file changed, 24 insertions(+), 20 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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; -- cgit v1.2.3 From a5743a4e7157cb115cb1564d9327a426afac5ee0 Mon Sep 17 00:00:00 2001 From: mcentner Date: Tue, 19 Jan 2010 07:37:59 +0000 Subject: Fixes XSS vulnerability. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@577 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java') 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 b8cdb208..9b3b88ed 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -571,7 +571,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC @Override public String toString() { - return "a-sign premium"; + return "a-sign premium (version " + getAppVersion() + ")"; } //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3