1 /** 2 * --------- 3 * |.##> <##.| Open Smart Card Development Platform (www.openscdp.org) 4 * |# #| 5 * |# #| Copyright (c) 1999-2006 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 Dump the content of a passport with Basic Access Control to file 25 * 26 * Before running this script, please make sure that the variable mrz2 is set 27 * to the second line of the machine readable zone on your passport. 28 */ 29 30 // MRZ of silver data set 31 // 32 // P<UTOERIKSSON<<ANNA<MARIA<<<<<<<<<<<<<<<<<<< 33 // L898902C<3UTO6908061F9406236ZE184226B<<<<<14 34 // '-DocNo--' '-DoB-' '-DoE-' 35 var mrz2 = "L898902C<3UTO6908061F9406236ZE184226B<<<<<14"; 36 37 // MRZ of Tsukuba data set 38 // 39 // WG30004036UTO6007078M0511014<<<<<<<<<<<<<<06 40 // '-DocNo--' '-DoB-' '-DoE-' 41 42 // var mrz2 = "WG30004036UTO6007078M0511014<<<<<<<<<<<<<<06"; 43 44 45 // Import some tools 46 load("tools.js"); 47 48 49 /* 50 * Read file from passport and save to disk 51 * 52 */ 53 function handleFile(secureChannel, lds, name, fid) { 54 print("Reading " + name + " (" + fid + ")..."); 55 56 // Select file 57 var ef = new CardFile(lds, ":" + fid); 58 59 if (secureChannel) { 60 // Set secure channel as credential for read access 61 ef.setCredential(CardFile.READ, Card.ALL, secureChannel); 62 } 63 64 // Read first 4 bytes of file 65 var res = ef.readBinary(0, 4); 66 67 // Determine file length from TLV header 68 var len = lengthFromHeader(res); 69 70 // Read complete file 71 var res = ef.readBinary(0, len); 72 print("Content"); 73 print(res); 74 75 writeFileOnDisk(name + ".bin", res); 76 77 return res; 78 } 79 80 81 82 /* 83 * Save picture from DG2 84 * 85 */ 86 function savePicture(dg2) { 87 // Save picture to .jpeg file 88 var tlv = new ASN1(dg2); 89 var bin = tlv.get(0).get(1).get(1).value; 90 91 // Try finding a JPEG 2000 picture 92 var offset = bin.find(new ByteString("0000000C6A5020200D0A870A", HEX)); 93 94 if (offset >= 0) { 95 writeFileOnDisk("face.jp2", bin.bytes(offset)); 96 } else { 97 var offset = bin.find(new ByteString("FFD8", HEX)); 98 99 if (offset >= 0) { 100 writeFileOnDisk("face.jpg", bin.bytes(offset)); 101 } 102 } 103 } 104 105 106 // Create card and crypto object 107 var card = new Card(_scsh3.reader); 108 card.reset(Card.RESET_COLD); 109 110 var crypto = new Crypto(); 111 112 // Select LDS application 113 var lds = new CardFile(card, "#A0000002471001"); 114 115 var secureChannel = null; 116 117 // Try reading EF_COM to figure out if BAC is needed 118 card.sendApdu(0x00, 0xB0, 0x9E, 0x00, 0x01); 119 120 if (card.SW != 0x9000) { 121 122 // Calculate kenc and kmac for mutual authentication from the MRZ data 123 print("Trying BAC with MRZ2=" + mrz2); 124 125 var kenc = calculateBACKey(crypto, mrz2, 1); 126 var kmac = calculateBACKey(crypto, mrz2, 2); 127 128 // Dummy to load crypto libraries (Saves some time later) 129 crypto.encrypt(kenc, Crypto.DES_CBC, new ByteString("0000000000000000", HEX), new ByteString("0000000000000000", HEX)); 130 131 secureChannel = openSecureChannel(card, crypto, kenc, kmac); 132 133 /* Only works with script based secure messaging. See tools.js for details 134 secureChannel.enableTrace(); 135 */ 136 137 // Enable SELECT commands to be send in secure messaging 138 // lds.setCredential(CardFile.SELECT, CardFile.ALL, secureChannel); 139 140 /* 141 card.setCredential(secureChannel); 142 var resp = card.sendSecMsgApdu(Card.ALL, 0x00, 0xA4, 0x02, 0x0C, new ByteString("011E", HEX)); 143 print(resp); 144 */ 145 } 146 147 handleFile(secureChannel, lds, "EF_COM", "1E"); 148 handleFile(secureChannel, lds, "EF_DG1", "01"); 149 var dg2 = handleFile(secureChannel, lds, "EF_DG2", "02"); 150 savePicture(dg2); 151 handleFile(secureChannel, lds, "EF_SOD", "1D"); 152 153 154 155