diff options
| author | J08nY | 2019-03-13 17:50:56 +0100 |
|---|---|---|
| committer | J08nY | 2019-03-13 17:50:56 +0100 |
| commit | dd620345feba56c413fcba1376c8a536033940b6 (patch) | |
| tree | 9a0872ed38ef115ed3ddee07055450d03dcaa310 /src/cz/crcs/ectester/reader | |
| parent | 26e5f00e782d3d060e3d78d34c16c405656f8c69 (diff) | |
| download | ECTester-dd620345feba56c413fcba1376c8a536033940b6.tar.gz ECTester-dd620345feba56c413fcba1376c8a536033940b6.tar.zst ECTester-dd620345feba56c413fcba1376c8a536033940b6.zip | |
Add custom command chaining to be able to test T=0 cards.
Diffstat (limited to 'src/cz/crcs/ectester/reader')
| -rw-r--r-- | src/cz/crcs/ectester/reader/CardMngr.java | 74 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/ECTesterReader.java | 5 |
2 files changed, 69 insertions, 10 deletions
diff --git a/src/cz/crcs/ectester/reader/CardMngr.java b/src/cz/crcs/ectester/reader/CardMngr.java index 8b6241d..5479f31 100644 --- a/src/cz/crcs/ectester/reader/CardMngr.java +++ b/src/cz/crcs/ectester/reader/CardMngr.java @@ -23,6 +23,7 @@ public class CardMngr { private boolean simulate = false; private boolean verbose = true; + private boolean extendedLength = false; private final byte[] selectCM = { (byte) 0x00, (byte) 0xa4, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0xa0, (byte) 0x00, (byte) 0x00, @@ -51,6 +52,16 @@ public class CardMngr { this.simulate = simulate; } + private void connectWithHighest() throws CardException { + try { + card = terminal.connect("T=1"); + } catch (CardException ex) { + if (verbose) + System.out.println("T=1 failed, trying protocol '*'"); + card = terminal.connect("*"); + } + } + public boolean connectToCard() throws CardException { if (simulate) return true; @@ -72,13 +83,7 @@ public class CardMngr { terminal = terminalList.get(i); if (terminal.isCardPresent()) { - try { - card = terminal.connect("T=1"); - } catch (CardException ex) { - if (verbose) - System.out.println("T=1 failed, trying protocol '*'"); - card = terminal.connect("*"); - } + connectWithHighest(); if (verbose) System.out.println("card: " + card); @@ -132,7 +137,7 @@ public class CardMngr { } if (terminal != null) { - card = terminal.connect("*"); + connectWithHighest(); if (verbose) System.out.println("card: " + card); channel = card.getBasicChannel(); @@ -324,7 +329,36 @@ public class CardMngr { System.out.println(ByteUtil.bytesToHex(apdu.getBytes())); } - long elapsed = -System.nanoTime(); + long elapsed; + if (card.getProtocol().equals("T=0") && apdu.getNc() >= 0xff) { + if (verbose) { + System.out.print("Chunking:"); + } + byte[] data = apdu.getBytes(); + int numChunks = (data.length + 254) / 255; + for (int i = 0; i < numChunks; ++i) { + int chunkStart = i *255; + int chunkLength = 255; + if (chunkStart + chunkLength > data.length) { + chunkLength = data.length - chunkStart; + } + if (verbose) { + System.out.print(" " + chunkLength); + } + byte[] chunk = new byte[chunkLength]; + System.arraycopy(data, chunkStart, chunk, 0, chunkLength); + CommandAPDU cmd = new CommandAPDU(apdu.getCLA(), 0x7a, 0, 0, chunk); + ResponseAPDU resp = channel.transmit(cmd); + if ((short) resp.getSW() != ISO7816.SW_NO_ERROR) { + return resp; + } + } + if (verbose) + System.out.println(); + apdu = new CommandAPDU(apdu.getCLA(), 0x7b, 0, 0, 0xff); + } + + elapsed = -System.nanoTime(); ResponseAPDU responseAPDU = channel.transmit(apdu); @@ -372,6 +406,28 @@ public class CardMngr { System.out.println(ByteUtil.bytesToHex(apdu.getBytes())); } + /* + if (apdu.getNc() >= 0xff) { + byte[] data = apdu.getBytes(); + int numChunks = (data.length + 254) / 255; + for (int i = 0; i < numChunks; ++i) { + int chunkStart = i *255; + int chunkLength = 255; + if (chunkStart + chunkLength > data.length) { + chunkLength = data.length - chunkStart; + } + byte[] chunk = new byte[chunkLength]; + System.arraycopy(data, chunkStart, chunk, 0, chunkLength); + CommandAPDU cmd = new CommandAPDU(apdu.getCLA(), 0x7a, 0, 0, chunk); + ResponseAPDU resp = simulator.transmitCommand(cmd); + if ((short) resp.getSW() != ISO7816.SW_NO_ERROR) { + return resp; + } + } + apdu = new CommandAPDU(apdu.getCLA(), 0x7b, 0, 0); + } + */ + ResponseAPDU response = simulator.transmitCommand(apdu); byte[] responseBytes = response.getBytes(); diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index 6372248..9447814 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -1,6 +1,6 @@ /* * ECTester, tool for testing Elliptic curve cryptography implementations. - * Copyright (c) 2016-2018 Petr Svenda <petr@svenda.com> + * Copyright (c) 2016-2019 Petr Svenda <petr@svenda.com> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -163,6 +163,9 @@ public class ECTesterReader { Security.addProvider(new BouncyCastleProvider()); } catch (SecurityException | NoClassDefFoundError ignored) { } + // Make BouncyCastle more lenient when we work with signatures in ASN.1 DER format, + // cards sometimes are not fully compliant. + System.setProperty("org.bouncycastle.asn1.allow_unsafe_integer", "true"); //do action if (cli.hasOption("export")) { |
