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 An eID card simulation 25 */ 26 27 load("tools/file.js"); 28 29 load("../cardsim/filesystem.js"); 30 load("../cardsim/authenticationobject.js"); 31 load("../cardsim/trustanchor.js"); 32 load("../cardsim/signaturekey.js"); 33 34 load("eidcommandinterpreter.js"); 35 load("eidaccesscontroller.js"); 36 load("../cardsim/securechannel.js"); 37 38 load("../icao/eac20.js"); 39 load("../icao/cvc.js"); 40 load("../icao/pace.js"); 41 load("../icao/chipauthentication.js"); 42 load("../icao/restrictedidentification.js"); 43 44 45 var mrz = "TPD<<T220001293<<<<<<<<<<<<<<<" + 46 "6408125<1010318D<<<<<<<<<<<<<6" + 47 "MUSTERMANN<<ERIKA<<<<<<<<<<<<<"; 48 49 var paceInfo = new PACEInfo(); 50 paceInfo.protocol = new ByteString("id-PACE-ECDH-GM-AES-CBC-CMAC-128", OID); 51 paceInfo.version = 2; 52 paceInfo.parameterId = 13; 53 54 var chipAuthenticationInfo = new ChipAuthenticationInfo(); 55 chipAuthenticationInfo.protocol = new ByteString("id-CA-ECDH-AES-CBC-CMAC-128", OID); 56 chipAuthenticationInfo.version = 2; 57 chipAuthenticationInfo.keyId = 16; 58 59 var privChipAuthenticationInfo = new ChipAuthenticationInfo(); 60 privChipAuthenticationInfo.protocol = new ByteString("id-CA-ECDH-AES-CBC-CMAC-128", OID); 61 privChipAuthenticationInfo.version = 2; 62 privChipAuthenticationInfo.keyId = 17; 63 64 var chipAuthenticationInfoDG14 = new ChipAuthenticationInfo(); 65 chipAuthenticationInfoDG14.protocol = new ByteString("id-CA-ECDH-3DES-CBC-CBC", OID); 66 chipAuthenticationInfoDG14.version = 1; 67 68 var chipAuthenticationDomainParameterInfo = new ChipAuthenticationDomainParameterInfo(); 69 chipAuthenticationDomainParameterInfo.protocol = new ByteString("id-CA-ECDH", OID); 70 chipAuthenticationDomainParameterInfo.standardizedDomainParameter = 13; 71 chipAuthenticationDomainParameterInfo.keyId = 16; 72 73 var privChipAuthenticationDomainParameterInfo = new ChipAuthenticationDomainParameterInfo(); 74 privChipAuthenticationDomainParameterInfo.protocol = new ByteString("id-CA-ECDH", OID); 75 privChipAuthenticationDomainParameterInfo.standardizedDomainParameter = 13; 76 privChipAuthenticationDomainParameterInfo.keyId = 17; 77 78 var groupCAPrk = new Key("kp_prk_GroupCAKey.xml"); 79 var groupCAPuk = new Key("kp_puk_GroupCAKey.xml"); 80 groupCAPrk.setComponent(Key.ECC_CURVE_OID, groupCAPrk.getComponent(Key.ECC_CURVE_OID)); 81 82 var chipAuthenticationPublicKeyInfo = new ChipAuthenticationPublicKeyInfo(); 83 chipAuthenticationPublicKeyInfo.protocol = new ByteString("id-PK-ECDH", OID); 84 chipAuthenticationPublicKeyInfo.algorithm = new ByteString("standardizedDomainParameter", OID); 85 chipAuthenticationPublicKeyInfo.standardizedDomainParameter = 13; 86 chipAuthenticationPublicKeyInfo.publicKey = groupCAPuk; 87 chipAuthenticationPublicKeyInfo.keyId = 16; 88 89 var chipAuthenticationPublicKeyInfoDG14 = new ChipAuthenticationPublicKeyInfo(); 90 chipAuthenticationPublicKeyInfoDG14.protocol = new ByteString("id-PK-ECDH", OID); 91 chipAuthenticationPublicKeyInfoDG14.algorithm = new ByteString("id-ecPublicKey", OID); 92 chipAuthenticationPublicKeyInfoDG14.publicKey = groupCAPuk; 93 94 var chipCAPrk = new Key("kp_prk_UniqueCAKey.xml"); 95 var chipCAPuk = new Key("kp_puk_UniqueCAKey.xml"); 96 chipCAPrk.setComponent(Key.ECC_CURVE_OID, chipCAPrk.getComponent(Key.ECC_CURVE_OID)); 97 98 var privChipAuthenticationPublicKeyInfo = new ChipAuthenticationPublicKeyInfo(); 99 privChipAuthenticationPublicKeyInfo.protocol = new ByteString("id-PK-ECDH", OID); 100 privChipAuthenticationPublicKeyInfo.algorithm = new ByteString("standardizedDomainParameter", OID); 101 privChipAuthenticationPublicKeyInfo.standardizedDomainParameter = 13; 102 privChipAuthenticationPublicKeyInfo.publicKey = chipCAPuk; 103 privChipAuthenticationPublicKeyInfo.keyId = 17; 104 105 var terminalAuthenticationInfo = new ASN1("terminalAuthenticationInfo", ASN1.SEQUENCE, 106 new ASN1("protocol", ASN1.OBJECT_IDENTIFIER, new ByteString("id-TA", OID)), 107 new ASN1("version", ASN1.INTEGER, ByteString.valueOf(2)) 108 ); 109 110 var terminalAuthenticationInfoDG14 = new ASN1("terminalAuthenticationInfo", ASN1.SEQUENCE, 111 new ASN1("protocol", ASN1.OBJECT_IDENTIFIER, new ByteString("id-TA", OID)), 112 new ASN1("version", ASN1.INTEGER, ByteString.valueOf(1)) 113 ); 114 115 var restrictedIdentificationDomainParameterInfo = new RestrictedIdentificationDomainParameterInfo(); 116 restrictedIdentificationDomainParameterInfo.protocol = new ByteString("id-RI-ECDH", OID); 117 restrictedIdentificationDomainParameterInfo.standardizedDomainParameter = 13; 118 119 var rIKeys = []; 120 121 var restrictedIdentificationRecovation = new RestrictedIdentificationInfo(); 122 restrictedIdentificationRecovation.protocol = new ByteString("id-RI-ECDH-SHA-256", OID); 123 restrictedIdentificationRecovation.version = 1; 124 restrictedIdentificationRecovation.keyId = 0x8; 125 restrictedIdentificationRecovation.authorizedOnly = false; 126 127 var riKey = new Key("kp_prk_RevocationKey.xml"); 128 rIKeys[restrictedIdentificationRecovation.keyId] = { 129 prk: riKey, 130 authorizedOnly: false 131 }; 132 133 134 var restrictedIdentificationSector = new RestrictedIdentificationInfo(); 135 restrictedIdentificationSector.protocol = new ByteString("id-RI-ECDH-SHA-256", OID); 136 restrictedIdentificationSector.version = 1; 137 restrictedIdentificationSector.keyId = 0x9; 138 restrictedIdentificationSector.authorizedOnly = true; 139 140 var riKey = new Key("kp_prk_IDKey.xml"); 141 rIKeys[restrictedIdentificationSector.keyId] = { 142 prk: riKey, 143 authorizedOnly: true 144 }; 145 146 var ciInfo = new ASN1(ASN1.SEQUENCE, 147 new ASN1(ASN1.OBJECT_IDENTIFIER, new ByteString("id-CI", OID)), 148 new ASN1(ASN1.IA5String, new ByteString("http://www.openscdp.org/eID/eID.xml", ASCII)) 149 ); 150 151 152 var cardAccess = new ASN1(ASN1.SET, 153 terminalAuthenticationInfo, 154 chipAuthenticationInfo.toTLV(), 155 paceInfo.toTLV(), 156 chipAuthenticationDomainParameterInfo.toTLV(), 157 ciInfo, 158 new ASN1(ASN1.SEQUENCE, 159 new ASN1(ASN1.OBJECT_IDENTIFIER, new ByteString("id-PT", OID)), 160 new ASN1(ASN1.SET, 161 privChipAuthenticationInfo.toTLV(), 162 privChipAuthenticationDomainParameterInfo.toTLV() 163 ) 164 ) 165 ); 166 print("CardAccess:"); 167 print(cardAccess); 168 169 var cardSecurity = new ASN1(ASN1.SET, 170 terminalAuthenticationInfo, 171 chipAuthenticationInfo.toTLV(), 172 paceInfo.toTLV(), 173 restrictedIdentificationRecovation.toTLV(), 174 restrictedIdentificationSector.toTLV(), 175 restrictedIdentificationDomainParameterInfo.toTLV(), 176 chipAuthenticationDomainParameterInfo.toTLV(), 177 ciInfo, 178 chipAuthenticationPublicKeyInfo.toTLV() 179 ); 180 print("CardSecurity:"); 181 print(cardSecurity); 182 183 var chipSecurity = new ASN1(ASN1.SET, 184 terminalAuthenticationInfo, 185 privChipAuthenticationInfo.toTLV(), 186 paceInfo.toTLV(), 187 restrictedIdentificationRecovation.toTLV(), 188 restrictedIdentificationSector.toTLV(), 189 restrictedIdentificationDomainParameterInfo.toTLV(), 190 privChipAuthenticationDomainParameterInfo.toTLV(), 191 ciInfo, 192 privChipAuthenticationPublicKeyInfo.toTLV() 193 ); 194 print("ChipSecurity:"); 195 print(chipSecurity); 196 197 var dg14 = new ASN1(0x6E, 198 new ASN1(ASN1.SET, 199 terminalAuthenticationInfoDG14, 200 chipAuthenticationInfoDG14.toTLV(), 201 chipAuthenticationPublicKeyInfoDG14.toTLV() 202 ) 203 ); 204 205 206 var dskey = new Key("kp_prk_DocSigner.xml"); 207 var dscert = new X509("C_DocSigner.cer"); 208 209 var gen = new CMSGenerator(CMSGenerator.TYPE_SIGNED_DATA); 210 gen.setDataContent(cardSecurity.getBytes()); 211 gen.addSigner(dskey, dscert, new ByteString("id-sha256", OID), true); 212 var signedCardSecurity = gen.generate(new ByteString("id-SecurityObject", OID)); 213 //print(new ASN1(signedCardSecurity)); 214 215 var gen = new CMSGenerator(CMSGenerator.TYPE_SIGNED_DATA); 216 gen.setDataContent(chipSecurity.getBytes()); 217 gen.addSigner(dskey, dscert, new ByteString("id-sha256", OID), true); 218 var signedChipSecurity = gen.generate(new ByteString("id-SecurityObject", OID)); 219 //print(new ASN1(signedChipSecurity)); 220 221 222 // Load root certificates 223 var f = new File(GPSystem.mapFilename("cvc/UTISCVCA/UTISCVCA00001.selfsigned.cvcert", GPSystem.CWD)); 224 var c = new CVC(f.readAllAsBinary()); 225 print(c); 226 var currentDate = c.getCED(); 227 var cvcis = new TrustAnchor(c); 228 229 var f = new File(GPSystem.mapFilename("cvc/UTATCVCA/UTATCVCA00001.selfsigned.cvcert", GPSystem.CWD)); 230 var c = new CVC(f.readAllAsBinary()); 231 print(c); 232 var cvcat = new TrustAnchor(c); 233 234 var f = new File(GPSystem.mapFilename("cvc/UTSTCVCA/UTSTCVCA00001.selfsigned.cvcert", GPSystem.CWD)); 235 var c = new CVC(f.readAllAsBinary()); 236 print(c); 237 var cvcst = new TrustAnchor(c); 238 239 240 241 242 243 /** 244 * Create a card simulation object 245 * 246 * @class Class implementing a simple ISO 7816-4 card simulation 247 * @constructor 248 */ 249 function eIDSimulation() { 250 this.createFileSystem(); 251 this.initialize(); 252 } 253 254 255 256 /** 257 * Initialize card runtime 258 */ 259 eIDSimulation.prototype.createFileSystem = function() { 260 var eac = new EAC20(new Crypto()); 261 262 this.mf = new DF(FCP.newDF("3F00", null), 263 new TransparentEF(FCP.newTransparentEF("011C", 0x1C, 100), cardAccess.getBytes()), 264 new TransparentEF(FCP.newTransparentEF("011D", 0x1D, 100), signedCardSecurity), 265 new TransparentEF(FCP.newTransparentEF("011B", 0x1B, 100), signedChipSecurity) 266 ); 267 268 this.mf.addMeta("accessController", new MFAccessController()); 269 this.mf.addMeta("groupChipAuthenticationPrivateKey", groupCAPrk); 270 this.mf.addMeta("groupChipAuthenticationPublicKey", groupCAPuk); 271 this.mf.addMeta("groupChipAuthenticationInfo", chipAuthenticationInfo); 272 this.mf.addMeta("uniqueChipAuthenticationPrivateKey", chipCAPrk); 273 this.mf.addMeta("uniqueChipAuthenticationPublicKey", chipCAPuk); 274 this.mf.addMeta("uniqueChipAuthenticationInfo", privChipAuthenticationInfo); 275 276 this.mf.addMeta("paceInfo", paceInfo); 277 this.mf.addMeta("idPICC", new ByteString(EAC20.decodeDocumentNumber(mrz), ASCII)); 278 this.mf.addObject(cvcis); 279 this.mf.addObject(cvcat); 280 this.mf.addObject(cvcst); 281 this.mf.addMeta("currentDate", { currentDate: currentDate} ); 282 283 var pacemrz = new AuthenticationObject("PACE_MRZ", AuthenticationObject.TYPE_PACE, 1, 284 eac.hashMRZ(mrz)); 285 pacemrz.initialretrycounter = 0; 286 this.mf.addObject(pacemrz); 287 288 var pacecan = new AuthenticationObject("PACE_CAN", AuthenticationObject.TYPE_PACE, 2, 289 new ByteString("500540", ASCII)); 290 pacecan.initialretrycounter = 0; 291 pacecan.allowResetRetryCounter = true; 292 pacecan.allowResetValue = true; 293 this.mf.addObject(pacecan); 294 295 var pacepin = new AuthenticationObject("PACE_PIN", AuthenticationObject.TYPE_PACE, 3, 296 new ByteString("55555", ASCII)); 297 pacepin.isTransport = true; 298 pacepin.allowActivate = true; 299 pacepin.allowDeactivate = true; 300 pacepin.allowResetRetryCounter = true; 301 pacepin.allowResetValue = true; 302 pacepin.minLength = 6; 303 pacepin.unsuspendAuthenticationObject = pacecan; 304 this.mf.addObject(pacepin); 305 306 var pacepuk = new AuthenticationObject("PACE_PUK", AuthenticationObject.TYPE_PACE, 4, 307 new ByteString("87654321", ASCII)); 308 pacecan.initialretrycounter = 0; 309 this.mf.addObject(pacepuk); 310 311 pacepin.unblockAuthenticationObject = pacepuk; 312 313 var binCVCA = (new ASN1(0x42, new ByteString("UTISCVCA00001", ASCII))).getBytes(); 314 var binCVCA = binCVCA.concat((new ByteString("000000000000000000000000000000000000000000000000000000000000000000000000", HEX)).bytes(binCVCA.length)); 315 var efCVCA = new TransparentEF(FCP.newTransparentEF("011C", 0x1C, 36), binCVCA); // EF.CVCA 316 317 this.mf.addMeta("efCVCA", efCVCA); 318 319 var com = (new ASN1(0x60, 320 new ASN1(0x5F01, new ByteString("0107", ASCII)), 321 new ASN1(0x5F36, new ByteString("040000", ASCII)), 322 new ASN1(0x5C, new ByteString("6175637664", HEX)) 323 )).getBytes(); 324 var dg1 = (new ASN1(0x61, new ASN1(0x5F1F, new ByteString(mrz, ASCII)))).getBytes(); 325 print(dg1); 326 327 var dFePass = new DF(FCP.newDF(null, new ByteString("A0000002471001", HEX)), 328 new TransparentEF(FCP.newTransparentEF("011E", 0x1E, 100), // EF.COM 329 com), 330 new TransparentEF(FCP.newTransparentEF("011D", 0x1D, 100), // EF.SOD 331 new ByteString("77050123456789", HEX)), 332 new TransparentEF(FCP.newTransparentEF("0101", 0x01, 100), // EF.DG1 333 dg1), 334 new TransparentEF(FCP.newTransparentEF("0102", 0x02, 100), // EF.DG2 335 new ByteString("75037F6101AA", HEX)), 336 new TransparentEF(FCP.newTransparentEF("0103", 0x03, 100), // EF.DG3 337 new ByteString("63037F6101AA", HEX)), 338 new TransparentEF(FCP.newTransparentEF("0104", 0x04, 100), // EF.DG4 339 new ByteString("76037F6101AA", HEX)), 340 new TransparentEF(FCP.newTransparentEF("010E", 0x0E, 100), // EF.DG14 341 dg14.getBytes()), 342 efCVCA 343 ); 344 345 dFePass.addMeta("accessController", new ePassAccessController()); 346 347 dFePass.addMeta("KENC", eac.calculateBACKey(mrz, 1)); 348 dFePass.addMeta("KMAC", eac.calculateBACKey(mrz, 2)); 349 350 dFePass.addMeta("chipAuthenticationPrivateKey", groupCAPrk); 351 dFePass.addMeta("chipAuthenticationPublicKey", groupCAPuk); 352 dFePass.addMeta("chipAuthenticationInfo", chipAuthenticationInfoDG14); 353 354 355 var dFeID = new DF(FCP.newDF(null, new ByteString("E80704007F00070302", HEX)), 356 new TransparentEF(FCP.newTransparentEF("0101", 0x01, 100), // EF.DG1 357 new ByteString("6100", HEX)), 358 new TransparentEF(FCP.newTransparentEF("0102", 0x02, 100), // EF.DG2 359 new ByteString("6200", HEX)), 360 new TransparentEF(FCP.newTransparentEF("0103", 0x03, 100), // EF.DG3 361 new ByteString("6300", HEX)), 362 new TransparentEF(FCP.newTransparentEF("0104", 0x04, 100), // EF.DG4 363 new ByteString("6400", HEX)), 364 new TransparentEF(FCP.newTransparentEF("0105", 0x05, 100), // EF.DG5 365 new ByteString("6500", HEX)), 366 new TransparentEF(FCP.newTransparentEF("0106", 0x06, 100), // EF.DG6 367 new ByteString("6600", HEX)), 368 new TransparentEF(FCP.newTransparentEF("0107", 0x07, 100), // EF.DG7 369 new ByteString("6700", HEX)), 370 new TransparentEF(FCP.newTransparentEF("0108", 0x08, 100), // EF.DG8 371 new ByteString("6800", HEX)), 372 new TransparentEF(FCP.newTransparentEF("0109", 0x09, 100), // EF.DG9 373 new ByteString("6900", HEX)), 374 new TransparentEF(FCP.newTransparentEF("010A", 0x0A, 100), // EF.DG10 375 new ByteString("6A00", HEX)), 376 new TransparentEF(FCP.newTransparentEF("010B", 0x0B, 100), // EF.DG11 377 new ByteString("6B00", HEX)), 378 new TransparentEF(FCP.newTransparentEF("010C", 0x0C, 100), // EF.DG12 379 new ByteString("6C00", HEX)), 380 new TransparentEF(FCP.newTransparentEF("010D", 0x0D, 100), // EF.DG13 381 new ByteString("6D00", HEX)), 382 new TransparentEF(FCP.newTransparentEF("010E", 0x0E, 100), // EF.DG14 383 new ByteString("6E00", HEX)), 384 new TransparentEF(FCP.newTransparentEF("010F", 0x0F, 100), // EF.DG15 385 new ByteString("6F00", HEX)), 386 new TransparentEF(FCP.newTransparentEF("0110", 0x10, 100), // EF.DG16 387 new ByteString("7000", HEX)), 388 new TransparentEF(FCP.newTransparentEF("0111", 0x11, 200), // EF.DG17 389 new ByteString("7100", HEX)), 390 new TransparentEF(FCP.newTransparentEF("0112", 0x12, 100), // EF.DG18 391 new ByteString("7200", HEX)), 392 new TransparentEF(FCP.newTransparentEF("0113", 0x13, 100), // EF.DG19 393 new ByteString("7300", HEX)), 394 new TransparentEF(FCP.newTransparentEF("0114", 0x14, 100), // EF.DG20 395 new ByteString("7400", HEX)), 396 new TransparentEF(FCP.newTransparentEF("0115", 0x15, 100), // EF.DG21 397 new ByteString("7500", HEX)) 398 ); 399 400 dFeID.addMeta("accessController", new eIDAccessController()); 401 dFeID.addMeta("DateOfExpiry", "20161231"); 402 dFeID.addMeta("DateOfBirth", "19661109"); 403 dFeID.addMeta("CommunityID", "1234"); 404 dFeID.addMeta("RIKeys", rIKeys); 405 406 407 var dFeSign = new DF(FCP.newDF(null, new ByteString("A000000167455349474E", HEX)), 408 new TransparentEF(FCP.newTransparentEF("C000", 1, 2048)), // EF.C.ZDA.QES 409 new TransparentEF(FCP.newTransparentEF("C001", 2, 2048)) // EF.C.ICC.QES 410 ); 411 412 dFeSign.addMeta("accessController", new eSignAccessController()); 413 414 var signpin = new AuthenticationObject("PIN.QES", AuthenticationObject.TYPE_PIN, 1); 415 signpin.isTerminated = true; 416 signpin.allowTerminate = true; 417 signpin.allowResetRetryCounter = true; 418 signpin.allowResetValue = true; 419 signpin.allowChangeReferenceData = true; 420 signpin.unblockAuthenticationObject = pacepuk; 421 dFeSign.addObject(signpin); 422 423 var signaturekey = new SignatureKey("PrK.QES", 1); 424 signaturekey.useAuthenticationObject = signpin; 425 signpin.associatedKey = signaturekey; 426 dFeSign.addObject(signaturekey); 427 428 this.mf.add(dFePass); 429 this.mf.add(dFeID); 430 this.mf.add(dFeSign); 431 432 print(this.mf.dump("")); 433 } 434 435 436 437 /** 438 * Initialize card runtime 439 */ 440 eIDSimulation.prototype.initialize = function() { 441 this.fileSelector = new FileSelector(this.mf); 442 this.commandInterpreter = new eIDCommandInterpreter(this.fileSelector); 443 444 } 445 446 447 448 /** 449 * Process an inbound APDU 450 * 451 * @param {ByteString} capdu the command APDU 452 * @type ByteString 453 * @return the response APDU 454 */ 455 eIDSimulation.prototype.processAPDU = function(capdu) { 456 print("Command APDU : " + capdu); 457 458 var apdu; 459 460 try { 461 apdu = new APDU(capdu); 462 } 463 catch(e) { 464 GPSystem.trace(e); 465 var sw = APDU.SW_GENERALERROR; 466 if (e instanceof GPError) { 467 sw = e.reason; 468 } 469 var bb = new ByteBuffer(); 470 bb.append(sw >> 8); 471 bb.append(sw & 0xFF); 472 return bb.toByteString(); 473 } 474 475 this.commandInterpreter.processAPDU(apdu); 476 477 var rapdu = apdu.getResponseAPDU(); 478 print("Response APDU: " + rapdu); 479 return rapdu; 480 } 481 482 483 484 /** 485 * Respond to reset request 486 * 487 * @param {Number} type reset type (One of Card.RESET_COLD or Card.RESET.WARM) 488 * @type ByteString 489 * @return answer to reset 490 */ 491 eIDSimulation.prototype.reset = function(type) { 492 print("Reset type: " + type); 493 494 this.initialize(); 495 496 var atr = new ByteString("3B600000", HEX); 497 return atr; 498 } 499 500 501 502 /** 503 * Create new simulation and register with existing or newly created adapter singleton. 504 * 505 */ 506 eIDSimulation.newInstance = function() { 507 var sim = new eIDSimulation(); 508 509 if (typeof(CARDSIM) == "undefined") { 510 var adapter = new CardSimulationAdapter("JCOPSimulation", "8050"); 511 adapter.setSimulationObject(sim); 512 adapter.start(); 513 CARDSIM = adapter; 514 print("Simulation running..."); 515 } else { 516 CARDSIM.setSimulationObject(sim); 517 print("Simulation replaced..."); 518 } 519 } 520 521 522 523 eIDSimulation.newInstance(); 524