1 /**
  2  *  ---------
  3  * |.##> <##.|  SmartCard-HSM Support Scripts
  4  * |#       #|  
  5  * |#       #|  Copyright (c) 2011-2012 CardContact Software & System Consulting
  6  * |'##> <##'|  Andreas Schwier, 32429 Minden, Germany (www.cardcontact.de)
  7  *  --------- 
  8  *
  9  * Consult your license package for usage terms and conditions.
 10  * 
 11  * @fileoverview Class implementing a key store for X.509 certificate and private keys stored on a SmartCard-HSM
 12  */
 13 
 14 
 15 /**
 16  * Create a simple key store front-end
 17  *
 18  * @class Class implementing some simple access functions to generate key pairs and store certificates
 19  * @param {SmartCardHSM} sc the SmartCard-HSM card service
 20  */ 
 21 function HSMKeyStore(sc) {
 22 	this.sc = sc;
 23 }
 24 
 25 
 26 
 27 /**
 28  * Generate a RSA key pair
 29  *
 30  * @param {String} label the label under which the key pair shall be stored
 31  * @param {Number} keysize the key size in bits (1024, 1536 or 2048)
 32  */
 33 HSMKeyStore.prototype.generateRSAKeyPair = function(label, keysize) {
 34 	this.sc.enumerateObjects();
 35 
 36 	var key = this.sc.getKey(label);
 37 	if (key) {
 38 		var newkid = key.getId();
 39 	} else {
 40 		var newkid = this.sc.determineFreeKeyId();
 41 	}
 42 
 43 	var chr = new PublicKeyReference("UTNULL00000");
 44 	var car = new PublicKeyReference("UTNULL00000");
 45 	var algo = new ByteString("id-TA-RSA-v1-5-SHA-256", OID);
 46 
 47 	var keydata = SmartCardHSM.buildGAKPwithRSA(car, algo, chr, keysize);
 48 	var keydesc = SmartCardHSM.buildPrkDforRSA(newkid, label, keysize);
 49 
 50 	var reqbin = this.sc.generateAsymmetricKeyPair(newkid, 0, keydata);
 51 
 52 	var fid = ByteString.valueOf((SmartCardHSM.PRKDPREFIX << 8) + newkid);
 53 	this.sc.updateBinary(fid, 0, keydesc.getBytes());
 54 	var req = new CVC(reqbin);
 55 	
 56 	var hkey = new SmartCardHSMKey(this.sc, newkid);
 57 	hkey.setDescription(keydesc);
 58 	this.sc.addKeyToMap(hkey);
 59 	return req;
 60 }
 61 
 62 
 63 
 64 /**
 65  * Generate an ECDSA key pair
 66  *
 67  * @param {String} label the label under which the key pair shall be stored
 68  * @param {String} curve the curve object identifier
 69  */
 70 HSMKeyStore.prototype.generateECCKeyPair = function(label, curve) {
 71 	this.sc.enumerateObjects();
 72 
 73 	var key = this.sc.getKey(label);
 74 	if (key) {
 75 		var newkid = key.getId();
 76 	} else {
 77 		var newkid = this.sc.determineFreeKeyId();
 78 	}
 79 
 80 	var chr = new PublicKeyReference("UTNULL00000");
 81 	var car = new PublicKeyReference("UTNULL00000");
 82 	var algo = new ByteString("id-TA-ECDSA-SHA-256", OID);
 83 
 84 	var dp = new Key();
 85 	dp.setComponent(Key.ECC_CURVE_OID, new ByteString(curve, OID));
 86 
 87 	var keydata = SmartCardHSM.buildGAKPwithECC(car, algo, chr, dp);
 88 	print("Keysize: " + dp.getSize());
 89 	var keydesc = SmartCardHSM.buildPrkDforECC(newkid, label, dp.getSize());
 90 
 91 	var reqbin = this.sc.generateAsymmetricKeyPair(newkid, 0, keydata);
 92 
 93 	var fid = ByteString.valueOf((SmartCardHSM.PRKDPREFIX << 8) + newkid);
 94 	this.sc.updateBinary(fid, 0, keydesc.getBytes());
 95 	var req = new CVC(reqbin);
 96 	
 97 	var hkey = new SmartCardHSMKey(this.sc, newkid);
 98 	hkey.setDescription(keydesc);
 99 	this.sc.addKeyToMap(hkey);
100 	return req;
101 }
102 
103 
104 
105 /**
106  * Store certificate under given label
107  *
108  * @param {String} label the label under which the certificate shall be stored
109  * @param {X509} cert the certificate
110  */
111 HSMKeyStore.prototype.storeEndEntityCertificate = function(label, cert) {
112 	var key = this.sc.getKey(label);
113 	if (key) {
114 		var kid = key.getId();
115 	} else {
116 		throw new GPError("HSMKeyStore", GPError.INVALID_DATA, 0, "Could not find a key with label " + label);
117 	}
118 	
119 	var fid = ByteString.valueOf((SmartCardHSM.EECERTIFICATEPREFIX << 8) + kid);
120 	this.sc.updateBinary(fid, 0, cert.getBytes());
121 }
122 
123 
124 
125 /**
126  * Delete key and certificate with given label
127  *
128  * @param {String} label the label of the key to be removed
129  */
130 HSMKeyStore.prototype.deleteKey = function(label) {
131 	var key = this.sc.getKey(label);
132 	if (key) {
133 		var kid = key.getId();
134 	} else {
135 		throw new GPError("HSMKeyStore", GPError.INVALID_DATA, 0, "Could not find a key with label " + label);
136 	}
137 	
138 	try	{
139 		var fid = ByteString.valueOf((SmartCardHSM.EECERTIFICATEPREFIX << 8) + kid);
140 		this.sc.deleteFile(fid);
141 
142 		var fid = ByteString.valueOf((SmartCardHSM.PRKDPREFIX << 8) + kid);
143 		this.sc.deleteFile(fid);
144 
145 		var fid = ByteString.valueOf((SmartCardHSM.KEYPREFIX << 8) + kid);
146 		this.sc.deleteFile(fid);
147 	}
148 	catch(e) {
149 		// Ignore
150 	}
151 }
152 
153 
154 
155 /**
156  * Return list of keys
157  *
158  * @type String[]
159  * @return the list of key names
160  */
161 HSMKeyStore.prototype.enumerateKeys = function() {
162 	return this.sc.enumerateKeys();
163 }
164 
165 
166 
167 /**
168  * Get key for given label
169  *
170  * @param {String} label the certificate label
171  * @type Key
172  * @return the key
173  */
174 HSMKeyStore.prototype.getKey = function(label) {
175 	this.sc.enumerateKeys();
176 	var key = this.sc.getKey(label);
177 	if (!key) {
178 		throw new GPError("HSMKeyStore", GPError.INVALID_DATA, 0, "Could not find a key with label " + label);
179 	}
180 	return key;
181 }
182 
183 
184 
185 /**
186  * Get certificate for given label
187  *
188  * @param {String} label the certificate label
189  * @type X509
190  * @return the certificate
191  */
192 HSMKeyStore.prototype.getEndEntityCertificate = function(label) {
193 	var key = this.getKey(label);
194 	var kid = key.getId();
195 	var fid = ByteString.valueOf((SmartCardHSM.EECERTIFICATEPREFIX << 8) + kid);
196 	var certbin = this.sc.readBinary(fid);
197 	return new X509(certbin);
198 }
199