summaryrefslogtreecommitdiff
path: root/smccTest/src/main/java/at/gv
diff options
context:
space:
mode:
Diffstat (limited to 'smccTest/src/main/java/at/gv')
-rw-r--r--smccTest/src/main/java/at/gv/egiz/smcc/activation/ActivationTest.java265
-rw-r--r--smccTest/src/main/java/at/gv/egiz/smcc/activation/IdLinkTest.java40
-rw-r--r--smccTest/src/main/java/at/gv/egiz/smcctest/PKCS15Test.java15
3 files changed, 274 insertions, 46 deletions
diff --git a/smccTest/src/main/java/at/gv/egiz/smcc/activation/ActivationTest.java b/smccTest/src/main/java/at/gv/egiz/smcc/activation/ActivationTest.java
index c0d7ed73..d032d45e 100644
--- a/smccTest/src/main/java/at/gv/egiz/smcc/activation/ActivationTest.java
+++ b/smccTest/src/main/java/at/gv/egiz/smcc/activation/ActivationTest.java
@@ -2,17 +2,28 @@
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
-
package at.gv.egiz.smcc.activation;
+import at.gv.egiz.smcc.SignatureCardException;
+import at.gv.egiz.smcc.util.ISO7816Utils;
+import at.gv.egiz.smcc.util.TLVSequence;
+import iaik.asn1.ASN1;
+import iaik.asn1.ASN1Object;
+import iaik.asn1.CodingException;
+import iaik.asn1.DerCoder;
import iaik.security.provider.IAIK;
+import java.math.BigInteger;
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
+import java.security.spec.RSAPublicKeySpec;
import java.util.Arrays;
import java.util.List;
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 javax.smartcardio.TerminalFactory;
/**
@@ -21,55 +32,229 @@ import javax.smartcardio.TerminalFactory;
*/
public class ActivationTest {
- CardTerminal ct;
- Card icc;
+ CardTerminal ct;
+ Card icc;
+ CardChannel channel;
+
+ public void setUp() throws NoSuchAlgorithmException, CardException {
+
+ IAIK.addAsJDK14Provider();
+
+ System.out.println("create terminalFactory...\n");
+ TerminalFactory terminalFactory = TerminalFactory.getInstance("PC/SC", null);
+
+ System.out.println("get supported terminals...\n");
+ List<CardTerminal> terminals = terminalFactory.terminals().list();
+
+ if (terminals.size() < 1) {
+ throw new CardException("no terminals");
+ }
+
+ ct = terminals.get(0);
+ System.out.println("found " + terminals.size() + " terminals, using " + ct.getName() + "\n");
+
+ System.out.println("connecting " + ct.getName() + "\n");
+ icc = ct.connect("*");
+ byte[] atr = icc.getATR().getBytes();
+ byte[] historicalBytes = icc.getATR().getHistoricalBytes();
+ System.out.println("found card " + toString(atr) + " " + new String(historicalBytes, Charset.forName("ASCII")) + "\n\n");
+
+ channel = icc.getBasicChannel();
+ }
+
+ public void getSVNr() throws CardException {
+ CommandAPDU cmdAPDU;
+ ResponseAPDU resp;
+
+ System.out.println("SELECT MF");
+ cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0c, new byte[]{(byte) 0x3f, (byte) 0x00});
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
+
+ System.out.println("SELECT DF_SVPersonendaten");
+ // P1=0x00 -> 6a:80 (incorrect cmd data)
+ // no Le -> 67:00 (wrong length)
+ cmdAPDU = new CommandAPDU(0x00, 0xa4, 0x01, 0x00, new byte[]{(byte) 0x3f, (byte) 0x01}, 256);
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
+
+ if (resp.getSW() == 0x9000) {
+ System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x6f)));
+ }
+
+ System.out.println("SELECT EF.Grunddaten");
+ // P2=00, Le present -> 67:00
+ cmdAPDU = new CommandAPDU(0x00, 0xa4, 0x02, 0x0c, new byte[]{(byte) 0xef, (byte) 0x01});
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
+
+ System.out.println("READ EF.Grunddaten");
+ // 7.2.2 (case2), offset=0
+ cmdAPDU = new CommandAPDU(0x00, 0xb0, 0x00, 0x00, 256);
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
+
+ try {
+ ASN1Object grunddaten = DerCoder.decode(resp.getData());
+ System.out.println(ASN1.print(grunddaten));
+
+ // ensure OID 1.2.40.0.10.1.4.1.1
+ System.out.println("oid: " + (String) grunddaten.getComponentAt(0).getComponentAt(0).getValue());
+ System.out.println("svNr: " + (String) grunddaten.getComponentAt(0).getComponentAt(1).getComponentAt(0).getValue());
+ } catch (CodingException ex) {
+ ex.printStackTrace();
+ }
+ }
- public void setUp() throws NoSuchAlgorithmException, CardException {
+ public byte[] getCIN() throws CardException, SignatureCardException {
+ CommandAPDU cmdAPDU;
+ ResponseAPDU resp;
- IAIK.addAsJDK14Provider();
+ System.out.println("SELECT MF");
+ cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0c, new byte[]{(byte) 0x3F, (byte) 0x00});
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
- System.out.println("create terminalFactory...\n");
- TerminalFactory terminalFactory = TerminalFactory.getInstance("PC/SC", null);
+ System.out.println("SELECT EF.GDO");
+ // alternative: read with SFI=02: 00 b0 82 00 fa
+ // P1=0x00 -> 6a:80 (incorrect cmd data)
+ // no Le -> 67:00 (wrong length)
+ cmdAPDU = new CommandAPDU(0x00, 0xa4, 0x02, 0x00, new byte[] {(byte) 0x2f, (byte) 0x02}, 256);
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
- System.out.println("get supported terminals...\n");
- List<CardTerminal> terminals = terminalFactory.terminals().list();
+ System.out.println("READ EF.GDO");
+ // 7.2.2 (case2), offset=0
+ cmdAPDU = new CommandAPDU(0x00, 0xb0, 0x00, 0x00, 256);
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
- if (terminals.size() < 1) {
- throw new CardException("no terminals");
+ if (resp.getSW() == 0x9000) {
+ byte[] cin = new TLVSequence(resp.getData()).getValue(0x5a);
+ System.out.println("CIN: " + toString(cin));
+ return cin;
+ } else {
+ throw new SignatureCardException("Failed to read EF.GDO: 0x" + Integer.toHexString(resp.getSW()));
+ }
}
- ct = terminals.get(0);
- System.out.println("found " + terminals.size() + " terminals, using " + ct.getName() + "\n");
-
- System.out.println("connecting " + ct.getName() + "\n");
- icc = ct.connect("*");
- byte[] atr = icc.getATR().getBytes();
- byte[] historicalBytes = icc.getATR().getHistoricalBytes();
- System.out.println("found card " + toString(atr) + " " + new String(historicalBytes, Charset.forName("ASCII")) + "\n\n");
-
- }
-
- public static String toString(byte[] b) {
- StringBuffer sb = new StringBuffer();
- sb.append('[');
- if (b != null && b.length > 0) {
- sb.append(Integer.toHexString((b[0] & 240) >> 4));
- sb.append(Integer.toHexString(b[0] & 15));
- for (int i = 1; i < b.length; i++) {
- sb.append((i % 32 == 0) ? '\n' : ':');
- sb.append(Integer.toHexString((b[i] & 240) >> 4));
- sb.append(Integer.toHexString(b[i] & 15));
- }
+ public static String toString(byte[] b) {
+ StringBuffer sb = new StringBuffer();
+ sb.append('[');
+ if (b != null && b.length > 0) {
+ sb.append(Integer.toHexString((b[0] & 240) >> 4));
+ sb.append(Integer.toHexString(b[0] & 15));
+ for (int i = 1; i < b.length; i++) {
+ sb.append((i % 32 == 0) ? '\n' : ':');
+ sb.append(Integer.toHexString((b[i] & 240) >> 4));
+ sb.append(Integer.toHexString(b[i] & 15));
+ }
+ }
+ sb.append(']');
+ return sb.toString();
}
- sb.append(']');
- return sb.toString();
- }
- public static void main(String[] args) throws NoSuchAlgorithmException, CardException {
+ public void getPuK_GewSig() throws CardException, SignatureCardException, CodingException {
+ CommandAPDU cmdAPDU;
+ ResponseAPDU resp;
+
+ System.out.println("SELECT MF");
+ cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0c, new byte[]{(byte) 0x3f, (byte) 0x00});
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
+
+ System.out.println("SELECT DF.QualifizierteSignatur");
+ // P1=0x00 -> 67:00 (wrong length)
+ cmdAPDU = new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, new byte[] {(byte) 0xd0, (byte) 0x40, (byte) 0x00, (byte) 0x00, (byte) 0x17, (byte) 0x00, (byte) 0x12, (byte) 0x01});
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
+
+ System.out.println("SELECT EF.PrKD");
+ // P1=0x00 -> 67:00 (wrong length)
+ cmdAPDU = new CommandAPDU(0x00, 0xa4, 0x02, 0x04, new byte[] {(byte) 0x50, (byte) 0x35}, 256);
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
+
+ System.out.println("READ EF.PrKD");
+ cmdAPDU = new CommandAPDU(0x00, 0xb0, 0x00, 0x00, 256);
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
+
+ ASN1Object efPrK_QS = DerCoder.decode(resp.getData());
+ System.out.println(ASN1.print(efPrK_QS));
+
+ String label = (String) efPrK_QS.getComponentAt(0).getComponentAt(0).getValue();
+ System.out.println("PrK_QS label: " + label);
+ byte[] authObjId = (byte[]) efPrK_QS.getComponentAt(0).getComponentAt(2).getValue();
+ System.out.println("PrK_QS authObjId: " + toString(authObjId));
+ byte[] id = (byte[]) efPrK_QS.getComponentAt(1).getComponentAt(0).getValue();
+ System.out.println("PrK_QS Id: " + toString(id));
+ BigInteger keyRef = (BigInteger) efPrK_QS.getComponentAt(1).getComponentAt(4).getValue();
+ System.out.println("PrK_QS keyRef: 0x" + Integer.toHexString(keyRef.intValue()) + "\n");
+
+ int dfSpecificKeyRef = 1;
+ byte[] crt_at = new byte[] {
+ (byte) 0x83, (byte) 0x01, (byte) (0x80 | (0x7f & dfSpecificKeyRef)),
+ // algorithm id 0x54???
+ (byte) 0x80, (byte) 0x01, (byte) 0x54
+ };
+
+ System.out.println("MSE SET AT for key agreement");
+ cmdAPDU = new CommandAPDU(0x00, 0x22, 0x81, 0xa4, crt_at);
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
- ActivationTest test = new ActivationTest();
- test.setUp();
+ System.out.println("GET CHALLENGE");
+ // eg. RNDICC = [ed:9b:a3:78:83:2f:d3:6c:90:00]
+ cmdAPDU = new CommandAPDU(0x00, 0x84, 0x00, 0x00, 0x08);
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
- }
+ // ICCSN + RNDICC => Kryptogramm_CRS (STARCOS31, p357 authentication according to e-SignK)
+ // MUTUALAUTH -> Kryptogramm_Karte -> prüfung -> session key
+ System.out.println("MUTUAL AUTHENTICATE TODO...");
+
+
+ System.out.println("SELECT EF.PuK_QS");
+ // P1=0x00 -> 67:00 (wrong length)
+ cmdAPDU = new CommandAPDU(0x00, 0xa4, 0x02, 0x04, new byte[] {(byte) 0x0e, (byte) 0x01}, 256);
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
+
+ System.out.println("READ EF.PuK_QS");
+ // 7.2.2 (case2), offset=0
+ cmdAPDU = new CommandAPDU(0x00, 0xb0, 0x00, 0x00, 256);
+ System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
+ resp = channel.transmit(cmdAPDU);
+ System.out.println(" -> " + toString(resp.getBytes()) + "\n");
+
+ System.out.println("PuK_QS:\n" + toString(resp.getData()));
+
+
+ }
+
+
+ public static void main(String[] args) throws NoSuchAlgorithmException, CardException, SignatureCardException, CodingException {
+
+ ActivationTest test = new ActivationTest();
+ test.setUp();
+// test.getCIN();
+// test.getSVNr();
+ test.getPuK_GewSig();
+ }
}
diff --git a/smccTest/src/main/java/at/gv/egiz/smcc/activation/IdLinkTest.java b/smccTest/src/main/java/at/gv/egiz/smcc/activation/IdLinkTest.java
new file mode 100644
index 00000000..2950ef90
--- /dev/null
+++ b/smccTest/src/main/java/at/gv/egiz/smcc/activation/IdLinkTest.java
@@ -0,0 +1,40 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package at.gv.egiz.smcc.activation;
+
+import iaik.asn1.ASN1;
+import iaik.asn1.ASN1Object;
+import iaik.asn1.CodingException;
+import iaik.asn1.DerCoder;
+import iaik.utils.Base64InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+
+/**
+ *
+ * @author clemens
+ */
+public class IdLinkTest {
+
+ public static final String IdLink = "MIICCAIBAQwmaHR0cDovL3d3dy5hLXRydXN0LmF0L3ptci9wZXJzYjIwNC54c2wMKXN6ci5ibWkuZ3YuYXQtQXNzZXJ0aW9uSUQxMjY5MzM5ODczNzM2MjY1DBkyMDEwLTAzLTIzVDExOjI0OjMzKzAxOjAwoDkwNwwYbys5TmQ4bHQ1a09SdUtuaFhUK0h3UT09DANNYXgMCk11c3Rlcm1hbm4MCjE5NDAtMDEtMDEwCqADAgEAoAMCAQEDggEBACkl33tK+BTbHi842hSYTpcn87GH0FNayE70z7Ohg4BDB84hc3eM6e8Nslt2nTMnjInf1sJzJYRVDMopE8VVIDmtSoGnz9Tu5U06tuIM87Lv9tgGUzDqn9fdZIyWs9eTJHHYOIwh16ISvgswKV1iioE55g5GaW3G+fCTbgdq5I0TuE4jRP7YwMXLtLulRes1e3Y4Hvv3PgACDkafzZVbWlD9WpK/eCQ75YTBev9KM0YWJ/w3yaWAMoukI2c2H1T4nmc1/3b/1q+XzuEQPuugDYPbV4myD55/W0J6WqOKA2e3NfWswPqxfr1TLcoR+TZ/18BYrNv2s1ZyQ5ZrZ164UKKgFwMVAN6gGAcGTABXOTAw5MDMsVeS7Tj0oRcDFQARNKXtL0cSdwP8Co74fdURaskUzqIXAxUAlWlQLXBfizrWKBahBj4IcJ+xUl4=";
+
+ protected void decodeIdLink(InputStream idLinkDER) throws UnsupportedEncodingException, IOException, CodingException {
+ ASN1Object idLink = DerCoder.decode(idLinkDER);
+ System.out.println(ASN1.print(idLink));
+ }
+
+ public static void main(String[] args) throws UnsupportedEncodingException, IOException, CodingException {
+
+ IdLinkTest test = new IdLinkTest();
+ test.decodeIdLink(new Base64InputStream(new ByteArrayInputStream(IdLink.getBytes())));
+
+ }
+
+}
+
diff --git a/smccTest/src/main/java/at/gv/egiz/smcctest/PKCS15Test.java b/smccTest/src/main/java/at/gv/egiz/smcctest/PKCS15Test.java
index d3035c8a..5a184680 100644
--- a/smccTest/src/main/java/at/gv/egiz/smcctest/PKCS15Test.java
+++ b/smccTest/src/main/java/at/gv/egiz/smcctest/PKCS15Test.java
@@ -133,7 +133,7 @@ public class PKCS15Test {
// resp = basicChannel.transmit(cmdAPDU);
// }
// }
-
+
System.out.println("SELECT DF.CIA");
// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x04, 0x00, new byte[] { (byte) 0xE8, (byte) 0x28, (byte) 0xBD, (byte) 0x08, (byte) 0x0F }, 256);
cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x04, 0x00, new byte[] { (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x63,(byte) 0x50,(byte) 0x4B,(byte) 0x43,(byte) 0x53,(byte) 0x2D,(byte) 0x31,(byte) 0x35 }, 256);
@@ -161,7 +161,7 @@ public class PKCS15Test {
// }
- System.out.println("SELECT EF 0x0b 0X02");
+ System.out.println("SELECT EF 0x0b 0x02");
cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, new byte[] { (byte) 0x0B,(byte) 0x02 }, 256);
System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes()));
resp = basicChannel.transmit(cmdAPDU);
@@ -542,9 +542,12 @@ public class PKCS15Test {
// resp = basicChannel.transmit(cmdAPDU);
// System.out.println(" -> " + toString(resp.getBytes()) + "\n");
+ int i = 1;
byte[] dst = new byte[] {
- // key 0x81?
- (byte) 0x84, (byte) 0x01, (byte) 0x81,
+ // 3 byte keyRef (key number 1)
+// (byte) 0x84, (byte) 0x03, (byte) 0x80, (byte) 0x01, (byte) 0xff,
+ // 1 byte keyRef (key number 1)
+ (byte) 0x84, (byte) 0x01, (byte) (0x80 | (i & 0x7f)),
//RSA Authentication
(byte) 0x89, (byte) 0x02, (byte) 0x23, (byte) 0x13
};
@@ -1085,8 +1088,8 @@ public class PKCS15Test {
System.out.println("manually running pkcs15 test...");
PKCS15Test test = new PKCS15Test();
test.setUp();
- test.getEFDIR();
-// test.sign();
+// test.getEFDIR();
+ test.sign();
// test.selectAndRead();
} catch (Exception ex) {
ex.printStackTrace();