pk11akey.c (104801B)
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 contains functions to manage asymetric keys, (public and 6 * private keys). 7 */ 8 #include <stddef.h> 9 10 #include "seccomon.h" 11 #include "secmod.h" 12 #include "secmodi.h" 13 #include "secmodti.h" 14 #include "pkcs11.h" 15 #include "pkcs11t.h" 16 #include "pk11func.h" 17 #include "cert.h" 18 #include "keyhi.h" 19 #include "keyi.h" 20 #include "secitem.h" 21 #include "secasn1.h" 22 #include "secoid.h" 23 #include "secerr.h" 24 #include "sechash.h" 25 26 #include "secpkcs5.h" 27 #include "blapit.h" 28 29 const SECItem * 30 PK11_GetPublicValueFromPublicKey(const SECKEYPublicKey *pubKey) 31 { 32 /* set the ID to the public key so we can find it again */ 33 const SECItem *pubKeyIndex = NULL; 34 switch (pubKey->keyType) { 35 case rsaKey: 36 case rsaPssKey: 37 case rsaOaepKey: 38 pubKeyIndex = &pubKey->u.rsa.modulus; 39 break; 40 case dsaKey: 41 pubKeyIndex = &pubKey->u.dsa.publicValue; 42 break; 43 case dhKey: 44 pubKeyIndex = &pubKey->u.dh.publicValue; 45 break; 46 case edKey: 47 case ecKey: 48 case ecMontKey: 49 pubKeyIndex = &pubKey->u.ec.publicValue; 50 break; 51 case kyberKey: 52 pubKeyIndex = &pubKey->u.kyber.publicValue; 53 break; 54 case mldsaKey: 55 pubKeyIndex = &pubKey->u.mldsa.publicValue; 56 break; 57 /* explicitly put unsupported keys here. The 58 * compiler will tell you when you need to 59 * add switch statements */ 60 case fortezzaKey: 61 case keaKey: 62 case nullKey: 63 return NULL; 64 } 65 PORT_Assert(pubKeyIndex != NULL); 66 67 return pubKeyIndex; 68 } 69 70 KeyType 71 pk11_getKeyTypeFromPKCS11KeyType(CK_KEY_TYPE pk11KeyType) 72 { 73 KeyType keyType = nullKey; 74 switch (pk11KeyType) { 75 case CKK_RSA: 76 keyType = rsaKey; 77 break; 78 case CKK_DSA: 79 keyType = dsaKey; 80 break; 81 case CKK_DH: 82 keyType = dhKey; 83 break; 84 case CKK_EC: 85 keyType = ecKey; 86 break; 87 case CKK_EC_MONTGOMERY: 88 keyType = ecMontKey; 89 break; 90 case CKK_EC_EDWARDS: 91 keyType = edKey; 92 break; 93 case CKK_NSS_KYBER: 94 case CKK_NSS_ML_KEM: 95 case CKK_ML_KEM: 96 keyType = kyberKey; 97 break; 98 case CKK_ML_DSA: 99 keyType = mldsaKey; 100 break; 101 default: 102 PORT_SetError(SEC_ERROR_BAD_KEY); 103 break; 104 } 105 return keyType; 106 } 107 108 CK_KEY_TYPE 109 pk11_getPKCS11KeyTypeFromKeyType(KeyType keyType) 110 { 111 CK_KEY_TYPE pk11KeyType = CKK_INVALID_KEY_TYPE; 112 switch (keyType) { 113 case rsaKey: 114 case rsaPssKey: 115 case rsaOaepKey: 116 pk11KeyType = CKK_RSA; 117 break; 118 case dsaKey: 119 pk11KeyType = CKK_DSA; 120 break; 121 case dhKey: 122 pk11KeyType = CKK_DH; 123 break; 124 case ecKey: 125 pk11KeyType = CKK_EC; 126 break; 127 case ecMontKey: 128 pk11KeyType = CKK_EC_MONTGOMERY; 129 break; 130 case edKey: 131 pk11KeyType = CKK_EC_EDWARDS; 132 break; 133 case kyberKey: 134 pk11KeyType = CKK_ML_KEM; 135 break; 136 case mldsaKey: 137 pk11KeyType = CKK_ML_DSA; 138 break; 139 /* explicitly put unsupported keys here. The 140 * compiler will tell you when you need to 141 * add switch statements */ 142 case fortezzaKey: 143 case keaKey: 144 case nullKey: 145 break; 146 } 147 if (pk11KeyType == CKK_INVALID_KEY_TYPE) { 148 PORT_SetError(SEC_ERROR_BAD_KEY); 149 } 150 return pk11KeyType; 151 } 152 153 SECItem * 154 pk11_MakeIDFromPublicKey(const SECKEYPublicKey *pubKey) 155 { 156 /* set the ID to the public key so we can find it again */ 157 const SECItem *pubKeyIndex = PK11_GetPublicValueFromPublicKey(pubKey); 158 PORT_Assert(pubKeyIndex != NULL); 159 160 return PK11_MakeIDFromPubKey(pubKeyIndex); 161 } 162 163 /* 164 * import a public key into the desired slot 165 * 166 * This function takes a public key structure and creates a public key in a 167 * given slot. If isToken is set, then a persistant public key is created. 168 * 169 * Note: it is possible for this function to return a handle for a key which 170 * is persistant, even if isToken is not set. 171 */ 172 CK_OBJECT_HANDLE 173 PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey, 174 PRBool isToken) 175 { 176 CK_BBOOL cktrue = CK_TRUE; 177 CK_BBOOL ckfalse = CK_FALSE; 178 CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; 179 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; 180 CK_OBJECT_HANDLE objectID; 181 CK_ATTRIBUTE theTemplate[11]; 182 CK_ATTRIBUTE *signedattr = NULL; 183 CK_ATTRIBUTE *attrs = theTemplate; 184 CK_NSS_KEM_PARAMETER_SET_TYPE kemParams; 185 SECItem *ckaId = NULL; 186 SECItem *pubValue = NULL; 187 int signedcount = 0; 188 unsigned int templateCount = 0; 189 SECStatus rv; 190 CK_ML_DSA_PARAMETER_SET_TYPE paramSet; 191 192 /* if we already have an object in the desired slot, use it */ 193 if (!isToken && pubKey->pkcs11Slot == slot) { 194 return pubKey->pkcs11ID; 195 } 196 197 /* free the existing key */ 198 if (pubKey->pkcs11Slot != NULL) { 199 PK11SlotInfo *oSlot = pubKey->pkcs11Slot; 200 if (!PK11_IsPermObject(pubKey->pkcs11Slot, pubKey->pkcs11ID)) { 201 PK11_EnterSlotMonitor(oSlot); 202 (void)PK11_GETTAB(oSlot)->C_DestroyObject(oSlot->session, 203 pubKey->pkcs11ID); 204 PK11_ExitSlotMonitor(oSlot); 205 } 206 PK11_FreeSlot(oSlot); 207 pubKey->pkcs11Slot = NULL; 208 } 209 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); 210 attrs++; 211 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); 212 attrs++; 213 PK11_SETATTRS(attrs, CKA_TOKEN, isToken ? &cktrue : &ckfalse, 214 sizeof(CK_BBOOL)); 215 attrs++; 216 if (isToken) { 217 ckaId = pk11_MakeIDFromPublicKey(pubKey); 218 if (ckaId == NULL) { 219 PORT_SetError(SEC_ERROR_BAD_KEY); 220 return CK_INVALID_HANDLE; 221 } 222 PK11_SETATTRS(attrs, CKA_ID, ckaId->data, ckaId->len); 223 attrs++; 224 } 225 226 /* now import the key */ 227 { 228 switch (pubKey->keyType) { 229 case rsaKey: 230 keyType = CKK_RSA; 231 PK11_SETATTRS(attrs, CKA_WRAP, &cktrue, sizeof(CK_BBOOL)); 232 attrs++; 233 PK11_SETATTRS(attrs, CKA_ENCRYPT, &cktrue, 234 sizeof(CK_BBOOL)); 235 attrs++; 236 PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL)); 237 attrs++; 238 signedattr = attrs; 239 PK11_SETATTRS(attrs, CKA_MODULUS, pubKey->u.rsa.modulus.data, 240 pubKey->u.rsa.modulus.len); 241 attrs++; 242 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, 243 pubKey->u.rsa.publicExponent.data, 244 pubKey->u.rsa.publicExponent.len); 245 attrs++; 246 break; 247 case dsaKey: 248 keyType = CKK_DSA; 249 PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL)); 250 attrs++; 251 signedattr = attrs; 252 PK11_SETATTRS(attrs, CKA_PRIME, pubKey->u.dsa.params.prime.data, 253 pubKey->u.dsa.params.prime.len); 254 attrs++; 255 PK11_SETATTRS(attrs, CKA_SUBPRIME, pubKey->u.dsa.params.subPrime.data, 256 pubKey->u.dsa.params.subPrime.len); 257 attrs++; 258 PK11_SETATTRS(attrs, CKA_BASE, pubKey->u.dsa.params.base.data, 259 pubKey->u.dsa.params.base.len); 260 attrs++; 261 PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.dsa.publicValue.data, 262 pubKey->u.dsa.publicValue.len); 263 attrs++; 264 break; 265 case fortezzaKey: 266 keyType = CKK_DSA; 267 PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL)); 268 attrs++; 269 signedattr = attrs; 270 PK11_SETATTRS(attrs, CKA_PRIME, pubKey->u.fortezza.params.prime.data, 271 pubKey->u.fortezza.params.prime.len); 272 attrs++; 273 PK11_SETATTRS(attrs, CKA_SUBPRIME, 274 pubKey->u.fortezza.params.subPrime.data, 275 pubKey->u.fortezza.params.subPrime.len); 276 attrs++; 277 PK11_SETATTRS(attrs, CKA_BASE, pubKey->u.fortezza.params.base.data, 278 pubKey->u.fortezza.params.base.len); 279 attrs++; 280 PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.fortezza.DSSKey.data, 281 pubKey->u.fortezza.DSSKey.len); 282 attrs++; 283 break; 284 case dhKey: 285 keyType = CKK_DH; 286 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); 287 attrs++; 288 signedattr = attrs; 289 PK11_SETATTRS(attrs, CKA_PRIME, pubKey->u.dh.prime.data, 290 pubKey->u.dh.prime.len); 291 attrs++; 292 PK11_SETATTRS(attrs, CKA_BASE, pubKey->u.dh.base.data, 293 pubKey->u.dh.base.len); 294 attrs++; 295 PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.dh.publicValue.data, 296 pubKey->u.dh.publicValue.len); 297 attrs++; 298 break; 299 case edKey: 300 keyType = CKK_EC_EDWARDS; 301 PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL)); 302 attrs++; 303 PK11_SETATTRS(attrs, CKA_EC_PARAMS, 304 pubKey->u.ec.DEREncodedParams.data, 305 pubKey->u.ec.DEREncodedParams.len); 306 attrs++; 307 PK11_SETATTRS(attrs, CKA_EC_POINT, 308 pubKey->u.ec.publicValue.data, 309 pubKey->u.ec.publicValue.len); 310 attrs++; 311 break; 312 case ecMontKey: 313 keyType = CKK_EC_MONTGOMERY; 314 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); 315 attrs++; 316 PK11_SETATTRS(attrs, CKA_EC_PARAMS, 317 pubKey->u.ec.DEREncodedParams.data, 318 pubKey->u.ec.DEREncodedParams.len); 319 attrs++; 320 PK11_SETATTRS(attrs, CKA_EC_POINT, 321 pubKey->u.ec.publicValue.data, 322 pubKey->u.ec.publicValue.len); 323 attrs++; 324 break; 325 case ecKey: 326 keyType = CKK_EC; 327 PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL)); 328 attrs++; 329 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); 330 attrs++; 331 PK11_SETATTRS(attrs, CKA_EC_PARAMS, 332 pubKey->u.ec.DEREncodedParams.data, 333 pubKey->u.ec.DEREncodedParams.len); 334 attrs++; 335 if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT")) { 336 PK11_SETATTRS(attrs, CKA_EC_POINT, 337 pubKey->u.ec.publicValue.data, 338 pubKey->u.ec.publicValue.len); 339 attrs++; 340 } else { 341 pubValue = SEC_ASN1EncodeItem(NULL, NULL, 342 &pubKey->u.ec.publicValue, 343 SEC_ASN1_GET(SEC_OctetStringTemplate)); 344 if (pubValue == NULL) { 345 if (ckaId) { 346 SECITEM_FreeItem(ckaId, PR_TRUE); 347 } 348 return CK_INVALID_HANDLE; 349 } 350 PK11_SETATTRS(attrs, CKA_EC_POINT, 351 pubValue->data, pubValue->len); 352 attrs++; 353 } 354 break; 355 case kyberKey: 356 switch (pubKey->u.kyber.params) { 357 #ifndef NSS_DISABLE_KYBER 358 case params_kyber768_round3: 359 case params_kyber768_round3_test_mode: 360 keyType = CKK_NSS_KYBER; 361 kemParams = CKP_NSS_KYBER_768_ROUND3; 362 break; 363 #endif 364 case params_ml_kem768: 365 case params_ml_kem768_test_mode: 366 keyType = CKK_ML_KEM; 367 kemParams = CKP_ML_KEM_768; 368 break; 369 case params_ml_kem1024: 370 case params_ml_kem1024_test_mode: 371 keyType = CKK_ML_KEM; 372 kemParams = CKP_ML_KEM_1024; 373 break; 374 default: 375 kemParams = CKP_INVALID_ID; 376 break; 377 } 378 PK11_SETATTRS(attrs, CKA_NSS_PARAMETER_SET, 379 &kemParams, 380 sizeof(CK_NSS_KEM_PARAMETER_SET_TYPE)); 381 attrs++; 382 PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.kyber.publicValue.data, 383 pubKey->u.kyber.publicValue.len); 384 attrs++; 385 break; 386 case mldsaKey: 387 keyType = CKK_ML_DSA; 388 PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL)); 389 attrs++; 390 paramSet = SECKEY_GetMLDSAPkcs11ParamSetByOidTag(pubKey->u.mldsa.paramSet); 391 if (paramSet == CKP_INVALID_ID) { 392 PORT_SetError(SEC_ERROR_BAD_KEY); 393 return CK_INVALID_HANDLE; 394 } 395 PK11_SETATTRS(attrs, CKA_PARAMETER_SET, ¶mSet, 396 sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)); 397 attrs++; 398 PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.mldsa.publicValue.data, 399 pubKey->u.mldsa.publicValue.len); 400 attrs++; 401 break; 402 default: 403 if (ckaId) { 404 SECITEM_FreeItem(ckaId, PR_TRUE); 405 } 406 PORT_SetError(SEC_ERROR_BAD_KEY); 407 return CK_INVALID_HANDLE; 408 } 409 templateCount = attrs - theTemplate; 410 PORT_Assert(templateCount <= (sizeof(theTemplate) / sizeof(CK_ATTRIBUTE))); 411 if (signedattr) { 412 signedcount = attrs - signedattr; 413 for (attrs = signedattr; signedcount; attrs++, signedcount--) { 414 pk11_SignedToUnsigned(attrs); 415 } 416 } 417 rv = PK11_CreateNewObject(slot, CK_INVALID_HANDLE, theTemplate, 418 templateCount, isToken, &objectID); 419 if (ckaId) { 420 SECITEM_FreeItem(ckaId, PR_TRUE); 421 } 422 if (pubValue) { 423 SECITEM_FreeItem(pubValue, PR_TRUE); 424 } 425 if (rv != SECSuccess) { 426 return CK_INVALID_HANDLE; 427 } 428 } 429 430 pubKey->pkcs11ID = objectID; 431 pubKey->pkcs11Slot = PK11_ReferenceSlot(slot); 432 433 return objectID; 434 } 435 436 /* 437 * take an attribute and copy it into a secitem 438 */ 439 static CK_RV 440 pk11_Attr2SecItem(PLArenaPool *arena, const CK_ATTRIBUTE *attr, SECItem *item) 441 { 442 item->data = NULL; 443 444 (void)SECITEM_AllocItem(arena, item, attr->ulValueLen); 445 if (item->data == NULL) { 446 return CKR_HOST_MEMORY; 447 } 448 PORT_Memcpy(item->data, attr->pValue, item->len); 449 return CKR_OK; 450 } 451 452 /* 453 * get a curve length from a set of ecParams. 454 * 455 * We need this so we can reliably determine if the ecPoint passed to us 456 * was encoded or not. With out this, for many curves, we would incorrectly 457 * identify an unencoded curve as an encoded curve 1 in 65536 times, and for 458 * a few we would make that same mistake 1 in 32768 times. These are bad 459 * numbers since they are rare enough to pass tests, but common enough to 460 * be tripped over in the field. 461 * 462 * This function will only work for curves we recognized as of March 2009. 463 * The assumption is curves in use after March of 2009 would be supplied by 464 * PKCS #11 modules that already pass the correct encoding to us. 465 * 466 * Point length = (Roundup(curveLenInBits/8)*2+1) 467 */ 468 static int 469 pk11_get_EC_PointLenInBytes(PLArenaPool *arena, const SECItem *ecParams, 470 PRBool *plain) 471 { 472 SECItem oid; 473 SECOidTag tag; 474 SECStatus rv; 475 476 /* decode the OID tag */ 477 rv = SEC_QuickDERDecodeItem(arena, &oid, 478 SEC_ASN1_GET(SEC_ObjectIDTemplate), ecParams); 479 if (rv != SECSuccess) { 480 /* could be explict curves, allow them to work if the 481 * PKCS #11 module support them. If we try to parse the 482 * explicit curve value in the future, we may return -1 here 483 * to indicate an invalid parameter if the explicit curve 484 * decode fails. */ 485 return 0; 486 } 487 488 *plain = PR_FALSE; 489 tag = SECOID_FindOIDTag(&oid); 490 switch (tag) { 491 case SEC_OID_SECG_EC_SECP112R1: 492 case SEC_OID_SECG_EC_SECP112R2: 493 return 29; /* curve len in bytes = 14 bytes */ 494 case SEC_OID_SECG_EC_SECT113R1: 495 case SEC_OID_SECG_EC_SECT113R2: 496 return 31; /* curve len in bytes = 15 bytes */ 497 case SEC_OID_SECG_EC_SECP128R1: 498 case SEC_OID_SECG_EC_SECP128R2: 499 return 33; /* curve len in bytes = 16 bytes */ 500 case SEC_OID_SECG_EC_SECT131R1: 501 case SEC_OID_SECG_EC_SECT131R2: 502 return 35; /* curve len in bytes = 17 bytes */ 503 case SEC_OID_SECG_EC_SECP160K1: 504 case SEC_OID_SECG_EC_SECP160R1: 505 case SEC_OID_SECG_EC_SECP160R2: 506 return 41; /* curve len in bytes = 20 bytes */ 507 case SEC_OID_SECG_EC_SECT163K1: 508 case SEC_OID_SECG_EC_SECT163R1: 509 case SEC_OID_SECG_EC_SECT163R2: 510 case SEC_OID_ANSIX962_EC_C2PNB163V1: 511 case SEC_OID_ANSIX962_EC_C2PNB163V2: 512 case SEC_OID_ANSIX962_EC_C2PNB163V3: 513 return 43; /* curve len in bytes = 21 bytes */ 514 case SEC_OID_ANSIX962_EC_C2PNB176V1: 515 return 45; /* curve len in bytes = 22 bytes */ 516 case SEC_OID_ANSIX962_EC_C2TNB191V1: 517 case SEC_OID_ANSIX962_EC_C2TNB191V2: 518 case SEC_OID_ANSIX962_EC_C2TNB191V3: 519 case SEC_OID_SECG_EC_SECP192K1: 520 case SEC_OID_ANSIX962_EC_PRIME192V1: 521 case SEC_OID_ANSIX962_EC_PRIME192V2: 522 case SEC_OID_ANSIX962_EC_PRIME192V3: 523 return 49; /*curve len in bytes = 24 bytes */ 524 case SEC_OID_SECG_EC_SECT193R1: 525 case SEC_OID_SECG_EC_SECT193R2: 526 return 51; /*curve len in bytes = 25 bytes */ 527 case SEC_OID_ANSIX962_EC_C2PNB208W1: 528 return 53; /*curve len in bytes = 26 bytes */ 529 case SEC_OID_SECG_EC_SECP224K1: 530 case SEC_OID_SECG_EC_SECP224R1: 531 return 57; /*curve len in bytes = 28 bytes */ 532 case SEC_OID_SECG_EC_SECT233K1: 533 case SEC_OID_SECG_EC_SECT233R1: 534 case SEC_OID_SECG_EC_SECT239K1: 535 case SEC_OID_ANSIX962_EC_PRIME239V1: 536 case SEC_OID_ANSIX962_EC_PRIME239V2: 537 case SEC_OID_ANSIX962_EC_PRIME239V3: 538 case SEC_OID_ANSIX962_EC_C2TNB239V1: 539 case SEC_OID_ANSIX962_EC_C2TNB239V2: 540 case SEC_OID_ANSIX962_EC_C2TNB239V3: 541 return 61; /*curve len in bytes = 30 bytes */ 542 case SEC_OID_ANSIX962_EC_PRIME256V1: 543 case SEC_OID_SECG_EC_SECP256K1: 544 return 65; /*curve len in bytes = 32 bytes */ 545 case SEC_OID_ANSIX962_EC_C2PNB272W1: 546 return 69; /*curve len in bytes = 34 bytes */ 547 case SEC_OID_SECG_EC_SECT283K1: 548 case SEC_OID_SECG_EC_SECT283R1: 549 return 73; /*curve len in bytes = 36 bytes */ 550 case SEC_OID_ANSIX962_EC_C2PNB304W1: 551 return 77; /*curve len in bytes = 38 bytes */ 552 case SEC_OID_ANSIX962_EC_C2TNB359V1: 553 return 91; /*curve len in bytes = 45 bytes */ 554 case SEC_OID_ANSIX962_EC_C2PNB368W1: 555 return 93; /*curve len in bytes = 46 bytes */ 556 case SEC_OID_SECG_EC_SECP384R1: 557 return 97; /*curve len in bytes = 48 bytes */ 558 case SEC_OID_SECG_EC_SECT409K1: 559 case SEC_OID_SECG_EC_SECT409R1: 560 return 105; /*curve len in bytes = 52 bytes */ 561 case SEC_OID_ANSIX962_EC_C2TNB431R1: 562 return 109; /*curve len in bytes = 54 bytes */ 563 case SEC_OID_SECG_EC_SECP521R1: 564 return 133; /*curve len in bytes = 66 bytes */ 565 case SEC_OID_SECG_EC_SECT571K1: 566 case SEC_OID_SECG_EC_SECT571R1: 567 return 145; /*curve len in bytes = 72 bytes */ 568 case SEC_OID_X25519: 569 case SEC_OID_CURVE25519: 570 case SEC_OID_ED25519_PUBLIC_KEY: 571 *plain = PR_TRUE; 572 return 32; /* curve len in bytes = 32 bytes (only X) */ 573 /* unknown or unrecognized OIDs. return unknown length */ 574 default: 575 break; 576 } 577 return 0; 578 } 579 580 /* 581 * returns the decoded point. In some cases the point may already be decoded. 582 * this function tries to detect those cases and return the point in 583 * publicKeyValue. In other cases it's DER encoded. In those cases the point 584 * is first decoded and returned. Space for the point is allocated out of 585 * the passed in arena. 586 */ 587 static CK_RV 588 pk11_get_Decoded_ECPoint(PLArenaPool *arena, const SECItem *ecParams, 589 const CK_ATTRIBUTE *ecPoint, SECItem *publicKeyValue) 590 { 591 SECItem encodedPublicValue; 592 SECStatus rv; 593 int keyLen; 594 PRBool plain = PR_FALSE; 595 596 if (ecPoint->ulValueLen == 0) { 597 return CKR_ATTRIBUTE_VALUE_INVALID; 598 } 599 600 /* 601 * The PKCS #11 spec requires ecPoints to be encoded as a DER OCTET String. 602 * NSS has mistakenly passed unencoded values, and some PKCS #11 vendors 603 * followed that mistake. Now we need to detect which encoding we were 604 * passed in. The task is made more complicated by the fact the the 605 * DER encoding byte (SEC_ASN_OCTET_STRING) is the same as the 606 * EC_POINT_FORM_UNCOMPRESSED byte (0x04), so we can't use that to 607 * determine which curve we are using. 608 */ 609 610 /* get the expected key length for the passed in curve. 611 * pk11_get_EC_PointLenInBytes only returns valid values for curves 612 * NSS has traditionally recognized. If the curve is not recognized, 613 * it will return '0', and we have to figure out if the key was 614 * encoded or not heuristically. If the ecParams are invalid, it 615 * will return -1 for the keyLen. 616 */ 617 keyLen = pk11_get_EC_PointLenInBytes(arena, ecParams, &plain); 618 if (keyLen < 0) { 619 return CKR_ATTRIBUTE_VALUE_INVALID; 620 } 621 622 /* 623 * Some curves are not encoded but we don't have the name here. 624 * Instead, pk11_get_EC_PointLenInBytes returns true plain if this is the 625 * case. 626 */ 627 if (plain && ecPoint->ulValueLen == (unsigned int)keyLen) { 628 return pk11_Attr2SecItem(arena, ecPoint, publicKeyValue); 629 } 630 631 /* If the point is uncompressed and the lengths match, it 632 * must be an unencoded point */ 633 if ((*((char *)ecPoint->pValue) == EC_POINT_FORM_UNCOMPRESSED) && 634 (ecPoint->ulValueLen == (unsigned int)keyLen)) { 635 return pk11_Attr2SecItem(arena, ecPoint, publicKeyValue); 636 } 637 638 /* now assume the key passed to us was encoded and decode it */ 639 if (*((char *)ecPoint->pValue) == SEC_ASN1_OCTET_STRING) { 640 /* OK, now let's try to decode it and see if it's valid */ 641 encodedPublicValue.data = ecPoint->pValue; 642 encodedPublicValue.len = ecPoint->ulValueLen; 643 rv = SEC_QuickDERDecodeItem(arena, publicKeyValue, 644 SEC_ASN1_GET(SEC_OctetStringTemplate), &encodedPublicValue); 645 646 /* it coded correctly & we know the key length (and they match) 647 * then we are done, return the results. */ 648 if (keyLen && rv == SECSuccess && publicKeyValue->len == (unsigned int)keyLen) { 649 return CKR_OK; 650 } 651 652 /* if we know the key length, one of the above tests should have 653 * succeded. If it doesn't the module gave us bad data */ 654 if (keyLen) { 655 return CKR_ATTRIBUTE_VALUE_INVALID; 656 } 657 658 /* We don't know the key length, so we don't know deterministically 659 * which encoding was used. We now will try to pick the most likely 660 * form that's correct, with a preference for the encoded form if we 661 * can't determine for sure. We do this by checking the key we got 662 * back from SEC_QuickDERDecodeItem for defects. If no defects are 663 * found, we assume the encoded parameter was was passed to us. 664 * our defect tests include: 665 * 1) it didn't decode. 666 * 2) The decode key had an invalid length (must be odd). 667 * 3) The decoded key wasn't an UNCOMPRESSED key. 668 * 4) The decoded key didn't include the entire encoded block 669 * except the DER encoding values. (fixing DER length to one 670 * particular value). 671 */ 672 if ((rv != SECSuccess) || ((publicKeyValue->len & 1) != 1) || 673 (publicKeyValue->data[0] != EC_POINT_FORM_UNCOMPRESSED) || 674 (PORT_Memcmp(&encodedPublicValue.data[encodedPublicValue.len - publicKeyValue->len], 675 publicKeyValue->data, 676 publicKeyValue->len) != 0)) { 677 /* The decoded public key was flawed, the original key must have 678 * already been in decoded form. Do a quick sanity check then 679 * return the original key value. 680 */ 681 if ((encodedPublicValue.len & 1) == 0) { 682 return CKR_ATTRIBUTE_VALUE_INVALID; 683 } 684 return pk11_Attr2SecItem(arena, ecPoint, publicKeyValue); 685 } 686 687 /* as best we can figure, the passed in key was encoded, and we've 688 * now decoded it. Note: there is a chance this could be wrong if the 689 * following conditions hold: 690 * 1) The first byte or bytes of the X point looks like a valid length 691 * of precisely the right size (2*curveSize -1). this means for curves 692 * less than 512 bits (64 bytes), this will happen 1 in 256 times*. 693 * for curves between 512 and 1024, this will happen 1 in 65,536 times* 694 * for curves between 1024 and 256K this will happen 1 in 16 million* 695 * 2) The length of the 'DER length field' is odd 696 * (making both the encoded and decode 697 * values an odd length. this is true of all curves less than 512, 698 * as well as curves between 1024 and 256K). 699 * 3) The X[length of the 'DER length field'] == 0x04, 1 in 256. 700 * 701 * (* assuming all values are equally likely in the first byte, 702 * This isn't true if the curve length is not a multiple of 8. In these 703 * cases, if the DER length is possible, it's more likely, 704 * if it's not possible, then we have no false decodes). 705 * 706 * For reference here are the odds for the various curves we currently 707 * have support for (and the only curves SSL will negotiate at this 708 * time). NOTE: None of the supported curves will show up here 709 * because we return a valid length for all of these curves. 710 * The only way to get here is to have some application (not SSL) 711 * which supports some unknown curve and have some vendor supplied 712 * PKCS #11 module support that curve. NOTE: in this case, one 713 * presumes that that pkcs #11 module is likely to be using the 714 * correct encodings. 715 * 716 * Prime Curves (GFp): 717 * Bit False Odds of 718 * Size DER Len False Decode Positive 719 * 112 27 1 in 65536 720 * 128 31 1 in 65536 721 * 160 39 1 in 65536 722 * 192 47 1 in 65536 723 * 224 55 1 in 65536 724 * 239 59 1 in 32768 (top byte can only be 0-127) 725 * 256 63 1 in 65536 726 * 521 129,131 0 (decoded value would be even) 727 * 728 * Binary curves (GF2m). 729 * Bit False Odds of 730 * Size DER Len False Decode Positive 731 * 131 33 0 (top byte can only be 0-7) 732 * 163 41 0 (top byte can only be 0-7) 733 * 176 43 1 in 65536 734 * 191 47 1 in 32768 (top byte can only be 0-127) 735 * 193 49 0 (top byte can only be 0-1) 736 * 208 51 1 in 65536 737 * 233 59 0 (top byte can only be 0-1) 738 * 239 59 1 in 32768 (top byte can only be 0-127) 739 * 272 67 1 in 65536 740 * 283 71 0 (top byte can only be 0-7) 741 * 304 75 1 in 65536 742 * 359 89 1 in 32768 (top byte can only be 0-127) 743 * 368 91 1 in 65536 744 * 409 103 0 (top byte can only be 0-1) 745 * 431 107 1 in 32768 (top byte can only be 0-127) 746 * 571 129,143 0 (decoded value would be even) 747 * 748 */ 749 750 return CKR_OK; 751 } 752 753 /* In theory, we should handle the case where the curve == 0 and 754 * the first byte is EC_POINT_FORM_UNCOMPRESSED, (which would be 755 * handled by doing a santity check on the key length and returning 756 * pk11_Attr2SecItem() to copy the ecPoint to the publicKeyValue). 757 * 758 * This test is unnecessary, however, due to the fact that 759 * EC_POINT_FORM_UNCOMPRESSED == SEC_ASIN1_OCTET_STRING, that case is 760 * handled in the above if. That means if we get here, the initial 761 * byte of our ecPoint value was invalid, so we can safely return. 762 * invalid attribute. 763 */ 764 765 return CKR_ATTRIBUTE_VALUE_INVALID; 766 } 767 768 /* 769 * extract a public key from a slot and id 770 */ 771 SECKEYPublicKey * 772 PK11_ExtractPublicKey(PK11SlotInfo *slot, KeyType keyType, CK_OBJECT_HANDLE id) 773 { 774 CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; 775 PLArenaPool *arena; 776 PLArenaPool *tmp_arena; 777 SECKEYPublicKey *pubKey; 778 unsigned int templateCount = 0; 779 CK_KEY_TYPE pk11KeyType; 780 CK_RV crv; 781 CK_ATTRIBUTE template[8]; 782 CK_ATTRIBUTE *attrs = template; 783 CK_ATTRIBUTE *modulus, *exponent, *base, *prime, *subprime, *value; 784 CK_ATTRIBUTE *ecparams, *kemParams, *mldsaParams; 785 786 /* if we didn't know the key type, get it */ 787 if (keyType == nullKey) { 788 pk11KeyType = PK11_ReadULongAttribute(slot, id, CKA_KEY_TYPE); 789 if (pk11KeyType == CK_UNAVAILABLE_INFORMATION) { 790 return NULL; 791 } 792 keyType = pk11_getKeyTypeFromPKCS11KeyType(pk11KeyType); 793 if (keyType == nullKey) { 794 return NULL; 795 } 796 } 797 798 /* now we need to create space for the public key */ 799 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 800 if (arena == NULL) 801 return NULL; 802 tmp_arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 803 if (tmp_arena == NULL) { 804 PORT_FreeArena(arena, PR_FALSE); 805 return NULL; 806 } 807 808 pubKey = (SECKEYPublicKey *) 809 PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey)); 810 if (pubKey == NULL) { 811 PORT_FreeArena(arena, PR_FALSE); 812 PORT_FreeArena(tmp_arena, PR_FALSE); 813 return NULL; 814 } 815 816 pubKey->arena = arena; 817 pubKey->keyType = keyType; 818 pubKey->pkcs11Slot = PK11_ReferenceSlot(slot); 819 pubKey->pkcs11ID = id; 820 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, 821 sizeof(keyClass)); 822 attrs++; 823 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &pk11KeyType, 824 sizeof(pk11KeyType)); 825 attrs++; 826 switch (pubKey->keyType) { 827 case rsaKey: 828 modulus = attrs; 829 PK11_SETATTRS(attrs, CKA_MODULUS, NULL, 0); 830 attrs++; 831 exponent = attrs; 832 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, NULL, 0); 833 attrs++; 834 835 templateCount = attrs - template; 836 PR_ASSERT(templateCount <= sizeof(template) / sizeof(CK_ATTRIBUTE)); 837 crv = PK11_GetAttributes(tmp_arena, slot, id, template, templateCount); 838 if (crv != CKR_OK) 839 break; 840 841 if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_RSA)) { 842 crv = CKR_OBJECT_HANDLE_INVALID; 843 break; 844 } 845 crv = pk11_Attr2SecItem(arena, modulus, &pubKey->u.rsa.modulus); 846 if (crv != CKR_OK) 847 break; 848 crv = pk11_Attr2SecItem(arena, exponent, &pubKey->u.rsa.publicExponent); 849 if (crv != CKR_OK) 850 break; 851 break; 852 case dsaKey: 853 prime = attrs; 854 PK11_SETATTRS(attrs, CKA_PRIME, NULL, 0); 855 attrs++; 856 subprime = attrs; 857 PK11_SETATTRS(attrs, CKA_SUBPRIME, NULL, 0); 858 attrs++; 859 base = attrs; 860 PK11_SETATTRS(attrs, CKA_BASE, NULL, 0); 861 attrs++; 862 value = attrs; 863 PK11_SETATTRS(attrs, CKA_VALUE, NULL, 0); 864 attrs++; 865 templateCount = attrs - template; 866 PR_ASSERT(templateCount <= sizeof(template) / sizeof(CK_ATTRIBUTE)); 867 crv = PK11_GetAttributes(tmp_arena, slot, id, template, templateCount); 868 if (crv != CKR_OK) 869 break; 870 871 if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_DSA)) { 872 crv = CKR_OBJECT_HANDLE_INVALID; 873 break; 874 } 875 crv = pk11_Attr2SecItem(arena, prime, &pubKey->u.dsa.params.prime); 876 if (crv != CKR_OK) 877 break; 878 crv = pk11_Attr2SecItem(arena, subprime, &pubKey->u.dsa.params.subPrime); 879 if (crv != CKR_OK) 880 break; 881 crv = pk11_Attr2SecItem(arena, base, &pubKey->u.dsa.params.base); 882 if (crv != CKR_OK) 883 break; 884 crv = pk11_Attr2SecItem(arena, value, &pubKey->u.dsa.publicValue); 885 if (crv != CKR_OK) 886 break; 887 break; 888 case dhKey: 889 prime = attrs; 890 PK11_SETATTRS(attrs, CKA_PRIME, NULL, 0); 891 attrs++; 892 base = attrs; 893 PK11_SETATTRS(attrs, CKA_BASE, NULL, 0); 894 attrs++; 895 value = attrs; 896 PK11_SETATTRS(attrs, CKA_VALUE, NULL, 0); 897 attrs++; 898 templateCount = attrs - template; 899 PR_ASSERT(templateCount <= sizeof(template) / sizeof(CK_ATTRIBUTE)); 900 crv = PK11_GetAttributes(tmp_arena, slot, id, template, templateCount); 901 if (crv != CKR_OK) 902 break; 903 904 if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_DH)) { 905 crv = CKR_OBJECT_HANDLE_INVALID; 906 break; 907 } 908 crv = pk11_Attr2SecItem(arena, prime, &pubKey->u.dh.prime); 909 if (crv != CKR_OK) 910 break; 911 crv = pk11_Attr2SecItem(arena, base, &pubKey->u.dh.base); 912 if (crv != CKR_OK) 913 break; 914 crv = pk11_Attr2SecItem(arena, value, &pubKey->u.dh.publicValue); 915 if (crv != CKR_OK) 916 break; 917 break; 918 case edKey: 919 case ecKey: 920 case ecMontKey: 921 pubKey->u.ec.size = 0; 922 ecparams = attrs; 923 PK11_SETATTRS(attrs, CKA_EC_PARAMS, NULL, 0); 924 attrs++; 925 value = attrs; 926 PK11_SETATTRS(attrs, CKA_EC_POINT, NULL, 0); 927 attrs++; 928 templateCount = attrs - template; 929 PR_ASSERT(templateCount <= sizeof(template) / sizeof(CK_ATTRIBUTE)); 930 crv = PK11_GetAttributes(arena, slot, id, template, templateCount); 931 if (crv != CKR_OK) 932 break; 933 934 if ((keyClass != CKO_PUBLIC_KEY) || 935 (pubKey->keyType == ecKey && pk11KeyType != CKK_EC) || 936 (pubKey->keyType == edKey && pk11KeyType != CKK_EC_EDWARDS) || 937 (pubKey->keyType == ecMontKey && pk11KeyType != CKK_EC_MONTGOMERY)) { 938 crv = CKR_OBJECT_HANDLE_INVALID; 939 break; 940 } 941 942 crv = pk11_Attr2SecItem(arena, ecparams, 943 &pubKey->u.ec.DEREncodedParams); 944 if (crv != CKR_OK) 945 break; 946 pubKey->u.ec.encoding = ECPoint_Undefined; 947 crv = pk11_get_Decoded_ECPoint(arena, 948 &pubKey->u.ec.DEREncodedParams, value, 949 &pubKey->u.ec.publicValue); 950 break; 951 case mldsaKey: 952 value = attrs; 953 PK11_SETATTRS(attrs, CKA_VALUE, NULL, 0); 954 attrs++; 955 mldsaParams = attrs; 956 PK11_SETATTRS(attrs, CKA_PARAMETER_SET, NULL, 0); 957 attrs++; 958 templateCount = attrs - template; 959 PR_ASSERT(templateCount <= sizeof(template) / sizeof(CK_ATTRIBUTE)); 960 crv = PK11_GetAttributes(tmp_arena, slot, id, template, templateCount); 961 if (crv != CKR_OK) 962 break; 963 964 if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_ML_DSA)) { 965 crv = CKR_OBJECT_HANDLE_INVALID; 966 break; 967 } 968 969 if (mldsaParams->ulValueLen != sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)) { 970 crv = CKR_OBJECT_HANDLE_INVALID; 971 break; 972 } 973 pubKey->u.mldsa.paramSet = SECKEY_GetMLDSAOidTagByPkcs11ParamSet( 974 *(CK_ML_DSA_PARAMETER_SET_TYPE *)mldsaParams->pValue); 975 976 crv = pk11_Attr2SecItem(arena, value, &pubKey->u.mldsa.publicValue); 977 if (crv != CKR_OK) 978 break; 979 break; 980 case kyberKey: 981 value = attrs; 982 PK11_SETATTRS(attrs, CKA_VALUE, NULL, 0); 983 attrs++; 984 kemParams = attrs; 985 PK11_SETATTRS(attrs, CKA_PARAMETER_SET, NULL, 0); 986 attrs++; 987 templateCount = attrs - template; 988 PR_ASSERT(templateCount <= sizeof(template) / sizeof(CK_ATTRIBUTE)); 989 990 crv = PK11_GetAttributes(arena, slot, id, template, templateCount); 991 if (crv != CKR_OK) { 992 kemParams->type = CKA_NSS_PARAMETER_SET; 993 crv = PK11_GetAttributes(arena, slot, id, template, 994 templateCount); 995 if (crv != CKR_OK) { 996 break; 997 } 998 } 999 1000 if (keyClass != CKO_PUBLIC_KEY) { 1001 crv = CKR_OBJECT_HANDLE_INVALID; 1002 break; 1003 } 1004 1005 switch (pk11KeyType) { 1006 #ifndef NSS_DISABLE_KYBER 1007 case CKK_NSS_KYBER: 1008 #endif 1009 case CKK_NSS_ML_KEM: 1010 case CKK_ML_KEM: 1011 break; 1012 default: 1013 crv = CKR_OBJECT_HANDLE_INVALID; 1014 break; 1015 } 1016 if (crv != CKR_OK) { 1017 break; 1018 } 1019 1020 if (kemParams->ulValueLen != sizeof(CK_NSS_KEM_PARAMETER_SET_TYPE)) { 1021 crv = CKR_OBJECT_HANDLE_INVALID; 1022 break; 1023 } 1024 CK_NSS_KEM_PARAMETER_SET_TYPE *pPK11Params = kemParams->pValue; 1025 switch (*pPK11Params) { 1026 #ifndef NSS_DISABLE_KYBER 1027 case CKP_NSS_KYBER_768_ROUND3: 1028 pubKey->u.kyber.params = params_kyber768_round3; 1029 break; 1030 #endif 1031 case CKP_NSS_ML_KEM_768: 1032 case CKP_ML_KEM_768: 1033 pubKey->u.kyber.params = params_ml_kem768; 1034 break; 1035 case CKP_ML_KEM_1024: 1036 pubKey->u.kyber.params = params_ml_kem1024; 1037 break; 1038 default: 1039 pubKey->u.kyber.params = params_kyber_invalid; 1040 break; 1041 } 1042 crv = pk11_Attr2SecItem(arena, value, &pubKey->u.kyber.publicValue); 1043 break; 1044 case fortezzaKey: 1045 case nullKey: 1046 default: 1047 crv = CKR_OBJECT_HANDLE_INVALID; 1048 break; 1049 } 1050 1051 PORT_FreeArena(tmp_arena, PR_FALSE); 1052 1053 if (crv != CKR_OK) { 1054 PORT_FreeArena(arena, PR_FALSE); 1055 PK11_FreeSlot(slot); 1056 PORT_SetError(PK11_MapError(crv)); 1057 return NULL; 1058 } 1059 1060 return pubKey; 1061 } 1062 1063 /* 1064 * Build a Private Key structure from raw PKCS #11 information. 1065 */ 1066 SECKEYPrivateKey * 1067 PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType, 1068 PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx) 1069 { 1070 PLArenaPool *arena; 1071 SECKEYPrivateKey *privKey; 1072 PRBool isPrivate; 1073 SECStatus rv; 1074 1075 /* don't know? look it up */ 1076 if (keyType == nullKey) { 1077 CK_KEY_TYPE pk11Type = CKK_RSA; 1078 1079 pk11Type = PK11_ReadULongAttribute(slot, privID, CKA_KEY_TYPE); 1080 isTemp = (PRBool)!PK11_HasAttributeSet(slot, privID, CKA_TOKEN, PR_FALSE); 1081 keyType = pk11_getKeyTypeFromPKCS11KeyType(pk11Type); 1082 if (keyType == nullKey) { 1083 return NULL; 1084 } 1085 } 1086 1087 /* if the key is private, make sure we are authenticated to the 1088 * token before we try to use it */ 1089 isPrivate = (PRBool)PK11_HasAttributeSet(slot, privID, CKA_PRIVATE, PR_FALSE); 1090 if (isPrivate) { 1091 rv = PK11_Authenticate(slot, PR_TRUE, wincx); 1092 if (rv != SECSuccess) { 1093 return NULL; 1094 } 1095 } 1096 1097 /* now we need to create space for the private key */ 1098 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 1099 if (arena == NULL) 1100 return NULL; 1101 1102 privKey = (SECKEYPrivateKey *) 1103 PORT_ArenaZAlloc(arena, sizeof(SECKEYPrivateKey)); 1104 if (privKey == NULL) { 1105 PORT_FreeArena(arena, PR_FALSE); 1106 return NULL; 1107 } 1108 1109 privKey->arena = arena; 1110 privKey->keyType = keyType; 1111 privKey->pkcs11Slot = PK11_ReferenceSlot(slot); 1112 privKey->pkcs11ID = privID; 1113 privKey->pkcs11IsTemp = isTemp; 1114 privKey->wincx = wincx; 1115 1116 return privKey; 1117 } 1118 1119 PK11SlotInfo * 1120 PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key) 1121 { 1122 PK11SlotInfo *slot = key->pkcs11Slot; 1123 slot = PK11_ReferenceSlot(slot); 1124 return slot; 1125 } 1126 1127 /* 1128 * Get the modulus length for raw parsing 1129 */ 1130 int 1131 PK11_GetPrivateModulusLen(SECKEYPrivateKey *key) 1132 { 1133 CK_ATTRIBUTE theTemplate = { CKA_MODULUS, NULL, 0 }; 1134 PK11SlotInfo *slot = key->pkcs11Slot; 1135 CK_RV crv; 1136 int length; 1137 1138 switch (key->keyType) { 1139 case rsaKey: 1140 crv = PK11_GetAttributes(NULL, slot, key->pkcs11ID, &theTemplate, 1); 1141 if (crv != CKR_OK) { 1142 PORT_SetError(PK11_MapError(crv)); 1143 return -1; 1144 } 1145 if (theTemplate.pValue == NULL) { 1146 PORT_SetError(PK11_MapError(CKR_ATTRIBUTE_VALUE_INVALID)); 1147 return -1; 1148 } 1149 length = theTemplate.ulValueLen; 1150 if (*(unsigned char *)theTemplate.pValue == 0) { 1151 length--; 1152 } 1153 PORT_Free(theTemplate.pValue); 1154 return (int)length; 1155 default: 1156 break; 1157 } 1158 if (theTemplate.pValue != NULL) 1159 PORT_Free(theTemplate.pValue); 1160 PORT_SetError(SEC_ERROR_INVALID_KEY); 1161 return -1; 1162 } 1163 1164 /* 1165 * take a private key in one pkcs11 module and load it into another: 1166 * NOTE: the source private key is a rare animal... it can't be sensitive. 1167 * This is used to do a key gen using one pkcs11 module and storing the 1168 * result into another. 1169 */ 1170 static SECKEYPrivateKey * 1171 pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot, SECKEYPrivateKey *privKey, 1172 SECKEYPublicKey *pubKey, PK11AttrFlags attrFlags) 1173 { 1174 CK_ATTRIBUTE privTemplate[] = { 1175 /* class must be first */ 1176 { CKA_CLASS, NULL, 0 }, 1177 { CKA_KEY_TYPE, NULL, 0 }, 1178 { CKA_ID, NULL, 0 }, 1179 /* RSA - the attributes below will be replaced for other 1180 * key types. 1181 */ 1182 { CKA_MODULUS, NULL, 0 }, 1183 { CKA_PRIVATE_EXPONENT, NULL, 0 }, 1184 { CKA_PUBLIC_EXPONENT, NULL, 0 }, 1185 { CKA_PRIME_1, NULL, 0 }, 1186 { CKA_PRIME_2, NULL, 0 }, 1187 { CKA_EXPONENT_1, NULL, 0 }, 1188 { CKA_EXPONENT_2, NULL, 0 }, 1189 { CKA_COEFFICIENT, NULL, 0 }, 1190 { CKA_DECRYPT, NULL, 0 }, 1191 { CKA_DERIVE, NULL, 0 }, 1192 { CKA_SIGN, NULL, 0 }, 1193 { CKA_SIGN_RECOVER, NULL, 0 }, 1194 { CKA_UNWRAP, NULL, 0 }, 1195 { CKA_DECAPSULATE, NULL, 0 }, 1196 /* reserve space for the attributes that may be 1197 * specified in attrFlags */ 1198 { CKA_TOKEN, NULL, 0 }, 1199 { CKA_PRIVATE, NULL, 0 }, 1200 { CKA_MODIFIABLE, NULL, 0 }, 1201 { CKA_SENSITIVE, NULL, 0 }, 1202 { CKA_EXTRACTABLE, NULL, 0 }, 1203 { CKA_PARAMETER_SET, NULL, 0 }, 1204 { CKA_SEED, NULL, 0 }, 1205 #define NUM_RESERVED_ATTRS 5 /* number of reserved attributes above */ 1206 }; 1207 CK_BBOOL cktrue = CK_TRUE; 1208 CK_BBOOL ckfalse = CK_FALSE; 1209 CK_ATTRIBUTE *attrs = NULL, *ap; 1210 const int templateSize = sizeof(privTemplate) / sizeof(privTemplate[0]); 1211 PLArenaPool *arena; 1212 CK_OBJECT_HANDLE objectID; 1213 int i, count = 0; 1214 int extra_count = 0; /* count of signed attributes */ 1215 CK_RV crv; 1216 SECStatus rv; 1217 PRBool token = ((attrFlags & PK11_ATTR_TOKEN) != 0); 1218 1219 if (pk11_BadAttrFlags(attrFlags)) { 1220 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1221 return NULL; 1222 } 1223 1224 for (i = 0; i < templateSize; i++) { 1225 if (privTemplate[i].type == CKA_MODULUS) { 1226 attrs = &privTemplate[i]; 1227 count = i; 1228 break; 1229 } 1230 } 1231 PORT_Assert(attrs != NULL); 1232 if (attrs == NULL) { 1233 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 1234 return NULL; 1235 } 1236 1237 ap = attrs; 1238 1239 switch (privKey->keyType) { 1240 case rsaKey: 1241 count = templateSize - NUM_RESERVED_ATTRS; 1242 extra_count = count - (attrs - privTemplate); 1243 break; 1244 case dsaKey: 1245 ap->type = CKA_PRIME; 1246 ap++; 1247 count++; 1248 extra_count++; 1249 ap->type = CKA_SUBPRIME; 1250 ap++; 1251 count++; 1252 extra_count++; 1253 ap->type = CKA_BASE; 1254 ap++; 1255 count++; 1256 extra_count++; 1257 ap->type = CKA_VALUE; 1258 ap++; 1259 count++; 1260 extra_count++; 1261 ap->type = CKA_SIGN; 1262 ap++; 1263 count++; 1264 extra_count++; 1265 break; 1266 case dhKey: 1267 ap->type = CKA_PRIME; 1268 ap++; 1269 count++; 1270 extra_count++; 1271 ap->type = CKA_BASE; 1272 ap++; 1273 count++; 1274 extra_count++; 1275 ap->type = CKA_VALUE; 1276 ap++; 1277 count++; 1278 extra_count++; 1279 ap->type = CKA_DERIVE; 1280 ap++; 1281 count++; 1282 extra_count++; 1283 break; 1284 case mldsaKey: 1285 ap->type = CKA_PARAMETER_SET; 1286 ap++; 1287 count++; 1288 ap->type = CKA_SEED; 1289 ap++; 1290 count++; 1291 ap->type = CKA_VALUE; 1292 ap++; 1293 count++; 1294 ap->type = CKA_SIGN; 1295 ap++; 1296 count++; 1297 break; 1298 case ecKey: 1299 case edKey: 1300 case ecMontKey: 1301 ap->type = CKA_EC_PARAMS; 1302 ap++; 1303 count++; 1304 ap->type = CKA_VALUE; 1305 ap++; 1306 count++; 1307 if (privKey->keyType == ecKey) { 1308 ap->type = CKA_DERIVE; 1309 ap++; 1310 count++; 1311 } 1312 1313 ap->type = CKA_SIGN; 1314 ap++; 1315 count++; 1316 break; 1317 default: 1318 count = 0; 1319 extra_count = 0; 1320 break; 1321 } 1322 1323 if (count == 0) { 1324 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 1325 return NULL; 1326 } 1327 1328 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 1329 if (arena == NULL) 1330 return NULL; 1331 /* 1332 * read out the old attributes. 1333 */ 1334 crv = PK11_GetAttributes(arena, privKey->pkcs11Slot, privKey->pkcs11ID, 1335 privTemplate, count); 1336 if (crv != CKR_OK) { 1337 PORT_SetError(PK11_MapError(crv)); 1338 PORT_FreeArena(arena, PR_TRUE); 1339 return NULL; 1340 } 1341 1342 /* Set token, private, modifiable, sensitive, and extractable */ 1343 count += pk11_AttrFlagsToAttributes(attrFlags, &privTemplate[count], 1344 &cktrue, &ckfalse); 1345 1346 /* Not everyone can handle zero padded key values, give 1347 * them the raw data as unsigned. Where the values are encoded or 1348 * zero-preserving per-RFC5915. NOTE Most new algorithms are 1349 * OCTET strings, not signed integers, so this conversion 1350 * isn't necessary for them. */ 1351 if (extra_count) { 1352 for (ap = attrs; extra_count; ap++, extra_count--) { 1353 pk11_SignedToUnsigned(ap); 1354 } 1355 } 1356 1357 /* now Store the puppies */ 1358 rv = PK11_CreateNewObject(slot, CK_INVALID_HANDLE, privTemplate, 1359 count, token, &objectID); 1360 PORT_FreeArena(arena, PR_TRUE); 1361 if (rv != SECSuccess) { 1362 return NULL; 1363 } 1364 1365 /* try loading the public key */ 1366 if (pubKey) { 1367 PK11_ImportPublicKey(slot, pubKey, token); 1368 if (pubKey->pkcs11Slot) { 1369 PK11_FreeSlot(pubKey->pkcs11Slot); 1370 pubKey->pkcs11Slot = NULL; 1371 pubKey->pkcs11ID = CK_INVALID_HANDLE; 1372 } 1373 } 1374 1375 /* build new key structure */ 1376 return PK11_MakePrivKey(slot, privKey->keyType, !token, 1377 objectID, privKey->wincx); 1378 } 1379 1380 static SECKEYPrivateKey * 1381 pk11_loadPrivKey(PK11SlotInfo *slot, SECKEYPrivateKey *privKey, 1382 SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive) 1383 { 1384 PK11AttrFlags attrFlags = 0; 1385 if (token) { 1386 attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE); 1387 } else { 1388 attrFlags |= (PK11_ATTR_SESSION | PK11_ATTR_PUBLIC); 1389 } 1390 if (sensitive) { 1391 attrFlags |= PK11_ATTR_SENSITIVE; 1392 } else { 1393 attrFlags |= PK11_ATTR_INSENSITIVE; 1394 } 1395 return pk11_loadPrivKeyWithFlags(slot, privKey, pubKey, attrFlags); 1396 } 1397 1398 /* 1399 * export this for PSM 1400 */ 1401 SECKEYPrivateKey * 1402 PK11_LoadPrivKey(PK11SlotInfo *slot, SECKEYPrivateKey *privKey, 1403 SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive) 1404 { 1405 return pk11_loadPrivKey(slot, privKey, pubKey, token, sensitive); 1406 } 1407 1408 /* 1409 * Use the token to generate a key pair. 1410 */ 1411 SECKEYPrivateKey * 1412 PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, 1413 void *param, SECKEYPublicKey **pubKey, PK11AttrFlags attrFlags, 1414 CK_FLAGS opFlags, CK_FLAGS opFlagsMask, void *wincx) 1415 { 1416 /* we have to use these native types because when we call PKCS 11 modules 1417 * we have to make sure that we are using the correct sizes for all the 1418 * parameters. */ 1419 CK_BBOOL ckfalse = CK_FALSE; 1420 CK_BBOOL cktrue = CK_TRUE; 1421 CK_ULONG modulusBits; 1422 CK_BYTE publicExponent[4]; 1423 CK_ATTRIBUTE privTemplate[] = { 1424 { CKA_SENSITIVE, NULL, 0 }, 1425 { CKA_TOKEN, NULL, 0 }, 1426 { CKA_PRIVATE, NULL, 0 }, 1427 { CKA_DERIVE, NULL, 0 }, 1428 { CKA_UNWRAP, NULL, 0 }, 1429 { CKA_SIGN, NULL, 0 }, 1430 { CKA_DECRYPT, NULL, 0 }, 1431 { CKA_EXTRACTABLE, NULL, 0 }, 1432 { CKA_MODIFIABLE, NULL, 0 }, 1433 { CKA_DECAPSULATE, NULL, 0 }, 1434 }; 1435 CK_ATTRIBUTE rsaPubTemplate[] = { 1436 { CKA_MODULUS_BITS, NULL, 0 }, 1437 { CKA_PUBLIC_EXPONENT, NULL, 0 }, 1438 { CKA_TOKEN, NULL, 0 }, 1439 { CKA_DERIVE, NULL, 0 }, 1440 { CKA_WRAP, NULL, 0 }, 1441 { CKA_VERIFY, NULL, 0 }, 1442 { CKA_VERIFY_RECOVER, NULL, 0 }, 1443 { CKA_ENCRYPT, NULL, 0 }, 1444 { CKA_MODIFIABLE, NULL, 0 }, 1445 { CKA_ENCAPSULATE, NULL, 0 }, 1446 }; 1447 CK_ATTRIBUTE dsaPubTemplate[] = { 1448 { CKA_PRIME, NULL, 0 }, 1449 { CKA_SUBPRIME, NULL, 0 }, 1450 { CKA_BASE, NULL, 0 }, 1451 { CKA_TOKEN, NULL, 0 }, 1452 { CKA_DERIVE, NULL, 0 }, 1453 { CKA_WRAP, NULL, 0 }, 1454 { CKA_VERIFY, NULL, 0 }, 1455 { CKA_VERIFY_RECOVER, NULL, 0 }, 1456 { CKA_ENCRYPT, NULL, 0 }, 1457 { CKA_MODIFIABLE, NULL, 0 }, 1458 { CKA_ENCAPSULATE, NULL, 0 }, 1459 }; 1460 CK_ATTRIBUTE dhPubTemplate[] = { 1461 { CKA_PRIME, NULL, 0 }, 1462 { CKA_BASE, NULL, 0 }, 1463 { CKA_TOKEN, NULL, 0 }, 1464 { CKA_DERIVE, NULL, 0 }, 1465 { CKA_WRAP, NULL, 0 }, 1466 { CKA_VERIFY, NULL, 0 }, 1467 { CKA_VERIFY_RECOVER, NULL, 0 }, 1468 { CKA_ENCRYPT, NULL, 0 }, 1469 { CKA_MODIFIABLE, NULL, 0 }, 1470 { CKA_ENCAPSULATE, NULL, 0 }, 1471 }; 1472 CK_ATTRIBUTE ecPubTemplate[] = { 1473 { CKA_EC_PARAMS, NULL, 0 }, 1474 { CKA_TOKEN, NULL, 0 }, 1475 { CKA_DERIVE, NULL, 0 }, 1476 { CKA_WRAP, NULL, 0 }, 1477 { CKA_VERIFY, NULL, 0 }, 1478 { CKA_VERIFY_RECOVER, NULL, 0 }, 1479 { CKA_ENCRYPT, NULL, 0 }, 1480 { CKA_MODIFIABLE, NULL, 0 }, 1481 { CKA_ENCAPSULATE, NULL, 0 }, 1482 }; 1483 SECKEYECParams *ecParams; 1484 1485 CK_ATTRIBUTE mlDsaPubTemplate[] = { 1486 { CKA_PARAMETER_SET, NULL, 0 }, 1487 { CKA_TOKEN, NULL, 0 }, 1488 { CKA_DERIVE, NULL, 0 }, 1489 { CKA_WRAP, NULL, 0 }, 1490 { CKA_VERIFY, NULL, 0 }, 1491 { CKA_VERIFY_RECOVER, NULL, 0 }, 1492 { CKA_ENCRYPT, NULL, 0 }, 1493 { CKA_MODIFIABLE, NULL, 0 }, 1494 }; 1495 1496 CK_ATTRIBUTE kyberPubTemplate[] = { 1497 { CKA_NSS_PARAMETER_SET, NULL, 0 }, 1498 { CKA_TOKEN, NULL, 0 }, 1499 { CKA_DERIVE, NULL, 0 }, 1500 { CKA_WRAP, NULL, 0 }, 1501 { CKA_VERIFY, NULL, 0 }, 1502 { CKA_VERIFY_RECOVER, NULL, 0 }, 1503 { CKA_ENCRYPT, NULL, 0 }, 1504 { CKA_MODIFIABLE, NULL, 0 }, 1505 { CKA_ENCAPSULATE, NULL, 0 }, 1506 }; 1507 1508 /*CK_ULONG key_size = 0;*/ 1509 CK_ATTRIBUTE *pubTemplate; 1510 int privCount = 0; 1511 int pubCount = 0; 1512 PK11RSAGenParams *rsaParams; 1513 SECKEYPQGParams *dsaParams; 1514 SECKEYDHParams *dhParams; 1515 CK_NSS_KEM_PARAMETER_SET_TYPE *kemParams; 1516 CK_ML_DSA_PARAMETER_SET_TYPE *mldsaParams; 1517 CK_MECHANISM mechanism; 1518 CK_MECHANISM test_mech; 1519 CK_MECHANISM test_mech2; 1520 CK_SESSION_HANDLE session_handle; 1521 CK_RV crv; 1522 CK_OBJECT_HANDLE privID, pubID; 1523 SECKEYPrivateKey *privKey; 1524 KeyType keyType; 1525 PRBool restore; 1526 int peCount, i; 1527 CK_ATTRIBUTE *attrs; 1528 CK_ATTRIBUTE *privattrs; 1529 CK_ATTRIBUTE setTemplate; 1530 CK_MECHANISM_INFO mechanism_info; 1531 CK_OBJECT_CLASS keyClass; 1532 SECItem *cka_id; 1533 PRBool haslock = PR_FALSE; 1534 PRBool pubIsToken = PR_FALSE; 1535 PRBool token = ((attrFlags & PK11_ATTR_TOKEN) != 0); 1536 /* subset of attrFlags applicable to the public key */ 1537 PK11AttrFlags pubKeyAttrFlags = attrFlags & 1538 (PK11_ATTR_TOKEN | PK11_ATTR_SESSION | PK11_ATTR_MODIFIABLE | PK11_ATTR_UNMODIFIABLE); 1539 1540 if (pk11_BadAttrFlags(attrFlags)) { 1541 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1542 return NULL; 1543 } 1544 1545 if (!param) { 1546 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1547 return NULL; 1548 } 1549 1550 /* 1551 * The opFlags and opFlagMask parameters allow us to control the 1552 * settings of the key usage attributes (CKA_ENCRYPT and friends). 1553 * opFlagMask is set to one if the flag is specified in opFlags and 1554 * zero if it is to take on a default value calculated by 1555 * PK11_GenerateKeyPairWithOpFlags. 1556 * opFlags specifies the actual value of the flag 1 or 0. 1557 * Bits not corresponding to one bits in opFlagMask should be zero. 1558 */ 1559 1560 /* if we are trying to turn on a flag, it better be in the mask */ 1561 PORT_Assert((opFlags & ~opFlagsMask) == 0); 1562 opFlags &= opFlagsMask; 1563 1564 PORT_Assert(slot != NULL); 1565 if (slot == NULL) { 1566 PORT_SetError(SEC_ERROR_NO_MODULE); 1567 return NULL; 1568 } 1569 1570 /* if our slot really doesn't do this mechanism, Generate the key 1571 * in our internal token and write it out */ 1572 if (!PK11_DoesMechanism(slot, type)) { 1573 PK11SlotInfo *int_slot = PK11_GetInternalSlot(); 1574 1575 /* don't loop forever looking for a slot */ 1576 if (slot == int_slot) { 1577 PK11_FreeSlot(int_slot); 1578 /* if we don't have support in softoken, then the mechanism 1579 * just isnt' supported */ 1580 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 1581 return NULL; 1582 } 1583 1584 /* if there isn't a suitable slot, then we can't do the keygen */ 1585 if (int_slot == NULL) { 1586 PORT_SetError(SEC_ERROR_NO_MODULE); 1587 return NULL; 1588 } 1589 1590 /* generate the temporary key to load */ 1591 privKey = PK11_GenerateKeyPair(int_slot, type, param, pubKey, PR_FALSE, 1592 PR_FALSE, wincx); 1593 PK11_FreeSlot(int_slot); 1594 1595 /* if successful, load the temp key into the new token */ 1596 if (privKey != NULL) { 1597 SECKEYPrivateKey *newPrivKey = pk11_loadPrivKeyWithFlags(slot, 1598 privKey, *pubKey, attrFlags); 1599 SECKEY_DestroyPrivateKey(privKey); 1600 if (newPrivKey == NULL) { 1601 SECKEY_DestroyPublicKey(*pubKey); 1602 *pubKey = NULL; 1603 } 1604 return newPrivKey; 1605 } 1606 return NULL; 1607 } 1608 1609 mechanism.mechanism = type; 1610 mechanism.pParameter = NULL; 1611 mechanism.ulParameterLen = 0; 1612 test_mech.pParameter = NULL; 1613 test_mech.ulParameterLen = 0; 1614 test_mech2.mechanism = CKM_INVALID_MECHANISM; 1615 test_mech2.pParameter = NULL; 1616 test_mech2.ulParameterLen = 0; 1617 1618 /* set up the private key template */ 1619 privattrs = privTemplate; 1620 privattrs += pk11_AttrFlagsToAttributes(attrFlags, privattrs, 1621 &cktrue, &ckfalse); 1622 1623 /* set up the mechanism specific info */ 1624 switch (type) { 1625 case CKM_RSA_PKCS_KEY_PAIR_GEN: 1626 case CKM_RSA_X9_31_KEY_PAIR_GEN: 1627 rsaParams = (PK11RSAGenParams *)param; 1628 if (rsaParams->pe == 0) { 1629 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1630 return NULL; 1631 } 1632 modulusBits = rsaParams->keySizeInBits; 1633 peCount = 0; 1634 1635 /* convert pe to a PKCS #11 string */ 1636 for (i = 0; i < 4; i++) { 1637 if (peCount || (rsaParams->pe & 1638 ((unsigned long)0xff000000L >> (i * 8)))) { 1639 publicExponent[peCount] = 1640 (CK_BYTE)((rsaParams->pe >> (3 - i) * 8) & 0xff); 1641 peCount++; 1642 } 1643 } 1644 PORT_Assert(peCount != 0); 1645 attrs = rsaPubTemplate; 1646 PK11_SETATTRS(attrs, CKA_MODULUS_BITS, 1647 &modulusBits, sizeof(modulusBits)); 1648 attrs++; 1649 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, 1650 publicExponent, peCount); 1651 attrs++; 1652 pubTemplate = rsaPubTemplate; 1653 keyType = rsaKey; 1654 test_mech.mechanism = CKM_RSA_PKCS; 1655 break; 1656 case CKM_DSA_KEY_PAIR_GEN: 1657 dsaParams = (SECKEYPQGParams *)param; 1658 attrs = dsaPubTemplate; 1659 PK11_SETATTRS(attrs, CKA_PRIME, dsaParams->prime.data, 1660 dsaParams->prime.len); 1661 attrs++; 1662 PK11_SETATTRS(attrs, CKA_SUBPRIME, dsaParams->subPrime.data, 1663 dsaParams->subPrime.len); 1664 attrs++; 1665 PK11_SETATTRS(attrs, CKA_BASE, dsaParams->base.data, 1666 dsaParams->base.len); 1667 attrs++; 1668 pubTemplate = dsaPubTemplate; 1669 keyType = dsaKey; 1670 test_mech.mechanism = CKM_DSA; 1671 break; 1672 case CKM_DH_PKCS_KEY_PAIR_GEN: 1673 dhParams = (SECKEYDHParams *)param; 1674 attrs = dhPubTemplate; 1675 PK11_SETATTRS(attrs, CKA_PRIME, dhParams->prime.data, 1676 dhParams->prime.len); 1677 attrs++; 1678 PK11_SETATTRS(attrs, CKA_BASE, dhParams->base.data, 1679 dhParams->base.len); 1680 attrs++; 1681 pubTemplate = dhPubTemplate; 1682 keyType = dhKey; 1683 test_mech.mechanism = CKM_DH_PKCS_DERIVE; 1684 break; 1685 case CKM_EC_KEY_PAIR_GEN: 1686 case CKM_NSS_ECDHE_NO_PAIRWISE_CHECK_KEY_PAIR_GEN: 1687 ecParams = (SECKEYECParams *)param; 1688 attrs = ecPubTemplate; 1689 PK11_SETATTRS(attrs, CKA_EC_PARAMS, ecParams->data, 1690 ecParams->len); 1691 attrs++; 1692 pubTemplate = ecPubTemplate; 1693 keyType = ecKey; 1694 /* 1695 * ECC supports 2 different mechanism types (unlike RSA, which 1696 * supports different usages with the same mechanism). 1697 * We may need to query both mechanism types and or the results 1698 * together -- but we only do that if either the user has 1699 * requested both usages, or not specified any usages. 1700 */ 1701 if ((opFlags & (CKF_SIGN | CKF_DERIVE)) == (CKF_SIGN | CKF_DERIVE)) { 1702 /* We've explicitly turned on both flags, use both mechanism */ 1703 test_mech.mechanism = CKM_ECDH1_DERIVE; 1704 test_mech2.mechanism = CKM_ECDSA; 1705 } else if (opFlags & CKF_SIGN) { 1706 /* just do signing */ 1707 test_mech.mechanism = CKM_ECDSA; 1708 } else if (opFlags & CKF_DERIVE) { 1709 /* just do ECDH */ 1710 test_mech.mechanism = CKM_ECDH1_DERIVE; 1711 } else { 1712 /* neither was specified default to both */ 1713 test_mech.mechanism = CKM_ECDH1_DERIVE; 1714 test_mech2.mechanism = CKM_ECDSA; 1715 } 1716 break; 1717 #ifndef NSS_DISABLE_KYBER 1718 case CKM_NSS_KYBER_KEY_PAIR_GEN: 1719 #endif 1720 case CKM_NSS_ML_KEM_KEY_PAIR_GEN: 1721 case CKM_ML_KEM_KEY_PAIR_GEN: 1722 kemParams = (CK_NSS_KEM_PARAMETER_SET_TYPE *)param; 1723 attrs = kyberPubTemplate; 1724 PK11_SETATTRS(attrs, CKA_PARAMETER_SET, 1725 kemParams, 1726 sizeof(CK_NSS_KEM_PARAMETER_SET_TYPE)); 1727 attrs++; 1728 pubTemplate = kyberPubTemplate; 1729 keyType = kyberKey; 1730 test_mech.mechanism = CKM_ML_KEM; 1731 break; 1732 case CKM_EC_MONTGOMERY_KEY_PAIR_GEN: 1733 ecParams = (SECKEYECParams *)param; 1734 attrs = ecPubTemplate; 1735 PK11_SETATTRS(attrs, CKA_EC_PARAMS, ecParams->data, 1736 ecParams->len); 1737 attrs++; 1738 pubTemplate = ecPubTemplate; 1739 keyType = ecMontKey; 1740 test_mech.mechanism = CKM_ECDH1_DERIVE; 1741 break; 1742 case CKM_EC_EDWARDS_KEY_PAIR_GEN: 1743 ecParams = (SECKEYECParams *)param; 1744 attrs = ecPubTemplate; 1745 PK11_SETATTRS(attrs, CKA_EC_PARAMS, ecParams->data, 1746 ecParams->len); 1747 attrs++; 1748 pubTemplate = ecPubTemplate; 1749 keyType = edKey; 1750 test_mech.mechanism = CKM_EDDSA; 1751 break; 1752 case CKM_ML_DSA_KEY_PAIR_GEN: 1753 mldsaParams = (CK_ML_DSA_PARAMETER_SET_TYPE *)param; 1754 attrs = mlDsaPubTemplate; 1755 PK11_SETATTRS(attrs, 1756 CKA_PARAMETER_SET, 1757 mldsaParams, 1758 sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)); 1759 attrs++; 1760 pubTemplate = mlDsaPubTemplate; 1761 keyType = mldsaKey; 1762 test_mech.mechanism = CKM_ML_DSA; 1763 break; 1764 default: 1765 PORT_SetError(SEC_ERROR_BAD_KEY); 1766 return NULL; 1767 } 1768 1769 /* now query the slot to find out how "good" a key we can generate */ 1770 if (!slot->isThreadSafe) 1771 PK11_EnterSlotMonitor(slot); 1772 crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID, 1773 test_mech.mechanism, &mechanism_info); 1774 /* 1775 * EC keys are used in multiple different types of mechanism, if we 1776 * are using dual use keys, we need to query the second mechanism 1777 * as well. 1778 */ 1779 if (test_mech2.mechanism != CKM_INVALID_MECHANISM) { 1780 CK_MECHANISM_INFO mechanism_info2; 1781 CK_RV crv2; 1782 1783 if (crv != CKR_OK) { 1784 /* the first failed, make sure there is no trash in the 1785 * mechanism flags when we or it below */ 1786 mechanism_info.flags = 0; 1787 } 1788 crv2 = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID, 1789 test_mech2.mechanism, &mechanism_info2); 1790 if (crv2 == CKR_OK) { 1791 crv = CKR_OK; /* succeed if either mechnaism info succeeds */ 1792 /* combine the 2 sets of mechnanism flags */ 1793 mechanism_info.flags |= mechanism_info2.flags; 1794 } 1795 } 1796 if (!slot->isThreadSafe) 1797 PK11_ExitSlotMonitor(slot); 1798 if ((crv != CKR_OK) || (mechanism_info.flags == 0)) { 1799 /* must be old module... guess what it should be... */ 1800 switch (test_mech.mechanism) { 1801 case CKM_RSA_PKCS: 1802 mechanism_info.flags = (CKF_SIGN | CKF_DECRYPT | 1803 CKF_WRAP | CKF_VERIFY_RECOVER | CKF_ENCRYPT | CKF_WRAP); 1804 break; 1805 case CKM_DSA: 1806 case CKM_ECDSA: 1807 case CKM_EDDSA: 1808 case CKM_ML_DSA: 1809 mechanism_info.flags = CKF_SIGN | CKF_VERIFY; 1810 break; 1811 case CKM_DH_PKCS_DERIVE: 1812 mechanism_info.flags = CKF_DERIVE; 1813 break; 1814 case CKM_ECDH1_DERIVE: 1815 mechanism_info.flags = CKF_DERIVE; 1816 if (test_mech2.mechanism == CKM_ECDSA) { 1817 mechanism_info.flags |= CKF_SIGN | CKF_VERIFY; 1818 } 1819 break; 1820 case CKM_NSS_KYBER: 1821 case CKM_NSS_ML_KEM: 1822 case CKM_ML_KEM: 1823 mechanism_info.flags = CKF_ENCAPSULATE | CKF_DECAPSULATE; 1824 break; 1825 default: 1826 break; 1827 } 1828 } 1829 /* now adjust our flags according to the user's key usage passed to us */ 1830 mechanism_info.flags = (mechanism_info.flags & (~opFlagsMask)) | opFlags; 1831 /* set the public key attributes */ 1832 attrs += pk11_AttrFlagsToAttributes(pubKeyAttrFlags, attrs, 1833 &cktrue, &ckfalse); 1834 PK11_SETATTRS(attrs, CKA_DERIVE, 1835 mechanism_info.flags & CKF_DERIVE ? &cktrue : &ckfalse, 1836 sizeof(CK_BBOOL)); 1837 attrs++; 1838 PK11_SETATTRS(attrs, CKA_WRAP, 1839 mechanism_info.flags & CKF_WRAP ? &cktrue : &ckfalse, 1840 sizeof(CK_BBOOL)); 1841 attrs++; 1842 PK11_SETATTRS(attrs, CKA_VERIFY, 1843 mechanism_info.flags & CKF_VERIFY ? &cktrue : &ckfalse, 1844 sizeof(CK_BBOOL)); 1845 attrs++; 1846 PK11_SETATTRS(attrs, CKA_VERIFY_RECOVER, 1847 mechanism_info.flags & CKF_VERIFY_RECOVER ? &cktrue : &ckfalse, 1848 sizeof(CK_BBOOL)); 1849 attrs++; 1850 PK11_SETATTRS(attrs, CKA_ENCRYPT, 1851 mechanism_info.flags & CKF_ENCRYPT ? &cktrue : &ckfalse, 1852 sizeof(CK_BBOOL)); 1853 attrs++; 1854 /* only set encapsulate if it's requested and shows up in the mechanism 1855 * list, that way we don't confuse pre-3.2 PKCS #11 modules */ 1856 if (mechanism_info.flags & CKF_ENCAPSULATE) { 1857 PK11_SETATTRS(attrs, CKA_ENCAPSULATE, &cktrue, sizeof(CK_BBOOL)); 1858 attrs++; 1859 } 1860 1861 /* set the private key attributes */ 1862 PK11_SETATTRS(privattrs, CKA_DERIVE, 1863 mechanism_info.flags & CKF_DERIVE ? &cktrue : &ckfalse, 1864 sizeof(CK_BBOOL)); 1865 privattrs++; 1866 PK11_SETATTRS(privattrs, CKA_UNWRAP, 1867 mechanism_info.flags & CKF_UNWRAP ? &cktrue : &ckfalse, 1868 sizeof(CK_BBOOL)); 1869 privattrs++; 1870 PK11_SETATTRS(privattrs, CKA_SIGN, 1871 mechanism_info.flags & CKF_SIGN ? &cktrue : &ckfalse, 1872 sizeof(CK_BBOOL)); 1873 privattrs++; 1874 PK11_SETATTRS(privattrs, CKA_DECRYPT, 1875 mechanism_info.flags & CKF_DECRYPT ? &cktrue : &ckfalse, 1876 sizeof(CK_BBOOL)); 1877 privattrs++; 1878 /* only set it if the attribute exists so we don't confuse old modules */ 1879 if (mechanism_info.flags & CKF_DECAPSULATE) { 1880 PK11_SETATTRS(privattrs, CKA_DECAPSULATE, &cktrue, sizeof(CK_BBOOL)); 1881 privattrs++; 1882 } 1883 1884 if (token) { 1885 session_handle = PK11_GetRWSession(slot); 1886 haslock = PK11_RWSessionHasLock(slot, session_handle); 1887 restore = PR_TRUE; 1888 } else { 1889 session_handle = slot->session; 1890 if (session_handle != CK_INVALID_HANDLE) 1891 PK11_EnterSlotMonitor(slot); 1892 restore = PR_FALSE; 1893 haslock = PR_TRUE; 1894 } 1895 1896 if (session_handle == CK_INVALID_HANDLE) { 1897 PORT_SetError(SEC_ERROR_BAD_DATA); 1898 return NULL; 1899 } 1900 privCount = privattrs - privTemplate; 1901 pubCount = attrs - pubTemplate; 1902 crv = PK11_GETTAB(slot)->C_GenerateKeyPair(session_handle, &mechanism, 1903 pubTemplate, pubCount, privTemplate, privCount, &pubID, &privID); 1904 1905 if (crv != CKR_OK) { 1906 if (restore) { 1907 PK11_RestoreROSession(slot, session_handle); 1908 } else 1909 PK11_ExitSlotMonitor(slot); 1910 PORT_SetError(PK11_MapError(crv)); 1911 return NULL; 1912 } 1913 /* This locking code is dangerous and needs to be more thought 1914 * out... the real problem is that we're holding the mutex open this long 1915 */ 1916 if (haslock) { 1917 PK11_ExitSlotMonitor(slot); 1918 } 1919 1920 /* swap around the ID's for older PKCS #11 modules */ 1921 keyClass = PK11_ReadULongAttribute(slot, pubID, CKA_CLASS); 1922 if (keyClass != CKO_PUBLIC_KEY) { 1923 CK_OBJECT_HANDLE tmp = pubID; 1924 pubID = privID; 1925 privID = tmp; 1926 } 1927 1928 *pubKey = PK11_ExtractPublicKey(slot, keyType, pubID); 1929 if (*pubKey == NULL) { 1930 if (restore) { 1931 /* we may have to restore the mutex so it get's exited properly 1932 * in RestoreROSession */ 1933 if (haslock) 1934 PK11_EnterSlotMonitor(slot); 1935 PK11_RestoreROSession(slot, session_handle); 1936 } 1937 PK11_DestroyObject(slot, pubID); 1938 PK11_DestroyObject(slot, privID); 1939 return NULL; 1940 } 1941 1942 /* set the ID to the public key so we can find it again */ 1943 cka_id = pk11_MakeIDFromPublicKey(*pubKey); 1944 pubIsToken = (PRBool)PK11_HasAttributeSet(slot, pubID, CKA_TOKEN, PR_FALSE); 1945 1946 PK11_SETATTRS(&setTemplate, CKA_ID, cka_id->data, cka_id->len); 1947 1948 if (haslock) { 1949 PK11_EnterSlotMonitor(slot); 1950 } 1951 crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, privID, 1952 &setTemplate, 1); 1953 1954 if (crv == CKR_OK && pubIsToken) { 1955 crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, pubID, 1956 &setTemplate, 1); 1957 } 1958 1959 if (restore) { 1960 PK11_RestoreROSession(slot, session_handle); 1961 } else { 1962 PK11_ExitSlotMonitor(slot); 1963 } 1964 SECITEM_FreeItem(cka_id, PR_TRUE); 1965 1966 if (crv != CKR_OK) { 1967 PK11_DestroyObject(slot, pubID); 1968 PK11_DestroyObject(slot, privID); 1969 PORT_SetError(PK11_MapError(crv)); 1970 *pubKey = NULL; 1971 return NULL; 1972 } 1973 1974 privKey = PK11_MakePrivKey(slot, keyType, !token, privID, wincx); 1975 if (privKey == NULL) { 1976 SECKEY_DestroyPublicKey(*pubKey); 1977 PK11_DestroyObject(slot, privID); 1978 *pubKey = NULL; 1979 return NULL; 1980 } 1981 1982 return privKey; 1983 } 1984 1985 SECKEYPrivateKey * 1986 PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, 1987 void *param, SECKEYPublicKey **pubKey, PK11AttrFlags attrFlags, void *wincx) 1988 { 1989 return PK11_GenerateKeyPairWithOpFlags(slot, type, param, pubKey, attrFlags, 1990 0, 0, wincx); 1991 } 1992 1993 /* 1994 * Use the token to generate a key pair. 1995 */ 1996 SECKEYPrivateKey * 1997 PK11_GenerateKeyPair(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, 1998 void *param, SECKEYPublicKey **pubKey, PRBool token, 1999 PRBool sensitive, void *wincx) 2000 { 2001 PK11AttrFlags attrFlags = 0; 2002 2003 if (token) { 2004 attrFlags |= PK11_ATTR_TOKEN; 2005 } else { 2006 attrFlags |= PK11_ATTR_SESSION; 2007 } 2008 if (sensitive) { 2009 attrFlags |= (PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE); 2010 } else { 2011 attrFlags |= (PK11_ATTR_INSENSITIVE | PK11_ATTR_PUBLIC); 2012 } 2013 return PK11_GenerateKeyPairWithFlags(slot, type, param, pubKey, 2014 attrFlags, wincx); 2015 } 2016 2017 /* build a public KEA key from the public value */ 2018 SECKEYPublicKey * 2019 PK11_MakeKEAPubKey(unsigned char *keyData, int length) 2020 { 2021 SECKEYPublicKey *pubk; 2022 SECItem pkData; 2023 SECStatus rv; 2024 PLArenaPool *arena; 2025 2026 pkData.data = keyData; 2027 pkData.len = length; 2028 pkData.type = siBuffer; 2029 2030 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 2031 if (arena == NULL) 2032 return NULL; 2033 2034 pubk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey)); 2035 if (pubk == NULL) { 2036 PORT_FreeArena(arena, PR_FALSE); 2037 return NULL; 2038 } 2039 2040 pubk->arena = arena; 2041 pubk->pkcs11Slot = 0; 2042 pubk->pkcs11ID = CK_INVALID_HANDLE; 2043 pubk->keyType = fortezzaKey; 2044 rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.KEAKey, &pkData); 2045 if (rv != SECSuccess) { 2046 PORT_FreeArena(arena, PR_FALSE); 2047 return NULL; 2048 } 2049 return pubk; 2050 } 2051 2052 SECStatus 2053 SECKEY_SetPublicValue(SECKEYPrivateKey *privKey, const SECItem *publicValue) 2054 { 2055 SECStatus rv; 2056 SECKEYPublicKey pubKey; 2057 PLArenaPool *arena; 2058 PK11SlotInfo *slot; 2059 CK_OBJECT_HANDLE privKeyID; 2060 CK_ULONG paramSet; 2061 2062 if (privKey == NULL || publicValue == NULL || 2063 publicValue->data == NULL || publicValue->len == 0) { 2064 PORT_SetError(SEC_ERROR_INVALID_ARGS); 2065 return SECFailure; 2066 } 2067 2068 pubKey.arena = NULL; 2069 pubKey.keyType = privKey->keyType; 2070 pubKey.pkcs11Slot = NULL; 2071 pubKey.pkcs11ID = CK_INVALID_HANDLE; 2072 /* can't use PORT_InitCheapArena here becase SECKEY_DestroyPublic is used 2073 * to free it, and it uses PORT_FreeArena which not only frees the 2074 * underlying arena, it also frees the allocated arena struct. */ 2075 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 2076 pubKey.arena = arena; 2077 if (arena == NULL) { 2078 return SECFailure; 2079 } 2080 2081 slot = privKey->pkcs11Slot; 2082 privKeyID = privKey->pkcs11ID; 2083 rv = SECFailure; 2084 switch (privKey->keyType) { 2085 default: 2086 /* error code already set to SECFailure */ 2087 break; 2088 case rsaKey: 2089 pubKey.u.rsa.modulus = *publicValue; 2090 rv = PK11_ReadAttribute(slot, privKeyID, CKA_PUBLIC_EXPONENT, 2091 arena, &pubKey.u.rsa.publicExponent); 2092 break; 2093 case dsaKey: 2094 pubKey.u.dsa.publicValue = *publicValue; 2095 rv = PK11_ReadAttribute(slot, privKeyID, CKA_PRIME, 2096 arena, &pubKey.u.dsa.params.prime); 2097 if (rv != SECSuccess) { 2098 break; 2099 } 2100 rv = PK11_ReadAttribute(slot, privKeyID, CKA_SUBPRIME, 2101 arena, &pubKey.u.dsa.params.subPrime); 2102 if (rv != SECSuccess) { 2103 break; 2104 } 2105 rv = PK11_ReadAttribute(slot, privKeyID, CKA_BASE, 2106 arena, &pubKey.u.dsa.params.base); 2107 break; 2108 case dhKey: 2109 pubKey.u.dh.publicValue = *publicValue; 2110 rv = PK11_ReadAttribute(slot, privKeyID, CKA_PRIME, 2111 arena, &pubKey.u.dh.prime); 2112 if (rv != SECSuccess) { 2113 break; 2114 } 2115 rv = PK11_ReadAttribute(slot, privKeyID, CKA_BASE, 2116 arena, &pubKey.u.dh.base); 2117 break; 2118 case ecKey: 2119 case edKey: 2120 case ecMontKey: 2121 pubKey.u.ec.publicValue = *publicValue; 2122 pubKey.u.ec.encoding = ECPoint_Undefined; 2123 pubKey.u.ec.size = 0; 2124 rv = PK11_ReadAttribute(slot, privKeyID, CKA_EC_PARAMS, 2125 arena, &pubKey.u.ec.DEREncodedParams); 2126 break; 2127 case mldsaKey: 2128 pubKey.u.mldsa.publicValue = *publicValue; 2129 paramSet = PK11_ReadULongAttribute(slot, privKeyID, 2130 CKA_PARAMETER_SET); 2131 if (paramSet == CK_UNAVAILABLE_INFORMATION) { 2132 PORT_SetError(SEC_ERROR_BAD_KEY); 2133 break; 2134 } 2135 pubKey.u.mldsa.paramSet = SECKEY_GetMLDSAPkcs11ParamSetByOidTag(paramSet); 2136 if (pubKey.u.mldsa.paramSet == SEC_OID_UNKNOWN) { 2137 PORT_SetError(SEC_ERROR_BAD_KEY); 2138 break; 2139 } 2140 rv = SECSuccess; 2141 break; 2142 } 2143 if (rv == SECSuccess) { 2144 rv = PK11_ImportPublicKey(slot, &pubKey, PR_TRUE); 2145 } 2146 /* Even though pubKey is stored on the stack, we've allocated 2147 * some of it's data from the arena. SECKEY_DestroyPublicKey 2148 * destroys keys by freeing the arena, so this will clean up all 2149 * the data we allocated specifically for the key above. It will 2150 * also free any slot references which we may have picked up in 2151 * PK11_ImportPublicKey. It won't delete the underlying key if 2152 * its a Token/Permanent key (which it will be if 2153 * PK11_ImportPublicKey succeeds). */ 2154 SECKEY_DestroyPublicKey(&pubKey); 2155 2156 return rv; 2157 } 2158 2159 /* 2160 * NOTE: This function doesn't return a SECKEYPrivateKey struct to represent 2161 * the new private key object. If it were to create a session object that 2162 * could later be looked up by its nickname, it would leak a SECKEYPrivateKey. 2163 * So isPerm must be true. 2164 */ 2165 SECStatus 2166 PK11_ImportEncryptedPrivateKeyInfo(PK11SlotInfo *slot, 2167 SECKEYEncryptedPrivateKeyInfo *epki, SECItem *pwitem, 2168 SECItem *nickname, const SECItem *publicValue, PRBool isPerm, 2169 PRBool isPrivate, KeyType keyType, 2170 unsigned int keyUsage, void *wincx) 2171 { 2172 if (!isPerm) { 2173 PORT_SetError(SEC_ERROR_INVALID_ARGS); 2174 return SECFailure; 2175 } 2176 return PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(slot, epki, 2177 pwitem, nickname, publicValue, isPerm, isPrivate, keyType, 2178 keyUsage, NULL, wincx); 2179 } 2180 2181 SECStatus 2182 PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, 2183 SECKEYEncryptedPrivateKeyInfo *epki, SECItem *pwitem, 2184 SECItem *nickname, const SECItem *publicValue, PRBool isPerm, 2185 PRBool isPrivate, KeyType keyType, 2186 unsigned int keyUsage, SECKEYPrivateKey **privk, 2187 void *wincx) 2188 { 2189 CK_MECHANISM_TYPE pbeMechType; 2190 SECItem *crypto_param = NULL; 2191 PK11SymKey *key = NULL; 2192 SECStatus rv = SECSuccess; 2193 CK_MECHANISM_TYPE cryptoMechType; 2194 SECKEYPrivateKey *privKey = NULL; 2195 PRBool faulty3DES = PR_FALSE; 2196 if ((epki == NULL) || (pwitem == NULL)) 2197 return SECFailure; 2198 2199 pbeMechType = PK11_AlgtagToMechanism(SECOID_FindOIDTag( 2200 &epki->algorithm.algorithm)); 2201 2202 try_faulty_3des: 2203 2204 key = PK11_PBEKeyGen(slot, &epki->algorithm, pwitem, faulty3DES, wincx); 2205 if (key == NULL) { 2206 rv = SECFailure; 2207 goto done; 2208 } 2209 cryptoMechType = pk11_GetPBECryptoMechanism(&epki->algorithm, 2210 &crypto_param, pwitem, faulty3DES); 2211 if (cryptoMechType == CKM_INVALID_MECHANISM) { 2212 rv = SECFailure; 2213 goto done; 2214 } 2215 2216 cryptoMechType = PK11_GetPadMechanism(cryptoMechType); 2217 2218 privKey = PK11_UnwrapPrivKeyByKeyType(slot, key, cryptoMechType, 2219 crypto_param, &epki->encryptedData, 2220 nickname, publicValue, isPerm, 2221 isPrivate, keyType, keyUsage, wincx); 2222 if (privKey) { 2223 rv = SECSuccess; 2224 goto done; 2225 } 2226 2227 /* if we are unable to import the key and the pbeMechType is 2228 * CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC, then it is possible that 2229 * the encrypted blob was created with a buggy key generation method 2230 * which is described in the PKCS 12 implementation notes. So we 2231 * need to try importing via that method. 2232 */ 2233 if ((pbeMechType == CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC) && (!faulty3DES)) { 2234 /* clean up after ourselves before redoing the key generation. */ 2235 2236 PK11_FreeSymKey(key); 2237 key = NULL; 2238 2239 if (crypto_param) { 2240 SECITEM_ZfreeItem(crypto_param, PR_TRUE); 2241 crypto_param = NULL; 2242 } 2243 2244 faulty3DES = PR_TRUE; 2245 goto try_faulty_3des; 2246 } 2247 2248 /* key import really did fail */ 2249 rv = SECFailure; 2250 2251 done: 2252 if ((rv == SECSuccess) && isPerm) { 2253 /* If we are importing a token object, 2254 * create the corresponding public key. 2255 * If this fails, just continue as the target 2256 * token simply might not support persistant 2257 * public keys. Such tokens are usable, but 2258 * need to be authenticated before searching 2259 * for user certs. */ 2260 (void)SECKEY_SetPublicValue(privKey, publicValue); 2261 } 2262 2263 if (privKey) { 2264 if (privk) { 2265 *privk = privKey; 2266 } else { 2267 SECKEY_DestroyPrivateKey(privKey); 2268 } 2269 privKey = NULL; 2270 } 2271 if (crypto_param != NULL) { 2272 SECITEM_ZfreeItem(crypto_param, PR_TRUE); 2273 } 2274 2275 if (key != NULL) { 2276 PK11_FreeSymKey(key); 2277 } 2278 2279 return rv; 2280 } 2281 2282 SECKEYPrivateKeyInfo * 2283 PK11_ExportPrivateKeyInfo(CERTCertificate *cert, void *wincx) 2284 { 2285 SECKEYPrivateKeyInfo *pki = NULL; 2286 SECKEYPrivateKey *pk = PK11_FindKeyByAnyCert(cert, wincx); 2287 if (pk != NULL) { 2288 pki = PK11_ExportPrivKeyInfo(pk, wincx); 2289 SECKEY_DestroyPrivateKey(pk); 2290 } 2291 return pki; 2292 } 2293 2294 /* V2 refers to PKCS #5 V2 here. If a PKCS #5 v1 or PKCS #12 pbe is passed 2295 * for pbeTag, then encTag and hashTag are ignored. If pbe is an encryption 2296 * algorithm, then PKCS #5 V2 is used with prfTag for the prf. If prfTag isn't 2297 * supplied prf will be SEC_OID_HMAC_SHA1 */ 2298 SECKEYEncryptedPrivateKeyInfo * 2299 PK11_ExportEncryptedPrivKeyInfoV2( 2300 PK11SlotInfo *slot, /* optional, encrypt key in this slot */ 2301 SECOidTag pbeAlg, /* PBE algorithm to encrypt the with key */ 2302 SECOidTag encAlg, /* Encryption algorithm to Encrypt the key with */ 2303 SECOidTag prfAlg, /* Hash algorithm for PRF */ 2304 SECItem *pwitem, /* password for PBE encryption */ 2305 SECKEYPrivateKey *pk, /* encrypt this private key */ 2306 int iteration, /* interations for PBE alg */ 2307 void *pwArg) /* context for password callback */ 2308 { 2309 SECKEYEncryptedPrivateKeyInfo *epki = NULL; 2310 PLArenaPool *arena = NULL; 2311 SECAlgorithmID *algid; 2312 SECOidTag pbeAlgTag = SEC_OID_UNKNOWN; 2313 SECItem *crypto_param = NULL; 2314 PK11SymKey *key = NULL; 2315 SECKEYPrivateKey *tmpPK = NULL; 2316 SECStatus rv = SECSuccess; 2317 CK_RV crv; 2318 CK_ULONG encBufLen; 2319 CK_MECHANISM_TYPE pbeMechType; 2320 CK_MECHANISM_TYPE cryptoMechType; 2321 CK_MECHANISM cryptoMech; 2322 2323 if (!pwitem || !pk) { 2324 PORT_SetError(SEC_ERROR_INVALID_ARGS); 2325 return NULL; 2326 } 2327 2328 algid = sec_pkcs5CreateAlgorithmID(pbeAlg, encAlg, prfAlg, 2329 &pbeAlgTag, 0, NULL, iteration); 2330 if (algid == NULL) { 2331 return NULL; 2332 } 2333 2334 arena = PORT_NewArena(2048); 2335 if (arena) 2336 epki = PORT_ArenaZNew(arena, SECKEYEncryptedPrivateKeyInfo); 2337 if (epki == NULL) { 2338 rv = SECFailure; 2339 goto loser; 2340 } 2341 epki->arena = arena; 2342 2343 /* if we didn't specify a slot, use the slot the private key was in */ 2344 if (!slot) { 2345 slot = pk->pkcs11Slot; 2346 } 2347 2348 /* if we specified a different slot, and the private key slot can do the 2349 * pbe key gen, generate the key in the private key slot so we don't have 2350 * to move it later */ 2351 pbeMechType = PK11_AlgtagToMechanism(pbeAlgTag); 2352 if (slot != pk->pkcs11Slot) { 2353 if (PK11_DoesMechanism(pk->pkcs11Slot, pbeMechType)) { 2354 slot = pk->pkcs11Slot; 2355 } 2356 } 2357 key = PK11_PBEKeyGen(slot, algid, pwitem, PR_FALSE, pwArg); 2358 if (key == NULL) { 2359 rv = SECFailure; 2360 goto loser; 2361 } 2362 2363 cryptoMechType = PK11_GetPBECryptoMechanism(algid, &crypto_param, pwitem); 2364 if (cryptoMechType == CKM_INVALID_MECHANISM) { 2365 rv = SECFailure; 2366 goto loser; 2367 } 2368 2369 cryptoMech.mechanism = PK11_GetPadMechanism(cryptoMechType); 2370 cryptoMech.pParameter = crypto_param ? crypto_param->data : NULL; 2371 cryptoMech.ulParameterLen = crypto_param ? crypto_param->len : 0; 2372 2373 /* If the key isn't in the private key slot, move it */ 2374 if (key->slot != pk->pkcs11Slot) { 2375 PK11SymKey *newkey = pk11_CopyToSlot(pk->pkcs11Slot, 2376 key->type, CKA_WRAP, key); 2377 if (newkey == NULL) { 2378 /* couldn't import the wrapping key, try exporting the 2379 * private key */ 2380 tmpPK = pk11_loadPrivKey(key->slot, pk, NULL, PR_FALSE, PR_TRUE); 2381 if (tmpPK == NULL) { 2382 rv = SECFailure; 2383 goto loser; 2384 } 2385 pk = tmpPK; 2386 } else { 2387 /* free the old key and use the new key */ 2388 PK11_FreeSymKey(key); 2389 key = newkey; 2390 } 2391 } 2392 2393 /* we are extracting an encrypted privateKey structure. 2394 * which needs to be freed along with the buffer into which it is 2395 * returned. eventually, we should retrieve an encrypted key using 2396 * pkcs8/pkcs5. 2397 */ 2398 encBufLen = 0; 2399 PK11_EnterSlotMonitor(pk->pkcs11Slot); 2400 crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session, &cryptoMech, key->objectID, pk->pkcs11ID, NULL, &encBufLen); 2401 PK11_ExitSlotMonitor(pk->pkcs11Slot); 2402 if (crv != CKR_OK) { 2403 rv = SECFailure; 2404 goto loser; 2405 } 2406 epki->encryptedData.data = PORT_ArenaAlloc(arena, encBufLen); 2407 if (!epki->encryptedData.data) { 2408 rv = SECFailure; 2409 goto loser; 2410 } 2411 PK11_EnterSlotMonitor(pk->pkcs11Slot); 2412 crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session, &cryptoMech, key->objectID, pk->pkcs11ID, epki->encryptedData.data, &encBufLen); 2413 PK11_ExitSlotMonitor(pk->pkcs11Slot); 2414 epki->encryptedData.len = (unsigned int)encBufLen; 2415 if (crv != CKR_OK) { 2416 rv = SECFailure; 2417 goto loser; 2418 } 2419 2420 if (!epki->encryptedData.len) { 2421 rv = SECFailure; 2422 goto loser; 2423 } 2424 2425 rv = SECOID_CopyAlgorithmID(arena, &epki->algorithm, algid); 2426 2427 loser: 2428 if (crypto_param != NULL) { 2429 SECITEM_ZfreeItem(crypto_param, PR_TRUE); 2430 crypto_param = NULL; 2431 } 2432 2433 if (key != NULL) { 2434 PK11_FreeSymKey(key); 2435 } 2436 if (tmpPK != NULL) { 2437 SECKEY_DestroyPrivateKey(tmpPK); 2438 } 2439 SECOID_DestroyAlgorithmID(algid, PR_TRUE); 2440 2441 if (rv == SECFailure) { 2442 if (arena != NULL) { 2443 PORT_FreeArena(arena, PR_TRUE); 2444 } 2445 epki = NULL; 2446 } 2447 2448 return epki; 2449 } 2450 2451 SECKEYEncryptedPrivateKeyInfo * 2452 PK11_ExportEncryptedPrivKeyInfo( 2453 PK11SlotInfo *slot, /* optional, encrypt key in this slot */ 2454 SECOidTag algTag, /* PBE algorithm to encrypt the with key */ 2455 SECItem *pwitem, /* password for PBE encryption */ 2456 SECKEYPrivateKey *pk, /* encrypt this private key */ 2457 int iteration, /* interations for PBE alg */ 2458 void *pwArg) /* context for password callback */ 2459 { 2460 return PK11_ExportEncryptedPrivKeyInfoV2(slot, algTag, SEC_OID_UNKNOWN, 2461 SEC_OID_UNKNOWN, pwitem, pk, 2462 iteration, pwArg); 2463 } 2464 2465 /* V2 refers to PKCS #5 V2 here. If a PKCS #5 v1 or PKCS #12 pbe is passed 2466 * for pbeTag, then encTag and hashTag are ignored. If pbe is an encryption 2467 * algorithm, then PKCS #5 V2 is used with prfTag for the prf. If prfTag isn't 2468 * supplied prf will be SEC_OID_HMAC_SHA1 */ 2469 SECKEYEncryptedPrivateKeyInfo * 2470 PK11_ExportEncryptedPrivateKeyInfoV2( 2471 PK11SlotInfo *slot, /* optional, encrypt key in this slot */ 2472 SECOidTag pbeAlg, /* PBE algorithm to encrypt the with key */ 2473 SECOidTag encAlg, /* Encryption algorithm to Encrypt the key with */ 2474 SECOidTag prfAlg, /* HMAC algorithm for PRF*/ 2475 SECItem *pwitem, /* password for PBE encryption */ 2476 CERTCertificate *cert, /* wrap priv key for this user cert */ 2477 int iteration, /* interations for PBE alg */ 2478 void *pwArg) /* context for password callback */ 2479 { 2480 SECKEYEncryptedPrivateKeyInfo *epki = NULL; 2481 SECKEYPrivateKey *pk = PK11_FindKeyByAnyCert(cert, pwArg); 2482 if (pk != NULL) { 2483 epki = PK11_ExportEncryptedPrivKeyInfoV2(slot, pbeAlg, encAlg, prfAlg, 2484 pwitem, pk, iteration, 2485 pwArg); 2486 SECKEY_DestroyPrivateKey(pk); 2487 } 2488 return epki; 2489 } 2490 2491 SECKEYEncryptedPrivateKeyInfo * 2492 PK11_ExportEncryptedPrivateKeyInfo( 2493 PK11SlotInfo *slot, /* optional, encrypt key in this slot */ 2494 SECOidTag algTag, /* encrypt key with this algorithm */ 2495 SECItem *pwitem, /* password for PBE encryption */ 2496 CERTCertificate *cert, /* wrap priv key for this user cert */ 2497 int iteration, /* interations for PBE alg */ 2498 void *pwArg) /* context for password callback */ 2499 { 2500 return PK11_ExportEncryptedPrivateKeyInfoV2(slot, algTag, SEC_OID_UNKNOWN, 2501 SEC_OID_UNKNOWN, pwitem, cert, 2502 iteration, pwArg); 2503 } 2504 2505 SECItem * 2506 PK11_DEREncodePublicKey(const SECKEYPublicKey *pubk) 2507 { 2508 return SECKEY_EncodeDERSubjectPublicKeyInfo(pubk); 2509 } 2510 2511 char * 2512 PK11_GetPrivateKeyNickname(SECKEYPrivateKey *privKey) 2513 { 2514 return PK11_GetObjectNickname(privKey->pkcs11Slot, privKey->pkcs11ID); 2515 } 2516 2517 char * 2518 PK11_GetPublicKeyNickname(SECKEYPublicKey *pubKey) 2519 { 2520 return PK11_GetObjectNickname(pubKey->pkcs11Slot, pubKey->pkcs11ID); 2521 } 2522 2523 SECStatus 2524 PK11_SetPrivateKeyNickname(SECKEYPrivateKey *privKey, const char *nickname) 2525 { 2526 return PK11_SetObjectNickname(privKey->pkcs11Slot, 2527 privKey->pkcs11ID, nickname); 2528 } 2529 2530 SECStatus 2531 PK11_SetPublicKeyNickname(SECKEYPublicKey *pubKey, const char *nickname) 2532 { 2533 return PK11_SetObjectNickname(pubKey->pkcs11Slot, 2534 pubKey->pkcs11ID, nickname); 2535 } 2536 2537 SECKEYPQGParams * 2538 PK11_GetPQGParamsFromPrivateKey(SECKEYPrivateKey *privKey) 2539 { 2540 CK_ATTRIBUTE pTemplate[] = { 2541 { CKA_PRIME, NULL, 0 }, 2542 { CKA_SUBPRIME, NULL, 0 }, 2543 { CKA_BASE, NULL, 0 }, 2544 }; 2545 int pTemplateLen = sizeof(pTemplate) / sizeof(pTemplate[0]); 2546 PLArenaPool *arena = NULL; 2547 SECKEYPQGParams *params; 2548 CK_RV crv; 2549 2550 arena = PORT_NewArena(2048); 2551 if (arena == NULL) { 2552 goto loser; 2553 } 2554 params = (SECKEYPQGParams *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPQGParams)); 2555 if (params == NULL) { 2556 goto loser; 2557 } 2558 2559 crv = PK11_GetAttributes(arena, privKey->pkcs11Slot, privKey->pkcs11ID, 2560 pTemplate, pTemplateLen); 2561 if (crv != CKR_OK) { 2562 PORT_SetError(PK11_MapError(crv)); 2563 goto loser; 2564 } 2565 2566 params->arena = arena; 2567 params->prime.data = pTemplate[0].pValue; 2568 params->prime.len = pTemplate[0].ulValueLen; 2569 params->subPrime.data = pTemplate[1].pValue; 2570 params->subPrime.len = pTemplate[1].ulValueLen; 2571 params->base.data = pTemplate[2].pValue; 2572 params->base.len = pTemplate[2].ulValueLen; 2573 2574 return params; 2575 2576 loser: 2577 if (arena != NULL) { 2578 PORT_FreeArena(arena, PR_FALSE); 2579 } 2580 return NULL; 2581 } 2582 2583 SECKEYPrivateKey * 2584 PK11_CopyTokenPrivKeyToSessionPrivKey(PK11SlotInfo *destSlot, 2585 SECKEYPrivateKey *privKey) 2586 { 2587 CK_RV crv; 2588 CK_OBJECT_HANDLE newKeyID; 2589 2590 static const CK_BBOOL ckfalse = CK_FALSE; 2591 static const CK_ATTRIBUTE template[1] = { 2592 { CKA_TOKEN, (CK_BBOOL *)&ckfalse, sizeof ckfalse } 2593 }; 2594 2595 if (destSlot && destSlot != privKey->pkcs11Slot) { 2596 SECKEYPrivateKey *newKey = 2597 pk11_loadPrivKey(destSlot, 2598 privKey, 2599 NULL, /* pubKey */ 2600 PR_FALSE, /* token */ 2601 PR_FALSE); /* sensitive */ 2602 if (newKey) 2603 return newKey; 2604 } 2605 destSlot = privKey->pkcs11Slot; 2606 PK11_Authenticate(destSlot, PR_TRUE, privKey->wincx); 2607 PK11_EnterSlotMonitor(destSlot); 2608 crv = PK11_GETTAB(destSlot)->C_CopyObject(destSlot->session, 2609 privKey->pkcs11ID, 2610 (CK_ATTRIBUTE *)template, 2611 1, &newKeyID); 2612 PK11_ExitSlotMonitor(destSlot); 2613 2614 if (crv != CKR_OK) { 2615 PORT_SetError(PK11_MapError(crv)); 2616 return NULL; 2617 } 2618 2619 return PK11_MakePrivKey(destSlot, privKey->keyType, PR_TRUE /*isTemp*/, 2620 newKeyID, privKey->wincx); 2621 } 2622 2623 SECKEYPrivateKey * 2624 PK11_ConvertSessionPrivKeyToTokenPrivKey(SECKEYPrivateKey *privk, void *wincx) 2625 { 2626 PK11SlotInfo *slot = privk->pkcs11Slot; 2627 CK_ATTRIBUTE template[1]; 2628 CK_ATTRIBUTE *attrs = template; 2629 CK_BBOOL cktrue = CK_TRUE; 2630 CK_RV crv; 2631 CK_OBJECT_HANDLE newKeyID; 2632 CK_SESSION_HANDLE rwsession; 2633 2634 PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); 2635 attrs++; 2636 2637 PK11_Authenticate(slot, PR_TRUE, wincx); 2638 rwsession = PK11_GetRWSession(slot); 2639 if (rwsession == CK_INVALID_HANDLE) { 2640 PORT_SetError(SEC_ERROR_BAD_DATA); 2641 return NULL; 2642 } 2643 crv = PK11_GETTAB(slot)->C_CopyObject(rwsession, privk->pkcs11ID, 2644 template, 1, &newKeyID); 2645 PK11_RestoreROSession(slot, rwsession); 2646 2647 if (crv != CKR_OK) { 2648 PORT_SetError(PK11_MapError(crv)); 2649 return NULL; 2650 } 2651 2652 return PK11_MakePrivKey(slot, nullKey /*KeyType*/, PR_FALSE /*isTemp*/, 2653 newKeyID, NULL /*wincx*/); 2654 } 2655 2656 /* 2657 * destroy a private key if there are no matching certs. 2658 * this function also frees the privKey structure. 2659 */ 2660 SECStatus 2661 PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey, PRBool force) 2662 { 2663 CERTCertificate *cert = PK11_GetCertFromPrivateKey(privKey); 2664 SECStatus rv = SECWouldBlock; 2665 2666 if (!cert || force) { 2667 /* now, then it's safe for the key to go away */ 2668 rv = PK11_DestroyTokenObject(privKey->pkcs11Slot, privKey->pkcs11ID); 2669 } 2670 if (cert) { 2671 CERT_DestroyCertificate(cert); 2672 } 2673 SECKEY_DestroyPrivateKey(privKey); 2674 return rv; 2675 } 2676 2677 /* 2678 * destroy a private key if there are no matching certs. 2679 * this function also frees the privKey structure. 2680 */ 2681 SECStatus 2682 PK11_DeleteTokenPublicKey(SECKEYPublicKey *pubKey) 2683 { 2684 /* now, then it's safe for the key to go away */ 2685 if (pubKey->pkcs11Slot == NULL) { 2686 return SECFailure; 2687 } 2688 PK11_DestroyTokenObject(pubKey->pkcs11Slot, pubKey->pkcs11ID); 2689 SECKEY_DestroyPublicKey(pubKey); 2690 return SECSuccess; 2691 } 2692 2693 /* 2694 * key call back structure. 2695 */ 2696 typedef struct pk11KeyCallbackStr { 2697 SECStatus (*callback)(SECKEYPrivateKey *, void *); 2698 void *callbackArg; 2699 void *wincx; 2700 } pk11KeyCallback; 2701 2702 /* 2703 * callback to map Object Handles to Private Keys; 2704 */ 2705 SECStatus 2706 pk11_DoKeys(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle, void *arg) 2707 { 2708 SECStatus rv = SECSuccess; 2709 SECKEYPrivateKey *privKey; 2710 pk11KeyCallback *keycb = (pk11KeyCallback *)arg; 2711 if (!arg) { 2712 return SECFailure; 2713 } 2714 2715 privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, keycb->wincx); 2716 2717 if (privKey == NULL) { 2718 return SECFailure; 2719 } 2720 2721 if (keycb->callback) { 2722 rv = (*keycb->callback)(privKey, keycb->callbackArg); 2723 } 2724 2725 SECKEY_DestroyPrivateKey(privKey); 2726 return rv; 2727 } 2728 2729 /*********************************************************************** 2730 * PK11_TraversePrivateKeysInSlot 2731 * 2732 * Traverses all the private keys on a slot. 2733 * 2734 * INPUTS 2735 * slot 2736 * The PKCS #11 slot whose private keys you want to traverse. 2737 * callback 2738 * A callback function that will be called for each key. 2739 * arg 2740 * An argument that will be passed to the callback function. 2741 */ 2742 SECStatus 2743 PK11_TraversePrivateKeysInSlot(PK11SlotInfo *slot, 2744 SECStatus (*callback)(SECKEYPrivateKey *, void *), void *arg) 2745 { 2746 pk11KeyCallback perKeyCB; 2747 pk11TraverseSlot perObjectCB; 2748 CK_OBJECT_CLASS privkClass = CKO_PRIVATE_KEY; 2749 CK_BBOOL ckTrue = CK_TRUE; 2750 CK_ATTRIBUTE theTemplate[2]; 2751 int templateSize = 2; 2752 2753 theTemplate[0].type = CKA_CLASS; 2754 theTemplate[0].pValue = &privkClass; 2755 theTemplate[0].ulValueLen = sizeof(privkClass); 2756 theTemplate[1].type = CKA_TOKEN; 2757 theTemplate[1].pValue = &ckTrue; 2758 theTemplate[1].ulValueLen = sizeof(ckTrue); 2759 2760 if (slot == NULL) { 2761 return SECSuccess; 2762 } 2763 2764 perObjectCB.callback = pk11_DoKeys; 2765 perObjectCB.callbackArg = &perKeyCB; 2766 perObjectCB.findTemplate = theTemplate; 2767 perObjectCB.templateCount = templateSize; 2768 perKeyCB.callback = callback; 2769 perKeyCB.callbackArg = arg; 2770 perKeyCB.wincx = NULL; 2771 2772 return PK11_TraverseSlot(slot, &perObjectCB); 2773 } 2774 2775 /* 2776 * return the private key with the given ID 2777 */ 2778 CK_OBJECT_HANDLE 2779 pk11_FindPrivateKeyFromCertID(PK11SlotInfo *slot, SECItem *keyID) 2780 { 2781 CK_OBJECT_CLASS privKey = CKO_PRIVATE_KEY; 2782 CK_ATTRIBUTE theTemplate[] = { 2783 { CKA_ID, NULL, 0 }, 2784 { CKA_CLASS, NULL, 0 }, 2785 }; 2786 /* if you change the array, change the variable below as well */ 2787 int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]); 2788 CK_ATTRIBUTE *attrs = theTemplate; 2789 2790 PK11_SETATTRS(attrs, CKA_ID, keyID->data, keyID->len); 2791 attrs++; 2792 PK11_SETATTRS(attrs, CKA_CLASS, &privKey, sizeof(privKey)); 2793 2794 return pk11_FindObjectByTemplate(slot, theTemplate, tsize); 2795 } 2796 2797 SECKEYPrivateKey * 2798 PK11_FindKeyByKeyID(PK11SlotInfo *slot, SECItem *keyID, void *wincx) 2799 { 2800 CK_OBJECT_HANDLE keyHandle; 2801 SECKEYPrivateKey *privKey; 2802 2803 keyHandle = pk11_FindPrivateKeyFromCertID(slot, keyID); 2804 if (keyHandle == CK_INVALID_HANDLE) { 2805 return NULL; 2806 } 2807 privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx); 2808 return privKey; 2809 } 2810 2811 /* 2812 * Generate a CKA_ID from the relevant public key data. The CKA_ID is generated 2813 * from the pubKeyData by SHA1_Hashing it to produce a smaller CKA_ID (to make 2814 * smart cards happy. 2815 */ 2816 SECItem * 2817 PK11_MakeIDFromPubKey(const SECItem *pubKeyData) 2818 { 2819 PK11Context *context; 2820 SECItem *certCKA_ID; 2821 SECStatus rv; 2822 2823 if (pubKeyData->len <= SHA1_LENGTH) { 2824 /* probably an already hashed value. The strongest known public 2825 * key values <= 160 bits would be less than 40 bit symetric in 2826 * strength. Don't hash them, just return the value. There are 2827 * none at the time of this writing supported by previous versions 2828 * of NSS, so change is binary compatible safe */ 2829 return SECITEM_DupItem(pubKeyData); 2830 } 2831 2832 context = PK11_CreateDigestContext(SEC_OID_SHA1); 2833 if (context == NULL) { 2834 return NULL; 2835 } 2836 2837 rv = PK11_DigestBegin(context); 2838 if (rv == SECSuccess) { 2839 rv = PK11_DigestOp(context, pubKeyData->data, pubKeyData->len); 2840 } 2841 if (rv != SECSuccess) { 2842 PK11_DestroyContext(context, PR_TRUE); 2843 return NULL; 2844 } 2845 2846 certCKA_ID = (SECItem *)PORT_Alloc(sizeof(SECItem)); 2847 if (certCKA_ID == NULL) { 2848 PK11_DestroyContext(context, PR_TRUE); 2849 return NULL; 2850 } 2851 2852 certCKA_ID->len = SHA1_LENGTH; 2853 certCKA_ID->data = (unsigned char *)PORT_Alloc(certCKA_ID->len); 2854 if (certCKA_ID->data == NULL) { 2855 PORT_Free(certCKA_ID); 2856 PK11_DestroyContext(context, PR_TRUE); 2857 return NULL; 2858 } 2859 2860 rv = PK11_DigestFinal(context, certCKA_ID->data, &certCKA_ID->len, 2861 SHA1_LENGTH); 2862 PK11_DestroyContext(context, PR_TRUE); 2863 if (rv != SECSuccess) { 2864 SECITEM_FreeItem(certCKA_ID, PR_TRUE); 2865 return NULL; 2866 } 2867 2868 return certCKA_ID; 2869 } 2870 2871 /* Looking for PK11_GetKeyIDFromPrivateKey? 2872 * Call PK11_GetLowLevelKeyIDForPrivateKey instead. 2873 */ 2874 2875 SECItem * 2876 PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *privKey) 2877 { 2878 return pk11_GetLowLevelKeyFromHandle(privKey->pkcs11Slot, privKey->pkcs11ID); 2879 } 2880 2881 static SECStatus 2882 privateKeyListCallback(SECKEYPrivateKey *key, void *arg) 2883 { 2884 SECKEYPrivateKeyList *list = (SECKEYPrivateKeyList *)arg; 2885 return SECKEY_AddPrivateKeyToListTail(list, SECKEY_CopyPrivateKey(key)); 2886 } 2887 2888 SECKEYPrivateKeyList * 2889 PK11_ListPrivateKeysInSlot(PK11SlotInfo *slot) 2890 { 2891 SECStatus status; 2892 SECKEYPrivateKeyList *keys; 2893 2894 keys = SECKEY_NewPrivateKeyList(); 2895 if (keys == NULL) 2896 return NULL; 2897 2898 status = PK11_TraversePrivateKeysInSlot(slot, privateKeyListCallback, 2899 (void *)keys); 2900 2901 if (status != SECSuccess) { 2902 SECKEY_DestroyPrivateKeyList(keys); 2903 keys = NULL; 2904 } 2905 2906 return keys; 2907 } 2908 2909 SECKEYPublicKeyList * 2910 PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, char *nickname) 2911 { 2912 CK_ATTRIBUTE findTemp[4]; 2913 CK_ATTRIBUTE *attrs; 2914 CK_BBOOL ckTrue = CK_TRUE; 2915 CK_OBJECT_CLASS keyclass = CKO_PUBLIC_KEY; 2916 size_t tsize = 0; 2917 int objCount = 0; 2918 CK_OBJECT_HANDLE *key_ids; 2919 SECKEYPublicKeyList *keys; 2920 int i, len; 2921 2922 attrs = findTemp; 2923 PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); 2924 attrs++; 2925 PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); 2926 attrs++; 2927 if (nickname) { 2928 len = PORT_Strlen(nickname); 2929 PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); 2930 attrs++; 2931 } 2932 tsize = attrs - findTemp; 2933 PORT_Assert(tsize <= sizeof(findTemp) / sizeof(CK_ATTRIBUTE)); 2934 2935 key_ids = pk11_FindObjectsByTemplate(slot, findTemp, tsize, &objCount); 2936 if (key_ids == NULL) { 2937 return NULL; 2938 } 2939 keys = SECKEY_NewPublicKeyList(); 2940 if (keys == NULL) { 2941 PORT_Free(key_ids); 2942 return NULL; 2943 } 2944 2945 for (i = 0; i < objCount; i++) { 2946 SECKEYPublicKey *pubKey = 2947 PK11_ExtractPublicKey(slot, nullKey, key_ids[i]); 2948 if (pubKey) { 2949 SECKEY_AddPublicKeyToListTail(keys, pubKey); 2950 } 2951 } 2952 2953 PORT_Free(key_ids); 2954 return keys; 2955 } 2956 2957 SECKEYPrivateKeyList * 2958 PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx) 2959 { 2960 CK_ATTRIBUTE findTemp[4]; 2961 CK_ATTRIBUTE *attrs; 2962 CK_BBOOL ckTrue = CK_TRUE; 2963 CK_OBJECT_CLASS keyclass = CKO_PRIVATE_KEY; 2964 size_t tsize = 0; 2965 int objCount = 0; 2966 CK_OBJECT_HANDLE *key_ids; 2967 SECKEYPrivateKeyList *keys; 2968 int i, len; 2969 2970 attrs = findTemp; 2971 PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); 2972 attrs++; 2973 PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); 2974 attrs++; 2975 if (nickname) { 2976 len = PORT_Strlen(nickname); 2977 PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); 2978 attrs++; 2979 } 2980 tsize = attrs - findTemp; 2981 PORT_Assert(tsize <= sizeof(findTemp) / sizeof(CK_ATTRIBUTE)); 2982 2983 key_ids = pk11_FindObjectsByTemplate(slot, findTemp, tsize, &objCount); 2984 if (key_ids == NULL) { 2985 return NULL; 2986 } 2987 keys = SECKEY_NewPrivateKeyList(); 2988 if (keys == NULL) { 2989 PORT_Free(key_ids); 2990 return NULL; 2991 } 2992 2993 for (i = 0; i < objCount; i++) { 2994 SECKEYPrivateKey *privKey = 2995 PK11_MakePrivKey(slot, nullKey, PR_TRUE, key_ids[i], wincx); 2996 SECKEY_AddPrivateKeyToListTail(keys, privKey); 2997 } 2998 2999 PORT_Free(key_ids); 3000 return keys; 3001 }