From 18c4cd1c0a5665dde4bf6540fc0e5c9c03ea1833 Mon Sep 17 00:00:00 2001 From: clemenso Date: Tue, 14 Dec 2010 18:09:17 +0000 Subject: activation git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@853 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../at/gv/egiz/smcc/activation/ActivationTest.java | 265 +++++++++++++++++---- 1 file changed, 225 insertions(+), 40 deletions(-) (limited to 'smccTest/src/main/java/at/gv/egiz/smcc/activation/ActivationTest.java') 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 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 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(); + } } -- cgit v1.2.3