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