From 7229336487111d6b17fb2693e6a9ef52283c08c9 Mon Sep 17 00:00:00 2001 From: clemenso Date: Fri, 5 Nov 2010 12:48:37 +0000 Subject: mv PKCS15Test to main classes (distribute jar) git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@821 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smccTest/pom.xml | 5 +- .../src/main/java/at/gv/egiz/smcc/util/TLV.java | 84 ++ .../java/at/gv/egiz/smcc/util/TLVSequence.java | 83 ++ .../main/java/at/gv/egiz/smcctest/CardTest.java | 2 +- .../main/java/at/gv/egiz/smcctest/PKCS15Test.java | 1030 ++++++++++++++++++++ .../java/at/gv/egiz/pkcs15test/PKCS15Test.java | 1023 ------------------- .../src/test/java/at/gv/egiz/pkcs15test/TLV.java | 82 -- .../java/at/gv/egiz/pkcs15test/TLVSequence.java | 81 -- 8 files changed, 1200 insertions(+), 1190 deletions(-) create mode 100644 smccTest/src/main/java/at/gv/egiz/smcc/util/TLV.java create mode 100644 smccTest/src/main/java/at/gv/egiz/smcc/util/TLVSequence.java create mode 100644 smccTest/src/main/java/at/gv/egiz/smcctest/PKCS15Test.java delete mode 100644 smccTest/src/test/java/at/gv/egiz/pkcs15test/PKCS15Test.java delete mode 100644 smccTest/src/test/java/at/gv/egiz/pkcs15test/TLV.java delete mode 100644 smccTest/src/test/java/at/gv/egiz/pkcs15test/TLVSequence.java diff --git a/smccTest/pom.xml b/smccTest/pom.xml index f6730795..51ca3449 100644 --- a/smccTest/pom.xml +++ b/smccTest/pom.xml @@ -1,5 +1,4 @@ - + 4.0.0 mocca @@ -21,7 +20,7 @@ true lib/ - at.gv.egiz.smcctest.CardTest + at.gv.egiz.smcctest.PKCS15Test diff --git a/smccTest/src/main/java/at/gv/egiz/smcc/util/TLV.java b/smccTest/src/main/java/at/gv/egiz/smcc/util/TLV.java new file mode 100644 index 00000000..b67fe3fa --- /dev/null +++ b/smccTest/src/main/java/at/gv/egiz/smcc/util/TLV.java @@ -0,0 +1,84 @@ +package at.gv.egiz.smcc.util; + + + +/* + * Copyright 2009 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. + */ + +public class TLV { + + private byte[] bytes; + private int start; + + public TLV(byte[] bytes, int start) { + if (bytes.length - start < 2) { + throw new IllegalArgumentException("TLV must at least consit of tag and length."); + } + this.bytes = bytes; + this.start = start; + } + + /** + * @return the tag + */ + public int getTag() { + return 0xFF & bytes[start]; + } + + /** + * @return the length + */ + public int getLength() { + return 0xFF & bytes[start + 1]; + } + + /** + * @return the value + */ + public byte[] getValue() { + byte[] value = new byte[getLength()]; + System.arraycopy(bytes, start + 2, value, 0, value.length); + return value; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "Tag = " + Integer.toHexString(getTag()) + ", Length = " + getLength() + ", Value = " + toString(getValue()); + } + + 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(); + } + + + +} diff --git a/smccTest/src/main/java/at/gv/egiz/smcc/util/TLVSequence.java b/smccTest/src/main/java/at/gv/egiz/smcc/util/TLVSequence.java new file mode 100644 index 00000000..fc29a7e7 --- /dev/null +++ b/smccTest/src/main/java/at/gv/egiz/smcc/util/TLVSequence.java @@ -0,0 +1,83 @@ +package at.gv.egiz.smcc.util; + + + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/* + * Copyright 2009 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. + */ + +public class TLVSequence implements Iterable { + + private byte[] bytes; + + public TLVSequence(byte[] bytes) { + this.bytes = bytes; + } + + @Override + public Iterator iterator() { + return new TLVIterator(); + } + + public byte[] getValue(int tag) { + for (TLV tlv : this) { + if (tlv.getTag() == tag) { + return tlv.getValue(); + } + } + return null; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (TLV tlv : this) { + sb.append(tlv).append('\n'); + } + return sb.toString(); + } + + private class TLVIterator implements Iterator { + + private int pos = 0; + + @Override + public boolean hasNext() { + return (bytes.length - pos > 2); + } + + @Override + public TLV next() { + if (hasNext()) { + TLV tlv = new TLV(bytes, pos); + pos += tlv.getLength() + 2; + return tlv; + } else { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + } + +} diff --git a/smccTest/src/main/java/at/gv/egiz/smcctest/CardTest.java b/smccTest/src/main/java/at/gv/egiz/smcctest/CardTest.java index 8eadf13e..393d49ef 100644 --- a/smccTest/src/main/java/at/gv/egiz/smcctest/CardTest.java +++ b/smccTest/src/main/java/at/gv/egiz/smcctest/CardTest.java @@ -59,7 +59,7 @@ public class CardTest { // Certificates try { System.out.println("--- Certificate " + keyboxName + " ---"); - byte[] certificate = signatureCard.getCertificate(keyboxName); + byte[] certificate = signatureCard.getCertificate(keyboxName, null); Certificate cert = certificateFactory.generateCertificate(new ByteArrayInputStream(certificate)); System.out.println(cert); } catch (SignatureCardException e) { diff --git a/smccTest/src/main/java/at/gv/egiz/smcctest/PKCS15Test.java b/smccTest/src/main/java/at/gv/egiz/smcctest/PKCS15Test.java new file mode 100644 index 00000000..1f032554 --- /dev/null +++ b/smccTest/src/main/java/at/gv/egiz/smcctest/PKCS15Test.java @@ -0,0 +1,1030 @@ +package at.gv.egiz.smcctest; + +import at.gv.egiz.smcc.SignatureCardException; +import at.gv.egiz.smcc.VerifyAPDUSpec; +import at.gv.egiz.smcc.util.ISO7816Utils; +import at.gv.egiz.smcc.util.TLV; +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 iaik.security.ecc.provider.ECCProvider; + +import iaik.security.provider.IAIK; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.Charset; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.Signature; +import java.security.SignatureException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +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; +//import org.junit.After; +//import org.junit.AfterClass; +//import org.junit.Before; +//import org.junit.BeforeClass; +//import org.junit.Ignore; +//import org.junit.Test; +//import org.opensc.pkcs15.asn1.PKCS15Certificate; +//import org.opensc.pkcs15.asn1.PKCS15Objects; +//import org.opensc.pkcs15.asn1.sequence.SequenceOf; + + + +/** + * + * @author clemens + */ +public class PKCS15Test { + + CardTerminal ct; + Card icc; + boolean liezert; + + public PKCS15Test() { + } + +// @BeforeClass + public static void setUpClass() throws Exception { + } + +// @AfterClass + public static void tearDownClass() throws Exception { + } + +// @Before + public void setUp() throws NoSuchAlgorithmException, CardException { + + IAIK.addAsJDK14Provider(); + ECCProvider.addAsProvider(); + + 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(); + liezert = Arrays.equals(atr, new byte[] {(byte) 0x3b, (byte) 0xbb, (byte) 0x18, (byte) 0x00, (byte) 0xc0, (byte) 0x10, (byte) 0x31, (byte) 0xfe, (byte) 0x45, (byte) 0x80, (byte) 0x67, (byte) 0x04, (byte) 0x12, (byte) 0xb0, (byte) 0x03, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x81, (byte) 0x05, (byte) 0x3c}); + byte[] historicalBytes = icc.getATR().getHistoricalBytes(); + System.out.println("found card " + toString(atr) + " " + new String(historicalBytes, Charset.forName("ASCII")) + "\n\n"); + + } + +// @After + public void tearDown() { + } + +// @Test +// @Ignore + public void getEFDIR() throws CardException, SignatureCardException, InstantiationException, CodingException { + + CardChannel basicChannel = icc.getBasicChannel(); + CommandAPDU cmdAPDU; + ResponseAPDU resp; + + System.out.println("SELECT MF"); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0c, new byte[] { 0x3F, 0x00}); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + +// for (int i = 0x1F00; i <= 0xFFFF; i++) { +//// for (int i = 0x5000; i <= 0x6000; i++) { +// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x01, 0x00, new byte[] { (byte) ((i >> 8) & 0xFF), (byte) (i & 0xFF)}, 256); +// resp = basicChannel.transmit(cmdAPDU); +// if ((i & 0xFF) == 0) { +// System.out.println(Integer.toHexString(i)); +// } +// if (resp.getSW() == 0x9000) { +// System.out.println("found [" + Integer.toHexString((i >> 8) & 0xff) + ":" + Integer.toHexString((i) & 0xff) + "]"); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); +// +// byte[] fcx = new TLVSequence(resp.getBytes()).getValue(0x6f); +// System.out.println(Integer.toHexString(i) + ": " + new TLVSequence(fcx)); +// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0C, new byte[] { 0x3F, 0x00}); +// 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); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + +// for (int i = 0x1F00; i <= 0xFFFF; i++) { +//// for (int i = 0x5000; i <= 0x6000; i++) { +// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, new byte[] { (byte) ((i >> 8) & 0xFF), (byte) (i & 0xFF)}, 256); +// resp = basicChannel.transmit(cmdAPDU); +// if ((i & 0xFF) == 0) { +// System.out.println(Integer.toHexString(i)); +// } +// if (resp.getSW() == 0x9000) { +// System.out.println("found [" + Integer.toHexString((i >> 8) & 0xff) + ":" + Integer.toHexString((i) & 0xff) + "]"); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); +// +// byte[] fcx = new TLVSequence(resp.getBytes()).getValue(0x6f); +// System.out.println(Integer.toHexString(i) + ": " + new TLVSequence(fcx)); +// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0C, new byte[] { 0x3F, 0x00}); +// resp = basicChannel.transmit(cmdAPDU); +// } +// } + + + 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); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + + System.out.println("SELECT EF.CardInfo (P1=02 P2=00)"); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, new byte[] { (byte) 0x50,(byte) 0x32 }, 256); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + System.out.println("READ EF.CardInfo"); + byte[] efCardInfo = ISO7816Utils.readTransparentFile(basicChannel, -1); + System.out.println(toString(efCardInfo)); + ASN1Object efCardInfoASN1 = DerCoder.decode(efCardInfo); +// try { +// FileOutputStream os = new FileOutputStream("EF.CardInfo"); +// os.write(efCardInfo); +// os.close(); +// } catch (FileNotFoundException e) { +// e.printStackTrace(); +// } catch (IOException e) { +// e.printStackTrace(); +// } + System.out.println(ASN1.print(efCardInfoASN1)); + + System.out.println("SELECT EF.OD"); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, new byte[] { (byte) 0x50,(byte) 0x31 }, 256); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + System.out.println("READ EF.OD"); + byte[] efod = ISO7816Utils.readTransparentFile(basicChannel, -1); + System.out.println(" " + toString(efod)); + + for (TLV cio : new TLVSequence(efod)) { + + System.out.println("\n\nTag = " + cio.getTag()); + if (cio.getTag() == 0) { + System.out.println("cannot decode null data"); + continue; + } + + ASN1Object object = DerCoder.decode(cio.getValue()); + byte[] fid = (byte[]) object.getComponentAt(0).getValue(); + + System.out.println("SELECT EF fid=" + toString(fid)); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x04, fid, 256); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + byte[] fcx = new TLVSequence(resp.getBytes()).getValue(0x62); //0x62 for FCP, 0x6f for FCI + byte[] fd = new TLVSequence(fcx).getValue(0x82); + +// System.out.println("cio " + toString(fid) + " fd: " + toString(fd)); + + if ((fd[0] & 0x04) > 0) { + // records + int records = fd[fd.length - 1]; + + for (int record = 1; record < records; record++) { + System.out.println("READ RECORD " + record); + byte[] ef = ISO7816Utils.readRecord(basicChannel, record); + System.out.println(" " + toString(ef)); + ASN1Object informationObject = DerCoder.decode(Arrays.copyOfRange(ef, 2, ef.length)); + System.out.println(ASN1.print(informationObject)); + if (cio.getTag() == 0xa0 || cio.getTag() == 0xa1) { + System.out.println("Path = " + + toString((byte[]) informationObject.getComponentAt(3) + .getComponentAt(0).getComponentAt(0).getComponentAt(0) + .getValue())); + } + } + + } else if (fd[0] == 0x11) { + System.out.println("transparent structure"); + + byte[] ef = ISO7816Utils.readTransparentFile(basicChannel, -1); +// System.out.println(" " + toString(ef)); + + int length; + int i = 0; + int j; + + do { + System.out.println("tag: 0x" + Integer.toHexString(ef[i]) + ", length: 0x" + Integer.toHexString(ef[i+1])); + if ((ef[i+1] & 0xff) == 0x81) { + length = ef[i+2] & 0xff; + j = 3; +// System.out.println("ef["+(i+1)+"]=0x81, setting length=" + (ef[i+2] & 0xff)); + + } else if ((ef[i+1] & 0xff) == 0x82) { + length = ((ef[i+2] & 0xff) << 8) | (ef[i+3] & 0xff); + j = 4; +// System.out.println("ef["+(i+1)+"]=0x82, setting length=" + (((ef[i+2] & 0xff) << 8) | (ef[i+3] & 0xff))); + + } else { + length = ef[i+1] & 0xff; + j = 2; +// System.out.println("ef["+(i+1)+"]=0x" + Integer.toBinaryString(ef[i+1] & 0xff)); + } + + System.out.println("setting length: 0x" + Integer.toHexString(length)); + +// if (cio.getTag() == 0xa4) { +// byte[] cert = Arrays.copyOfRange(ef, 0, ef.length-1); +//// System.out.println("cert 1: \n " + toString(cert)); + + j = i + j + length; + System.out.println("reading ef[" + i +"-" + (j-1) + "]:\n" + toString(Arrays.copyOfRange(ef, i, j)) ); + ASN1Object informationObject = DerCoder.decode(Arrays.copyOfRange(ef, i, j)); + System.out.println(ASN1.print(informationObject)); + i = j; + } while (i0); + } + } + + +// System.out.println("SELECT by Path"); +// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x09, 0x00, new byte[] { (byte) 0x3F, (byte) 0x00, (byte) 0x56, (byte) 0x49 }, 256); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); +// +// System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x6f))); +// +// byte[] ef = ISO7816Utils.readTransparentFile(basicChannel, -1); +// System.out.println(toString(ef)); +// +// try { +// FileOutputStream fileOutputStream = new FileOutputStream("EF.IV"); +// fileOutputStream.write(ef); +// fileOutputStream.close(); +// } catch (FileNotFoundException e1) { +// e1.printStackTrace(); +// } catch (IOException e1) { +// e1.printStackTrace(); +// } +// +// System.out.println("done."); + + } + +// @Test +// @Ignore + public void ecard() throws CardException, SignatureCardException, CodingException { + CardChannel basicChannel = icc.getBasicChannel(); + 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 = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + System.out.println("SELECT EF.CardInfo (P1=02 P2=00)"); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, new byte[] { (byte) 0x50,(byte) 0x32 }, 256); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + System.out.println("READ EF.CardInfo"); + byte[] efCardInfo = ISO7816Utils.readTransparentFile(basicChannel, -1); + System.out.println(toString(efCardInfo)); + ASN1Object efCardInfoASN1 = DerCoder.decode(efCardInfo); + System.out.println(ASN1.print(efCardInfoASN1)); + + cmdAPDU = new CommandAPDU(0x00, 0xa4, 0x04, 0x00, new byte[] { (byte) 0xd0, (byte) 0x40, + (byte) 0x00, (byte) 0x00, (byte) 0x17, (byte) 0x00, (byte) 0x12, + (byte) 0x01 }, 256); + System.out.println("SELECT AID " + toString(cmdAPDU.getData())); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x6f))); + + System.out.println("SELECT CERTIFICATE"); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, new byte[] { (byte) 0xc0, (byte) 0x00 }, 256); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + X509Certificate certificate = null; + try { + System.out.println("READ cert?"); + CertificateFactory certificateFactory = CertificateFactory.getInstance("X509"); + certificate = (X509Certificate) certificateFactory.generateCertificate(ISO7816Utils.openTransparentFileInputStream(basicChannel, -1)); +// certificate = certificateFactory.generateCertificate(new BASE64DecoderStream(new ByteArrayInputStream(CERT.getBytes()))); +// System.out.println("certificate: \n" + toString(certificate.getEncoded())); + System.out.println("certificate: \n" + certificate); + } catch (CertificateException e) { + e.printStackTrace(); + } + + byte[] fid = new byte[] {(byte) 0x00, (byte) 0x30 }; + System.out.println("SELECT EF FID=" + toString(fid)); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x04, fid, 256); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x62))); + + byte[] fcx = new TLVSequence(resp.getBytes()).getValue(0x62); //0x62 for FCP, 0x6f for FCI + byte[] fd = new TLVSequence(fcx).getValue(0x82); + +// System.out.println("cio " + toString(fid) + " fd: " + toString(fd)); + + if ((fd[0] & 0x04) > 0) { + // records + int records = fd[fd.length - 1]; + + for (int record = 1; record < records-1; record++) { + System.out.println("READ RECORD " + record); + byte[] ef = ISO7816Utils.readRecord(basicChannel, record); + System.out.println(" " + toString(ef)); + } + } + } + + +// @Test +// @Ignore + public void sign() throws CardException, SignatureCardException, InstantiationException, CodingException { + CardChannel basicChannel = icc.getBasicChannel(); + CommandAPDU cmdAPDU; + ResponseAPDU resp; + + System.out.println("SELECT DF.CIA"); + 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); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + System.out.println("SELECT CERTIFICATE"); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, new byte[] { (byte) 0x0c, (byte) 0x02 }, 256); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + Certificate certificate = null; + try { + System.out.println("READ cert?"); + CertificateFactory certificateFactory = CertificateFactory.getInstance("X509"); + certificate = certificateFactory.generateCertificate(ISO7816Utils.openTransparentFileInputStream(basicChannel, -1)); +// certificate = certificateFactory.generateCertificate(new BASE64DecoderStream(new ByteArrayInputStream(CERT.getBytes()))); + System.out.println("certificate: \n" + toString(certificate.getEncoded())); + } catch (CertificateException e) { + e.printStackTrace(); + } + + 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 = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + +// byte[] fid = new byte[] {(byte) 0x50, (byte) 0x15 }; +// System.out.println("SELECT DF FID=" + toString(fid)); +// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x01, 0x00, fid, 256); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); +// System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x6f))); + + cmdAPDU = (liezert) + ? new CommandAPDU(0x00, 0xA4, 0x04, 0x04, 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) + : new CommandAPDU(0x00, 0xa4, 0x04, 0x00, new byte[] { (byte) 0xd2, (byte) 0x76, (byte) 0x00, (byte) 0x00, (byte) 0x66, (byte) 0x01 }, 256); + System.out.println("SELECT AID " + toString(cmdAPDU.getData())); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x62))); + + byte kid = (liezert) + ? (byte) 0x82 // don't set to 0x03 (SO Pin, 63c2) + : (byte) 0x81; // QuoVadis: 0x81 ?! CommonObjectAttributes.authId = 0x11 + System.out.println("VERIFY kid=" + Integer.toHexString(kid & 0xff)); + cmdAPDU = ISO7816Utils.createVerifyAPDU(new VerifyAPDUSpec(new byte[] {(byte) 0x00, (byte) 0x20, (byte) 0x00, kid}, 0, VerifyAPDUSpec.PIN_FORMAT_ASCII, (liezert) ? 8 : 0), "123456".toCharArray()); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + +// byte[] fid = new byte[] {(byte) 0x00, (byte) 0x30 }; +// System.out.println("SELECT EF FID=" + toString(fid)); +// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x04, fid, 256); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + +// int seid = 1; +// System.out.println("RESTORE SE Id " + seid); +// cmdAPDU = new CommandAPDU(0x00, 0x22, 0xF3, seid); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + +// byte keyRef = (liezert) +// ? (byte) 132 //0x84 +// : (byte) 2; //QuoVadis: 0x02 +// System.out.println("SET DST (key ref: 0x" + Integer.toHexString(keyRef & 0xff) + ")"); +// byte[] dst = new byte[] { +//// (byte) 0x95, (byte) 0x01, (byte) 0x40, +// (byte) 0x84, (byte) 0x03, (byte) 0x80, (byte) (0x80 ^ keyRef), (byte) 0x00, +// (byte) 0x89, (byte) 0x03, (byte) 0x13, (byte) 0x23, (byte) 0x10 +// }; +// cmdAPDU = new CommandAPDU(0x00, 0x22, 0x41, 0xb6, dst, 256); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + byte[] dst = new byte[] { + // key 0x81? + (byte) 0x84, (byte) 0x01, (byte) 0x81, + //RSA Authentication + (byte) 0x89, (byte) 0x02, (byte) 0x23, (byte) 0x13 + }; + cmdAPDU = new CommandAPDU(0x00, 0x22, 0x41, 0xa4, dst); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + byte[] oid = 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) 0x14 }; + + byte[] hash; + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + hash = md.digest(); + System.out.println("hash value to be signed:\n " + toString(hash)); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + return; + } + +// byte[] AI = new byte[] { +// (byte) 0xF3, (byte) 0x15, (byte) 0x7B, (byte) 0xAC, (byte) 0x94, +// (byte) 0xCA, (byte) 0x1D, (byte) 0xC1, (byte) 0xE7, (byte) 0x7D, +// (byte) 0xCA, (byte) 0xF5, (byte) 0xF5, (byte) 0x3A, (byte) 0x80, +// (byte) 0xEF, (byte) 0x6C, (byte) 0xC2, (byte) 0x1C, (byte) 0xE9 }; + + ByteArrayOutputStream data = new ByteArrayOutputStream(); + + try { + // oid + data.write(oid); + // hash + data.write(hash); + } catch (IOException e) { + throw new SignatureCardException(e); + } + + cmdAPDU = new CommandAPDU(0x00, 0x88, 0x00, 0x00, data.toByteArray(), 256); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + + + +// for (int i = 1; i < 256; i++) { +// System.out.println("trying alg id " + Integer.toHexString(i & 0xff)); +// +// final byte[] dst = { +// (byte) 0x80, // algorithm reference +// // (byte) 0x01, (byte) 0x12, // RSASSA-PKCS1-v1.5 using SHA1 +// (byte) 0x01, (byte) (i & 0xff), // RSASSA-PKCS1-v1.5 using SHA1 +// (byte) 0x84, // private key reference +// (byte) 0x01, (byte) 0x82}; +// // (byte) 0x91, (byte) 0x00 }; // random num provided by card +// +//// System.out.println("SET DST"); +// cmdAPDU = new CommandAPDU(0x00, 0x22, 0x41, 0xb6, dst); +//// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +//// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); +// +// if (resp.getSW() != 0x6a80) { +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); +// } +// } + + + +// byte[] fid = new byte[] {(byte) 0x0f, (byte) 0x01 }; +// System.out.println("SELECT EF FID=" + toString(fid)); +// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x04, fid, 256); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); +// System.out.println("READ priv key?"); +// byte[] readTransparentFile = ISO7816Utils.readTransparentFile(basicChannel, -1); +// System.out.println("read: " + toString(readTransparentFile)); + +// byte[] hash; +// try { +// MessageDigest md = MessageDigest.getInstance("SHA-1"); +// hash = md.digest(); +// System.out.println("hash value to be signed:\n " + toString(hash)); +// } catch (NoSuchAlgorithmException e) { +// e.printStackTrace(); +// return; +// } +// +// System.out.println("HASH"); +// byte[] dataObj = new byte[hash.length+2]; +// dataObj[0] = (byte) 0x90; +// dataObj[1] = (byte) 0x14; +// System.arraycopy(hash, 0, dataObj, 2, hash.length); +// cmdAPDU = new CommandAPDU(0x00, 0x2a, 0x90, 0xa0, dataObj); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); +// +// System.out.println("PSO COMPUTE DIGITAL SIGNATURE"); +// cmdAPDU = new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, 256); //data.toByteArray(), +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); +// +// if (resp.getSW() != 0x9000) { +// byte[] oid = 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) 0x14 }; +// +// ByteArrayOutputStream data = new ByteArrayOutputStream(); +// +// try { +// // oid +// data.write(oid); +// // hash +// data.write(hash); +// } catch (IOException e) { +// throw new SignatureCardException(e); +// } +// +// System.out.println("PSO COMPUTE DIGITAL SIGNATURE"); +// cmdAPDU = new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, data.toByteArray(), 256); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); +// } + + if (resp.getSW() == 0x9000 && certificate != null) { + + try { + System.out.println("Verifying signature with " + ((X509Certificate) certificate).getIssuerDN()); + Signature signature = Signature.getInstance("SHA/RSA"); + signature.initVerify(certificate.getPublicKey()); + boolean valid = signature.verify(resp.getData()); + + System.out.println("Signature is " + ((valid) ? "valid" : "invalid")); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (SignatureException e) { + e.printStackTrace(); + } + + } + + } + + private final static String CERT = //"-----BEGIN CERTIFICATE-----" + + "MIIGFDCCBPygAwIBAgICDOEwDQYJKoZIhvcNAQEFBQAwgYYxCzAJBgNVBAYTAkxJ" ++"MSMwIQYDVQQKExpMaWVjaHRlbnN0ZWluaXNjaGUgUG9zdCBBRzEoMCYGA1UECxMf" ++"SXNzdWluZyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEoMCYGA1UEAxMfTGllY2h0" ++"ZW5zdGVpbiBQb3N0IFF1YWxpZmllZCBDQTAeFw0xMDA5MDExMjQ5MTJaFw0xMTA5" ++"MDExMjQ5MDdaMIHaMQswCQYDVQQGEwJMSTEOMAwGA1UEBxMFVmFkdXoxLDAqBgNV" ++"BAoTI0xpZWNodGVuc3RlaW5pc2NoZSBMYW5kZXN2ZXJ3YWx0dW5nMUcwRQYDVQQL" ++"Ez5UZXN0IGNlcnRpZmljYXRlIChubyBsaWFiaWxpdHkpIFRlc3R6ZXJ0aWZpa2F0" ++"IChrZWluZSBIYWZ0dW5nKTErMCkGA1UECxMiQW10IGZ1ZXIgUGVyc29uYWwgdW5k" ++"IE9yZ2FuaXNhdGlvbjEXMBUGA1UEAxMOVEVTVCBMTFYgQVBPIDIwggEiMA0GCSqG" ++"SIb3DQEBAQUAA4IBDwAwggEKAoIBAQChDpzPyb0NIuqi+UGCOhypcODFMKas1kTw" ++"HPyLW2ZdtqzmrgO7Q7Y5jm2CpPdCkd61Z+/lswEB+wPgSe+YnnNuytYtM0uYaNv9" ++"UNxc6CmlthIOJTK2+VP9lwIOsS61Jr+boTEXjXszFVwkO288wGJtCB3SG6IZja6l" ++"UD/veXoJckC5OIS43V6CqOKcyz6CNhu+OhKTwgqd07KXzzEdUeLemrgrNP9/qnDz" ++"xnDiRtyu/zocCG9xR7Rq6ZNwX69JNPi6AljsAvMucM7bhdbW8pyPKVUEhBFLduM0" ++"hmQYpodANUnPtpXA5ksxcgSWn/SdTuJ8VbG8SrvSR+1b70Coef0fAgMBAAGjggI0" ++"MIICMDCB/gYDVR0gBIH2MIHzMAgGBgQAizABATCB5gYKKwYBBAG+WAGDEDCB1zCB" ++"ngYIKwYBBQUHAgIwgZEagY5SZWxpYW5jZSBvbiB0aGUgUXVvVmFkaXMgUm9vdCBD" ++"ZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2NlcHRhbmNlIG9mIHRo" ++"ZSBRdW9WYWRpcyBDZXJ0aWZpY2F0ZSBQb2xpY3kvQ2VydGlmaWNhdGlvbiBQcmFj" ++"dGljZSBTdGF0ZW1lbnQuMDQGCCsGAQUFBwIBFihodHRwOi8vd3d3LnF1b3ZhZGlz" ++"Z2xvYmFsLmNvbS9yZXBvc2l0b3J5MC4GCCsGAQUFBwEDBCIwIDAKBggrBgEFBQcL" ++"AjAIBgYEAI5GAQEwCAYGBACORgEEMHIGCCsGAQUFBwEBBGYwZDAqBggrBgEFBQcw" ++"AYYeaHR0cDovL29jc3AucXVvdmFkaXNnbG9iYWwuY29tMDYGCCsGAQUFBzAChipo" ++"dHRwOi8vdHJ1c3QucXVvdmFkaXNnbG9iYWwuY29tL2xpcHFjYS5jcnQwDgYDVR0P" ++"AQH/BAQDAgbAMB8GA1UdIwQYMBaAFPsbkJP9mNp/kmoaRiY20fOPhwDgMDkGA1Ud" ++"HwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwucXVvdmFkaXNnbG9iYWwuY29tL2xpcHFj" ++"YS5jcmwwHQYDVR0OBBYEFADlv8IBR5ga0KjxSiByi2T1whHEMA0GCSqGSIb3DQEB" ++"BQUAA4IBAQB4LzgcpNxKcGwxdbep1E6MiXk3gwS6kq06Iaf7Ar/By2SuyLB8l0B7" ++"myk8VvkIGVCP0f+i7WxblUV5xqXP2Itnq7Ynm4A5qdUkBZuXvOGY2sOtjNttqdnv" ++"oemsshz3QIEBwlh10SZZbwtVv7W7uy0xUwbsWFX0r8/jiQyVANyPRQ+KqW+H6U05" ++"13FG5da/AgXvUGGLYVDk66qGYn/TlGBgj8ijvWqqbZ94vvbog/rwGHG+P+0JMRTS" ++"QsNR8hmlgd8OLwWc1SFB5TrDsjkDTCQHce/MJ0n6YNPXQr8EHWpu5And2gzmWrYh" ++"Cx5l+gCuh6N9ITOAFmyc1gleyNdTenEE"; +// +"-----END CERTIFICATE-----"; + + +// @Ignore + public void directoryListing(CommandAPDU cmdAPDU, ResponseAPDU resp, CardChannel basicChannel) throws CardException, SignatureCardException { + + byte[] dir = new byte[] {(byte) 0x50, (byte) 0x15}; + + System.out.println("SELECT MF"); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0c, new byte[] { (byte) 0x3F, (byte) 0x00 }, 256); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + +// System.out.println("SELECT DF.CIA"); +// 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); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + System.out.println("SELECT [50:15]"); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x01, 0x04, dir, 256); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + for (int i = 0x1F00; i <= 0xFFFF; i++) { +// for (int i = 0x0000; i <= 0x1F00; i++) { + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x04, new byte[] { (byte) ((i >> 8) & 0xFF), (byte) (i & 0xFF)}, 256); + resp = basicChannel.transmit(cmdAPDU); + if ((i & 0xFF) == 0) { + System.out.println(Integer.toHexString(i)); + } + if (resp.getSW() == 0x9000) { + System.out.println("found [" + Integer.toHexString((i >> 8) & 0xff) + ":" + Integer.toHexString((i) & 0xff) + "]"); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + +// byte[] fcx = new TLVSequence(resp.getBytes()).getValue(0x6f); +// System.out.println(Integer.toHexString(i) + ": " + new TLVSequence(fcx)); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0C, new byte[] { 0x3F, 0x00}); + resp = basicChannel.transmit(cmdAPDU); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x01, 0x04, dir); + resp = basicChannel.transmit(cmdAPDU); + } + } + + } + +// @Test +// @Ignore + public void verify() throws CardException { + CardChannel basicChannel = icc.getBasicChannel(); + CommandAPDU cmdAPDU; + ResponseAPDU resp; + + byte kid = (liezert) + ? (byte) 0x82 // don't set to 0x03 (SO Pin, 63c2) + : (byte) 0x81; // QuoVadis: 0x81 ?! CommonObjectAttributes.authId = 0x11 + System.out.println("VERIFY kid=" + Integer.toHexString(kid & 0xff)); + cmdAPDU = ISO7816Utils.createVerifyAPDU(new VerifyAPDUSpec(new byte[] {(byte) 0x00, (byte) 0x20, (byte) 0x00, kid}, 0, VerifyAPDUSpec.PIN_FORMAT_ASCII, (liezert) ? 8 : 0), "123456".toCharArray()); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + cmdAPDU = new CommandAPDU(0x00, 0x20, 0x00, kid); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + + } + +// @Test +// @Ignore + public void selectAndRead() throws CardException, SignatureCardException { + CardChannel basicChannel = icc.getBasicChannel(); + CommandAPDU cmdAPDU; + ResponseAPDU resp; + + System.out.println("SELECT MF"); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0c, new byte[] { (byte) 0x3F, (byte) 0x00 }, 256); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + System.out.println("SELECT DF.CIA"); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x04, 0x04, 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); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + +// byte kid = (liezert) +// ? (byte) 0x82 // don't set to 0x03 (SO Pin, 63c2) +// : (byte) 0x81; // QuoVadis: 0x81 ?! CommonObjectAttributes.authId = 0x11 +// System.out.println("VERIFY kid=" + Integer.toHexString(kid & 0xff)); +// cmdAPDU = ISO7816Utils.createVerifyAPDU(new VerifyAPDUSpec(new byte[] {(byte) 0x00, (byte) 0x20, (byte) 0x00, kid}, 0, VerifyAPDUSpec.PIN_FORMAT_ASCII, (liezert) ? 8 : 0), "123456".toCharArray()); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + byte[][] fids = new byte[][] {{(byte)0x00,(byte)0x12}, + {(byte)0x00,(byte)0x13}, + {(byte)0x00,(byte)0x15}, + {(byte)0x00,(byte)0x16}, + {(byte)0x00,(byte)0x30}, + {(byte)0x00,(byte)0x37}, + {(byte)0x0c,(byte)0x02}, + {(byte)0x0e,(byte)0x01}, + {(byte)0x0e,(byte)0x02}, + {(byte)0x0f,(byte)0x01}, + {(byte)0x0f,(byte)0x02}, + {(byte)0x44,(byte)0x00}, + {(byte)0x44,(byte)0x01}, + {(byte)0x50,(byte)0x31}, + {(byte)0x50,(byte)0x32}, + {(byte)0x53,(byte)0x42}, + {(byte)0x53,(byte)0x62}, + {(byte)0xae,(byte)0x0a}}; + + for (int i = 0; i < fids.length; i++) { + System.out.println("SELECT EF " + toString(fids[i])); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x04, fids[i], 256); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + byte[] fcx = new TLVSequence(resp.getBytes()).getValue(0x62); //0x62 for FCP, 0x6f for FCI + try { + readFile(basicChannel, fids[i], fcx); + + } catch (Exception ex) { + System.out.println("************ read failed: " + ex.getMessage()); + } + } + } + + protected void readFile(CardChannel channel, byte[] fid, byte[] fcx) throws CardException, SignatureCardException, CodingException { + + byte[] fd = new TLVSequence(fcx).getValue(0x82); + + if ((fd[0] & 0x04) > 0 || fd[0] == 0x12) { + System.out.println(" records"); + int records = fd[fd.length - 1]; + + for (int record = 1; record < records; record++) { +// System.out.println(" READ RECORD " + record); + byte[] ef = ISO7816Utils.readRecord(channel, record); +// System.out.println(" " + toString(ef)); +// ASN1Object informationObject = DerCoder.decode(Arrays.copyOfRange(ef, 2, ef.length)); +// System.out.println(ASN1.print(informationObject)); + } + + } else if (fd[0] == 0x11) { + System.out.println(" transparent structure"); + + byte[] ef = ISO7816Utils.readTransparentFile(channel, -1); +// System.out.println(" " + toString(ef)); + +// int length; +// int i = 0; +// int j; +// +// do { +// System.out.println("tag: 0x" + Integer.toHexString(ef[i]) + ", length: 0x" + Integer.toHexString(ef[i+1])); +// if ((ef[i+1] & 0xff) == 0x81) { +// length = ef[i+2] & 0xff; +// j = 3; +//// System.out.println("ef["+(i+1)+"]=0x81, setting length=" + (ef[i+2] & 0xff)); +// +// } else if ((ef[i+1] & 0xff) == 0x82) { +// length = ((ef[i+2] & 0xff) << 8) | (ef[i+3] & 0xff); +// j = 4; +//// System.out.println("ef["+(i+1)+"]=0x82, setting length=" + (((ef[i+2] & 0xff) << 8) | (ef[i+3] & 0xff))); +// +// } else { +// length = ef[i+1] & 0xff; +// j = 2; +//// System.out.println("ef["+(i+1)+"]=0x" + Integer.toBinaryString(ef[i+1] & 0xff)); +// } +// +// System.out.println("setting length: 0x" + Integer.toHexString(length)); +// +//// if (cio.getTag() == 0xa4) { +//// byte[] cert = Arrays.copyOfRange(ef, 0, ef.length-1); +////// System.out.println("cert 1: \n " + toString(cert)); +// +// j = i + j + length; +// System.out.println("reading ef[" + i +"-" + (j-1) + "]:\n" + toString(Arrays.copyOfRange(ef, i, j)) ); +// ASN1Object informationObject = DerCoder.decode(Arrays.copyOfRange(ef, i, j)); +// System.out.println(ASN1.print(informationObject)); +// i = j; +// } while (i0); + } else { + System.out.println(" structure not supported: 0x" + Integer.toHexString(fd[0])); + } + } + + +// @Ignore + public void todo(Certificate certificate, CommandAPDU cmdAPDU, ResponseAPDU resp, CardChannel basicChannel) throws CardException, SignatureCardException { + +// System.out.println("SELECT by Path"); +// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x09, 0x00, new byte[] { (byte) 0x3F, (byte) 0x00, (byte) 0x56, (byte) 0x49 }, 256); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); +// +//// System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x6f))); +// +// byte[] ef = ISO7816Utils.readTransparentFile(basicChannel, -1); +// System.out.println(toString(ef)); +// +// try { +// FileOutputStream fileOutputStream = new FileOutputStream("EF.IV"); +// fileOutputStream.write(ef); +// fileOutputStream.close(); +// } catch (FileNotFoundException e1) { +// e1.printStackTrace(); +// } catch (IOException e1) { +// e1.printStackTrace(); +// } +// +// System.out.println("done."); + + final byte[] AID = new byte[] {(byte) 0xd2, (byte) 0x76, (byte) 0x00, (byte) 0x00, (byte) 0x66, (byte) 0x01}; + + System.out.println("SELECT Application (" + toString(AID) + ")"); + cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x04, 0x00, AID, 256); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x6f))); + +// int seid = 1; +// cmdAPDU = new CommandAPDU(0x00, 0x22, 0xF3, seid); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + System.out.println("VERIFY"); + cmdAPDU = new CommandAPDU(0x00, 0x20, 0x00, 0x81, "123456".getBytes(Charset.forName("ASCII")), 256); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + byte[] hash; + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + hash = md.digest(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + return; + } + + byte[] oid = 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) 0x14 }; + + ByteArrayOutputStream data = new ByteArrayOutputStream(); + + try { + // oid + data.write(oid); + // hash + data.write(hash); + } catch (IOException e) { + throw new SignatureCardException(e); + } + + + System.out.println("PSO COMPUTE DIGITAL SIGNATURE"); + cmdAPDU = new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, data.toByteArray(), 256); + System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); + resp = basicChannel.transmit(cmdAPDU); + System.out.println(" -> " + toString(resp.getBytes()) + "\n"); + + if (resp.getSW() == 0x9000 && certificate != null) { + + try { + System.out.println("Verifying signature with " + ((X509Certificate) certificate).getSubjectDN()); + Signature signature = Signature.getInstance("SHA/RSA"); + signature.initVerify(certificate.getPublicKey()); + boolean valid = signature.verify(resp.getData()); + + System.out.println("Signature is " + ((valid) ? "valid" : "invalid")); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (SignatureException e) { + e.printStackTrace(); + } + + } + + +// final byte[] data = new byte[] {}; //new byte[] {(byte) 0x7B, (byte) 0x02, (byte) 0xB6, (byte) 0x80}; +// +// System.out.println("GET DATA"); +// for (int i = 0x004D; i <= 0x004D; i++) { +// cmdAPDU = new CommandAPDU(0x00, 0xCA, 0xFF & (i >> 8), 0xFF & i, data , 256); +// resp = basicChannel.transmit(cmdAPDU); +// if (resp.getSW() == 0x9000) { +// if (i == 0x180) { +// try { +// System.out.println(new String(resp.getData(), "ASCII")); +// } catch (UnsupportedEncodingException e) { +// e.printStackTrace(); +// } +// } else { +// System.out.println(Integer.toHexString(i) + " -> " + toString(resp.getData())); +// } +// } +// } + + + +// final byte[] DST = new byte[] {}; +// +// System.out.println("MSE SET DST (" + toString(DST) + ")"); +// cmdAPDU = new CommandAPDU(0x00, 0x22, 0x04, 0x01, DST); +// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); +// resp = basicChannel.transmit(cmdAPDU); +// System.out.println(" -> " + toString(resp.getBytes()) + "\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)); + } + } + sb.append(']'); + return sb.toString(); + } + + + public static void main(String[] args) { + try { + System.out.println("manually running pkcs15 test..."); + PKCS15Test test = new PKCS15Test(); + test.setUp(); + test.getEFDIR(); + // test.selectAndRead(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + +} diff --git a/smccTest/src/test/java/at/gv/egiz/pkcs15test/PKCS15Test.java b/smccTest/src/test/java/at/gv/egiz/pkcs15test/PKCS15Test.java deleted file mode 100644 index a80210c5..00000000 --- a/smccTest/src/test/java/at/gv/egiz/pkcs15test/PKCS15Test.java +++ /dev/null @@ -1,1023 +0,0 @@ -package at.gv.egiz.pkcs15test; - -import at.gv.egiz.smcc.SignatureCardException; -import at.gv.egiz.smcc.VerifyAPDUSpec; -import at.gv.egiz.smcc.util.ISO7816Utils; -import iaik.asn1.ASN1; -import iaik.asn1.ASN1Object; -import iaik.asn1.CodingException; -import iaik.asn1.DerCoder; -//import iaik.security.provider.IAIK; -import iaik.security.ecc.provider.ECCProvider; - -import iaik.security.provider.IAIK; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.charset.Charset; -import java.security.InvalidKeyException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.Signature; -import java.security.SignatureException; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -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; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; -//import org.opensc.pkcs15.asn1.PKCS15Certificate; -//import org.opensc.pkcs15.asn1.PKCS15Objects; -//import org.opensc.pkcs15.asn1.sequence.SequenceOf; - - - -/** - * - * @author clemens - */ -public class PKCS15Test { - - CardTerminal ct; - Card icc; - boolean liezert; - - public PKCS15Test() { - } - - @BeforeClass - public static void setUpClass() throws Exception { - } - - @AfterClass - public static void tearDownClass() throws Exception { - } - - @Before - public void setUp() throws NoSuchAlgorithmException, CardException { - - IAIK.addAsJDK14Provider(); - ECCProvider.addAsProvider(); - - 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(); - liezert = Arrays.equals(atr, new byte[] {(byte) 0x3b, (byte) 0xbb, (byte) 0x18, (byte) 0x00, (byte) 0xc0, (byte) 0x10, (byte) 0x31, (byte) 0xfe, (byte) 0x45, (byte) 0x80, (byte) 0x67, (byte) 0x04, (byte) 0x12, (byte) 0xb0, (byte) 0x03, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x81, (byte) 0x05, (byte) 0x3c}); - byte[] historicalBytes = icc.getATR().getHistoricalBytes(); - System.out.println("found card " + toString(atr) + " " + new String(historicalBytes, Charset.forName("ASCII")) + "\n\n"); - - } - - @After - public void tearDown() { - } - - @Test - @Ignore - public void getEFDIR() throws CardException, SignatureCardException, InstantiationException, CodingException { - - CardChannel basicChannel = icc.getBasicChannel(); - CommandAPDU cmdAPDU; - ResponseAPDU resp; - - System.out.println("SELECT MF"); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0c, new byte[] { 0x3F, 0x00}); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - -// for (int i = 0x1F00; i <= 0xFFFF; i++) { -//// for (int i = 0x5000; i <= 0x6000; i++) { -// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x01, 0x00, new byte[] { (byte) ((i >> 8) & 0xFF), (byte) (i & 0xFF)}, 256); -// resp = basicChannel.transmit(cmdAPDU); -// if ((i & 0xFF) == 0) { -// System.out.println(Integer.toHexString(i)); -// } -// if (resp.getSW() == 0x9000) { -// System.out.println("found [" + Integer.toHexString((i >> 8) & 0xff) + ":" + Integer.toHexString((i) & 0xff) + "]"); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); -// -// byte[] fcx = new TLVSequence(resp.getBytes()).getValue(0x6f); -// System.out.println(Integer.toHexString(i) + ": " + new TLVSequence(fcx)); -// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0C, new byte[] { 0x3F, 0x00}); -// 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); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - -// for (int i = 0x1F00; i <= 0xFFFF; i++) { -//// for (int i = 0x5000; i <= 0x6000; i++) { -// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, new byte[] { (byte) ((i >> 8) & 0xFF), (byte) (i & 0xFF)}, 256); -// resp = basicChannel.transmit(cmdAPDU); -// if ((i & 0xFF) == 0) { -// System.out.println(Integer.toHexString(i)); -// } -// if (resp.getSW() == 0x9000) { -// System.out.println("found [" + Integer.toHexString((i >> 8) & 0xff) + ":" + Integer.toHexString((i) & 0xff) + "]"); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); -// -// byte[] fcx = new TLVSequence(resp.getBytes()).getValue(0x6f); -// System.out.println(Integer.toHexString(i) + ": " + new TLVSequence(fcx)); -// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0C, new byte[] { 0x3F, 0x00}); -// resp = basicChannel.transmit(cmdAPDU); -// } -// } - - - 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); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - - System.out.println("SELECT EF.CardInfo (P1=02 P2=00)"); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, new byte[] { (byte) 0x50,(byte) 0x32 }, 256); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - System.out.println("READ EF.CardInfo"); - byte[] efCardInfo = ISO7816Utils.readTransparentFile(basicChannel, -1); - System.out.println(toString(efCardInfo)); - ASN1Object efCardInfoASN1 = DerCoder.decode(efCardInfo); -// try { -// FileOutputStream os = new FileOutputStream("EF.CardInfo"); -// os.write(efCardInfo); -// os.close(); -// } catch (FileNotFoundException e) { -// e.printStackTrace(); -// } catch (IOException e) { -// e.printStackTrace(); -// } - System.out.println(ASN1.print(efCardInfoASN1)); - - System.out.println("SELECT EF.OD"); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, new byte[] { (byte) 0x50,(byte) 0x31 }, 256); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - System.out.println("READ EF.OD"); - byte[] efod = ISO7816Utils.readTransparentFile(basicChannel, -1); - System.out.println(" " + toString(efod)); - - for (TLV cio : new TLVSequence(efod)) { - - System.out.println("\n\nTag = " + cio.getTag()); - if (cio.getTag() == 0) { - System.out.println("cannot decode null data"); - continue; - } - - ASN1Object object = DerCoder.decode(cio.getValue()); - byte[] fid = (byte[]) object.getComponentAt(0).getValue(); - - System.out.println("SELECT EF fid=" + toString(fid)); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, fid, 256); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - byte[] fcx = new TLVSequence(resp.getBytes()).getValue(0x6f); //0x62 for FCP, 0x6f for FCI - byte[] fd = new TLVSequence(fcx).getValue(0x82); - -// System.out.println("cio " + toString(fid) + " fd: " + toString(fd)); - - if ((fd[0] & 0x04) > 0) { - // records - int records = fd[fd.length - 1]; - - for (int record = 1; record < records; record++) { - System.out.println("READ RECORD " + record); - byte[] ef = ISO7816Utils.readRecord(basicChannel, record); - System.out.println(" " + toString(ef)); - ASN1Object informationObject = DerCoder.decode(Arrays.copyOfRange(ef, 2, ef.length)); - System.out.println(ASN1.print(informationObject)); - if (cio.getTag() == 0xa0 || cio.getTag() == 0xa1) { - System.out.println("Path = " - + toString((byte[]) informationObject.getComponentAt(3) - .getComponentAt(0).getComponentAt(0).getComponentAt(0) - .getValue())); - } - } - - } else if (fd[0] == 0x11) { - System.out.println("transparent structure"); - - byte[] ef = ISO7816Utils.readTransparentFile(basicChannel, -1); -// System.out.println(" " + toString(ef)); - - int length; - int i = 0; - int j; - - do { - System.out.println("tag: 0x" + Integer.toHexString(ef[i]) + ", length: 0x" + Integer.toHexString(ef[i+1])); - if ((ef[i+1] & 0xff) == 0x81) { - length = ef[i+2] & 0xff; - j = 3; -// System.out.println("ef["+(i+1)+"]=0x81, setting length=" + (ef[i+2] & 0xff)); - - } else if ((ef[i+1] & 0xff) == 0x82) { - length = ((ef[i+2] & 0xff) << 8) | (ef[i+3] & 0xff); - j = 4; -// System.out.println("ef["+(i+1)+"]=0x82, setting length=" + (((ef[i+2] & 0xff) << 8) | (ef[i+3] & 0xff))); - - } else { - length = ef[i+1] & 0xff; - j = 2; -// System.out.println("ef["+(i+1)+"]=0x" + Integer.toBinaryString(ef[i+1] & 0xff)); - } - - System.out.println("setting length: 0x" + Integer.toHexString(length)); - -// if (cio.getTag() == 0xa4) { -// byte[] cert = Arrays.copyOfRange(ef, 0, ef.length-1); -//// System.out.println("cert 1: \n " + toString(cert)); - - j = i + j + length; - System.out.println("reading ef[" + i +"-" + (j-1) + "]:\n" + toString(Arrays.copyOfRange(ef, i, j)) ); - ASN1Object informationObject = DerCoder.decode(Arrays.copyOfRange(ef, i, j)); - System.out.println(ASN1.print(informationObject)); - i = j; - } while (i0); - } - } - - -// System.out.println("SELECT by Path"); -// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x09, 0x00, new byte[] { (byte) 0x3F, (byte) 0x00, (byte) 0x56, (byte) 0x49 }, 256); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); -// -// System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x6f))); -// -// byte[] ef = ISO7816Utils.readTransparentFile(basicChannel, -1); -// System.out.println(toString(ef)); -// -// try { -// FileOutputStream fileOutputStream = new FileOutputStream("EF.IV"); -// fileOutputStream.write(ef); -// fileOutputStream.close(); -// } catch (FileNotFoundException e1) { -// e1.printStackTrace(); -// } catch (IOException e1) { -// e1.printStackTrace(); -// } -// -// System.out.println("done."); - - } - - @Test - @Ignore - public void ecard() throws CardException, SignatureCardException, CodingException { - CardChannel basicChannel = icc.getBasicChannel(); - 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 = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - System.out.println("SELECT EF.CardInfo (P1=02 P2=00)"); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, new byte[] { (byte) 0x50,(byte) 0x32 }, 256); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - System.out.println("READ EF.CardInfo"); - byte[] efCardInfo = ISO7816Utils.readTransparentFile(basicChannel, -1); - System.out.println(toString(efCardInfo)); - ASN1Object efCardInfoASN1 = DerCoder.decode(efCardInfo); - System.out.println(ASN1.print(efCardInfoASN1)); - - cmdAPDU = new CommandAPDU(0x00, 0xa4, 0x04, 0x00, new byte[] { (byte) 0xd0, (byte) 0x40, - (byte) 0x00, (byte) 0x00, (byte) 0x17, (byte) 0x00, (byte) 0x12, - (byte) 0x01 }, 256); - System.out.println("SELECT AID " + toString(cmdAPDU.getData())); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x6f))); - - System.out.println("SELECT CERTIFICATE"); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, new byte[] { (byte) 0xc0, (byte) 0x00 }, 256); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - X509Certificate certificate = null; - try { - System.out.println("READ cert?"); - CertificateFactory certificateFactory = CertificateFactory.getInstance("X509"); - certificate = (X509Certificate) certificateFactory.generateCertificate(ISO7816Utils.openTransparentFileInputStream(basicChannel, -1)); -// certificate = certificateFactory.generateCertificate(new BASE64DecoderStream(new ByteArrayInputStream(CERT.getBytes()))); -// System.out.println("certificate: \n" + toString(certificate.getEncoded())); - System.out.println("certificate: \n" + certificate); - } catch (CertificateException e) { - e.printStackTrace(); - } - - byte[] fid = new byte[] {(byte) 0x00, (byte) 0x30 }; - System.out.println("SELECT EF FID=" + toString(fid)); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x04, fid, 256); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x62))); - - byte[] fcx = new TLVSequence(resp.getBytes()).getValue(0x62); //0x62 for FCP, 0x6f for FCI - byte[] fd = new TLVSequence(fcx).getValue(0x82); - -// System.out.println("cio " + toString(fid) + " fd: " + toString(fd)); - - if ((fd[0] & 0x04) > 0) { - // records - int records = fd[fd.length - 1]; - - for (int record = 1; record < records-1; record++) { - System.out.println("READ RECORD " + record); - byte[] ef = ISO7816Utils.readRecord(basicChannel, record); - System.out.println(" " + toString(ef)); - } - } - } - - - @Test - @Ignore - public void sign() throws CardException, SignatureCardException, InstantiationException, CodingException { - CardChannel basicChannel = icc.getBasicChannel(); - CommandAPDU cmdAPDU; - ResponseAPDU resp; - - System.out.println("SELECT DF.CIA"); - 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); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - System.out.println("SELECT CERTIFICATE"); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x00, new byte[] { (byte) 0x0c, (byte) 0x02 }, 256); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - Certificate certificate = null; - try { - System.out.println("READ cert?"); - CertificateFactory certificateFactory = CertificateFactory.getInstance("X509"); - certificate = certificateFactory.generateCertificate(ISO7816Utils.openTransparentFileInputStream(basicChannel, -1)); -// certificate = certificateFactory.generateCertificate(new BASE64DecoderStream(new ByteArrayInputStream(CERT.getBytes()))); - System.out.println("certificate: \n" + toString(certificate.getEncoded())); - } catch (CertificateException e) { - e.printStackTrace(); - } - - 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 = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - -// byte[] fid = new byte[] {(byte) 0x50, (byte) 0x15 }; -// System.out.println("SELECT DF FID=" + toString(fid)); -// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x01, 0x00, fid, 256); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); -// System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x6f))); - - cmdAPDU = (liezert) - ? new CommandAPDU(0x00, 0xA4, 0x04, 0x04, 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) - : new CommandAPDU(0x00, 0xa4, 0x04, 0x00, new byte[] { (byte) 0xd2, (byte) 0x76, (byte) 0x00, (byte) 0x00, (byte) 0x66, (byte) 0x01 }, 256); - System.out.println("SELECT AID " + toString(cmdAPDU.getData())); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x62))); - - byte kid = (liezert) - ? (byte) 0x82 // don't set to 0x03 (SO Pin, 63c2) - : (byte) 0x81; // QuoVadis: 0x81 ?! CommonObjectAttributes.authId = 0x11 - System.out.println("VERIFY kid=" + Integer.toHexString(kid & 0xff)); - cmdAPDU = ISO7816Utils.createVerifyAPDU(new VerifyAPDUSpec(new byte[] {(byte) 0x00, (byte) 0x20, (byte) 0x00, kid}, 0, VerifyAPDUSpec.PIN_FORMAT_ASCII, (liezert) ? 8 : 0), "123456".toCharArray()); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - -// byte[] fid = new byte[] {(byte) 0x00, (byte) 0x30 }; -// System.out.println("SELECT EF FID=" + toString(fid)); -// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x04, fid, 256); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - -// int seid = 1; -// System.out.println("RESTORE SE Id " + seid); -// cmdAPDU = new CommandAPDU(0x00, 0x22, 0xF3, seid); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - -// byte keyRef = (liezert) -// ? (byte) 132 //0x84 -// : (byte) 2; //QuoVadis: 0x02 -// System.out.println("SET DST (key ref: 0x" + Integer.toHexString(keyRef & 0xff) + ")"); -// byte[] dst = new byte[] { -//// (byte) 0x95, (byte) 0x01, (byte) 0x40, -// (byte) 0x84, (byte) 0x03, (byte) 0x80, (byte) (0x80 ^ keyRef), (byte) 0x00, -// (byte) 0x89, (byte) 0x03, (byte) 0x13, (byte) 0x23, (byte) 0x10 -// }; -// cmdAPDU = new CommandAPDU(0x00, 0x22, 0x41, 0xb6, dst, 256); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - byte[] dst = new byte[] { - // key 0x81? - (byte) 0x84, (byte) 0x01, (byte) 0x81, - //RSA Authentication - (byte) 0x89, (byte) 0x02, (byte) 0x23, (byte) 0x13 - }; - cmdAPDU = new CommandAPDU(0x00, 0x22, 0x41, 0xa4, dst); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - byte[] oid = 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) 0x14 }; - - byte[] hash; - try { - MessageDigest md = MessageDigest.getInstance("SHA-1"); - hash = md.digest(); - System.out.println("hash value to be signed:\n " + toString(hash)); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - return; - } - -// byte[] AI = new byte[] { -// (byte) 0xF3, (byte) 0x15, (byte) 0x7B, (byte) 0xAC, (byte) 0x94, -// (byte) 0xCA, (byte) 0x1D, (byte) 0xC1, (byte) 0xE7, (byte) 0x7D, -// (byte) 0xCA, (byte) 0xF5, (byte) 0xF5, (byte) 0x3A, (byte) 0x80, -// (byte) 0xEF, (byte) 0x6C, (byte) 0xC2, (byte) 0x1C, (byte) 0xE9 }; - - ByteArrayOutputStream data = new ByteArrayOutputStream(); - - try { - // oid - data.write(oid); - // hash - data.write(hash); - } catch (IOException e) { - throw new SignatureCardException(e); - } - - cmdAPDU = new CommandAPDU(0x00, 0x88, 0x00, 0x00, data.toByteArray(), 256); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - - - -// for (int i = 1; i < 256; i++) { -// System.out.println("trying alg id " + Integer.toHexString(i & 0xff)); -// -// final byte[] dst = { -// (byte) 0x80, // algorithm reference -// // (byte) 0x01, (byte) 0x12, // RSASSA-PKCS1-v1.5 using SHA1 -// (byte) 0x01, (byte) (i & 0xff), // RSASSA-PKCS1-v1.5 using SHA1 -// (byte) 0x84, // private key reference -// (byte) 0x01, (byte) 0x82}; -// // (byte) 0x91, (byte) 0x00 }; // random num provided by card -// -//// System.out.println("SET DST"); -// cmdAPDU = new CommandAPDU(0x00, 0x22, 0x41, 0xb6, dst); -//// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -//// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); -// -// if (resp.getSW() != 0x6a80) { -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); -// } -// } - - - -// byte[] fid = new byte[] {(byte) 0x0f, (byte) 0x01 }; -// System.out.println("SELECT EF FID=" + toString(fid)); -// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x04, fid, 256); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); -// System.out.println("READ priv key?"); -// byte[] readTransparentFile = ISO7816Utils.readTransparentFile(basicChannel, -1); -// System.out.println("read: " + toString(readTransparentFile)); - -// byte[] hash; -// try { -// MessageDigest md = MessageDigest.getInstance("SHA-1"); -// hash = md.digest(); -// System.out.println("hash value to be signed:\n " + toString(hash)); -// } catch (NoSuchAlgorithmException e) { -// e.printStackTrace(); -// return; -// } -// -// System.out.println("HASH"); -// byte[] dataObj = new byte[hash.length+2]; -// dataObj[0] = (byte) 0x90; -// dataObj[1] = (byte) 0x14; -// System.arraycopy(hash, 0, dataObj, 2, hash.length); -// cmdAPDU = new CommandAPDU(0x00, 0x2a, 0x90, 0xa0, dataObj); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); -// -// System.out.println("PSO COMPUTE DIGITAL SIGNATURE"); -// cmdAPDU = new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, 256); //data.toByteArray(), -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); -// -// if (resp.getSW() != 0x9000) { -// byte[] oid = 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) 0x14 }; -// -// ByteArrayOutputStream data = new ByteArrayOutputStream(); -// -// try { -// // oid -// data.write(oid); -// // hash -// data.write(hash); -// } catch (IOException e) { -// throw new SignatureCardException(e); -// } -// -// System.out.println("PSO COMPUTE DIGITAL SIGNATURE"); -// cmdAPDU = new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, data.toByteArray(), 256); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); -// } - - if (resp.getSW() == 0x9000 && certificate != null) { - - try { - System.out.println("Verifying signature with " + ((X509Certificate) certificate).getIssuerDN()); - Signature signature = Signature.getInstance("SHA/RSA"); - signature.initVerify(certificate.getPublicKey()); - boolean valid = signature.verify(resp.getData()); - - System.out.println("Signature is " + ((valid) ? "valid" : "invalid")); - } catch (InvalidKeyException e) { - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (SignatureException e) { - e.printStackTrace(); - } - - } - - } - - private final static String CERT = //"-----BEGIN CERTIFICATE-----" + - "MIIGFDCCBPygAwIBAgICDOEwDQYJKoZIhvcNAQEFBQAwgYYxCzAJBgNVBAYTAkxJ" -+"MSMwIQYDVQQKExpMaWVjaHRlbnN0ZWluaXNjaGUgUG9zdCBBRzEoMCYGA1UECxMf" -+"SXNzdWluZyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEoMCYGA1UEAxMfTGllY2h0" -+"ZW5zdGVpbiBQb3N0IFF1YWxpZmllZCBDQTAeFw0xMDA5MDExMjQ5MTJaFw0xMTA5" -+"MDExMjQ5MDdaMIHaMQswCQYDVQQGEwJMSTEOMAwGA1UEBxMFVmFkdXoxLDAqBgNV" -+"BAoTI0xpZWNodGVuc3RlaW5pc2NoZSBMYW5kZXN2ZXJ3YWx0dW5nMUcwRQYDVQQL" -+"Ez5UZXN0IGNlcnRpZmljYXRlIChubyBsaWFiaWxpdHkpIFRlc3R6ZXJ0aWZpa2F0" -+"IChrZWluZSBIYWZ0dW5nKTErMCkGA1UECxMiQW10IGZ1ZXIgUGVyc29uYWwgdW5k" -+"IE9yZ2FuaXNhdGlvbjEXMBUGA1UEAxMOVEVTVCBMTFYgQVBPIDIwggEiMA0GCSqG" -+"SIb3DQEBAQUAA4IBDwAwggEKAoIBAQChDpzPyb0NIuqi+UGCOhypcODFMKas1kTw" -+"HPyLW2ZdtqzmrgO7Q7Y5jm2CpPdCkd61Z+/lswEB+wPgSe+YnnNuytYtM0uYaNv9" -+"UNxc6CmlthIOJTK2+VP9lwIOsS61Jr+boTEXjXszFVwkO288wGJtCB3SG6IZja6l" -+"UD/veXoJckC5OIS43V6CqOKcyz6CNhu+OhKTwgqd07KXzzEdUeLemrgrNP9/qnDz" -+"xnDiRtyu/zocCG9xR7Rq6ZNwX69JNPi6AljsAvMucM7bhdbW8pyPKVUEhBFLduM0" -+"hmQYpodANUnPtpXA5ksxcgSWn/SdTuJ8VbG8SrvSR+1b70Coef0fAgMBAAGjggI0" -+"MIICMDCB/gYDVR0gBIH2MIHzMAgGBgQAizABATCB5gYKKwYBBAG+WAGDEDCB1zCB" -+"ngYIKwYBBQUHAgIwgZEagY5SZWxpYW5jZSBvbiB0aGUgUXVvVmFkaXMgUm9vdCBD" -+"ZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2NlcHRhbmNlIG9mIHRo" -+"ZSBRdW9WYWRpcyBDZXJ0aWZpY2F0ZSBQb2xpY3kvQ2VydGlmaWNhdGlvbiBQcmFj" -+"dGljZSBTdGF0ZW1lbnQuMDQGCCsGAQUFBwIBFihodHRwOi8vd3d3LnF1b3ZhZGlz" -+"Z2xvYmFsLmNvbS9yZXBvc2l0b3J5MC4GCCsGAQUFBwEDBCIwIDAKBggrBgEFBQcL" -+"AjAIBgYEAI5GAQEwCAYGBACORgEEMHIGCCsGAQUFBwEBBGYwZDAqBggrBgEFBQcw" -+"AYYeaHR0cDovL29jc3AucXVvdmFkaXNnbG9iYWwuY29tMDYGCCsGAQUFBzAChipo" -+"dHRwOi8vdHJ1c3QucXVvdmFkaXNnbG9iYWwuY29tL2xpcHFjYS5jcnQwDgYDVR0P" -+"AQH/BAQDAgbAMB8GA1UdIwQYMBaAFPsbkJP9mNp/kmoaRiY20fOPhwDgMDkGA1Ud" -+"HwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwucXVvdmFkaXNnbG9iYWwuY29tL2xpcHFj" -+"YS5jcmwwHQYDVR0OBBYEFADlv8IBR5ga0KjxSiByi2T1whHEMA0GCSqGSIb3DQEB" -+"BQUAA4IBAQB4LzgcpNxKcGwxdbep1E6MiXk3gwS6kq06Iaf7Ar/By2SuyLB8l0B7" -+"myk8VvkIGVCP0f+i7WxblUV5xqXP2Itnq7Ynm4A5qdUkBZuXvOGY2sOtjNttqdnv" -+"oemsshz3QIEBwlh10SZZbwtVv7W7uy0xUwbsWFX0r8/jiQyVANyPRQ+KqW+H6U05" -+"13FG5da/AgXvUGGLYVDk66qGYn/TlGBgj8ijvWqqbZ94vvbog/rwGHG+P+0JMRTS" -+"QsNR8hmlgd8OLwWc1SFB5TrDsjkDTCQHce/MJ0n6YNPXQr8EHWpu5And2gzmWrYh" -+"Cx5l+gCuh6N9ITOAFmyc1gleyNdTenEE"; -// +"-----END CERTIFICATE-----"; - - - @Ignore - public void directoryListing(CommandAPDU cmdAPDU, ResponseAPDU resp, CardChannel basicChannel) throws CardException, SignatureCardException { - - byte[] dir = new byte[] {(byte) 0x50, (byte) 0x15}; - - System.out.println("SELECT MF"); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0c, new byte[] { (byte) 0x3F, (byte) 0x00 }, 256); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - -// System.out.println("SELECT DF.CIA"); -// 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); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - System.out.println("SELECT [50:15]"); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x01, 0x04, dir, 256); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - for (int i = 0x1F00; i <= 0xFFFF; i++) { -// for (int i = 0x0000; i <= 0x1F00; i++) { - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x04, new byte[] { (byte) ((i >> 8) & 0xFF), (byte) (i & 0xFF)}, 256); - resp = basicChannel.transmit(cmdAPDU); - if ((i & 0xFF) == 0) { - System.out.println(Integer.toHexString(i)); - } - if (resp.getSW() == 0x9000) { - System.out.println("found [" + Integer.toHexString((i >> 8) & 0xff) + ":" + Integer.toHexString((i) & 0xff) + "]"); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - -// byte[] fcx = new TLVSequence(resp.getBytes()).getValue(0x6f); -// System.out.println(Integer.toHexString(i) + ": " + new TLVSequence(fcx)); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0C, new byte[] { 0x3F, 0x00}); - resp = basicChannel.transmit(cmdAPDU); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x01, 0x04, dir); - resp = basicChannel.transmit(cmdAPDU); - } - } - - } - - @Test - @Ignore - public void verify() throws CardException { - CardChannel basicChannel = icc.getBasicChannel(); - CommandAPDU cmdAPDU; - ResponseAPDU resp; - - byte kid = (liezert) - ? (byte) 0x82 // don't set to 0x03 (SO Pin, 63c2) - : (byte) 0x81; // QuoVadis: 0x81 ?! CommonObjectAttributes.authId = 0x11 - System.out.println("VERIFY kid=" + Integer.toHexString(kid & 0xff)); - cmdAPDU = ISO7816Utils.createVerifyAPDU(new VerifyAPDUSpec(new byte[] {(byte) 0x00, (byte) 0x20, (byte) 0x00, kid}, 0, VerifyAPDUSpec.PIN_FORMAT_ASCII, (liezert) ? 8 : 0), "123456".toCharArray()); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - cmdAPDU = new CommandAPDU(0x00, 0x20, 0x00, kid); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - - } - - @Test - @Ignore - public void selectAndRead() throws CardException, SignatureCardException { - CardChannel basicChannel = icc.getBasicChannel(); - CommandAPDU cmdAPDU; - ResponseAPDU resp; - - System.out.println("SELECT MF"); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x0c, new byte[] { (byte) 0x3F, (byte) 0x00 }, 256); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - System.out.println("SELECT DF.CIA"); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x04, 0x04, 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); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - -// byte kid = (liezert) -// ? (byte) 0x82 // don't set to 0x03 (SO Pin, 63c2) -// : (byte) 0x81; // QuoVadis: 0x81 ?! CommonObjectAttributes.authId = 0x11 -// System.out.println("VERIFY kid=" + Integer.toHexString(kid & 0xff)); -// cmdAPDU = ISO7816Utils.createVerifyAPDU(new VerifyAPDUSpec(new byte[] {(byte) 0x00, (byte) 0x20, (byte) 0x00, kid}, 0, VerifyAPDUSpec.PIN_FORMAT_ASCII, (liezert) ? 8 : 0), "123456".toCharArray()); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - byte[][] fids = new byte[][] {{(byte)0x00,(byte)0x12}, - {(byte)0x00,(byte)0x13}, - {(byte)0x00,(byte)0x15}, - {(byte)0x00,(byte)0x16}, - {(byte)0x00,(byte)0x30}, - {(byte)0x00,(byte)0x37}, - {(byte)0x0c,(byte)0x02}, - {(byte)0x0e,(byte)0x01}, - {(byte)0x0e,(byte)0x02}, - {(byte)0x0f,(byte)0x01}, - {(byte)0x0f,(byte)0x02}, - {(byte)0x44,(byte)0x00}, - {(byte)0x44,(byte)0x01}, - {(byte)0x50,(byte)0x31}, - {(byte)0x50,(byte)0x32}, - {(byte)0x53,(byte)0x42}, - {(byte)0x53,(byte)0x62}, - {(byte)0xae,(byte)0x0a}}; - - for (int i = 0; i < fids.length; i++) { - System.out.println("SELECT EF " + toString(fids[i])); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x02, 0x04, fids[i], 256); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - byte[] fcx = new TLVSequence(resp.getBytes()).getValue(0x62); //0x62 for FCP, 0x6f for FCI - try { - readFile(basicChannel, fids[i], fcx); - - } catch (Exception ex) { - System.out.println("************ read failed: " + ex.getMessage()); - } - } - } - - protected void readFile(CardChannel channel, byte[] fid, byte[] fcx) throws CardException, SignatureCardException, CodingException { - - byte[] fd = new TLVSequence(fcx).getValue(0x82); - - if ((fd[0] & 0x04) > 0 || fd[0] == 0x12) { - System.out.println(" records"); - int records = fd[fd.length - 1]; - - for (int record = 1; record < records; record++) { -// System.out.println(" READ RECORD " + record); - byte[] ef = ISO7816Utils.readRecord(channel, record); -// System.out.println(" " + toString(ef)); -// ASN1Object informationObject = DerCoder.decode(Arrays.copyOfRange(ef, 2, ef.length)); -// System.out.println(ASN1.print(informationObject)); - } - - } else if (fd[0] == 0x11) { - System.out.println(" transparent structure"); - - byte[] ef = ISO7816Utils.readTransparentFile(channel, -1); -// System.out.println(" " + toString(ef)); - -// int length; -// int i = 0; -// int j; -// -// do { -// System.out.println("tag: 0x" + Integer.toHexString(ef[i]) + ", length: 0x" + Integer.toHexString(ef[i+1])); -// if ((ef[i+1] & 0xff) == 0x81) { -// length = ef[i+2] & 0xff; -// j = 3; -//// System.out.println("ef["+(i+1)+"]=0x81, setting length=" + (ef[i+2] & 0xff)); -// -// } else if ((ef[i+1] & 0xff) == 0x82) { -// length = ((ef[i+2] & 0xff) << 8) | (ef[i+3] & 0xff); -// j = 4; -//// System.out.println("ef["+(i+1)+"]=0x82, setting length=" + (((ef[i+2] & 0xff) << 8) | (ef[i+3] & 0xff))); -// -// } else { -// length = ef[i+1] & 0xff; -// j = 2; -//// System.out.println("ef["+(i+1)+"]=0x" + Integer.toBinaryString(ef[i+1] & 0xff)); -// } -// -// System.out.println("setting length: 0x" + Integer.toHexString(length)); -// -//// if (cio.getTag() == 0xa4) { -//// byte[] cert = Arrays.copyOfRange(ef, 0, ef.length-1); -////// System.out.println("cert 1: \n " + toString(cert)); -// -// j = i + j + length; -// System.out.println("reading ef[" + i +"-" + (j-1) + "]:\n" + toString(Arrays.copyOfRange(ef, i, j)) ); -// ASN1Object informationObject = DerCoder.decode(Arrays.copyOfRange(ef, i, j)); -// System.out.println(ASN1.print(informationObject)); -// i = j; -// } while (i0); - } else { - System.out.println(" structure not supported: 0x" + Integer.toHexString(fd[0])); - } - } - - - @Ignore - public void todo(Certificate certificate, CommandAPDU cmdAPDU, ResponseAPDU resp, CardChannel basicChannel) throws CardException, SignatureCardException { - -// System.out.println("SELECT by Path"); -// cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x09, 0x00, new byte[] { (byte) 0x3F, (byte) 0x00, (byte) 0x56, (byte) 0x49 }, 256); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); -// -//// System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x6f))); -// -// byte[] ef = ISO7816Utils.readTransparentFile(basicChannel, -1); -// System.out.println(toString(ef)); -// -// try { -// FileOutputStream fileOutputStream = new FileOutputStream("EF.IV"); -// fileOutputStream.write(ef); -// fileOutputStream.close(); -// } catch (FileNotFoundException e1) { -// e1.printStackTrace(); -// } catch (IOException e1) { -// e1.printStackTrace(); -// } -// -// System.out.println("done."); - - final byte[] AID = new byte[] {(byte) 0xd2, (byte) 0x76, (byte) 0x00, (byte) 0x00, (byte) 0x66, (byte) 0x01}; - - System.out.println("SELECT Application (" + toString(AID) + ")"); - cmdAPDU = new CommandAPDU(0x00, 0xA4, 0x04, 0x00, AID, 256); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - System.out.println(new TLVSequence(new TLVSequence(resp.getData()).getValue(0x6f))); - -// int seid = 1; -// cmdAPDU = new CommandAPDU(0x00, 0x22, 0xF3, seid); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - System.out.println("VERIFY"); - cmdAPDU = new CommandAPDU(0x00, 0x20, 0x00, 0x81, "123456".getBytes(Charset.forName("ASCII")), 256); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - byte[] hash; - try { - MessageDigest md = MessageDigest.getInstance("SHA-1"); - hash = md.digest(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - return; - } - - byte[] oid = 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) 0x14 }; - - ByteArrayOutputStream data = new ByteArrayOutputStream(); - - try { - // oid - data.write(oid); - // hash - data.write(hash); - } catch (IOException e) { - throw new SignatureCardException(e); - } - - - System.out.println("PSO COMPUTE DIGITAL SIGNATURE"); - cmdAPDU = new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, data.toByteArray(), 256); - System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); - resp = basicChannel.transmit(cmdAPDU); - System.out.println(" -> " + toString(resp.getBytes()) + "\n"); - - if (resp.getSW() == 0x9000 && certificate != null) { - - try { - System.out.println("Verifying signature with " + ((X509Certificate) certificate).getSubjectDN()); - Signature signature = Signature.getInstance("SHA/RSA"); - signature.initVerify(certificate.getPublicKey()); - boolean valid = signature.verify(resp.getData()); - - System.out.println("Signature is " + ((valid) ? "valid" : "invalid")); - } catch (InvalidKeyException e) { - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (SignatureException e) { - e.printStackTrace(); - } - - } - - -// final byte[] data = new byte[] {}; //new byte[] {(byte) 0x7B, (byte) 0x02, (byte) 0xB6, (byte) 0x80}; -// -// System.out.println("GET DATA"); -// for (int i = 0x004D; i <= 0x004D; i++) { -// cmdAPDU = new CommandAPDU(0x00, 0xCA, 0xFF & (i >> 8), 0xFF & i, data , 256); -// resp = basicChannel.transmit(cmdAPDU); -// if (resp.getSW() == 0x9000) { -// if (i == 0x180) { -// try { -// System.out.println(new String(resp.getData(), "ASCII")); -// } catch (UnsupportedEncodingException e) { -// e.printStackTrace(); -// } -// } else { -// System.out.println(Integer.toHexString(i) + " -> " + toString(resp.getData())); -// } -// } -// } - - - -// final byte[] DST = new byte[] {}; -// -// System.out.println("MSE SET DST (" + toString(DST) + ")"); -// cmdAPDU = new CommandAPDU(0x00, 0x22, 0x04, 0x01, DST); -// System.out.println(" cmd apdu " + toString(cmdAPDU.getBytes())); -// resp = basicChannel.transmit(cmdAPDU); -// System.out.println(" -> " + toString(resp.getBytes()) + "\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)); - } - } - sb.append(']'); - return sb.toString(); - } - - - public static void main(String[] args) { - System.out.println("manually running pkcs15 test..."); - PKCS15Test test = new PKCS15Test(); -// test.setUp(); -// test.selectAndRead(); - } - -} diff --git a/smccTest/src/test/java/at/gv/egiz/pkcs15test/TLV.java b/smccTest/src/test/java/at/gv/egiz/pkcs15test/TLV.java deleted file mode 100644 index e7be62e8..00000000 --- a/smccTest/src/test/java/at/gv/egiz/pkcs15test/TLV.java +++ /dev/null @@ -1,82 +0,0 @@ -package at.gv.egiz.pkcs15test; - -/* - * Copyright 2009 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. - */ - -public class TLV { - - private byte[] bytes; - private int start; - - public TLV(byte[] bytes, int start) { - if (bytes.length - start < 2) { - throw new IllegalArgumentException("TLV must at least consit of tag and length."); - } - this.bytes = bytes; - this.start = start; - } - - /** - * @return the tag - */ - public int getTag() { - return 0xFF & bytes[start]; - } - - /** - * @return the length - */ - public int getLength() { - return 0xFF & bytes[start + 1]; - } - - /** - * @return the value - */ - public byte[] getValue() { - byte[] value = new byte[getLength()]; - System.arraycopy(bytes, start + 2, value, 0, value.length); - return value; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "Tag = " + Integer.toHexString(getTag()) + ", Length = " + getLength() + ", Value = " + toString(getValue()); - } - - 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(); - } - - - -} diff --git a/smccTest/src/test/java/at/gv/egiz/pkcs15test/TLVSequence.java b/smccTest/src/test/java/at/gv/egiz/pkcs15test/TLVSequence.java deleted file mode 100644 index fcfc22e5..00000000 --- a/smccTest/src/test/java/at/gv/egiz/pkcs15test/TLVSequence.java +++ /dev/null @@ -1,81 +0,0 @@ -package at.gv.egiz.pkcs15test; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/* - * Copyright 2009 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. - */ - -public class TLVSequence implements Iterable { - - private byte[] bytes; - - public TLVSequence(byte[] bytes) { - this.bytes = bytes; - } - - @Override - public Iterator iterator() { - return new TLVIterator(); - } - - public byte[] getValue(int tag) { - for (TLV tlv : this) { - if (tlv.getTag() == tag) { - return tlv.getValue(); - } - } - return null; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - for (TLV tlv : this) { - sb.append(tlv).append('\n'); - } - return sb.toString(); - } - - private class TLVIterator implements Iterator { - - private int pos = 0; - - @Override - public boolean hasNext() { - return (bytes.length - pos > 2); - } - - @Override - public TLV next() { - if (hasNext()) { - TLV tlv = new TLV(bytes, pos); - pos += tlv.getLength() + 2; - return tlv; - } else { - throw new NoSuchElementException(); - } - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - } - -} -- cgit v1.2.3