1 /** 2 * --------- 3 * |.##> <##.| Open Smart Card Development Platform (www.openscdp.org) 4 * |# #| 5 * |# #| Copyright (c) 1999-2009 CardContact Software & System Consulting 6 * |'##> <##'| Andreas Schwier, 32429 Minden, Germany (www.cardcontact.de) 7 * --------- 8 * 9 * This file is part of OpenSCDP. 10 * 11 * OpenSCDP is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 * 15 * OpenSCDP is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with OpenSCDP; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 * 24 * @fileoverview A simple card simulation 25 */ 26 27 load("filesystem.js"); 28 load("commandinterpreter.js"); 29 load("securechannel.js"); 30 31 32 /** 33 * Create a card simulation object 34 * 35 * @class Class implementing a simple ISO 7816-4 card simulation 36 * @constructor 37 */ 38 function SimpleCardSimulator() { 39 var aid = new ByteString("A0000000010101", HEX); 40 41 var efdir_example = new ASN1(0x61, 42 new ASN1(0x4F, aid), 43 new ASN1(0x50, new ByteString("Example Application", ASCII)) 44 ); 45 46 var efdir = [ efdir_example.getBytes() ]; 47 48 this.mf = new DF(FCP.newDF("3F00", null), 49 new LinearEF(FCP.newLinearEF("2F00", 30, FCP.LINEARVARIABLE, 20, 10), efdir), 50 new TransparentEF(FCP.newTransparentEF("2F02", 1, 100), new ByteString("5A0A00010203040506070809", HEX)), 51 new TransparentEF(FCP.newTransparentEF("EF01", 2, 100), new ByteString("4041424344", HEX)), 52 new DF(FCP.newDF("DF01", this.aid), 53 new TransparentEF(FCP.newTransparentEF("EF01", 0, 100)), 54 new TransparentEF(FCP.newTransparentEF("EF02", 0, 100)) 55 ) 56 ); 57 58 print(this.mf.dump("")); 59 60 this.initialize(); 61 } 62 63 64 65 /** 66 * Initialize card runtime 67 */ 68 SimpleCardSimulator.prototype.initialize = function() { 69 this.fileSelector = new FileSelector(this.mf); 70 this.commandInterpreter = new CommandInterpreter(this.fileSelector); 71 72 var sm = new SecureChannel(new Crypto()); 73 74 sm.setSendSequenceCounterPolicy(IsoSecureChannel.SSC_SYNC_ENC_POLICY); 75 76 var k = new Key(); 77 k.setComponent(Key.AES, new ByteString("7CA110454A1A6E570131D9619DC1376E4A1A6E570131D961", HEX)); 78 sm.setMacKey(k); 79 80 var k = new Key(); 81 k.setComponent(Key.AES, new ByteString("0131D9619DC1376E7CA110454A1A6E579DC1376E7CA11045", HEX)); 82 sm.setEncKey(k); 83 84 sm.setMACSendSequenceCounter(new ByteString("00000000000000000000000000000000", HEX)); 85 86 this.commandInterpreter.setSecureChannel(sm); 87 } 88 89 90 91 /** 92 * Process an inbound APDU 93 * 94 * @param {ByteString} capdu the command APDU 95 * @type ByteString 96 * @return the response APDU 97 */ 98 SimpleCardSimulator.prototype.processAPDU = function(capdu) { 99 print("Command APDU : " + capdu); 100 101 var apdu; 102 103 try { 104 apdu = new APDU(capdu); 105 } 106 catch(e) { 107 GPSystem.trace(e); 108 var sw = APDU.SW_GENERALERROR; 109 if (e instanceof GPError) { 110 sw = e.reason; 111 } 112 var bb = new ByteBuffer(); 113 bb.append(sw >> 8); 114 bb.append(sw & 0xFF); 115 return bb.toByteString(); 116 } 117 118 this.commandInterpreter.processAPDU(apdu); 119 120 var rapdu = apdu.getResponseAPDU(); 121 print("Response APDU: " + rapdu); 122 return rapdu; 123 } 124 125 126 127 /** 128 * Respond to reset request 129 * 130 * @param {Number} type reset type (One of Card.RESET_COLD or Card.RESET.WARM) 131 * @type ByteString 132 * @return answer to reset 133 */ 134 SimpleCardSimulator.prototype.reset = function(type) { 135 print("Reset type: " + type); 136 137 this.initialize(); 138 139 var atr = new ByteString("3B600000", HEX); 140 return atr; 141 } 142 143 144 145 /** 146 * Create new simulation and register with existing or newly created adapter singleton. 147 * 148 */ 149 SimpleCardSimulator.newInstance = function() { 150 var sim = new SimpleCardSimulator(); 151 152 if (typeof(CARDSIM) == "undefined") { 153 var adapter = new CardSimulationAdapter("JCOPSimulation", "8050"); 154 adapter.setSimulationObject(sim); 155 adapter.start(); 156 CARDSIM = adapter; 157 print("Simulation running..."); 158 } else { 159 CARDSIM.setSimulationObject(sim); 160 print("Simulation replaced..."); 161 } 162 } 163 164 165 166 SimpleCardSimulator.newInstance(); 167