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  *  MuscleCard libary functions
 25  */
 26 
 27 
 28 var mcaid = new ByteString("A00000000101", HEX);
 29 
 30 var mckeytypes = ["UNKNOWN",
 31 		  "RSA_PUBLIC",
 32 		  "RSA_PRIVATE",
 33 		  "RSA_PRIVATE_CRT",
 34 		  "DSA_PUBLIC",
 35 		  "DSA_PRIVATE",
 36 		  "DES",
 37 		  "TRIPLE_DES",
 38 		  "TRIPLE_DES_3KEY"];
 39 
 40 function printStatus(resp) {
 41 	print("Response to MSCGetStatus command APDU: " + resp);
 42 	print("Card Edge Major Version        : " + resp.byteAt(0));
 43 	print("Card Edge Minor Version        : " + resp.byteAt(1));
 44 	print("Software Major Version         : " + resp.byteAt(2));
 45 	print("Software Minor Version         : " + resp.byteAt(3));
 46 	print("Total Object memory            : " + resp.bytes(4, 4).toUnsigned());
 47 	print("Free Object Memory             : " + resp.bytes(8, 4).toUnsigned());
 48 	print("Number of used PINs            : " + resp.byteAt(12));
 49 	print("Number of used Keys            : " + resp.byteAt(13));
 50 	print("Currently Logged in Identities : " + accessMaskToString(resp.bytes(14, 2).toUnsigned(), "none", "all", ","));
 51 }
 52 
 53 
 54 
 55 //
 56 // Return string for bitmap position
 57 //
 58 function accessPermissionToString(ap) {
 59 	if (ap < 8) {
 60 		return "PIN" + ap;
 61 	} else if (ap < 14) {
 62 		return "KEY" + (ap - 8);
 63 	}
 64 	return "RES" + (ap - 14);
 65 }
 66 
 67 
 68 
 69 //
 70 // Convert bitmask to string
 71 //
 72 function accessMaskToString(am, allzero, allone, delim) {
 73 	if (am == 0)
 74 		return allzero;
 75 	if (am == 0xFFFF)
 76 		return allone;
 77 	
 78 	var first = true;
 79 	var str;
 80 	
 81 	for (var i = 0; i < 16; i++) {
 82 		if (am & 1) {
 83 			if (first) {
 84 				str = accessPermissionToString(i);
 85 				first = false;
 86 			} else {
 87 				str += delim + accessPermissionToString(i);
 88 			}
 89 		}
 90 		am >>= 1;
 91 	}
 92 	return str;
 93 }
 94 
 95 
 96 
 97 //
 98 // Return human readable interpretation of access condition
 99 //
100 function accessConditionToString(ac) {
101 	return accessMaskToString(ac, "Always", "Never", " and ");
102 }
103 
104 
105 
106 //
107 // Helper function to append a four byte integer in MSB/LSB format to a byte buffer
108 //
109 function longToBytes(b, v) {
110 	b.append((v >> 24) & 0xFF);
111 	b.append((v >> 16) & 0xFF);
112 	b.append((v >>  8) & 0xFF);
113 	b.append((v >>  0) & 0xFF);
114 }
115 
116 
117 
118 //
119 // Read data from MuscleCard object
120 //
121 function readObject(card, objid, offset, length) {
122 
123 	var respbb = new ByteBuffer();
124 	
125 	while (length > 0) {
126 		var nlen = length > 255 ? 255 : length;
127 		
128 		var bb = new ByteBuffer();
129 		longToBytes(bb, objid);
130 		longToBytes(bb, offset);
131 		bb.append(nlen);
132 		
133 		var resp = card.sendApdu(0xB0, 0x56, 0x00, 0x00, bb.toByteString(), [0x9000]);
134 		respbb.append(resp);
135 		length -= nlen;
136 		offset += nlen;
137 	}
138 	return respbb.toByteString();
139 }
140 
141 
142 
143 //
144 // Read key blob for a previously exported key
145 //
146 // Return an object with contains the key components as
147 // 0-based array entries and the property "header" set to
148 // the value of the key header
149 //
150 function readKeyBlob(card) {
151 	
152 	var result = new Object();
153 	
154 	// Read header
155 	result.header = readObject(card, 0xFFFFFFFF, 0, 4);
156 
157 	var complist = [2,	// RSA_PUBLIC
158 			2,	// RSA_PRIVATE
159 			5,	// RSA_PRIVATE_CRT
160 			4,	// DSA_PUBLIC
161 			4,	// DSA_PRIVATE
162 			1,	// DES
163 			1,	// TRIPLE_DES
164 			1];	// TRIPLE_DES_3KEY
165 
166 	var ofs = 4;
167 	var comps = complist[result.header.byteAt(1) - 1];
168 	for (var i = 0; i < comps; i++) {
169 		var lenb = readObject(card, 0xFFFFFFFF, ofs, 2);
170 		var len = lenb.toUnsigned();
171 		ofs += 2;
172 		result[i] = readObject(card, 0xFFFFFFFF, ofs, len);
173 		ofs += len;
174 	}
175 	return result;
176 }
177