diff options
Diffstat (limited to 'src/simpleapdu')
| -rw-r--r-- | src/simpleapdu/CardMngr.java | 260 | ||||
| -rw-r--r-- | src/simpleapdu/DirtyLogger.java | 48 | ||||
| -rw-r--r-- | src/simpleapdu/ISO7816_status_words.txt | 71 | ||||
| -rw-r--r-- | src/simpleapdu/SimpleAPDU.java | 460 |
4 files changed, 0 insertions, 839 deletions
diff --git a/src/simpleapdu/CardMngr.java b/src/simpleapdu/CardMngr.java deleted file mode 100644 index e60f695..0000000 --- a/src/simpleapdu/CardMngr.java +++ /dev/null @@ -1,260 +0,0 @@ -package simpleapdu; - -import com.licel.jcardsim.io.CAD; -import com.licel.jcardsim.io.JavaxSmartCardInterface; -import java.util.List; -import java.util.Scanner; -import javacard.framework.AID; -import javax.smartcardio.*; - -/** - * - * @author xsvenda - */ -public class CardMngr { - private CardTerminal m_terminal = null; - private CardChannel m_channel = null; - private Card m_card = null; - - // Simulator related attributes - private CAD m_cad = null; - private JavaxSmartCardInterface m_simulator = null; - - - private final byte selectCM[] = { - (byte) 0x00, (byte) 0xa4, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0xa0, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x18, (byte) 0x43, (byte) 0x4d}; - - public static final byte OFFSET_CLA = 0x00; - public static final byte OFFSET_INS = 0x01; - public static final byte OFFSET_P1 = 0x02; - public static final byte OFFSET_P2 = 0x03; - public static final byte OFFSET_LC = 0x04; - public static final byte OFFSET_DATA = 0x05; - public static final byte HEADER_LENGTH = 0x05; - public final static short DATA_RECORD_LENGTH = (short) 0x80; // 128B per record - public final static short NUMBER_OF_RECORDS = (short) 0x0a; // 10 records - - public boolean ConnectToCard() throws Exception { - // TRY ALL READERS, FIND FIRST SELECTABLE - List<CardTerminal> terminalList = GetReaderList(); - - if (terminalList == null || terminalList.isEmpty()) { - System.out.println("No terminals found"); - return false; - } - - //List numbers of Card readers - boolean cardFound = false; - for (int i = 0; i < terminalList.size(); i++) { - System.out.println(i + " : " + terminalList.get(i)); - m_terminal = (CardTerminal) terminalList.get(i); - if (m_terminal.isCardPresent()) { - m_card = m_terminal.connect("*"); - System.out.println("card: " + m_card); - m_channel = m_card.getBasicChannel(); - - //reset the card - ATR atr = m_card.getATR(); - System.out.println(bytesToHex(m_card.getATR().getBytes())); - - cardFound = true; - } - } - - return cardFound; - } - - public boolean ConnectToCardSelect() throws CardException { - // Test available card - if more present, let user to select one - List<CardTerminal> terminalList = CardMngr.GetReaderList(); - if (terminalList == null || terminalList.isEmpty()) { - System.out.println("ERROR: No suitable reader with card detected. Please check your reader connection"); - return false; - } else { - if (terminalList.size() == 1) { - m_terminal = terminalList.get(0); // return first and only reader - } else { - int terminalIndex = 1; - // Let user select target terminal - for (CardTerminal terminal : terminalList) { - Card card; - try { - card = terminal.connect("*"); - ATR atr = card.getATR(); - System.out.println(terminalIndex + " : " + terminal.getName() + " - " + CardMngr.bytesToHex(atr.getBytes())); - terminalIndex++; - } catch (CardException ex) { - System.out.println(ex); - } - } - System.out.print("Select index of target reader you like to use 1.." + (terminalIndex - 1) + ": "); - Scanner sc = new Scanner(System.in); - int answ = sc.nextInt(); - System.out.println(String.format("%d", answ)); - answ--; // is starting with 0 - // BUGBUG; verify allowed index range - m_terminal = terminalList.get(answ); - } - } - - if (m_terminal != null) { - m_card = m_terminal.connect("*"); - System.out.println("card: " + m_card); - m_channel = m_card.getBasicChannel(); - } - - return true; - } - - public boolean isConnected() { - return m_card != null; - } - - public void DisconnectFromCard() throws Exception { - if (m_card != null) { - m_card.disconnect(false); - m_card = null; - } - } - - public byte[] GetCPLCData() throws Exception { - byte[] data; - - // TODO: Modify to obtain CPLC data - byte apdu[] = new byte[HEADER_LENGTH]; - apdu[OFFSET_CLA] = (byte) 0x00; - apdu[OFFSET_INS] = (byte) 0x00; - apdu[OFFSET_P1] = (byte) 0x00; - apdu[OFFSET_P2] = (byte) 0x00; - apdu[OFFSET_LC] = (byte) 0x00; - - ResponseAPDU resp = sendAPDU(apdu); - if (resp.getSW() != 0x9000) { // 0x9000 is "OK" - System.out.println("Fail to obtain card's response data"); - data = null; - } else { - byte temp[] = resp.getBytes(); - data = new byte[temp.length - 2]; - System.arraycopy(temp, 0, data, 0, temp.length - 2); - // Last two bytes are status word (also obtainable by resp.getSW()) - // Take a look at ISO7816_status_words.txt for common codes - } - - return data; - } - - public void ProbeCardCommands() throws Exception { - // TODO: modify to probe for instruction - for (int i = 0; i <= 0; i++) { - byte apdu[] = new byte[HEADER_LENGTH]; - apdu[OFFSET_CLA] = (byte) 0x00; - apdu[OFFSET_INS] = (byte) 0x00; - apdu[OFFSET_P1] = (byte) 0x00; - apdu[OFFSET_P2] = (byte) 0x00; - apdu[OFFSET_LC] = (byte) 0x00; - - ResponseAPDU resp = sendAPDU(apdu); - - System.out.println("Response: " + Integer.toHexString(resp.getSW())); - - if (resp.getSW() != 0x6D00) { // Note: 0x6D00 is SW_INS_NOT_SUPPORTED - // something? - } - } - } - - public static List<CardTerminal> GetReaderList() { - try { - TerminalFactory factory = TerminalFactory.getDefault(); - return factory.terminals().list(); - } catch (Exception ex) { - System.out.println("Exception : " + ex); - return null; - } - } - - public ResponseAPDU sendAPDU(byte apdu[]) throws Exception { - CommandAPDU commandAPDU = new CommandAPDU(apdu); - - System.out.println(">>>>"); - System.out.println(commandAPDU); - - System.out.println(bytesToHex(commandAPDU.getBytes())); - - long elapsed = -System.nanoTime(); - - ResponseAPDU responseAPDU = m_channel.transmit(commandAPDU); - - elapsed += System.nanoTime(); - - System.out.println(responseAPDU); - System.out.println(bytesToHex(responseAPDU.getBytes())); - - if (responseAPDU.getSW1() == (byte) 0x61) { - CommandAPDU apduToSend = new CommandAPDU((byte) 0x00, - (byte) 0xC0, (byte) 0x00, (byte) 0x00, - responseAPDU.getSW1()); - - responseAPDU = m_channel.transmit(apduToSend); - System.out.println(bytesToHex(responseAPDU.getBytes())); - } - - System.out.println("<<<<"); - System.out.println("Elapsed time (ms): " + elapsed / 1000000); - return (responseAPDU); - } - - public static String byteToHex(byte data) { - StringBuilder buf = new StringBuilder(); - buf.append(toHexChar((data >>> 4) & 0x0F)); - buf.append(toHexChar(data & 0x0F)); - return buf.toString(); - } - - - public static char toHexChar(int i) { - if ((0 <= i) && (i <= 9)) { - return (char) ('0' + i); - } else { - return (char) ('a' + (i - 10)); - } - } - - public static String bytesToHex(byte[] data) { - return bytesToHex(data, 0, data.length, true); - } - - public static String bytesToHex(byte[] data, int offset, int len, boolean bAddSpace) { - StringBuilder buf = new StringBuilder(); - for (int i = offset; i < (offset + len); i++) { - buf.append(byteToHex(data[i])); - if (bAddSpace) { buf.append(" "); } - } - return (buf.toString()); - } - - public boolean prepareLocalSimulatorApplet(byte[] appletAIDArray, byte[] installData, Class appletClass) { - System.setProperty("com.licel.jcardsim.terminal.type", "2"); - m_cad = new CAD(System.getProperties()); - m_simulator = (JavaxSmartCardInterface) m_cad.getCardInterface(); - AID appletAID = new AID(appletAIDArray, (short) 0, (byte) appletAIDArray.length); - - AID appletAIDRes = m_simulator.installApplet(appletAID, appletClass, installData, (short) 0, (byte) installData.length); - return m_simulator.selectApplet(appletAID); - } - - public byte[] sendAPDUSimulator(byte apdu[]) throws Exception { - System.out.println(">>>>"); - System.out.println(bytesToHex(apdu)); - - byte[] responseBytes = m_simulator.transmitCommand(apdu); - - System.out.println(bytesToHex(responseBytes)); - System.out.println("<<<<"); - - return responseBytes; - } - - -} diff --git a/src/simpleapdu/DirtyLogger.java b/src/simpleapdu/DirtyLogger.java deleted file mode 100644 index c06571b..0000000 --- a/src/simpleapdu/DirtyLogger.java +++ /dev/null @@ -1,48 +0,0 @@ -package simpleapdu; - -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * - * @author xsvenda - */ -public class DirtyLogger { - FileOutputStream m_logFile; - boolean m_bOutputSystemOut = true; - - public DirtyLogger(FileOutputStream logFile, boolean bOutputSystemOut) { - m_logFile = logFile; - m_bOutputSystemOut = bOutputSystemOut; - } - public void println() { - String logLine = "\n"; - print(logLine); - } - public void println(String logLine) { - logLine += "\n"; - print(logLine); - } - public void print(String logLine) { - if (m_bOutputSystemOut) { - System.out.print(logLine); - } - if (m_logFile != null) { - try { - m_logFile.write(logLine.getBytes()); - } catch (IOException ex) { - } - } - } - - void flush() { - try { - m_logFile.flush(); - } catch (IOException ex) { - } - } - - void close() throws IOException { - m_logFile.close(); - } -} diff --git a/src/simpleapdu/ISO7816_status_words.txt b/src/simpleapdu/ISO7816_status_words.txt deleted file mode 100644 index bf5af2b..0000000 --- a/src/simpleapdu/ISO7816_status_words.txt +++ /dev/null @@ -1,71 +0,0 @@ -public interface ISO7816 { - - // Fields - public static final byte INS_EXTERNAL_AUTHENTICATE = -126; - public static final byte INS_SELECT = -92; - public static final byte CLA_ISO7816 = 0; - public static final byte OFFSET_CDATA = 5; - public static final byte OFFSET_LC = 4; - public static final byte OFFSET_P2 = 3; - public static final byte OFFSET_P1 = 2; - public static final byte OFFSET_INS = 1; - public static final byte OFFSET_CLA = 0; - public static final short SW_FILE_FULL = 27268; 0x6A84 - public static final short SW_UNKNOWN = 28416; 0x6F00 - public static final short SW_CLA_NOT_SUPPORTED = 28160; 0x6E00 - public static final short SW_INS_NOT_SUPPORTED = 27904; 0x6D00 - public static final short SW_CORRECT_LENGTH_00 = 27648; 0x6C00 - public static final short SW_WRONG_P1P2 = 27392; 0x6B00 - public static final short SW_INCORRECT_P1P2 = 27270; 0x6A86 - public static final short SW_RECORD_NOT_FOUND = 27267; 0x6A83 - public static final short SW_FILE_NOT_FOUND = 27266; 0x6A82 - public static final short SW_FUNC_NOT_SUPPORTED = 27265; 0x6A81 - public static final short SW_WRONG_DATA = 27264; 0x6A80 - public static final short SW_APPLET_SELECT_FAILED = 27033; 0x6999 - public static final short SW_COMMAND_NOT_ALLOWED = 27014; 0x6986 - public static final short SW_CONDITIONS_NOT_SATISFIED = 27013; 0x6985 - public static final short SW_DATA_INVALID = 27012; 0x6984 - public static final short SW_FILE_INVALID = 27011; 0x6983 - public static final short SW_SECURITY_STATUS_NOT_SATISFIED = 27010; 0x6982 - public static final short SW_WRONG_LENGTH = 26368; 0x6700 - public static final short SW_BYTES_REMAINING_00 = 24832; 0x6100 - public static final short SW_NO_ERROR = -28672; 0x9000 -} - -public interface JCStatus { -static int ALGORITHM_NOT_SUPPORTED = 0x9484; -static int APPLET_INVALIDATED = 0x6283; -static int APPLET_SELECT_FAILED = 0x6999 -static int AUTHENTICATION_FAILED = 0x6300 -static int AUTHORIZATION_FAILED = 0x9482 -static int CHECKSUM_FAILED = 0x9584 -static int CLA_NOT_SUPPORTED = 0x6E00 -static int COMMAND_NOT_ALLOWED = 0x6986 -static int CONDITIONS_NOT_SATISFIED = 0x6985 -static int CORRECT_LENGTH_00 = 0x6C00 -static int DATA_INVALID = 0x6984 -static int DECRYPTION_FAILED = 0x9583 -static int FILE_FULL = 0x6A84 -static int FILE_INVALID = 0x6983 -static int FILE_NOT_FOUND = 0x6A82 -static int FUNC_NOT_SUPPORTED = 0x6A81 -static int INCORRECT_P1P2 = 0x6A86 -static int INS_NOT_SUPPORTED = 0x6D00 -static int INSTALLATION_FAILED = 0x9585 -static int INVALID_STATE = 0x9481 -static int NO_ERROR = 0x9000 -static int NO_SPECIFIC_DIAGNOSIS = 0x6400 -static int PIN_REQUIRED = 0x6982 -static int RECORD_NOT_FOUND = 0x6A83 -static int REFERENCE_DATA_NOT_FOUND = 0x6A88 -static int REGISTRATION_FAILED = 0x9586 -static int SECURITY_STATUS_NOT_SATISFIED = 0x6982 -static int SIGNATURE_CHECK_FAILED = 0x9582 -static int SM_INCORRECT = 0x6988 -static int SM_MISSING = 0x6987 -static int TRUNCATED_DATA = 0x6100 -static int UNKNOWN = 0x6F00 -static int WRONG_DATA = 0x6A80 -static int WRONG_LENGTH = 0x6700 -static int WRONG_P1P2 = 0x6B00 -}
\ No newline at end of file diff --git a/src/simpleapdu/SimpleAPDU.java b/src/simpleapdu/SimpleAPDU.java deleted file mode 100644 index 5e51221..0000000 --- a/src/simpleapdu/SimpleAPDU.java +++ /dev/null @@ -1,460 +0,0 @@ -package simpleapdu; - -import applets.EC_Consts; -import applets.SimpleECCApplet; -import javacard.framework.ISO7816; -import javacard.security.CryptoException; -import javacard.security.KeyPair; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; - -import javax.smartcardio.ResponseAPDU; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Arrays; - - -/** - * @author Petr Svenda petr@svenda.com - */ -public class SimpleAPDU { - private CardMngr cardManager = new CardMngr(); - private DirtyLogger systemOutLogger = null; - - private CommandLineParser cliParser = new DefaultParser(); - private Options opts = new Options(); - private static final String cliHeader = ""; - private static final String cliFooter = ""; - - private final static byte SELECT_ECTESTERAPPLET[] = {(byte) 0x00, (byte) 0xa4, (byte) 0x04, (byte) 0x00, (byte) 0x0a, - (byte) 0x45, (byte) 0x43, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x30, (byte) 0x31}; - - private static final byte TESTECSUPPORTALL_FP[] = {(byte) 0xB0, (byte) 0x5E, (byte) 0x00, (byte) 0x00, (byte) 0x00}; - private static final byte TESTECSUPPORTALL_F2M[] = {(byte) 0xB0, (byte) 0x5F, (byte) 0x00, (byte) 0x00, (byte) 0x00}; - private static final byte TESTECSUPPORT_GIVENALG[] = {(byte) 0xB0, (byte) 0x71, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00}; - private static final short TESTECSUPPORT_ALG_OFFSET = 5; - private static final short TESTECSUPPORT_KEYLENGTH_OFFSET = 6; - - private static final byte TESTECSUPPORTALL_LASTUSEDPARAMS[] = {(byte) 0xB0, (byte) 0x40, (byte) 0x00, (byte) 0x00, (byte) 0x00}; - - private static final byte TESTECSUPPORTALL_FP_KEYGEN_INVALIDCURVEB[] = {(byte) 0xB0, (byte) 0x70, (byte) 0x00, (byte) 0x00, (byte) 0x05, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}; - private static final short INVALIDCURVEB_NUMREPEATS_OFFSET = 5; - private static final short INVALIDCURVEB_CORRUPTIONTYPE_OFFSET = 7; - private static final short INVALIDCURVEB_REWINDONSUCCESS_OFFSET = 9; - - private static final byte TESTECSUPPORT_GENERATEECCKEY[] = {(byte) 0xB0, (byte) 0x5a, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}; - private static final short GENERATEECKEY_ALG_OFFSET = 5; - private static final short GENERATEECKEY_KEYLENGTH_OFFSET = 6; - private static final short GENERATEECKEY_ANOMALOUS_OFFSET = 8; - - - private void run(String[] args) { - try { - //parse cmd args - CommandLine cli = parseArgs(args); - - //byte[] installData = new byte[10]; - //byte[] AID = {(byte) 0x4C, (byte) 0x61, (byte) 0x62, (byte) 0x61, (byte) 0x6B, (byte) 0x41, (byte) 0x70, (byte) 0x70, (byte) 0x6C, (byte) 0x65, (byte) 0x74}; - //cardManager.prepareLocalSimulatorApplet(AID, installData, SimpleECCApplet.class); - - //do stuff - if (cli.hasOption("help")) { - HelpFormatter help = new HelpFormatter(); - help.printHelp("SimpleAPDU", cliHeader, opts, cliFooter); - } else { - //open log(only when actually doing something) - String logFileName = cli.getOptionValue("output-file", String.format("ECTESTER_log_%d.log", System.currentTimeMillis())); - FileOutputStream stdoutStream = new FileOutputStream(logFileName); - systemOutLogger = new DirtyLogger(stdoutStream, true); - - boolean fp = cli.hasOption("fp"); - boolean f2m = cli.hasOption("f2m"); - if (!fp && !f2m) { - fp = true; - f2m = true; - } - int genAmount = Integer.parseInt(cli.getOptionValue("generate", "0")); - int keyLength = Integer.parseInt(cli.getOptionValue("b", "192")); - - if (cli.hasOption("generate")) { - //generate EC keys - if (fp) { - generateECKeys(genAmount, KeyPair.ALG_EC_FP, (short) keyLength, cli.hasOption("anomalous")); - } - if (f2m) { - generateECKeys(genAmount, KeyPair.ALG_EC_F2M, (short) keyLength, cli.hasOption("anomalous")); - } - } else if (cli.hasOption("test")) { - if (cli.hasOption("bit-size")) { - //test only one bitsize - if (fp) { - testSupportECFp((short) keyLength); - } - if (f2m) { - testSupportECFp((short) keyLength); - } - } else { - //test default bit sizes - testSupportECAll(fp, f2m); - testFPkeyGen((short) 10, EC_Consts.CORRUPTION_ONEBYTERANDOM, true); - } - } else { - systemOutLogger.println("You need to specify one of -t / -g [num] commands."); - } - - //close log - systemOutLogger.close(); - } - - //disconnect - cardManager.DisconnectFromCard(); - } catch (Exception ex) { - if (systemOutLogger != null) { - systemOutLogger.println("Exception : " + ex); - } - } - } - - private CommandLine parseArgs(String[] args) throws ParseException { - - opts.addOption("h", "help", false, "show this help"); - opts.addOption(Option.builder("g") - .longOpt("generate") - .hasArg() - .optionalArg(true) - .argName("num") - .desc("generate EC keys").build()); - opts.addOption("t", "test", false, "test EC support (default)"); - opts.addOption(Option.builder("b") - .longOpt("bit-size") - .hasArg() - .argName("bits") - .desc("set EC bit size").build()); - opts.addOption("f2m", "use EC over binary-fields"); - opts.addOption("fp", "user EC over prime-fields (default)"); - opts.addOption("s", "anomalous", false, "generate anomalous (non-prime order, small pubkey order) curves"); - opts.addOption(Option.builder("o") - .longOpt("output-file") - .hasArg() - .argName("file") - .desc("output file to log to").build()); - return cliParser.parse(opts, args); - } - - static short getShort(byte[] array, int offset) { - return (short) (((array[offset] & 0xFF) << 8) | (array[offset + 1] & 0xFF)); - } - - static void setShort(byte[] array, int offset, short value) { - array[offset + 1] = (byte) (value & 0xFF); - array[offset] = (byte) ((value >> 8) & 0xFF); - } - - private boolean ReconnnectToCard() throws Exception { - if (cardManager.isConnected()) { - cardManager.DisconnectFromCard(); - } - - boolean result = cardManager.ConnectToCard(); - if (result) { - // Select our application on card - cardManager.sendAPDU(SELECT_ECTESTERAPPLET); - } - return result; - } - - private void testFPkeyGen(short numRepeats, short corruptionType, boolean bRewind) throws Exception { - byte[] apdu = Arrays.copyOf(TESTECSUPPORTALL_FP_KEYGEN_INVALIDCURVEB, TESTECSUPPORTALL_FP_KEYGEN_INVALIDCURVEB.length); - setShort(apdu, INVALIDCURVEB_NUMREPEATS_OFFSET, numRepeats); - setShort(apdu, INVALIDCURVEB_CORRUPTIONTYPE_OFFSET, corruptionType); - apdu[INVALIDCURVEB_REWINDONSUCCESS_OFFSET] = bRewind ? (byte) 1 : (byte) 0; - - ReconnnectToCard(); - ResponseAPDU resp_fp_keygen = cardManager.sendAPDU(apdu); - ResponseAPDU resp_keygen_params = cardManager.sendAPDU(TESTECSUPPORTALL_LASTUSEDPARAMS); - PrintECKeyGenInvalidCurveB(resp_fp_keygen); - PrintECKeyGenInvalidCurveB_lastUserParams(resp_keygen_params); - } - - private void testSupportECGivenAlg(short keyLength, byte keyClass) throws Exception { - byte[] apdu = Arrays.copyOf(TESTECSUPPORT_GIVENALG, TESTECSUPPORT_GIVENALG.length); - apdu[TESTECSUPPORT_ALG_OFFSET] = keyClass; - setShort(apdu, TESTECSUPPORT_KEYLENGTH_OFFSET, keyLength); - - ReconnnectToCard(); - ResponseAPDU resp = cardManager.sendAPDU(apdu); - //byte[] resp = cardManager.sendAPDUSimulator(apdu); - PrintECSupport(resp); - } - - private void testSupportECFp(short keyLength) throws Exception { - testSupportECGivenAlg(keyLength, KeyPair.ALG_EC_FP); - } - - private void testSupportECF2m(short keyLength) throws Exception { - testSupportECGivenAlg(keyLength, KeyPair.ALG_EC_F2M); - } - - private void testSupportECAll(boolean testFp, boolean testF2m) throws Exception { - if (testFp) { - testSupportECFp((short) 128); - testSupportECFp((short) 192); - testSupportECFp((short) 224); - testSupportECFp((short) 256); - testSupportECFp((short) 384); - testSupportECFp((short) 521); - } - - if (testF2m) { - testSupportECF2m((short) 113); - testSupportECF2m((short) 131); - testSupportECF2m((short) 163); - testSupportECF2m((short) 193); - } - } - - private void generateECKeys(int amount, byte keyClass, short keyLength, boolean anomalous) throws Exception { - if (cardManager.ConnectToCardSelect()) { - cardManager.sendAPDU(SELECT_ECTESTERAPPLET); - - String keyFileName = String.format("ECKEYS_%s_%d.log", keyClass == KeyPair.ALG_EC_FP ? "fp" : "f2m", System.currentTimeMillis()); - FileOutputStream keysFile = new FileOutputStream(keyFileName); - - String message = "index;time;pubW;privS\n"; - keysFile.write(message.getBytes()); - byte[] gatherKeyAPDU = Arrays.copyOf(TESTECSUPPORT_GENERATEECCKEY, TESTECSUPPORT_GENERATEECCKEY.length); - // Prepare keypair object - gatherKeyAPDU[ISO7816.OFFSET_P1] = SimpleECCApplet.P1_SETCURVE; - gatherKeyAPDU[GENERATEECKEY_ALG_OFFSET] = keyClass; - setShort(gatherKeyAPDU, GENERATEECKEY_KEYLENGTH_OFFSET, keyLength); - gatherKeyAPDU[GENERATEECKEY_ANOMALOUS_OFFSET] = anomalous ? (byte) 1 : (byte) 0; - - ResponseAPDU respGather = cardManager.sendAPDU(gatherKeyAPDU); - if (respGather.getSW() != ISO7816.SW_NO_ERROR) { - systemOutLogger.println(String.format("Card error: %x", respGather.getSW())); - keysFile.close(); - return; - } - - // Generate new keypair - gatherKeyAPDU[ISO7816.OFFSET_P1] = SimpleECCApplet.P1_GENERATEKEYPAIR; - int counter = 0; - while (true) { - counter++; - long elapsed = -System.nanoTime(); - respGather = cardManager.sendAPDU(gatherKeyAPDU); - elapsed += System.nanoTime(); - - if (respGather.getSW() != ISO7816.SW_NO_ERROR) { - systemOutLogger.println(String.format("Card error: %x", respGather.getSW())); - break; - } - byte[] data = respGather.getData(); - int offset = 0; - String pubKeyW = ""; - String privKeyS = ""; - if (data[offset] == EC_Consts.TAG_ECPUBKEY) { - offset++; - short len = getShort(data, offset); - offset += 2; - pubKeyW = CardMngr.bytesToHex(data, offset, len, false); - offset += len; - } - if (data[offset] == EC_Consts.TAG_ECPRIVKEY) { - offset++; - short len = getShort(data, offset); - offset += 2; - privKeyS = CardMngr.bytesToHex(data, offset, len, false); - offset += len; - } - - message = String.format("%d;%d;%s;%s\n", counter, elapsed / 1000000, pubKeyW, privKeyS); - keysFile.write(message.getBytes()); - - this.systemOutLogger.flush(); - keysFile.flush(); - - //stop when we have enough keys, go on forever with 0 - if (counter >= amount && amount != 0) - break; - } - keysFile.close(); - } - } - - private static String getPrintError(short code) { - if (code == ISO7816.SW_NO_ERROR) { - return "OK\t(0x9000)"; - } else { - String codeStr = "unknown"; - if (code == CryptoException.ILLEGAL_VALUE) { - codeStr = "ILLEGAL_VALUE"; - } - if (code == CryptoException.UNINITIALIZED_KEY) { - codeStr = "UNINITIALIZED_KEY"; - } - if (code == CryptoException.NO_SUCH_ALGORITHM) { - codeStr = "NO_SUCH_ALG"; - } - if (code == CryptoException.INVALID_INIT) { - codeStr = "INVALID_INIT"; - } - if (code == CryptoException.ILLEGAL_USE) { - codeStr = "ILLEGAL_USE"; - } - if (code == SimpleECCApplet.SW_SKIPPED) { - codeStr = "skipped"; - } - if (code == SimpleECCApplet.SW_KEYPAIR_GENERATED_INVALID) { - codeStr = "SW_KEYPAIR_GENERATED_INVALID"; - } - if (code == SimpleECCApplet.SW_INVALID_CORRUPTION_TYPE) { - codeStr = "SW_INVALID_CORRUPTION_TYPE"; - } - if (code == SimpleECCApplet.SW_SIG_VERIFY_FAIL) { - codeStr = "SW_SIG_VERIFY_FAIL"; - } - return String.format("fail\t(%s,\t0x%4x)", codeStr, code); - } - } - - enum ExpResult { - SHOULD_SUCCEED, - MAY_FAIL, - MUST_FAIL - } - - private int VerifyPrintResult(String message, byte expectedTag, byte[] buffer, int bufferOffset, ExpResult expRes) { - if (bufferOffset >= buffer.length) { - systemOutLogger.println(" No more data returned"); - } else { - if (buffer[bufferOffset] != expectedTag) { - systemOutLogger.println(" ERROR: mismatched tag"); - assert (buffer[bufferOffset] == expectedTag); - } - bufferOffset++; - short resCode = getShort(buffer, bufferOffset); - bufferOffset += 2; - - boolean bHiglight = false; - if ((expRes == ExpResult.MUST_FAIL) && (resCode == ISO7816.SW_NO_ERROR)) { - bHiglight = true; - } - if ((expRes == ExpResult.SHOULD_SUCCEED) && (resCode != ISO7816.SW_NO_ERROR)) { - bHiglight = true; - } - if (bHiglight) { - systemOutLogger.println(String.format("!! %-53s%s", message, getPrintError(resCode))); - } else { - systemOutLogger.println(String.format(" %-53s%s", message, getPrintError(resCode))); - } - } - return bufferOffset; - } - - private void PrintECSupport(ResponseAPDU resp) { - PrintECSupport(resp.getData()); - } - - private void PrintECSupport(byte[] buffer) { - systemOutLogger.println(); - systemOutLogger.println("### Test for support and with valid and invalid EC curves"); - int bufferOffset = 0; - while (bufferOffset < buffer.length) { - assert (buffer[bufferOffset] == SimpleECCApplet.ECTEST_SEPARATOR); - bufferOffset++; - String ecType = "unknown"; - if (buffer[bufferOffset] == KeyPair.ALG_EC_FP) { - ecType = "ALG_EC_FP"; - } - if (buffer[bufferOffset] == KeyPair.ALG_EC_F2M) { - ecType = "ALG_EC_F2M"; - } - systemOutLogger.println(String.format("%-56s%s", "EC type:", ecType)); - bufferOffset++; - short keyLen = getShort(buffer, bufferOffset); - systemOutLogger.println(String.format("%-56s%d bits", "EC key length (bits):", keyLen)); - bufferOffset += 2; - - bufferOffset = VerifyPrintResult("KeyPair object allocation:", SimpleECCApplet.ECTEST_ALLOCATE_KEYPAIR, buffer, bufferOffset, ExpResult.SHOULD_SUCCEED); - bufferOffset = VerifyPrintResult("Generate key with def curve (fails if no def):", SimpleECCApplet.ECTEST_GENERATE_KEYPAIR_DEFCURVE, buffer, bufferOffset, ExpResult.MAY_FAIL); - bufferOffset = VerifyPrintResult("Set valid custom curve:", SimpleECCApplet.ECTEST_SET_VALIDCURVE, buffer, bufferOffset, ExpResult.SHOULD_SUCCEED); - bufferOffset = VerifyPrintResult("Generate key with valid curve:", SimpleECCApplet.ECTEST_GENERATE_KEYPAIR_CUSTOMCURVE, buffer, bufferOffset, ExpResult.SHOULD_SUCCEED); - bufferOffset = VerifyPrintResult("ECDH agreement with valid point:", SimpleECCApplet.ECTEST_ECDH_AGREEMENT_VALID_POINT, buffer, bufferOffset, ExpResult.SHOULD_SUCCEED); - bufferOffset = VerifyPrintResult("ECDH agreement with invalid point (fail is good):", SimpleECCApplet.ECTEST_ECDH_AGREEMENT_INVALID_POINT, buffer, bufferOffset, ExpResult.MUST_FAIL); - bufferOffset = VerifyPrintResult("ECDSA signature on random data:", SimpleECCApplet.ECTEST_ECDSA_SIGNATURE, buffer, bufferOffset, ExpResult.SHOULD_SUCCEED); - bufferOffset = VerifyPrintResult("Set anomalous custom curve (may fail):", SimpleECCApplet.ECTEST_SET_ANOMALOUSCURVE, buffer, bufferOffset, ExpResult.MAY_FAIL); - bufferOffset = VerifyPrintResult("Generate key with anomalous curve (may fail):", SimpleECCApplet.ECTEST_GENERATE_KEYPAIR_ANOMALOUSCURVE, buffer, bufferOffset, ExpResult.MAY_FAIL); - bufferOffset = VerifyPrintResult("ECDH agreement with small order point (fail is good):", SimpleECCApplet.ECTEST_ECDH_AGREEMENT_SMALL_DEGREE_POINT, buffer, bufferOffset, ExpResult.MUST_FAIL); - bufferOffset = VerifyPrintResult("Set invalid custom curve (may fail):", SimpleECCApplet.ECTEST_SET_INVALIDCURVE, buffer, bufferOffset, ExpResult.MAY_FAIL); - bufferOffset = VerifyPrintResult("Generate key with invalid curve (fail is good):", SimpleECCApplet.ECTEST_GENERATE_KEYPAIR_INVALIDCUSTOMCURVE, buffer, bufferOffset, ExpResult.MUST_FAIL); - bufferOffset = VerifyPrintResult("Set invalid field (may fail):", SimpleECCApplet.ECTEST_SET_INVALIDFIELD, buffer, bufferOffset, ExpResult.MAY_FAIL); - bufferOffset = VerifyPrintResult("Generate key with invalid field (fail si good):", SimpleECCApplet.ECTEST_GENERATE_KEYPAIR_INVALIDFIELD, buffer, bufferOffset, ExpResult.MUST_FAIL); - - systemOutLogger.println(); - } - } - - private void PrintECKeyGenInvalidCurveB(ResponseAPDU resp) { - PrintECKeyGenInvalidCurveB(resp.getData()); - } - - private void PrintECKeyGenInvalidCurveB(byte[] buffer) { - systemOutLogger.println(); - systemOutLogger.println("### Test for computation with invalid parameter B for EC curve"); - int bufferOffset = 0; - while (bufferOffset < buffer.length) { - assert (buffer[bufferOffset] == SimpleECCApplet.ECTEST_SEPARATOR); - bufferOffset++; - String ecType = "unknown"; - if (buffer[bufferOffset] == KeyPair.ALG_EC_FP) { - ecType = "ALG_EC_FP"; - } - if (buffer[bufferOffset] == KeyPair.ALG_EC_F2M) { - ecType = "ALG_EC_F2M"; - } - systemOutLogger.println(String.format("%-53s%s", "EC type:", ecType)); - bufferOffset++; - short keyLen = getShort(buffer, bufferOffset); - systemOutLogger.println(String.format("%-53s%d bits", "EC key length (bits):", keyLen)); - bufferOffset += 2; - - short numRepeats = getShort(buffer, bufferOffset); - bufferOffset += 2; - systemOutLogger.println(String.format("%-53s%d times", "Executed repeats before unexpected error: ", numRepeats)); - - bufferOffset = VerifyPrintResult("KeyPair object allocation:", SimpleECCApplet.ECTEST_ALLOCATE_KEYPAIR, buffer, bufferOffset, ExpResult.SHOULD_SUCCEED); - while (bufferOffset < buffer.length) { - bufferOffset = VerifyPrintResult("Set invalid custom curve:", SimpleECCApplet.ECTEST_SET_INVALIDCURVE, buffer, bufferOffset, ExpResult.SHOULD_SUCCEED); - bufferOffset = VerifyPrintResult("Generate key with invalid curve (fail is good):", SimpleECCApplet.ECTEST_GENERATE_KEYPAIR_INVALIDCUSTOMCURVE, buffer, bufferOffset, ExpResult.MUST_FAIL); - if (buffer[bufferOffset] == SimpleECCApplet.ECTEST_DH_GENERATESECRET) { - bufferOffset = VerifyPrintResult("ECDH agreement with invalid point (fail is good):", SimpleECCApplet.ECTEST_DH_GENERATESECRET, buffer, bufferOffset, ExpResult.MUST_FAIL); - } - bufferOffset = VerifyPrintResult("Set valid custom curve:", SimpleECCApplet.ECTEST_SET_VALIDCURVE, buffer, bufferOffset, ExpResult.SHOULD_SUCCEED); - bufferOffset = VerifyPrintResult("Generate key with valid curve:", SimpleECCApplet.ECTEST_GENERATE_KEYPAIR_CUSTOMCURVE, buffer, bufferOffset, ExpResult.SHOULD_SUCCEED); - } - - systemOutLogger.println(); - } - } - - private void PrintECKeyGenInvalidCurveB_lastUserParams(ResponseAPDU resp) { - byte[] buffer = resp.getData(); - short offset = 0; - systemOutLogger.print("Last used value of B: "); - while (offset < buffer.length) { - systemOutLogger.print(String.format("%x ", buffer[offset])); - offset++; - } - } - - public static void main(String[] args) throws IOException { - SimpleAPDU app = new SimpleAPDU(); - app.run(args); - } -} |
