pk11pk12.c (38750B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 /* 5 * This file PKCS #12 fuctions that should really be moved to the 6 * PKCS #12 directory, however we can't do that in a point release 7 * because that will break binary compatibility, so we keep them here for now. 8 */ 9 10 #include "seccomon.h" 11 #include "secmod.h" 12 #include "secmodi.h" 13 #include "secmodti.h" 14 #include "secmodt.h" 15 #include "pkcs11.h" 16 #include "pk11func.h" 17 #include "secitem.h" 18 #include "keyhi.h" 19 #include "keyi.h" 20 #include "secoid.h" 21 #include "secasn1.h" 22 #include "secerr.h" 23 #include "prerror.h" 24 25 /* These data structures should move to a common .h file shared between the 26 * wrappers and the pkcs 12 code. */ 27 28 /* 29 ** RSA Raw Private Key structures 30 */ 31 32 /* member names from PKCS#1, section 7.2 */ 33 struct SECKEYRSAPrivateKeyStr { 34 PLArenaPool *arena; 35 SECItem version; 36 SECItem modulus; 37 SECItem publicExponent; 38 SECItem privateExponent; 39 SECItem prime1; 40 SECItem prime2; 41 SECItem exponent1; 42 SECItem exponent2; 43 SECItem coefficient; 44 }; 45 typedef struct SECKEYRSAPrivateKeyStr SECKEYRSAPrivateKey; 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 PLArenaPool *arena; 63 SECItem prime; 64 SECItem base; 65 SECItem privateValue; 66 }; 67 typedef struct SECKEYDHPrivateKeyStr SECKEYDHPrivateKey; 68 69 /* 70 ** Elliptic Curve Private Key structures 71 ** <https://tools.ietf.org/html/rfc5915#section-3> 72 */ 73 struct SECKEYECPrivateKeyStr { 74 PLArenaPool *arena; 75 SECItem version; 76 SECItem curveOID; /* optional/ignored */ 77 SECItem publicValue; /* required (for now) */ 78 SECItem privateValue; 79 }; 80 typedef struct SECKEYECPrivateKeyStr SECKEYECPrivateKey; 81 82 struct SECKEYMLDSAPrivateKeyStr { 83 SECOidTag params; 84 SECItem privateValue; 85 SECItem seed; 86 }; 87 typedef struct SECKEYMLDSAPrivateKeyStr SECKEYMLDSAPrivateKey; 88 89 /* 90 ** raw private key object 91 */ 92 struct SECKEYRawPrivateKeyStr { 93 PLArenaPool *arena; 94 KeyType keyType; 95 union { 96 SECKEYRSAPrivateKey rsa; 97 SECKEYDSAPrivateKey dsa; 98 SECKEYDHPrivateKey dh; 99 SECKEYECPrivateKey ec; 100 SECKEYMLDSAPrivateKey mldsa; 101 } u; 102 }; 103 typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey; 104 105 SEC_ASN1_MKSUB(SEC_AnyTemplate) 106 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) 107 SEC_ASN1_MKSUB(SEC_OctetStringTemplate) 108 109 /* ASN1 Templates for new decoder/encoder */ 110 /* 111 * Attribute value for PKCS8 entries (static?) 112 */ 113 const SEC_ASN1Template SECKEY_AttributeTemplate[] = { 114 { SEC_ASN1_SEQUENCE, 115 0, NULL, sizeof(SECKEYAttribute) }, 116 { SEC_ASN1_OBJECT_ID, offsetof(SECKEYAttribute, attrType) }, 117 { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(SECKEYAttribute, attrValue), 118 SEC_ASN1_SUB(SEC_AnyTemplate) }, 119 { 0 } 120 }; 121 122 const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = { 123 { SEC_ASN1_SET_OF, 0, SECKEY_AttributeTemplate }, 124 }; 125 126 const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = { 127 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKeyInfo) }, 128 { SEC_ASN1_INTEGER, offsetof(SECKEYPrivateKeyInfo, version) }, 129 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, 130 offsetof(SECKEYPrivateKeyInfo, algorithm), 131 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 132 { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPrivateKeyInfo, privateKey) }, 133 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, 134 offsetof(SECKEYPrivateKeyInfo, attributes), 135 SECKEY_SetOfAttributeTemplate }, 136 { 0 } 137 }; 138 139 const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[] = { 140 { SEC_ASN1_POINTER, 0, SECKEY_PrivateKeyInfoTemplate } 141 }; 142 143 const SEC_ASN1Template SECKEY_RSAPrivateKeyExportTemplate[] = { 144 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) }, 145 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.version) }, 146 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.modulus) }, 147 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.publicExponent) }, 148 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.privateExponent) }, 149 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.prime1) }, 150 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.prime2) }, 151 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.exponent1) }, 152 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.exponent2) }, 153 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.coefficient) }, 154 { 0 } 155 }; 156 157 const SEC_ASN1Template SECKEY_DSAPrivateKeyExportTemplate[] = { 158 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dsa.privateValue) }, 159 }; 160 161 const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = { 162 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.privateValue) }, 163 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.base) }, 164 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.prime) }, 165 }; 166 167 const SEC_ASN1Template SECKEY_MLDSAPrivateKeyBothExportTemplate[] = { 168 { SEC_ASN1_CHOICE, 0, NULL, sizeof(SECKEYRawPrivateKey) }, 169 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) }, 170 { SEC_ASN1_OCTET_STRING, offsetof(SECKEYRawPrivateKey, u.mldsa.seed) }, 171 { SEC_ASN1_OCTET_STRING, offsetof(SECKEYRawPrivateKey, u.mldsa.privateValue) }, 172 { 0 } 173 }; 174 175 const SEC_ASN1Template SECKEY_MLDSAPrivateKeySeedExportTemplate[] = { 176 { SEC_ASN1_CHOICE, 0, NULL, sizeof(SECKEYRawPrivateKey) }, 177 { SEC_ASN1_CONTEXT_SPECIFIC | 0, 178 offsetof(SECKEYRawPrivateKey, u.mldsa.seed), 179 SEC_ASN1_SUB(SEC_OctetStringTemplate) }, 180 { 0 } 181 }; 182 183 const SEC_ASN1Template SECKEY_MLDSAPrivateKeyKeyExportTemplate[] = { 184 { SEC_ASN1_CHOICE, 0, NULL, sizeof(SECKEYRawPrivateKey) }, 185 { SEC_ASN1_OCTET_STRING, offsetof(SECKEYRawPrivateKey, u.mldsa.privateValue) }, 186 { 0 } 187 }; 188 189 SEC_ASN1_MKSUB(SEC_BitStringTemplate) 190 SEC_ASN1_MKSUB(SEC_ObjectIDTemplate) 191 192 const SEC_ASN1Template SECKEY_ECPrivateKeyExportTemplate[] = { 193 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) }, 194 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.ec.version) }, 195 { SEC_ASN1_OCTET_STRING, 196 offsetof(SECKEYRawPrivateKey, u.ec.privateValue) }, 197 /* This value will always be ignored. u.ec.curveOID will always be 198 * overriden with the outer AlgorithmID.parameters. */ 199 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 200 SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 201 SEC_ASN1_XTRN | 0, 202 offsetof(SECKEYRawPrivateKey, u.ec.curveOID), 203 SEC_ASN1_SUB(SEC_ObjectIDTemplate) }, 204 /* The public value is optional per RFC, but required in NSS. We 205 * can't do scalar mult on ECs to get a raw point with PK11 APIs. */ 206 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 207 SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 208 SEC_ASN1_XTRN | 1, 209 offsetof(SECKEYRawPrivateKey, u.ec.publicValue), 210 SEC_ASN1_SUB(SEC_BitStringTemplate) }, 211 { 0 } 212 }; 213 214 /* The template operates a private key consisting only of private key. */ 215 const SEC_ASN1Template SECKEY_ECRawPrivateKeyTemplate[] = { 216 { SEC_ASN1_OCTET_STRING, 217 offsetof(SECKEYRawPrivateKey, u.ec.privateValue) }, 218 { 0 } 219 }; 220 221 const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = { 222 { SEC_ASN1_SEQUENCE, 223 0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) }, 224 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, 225 offsetof(SECKEYEncryptedPrivateKeyInfo, algorithm), 226 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 227 { SEC_ASN1_OCTET_STRING, 228 offsetof(SECKEYEncryptedPrivateKeyInfo, encryptedData) }, 229 { 0 } 230 }; 231 232 const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[] = { 233 { SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate } 234 }; 235 236 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_EncryptedPrivateKeyInfoTemplate) 237 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate) 238 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PrivateKeyInfoTemplate) 239 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToPrivateKeyInfoTemplate) 240 241 /* 242 * See bugzilla bug 125359 243 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints, 244 * all of the templates above that en/decode into integers must be converted 245 * from ASN.1's signed integer type. This is done by marking either the 246 * source or destination (encoding or decoding, respectively) type as 247 * siUnsignedInteger. 248 */ 249 250 static void 251 prepare_rsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) 252 { 253 key->u.rsa.modulus.type = siUnsignedInteger; 254 key->u.rsa.publicExponent.type = siUnsignedInteger; 255 key->u.rsa.privateExponent.type = siUnsignedInteger; 256 key->u.rsa.prime1.type = siUnsignedInteger; 257 key->u.rsa.prime2.type = siUnsignedInteger; 258 key->u.rsa.exponent1.type = siUnsignedInteger; 259 key->u.rsa.exponent2.type = siUnsignedInteger; 260 key->u.rsa.coefficient.type = siUnsignedInteger; 261 } 262 263 static void 264 prepare_dsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) 265 { 266 key->u.dsa.privateValue.type = siUnsignedInteger; 267 key->u.dsa.params.prime.type = siUnsignedInteger; 268 key->u.dsa.params.subPrime.type = siUnsignedInteger; 269 key->u.dsa.params.base.type = siUnsignedInteger; 270 } 271 272 static void 273 prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) 274 { 275 key->u.dh.privateValue.type = siUnsignedInteger; 276 key->u.dh.prime.type = siUnsignedInteger; 277 key->u.dh.base.type = siUnsignedInteger; 278 } 279 280 static void 281 prepare_ec_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) 282 { 283 key->u.ec.version.type = siUnsignedInteger; 284 key->u.ec.curveOID.type = siUnsignedInteger; 285 key->u.ec.privateValue.type = siUnsignedInteger; 286 key->u.ec.publicValue.type = siUnsignedInteger; 287 } 288 289 SECStatus 290 PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, SECItem *derPKI, 291 SECItem *nickname, const SECItem *publicValue, PRBool isPerm, 292 PRBool isPrivate, unsigned int keyUsage, void *wincx) 293 { 294 return PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, derPKI, 295 nickname, publicValue, 296 isPerm, isPrivate, keyUsage, 297 NULL, wincx); 298 } 299 300 SECStatus 301 PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI, 302 SECItem *nickname, const SECItem *publicValue, 303 PRBool isPerm, PRBool isPrivate, unsigned int keyUsage, 304 SECKEYPrivateKey **privk, void *wincx) 305 { 306 SECKEYPrivateKeyInfo *pki = NULL; 307 PLArenaPool *temparena = NULL; 308 SECStatus rv = SECFailure; 309 310 temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 311 if (!temparena) { 312 return rv; 313 } 314 315 pki = PORT_ArenaZNew(temparena, SECKEYPrivateKeyInfo); 316 if (!pki) { 317 PORT_FreeArena(temparena, PR_FALSE); 318 return rv; 319 } 320 pki->arena = temparena; 321 322 rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate, 323 derPKI); 324 if (rv != SECSuccess) { 325 /* If SEC_ASN1DecodeItem fails, we cannot assume anything about the 326 * validity of the data in pki. The best we can do is free the arena 327 * and return. */ 328 PORT_FreeArena(temparena, PR_TRUE); 329 return rv; 330 } 331 if (pki->privateKey.data == NULL) { 332 /* If SEC_ASN1DecodeItems succeeds but SECKEYPrivateKeyInfo.privateKey 333 * is a zero-length octet string, free the arena and return a failure 334 * to avoid trying to zero the corresponding SECItem in 335 * SECKEY_DestroyPrivateKeyInfo(). */ 336 PORT_FreeArena(temparena, PR_TRUE); 337 PORT_SetError(SEC_ERROR_BAD_KEY); 338 return SECFailure; 339 } 340 341 rv = PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname, 342 publicValue, isPerm, isPrivate, 343 keyUsage, privk, wincx); 344 345 /* this zeroes the key and frees the arena */ 346 SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/); 347 return rv; 348 } 349 350 SECStatus 351 PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk, 352 SECItem *nickname, const SECItem *publicValue, PRBool isPerm, 353 PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey **privk, 354 void *wincx) 355 { 356 CK_BBOOL cktrue = CK_TRUE; 357 CK_BBOOL ckfalse = CK_FALSE; 358 CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; 359 CK_KEY_TYPE keyType = CKK_RSA; 360 CK_OBJECT_HANDLE objectID; 361 CK_ATTRIBUTE theTemplate[20]; 362 int templateCount = 0; 363 SECStatus rv = SECFailure; 364 CK_ATTRIBUTE *attrs; 365 CK_ATTRIBUTE *signedattr = NULL; 366 int signedcount = 0; 367 CK_ATTRIBUTE *ap; 368 SECItem *ck_id = NULL; 369 CK_ULONG paramSet; 370 371 attrs = theTemplate; 372 373 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); 374 attrs++; 375 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); 376 attrs++; 377 PK11_SETATTRS(attrs, CKA_TOKEN, isPerm ? &cktrue : &ckfalse, 378 sizeof(CK_BBOOL)); 379 attrs++; 380 PK11_SETATTRS(attrs, CKA_SENSITIVE, isPrivate ? &cktrue : &ckfalse, 381 sizeof(CK_BBOOL)); 382 attrs++; 383 PK11_SETATTRS(attrs, CKA_PRIVATE, isPrivate ? &cktrue : &ckfalse, 384 sizeof(CK_BBOOL)); 385 attrs++; 386 387 switch (lpk->keyType) { 388 case rsaKey: 389 keyType = CKK_RSA; 390 PK11_SETATTRS(attrs, CKA_UNWRAP, (keyUsage & KU_KEY_ENCIPHERMENT) ? &cktrue : &ckfalse, 391 sizeof(CK_BBOOL)); 392 attrs++; 393 PK11_SETATTRS(attrs, CKA_DECRYPT, (keyUsage & KU_DATA_ENCIPHERMENT) ? &cktrue : &ckfalse, 394 sizeof(CK_BBOOL)); 395 attrs++; 396 PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue : &ckfalse, 397 sizeof(CK_BBOOL)); 398 attrs++; 399 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, 400 (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue 401 : &ckfalse, 402 sizeof(CK_BBOOL)); 403 attrs++; 404 ck_id = PK11_MakeIDFromPubKey(&lpk->u.rsa.modulus); 405 if (ck_id == NULL) { 406 goto loser; 407 } 408 PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len); 409 attrs++; 410 if (nickname) { 411 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); 412 attrs++; 413 } 414 signedattr = attrs; 415 PK11_SETATTRS(attrs, CKA_MODULUS, lpk->u.rsa.modulus.data, 416 lpk->u.rsa.modulus.len); 417 attrs++; 418 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, 419 lpk->u.rsa.publicExponent.data, 420 lpk->u.rsa.publicExponent.len); 421 attrs++; 422 PK11_SETATTRS(attrs, CKA_PRIVATE_EXPONENT, 423 lpk->u.rsa.privateExponent.data, 424 lpk->u.rsa.privateExponent.len); 425 attrs++; 426 PK11_SETATTRS(attrs, CKA_PRIME_1, 427 lpk->u.rsa.prime1.data, 428 lpk->u.rsa.prime1.len); 429 attrs++; 430 PK11_SETATTRS(attrs, CKA_PRIME_2, 431 lpk->u.rsa.prime2.data, 432 lpk->u.rsa.prime2.len); 433 attrs++; 434 PK11_SETATTRS(attrs, CKA_EXPONENT_1, 435 lpk->u.rsa.exponent1.data, 436 lpk->u.rsa.exponent1.len); 437 attrs++; 438 PK11_SETATTRS(attrs, CKA_EXPONENT_2, 439 lpk->u.rsa.exponent2.data, 440 lpk->u.rsa.exponent2.len); 441 attrs++; 442 PK11_SETATTRS(attrs, CKA_COEFFICIENT, 443 lpk->u.rsa.coefficient.data, 444 lpk->u.rsa.coefficient.len); 445 attrs++; 446 break; 447 case dsaKey: 448 keyType = CKK_DSA; 449 /* To make our intenal PKCS #11 module work correctly with 450 * our database, we need to pass in the public key value for 451 * this dsa key. We have a netscape only CKA_ value to do this. 452 * Only send it to internal slots */ 453 if (publicValue == NULL) { 454 goto loser; 455 } 456 if (PK11_IsInternal(slot)) { 457 PK11_SETATTRS(attrs, CKA_NSS_DB, 458 publicValue->data, publicValue->len); 459 attrs++; 460 } 461 PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(CK_BBOOL)); 462 attrs++; 463 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, &ckfalse, sizeof(CK_BBOOL)); 464 attrs++; 465 if (nickname) { 466 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); 467 attrs++; 468 } 469 ck_id = PK11_MakeIDFromPubKey(publicValue); 470 if (ck_id == NULL) { 471 goto loser; 472 } 473 PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len); 474 attrs++; 475 signedattr = attrs; 476 PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dsa.params.prime.data, 477 lpk->u.dsa.params.prime.len); 478 attrs++; 479 PK11_SETATTRS(attrs, CKA_SUBPRIME, lpk->u.dsa.params.subPrime.data, 480 lpk->u.dsa.params.subPrime.len); 481 attrs++; 482 PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dsa.params.base.data, 483 lpk->u.dsa.params.base.len); 484 attrs++; 485 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dsa.privateValue.data, 486 lpk->u.dsa.privateValue.len); 487 attrs++; 488 break; 489 case dhKey: 490 keyType = CKK_DH; 491 /* To make our intenal PKCS #11 module work correctly with 492 * our database, we need to pass in the public key value for 493 * this dh key. We have a netscape only CKA_ value to do this. 494 * Only send it to internal slots */ 495 if (PK11_IsInternal(slot)) { 496 PK11_SETATTRS(attrs, CKA_NSS_DB, 497 publicValue->data, publicValue->len); 498 attrs++; 499 } 500 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); 501 attrs++; 502 if (nickname) { 503 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); 504 attrs++; 505 } 506 ck_id = PK11_MakeIDFromPubKey(publicValue); 507 if (ck_id == NULL) { 508 goto loser; 509 } 510 PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len); 511 attrs++; 512 signedattr = attrs; 513 PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dh.prime.data, 514 lpk->u.dh.prime.len); 515 attrs++; 516 PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dh.base.data, 517 lpk->u.dh.base.len); 518 attrs++; 519 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dh.privateValue.data, 520 lpk->u.dh.privateValue.len); 521 attrs++; 522 break; 523 case ecKey: 524 keyType = CKK_EC; 525 if (lpk->u.ec.publicValue.len != 0) { 526 if (PK11_IsInternal(slot)) { 527 PK11_SETATTRS(attrs, CKA_NSS_DB, 528 lpk->u.ec.publicValue.data, 529 lpk->u.ec.publicValue.len); 530 attrs++; 531 } 532 } 533 534 PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue : &ckfalse, 535 sizeof(CK_BBOOL)); 536 attrs++; 537 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, &ckfalse, 538 sizeof(CK_BBOOL)); 539 attrs++; 540 PK11_SETATTRS(attrs, CKA_DERIVE, (keyUsage & KU_KEY_AGREEMENT) ? &cktrue : &ckfalse, 541 sizeof(CK_BBOOL)); 542 attrs++; 543 if (nickname) { 544 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); 545 attrs++; 546 } 547 ck_id = PK11_MakeIDFromPubKey(&lpk->u.ec.publicValue); 548 if (ck_id == NULL) { 549 goto loser; 550 } 551 PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len); 552 attrs++; 553 /* No signed attrs for EC */ 554 /* curveOID always is a copy of AlgorithmID.parameters. */ 555 PK11_SETATTRS(attrs, CKA_EC_PARAMS, lpk->u.ec.curveOID.data, 556 lpk->u.ec.curveOID.len); 557 attrs++; 558 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.ec.privateValue.data, 559 lpk->u.ec.privateValue.len); 560 attrs++; 561 PK11_SETATTRS(attrs, CKA_EC_POINT, lpk->u.ec.publicValue.data, 562 lpk->u.ec.publicValue.len); 563 attrs++; 564 break; 565 case edKey: 566 keyType = CKK_EC_EDWARDS; 567 PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(CK_BBOOL)); 568 attrs++; 569 if (nickname) { 570 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); 571 attrs++; 572 } 573 574 /* No signed attrs for EC */ 575 /* curveOID always is a copy of AlgorithmID.parameters. */ 576 PK11_SETATTRS(attrs, CKA_EC_PARAMS, lpk->u.ec.curveOID.data, 577 lpk->u.ec.curveOID.len); 578 attrs++; 579 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.ec.privateValue.data, 580 lpk->u.ec.privateValue.len); 581 attrs++; 582 break; 583 case ecMontKey: 584 keyType = CKK_EC_MONTGOMERY; 585 586 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); 587 attrs++; 588 589 if (nickname) { 590 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); 591 attrs++; 592 } 593 594 /* No signed attrs for EC */ 595 /* curveOID always is a copy of AlgorithmID.parameters. */ 596 PK11_SETATTRS(attrs, CKA_EC_PARAMS, lpk->u.ec.curveOID.data, 597 lpk->u.ec.curveOID.len); 598 attrs++; 599 600 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.ec.privateValue.data, 601 lpk->u.ec.privateValue.len); 602 attrs++; 603 break; 604 case mldsaKey: 605 keyType = CKK_ML_DSA; 606 /* we need at least one of these to import into PKCS #11. 607 * if we have only one, it may still fail, but that is up 608 * to the token */ 609 if ((lpk->u.mldsa.seed.len == 0) && 610 (lpk->u.mldsa.privateValue.len == 0)) { 611 PORT_SetError(SEC_ERROR_BAD_KEY); 612 goto loser; 613 } 614 PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(CK_BBOOL)); 615 attrs++; 616 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, &ckfalse, sizeof(CK_BBOOL)); 617 attrs++; 618 /* if we have the public value, we can do more, without it 619 * we won't be able to set the ck_id properly, which will make 620 * this key effectively invisible. The application will need 621 * to update the ID before it looses it's handle */ 622 if (publicValue != NULL) { 623 if (PK11_IsInternal(slot)) { 624 PK11_SETATTRS(attrs, CKA_NSS_DB, 625 publicValue->data, publicValue->len); 626 attrs++; 627 } 628 ck_id = PK11_MakeIDFromPubKey(publicValue); 629 if (ck_id == NULL) { 630 goto loser; 631 } 632 PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len); 633 attrs++; 634 } 635 if (nickname) { 636 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); 637 attrs++; 638 } 639 paramSet = SECKEY_GetMLDSAPkcs11ParamSetByOidTag(lpk->u.mldsa.params); 640 PK11_SETATTRS(attrs, CKA_PARAMETER_SET, (unsigned char *)¶mSet, 641 sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)); 642 attrs++; 643 if (lpk->u.mldsa.seed.len) { 644 PK11_SETATTRS(attrs, CKA_SEED, lpk->u.mldsa.seed.data, 645 lpk->u.mldsa.seed.len); 646 attrs++; 647 } 648 if (lpk->u.mldsa.privateValue.len) { 649 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.mldsa.privateValue.data, 650 lpk->u.mldsa.privateValue.len); 651 attrs++; 652 } 653 break; 654 default: 655 PORT_SetError(SEC_ERROR_BAD_KEY); 656 goto loser; 657 } 658 templateCount = attrs - theTemplate; 659 PORT_Assert(templateCount <= sizeof(theTemplate) / sizeof(CK_ATTRIBUTE)); 660 /* we used to assert unless the key didn't need signedattrs, but that's 661 * now true of almost all modern keys, so now if the key has signedattrs 662 * the just need to set the value */ 663 if (signedattr) { 664 signedcount = attrs - signedattr; 665 for (ap = signedattr; signedcount; ap++, signedcount--) { 666 pk11_SignedToUnsigned(ap); 667 } 668 } 669 670 rv = PK11_CreateNewObject(slot, CK_INVALID_HANDLE, 671 theTemplate, templateCount, isPerm, &objectID); 672 673 /* create and return a SECKEYPrivateKey */ 674 if (rv == SECSuccess && privk != NULL) { 675 *privk = PK11_MakePrivKey(slot, lpk->keyType, !isPerm, objectID, wincx); 676 if (*privk == NULL) { 677 rv = SECFailure; 678 } 679 } 680 loser: 681 if (ck_id) { 682 SECITEM_ZfreeItem(ck_id, PR_TRUE); 683 } 684 return rv; 685 } 686 687 SECStatus 688 PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, 689 SECKEYPrivateKeyInfo *pki, SECItem *nickname, const SECItem *publicValue, 690 PRBool isPerm, PRBool isPrivate, unsigned int keyUsage, 691 SECKEYPrivateKey **privk, void *wincx) 692 { 693 SECStatus rv = SECFailure; 694 SECKEYRawPrivateKey *lpk = NULL; 695 const SEC_ASN1Template *keyTemplate, *paramTemplate; 696 void *paramDest = NULL; 697 PLArenaPool *arena = NULL; 698 SECOidTag algTag; 699 700 arena = PORT_NewArena(2048); 701 if (!arena) { 702 return SECFailure; 703 } 704 705 /* need to change this to use RSA/DSA keys */ 706 lpk = (SECKEYRawPrivateKey *)PORT_ArenaZAlloc(arena, 707 sizeof(SECKEYRawPrivateKey)); 708 if (lpk == NULL) { 709 goto loser; 710 } 711 lpk->arena = arena; 712 713 algTag = SECOID_GetAlgorithmTag(&pki->algorithm); 714 switch (algTag) { 715 case SEC_OID_PKCS1_RSA_ENCRYPTION: 716 prepare_rsa_priv_key_export_for_asn1(lpk); 717 keyTemplate = SECKEY_RSAPrivateKeyExportTemplate; 718 paramTemplate = NULL; 719 paramDest = NULL; 720 lpk->keyType = rsaKey; 721 break; 722 case SEC_OID_ANSIX9_DSA_SIGNATURE: 723 prepare_dsa_priv_key_export_for_asn1(lpk); 724 keyTemplate = SECKEY_DSAPrivateKeyExportTemplate; 725 paramTemplate = SECKEY_PQGParamsTemplate; 726 paramDest = &(lpk->u.dsa.params); 727 lpk->keyType = dsaKey; 728 break; 729 case SEC_OID_X942_DIFFIE_HELMAN_KEY: 730 if (!publicValue) { 731 goto loser; 732 } 733 prepare_dh_priv_key_export_for_asn1(lpk); 734 keyTemplate = SECKEY_DHPrivateKeyExportTemplate; 735 paramTemplate = NULL; 736 paramDest = NULL; 737 lpk->keyType = dhKey; 738 break; 739 case SEC_OID_ED25519_PUBLIC_KEY: 740 keyTemplate = SECKEY_ECRawPrivateKeyTemplate; 741 paramTemplate = NULL; 742 paramDest = NULL; 743 lpk->keyType = edKey; 744 break; 745 case SEC_OID_X25519: 746 keyTemplate = SECKEY_ECRawPrivateKeyTemplate; 747 paramTemplate = NULL; 748 paramDest = NULL; 749 lpk->keyType = ecMontKey; 750 break; 751 case SEC_OID_ANSIX962_EC_PUBLIC_KEY: 752 prepare_ec_priv_key_export_for_asn1(lpk); 753 keyTemplate = SECKEY_ECPrivateKeyExportTemplate; 754 paramTemplate = NULL; 755 paramDest = NULL; 756 lpk->keyType = ecKey; 757 break; 758 case SEC_OID_ML_DSA_44: 759 case SEC_OID_ML_DSA_65: 760 case SEC_OID_ML_DSA_87: 761 /* choice */ 762 switch (pki->privateKey.data[0]) { 763 case SEC_ASN1_CONTEXT_SPECIFIC | 0: 764 keyTemplate = SECKEY_MLDSAPrivateKeySeedExportTemplate; 765 break; 766 case SEC_ASN1_OCTET_STRING: 767 keyTemplate = SECKEY_MLDSAPrivateKeyKeyExportTemplate; 768 break; 769 case SEC_ASN1_CONSTRUCTED | SEC_ASN1_SEQUENCE: 770 keyTemplate = SECKEY_MLDSAPrivateKeyBothExportTemplate; 771 break; 772 default: 773 keyTemplate = NULL; 774 PORT_SetError(SEC_ERROR_BAD_DER); 775 break; 776 } 777 paramTemplate = NULL; 778 paramDest = NULL; 779 lpk->keyType = mldsaKey; 780 lpk->u.mldsa.params = algTag; 781 break; 782 default: 783 keyTemplate = NULL; 784 paramTemplate = NULL; 785 paramDest = NULL; 786 break; 787 } 788 789 if (!keyTemplate) { 790 goto loser; 791 } 792 793 /* decode the private key and any algorithm parameters */ 794 rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey); 795 if (rv != SECSuccess) { 796 goto loser; 797 } 798 799 if (lpk->keyType == ecKey) { 800 /* Convert length in bits to length in bytes. */ 801 lpk->u.ec.publicValue.len >>= 3; 802 803 /* Always override curveOID, we're ignoring any given value. */ 804 rv = SECITEM_CopyItem(arena, &lpk->u.ec.curveOID, 805 &pki->algorithm.parameters); 806 if (rv != SECSuccess) { 807 goto loser; 808 } 809 } 810 811 if (lpk->keyType == edKey || lpk->keyType == ecMontKey) { 812 /* SECKEY_ECRawPrivateKeyTemplate (used for both key types) does not reference 813 publicKey, curveOID, ec verion. */ 814 if (pki->algorithm.parameters.len != 0) { 815 /* Currently supporting only (Pure)Ed25519/X25519 .*/ 816 PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); 817 goto loser; 818 } 819 820 SECOidData *oid25519 = SECOID_FindOIDByTag(SECOID_GetAlgorithmTag(&pki->algorithm)); 821 if (!oid25519) { 822 goto loser; 823 } 824 825 if (!SECITEM_AllocItem(arena, &lpk->u.ec.curveOID, oid25519->oid.len + 2)) { 826 goto loser; 827 } 828 lpk->u.ec.curveOID.data[0] = SEC_ASN1_OBJECT_ID; 829 lpk->u.ec.curveOID.data[1] = oid25519->oid.len; 830 PORT_Memcpy(lpk->u.ec.curveOID.data + 2, oid25519->oid.data, oid25519->oid.len); 831 } 832 833 if (paramDest && paramTemplate) { 834 rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate, 835 &(pki->algorithm.parameters)); 836 if (rv != SECSuccess) { 837 goto loser; 838 } 839 } 840 841 rv = PK11_ImportAndReturnPrivateKey(slot, lpk, nickname, publicValue, isPerm, 842 isPrivate, keyUsage, privk, wincx); 843 loser: 844 if (arena != NULL) { 845 PORT_FreeArena(arena, PR_TRUE); 846 } 847 848 return rv; 849 } 850 851 SECStatus 852 PK11_ImportPrivateKeyInfo(PK11SlotInfo *slot, SECKEYPrivateKeyInfo *pki, 853 SECItem *nickname, const SECItem *publicValue, PRBool isPerm, 854 PRBool isPrivate, unsigned int keyUsage, void *wincx) 855 { 856 return PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname, 857 publicValue, isPerm, isPrivate, keyUsage, NULL, wincx); 858 } 859 860 SECItem * 861 PK11_ExportDERPrivateKeyInfo(SECKEYPrivateKey *pk, void *wincx) 862 { 863 SECKEYPrivateKeyInfo *pki = PK11_ExportPrivKeyInfo(pk, wincx); 864 SECItem *derPKI; 865 866 if (!pki) { 867 return NULL; 868 } 869 derPKI = SEC_ASN1EncodeItem(NULL, NULL, pki, 870 SECKEY_PrivateKeyInfoTemplate); 871 SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE); 872 return derPKI; 873 } 874 875 static PRBool 876 ReadAttribute(SECKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, 877 PLArenaPool *arena, SECItem *output) 878 { 879 SECStatus rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, type, 880 arena, output); 881 return rv == SECSuccess; 882 } 883 884 /* 885 * The caller is responsible for freeing the return value by passing it to 886 * SECKEY_DestroyPrivateKeyInfo(..., PR_TRUE). 887 */ 888 SECKEYPrivateKeyInfo * 889 PK11_ExportPrivKeyInfo(SECKEYPrivateKey *pk, void *wincx) 890 { 891 /* PrivateKeyInfo version (always zero) */ 892 const unsigned char pkiVersion = 0; 893 /* RSAPrivateKey version (always zero) */ 894 const unsigned char rsaVersion = 0; 895 /* ECPrivateKey version (always one) */ 896 const unsigned char ecVersion = 1; 897 PLArenaPool *arena = NULL; 898 SECKEYRawPrivateKey rawKey; 899 SECKEYPrivateKeyInfo *pki; 900 SECItem *encoded; 901 const SEC_ASN1Template *keyTemplate; 902 SECStatus rv; 903 904 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 905 if (!arena) { 906 goto loser; 907 } 908 memset(&rawKey, 0, sizeof(rawKey)); 909 rawKey.keyType = pk->keyType; 910 pki = PORT_ArenaZNew(arena, SECKEYPrivateKeyInfo); 911 if (!pki) { 912 goto loser; 913 } 914 915 switch (pk->keyType) { 916 case rsaKey: { 917 rawKey.u.rsa.version.type = siUnsignedInteger; 918 rawKey.u.rsa.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1); 919 if (!rawKey.u.rsa.version.data) { 920 goto loser; 921 } 922 923 rawKey.u.rsa.version.data[0] = rsaVersion; 924 rawKey.u.rsa.version.len = 1; 925 926 /* Read the component attributes of the private key */ 927 prepare_rsa_priv_key_export_for_asn1(&rawKey); 928 if (!ReadAttribute(pk, CKA_MODULUS, arena, &rawKey.u.rsa.modulus) || 929 !ReadAttribute(pk, CKA_PUBLIC_EXPONENT, arena, 930 &rawKey.u.rsa.publicExponent) || 931 !ReadAttribute(pk, CKA_PRIVATE_EXPONENT, arena, 932 &rawKey.u.rsa.privateExponent) || 933 !ReadAttribute(pk, CKA_PRIME_1, arena, &rawKey.u.rsa.prime1) || 934 !ReadAttribute(pk, CKA_PRIME_2, arena, &rawKey.u.rsa.prime2) || 935 !ReadAttribute(pk, CKA_EXPONENT_1, arena, 936 &rawKey.u.rsa.exponent1) || 937 !ReadAttribute(pk, CKA_EXPONENT_2, arena, 938 &rawKey.u.rsa.exponent2) || 939 !ReadAttribute(pk, CKA_COEFFICIENT, arena, 940 &rawKey.u.rsa.coefficient)) { 941 goto loser; 942 } 943 944 keyTemplate = SECKEY_RSAPrivateKeyExportTemplate; 945 946 rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, SEC_OID_PKCS1_RSA_ENCRYPTION, NULL); 947 if (rv != SECSuccess) { 948 goto loser; 949 } 950 951 } break; 952 case ecKey: { 953 rawKey.u.ec.version.type = siUnsignedInteger; 954 rawKey.u.ec.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1); 955 if (!rawKey.u.ec.version.data) { 956 goto loser; 957 } 958 rawKey.u.ec.version.data[0] = ecVersion; 959 rawKey.u.ec.version.len = 1; 960 961 SECItem curveOID; 962 /* Read the component attributes of the private key */ 963 prepare_ec_priv_key_export_for_asn1(&rawKey); 964 if (!ReadAttribute(pk, CKA_VALUE, arena, 965 &rawKey.u.ec.privateValue) || 966 !ReadAttribute(pk, CKA_EC_PARAMS, arena, &curveOID)) { 967 goto loser; 968 } 969 if (!ReadAttribute(pk, CKA_EC_POINT, arena, 970 &rawKey.u.ec.publicValue)) { 971 SECKEYPublicKey *pubk = SECKEY_ConvertToPublicKey(pk); 972 if (pubk == NULL) 973 goto loser; 974 rv = SECITEM_CopyItem(arena, &rawKey.u.ec.publicValue, &pubk->u.ec.publicValue); 975 SECKEY_DestroyPublicKey(pubk); 976 if (rv != SECSuccess) { 977 goto loser; 978 } 979 } 980 981 keyTemplate = SECKEY_ECPrivateKeyExportTemplate; 982 /* Convert length in bytes to length in bits. */ 983 rawKey.u.ec.publicValue.len <<= 3; 984 985 rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, SEC_OID_ANSIX962_EC_PUBLIC_KEY, &curveOID); 986 if (rv != SECSuccess) { 987 goto loser; 988 } 989 990 } break; 991 case edKey: { 992 if (!ReadAttribute(pk, CKA_VALUE, arena, 993 &rawKey.u.ec.privateValue)) { 994 goto loser; 995 } 996 997 keyTemplate = SECKEY_ECRawPrivateKeyTemplate; 998 /* Currently, Ed25519 does not support any parameter. */ 999 rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, SEC_OID_ED25519_PUBLIC_KEY, NULL); 1000 if (rv != SECSuccess) { 1001 goto loser; 1002 } 1003 } break; 1004 case ecMontKey: { 1005 if (!ReadAttribute(pk, CKA_VALUE, arena, 1006 &rawKey.u.ec.privateValue)) { 1007 goto loser; 1008 } 1009 1010 keyTemplate = SECKEY_ECRawPrivateKeyTemplate; 1011 /* Currently, X25519 does not support any parameter. */ 1012 rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, SEC_OID_X25519, NULL); 1013 if (rv != SECSuccess) { 1014 goto loser; 1015 } 1016 } break; 1017 default: { 1018 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); 1019 goto loser; 1020 } 1021 } 1022 1023 encoded = SEC_ASN1EncodeItem(arena, &pki->privateKey, &rawKey, keyTemplate); 1024 if (!encoded) { 1025 goto loser; 1026 } 1027 pki->version.type = siUnsignedInteger; 1028 pki->version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1); 1029 if (!pki->version.data) { 1030 goto loser; 1031 } 1032 pki->version.data[0] = pkiVersion; 1033 pki->version.len = 1; 1034 pki->arena = arena; 1035 1036 return pki; 1037 1038 loser: 1039 if (arena) { 1040 PORT_FreeArena(arena, PR_TRUE); 1041 } 1042 return NULL; 1043 }