| OLD | NEW |
| (Empty) |
| 1 | |
| 2 /* This Source Code Form is subject to the terms of the Mozilla Public | |
| 3 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| 5 /* | |
| 6 * This file PKCS #12 fuctions that should really be moved to the | |
| 7 * PKCS #12 directory, however we can't do that in a point release | |
| 8 * because that will break binary compatibility, so we keep them here for now. | |
| 9 */ | |
| 10 | |
| 11 #include "seccomon.h" | |
| 12 #include "secmod.h" | |
| 13 #include "secmodi.h" | |
| 14 #include "pkcs11.h" | |
| 15 #include "pk11func.h" | |
| 16 #include "secitem.h" | |
| 17 #include "key.h" | |
| 18 #include "secoid.h" | |
| 19 #include "secasn1.h" | |
| 20 #include "secerr.h" | |
| 21 | |
| 22 | |
| 23 | |
| 24 /* These data structures should move to a common .h file shared between the | |
| 25 * wrappers and the pkcs 12 code. */ | |
| 26 | |
| 27 /* | |
| 28 ** RSA Raw Private Key structures | |
| 29 */ | |
| 30 | |
| 31 /* member names from PKCS#1, section 7.2 */ | |
| 32 struct SECKEYRSAPrivateKeyStr { | |
| 33 PRArenaPool * arena; | |
| 34 SECItem version; | |
| 35 SECItem modulus; | |
| 36 SECItem publicExponent; | |
| 37 SECItem privateExponent; | |
| 38 SECItem prime1; | |
| 39 SECItem prime2; | |
| 40 SECItem exponent1; | |
| 41 SECItem exponent2; | |
| 42 SECItem coefficient; | |
| 43 }; | |
| 44 typedef struct SECKEYRSAPrivateKeyStr SECKEYRSAPrivateKey; | |
| 45 | |
| 46 | |
| 47 /* | |
| 48 ** DSA Raw Private Key structures | |
| 49 */ | |
| 50 | |
| 51 struct SECKEYDSAPrivateKeyStr { | |
| 52 SECKEYPQGParams params; | |
| 53 SECItem privateValue; | |
| 54 }; | |
| 55 typedef struct SECKEYDSAPrivateKeyStr SECKEYDSAPrivateKey; | |
| 56 | |
| 57 /* | |
| 58 ** Diffie-Hellman Raw Private Key structures | |
| 59 ** Structure member names suggested by PKCS#3. | |
| 60 */ | |
| 61 struct SECKEYDHPrivateKeyStr { | |
| 62 PRArenaPool * arena; | |
| 63 SECItem prime; | |
| 64 SECItem base; | |
| 65 SECItem privateValue; | |
| 66 }; | |
| 67 typedef struct SECKEYDHPrivateKeyStr SECKEYDHPrivateKey; | |
| 68 | |
| 69 /* | |
| 70 ** raw private key object | |
| 71 */ | |
| 72 struct SECKEYRawPrivateKeyStr { | |
| 73 PLArenaPool *arena; | |
| 74 KeyType keyType; | |
| 75 union { | |
| 76 SECKEYRSAPrivateKey rsa; | |
| 77 SECKEYDSAPrivateKey dsa; | |
| 78 SECKEYDHPrivateKey dh; | |
| 79 } u; | |
| 80 }; | |
| 81 typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey; | |
| 82 | |
| 83 SEC_ASN1_MKSUB(SEC_AnyTemplate) | |
| 84 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) | |
| 85 | |
| 86 /* ASN1 Templates for new decoder/encoder */ | |
| 87 /* | |
| 88 * Attribute value for PKCS8 entries (static?) | |
| 89 */ | |
| 90 const SEC_ASN1Template SECKEY_AttributeTemplate[] = { | |
| 91 { SEC_ASN1_SEQUENCE, | |
| 92 0, NULL, sizeof(SECKEYAttribute) }, | |
| 93 { SEC_ASN1_OBJECT_ID, offsetof(SECKEYAttribute, attrType) }, | |
| 94 { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(SECKEYAttribute, attrValue), | |
| 95 SEC_ASN1_SUB(SEC_AnyTemplate) }, | |
| 96 { 0 } | |
| 97 }; | |
| 98 | |
| 99 const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = { | |
| 100 { SEC_ASN1_SET_OF, 0, SECKEY_AttributeTemplate }, | |
| 101 }; | |
| 102 | |
| 103 const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = { | |
| 104 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKeyInfo) }, | |
| 105 { SEC_ASN1_INTEGER, offsetof(SECKEYPrivateKeyInfo,version) }, | |
| 106 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, | |
| 107 offsetof(SECKEYPrivateKeyInfo,algorithm), | |
| 108 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, | |
| 109 { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPrivateKeyInfo,privateKey) }, | |
| 110 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, | |
| 111 offsetof(SECKEYPrivateKeyInfo,attributes), | |
| 112 SECKEY_SetOfAttributeTemplate }, | |
| 113 { 0 } | |
| 114 }; | |
| 115 | |
| 116 const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[] = { | |
| 117 { SEC_ASN1_POINTER, 0, SECKEY_PrivateKeyInfoTemplate } | |
| 118 }; | |
| 119 | |
| 120 const SEC_ASN1Template SECKEY_RSAPrivateKeyExportTemplate[] = { | |
| 121 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) }, | |
| 122 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.version) }, | |
| 123 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.modulus) }, | |
| 124 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.publicExponent) }, | |
| 125 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.privateExponent) }, | |
| 126 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.prime1) }, | |
| 127 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.prime2) }, | |
| 128 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.exponent1) }, | |
| 129 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.exponent2) }, | |
| 130 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.coefficient) }, | |
| 131 { 0 } | |
| 132 }; | |
| 133 | |
| 134 const SEC_ASN1Template SECKEY_DSAPrivateKeyExportTemplate[] = { | |
| 135 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dsa.privateValue) }, | |
| 136 }; | |
| 137 | |
| 138 const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = { | |
| 139 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.privateValue) }, | |
| 140 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.base) }, | |
| 141 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.prime) }, | |
| 142 }; | |
| 143 | |
| 144 const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = { | |
| 145 { SEC_ASN1_SEQUENCE, | |
| 146 0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) }, | |
| 147 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, | |
| 148 offsetof(SECKEYEncryptedPrivateKeyInfo,algorithm), | |
| 149 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, | |
| 150 { SEC_ASN1_OCTET_STRING, | |
| 151 offsetof(SECKEYEncryptedPrivateKeyInfo,encryptedData) }, | |
| 152 { 0 } | |
| 153 }; | |
| 154 | |
| 155 const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[] = { | |
| 156 { SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate } | |
| 157 }; | |
| 158 | |
| 159 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_EncryptedPrivateKeyInfoTemplate) | |
| 160 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate) | |
| 161 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PrivateKeyInfoTemplate) | |
| 162 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToPrivateKeyInfoTemplate) | |
| 163 | |
| 164 /* | |
| 165 * See bugzilla bug 125359 | |
| 166 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints, | |
| 167 * all of the templates above that en/decode into integers must be converted | |
| 168 * from ASN.1's signed integer type. This is done by marking either the | |
| 169 * source or destination (encoding or decoding, respectively) type as | |
| 170 * siUnsignedInteger. | |
| 171 */ | |
| 172 | |
| 173 static void | |
| 174 prepare_rsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) | |
| 175 { | |
| 176 key->u.rsa.modulus.type = siUnsignedInteger; | |
| 177 key->u.rsa.publicExponent.type = siUnsignedInteger; | |
| 178 key->u.rsa.privateExponent.type = siUnsignedInteger; | |
| 179 key->u.rsa.prime1.type = siUnsignedInteger; | |
| 180 key->u.rsa.prime2.type = siUnsignedInteger; | |
| 181 key->u.rsa.exponent1.type = siUnsignedInteger; | |
| 182 key->u.rsa.exponent2.type = siUnsignedInteger; | |
| 183 key->u.rsa.coefficient.type = siUnsignedInteger; | |
| 184 } | |
| 185 | |
| 186 static void | |
| 187 prepare_dsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) | |
| 188 { | |
| 189 key->u.dsa.privateValue.type = siUnsignedInteger; | |
| 190 key->u.dsa.params.prime.type = siUnsignedInteger; | |
| 191 key->u.dsa.params.subPrime.type = siUnsignedInteger; | |
| 192 key->u.dsa.params.base.type = siUnsignedInteger; | |
| 193 } | |
| 194 | |
| 195 static void | |
| 196 prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) | |
| 197 { | |
| 198 key->u.dh.privateValue.type = siUnsignedInteger; | |
| 199 key->u.dh.prime.type = siUnsignedInteger; | |
| 200 key->u.dh.base.type = siUnsignedInteger; | |
| 201 } | |
| 202 | |
| 203 | |
| 204 SECStatus | |
| 205 PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, SECItem *derPKI, | |
| 206 SECItem *nickname, SECItem *publicValue, PRBool isPerm, | |
| 207 PRBool isPrivate, unsigned int keyUsage, void *wincx) | |
| 208 { | |
| 209 return PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, derPKI, | |
| 210 nickname, publicValue, isPerm, isPrivate, keyUsage, NULL, wincx); | |
| 211 } | |
| 212 | |
| 213 SECStatus | |
| 214 PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI, | |
| 215 SECItem *nickname, SECItem *publicValue, PRBool isPerm, | |
| 216 PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey** privk, | |
| 217 void *wincx) | |
| 218 { | |
| 219 SECKEYPrivateKeyInfo *pki = NULL; | |
| 220 PRArenaPool *temparena = NULL; | |
| 221 SECStatus rv = SECFailure; | |
| 222 | |
| 223 temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | |
| 224 if (!temparena) | |
| 225 return rv; | |
| 226 pki = PORT_ArenaZNew(temparena, SECKEYPrivateKeyInfo); | |
| 227 if (!pki) { | |
| 228 PORT_FreeArena(temparena, PR_FALSE); | |
| 229 return rv; | |
| 230 } | |
| 231 pki->arena = temparena; | |
| 232 | |
| 233 rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate, | |
| 234 derPKI); | |
| 235 if( rv != SECSuccess ) { | |
| 236 goto finish; | |
| 237 } | |
| 238 | |
| 239 rv = PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname, | |
| 240 publicValue, isPerm, isPrivate, keyUsage, privk, wincx); | |
| 241 | |
| 242 finish: | |
| 243 /* this zeroes the key and frees the arena */ | |
| 244 SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/); | |
| 245 return rv; | |
| 246 } | |
| 247 | |
| 248 SECStatus | |
| 249 PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk, | |
| 250 SECItem *nickname, SECItem *publicValue, PRBool isPerm, | |
| 251 PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey **privk, | |
| 252 void *wincx) | |
| 253 { | |
| 254 CK_BBOOL cktrue = CK_TRUE; | |
| 255 CK_BBOOL ckfalse = CK_FALSE; | |
| 256 CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; | |
| 257 CK_KEY_TYPE keyType = CKK_RSA; | |
| 258 CK_OBJECT_HANDLE objectID; | |
| 259 CK_ATTRIBUTE theTemplate[20]; | |
| 260 int templateCount = 0; | |
| 261 SECStatus rv = SECFailure; | |
| 262 CK_ATTRIBUTE *attrs; | |
| 263 CK_ATTRIBUTE *signedattr = NULL; | |
| 264 int signedcount = 0; | |
| 265 CK_ATTRIBUTE *ap; | |
| 266 SECItem *ck_id = NULL; | |
| 267 | |
| 268 attrs = theTemplate; | |
| 269 | |
| 270 | |
| 271 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++; | |
| 272 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++; | |
| 273 PK11_SETATTRS(attrs, CKA_TOKEN, isPerm ? &cktrue : &ckfalse, | |
| 274 sizeof(CK_BBOOL) ); attrs++; | |
| 275 PK11_SETATTRS(attrs, CKA_SENSITIVE, isPrivate ? &cktrue : &ckfalse, | |
| 276 sizeof(CK_BBOOL) ); attrs++; | |
| 277 PK11_SETATTRS(attrs, CKA_PRIVATE, isPrivate ? &cktrue : &ckfalse, | |
| 278 sizeof(CK_BBOOL) ); attrs++; | |
| 279 | |
| 280 switch (lpk->keyType) { | |
| 281 case rsaKey: | |
| 282 keyType = CKK_RSA; | |
| 283 PK11_SETATTRS(attrs, CKA_UNWRAP, (keyUsage & KU_KEY_ENCIPHERMENT) ? | |
| 284 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++; | |
| 285 PK11_SETATTRS(attrs, CKA_DECRYPT, (keyUsage & KU_DATA_ENCIPHERMENT)
? | |
| 286 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++; | |
| 287 PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? | |
| 288 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++; | |
| 289 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, | |
| 290 (keyUsage & KU_DIGITAL_SIGNATURE) ? | |
| 291 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++; | |
| 292 ck_id = PK11_MakeIDFromPubKey(&lpk->u.rsa.modulus); | |
| 293 if (ck_id == NULL) { | |
| 294 goto loser; | |
| 295 } | |
| 296 PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++; | |
| 297 if (nickname) { | |
| 298 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
attrs++; | |
| 299 } | |
| 300 signedattr = attrs; | |
| 301 PK11_SETATTRS(attrs, CKA_MODULUS, lpk->u.rsa.modulus.data, | |
| 302 lpk->u.rsa.modulus.len); attrs++
; | |
| 303 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, | |
| 304 lpk->u.rsa.publicExponent.data, | |
| 305 lpk->u.rsa.publicExponent.len); attrs++; | |
| 306 PK11_SETATTRS(attrs, CKA_PRIVATE_EXPONENT, | |
| 307 lpk->u.rsa.privateExponent.data, | |
| 308 lpk->u.rsa.privateExponent.len); attrs++; | |
| 309 PK11_SETATTRS(attrs, CKA_PRIME_1, | |
| 310 lpk->u.rsa.prime1.data, | |
| 311 lpk->u.rsa.prime1.len); attrs++; | |
| 312 PK11_SETATTRS(attrs, CKA_PRIME_2, | |
| 313 lpk->u.rsa.prime2.data, | |
| 314 lpk->u.rsa.prime2.len); attrs++; | |
| 315 PK11_SETATTRS(attrs, CKA_EXPONENT_1, | |
| 316 lpk->u.rsa.exponent1.data, | |
| 317 lpk->u.rsa.exponent1.len); attrs++; | |
| 318 PK11_SETATTRS(attrs, CKA_EXPONENT_2, | |
| 319 lpk->u.rsa.exponent2.data, | |
| 320 lpk->u.rsa.exponent2.len); attrs++; | |
| 321 PK11_SETATTRS(attrs, CKA_COEFFICIENT, | |
| 322 lpk->u.rsa.coefficient.data, | |
| 323 lpk->u.rsa.coefficient.len); attrs++; | |
| 324 break; | |
| 325 case dsaKey: | |
| 326 keyType = CKK_DSA; | |
| 327 /* To make our intenal PKCS #11 module work correctly with | |
| 328 * our database, we need to pass in the public key value for | |
| 329 * this dsa key. We have a netscape only CKA_ value to do this. | |
| 330 * Only send it to internal slots */ | |
| 331 if( publicValue == NULL ) { | |
| 332 goto loser; | |
| 333 } | |
| 334 if (PK11_IsInternal(slot)) { | |
| 335 PK11_SETATTRS(attrs, CKA_NETSCAPE_DB, | |
| 336 publicValue->data, publicValue->len); attrs++; | |
| 337 } | |
| 338 PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(CK_BBOOL)); attrs++; | |
| 339 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, &cktrue, sizeof(CK_BBOOL)); a
ttrs++; | |
| 340 if(nickname) { | |
| 341 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); | |
| 342 attrs++; | |
| 343 } | |
| 344 ck_id = PK11_MakeIDFromPubKey(publicValue); | |
| 345 if (ck_id == NULL) { | |
| 346 goto loser; | |
| 347 } | |
| 348 PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++; | |
| 349 signedattr = attrs; | |
| 350 PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dsa.params.prime.data, | |
| 351 lpk->u.dsa.params.prime.len); attrs++; | |
| 352 PK11_SETATTRS(attrs,CKA_SUBPRIME,lpk->u.dsa.params.subPrime.data, | |
| 353 lpk->u.dsa.params.subPrime.len); attrs++; | |
| 354 PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dsa.params.base.data, | |
| 355 lpk->u.dsa.params.base.len); attrs++; | |
| 356 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dsa.privateValue.data, | |
| 357 lpk->u.dsa.privateValue.len); attrs++; | |
| 358 break; | |
| 359 case dhKey: | |
| 360 keyType = CKK_DH; | |
| 361 /* To make our intenal PKCS #11 module work correctly with | |
| 362 * our database, we need to pass in the public key value for | |
| 363 * this dh key. We have a netscape only CKA_ value to do this. | |
| 364 * Only send it to internal slots */ | |
| 365 if (PK11_IsInternal(slot)) { | |
| 366 PK11_SETATTRS(attrs, CKA_NETSCAPE_DB, | |
| 367 publicValue->data, publicValue->len); attrs++; | |
| 368 } | |
| 369 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); attrs++
; | |
| 370 if(nickname) { | |
| 371 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); | |
| 372 attrs++; | |
| 373 } | |
| 374 ck_id = PK11_MakeIDFromPubKey(publicValue); | |
| 375 if (ck_id == NULL) { | |
| 376 goto loser; | |
| 377 } | |
| 378 PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++; | |
| 379 signedattr = attrs; | |
| 380 PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dh.prime.data, | |
| 381 lpk->u.dh.prime.len); attrs++; | |
| 382 PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dh.base.data, | |
| 383 lpk->u.dh.base.len); attrs++; | |
| 384 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dh.privateValue.data, | |
| 385 lpk->u.dh.privateValue.len); attrs++; | |
| 386 break; | |
| 387 /* what about fortezza??? */ | |
| 388 default: | |
| 389 PORT_SetError(SEC_ERROR_BAD_KEY); | |
| 390 goto loser; | |
| 391 } | |
| 392 templateCount = attrs - theTemplate; | |
| 393 PORT_Assert(templateCount <= sizeof(theTemplate)/sizeof(CK_ATTRIBUTE)); | |
| 394 PORT_Assert(signedattr != NULL); | |
| 395 signedcount = attrs - signedattr; | |
| 396 | |
| 397 for (ap=signedattr; signedcount; ap++, signedcount--) { | |
| 398 pk11_SignedToUnsigned(ap); | |
| 399 } | |
| 400 | |
| 401 rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, | |
| 402 theTemplate, templateCount, isPerm, &objectID); | |
| 403 | |
| 404 /* create and return a SECKEYPrivateKey */ | |
| 405 if( rv == SECSuccess && privk != NULL) { | |
| 406 *privk = PK11_MakePrivKey(slot, lpk->keyType, !isPerm, objectID, wincx); | |
| 407 if( *privk == NULL ) { | |
| 408 rv = SECFailure; | |
| 409 } | |
| 410 } | |
| 411 loser: | |
| 412 if (ck_id) { | |
| 413 SECITEM_ZfreeItem(ck_id, PR_TRUE); | |
| 414 } | |
| 415 return rv; | |
| 416 } | |
| 417 | |
| 418 SECStatus | |
| 419 PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, | |
| 420 SECKEYPrivateKeyInfo *pki, SECItem *nickname, SECItem *publicValue, | |
| 421 PRBool isPerm, PRBool isPrivate, unsigned int keyUsage, | |
| 422 SECKEYPrivateKey **privk, void *wincx) | |
| 423 { | |
| 424 CK_KEY_TYPE keyType = CKK_RSA; | |
| 425 SECStatus rv = SECFailure; | |
| 426 SECKEYRawPrivateKey *lpk = NULL; | |
| 427 const SEC_ASN1Template *keyTemplate, *paramTemplate; | |
| 428 void *paramDest = NULL; | |
| 429 PRArenaPool *arena = NULL; | |
| 430 | |
| 431 arena = PORT_NewArena(2048); | |
| 432 if(!arena) { | |
| 433 return SECFailure; | |
| 434 } | |
| 435 | |
| 436 /* need to change this to use RSA/DSA keys */ | |
| 437 lpk = (SECKEYRawPrivateKey *)PORT_ArenaZAlloc(arena, | |
| 438 sizeof(SECKEYRawPrivateKey)); | |
| 439 if(lpk == NULL) { | |
| 440 goto loser; | |
| 441 } | |
| 442 lpk->arena = arena; | |
| 443 | |
| 444 switch(SECOID_GetAlgorithmTag(&pki->algorithm)) { | |
| 445 case SEC_OID_PKCS1_RSA_ENCRYPTION: | |
| 446 prepare_rsa_priv_key_export_for_asn1(lpk); | |
| 447 keyTemplate = SECKEY_RSAPrivateKeyExportTemplate; | |
| 448 paramTemplate = NULL; | |
| 449 paramDest = NULL; | |
| 450 lpk->keyType = rsaKey; | |
| 451 keyType = CKK_RSA; | |
| 452 break; | |
| 453 case SEC_OID_ANSIX9_DSA_SIGNATURE: | |
| 454 prepare_dsa_priv_key_export_for_asn1(lpk); | |
| 455 keyTemplate = SECKEY_DSAPrivateKeyExportTemplate; | |
| 456 paramTemplate = SECKEY_PQGParamsTemplate; | |
| 457 paramDest = &(lpk->u.dsa.params); | |
| 458 lpk->keyType = dsaKey; | |
| 459 keyType = CKK_DSA; | |
| 460 break; | |
| 461 case SEC_OID_X942_DIFFIE_HELMAN_KEY: | |
| 462 if(!publicValue) { | |
| 463 goto loser; | |
| 464 } | |
| 465 prepare_dh_priv_key_export_for_asn1(lpk); | |
| 466 keyTemplate = SECKEY_DHPrivateKeyExportTemplate; | |
| 467 paramTemplate = NULL; | |
| 468 paramDest = NULL; | |
| 469 lpk->keyType = dhKey; | |
| 470 keyType = CKK_DH; | |
| 471 break; | |
| 472 | |
| 473 default: | |
| 474 keyTemplate = NULL; | |
| 475 paramTemplate = NULL; | |
| 476 paramDest = NULL; | |
| 477 break; | |
| 478 } | |
| 479 | |
| 480 if(!keyTemplate) { | |
| 481 goto loser; | |
| 482 } | |
| 483 | |
| 484 /* decode the private key and any algorithm parameters */ | |
| 485 rv = SEC_ASN1DecodeItem(arena, lpk, keyTemplate, &pki->privateKey); | |
| 486 if(rv != SECSuccess) { | |
| 487 goto loser; | |
| 488 } | |
| 489 if(paramDest && paramTemplate) { | |
| 490 rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate, | |
| 491 &(pki->algorithm.parameters)); | |
| 492 if(rv != SECSuccess) { | |
| 493 goto loser; | |
| 494 } | |
| 495 } | |
| 496 | |
| 497 rv = PK11_ImportAndReturnPrivateKey(slot,lpk,nickname,publicValue, isPerm, | |
| 498 isPrivate, keyUsage, privk, wincx); | |
| 499 | |
| 500 | |
| 501 loser: | |
| 502 if (arena != NULL) { | |
| 503 PORT_FreeArena(arena, PR_TRUE); | |
| 504 } | |
| 505 | |
| 506 return rv; | |
| 507 } | |
| 508 | |
| 509 SECStatus | |
| 510 PK11_ImportPrivateKeyInfo(PK11SlotInfo *slot, SECKEYPrivateKeyInfo *pki, | |
| 511 SECItem *nickname, SECItem *publicValue, PRBool isPerm, | |
| 512 PRBool isPrivate, unsigned int keyUsage, void *wincx) | |
| 513 { | |
| 514 return PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname, | |
| 515 publicValue, isPerm, isPrivate, keyUsage, NULL, wincx); | |
| 516 | |
| 517 } | |
| 518 | |
| OLD | NEW |