summaryrefslogtreecommitdiff
path: root/smccTest/src/main/java/at/gv/egiz/smcc/activation/ActivationTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'smccTest/src/main/java/at/gv/egiz/smcc/activation/ActivationTest.java')
-rw-r--r--smccTest/src/main/java/at/gv/egiz/smcc/activation/ActivationTest.java265
1 files changed, 225 insertions, 40 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();
+ }
}