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