seckey.c (86681B)
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 #include "cryptohi.h" 5 #include "keyhi.h" 6 #include "pkcs11t.h" 7 #include "secoid.h" 8 #include "secitem.h" 9 #include "secder.h" 10 #include "base64.h" 11 #include "secasn1.h" 12 #include "cert.h" 13 #include "pk11func.h" 14 #include "secerr.h" 15 #include "secdig.h" 16 #include "prtime.h" 17 #include "keyi.h" 18 #include "nss.h" 19 20 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) 21 SEC_ASN1_MKSUB(SEC_IntegerTemplate) 22 23 const SEC_ASN1Template CERT_SubjectPublicKeyInfoTemplate[] = { 24 { SEC_ASN1_SEQUENCE, 25 0, NULL, sizeof(CERTSubjectPublicKeyInfo) }, 26 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, 27 offsetof(CERTSubjectPublicKeyInfo, algorithm), 28 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 29 { SEC_ASN1_BIT_STRING, 30 offsetof(CERTSubjectPublicKeyInfo, subjectPublicKey) }, 31 { 0 } 32 }; 33 34 const SEC_ASN1Template CERT_PublicKeyAndChallengeTemplate[] = { 35 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTPublicKeyAndChallenge) }, 36 { SEC_ASN1_ANY, offsetof(CERTPublicKeyAndChallenge, spki) }, 37 { SEC_ASN1_IA5_STRING, offsetof(CERTPublicKeyAndChallenge, challenge) }, 38 { 0 } 39 }; 40 41 const SEC_ASN1Template SECKEY_RSAPublicKeyTemplate[] = { 42 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPublicKey) }, 43 { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.rsa.modulus) }, 44 { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.rsa.publicExponent) }, 45 { 0 } 46 }; 47 48 static const SEC_ASN1Template seckey_PointerToAlgorithmIDTemplate[] = { 49 { SEC_ASN1_POINTER | SEC_ASN1_XTRN, 0, 50 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) } 51 }; 52 53 /* Parameters for SEC_OID_PKCS1_RSA_PSS_SIGNATURE */ 54 const SEC_ASN1Template SECKEY_RSAPSSParamsTemplate[] = { 55 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRSAPSSParams) }, 56 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 57 SEC_ASN1_CONTEXT_SPECIFIC | 0, 58 offsetof(SECKEYRSAPSSParams, hashAlg), 59 seckey_PointerToAlgorithmIDTemplate }, 60 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 61 SEC_ASN1_CONTEXT_SPECIFIC | 1, 62 offsetof(SECKEYRSAPSSParams, maskAlg), 63 seckey_PointerToAlgorithmIDTemplate }, 64 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 65 SEC_ASN1_XTRN | SEC_ASN1_CONTEXT_SPECIFIC | 2, 66 offsetof(SECKEYRSAPSSParams, saltLength), 67 SEC_ASN1_SUB(SEC_IntegerTemplate) }, 68 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 69 SEC_ASN1_XTRN | SEC_ASN1_CONTEXT_SPECIFIC | 3, 70 offsetof(SECKEYRSAPSSParams, trailerField), 71 SEC_ASN1_SUB(SEC_IntegerTemplate) }, 72 { 0 } 73 }; 74 75 const SEC_ASN1Template SECKEY_DSAPublicKeyTemplate[] = { 76 { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.dsa.publicValue) }, 77 { 0 } 78 }; 79 80 const SEC_ASN1Template SECKEY_PQGParamsTemplate[] = { 81 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPQGParams) }, 82 { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams, prime) }, 83 { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams, subPrime) }, 84 { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams, base) }, 85 { 0 } 86 }; 87 88 const SEC_ASN1Template SECKEY_DHPublicKeyTemplate[] = { 89 { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.dh.publicValue) }, 90 { 0 } 91 }; 92 93 const SEC_ASN1Template SECKEY_DHParamKeyTemplate[] = { 94 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPublicKey) }, 95 { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.dh.prime) }, 96 { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.dh.base) }, 97 /* XXX chrisk: this needs to be expanded for decoding of j and validationParms (RFC2459 7.3.2) */ 98 { SEC_ASN1_SKIP_REST }, 99 { 0 } 100 }; 101 102 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_DSAPublicKeyTemplate) 103 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_RSAPublicKeyTemplate) 104 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_RSAPSSParamsTemplate) 105 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SubjectPublicKeyInfoTemplate) 106 107 /* 108 * See bugzilla bug 125359 109 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints, 110 * all of the templates above that en/decode into integers must be converted 111 * from ASN.1's signed integer type. This is done by marking either the 112 * source or destination (encoding or decoding, respectively) type as 113 * siUnsignedInteger. 114 */ 115 static void 116 prepare_rsa_pub_key_for_asn1(SECKEYPublicKey *pubk) 117 { 118 pubk->u.rsa.modulus.type = siUnsignedInteger; 119 pubk->u.rsa.publicExponent.type = siUnsignedInteger; 120 } 121 122 static void 123 prepare_dsa_pub_key_for_asn1(SECKEYPublicKey *pubk) 124 { 125 pubk->u.dsa.publicValue.type = siUnsignedInteger; 126 } 127 128 static void 129 prepare_pqg_params_for_asn1(SECKEYPQGParams *params) 130 { 131 params->prime.type = siUnsignedInteger; 132 params->subPrime.type = siUnsignedInteger; 133 params->base.type = siUnsignedInteger; 134 } 135 136 static void 137 prepare_dh_pub_key_for_asn1(SECKEYPublicKey *pubk) 138 { 139 pubk->u.dh.prime.type = siUnsignedInteger; 140 pubk->u.dh.base.type = siUnsignedInteger; 141 pubk->u.dh.publicValue.type = siUnsignedInteger; 142 } 143 144 static const char *const keyTypeName[] = { 145 "null", "rsa", "dsa", "fortezza", "dh", "kea", "ec", "rsaPss", "rsaOaep", 146 "mlkem", "ed", "ecMont", "mldsa" 147 }; 148 static size_t keyTypeNameMax = PR_ARRAY_SIZE(keyTypeName); 149 150 const char * 151 SECKEY_GetKeyTypeString(KeyType keyType) 152 { 153 if (keyType < keyTypeNameMax) { 154 return keyTypeName[keyType]; 155 } 156 return "unknown"; 157 } 158 159 /* Create an RSA key pair is any slot able to do so. 160 ** The created keys are "session" (temporary), not "token" (permanent), 161 ** and they are "sensitive", which makes them costly to move to another token. 162 */ 163 SECKEYPrivateKey * 164 SECKEY_CreateRSAPrivateKey(int keySizeInBits, SECKEYPublicKey **pubk, void *cx) 165 { 166 SECKEYPrivateKey *privk; 167 PK11RSAGenParams param; 168 PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN, cx); 169 if (!slot) { 170 return NULL; 171 } 172 173 param.keySizeInBits = keySizeInBits; 174 param.pe = 65537L; 175 176 privk = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, ¶m, pubk, 177 PR_FALSE, PR_TRUE, cx); 178 PK11_FreeSlot(slot); 179 return (privk); 180 } 181 182 /* Create a DH key pair in any slot able to do so, 183 ** This is a "session" (temporary), not "token" (permanent) key. 184 ** Because of the high probability that this key will need to be moved to 185 ** another token, and the high cost of moving "sensitive" keys, we attempt 186 ** to create this key pair without the "sensitive" attribute, but revert to 187 ** creating a "sensitive" key if necessary. 188 */ 189 SECKEYPrivateKey * 190 SECKEY_CreateDHPrivateKey(SECKEYDHParams *param, SECKEYPublicKey **pubk, void *cx) 191 { 192 SECKEYPrivateKey *privk; 193 PK11SlotInfo *slot; 194 195 if (!param || !param->base.data || !param->prime.data || 196 SECKEY_BigIntegerBitLength(¶m->prime) < DH_MIN_P_BITS || 197 param->base.len == 0 || param->base.len > param->prime.len + 1 || 198 (param->base.len == 1 && param->base.data[0] == 0)) { 199 PORT_SetError(SEC_ERROR_INVALID_ARGS); 200 return NULL; 201 } 202 203 slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN, cx); 204 if (!slot) { 205 return NULL; 206 } 207 208 privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param, 209 pubk, PR_FALSE, PR_FALSE, cx); 210 if (!privk) 211 privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param, 212 pubk, PR_FALSE, PR_TRUE, cx); 213 214 PK11_FreeSlot(slot); 215 return (privk); 216 } 217 218 /* Create an EC key pair in any slot able to do so, 219 ** This is a "session" (temporary), not "token" (permanent) key. 220 ** Because of the high probability that this key will need to be moved to 221 ** another token, and the high cost of moving "sensitive" keys, we attempt 222 ** to create this key pair without the "sensitive" attribute, but revert to 223 ** creating a "sensitive" key if necessary. 224 */ 225 SECKEYPrivateKey * 226 SECKEY_CreateECPrivateKey(SECKEYECParams *param, SECKEYPublicKey **pubk, void *cx) 227 { 228 SECKEYPrivateKey *privk; 229 PK11SlotInfo *slot = PK11_GetBestSlot(CKM_EC_KEY_PAIR_GEN, cx); 230 if (!slot) { 231 return NULL; 232 } 233 234 privk = PK11_GenerateKeyPairWithOpFlags(slot, CKM_EC_KEY_PAIR_GEN, 235 param, pubk, 236 PK11_ATTR_SESSION | 237 PK11_ATTR_INSENSITIVE | 238 PK11_ATTR_PUBLIC, 239 CKF_DERIVE, CKF_DERIVE | CKF_SIGN, 240 cx); 241 if (!privk) 242 privk = PK11_GenerateKeyPairWithOpFlags(slot, CKM_EC_KEY_PAIR_GEN, 243 param, pubk, 244 PK11_ATTR_SESSION | 245 PK11_ATTR_SENSITIVE | 246 PK11_ATTR_PRIVATE, 247 CKF_DERIVE, CKF_DERIVE | CKF_SIGN, 248 cx); 249 250 PK11_FreeSlot(slot); 251 return (privk); 252 } 253 254 SECKEYPrivateKey * 255 SECKEY_CreateEDPrivateKey(SECKEYECParams *param, SECKEYPublicKey **pubk, void *cx) 256 { 257 SECKEYPrivateKey *privk; 258 PK11SlotInfo *slot = PK11_GetBestSlot(CKM_EC_EDWARDS_KEY_PAIR_GEN, cx); 259 if (!slot) { 260 return NULL; 261 } 262 263 privk = PK11_GenerateKeyPairWithOpFlags(slot, CKM_EC_EDWARDS_KEY_PAIR_GEN, 264 param, pubk, 265 PK11_ATTR_SESSION | 266 PK11_ATTR_INSENSITIVE | 267 PK11_ATTR_PUBLIC, 268 CKF_SIGN, CKF_SIGN, cx); 269 if (!privk) 270 privk = PK11_GenerateKeyPairWithOpFlags(slot, CKM_EC_EDWARDS_KEY_PAIR_GEN, 271 param, pubk, 272 PK11_ATTR_SESSION | 273 PK11_ATTR_SENSITIVE | 274 PK11_ATTR_PRIVATE, 275 CKF_SIGN, CKF_SIGN, cx); 276 277 PK11_FreeSlot(slot); 278 return (privk); 279 } 280 281 void 282 SECKEY_DestroyPrivateKey(SECKEYPrivateKey *privk) 283 { 284 if (privk) { 285 if (privk->pkcs11Slot) { 286 if (privk->pkcs11IsTemp) { 287 PK11_DestroyObject(privk->pkcs11Slot, privk->pkcs11ID); 288 } 289 PK11_FreeSlot(privk->pkcs11Slot); 290 } 291 if (privk->arena) { 292 PORT_FreeArena(privk->arena, PR_TRUE); 293 } 294 } 295 } 296 297 void 298 SECKEY_DestroyPublicKey(SECKEYPublicKey *pubk) 299 { 300 if (pubk) { 301 if (pubk->pkcs11Slot) { 302 if (!PK11_IsPermObject(pubk->pkcs11Slot, pubk->pkcs11ID)) { 303 PK11_DestroyObject(pubk->pkcs11Slot, pubk->pkcs11ID); 304 } 305 PK11_FreeSlot(pubk->pkcs11Slot); 306 } 307 if (pubk->arena) { 308 PORT_FreeArena(pubk->arena, PR_FALSE); 309 } 310 } 311 } 312 313 SECStatus 314 SECKEY_CopySubjectPublicKeyInfo(PLArenaPool *arena, 315 CERTSubjectPublicKeyInfo *to, 316 CERTSubjectPublicKeyInfo *from) 317 { 318 SECStatus rv; 319 SECItem spk; 320 321 rv = SECOID_CopyAlgorithmID(arena, &to->algorithm, &from->algorithm); 322 if (rv == SECSuccess) { 323 /* 324 * subjectPublicKey is a bit string, whose length is in bits. 325 * Convert the length from bits to bytes for SECITEM_CopyItem. 326 */ 327 spk = from->subjectPublicKey; 328 DER_ConvertBitString(&spk); 329 rv = SECITEM_CopyItem(arena, &to->subjectPublicKey, &spk); 330 /* Set the length back to bits. */ 331 if (rv == SECSuccess) { 332 to->subjectPublicKey.len = from->subjectPublicKey.len; 333 } 334 } 335 336 return rv; 337 } 338 339 /* Procedure to update the pqg parameters for a cert's public key. 340 * pqg parameters only need to be updated for DSA certificates. 341 * The procedure uses calls to itself recursively to update a certificate 342 * issuer's pqg parameters. Some important rules are: 343 * - Do nothing if the cert already has PQG parameters. 344 * - If the cert does not have PQG parameters, obtain them from the issuer. 345 * - A valid cert chain cannot have a DSA cert without 346 * pqg parameters that has a parent that is not a DSA cert. */ 347 348 static SECStatus 349 seckey_UpdateCertPQGChain(CERTCertificate *subjectCert, int count) 350 { 351 SECStatus rv; 352 SECOidData *oid = NULL; 353 int tag; 354 CERTSubjectPublicKeyInfo *subjectSpki = NULL; 355 CERTSubjectPublicKeyInfo *issuerSpki = NULL; 356 CERTCertificate *issuerCert = NULL; 357 358 /* increment cert chain length counter*/ 359 count++; 360 361 /* check if cert chain length exceeds the maximum length*/ 362 if (count > CERT_MAX_CERT_CHAIN) { 363 return SECFailure; 364 } 365 366 oid = SECOID_FindOID(&subjectCert->subjectPublicKeyInfo.algorithm.algorithm); 367 if (oid != NULL) { 368 tag = oid->offset; 369 370 /* Check if cert has a DSA or EC public key. If not, return 371 * success since no PQG params need to be updated. 372 * 373 * Question: do we really need to do this for EC keys. They don't have 374 * PQG parameters, but they do have parameters. The question is does 375 * the child cert inherit those parameters for EC from the parent, or 376 * do we always include those parameters in each cert. 377 */ 378 379 if ((tag != SEC_OID_ANSIX9_DSA_SIGNATURE) && 380 (tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) && 381 (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST) && 382 (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST) && 383 (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) && 384 (tag != SEC_OID_SDN702_DSA_SIGNATURE) && 385 (tag != SEC_OID_ED25519_PUBLIC_KEY) && 386 (tag != SEC_OID_ANSIX962_EC_PUBLIC_KEY)) { 387 388 return SECSuccess; 389 } 390 } else { 391 return SECFailure; /* return failure if oid is NULL */ 392 } 393 394 /* if cert has PQG parameters, return success */ 395 396 subjectSpki = &subjectCert->subjectPublicKeyInfo; 397 398 if (subjectSpki->algorithm.parameters.len != 0) { 399 return SECSuccess; 400 } 401 402 /* check if the cert is self-signed */ 403 if (subjectCert->isRoot) { 404 /* fail since cert is self-signed and has no pqg params. */ 405 return SECFailure; 406 } 407 408 /* get issuer cert */ 409 issuerCert = CERT_FindCertIssuer(subjectCert, PR_Now(), certUsageAnyCA); 410 if (!issuerCert) { 411 return SECFailure; 412 } 413 414 /* if parent is not DSA, return failure since 415 we don't allow this case. */ 416 417 oid = SECOID_FindOID(&issuerCert->subjectPublicKeyInfo.algorithm.algorithm); 418 if (oid != NULL) { 419 tag = oid->offset; 420 421 /* Check if issuer cert has a DSA public key. If not, 422 * return failure. */ 423 424 if ((tag != SEC_OID_ANSIX9_DSA_SIGNATURE) && 425 (tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) && 426 (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST) && 427 (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST) && 428 (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) && 429 (tag != SEC_OID_SDN702_DSA_SIGNATURE) && 430 (tag != SEC_OID_ED25519_PUBLIC_KEY) && 431 (tag != SEC_OID_ANSIX962_EC_PUBLIC_KEY)) { 432 rv = SECFailure; 433 goto loser; 434 } 435 } else { 436 rv = SECFailure; /* return failure if oid is NULL */ 437 goto loser; 438 } 439 440 /* at this point the subject cert has no pqg parameters and the 441 * issuer cert has a DSA public key. Update the issuer's 442 * pqg parameters with a recursive call to this same function. */ 443 444 rv = seckey_UpdateCertPQGChain(issuerCert, count); 445 if (rv != SECSuccess) { 446 rv = SECFailure; 447 goto loser; 448 } 449 450 /* ensure issuer has pqg parameters */ 451 452 issuerSpki = &issuerCert->subjectPublicKeyInfo; 453 if (issuerSpki->algorithm.parameters.len == 0) { 454 rv = SECFailure; 455 } 456 457 /* if update was successful and pqg params present, then copy the 458 * parameters to the subject cert's key. */ 459 460 if (rv == SECSuccess) { 461 rv = SECITEM_CopyItem(subjectCert->arena, 462 &subjectSpki->algorithm.parameters, 463 &issuerSpki->algorithm.parameters); 464 } 465 466 loser: 467 if (issuerCert) { 468 CERT_DestroyCertificate(issuerCert); 469 } 470 return rv; 471 } 472 473 SECStatus 474 SECKEY_UpdateCertPQG(CERTCertificate *subjectCert) 475 { 476 if (!subjectCert) { 477 PORT_SetError(SEC_ERROR_INVALID_ARGS); 478 return SECFailure; 479 } 480 return seckey_UpdateCertPQGChain(subjectCert, 0); 481 } 482 483 /* Decode the DSA PQG parameters. The params could be stored in two 484 * possible formats, the old fortezza-only wrapped format or 485 * the normal standard format. Store the decoded parameters in 486 * a V3 certificate data structure. */ 487 488 static SECStatus 489 seckey_DSADecodePQG(PLArenaPool *arena, SECKEYPublicKey *pubk, 490 const SECItem *params) 491 { 492 SECStatus rv; 493 SECItem newparams; 494 495 if (params == NULL) 496 return SECFailure; 497 498 if (params->data == NULL) 499 return SECFailure; 500 501 PORT_Assert(arena); 502 503 /* make a copy of the data into the arena so QuickDER output is valid */ 504 rv = SECITEM_CopyItem(arena, &newparams, params); 505 506 /* Check if params use the standard format. 507 * The value 0xa1 will appear in the first byte of the parameter data 508 * if the PQG parameters are not using the standard format. This 509 * code should be changed to use a better method to detect non-standard 510 * parameters. */ 511 512 if ((newparams.data[0] != 0xa1) && 513 (newparams.data[0] != 0xa0)) { 514 515 if (SECSuccess == rv) { 516 /* PQG params are in the standard format */ 517 prepare_pqg_params_for_asn1(&pubk->u.dsa.params); 518 rv = SEC_QuickDERDecodeItem(arena, &pubk->u.dsa.params, 519 SECKEY_PQGParamsTemplate, 520 &newparams); 521 } 522 } else { 523 524 if (SECSuccess == rv) { 525 /* else the old fortezza-only wrapped format is used. */ 526 PORT_SetError(SEC_ERROR_BAD_DER); 527 rv = SECFailure; 528 } 529 } 530 return rv; 531 } 532 533 /* Function used to make an oid tag to a key type */ 534 KeyType 535 seckey_GetKeyType(SECOidTag tag) 536 { 537 KeyType keyType; 538 539 switch (tag) { 540 case SEC_OID_X500_RSA_ENCRYPTION: 541 case SEC_OID_PKCS1_RSA_ENCRYPTION: 542 keyType = rsaKey; 543 break; 544 case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: 545 keyType = rsaPssKey; 546 break; 547 case SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION: 548 keyType = rsaOaepKey; 549 break; 550 case SEC_OID_ANSIX9_DSA_SIGNATURE: 551 keyType = dsaKey; 552 break; 553 case SEC_OID_MISSI_KEA_DSS_OLD: 554 case SEC_OID_MISSI_KEA_DSS: 555 case SEC_OID_MISSI_DSS_OLD: 556 case SEC_OID_MISSI_DSS: 557 keyType = fortezzaKey; 558 break; 559 case SEC_OID_MISSI_KEA: 560 case SEC_OID_MISSI_ALT_KEA: 561 keyType = keaKey; 562 break; 563 case SEC_OID_X942_DIFFIE_HELMAN_KEY: 564 keyType = dhKey; 565 break; 566 case SEC_OID_ANSIX962_EC_PUBLIC_KEY: 567 keyType = ecKey; 568 break; 569 case SEC_OID_ED25519_PUBLIC_KEY: 570 keyType = edKey; 571 break; 572 case SEC_OID_ML_DSA_44_PUBLIC_KEY: 573 case SEC_OID_ML_DSA_65_PUBLIC_KEY: 574 case SEC_OID_ML_DSA_87_PUBLIC_KEY: 575 keyType = mldsaKey; 576 break; 577 /* accommodate applications that hand us a signature type when they 578 * should be handing us a cipher type */ 579 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: 580 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: 581 case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: 582 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: 583 case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: 584 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: 585 keyType = rsaKey; 586 break; 587 default: 588 keyType = nullKey; 589 } 590 return keyType; 591 } 592 593 /* Function used to determine what kind of cert we are dealing with. */ 594 KeyType 595 CERT_GetCertKeyType(const CERTSubjectPublicKeyInfo *spki) 596 { 597 return seckey_GetKeyType(SECOID_GetAlgorithmTag(&spki->algorithm)); 598 } 599 600 /* Ensure pubKey contains an OID */ 601 static SECStatus 602 seckey_HasCurveOID(const SECKEYPublicKey *pubKey) 603 { 604 SECItem oid; 605 SECStatus rv; 606 PORTCheapArenaPool tmpArena; 607 608 PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE); 609 /* If we can decode it, an OID is available. */ 610 rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &oid, 611 SEC_ASN1_GET(SEC_ObjectIDTemplate), 612 &pubKey->u.ec.DEREncodedParams); 613 PORT_DestroyCheapArena(&tmpArena); 614 return rv; 615 } 616 617 CK_ML_DSA_PARAMETER_SET_TYPE 618 SECKEY_GetMLDSAPkcs11ParamSetByOidTag(SECOidTag tag) 619 { 620 switch (tag) { 621 case SEC_OID_ML_DSA_44: 622 return CKP_ML_DSA_44; 623 case SEC_OID_ML_DSA_65: 624 return CKP_ML_DSA_65; 625 case SEC_OID_ML_DSA_87: 626 return CKP_ML_DSA_87; 627 default: 628 return CKP_INVALID_ID; 629 } 630 } 631 632 SECOidTag 633 SECKEY_GetMLDSAOidTagByPkcs11ParamSet(CK_ML_DSA_PARAMETER_SET_TYPE paramSet) 634 { 635 switch (paramSet) { 636 case CKP_ML_DSA_44: 637 return SEC_OID_ML_DSA_44; 638 case CKP_ML_DSA_65: 639 return SEC_OID_ML_DSA_65; 640 case CKP_ML_DSA_87: 641 return SEC_OID_ML_DSA_87; 642 default: 643 return SEC_OID_UNKNOWN; 644 } 645 } 646 647 unsigned int 648 SECKEY_MLDSAOidParamsToLen(SECOidTag oid, SECKEYSizeType type) 649 { 650 switch (type) { 651 case SECKEYPubKeyType: 652 switch (oid) { 653 case SEC_OID_ML_DSA_44: 654 return ML_DSA_44_PUBLICKEY_LEN; 655 case SEC_OID_ML_DSA_65: 656 return ML_DSA_65_PUBLICKEY_LEN; 657 case SEC_OID_ML_DSA_87: 658 return ML_DSA_87_PUBLICKEY_LEN; 659 default: 660 break; 661 } 662 break; 663 case SECKEYPrivKeyType: 664 switch (oid) { 665 case SEC_OID_ML_DSA_44: 666 return ML_DSA_44_PRIVATEKEY_LEN; 667 case SEC_OID_ML_DSA_65: 668 return ML_DSA_65_PRIVATEKEY_LEN; 669 case SEC_OID_ML_DSA_87: 670 return ML_DSA_87_PRIVATEKEY_LEN; 671 default: 672 break; 673 } 674 break; 675 case SECKEYSignatureType: 676 switch (oid) { 677 case SEC_OID_ML_DSA_44: 678 return ML_DSA_44_SIGNATURE_LEN; 679 case SEC_OID_ML_DSA_65: 680 return ML_DSA_65_SIGNATURE_LEN; 681 case SEC_OID_ML_DSA_87: 682 return ML_DSA_87_SIGNATURE_LEN; 683 default: 684 break; 685 } 686 break; 687 default: 688 break; 689 } 690 return 0; 691 } 692 693 /* make this function generic. multiple key types will be able to use 694 * it (ml-kem, ml=dsa, shl-dsa, fn-dsa, etc. ) */ 695 SECOidTag 696 seckey_GetParameterSet(const SECKEYPrivateKey *key) 697 { 698 CK_ULONG paramSet = PK11_ReadULongAttribute(key->pkcs11Slot, 699 key->pkcs11ID, 700 CKA_PARAMETER_SET); 701 if (paramSet == CK_UNAVAILABLE_INFORMATION) { 702 return SEC_OID_UNKNOWN; 703 } 704 switch (key->keyType) { 705 case mldsaKey: 706 return SECKEY_GetMLDSAOidTagByPkcs11ParamSet(paramSet); 707 default: 708 break; 709 } 710 return SEC_OID_UNKNOWN; 711 } 712 713 SECOidTag 714 SECKEY_MLDSAOidParamsFromLen(unsigned int len, SECKEYSizeType type) 715 { 716 switch (type) { 717 case SECKEYPubKeyType: 718 switch (len) { 719 case ML_DSA_44_PUBLICKEY_LEN: 720 return SEC_OID_ML_DSA_44; 721 case ML_DSA_65_PUBLICKEY_LEN: 722 return SEC_OID_ML_DSA_65; 723 case ML_DSA_87_PUBLICKEY_LEN: 724 return SEC_OID_ML_DSA_87; 725 default: 726 break; 727 } 728 break; 729 case SECKEYPrivKeyType: 730 switch (len) { 731 case ML_DSA_44_PRIVATEKEY_LEN: 732 return SEC_OID_ML_DSA_44; 733 case ML_DSA_65_PRIVATEKEY_LEN: 734 return SEC_OID_ML_DSA_65; 735 case ML_DSA_87_PRIVATEKEY_LEN: 736 return SEC_OID_ML_DSA_87; 737 default: 738 break; 739 } 740 break; 741 case SECKEYSignatureType: 742 switch (len) { 743 case ML_DSA_44_SIGNATURE_LEN: 744 return SEC_OID_ML_DSA_44; 745 case ML_DSA_65_SIGNATURE_LEN: 746 return SEC_OID_ML_DSA_65; 747 case ML_DSA_87_SIGNATURE_LEN: 748 return SEC_OID_ML_DSA_87; 749 default: 750 break; 751 } 752 break; 753 default: 754 break; 755 } 756 return SEC_OID_UNKNOWN; 757 } 758 759 static SECKEYPublicKey * 760 seckey_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki) 761 { 762 SECKEYPublicKey *pubk; 763 SECItem os, newOs, newParms; 764 SECStatus rv; 765 PLArenaPool *arena; 766 SECOidTag tag; 767 768 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 769 if (arena == NULL) 770 return NULL; 771 772 pubk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey)); 773 if (pubk == NULL) { 774 PORT_FreeArena(arena, PR_FALSE); 775 return NULL; 776 } 777 778 pubk->arena = arena; 779 pubk->pkcs11Slot = 0; 780 pubk->pkcs11ID = CK_INVALID_HANDLE; 781 782 /* Convert bit string length from bits to bytes */ 783 os = spki->subjectPublicKey; 784 DER_ConvertBitString(&os); 785 786 tag = SECOID_GetAlgorithmTag(&spki->algorithm); 787 788 /* copy the DER into the arena, since Quick DER returns data that points 789 into the DER input, which may get freed by the caller */ 790 rv = SECITEM_CopyItem(arena, &newOs, &os); 791 if (rv == SECSuccess) 792 switch (tag) { 793 case SEC_OID_X500_RSA_ENCRYPTION: 794 case SEC_OID_PKCS1_RSA_ENCRYPTION: 795 case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: 796 pubk->keyType = rsaKey; 797 prepare_rsa_pub_key_for_asn1(pubk); 798 rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate, &newOs); 799 if (rv == SECSuccess) 800 return pubk; 801 break; 802 case SEC_OID_ANSIX9_DSA_SIGNATURE: 803 case SEC_OID_SDN702_DSA_SIGNATURE: 804 pubk->keyType = dsaKey; 805 prepare_dsa_pub_key_for_asn1(pubk); 806 rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DSAPublicKeyTemplate, &newOs); 807 if (rv != SECSuccess) 808 break; 809 810 rv = seckey_DSADecodePQG(arena, pubk, 811 &spki->algorithm.parameters); 812 813 if (rv == SECSuccess) 814 return pubk; 815 break; 816 case SEC_OID_X942_DIFFIE_HELMAN_KEY: 817 pubk->keyType = dhKey; 818 prepare_dh_pub_key_for_asn1(pubk); 819 rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DHPublicKeyTemplate, &newOs); 820 if (rv != SECSuccess) 821 break; 822 823 /* copy the DER into the arena, since Quick DER returns data that points 824 into the DER input, which may get freed by the caller */ 825 rv = SECITEM_CopyItem(arena, &newParms, &spki->algorithm.parameters); 826 if (rv != SECSuccess) 827 break; 828 829 rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DHParamKeyTemplate, 830 &newParms); 831 832 if (rv == SECSuccess) 833 return pubk; 834 break; 835 case SEC_OID_ML_DSA_44_PUBLIC_KEY: 836 case SEC_OID_ML_DSA_65_PUBLIC_KEY: 837 case SEC_OID_ML_DSA_87_PUBLIC_KEY: 838 /* A basic consistency check on inputs. */ 839 if (spki->algorithm.parameters.len != 0 && newOs.len == 0) { 840 PORT_SetError(SEC_ERROR_INPUT_LEN); 841 break; 842 } 843 844 pubk->keyType = mldsaKey; 845 pubk->u.mldsa.paramSet = tag; 846 847 /* newOS is already in the arena, we can just copy the data */ 848 pubk->u.mldsa.publicValue = newOs; 849 return pubk; 850 case SEC_OID_X25519: 851 case SEC_OID_ED25519_PUBLIC_KEY: 852 /* A basic consistency check on inputs. */ 853 if (newOs.len == 0) { 854 PORT_SetError(SEC_ERROR_INPUT_LEN); 855 break; 856 } 857 858 /* Currently supporting only (Pure)Ed25519 .*/ 859 if (spki->algorithm.parameters.len != 0) { 860 PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); 861 break; 862 } 863 864 /* edKey corresponds to Ed25519 mechanism. 865 * ecMontKey corresponds to X25519 mechanism. 866 * The other options are not supported. */ 867 if (tag == SEC_OID_X25519) { 868 pubk->keyType = ecMontKey; 869 } else { 870 /* tag == SEC_OID_ED25519_PUBLIC_KEY */ 871 pubk->keyType = edKey; 872 } 873 874 pubk->u.ec.size = 0; 875 876 SECOidData *oid25519 = SECOID_FindOIDByTag(tag); 877 if (!oid25519) { 878 break; 879 } 880 881 if (!SECITEM_AllocItem(arena, &pubk->u.ec.DEREncodedParams, oid25519->oid.len + 2)) { 882 break; 883 } 884 pubk->u.ec.DEREncodedParams.data[0] = SEC_ASN1_OBJECT_ID; 885 pubk->u.ec.DEREncodedParams.data[1] = oid25519->oid.len; 886 PORT_Memcpy(pubk->u.ec.DEREncodedParams.data + 2, oid25519->oid.data, oid25519->oid.len); 887 888 rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, &newOs); 889 if (rv != SECSuccess) { 890 break; 891 } 892 return pubk; 893 case SEC_OID_ANSIX962_EC_PUBLIC_KEY: 894 /* A basic sanity check on inputs. */ 895 if (spki->algorithm.parameters.len == 0 || newOs.len == 0) { 896 PORT_SetError(SEC_ERROR_INPUT_LEN); 897 break; 898 } 899 pubk->keyType = ecKey; 900 pubk->u.ec.size = 0; 901 902 /* Since PKCS#11 directly takes the DER encoding of EC params 903 * and public value, we don't need any decoding here. 904 */ 905 rv = SECITEM_CopyItem(arena, &pubk->u.ec.DEREncodedParams, 906 &spki->algorithm.parameters); 907 if (rv != SECSuccess) { 908 break; 909 } 910 rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, &newOs); 911 if (rv != SECSuccess) { 912 break; 913 } 914 pubk->u.ec.encoding = ECPoint_Undefined; 915 rv = seckey_HasCurveOID(pubk); 916 if (rv == SECSuccess) { 917 return pubk; 918 } 919 break; 920 921 default: 922 PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); 923 break; 924 } 925 926 SECKEY_DestroyPublicKey(pubk); 927 return NULL; 928 } 929 930 /* required for JSS */ 931 SECKEYPublicKey * 932 SECKEY_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki) 933 { 934 return seckey_ExtractPublicKey(spki); 935 } 936 937 SECKEYPublicKey * 938 CERT_ExtractPublicKey(CERTCertificate *cert) 939 { 940 return seckey_ExtractPublicKey(&cert->subjectPublicKeyInfo); 941 } 942 943 int 944 SECKEY_ECParamsToKeySize(const SECItem *encodedParams) 945 { 946 SECOidTag tag; 947 SECItem oid = { siBuffer, NULL, 0 }; 948 949 /* The encodedParams data contains 0x06 (SEC_ASN1_OBJECT_ID), 950 * followed by the length of the curve oid and the curve oid. 951 */ 952 oid.len = encodedParams->data[1]; 953 oid.data = encodedParams->data + 2; 954 if ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN) 955 return 0; 956 957 switch (tag) { 958 case SEC_OID_SECG_EC_SECP112R1: 959 case SEC_OID_SECG_EC_SECP112R2: 960 return 112; 961 962 case SEC_OID_SECG_EC_SECT113R1: 963 case SEC_OID_SECG_EC_SECT113R2: 964 return 113; 965 966 case SEC_OID_SECG_EC_SECP128R1: 967 case SEC_OID_SECG_EC_SECP128R2: 968 return 128; 969 970 case SEC_OID_SECG_EC_SECT131R1: 971 case SEC_OID_SECG_EC_SECT131R2: 972 return 131; 973 974 case SEC_OID_SECG_EC_SECP160K1: 975 case SEC_OID_SECG_EC_SECP160R1: 976 case SEC_OID_SECG_EC_SECP160R2: 977 return 160; 978 979 case SEC_OID_SECG_EC_SECT163K1: 980 case SEC_OID_SECG_EC_SECT163R1: 981 case SEC_OID_SECG_EC_SECT163R2: 982 case SEC_OID_ANSIX962_EC_C2PNB163V1: 983 case SEC_OID_ANSIX962_EC_C2PNB163V2: 984 case SEC_OID_ANSIX962_EC_C2PNB163V3: 985 return 163; 986 987 case SEC_OID_ANSIX962_EC_C2PNB176V1: 988 return 176; 989 990 case SEC_OID_ANSIX962_EC_C2TNB191V1: 991 case SEC_OID_ANSIX962_EC_C2TNB191V2: 992 case SEC_OID_ANSIX962_EC_C2TNB191V3: 993 case SEC_OID_ANSIX962_EC_C2ONB191V4: 994 case SEC_OID_ANSIX962_EC_C2ONB191V5: 995 return 191; 996 997 case SEC_OID_SECG_EC_SECP192K1: 998 case SEC_OID_ANSIX962_EC_PRIME192V1: 999 case SEC_OID_ANSIX962_EC_PRIME192V2: 1000 case SEC_OID_ANSIX962_EC_PRIME192V3: 1001 return 192; 1002 1003 case SEC_OID_SECG_EC_SECT193R1: 1004 case SEC_OID_SECG_EC_SECT193R2: 1005 return 193; 1006 1007 case SEC_OID_ANSIX962_EC_C2PNB208W1: 1008 return 208; 1009 1010 case SEC_OID_SECG_EC_SECP224K1: 1011 case SEC_OID_SECG_EC_SECP224R1: 1012 return 224; 1013 1014 case SEC_OID_SECG_EC_SECT233K1: 1015 case SEC_OID_SECG_EC_SECT233R1: 1016 return 233; 1017 1018 case SEC_OID_SECG_EC_SECT239K1: 1019 case SEC_OID_ANSIX962_EC_C2TNB239V1: 1020 case SEC_OID_ANSIX962_EC_C2TNB239V2: 1021 case SEC_OID_ANSIX962_EC_C2TNB239V3: 1022 case SEC_OID_ANSIX962_EC_C2ONB239V4: 1023 case SEC_OID_ANSIX962_EC_C2ONB239V5: 1024 case SEC_OID_ANSIX962_EC_PRIME239V1: 1025 case SEC_OID_ANSIX962_EC_PRIME239V2: 1026 case SEC_OID_ANSIX962_EC_PRIME239V3: 1027 return 239; 1028 1029 case SEC_OID_SECG_EC_SECP256K1: 1030 case SEC_OID_ANSIX962_EC_PRIME256V1: 1031 return 256; 1032 1033 case SEC_OID_ANSIX962_EC_C2PNB272W1: 1034 return 272; 1035 1036 case SEC_OID_SECG_EC_SECT283K1: 1037 case SEC_OID_SECG_EC_SECT283R1: 1038 return 283; 1039 1040 case SEC_OID_ANSIX962_EC_C2PNB304W1: 1041 return 304; 1042 1043 case SEC_OID_ANSIX962_EC_C2TNB359V1: 1044 return 359; 1045 1046 case SEC_OID_ANSIX962_EC_C2PNB368W1: 1047 return 368; 1048 1049 case SEC_OID_SECG_EC_SECP384R1: 1050 return 384; 1051 1052 case SEC_OID_SECG_EC_SECT409K1: 1053 case SEC_OID_SECG_EC_SECT409R1: 1054 return 409; 1055 1056 case SEC_OID_ANSIX962_EC_C2TNB431R1: 1057 return 431; 1058 1059 case SEC_OID_SECG_EC_SECP521R1: 1060 return 521; 1061 1062 case SEC_OID_SECG_EC_SECT571K1: 1063 case SEC_OID_SECG_EC_SECT571R1: 1064 return 571; 1065 1066 case SEC_OID_X25519: 1067 case SEC_OID_CURVE25519: 1068 case SEC_OID_ED25519_PUBLIC_KEY: 1069 return 255; 1070 1071 default: 1072 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); 1073 return 0; 1074 } 1075 } 1076 1077 int 1078 SECKEY_ECParamsToBasePointOrderLen(const SECItem *encodedParams) 1079 { 1080 SECOidTag tag; 1081 SECItem oid = { siBuffer, NULL, 0 }; 1082 1083 /* The encodedParams data contains 0x06 (SEC_ASN1_OBJECT_ID), 1084 * followed by the length of the curve oid and the curve oid. 1085 */ 1086 oid.len = encodedParams->data[1]; 1087 oid.data = encodedParams->data + 2; 1088 if ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN) 1089 return 0; 1090 1091 switch (tag) { 1092 case SEC_OID_SECG_EC_SECP112R1: 1093 return 112; 1094 case SEC_OID_SECG_EC_SECP112R2: 1095 return 110; 1096 1097 case SEC_OID_SECG_EC_SECT113R1: 1098 case SEC_OID_SECG_EC_SECT113R2: 1099 return 113; 1100 1101 case SEC_OID_SECG_EC_SECP128R1: 1102 return 128; 1103 case SEC_OID_SECG_EC_SECP128R2: 1104 return 126; 1105 1106 case SEC_OID_SECG_EC_SECT131R1: 1107 case SEC_OID_SECG_EC_SECT131R2: 1108 return 131; 1109 1110 case SEC_OID_SECG_EC_SECP160K1: 1111 case SEC_OID_SECG_EC_SECP160R1: 1112 case SEC_OID_SECG_EC_SECP160R2: 1113 return 161; 1114 1115 case SEC_OID_SECG_EC_SECT163K1: 1116 return 163; 1117 case SEC_OID_SECG_EC_SECT163R1: 1118 return 162; 1119 case SEC_OID_SECG_EC_SECT163R2: 1120 case SEC_OID_ANSIX962_EC_C2PNB163V1: 1121 return 163; 1122 case SEC_OID_ANSIX962_EC_C2PNB163V2: 1123 case SEC_OID_ANSIX962_EC_C2PNB163V3: 1124 return 162; 1125 1126 case SEC_OID_ANSIX962_EC_C2PNB176V1: 1127 return 161; 1128 1129 case SEC_OID_ANSIX962_EC_C2TNB191V1: 1130 return 191; 1131 case SEC_OID_ANSIX962_EC_C2TNB191V2: 1132 return 190; 1133 case SEC_OID_ANSIX962_EC_C2TNB191V3: 1134 return 189; 1135 case SEC_OID_ANSIX962_EC_C2ONB191V4: 1136 return 191; 1137 case SEC_OID_ANSIX962_EC_C2ONB191V5: 1138 return 188; 1139 1140 case SEC_OID_SECG_EC_SECP192K1: 1141 case SEC_OID_ANSIX962_EC_PRIME192V1: 1142 case SEC_OID_ANSIX962_EC_PRIME192V2: 1143 case SEC_OID_ANSIX962_EC_PRIME192V3: 1144 return 192; 1145 1146 case SEC_OID_SECG_EC_SECT193R1: 1147 case SEC_OID_SECG_EC_SECT193R2: 1148 return 193; 1149 1150 case SEC_OID_ANSIX962_EC_C2PNB208W1: 1151 return 193; 1152 1153 case SEC_OID_SECG_EC_SECP224K1: 1154 return 225; 1155 case SEC_OID_SECG_EC_SECP224R1: 1156 return 224; 1157 1158 case SEC_OID_SECG_EC_SECT233K1: 1159 return 232; 1160 case SEC_OID_SECG_EC_SECT233R1: 1161 return 233; 1162 1163 case SEC_OID_SECG_EC_SECT239K1: 1164 case SEC_OID_ANSIX962_EC_C2TNB239V1: 1165 return 238; 1166 case SEC_OID_ANSIX962_EC_C2TNB239V2: 1167 return 237; 1168 case SEC_OID_ANSIX962_EC_C2TNB239V3: 1169 return 236; 1170 case SEC_OID_ANSIX962_EC_C2ONB239V4: 1171 return 238; 1172 case SEC_OID_ANSIX962_EC_C2ONB239V5: 1173 return 237; 1174 case SEC_OID_ANSIX962_EC_PRIME239V1: 1175 case SEC_OID_ANSIX962_EC_PRIME239V2: 1176 case SEC_OID_ANSIX962_EC_PRIME239V3: 1177 return 239; 1178 1179 case SEC_OID_SECG_EC_SECP256K1: 1180 case SEC_OID_ANSIX962_EC_PRIME256V1: 1181 return 256; 1182 1183 case SEC_OID_ANSIX962_EC_C2PNB272W1: 1184 return 257; 1185 1186 case SEC_OID_SECG_EC_SECT283K1: 1187 return 281; 1188 case SEC_OID_SECG_EC_SECT283R1: 1189 return 282; 1190 1191 case SEC_OID_ANSIX962_EC_C2PNB304W1: 1192 return 289; 1193 1194 case SEC_OID_ANSIX962_EC_C2TNB359V1: 1195 return 353; 1196 1197 case SEC_OID_ANSIX962_EC_C2PNB368W1: 1198 return 353; 1199 1200 case SEC_OID_SECG_EC_SECP384R1: 1201 return 384; 1202 1203 case SEC_OID_SECG_EC_SECT409K1: 1204 return 407; 1205 case SEC_OID_SECG_EC_SECT409R1: 1206 return 409; 1207 1208 case SEC_OID_ANSIX962_EC_C2TNB431R1: 1209 return 418; 1210 1211 case SEC_OID_SECG_EC_SECP521R1: 1212 return 521; 1213 1214 case SEC_OID_SECG_EC_SECT571K1: 1215 case SEC_OID_SECG_EC_SECT571R1: 1216 return 570; 1217 1218 case SEC_OID_X25519: 1219 case SEC_OID_CURVE25519: 1220 case SEC_OID_ED25519_PUBLIC_KEY: 1221 return 255; 1222 1223 default: 1224 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); 1225 return 0; 1226 } 1227 } 1228 1229 /* The number of bits in the number from the first non-zero bit onward. */ 1230 unsigned 1231 SECKEY_BigIntegerBitLength(const SECItem *number) 1232 { 1233 const unsigned char *p; 1234 unsigned octets; 1235 unsigned bits; 1236 1237 if (!number || !number->data) { 1238 PORT_SetError(SEC_ERROR_INVALID_KEY); 1239 return 0; 1240 } 1241 1242 p = number->data; 1243 octets = number->len; 1244 while (octets > 0 && !*p) { 1245 ++p; 1246 --octets; 1247 } 1248 if (octets == 0) { 1249 return 0; 1250 } 1251 /* bits = 7..1 because we know at least one bit is set already */ 1252 /* Note: This could do a binary search, but this is faster for keys if we 1253 * assume that good keys will have the MSB set. */ 1254 for (bits = 7; bits > 0; --bits) { 1255 if (*p & (1 << bits)) { 1256 break; 1257 } 1258 } 1259 return octets * 8 + bits - 7; 1260 } 1261 1262 /* returns key strength in bytes (not bits) */ 1263 unsigned 1264 SECKEY_PublicKeyStrength(const SECKEYPublicKey *pubk) 1265 { 1266 return (SECKEY_PublicKeyStrengthInBits(pubk) + 7) / 8; 1267 } 1268 1269 /* returns key strength in bits */ 1270 unsigned 1271 SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk) 1272 { 1273 unsigned bitSize = 0; 1274 1275 if (!pubk) { 1276 PORT_SetError(SEC_ERROR_INVALID_KEY); 1277 return 0; 1278 } 1279 1280 /* interpret modulus length as key strength */ 1281 switch (pubk->keyType) { 1282 case rsaKey: 1283 bitSize = SECKEY_BigIntegerBitLength(&pubk->u.rsa.modulus); 1284 break; 1285 case dsaKey: 1286 bitSize = SECKEY_BigIntegerBitLength(&pubk->u.dsa.params.prime); 1287 break; 1288 case dhKey: 1289 bitSize = SECKEY_BigIntegerBitLength(&pubk->u.dh.prime); 1290 break; 1291 case ecKey: 1292 case edKey: 1293 case ecMontKey: 1294 bitSize = SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams); 1295 break; 1296 case mldsaKey: 1297 bitSize = SECKEY_MLDSAOidParamsToLen(pubk->u.mldsa.paramSet, 1298 SECKEYPubKeyType) * 1299 8; 1300 break; 1301 default: 1302 PORT_SetError(SEC_ERROR_INVALID_KEY); 1303 break; 1304 } 1305 return bitSize; 1306 } 1307 1308 unsigned 1309 SECKEY_PrivateKeyStrengthInBits(const SECKEYPrivateKey *privk) 1310 { 1311 unsigned bitSize = 0; 1312 SECItem params = { siBuffer, NULL, 0 }; 1313 SECStatus rv; 1314 SECOidTag paramSetOid; 1315 1316 if (!privk) { 1317 PORT_SetError(SEC_ERROR_INVALID_KEY); 1318 return 0; 1319 } 1320 1321 /* interpret modulus length as key strength */ 1322 switch (privk->keyType) { 1323 case rsaKey: 1324 case rsaPssKey: 1325 case rsaOaepKey: 1326 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, 1327 CKA_MODULUS, NULL, ¶ms); 1328 if ((rv != SECSuccess) || (params.data == NULL)) { 1329 /* some tokens don't export CKA_MODULUS on the private key, 1330 * PK11_SignatureLen works around this if necessary. This 1331 * method is less percise because it returns bytes instead 1332 * of bits, so we only do it if we can't get the modulus */ 1333 bitSize = PK11_SignatureLen((SECKEYPrivateKey *)privk) * PR_BITS_PER_BYTE; 1334 if (bitSize == -1) { 1335 return 0; 1336 } 1337 return bitSize; 1338 } 1339 bitSize = SECKEY_BigIntegerBitLength(¶ms); 1340 PORT_Free(params.data); 1341 return bitSize; 1342 case dsaKey: 1343 case fortezzaKey: 1344 case dhKey: 1345 case keaKey: 1346 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, 1347 CKA_PRIME, NULL, ¶ms); 1348 if ((rv != SECSuccess) || (params.data == NULL)) { 1349 PORT_SetError(SEC_ERROR_INVALID_KEY); 1350 return 0; 1351 } 1352 bitSize = SECKEY_BigIntegerBitLength(¶ms); 1353 PORT_Free(params.data); 1354 return bitSize; 1355 case ecKey: 1356 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, 1357 CKA_EC_PARAMS, NULL, ¶ms); 1358 if ((rv != SECSuccess) || (params.data == NULL)) { 1359 return 0; 1360 } 1361 bitSize = SECKEY_ECParamsToKeySize(¶ms); 1362 PORT_Free(params.data); 1363 return bitSize; 1364 case mldsaKey: 1365 paramSetOid = seckey_GetParameterSet(privk); 1366 if (paramSetOid == SEC_OID_UNKNOWN) { 1367 break; 1368 } 1369 return SECKEY_MLDSAOidParamsToLen(paramSetOid, SECKEYPrivKeyType) * 1370 8; 1371 break; 1372 default: 1373 break; 1374 } 1375 PORT_SetError(SEC_ERROR_INVALID_KEY); 1376 return 0; 1377 } 1378 1379 /* returns signature length in bytes (not bits) */ 1380 unsigned 1381 SECKEY_SignatureLen(const SECKEYPublicKey *pubk) 1382 { 1383 unsigned size; 1384 1385 switch (pubk->keyType) { 1386 case rsaKey: 1387 case rsaPssKey: 1388 if (pubk->u.rsa.modulus.len == 0) { 1389 return 0; 1390 } 1391 if (pubk->u.rsa.modulus.data[0] == 0) { 1392 return pubk->u.rsa.modulus.len - 1; 1393 } 1394 return pubk->u.rsa.modulus.len; 1395 case dsaKey: 1396 return pubk->u.dsa.params.subPrime.len * 2; 1397 case ecKey: 1398 case edKey: 1399 case ecMontKey: 1400 /* Get the base point order length in bits and adjust */ 1401 size = SECKEY_ECParamsToBasePointOrderLen( 1402 &pubk->u.ec.DEREncodedParams); 1403 return ((size + 7) / 8) * 2; 1404 case mldsaKey: 1405 return SECKEY_MLDSAOidParamsToLen(pubk->u.mldsa.paramSet, 1406 SECKEYSignatureType); 1407 break; 1408 default: 1409 break; 1410 } 1411 PORT_SetError(SEC_ERROR_INVALID_KEY); 1412 return 0; 1413 } 1414 1415 SECKEYPrivateKey * 1416 SECKEY_CopyPrivateKey(const SECKEYPrivateKey *privk) 1417 { 1418 SECKEYPrivateKey *copyk; 1419 PLArenaPool *arena; 1420 1421 if (!privk || !privk->pkcs11Slot) { 1422 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1423 return NULL; 1424 } 1425 1426 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 1427 if (arena == NULL) { 1428 return NULL; 1429 } 1430 1431 copyk = (SECKEYPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPrivateKey)); 1432 if (copyk) { 1433 copyk->arena = arena; 1434 copyk->keyType = privk->keyType; 1435 1436 /* copy the PKCS #11 parameters */ 1437 copyk->pkcs11Slot = PK11_ReferenceSlot(privk->pkcs11Slot); 1438 /* if the key we're referencing was a temparary key we have just 1439 * created, that we want to go away when we're through, we need 1440 * to make a copy of it */ 1441 if (privk->pkcs11IsTemp) { 1442 copyk->pkcs11ID = 1443 PK11_CopyKey(privk->pkcs11Slot, privk->pkcs11ID); 1444 if (copyk->pkcs11ID == CK_INVALID_HANDLE) 1445 goto fail; 1446 } else { 1447 copyk->pkcs11ID = privk->pkcs11ID; 1448 } 1449 copyk->pkcs11IsTemp = privk->pkcs11IsTemp; 1450 copyk->wincx = privk->wincx; 1451 copyk->staticflags = privk->staticflags; 1452 return copyk; 1453 } else { 1454 PORT_SetError(SEC_ERROR_NO_MEMORY); 1455 } 1456 1457 fail: 1458 PORT_FreeArena(arena, PR_FALSE); 1459 return NULL; 1460 } 1461 1462 SECKEYPublicKey * 1463 SECKEY_CopyPublicKey(const SECKEYPublicKey *pubk) 1464 { 1465 SECKEYPublicKey *copyk; 1466 PLArenaPool *arena; 1467 SECStatus rv = SECSuccess; 1468 1469 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 1470 if (arena == NULL) { 1471 PORT_SetError(SEC_ERROR_NO_MEMORY); 1472 return NULL; 1473 } 1474 1475 copyk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey)); 1476 if (!copyk) { 1477 PORT_FreeArena(arena, PR_FALSE); 1478 PORT_SetError(SEC_ERROR_NO_MEMORY); 1479 return NULL; 1480 } 1481 1482 copyk->arena = arena; 1483 copyk->keyType = pubk->keyType; 1484 if (pubk->pkcs11Slot && 1485 PK11_IsPermObject(pubk->pkcs11Slot, pubk->pkcs11ID)) { 1486 copyk->pkcs11Slot = PK11_ReferenceSlot(pubk->pkcs11Slot); 1487 copyk->pkcs11ID = pubk->pkcs11ID; 1488 } else { 1489 copyk->pkcs11Slot = NULL; /* go get own reference */ 1490 copyk->pkcs11ID = CK_INVALID_HANDLE; 1491 } 1492 switch (pubk->keyType) { 1493 case rsaKey: 1494 rv = SECITEM_CopyItem(arena, ©k->u.rsa.modulus, 1495 &pubk->u.rsa.modulus); 1496 if (rv == SECSuccess) { 1497 rv = SECITEM_CopyItem(arena, ©k->u.rsa.publicExponent, 1498 &pubk->u.rsa.publicExponent); 1499 if (rv == SECSuccess) 1500 return copyk; 1501 } 1502 break; 1503 case dsaKey: 1504 rv = SECITEM_CopyItem(arena, ©k->u.dsa.publicValue, 1505 &pubk->u.dsa.publicValue); 1506 if (rv != SECSuccess) 1507 break; 1508 rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.prime, 1509 &pubk->u.dsa.params.prime); 1510 if (rv != SECSuccess) 1511 break; 1512 rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.subPrime, 1513 &pubk->u.dsa.params.subPrime); 1514 if (rv != SECSuccess) 1515 break; 1516 rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.base, 1517 &pubk->u.dsa.params.base); 1518 break; 1519 case dhKey: 1520 rv = SECITEM_CopyItem(arena, ©k->u.dh.prime, &pubk->u.dh.prime); 1521 if (rv != SECSuccess) 1522 break; 1523 rv = SECITEM_CopyItem(arena, ©k->u.dh.base, &pubk->u.dh.base); 1524 if (rv != SECSuccess) 1525 break; 1526 rv = SECITEM_CopyItem(arena, ©k->u.dh.publicValue, 1527 &pubk->u.dh.publicValue); 1528 break; 1529 case ecKey: 1530 case edKey: 1531 case ecMontKey: 1532 copyk->u.ec.size = pubk->u.ec.size; 1533 rv = seckey_HasCurveOID(pubk); 1534 if (rv != SECSuccess) { 1535 break; 1536 } 1537 rv = SECITEM_CopyItem(arena, ©k->u.ec.DEREncodedParams, 1538 &pubk->u.ec.DEREncodedParams); 1539 if (rv != SECSuccess) { 1540 break; 1541 } 1542 copyk->u.ec.encoding = ECPoint_Undefined; 1543 rv = SECITEM_CopyItem(arena, ©k->u.ec.publicValue, 1544 &pubk->u.ec.publicValue); 1545 break; 1546 case mldsaKey: 1547 copyk->u.mldsa.paramSet = pubk->u.mldsa.paramSet; 1548 rv = SECITEM_CopyItem(arena, ©k->u.mldsa.publicValue, 1549 &pubk->u.mldsa.publicValue); 1550 break; 1551 case nullKey: 1552 return copyk; 1553 case kyberKey: 1554 copyk->u.kyber.params = pubk->u.kyber.params; 1555 rv = SECITEM_CopyItem(arena, ©k->u.kyber.publicValue, 1556 &pubk->u.kyber.publicValue); 1557 break; 1558 default: 1559 PORT_SetError(SEC_ERROR_INVALID_KEY); 1560 rv = SECFailure; 1561 break; 1562 } 1563 if (rv == SECSuccess) 1564 return copyk; 1565 1566 SECKEY_DestroyPublicKey(copyk); 1567 return NULL; 1568 } 1569 1570 /* 1571 * Check that a given key meets the policy limits for the given key 1572 * size. 1573 */ 1574 SECStatus 1575 SECKEY_EnforceKeySize(KeyType keyType, unsigned keyLength, SECErrorCodes error) 1576 { 1577 PRInt32 opt = -1; 1578 PRInt32 optVal; 1579 SECStatus rv; 1580 1581 switch (keyType) { 1582 case rsaKey: 1583 case rsaPssKey: 1584 case rsaOaepKey: 1585 opt = NSS_RSA_MIN_KEY_SIZE; 1586 break; 1587 case dsaKey: 1588 case fortezzaKey: 1589 opt = NSS_DSA_MIN_KEY_SIZE; 1590 break; 1591 case dhKey: 1592 case keaKey: 1593 opt = NSS_DH_MIN_KEY_SIZE; 1594 break; 1595 case ecKey: 1596 opt = NSS_ECC_MIN_KEY_SIZE; 1597 break; 1598 case mldsaKey: 1599 return SECSuccess; /* mldsa handles key size policy 1600 * by having separate controls on 1601 * key params */ 1602 case nullKey: 1603 default: 1604 PORT_SetError(SEC_ERROR_INVALID_KEY); 1605 return SECFailure; 1606 } 1607 PORT_Assert(opt != -1); 1608 rv = NSS_OptionGet(opt, &optVal); 1609 if (rv != SECSuccess) { 1610 return rv; 1611 } 1612 if (optVal > keyLength) { 1613 PORT_SetError(error); 1614 return SECFailure; 1615 } 1616 return SECSuccess; 1617 } 1618 1619 /* 1620 * Use the private key to find a public key handle. The handle will be on 1621 * the same slot as the private key. 1622 */ 1623 static CK_OBJECT_HANDLE 1624 seckey_FindPublicKeyHandle(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk) 1625 { 1626 CK_OBJECT_HANDLE keyID; 1627 1628 /* this helper function is only used below. If we want to make this more 1629 * general, we would need to free up any already cached handles if the 1630 * slot doesn't match up with the private key slot */ 1631 PORT_Assert(pubk->pkcs11ID == CK_INVALID_HANDLE); 1632 1633 /* first look for a matching public key */ 1634 keyID = PK11_MatchItem(privk->pkcs11Slot, privk->pkcs11ID, CKO_PUBLIC_KEY); 1635 if (keyID != CK_INVALID_HANDLE) { 1636 return keyID; 1637 } 1638 1639 /* none found, create a temp one, make the pubk the owner */ 1640 pubk->pkcs11ID = PK11_DerivePubKeyFromPrivKey(privk); 1641 if (pubk->pkcs11ID == CK_INVALID_HANDLE) { 1642 /* end of the road. Token doesn't have matching public key, nor can 1643 * token regenerate a new public key from and existing private key. */ 1644 return CK_INVALID_HANDLE; 1645 } 1646 pubk->pkcs11Slot = PK11_ReferenceSlot(privk->pkcs11Slot); 1647 return pubk->pkcs11ID; 1648 } 1649 1650 SECKEYPublicKey * 1651 SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk) 1652 { 1653 SECKEYPublicKey *pubk; 1654 PLArenaPool *arena; 1655 CERTCertificate *cert; 1656 SECStatus rv; 1657 CK_OBJECT_HANDLE pubKeyHandle; 1658 SECItem decodedPoint; 1659 1660 /* 1661 * First try to look up the cert. 1662 */ 1663 cert = PK11_GetCertFromPrivateKey(privk); 1664 if (cert) { 1665 pubk = CERT_ExtractPublicKey(cert); 1666 CERT_DestroyCertificate(cert); 1667 return pubk; 1668 } 1669 1670 /* couldn't find the cert, build pub key by hand */ 1671 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 1672 if (arena == NULL) { 1673 PORT_SetError(SEC_ERROR_NO_MEMORY); 1674 return NULL; 1675 } 1676 pubk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena, 1677 sizeof(SECKEYPublicKey)); 1678 if (pubk == NULL) { 1679 PORT_FreeArena(arena, PR_FALSE); 1680 return NULL; 1681 } 1682 pubk->keyType = privk->keyType; 1683 pubk->pkcs11Slot = NULL; 1684 pubk->pkcs11ID = CK_INVALID_HANDLE; 1685 pubk->arena = arena; 1686 1687 switch (privk->keyType) { 1688 case nullKey: 1689 /* Nothing to query, if the cert isn't there, we're done -- no way 1690 * to get the public key */ 1691 break; 1692 case dsaKey: 1693 pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk); 1694 if (pubKeyHandle == CK_INVALID_HANDLE) 1695 break; 1696 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, 1697 CKA_BASE, arena, &pubk->u.dsa.params.base); 1698 if (rv != SECSuccess) 1699 break; 1700 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, 1701 CKA_PRIME, arena, &pubk->u.dsa.params.prime); 1702 if (rv != SECSuccess) 1703 break; 1704 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, 1705 CKA_SUBPRIME, arena, &pubk->u.dsa.params.subPrime); 1706 if (rv != SECSuccess) 1707 break; 1708 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, 1709 CKA_VALUE, arena, &pubk->u.dsa.publicValue); 1710 if (rv != SECSuccess) 1711 break; 1712 return pubk; 1713 case dhKey: 1714 pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk); 1715 if (pubKeyHandle == CK_INVALID_HANDLE) 1716 break; 1717 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, 1718 CKA_BASE, arena, &pubk->u.dh.base); 1719 if (rv != SECSuccess) 1720 break; 1721 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, 1722 CKA_PRIME, arena, &pubk->u.dh.prime); 1723 if (rv != SECSuccess) 1724 break; 1725 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, 1726 CKA_VALUE, arena, &pubk->u.dh.publicValue); 1727 if (rv != SECSuccess) 1728 break; 1729 return pubk; 1730 case rsaKey: 1731 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, 1732 CKA_MODULUS, arena, &pubk->u.rsa.modulus); 1733 if (rv != SECSuccess) 1734 break; 1735 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, 1736 CKA_PUBLIC_EXPONENT, arena, &pubk->u.rsa.publicExponent); 1737 if (rv != SECSuccess) 1738 break; 1739 return pubk; 1740 case ecKey: 1741 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, 1742 CKA_EC_PARAMS, arena, &pubk->u.ec.DEREncodedParams); 1743 if (rv != SECSuccess) { 1744 break; 1745 } 1746 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, 1747 CKA_EC_POINT, arena, &pubk->u.ec.publicValue); 1748 if (rv != SECSuccess || pubk->u.ec.publicValue.len == 0) { 1749 pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk); 1750 if (pubKeyHandle == CK_INVALID_HANDLE) 1751 break; 1752 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, 1753 CKA_EC_POINT, arena, &pubk->u.ec.publicValue); 1754 if (rv != SECSuccess) 1755 break; 1756 } 1757 /* ec.publicValue should be decoded, PKCS #11 defines CKA_EC_POINT 1758 * as encoded, but it's not always. try do decoded it and if it 1759 * succeeds store the decoded value */ 1760 rv = SEC_QuickDERDecodeItem(arena, &decodedPoint, 1761 SEC_ASN1_GET(SEC_OctetStringTemplate), &pubk->u.ec.publicValue); 1762 if (rv == SECSuccess) { 1763 /* both values are in the public key arena, so it's safe to 1764 * overwrite the old value */ 1765 pubk->u.ec.publicValue = decodedPoint; 1766 } 1767 1768 pubk->u.ec.encoding = ECPoint_Undefined; 1769 return pubk; 1770 case edKey: 1771 case ecMontKey: 1772 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, 1773 CKA_EC_PARAMS, arena, &pubk->u.ec.DEREncodedParams); 1774 if (rv != SECSuccess) { 1775 break; 1776 } 1777 rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, 1778 CKA_EC_POINT, arena, &pubk->u.ec.publicValue); 1779 if (rv != SECSuccess || pubk->u.ec.publicValue.len == 0) { 1780 pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk); 1781 if (pubKeyHandle == CK_INVALID_HANDLE) { 1782 break; 1783 } 1784 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, 1785 CKA_EC_POINT, arena, &pubk->u.ec.publicValue); 1786 if (rv != SECSuccess) { 1787 break; 1788 } 1789 } 1790 pubk->u.ec.encoding = ECPoint_Undefined; 1791 return pubk; 1792 case mldsaKey: 1793 pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk); 1794 if (pubKeyHandle == CK_INVALID_HANDLE) { 1795 break; 1796 } 1797 pubk->u.mldsa.paramSet = seckey_GetParameterSet(privk); 1798 if (pubk->u.mldsa.paramSet == SEC_OID_UNKNOWN) { 1799 break; 1800 } 1801 rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, 1802 CKA_VALUE, arena, &pubk->u.mldsa.publicValue); 1803 if (rv != SECSuccess) { 1804 break; 1805 } 1806 return pubk; 1807 1808 default: 1809 break; 1810 } 1811 1812 /* must use Destroy public key here, because some paths create temporary 1813 * PKCS #11 objects which need to be freed */ 1814 SECKEY_DestroyPublicKey(pubk); 1815 return NULL; 1816 } 1817 1818 static CERTSubjectPublicKeyInfo * 1819 seckey_CreateSubjectPublicKeyInfo_helper(SECKEYPublicKey *pubk) 1820 { 1821 CERTSubjectPublicKeyInfo *spki; 1822 PLArenaPool *arena; 1823 SECItem params = { siBuffer, NULL, 0 }; 1824 SECOidTag tag; 1825 1826 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 1827 if (arena == NULL) { 1828 PORT_SetError(SEC_ERROR_NO_MEMORY); 1829 return NULL; 1830 } 1831 1832 spki = (CERTSubjectPublicKeyInfo *)PORT_ArenaZAlloc(arena, sizeof(*spki)); 1833 if (spki != NULL) { 1834 SECStatus rv; 1835 SECItem *rv_item; 1836 1837 spki->arena = arena; 1838 switch (pubk->keyType) { 1839 case rsaKey: 1840 rv = SECOID_SetAlgorithmID(arena, &spki->algorithm, 1841 SEC_OID_PKCS1_RSA_ENCRYPTION, 0); 1842 if (rv == SECSuccess) { 1843 /* 1844 * DER encode the public key into the subjectPublicKeyInfo. 1845 */ 1846 prepare_rsa_pub_key_for_asn1(pubk); 1847 rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey, 1848 pubk, SECKEY_RSAPublicKeyTemplate); 1849 if (rv_item != NULL) { 1850 /* 1851 * The stored value is supposed to be a BIT_STRING, 1852 * so convert the length. 1853 */ 1854 spki->subjectPublicKey.len <<= 3; 1855 /* 1856 * We got a good one; return it. 1857 */ 1858 return spki; 1859 } 1860 } 1861 break; 1862 case dsaKey: 1863 /* DER encode the params. */ 1864 prepare_pqg_params_for_asn1(&pubk->u.dsa.params); 1865 rv_item = SEC_ASN1EncodeItem(arena, ¶ms, &pubk->u.dsa.params, 1866 SECKEY_PQGParamsTemplate); 1867 if (rv_item != NULL) { 1868 rv = SECOID_SetAlgorithmID(arena, &spki->algorithm, 1869 SEC_OID_ANSIX9_DSA_SIGNATURE, 1870 ¶ms); 1871 if (rv == SECSuccess) { 1872 /* 1873 * DER encode the public key into the subjectPublicKeyInfo. 1874 */ 1875 prepare_dsa_pub_key_for_asn1(pubk); 1876 rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey, 1877 pubk, 1878 SECKEY_DSAPublicKeyTemplate); 1879 if (rv_item != NULL) { 1880 /* 1881 * The stored value is supposed to be a BIT_STRING, 1882 * so convert the length. 1883 */ 1884 spki->subjectPublicKey.len <<= 3; 1885 /* 1886 * We got a good one; return it. 1887 */ 1888 return spki; 1889 } 1890 } 1891 } 1892 SECITEM_FreeItem(¶ms, PR_FALSE); 1893 break; 1894 case ecKey: 1895 rv = SECITEM_CopyItem(arena, ¶ms, 1896 &pubk->u.ec.DEREncodedParams); 1897 if (rv != SECSuccess) { 1898 break; 1899 } 1900 1901 tag = SEC_OID_ANSIX962_EC_PUBLIC_KEY; 1902 rv = SECOID_SetAlgorithmID(arena, &spki->algorithm, 1903 tag, 1904 ¶ms); 1905 if (rv != SECSuccess) { 1906 break; 1907 } 1908 1909 rv = SECITEM_CopyItem(arena, &spki->subjectPublicKey, 1910 &pubk->u.ec.publicValue); 1911 1912 if (rv == SECSuccess) { 1913 /* 1914 * The stored value is supposed to be a BIT_STRING, 1915 * so convert the length. 1916 */ 1917 spki->subjectPublicKey.len <<= 3; 1918 /* 1919 * We got a good one; return it. 1920 */ 1921 return spki; 1922 } 1923 break; 1924 case edKey: 1925 case ecMontKey: 1926 tag = SECKEY_GetECCOid(&pubk->u.ec.DEREncodedParams); 1927 rv = SECOID_SetAlgorithmID(arena, &spki->algorithm, 1928 tag, 1929 ¶ms); 1930 if (rv != SECSuccess) { 1931 break; 1932 } 1933 1934 rv = SECITEM_CopyItem(arena, &spki->subjectPublicKey, 1935 &pubk->u.ec.publicValue); 1936 1937 if (rv == SECSuccess) { 1938 /* 1939 * The stored value is supposed to be a BIT_STRING, 1940 * so convert the length. 1941 */ 1942 spki->subjectPublicKey.len <<= 3; 1943 /* 1944 * We got a good one; return it. 1945 */ 1946 return spki; 1947 } 1948 break; 1949 case mldsaKey: 1950 tag = pubk->u.mldsa.paramSet; 1951 rv = SECOID_SetAlgorithmID(arena, &spki->algorithm, 1952 tag, NULL); 1953 if (rv != SECSuccess) { 1954 break; 1955 } 1956 1957 rv = SECITEM_CopyItem(arena, &spki->subjectPublicKey, 1958 &pubk->u.mldsa.publicValue); 1959 1960 if (rv == SECSuccess) { 1961 /* 1962 * The stored value is supposed to be a BIT_STRING, 1963 * so convert the length. 1964 */ 1965 spki->subjectPublicKey.len <<= 3; 1966 /* 1967 * We got a good one; return it. 1968 */ 1969 return spki; 1970 } 1971 break; 1972 case dhKey: /* later... */ 1973 1974 break; 1975 default: 1976 break; 1977 } 1978 } else { 1979 PORT_SetError(SEC_ERROR_NO_MEMORY); 1980 } 1981 1982 PORT_FreeArena(arena, PR_FALSE); 1983 return NULL; 1984 } 1985 1986 CERTSubjectPublicKeyInfo * 1987 SECKEY_CreateSubjectPublicKeyInfo(const SECKEYPublicKey *pubk) 1988 { 1989 CERTSubjectPublicKeyInfo *spki; 1990 SECKEYPublicKey *tempKey; 1991 1992 if (!pubk) { 1993 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1994 return NULL; 1995 } 1996 1997 tempKey = SECKEY_CopyPublicKey(pubk); 1998 if (!tempKey) { 1999 return NULL; 2000 } 2001 spki = seckey_CreateSubjectPublicKeyInfo_helper(tempKey); 2002 SECKEY_DestroyPublicKey(tempKey); 2003 return spki; 2004 } 2005 2006 void 2007 SECKEY_DestroySubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki) 2008 { 2009 if (spki && spki->arena) { 2010 PORT_FreeArena(spki->arena, PR_FALSE); 2011 } 2012 } 2013 2014 SECItem * 2015 SECKEY_EncodeDERSubjectPublicKeyInfo(const SECKEYPublicKey *pubk) 2016 { 2017 CERTSubjectPublicKeyInfo *spki = NULL; 2018 SECItem *spkiDER = NULL; 2019 2020 /* get the subjectpublickeyinfo */ 2021 spki = SECKEY_CreateSubjectPublicKeyInfo(pubk); 2022 if (spki == NULL) { 2023 goto finish; 2024 } 2025 2026 /* DER-encode the subjectpublickeyinfo */ 2027 spkiDER = SEC_ASN1EncodeItem(NULL /*arena*/, NULL /*dest*/, spki, 2028 CERT_SubjectPublicKeyInfoTemplate); 2029 2030 SECKEY_DestroySubjectPublicKeyInfo(spki); 2031 2032 finish: 2033 return spkiDER; 2034 } 2035 2036 CERTSubjectPublicKeyInfo * 2037 SECKEY_DecodeDERSubjectPublicKeyInfo(const SECItem *spkider) 2038 { 2039 PLArenaPool *arena; 2040 CERTSubjectPublicKeyInfo *spki; 2041 SECStatus rv; 2042 SECItem newSpkider; 2043 2044 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 2045 if (arena == NULL) { 2046 PORT_SetError(SEC_ERROR_NO_MEMORY); 2047 return NULL; 2048 } 2049 2050 spki = (CERTSubjectPublicKeyInfo *) 2051 PORT_ArenaZAlloc(arena, sizeof(CERTSubjectPublicKeyInfo)); 2052 if (spki != NULL) { 2053 spki->arena = arena; 2054 2055 /* copy the DER into the arena, since Quick DER returns data that points 2056 into the DER input, which may get freed by the caller */ 2057 rv = SECITEM_CopyItem(arena, &newSpkider, spkider); 2058 if (rv == SECSuccess) { 2059 rv = SEC_QuickDERDecodeItem(arena, spki, 2060 CERT_SubjectPublicKeyInfoTemplate, &newSpkider); 2061 } 2062 if (rv == SECSuccess) { 2063 return spki; 2064 } 2065 } else { 2066 PORT_SetError(SEC_ERROR_NO_MEMORY); 2067 } 2068 2069 PORT_FreeArena(arena, PR_FALSE); 2070 return NULL; 2071 } 2072 2073 /* 2074 * Decode a base64 ascii encoded DER encoded subject public key info. 2075 */ 2076 CERTSubjectPublicKeyInfo * 2077 SECKEY_ConvertAndDecodeSubjectPublicKeyInfo(const char *spkistr) 2078 { 2079 CERTSubjectPublicKeyInfo *spki; 2080 SECStatus rv; 2081 SECItem der; 2082 2083 rv = ATOB_ConvertAsciiToItem(&der, spkistr); 2084 if (rv != SECSuccess) 2085 return NULL; 2086 2087 spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der); 2088 2089 PORT_Free(der.data); 2090 return spki; 2091 } 2092 2093 /* 2094 * Decode a base64 ascii encoded DER encoded public key and challenge 2095 * Verify digital signature and make sure challenge matches 2096 */ 2097 CERTSubjectPublicKeyInfo * 2098 SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge, 2099 void *wincx) 2100 { 2101 CERTSubjectPublicKeyInfo *spki = NULL; 2102 CERTPublicKeyAndChallenge pkac; 2103 SECStatus rv; 2104 SECItem signedItem; 2105 PLArenaPool *arena = NULL; 2106 CERTSignedData sd; 2107 SECItem sig; 2108 SECKEYPublicKey *pubKey = NULL; 2109 unsigned int len; 2110 2111 signedItem.data = NULL; 2112 2113 /* convert the base64 encoded data to binary */ 2114 rv = ATOB_ConvertAsciiToItem(&signedItem, pkacstr); 2115 if (rv != SECSuccess) { 2116 goto loser; 2117 } 2118 2119 /* create an arena */ 2120 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 2121 if (arena == NULL) { 2122 goto loser; 2123 } 2124 2125 /* decode the outer wrapping of signed data */ 2126 PORT_Memset(&sd, 0, sizeof(CERTSignedData)); 2127 rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, &signedItem); 2128 if (rv) { 2129 goto loser; 2130 } 2131 2132 /* decode the public key and challenge wrapper */ 2133 PORT_Memset(&pkac, 0, sizeof(CERTPublicKeyAndChallenge)); 2134 rv = SEC_QuickDERDecodeItem(arena, &pkac, CERT_PublicKeyAndChallengeTemplate, 2135 &sd.data); 2136 if (rv) { 2137 goto loser; 2138 } 2139 2140 /* decode the subject public key info */ 2141 spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&pkac.spki); 2142 if (spki == NULL) { 2143 goto loser; 2144 } 2145 2146 /* get the public key */ 2147 pubKey = seckey_ExtractPublicKey(spki); 2148 if (pubKey == NULL) { 2149 goto loser; 2150 } 2151 2152 /* check the signature */ 2153 sig = sd.signature; 2154 DER_ConvertBitString(&sig); 2155 rv = VFY_VerifyDataWithAlgorithmID(sd.data.data, sd.data.len, pubKey, &sig, 2156 &(sd.signatureAlgorithm), NULL, wincx); 2157 if (rv != SECSuccess) { 2158 goto loser; 2159 } 2160 2161 /* check the challenge */ 2162 if (challenge) { 2163 len = PORT_Strlen(challenge); 2164 /* length is right */ 2165 if (len != pkac.challenge.len) { 2166 goto loser; 2167 } 2168 /* actual data is right */ 2169 if (PORT_Memcmp(challenge, pkac.challenge.data, len) != 0) { 2170 goto loser; 2171 } 2172 } 2173 goto done; 2174 2175 loser: 2176 /* make sure that we return null if we got an error */ 2177 if (spki) { 2178 SECKEY_DestroySubjectPublicKeyInfo(spki); 2179 } 2180 spki = NULL; 2181 2182 done: 2183 if (signedItem.data) { 2184 PORT_Free(signedItem.data); 2185 } 2186 if (arena) { 2187 PORT_FreeArena(arena, PR_FALSE); 2188 } 2189 if (pubKey) { 2190 SECKEY_DestroyPublicKey(pubKey); 2191 } 2192 2193 return spki; 2194 } 2195 2196 void 2197 SECKEY_DestroyPrivateKeyInfo(SECKEYPrivateKeyInfo *pvk, 2198 PRBool freeit) 2199 { 2200 PLArenaPool *poolp; 2201 2202 if (pvk != NULL) { 2203 if (pvk->arena) { 2204 poolp = pvk->arena; 2205 /* zero structure since PORT_FreeArena does not support 2206 * this yet. 2207 */ 2208 PORT_Memset(pvk->privateKey.data, 0, pvk->privateKey.len); 2209 PORT_Memset(pvk, 0, sizeof(*pvk)); 2210 if (freeit == PR_TRUE) { 2211 PORT_FreeArena(poolp, PR_TRUE); 2212 } else { 2213 pvk->arena = poolp; 2214 } 2215 } else { 2216 SECITEM_ZfreeItem(&pvk->version, PR_FALSE); 2217 SECITEM_ZfreeItem(&pvk->privateKey, PR_FALSE); 2218 SECOID_DestroyAlgorithmID(&pvk->algorithm, PR_FALSE); 2219 PORT_Memset(pvk, 0, sizeof(*pvk)); 2220 if (freeit == PR_TRUE) { 2221 PORT_Free(pvk); 2222 } 2223 } 2224 } 2225 } 2226 2227 void 2228 SECKEY_DestroyEncryptedPrivateKeyInfo(SECKEYEncryptedPrivateKeyInfo *epki, 2229 PRBool freeit) 2230 { 2231 PLArenaPool *poolp; 2232 2233 if (epki != NULL) { 2234 if (epki->arena) { 2235 poolp = epki->arena; 2236 /* zero structure since PORT_FreeArena does not support 2237 * this yet. 2238 */ 2239 PORT_Memset(epki->encryptedData.data, 0, epki->encryptedData.len); 2240 PORT_Memset(epki, 0, sizeof(*epki)); 2241 if (freeit == PR_TRUE) { 2242 PORT_FreeArena(poolp, PR_TRUE); 2243 } else { 2244 epki->arena = poolp; 2245 } 2246 } else { 2247 SECITEM_ZfreeItem(&epki->encryptedData, PR_FALSE); 2248 SECOID_DestroyAlgorithmID(&epki->algorithm, PR_FALSE); 2249 PORT_Memset(epki, 0, sizeof(*epki)); 2250 if (freeit == PR_TRUE) { 2251 PORT_Free(epki); 2252 } 2253 } 2254 } 2255 } 2256 2257 SECStatus 2258 SECKEY_CopyPrivateKeyInfo(PLArenaPool *poolp, 2259 SECKEYPrivateKeyInfo *to, 2260 const SECKEYPrivateKeyInfo *from) 2261 { 2262 SECStatus rv = SECFailure; 2263 2264 if ((to == NULL) || (from == NULL)) { 2265 return SECFailure; 2266 } 2267 2268 rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm); 2269 if (rv != SECSuccess) { 2270 return SECFailure; 2271 } 2272 rv = SECITEM_CopyItem(poolp, &to->privateKey, &from->privateKey); 2273 if (rv != SECSuccess) { 2274 return SECFailure; 2275 } 2276 rv = SECITEM_CopyItem(poolp, &to->version, &from->version); 2277 2278 return rv; 2279 } 2280 2281 SECStatus 2282 SECKEY_CopyEncryptedPrivateKeyInfo(PLArenaPool *poolp, 2283 SECKEYEncryptedPrivateKeyInfo *to, 2284 const SECKEYEncryptedPrivateKeyInfo *from) 2285 { 2286 SECStatus rv = SECFailure; 2287 2288 if ((to == NULL) || (from == NULL)) { 2289 return SECFailure; 2290 } 2291 2292 rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm); 2293 if (rv != SECSuccess) { 2294 return SECFailure; 2295 } 2296 rv = SECITEM_CopyItem(poolp, &to->encryptedData, &from->encryptedData); 2297 2298 return rv; 2299 } 2300 2301 KeyType 2302 SECKEY_GetPrivateKeyType(const SECKEYPrivateKey *privKey) 2303 { 2304 return privKey->keyType; 2305 } 2306 2307 KeyType 2308 SECKEY_GetPublicKeyType(const SECKEYPublicKey *pubKey) 2309 { 2310 return pubKey->keyType; 2311 } 2312 2313 SECKEYPublicKey * 2314 SECKEY_ImportDERPublicKey(const SECItem *derKey, CK_KEY_TYPE type) 2315 { 2316 SECKEYPublicKey *pubk = NULL; 2317 SECStatus rv = SECFailure; 2318 SECItem newDerKey; 2319 PLArenaPool *arena = NULL; 2320 2321 if (!derKey) { 2322 return NULL; 2323 } 2324 2325 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 2326 if (arena == NULL) { 2327 PORT_SetError(SEC_ERROR_NO_MEMORY); 2328 goto finish; 2329 } 2330 2331 pubk = PORT_ArenaZNew(arena, SECKEYPublicKey); 2332 if (pubk == NULL) { 2333 goto finish; 2334 } 2335 pubk->arena = arena; 2336 2337 rv = SECITEM_CopyItem(pubk->arena, &newDerKey, derKey); 2338 if (SECSuccess != rv) { 2339 goto finish; 2340 } 2341 2342 pubk->pkcs11Slot = NULL; 2343 pubk->pkcs11ID = CK_INVALID_HANDLE; 2344 2345 switch (type) { 2346 case CKK_RSA: 2347 prepare_rsa_pub_key_for_asn1(pubk); 2348 rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_RSAPublicKeyTemplate, &newDerKey); 2349 pubk->keyType = rsaKey; 2350 break; 2351 case CKK_DSA: 2352 prepare_dsa_pub_key_for_asn1(pubk); 2353 rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_DSAPublicKeyTemplate, &newDerKey); 2354 pubk->keyType = dsaKey; 2355 break; 2356 case CKK_DH: 2357 prepare_dh_pub_key_for_asn1(pubk); 2358 rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_DHPublicKeyTemplate, &newDerKey); 2359 pubk->keyType = dhKey; 2360 break; 2361 case CKK_ML_DSA: 2362 pubk->keyType = mldsaKey; 2363 /* ml_dsa has no derencoding */ 2364 pubk->u.mldsa.publicValue = newDerKey; 2365 pubk->u.mldsa.paramSet = SECKEY_MLDSAOidParamsFromLen(newDerKey.len, 2366 SECKEYPubKeyType); 2367 if (pubk->u.mldsa.paramSet == SEC_OID_UNKNOWN) { 2368 PORT_SetError(SEC_ERROR_BAD_KEY); 2369 rv = SECFailure; 2370 } 2371 break; 2372 default: 2373 rv = SECFailure; 2374 break; 2375 } 2376 2377 finish: 2378 if (rv != SECSuccess) { 2379 if (arena != NULL) { 2380 PORT_FreeArena(arena, PR_FALSE); 2381 } 2382 pubk = NULL; 2383 } 2384 return pubk; 2385 } 2386 2387 SECKEYPrivateKeyList * 2388 SECKEY_NewPrivateKeyList(void) 2389 { 2390 PLArenaPool *arena = NULL; 2391 SECKEYPrivateKeyList *ret = NULL; 2392 2393 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 2394 if (arena == NULL) { 2395 goto loser; 2396 } 2397 2398 ret = (SECKEYPrivateKeyList *)PORT_ArenaZAlloc(arena, 2399 sizeof(SECKEYPrivateKeyList)); 2400 if (ret == NULL) { 2401 goto loser; 2402 } 2403 2404 ret->arena = arena; 2405 2406 PR_INIT_CLIST(&ret->list); 2407 2408 return (ret); 2409 2410 loser: 2411 if (arena != NULL) { 2412 PORT_FreeArena(arena, PR_FALSE); 2413 } 2414 2415 return (NULL); 2416 } 2417 2418 void 2419 SECKEY_DestroyPrivateKeyList(SECKEYPrivateKeyList *keys) 2420 { 2421 while (!PR_CLIST_IS_EMPTY(&keys->list)) { 2422 SECKEY_RemovePrivateKeyListNode( 2423 (SECKEYPrivateKeyListNode *)(PR_LIST_HEAD(&keys->list))); 2424 } 2425 2426 PORT_FreeArena(keys->arena, PR_FALSE); 2427 2428 return; 2429 } 2430 2431 void 2432 SECKEY_RemovePrivateKeyListNode(SECKEYPrivateKeyListNode *node) 2433 { 2434 PR_ASSERT(node->key); 2435 SECKEY_DestroyPrivateKey(node->key); 2436 node->key = NULL; 2437 PR_REMOVE_LINK(&node->links); 2438 return; 2439 } 2440 2441 SECStatus 2442 SECKEY_AddPrivateKeyToListTail(SECKEYPrivateKeyList *list, 2443 SECKEYPrivateKey *key) 2444 { 2445 SECKEYPrivateKeyListNode *node; 2446 2447 node = (SECKEYPrivateKeyListNode *)PORT_ArenaZAlloc(list->arena, 2448 sizeof(SECKEYPrivateKeyListNode)); 2449 if (node == NULL) { 2450 goto loser; 2451 } 2452 2453 PR_INSERT_BEFORE(&node->links, &list->list); 2454 node->key = key; 2455 return (SECSuccess); 2456 2457 loser: 2458 return (SECFailure); 2459 } 2460 2461 SECKEYPublicKeyList * 2462 SECKEY_NewPublicKeyList(void) 2463 { 2464 PLArenaPool *arena = NULL; 2465 SECKEYPublicKeyList *ret = NULL; 2466 2467 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 2468 if (arena == NULL) { 2469 goto loser; 2470 } 2471 2472 ret = (SECKEYPublicKeyList *)PORT_ArenaZAlloc(arena, 2473 sizeof(SECKEYPublicKeyList)); 2474 if (ret == NULL) { 2475 goto loser; 2476 } 2477 2478 ret->arena = arena; 2479 2480 PR_INIT_CLIST(&ret->list); 2481 2482 return (ret); 2483 2484 loser: 2485 if (arena != NULL) { 2486 PORT_FreeArena(arena, PR_FALSE); 2487 } 2488 2489 return (NULL); 2490 } 2491 2492 void 2493 SECKEY_DestroyPublicKeyList(SECKEYPublicKeyList *keys) 2494 { 2495 while (!PR_CLIST_IS_EMPTY(&keys->list)) { 2496 SECKEY_RemovePublicKeyListNode( 2497 (SECKEYPublicKeyListNode *)(PR_LIST_HEAD(&keys->list))); 2498 } 2499 2500 PORT_FreeArena(keys->arena, PR_FALSE); 2501 2502 return; 2503 } 2504 2505 void 2506 SECKEY_RemovePublicKeyListNode(SECKEYPublicKeyListNode *node) 2507 { 2508 PR_ASSERT(node->key); 2509 SECKEY_DestroyPublicKey(node->key); 2510 node->key = NULL; 2511 PR_REMOVE_LINK(&node->links); 2512 return; 2513 } 2514 2515 SECStatus 2516 SECKEY_AddPublicKeyToListTail(SECKEYPublicKeyList *list, 2517 SECKEYPublicKey *key) 2518 { 2519 SECKEYPublicKeyListNode *node; 2520 2521 node = (SECKEYPublicKeyListNode *)PORT_ArenaZAlloc(list->arena, 2522 sizeof(SECKEYPublicKeyListNode)); 2523 if (node == NULL) { 2524 goto loser; 2525 } 2526 2527 PR_INSERT_BEFORE(&node->links, &list->list); 2528 node->key = key; 2529 return (SECSuccess); 2530 2531 loser: 2532 return (SECFailure); 2533 } 2534 2535 #define SECKEY_CacheAttribute(key, attribute) \ 2536 if (CK_TRUE == PK11_HasAttributeSet(key->pkcs11Slot, key->pkcs11ID, attribute, PR_FALSE)) { \ 2537 key->staticflags |= SECKEY_##attribute; \ 2538 } else { \ 2539 key->staticflags &= (~SECKEY_##attribute); \ 2540 } 2541 2542 SECStatus 2543 SECKEY_CacheStaticFlags(SECKEYPrivateKey *key) 2544 { 2545 SECStatus rv = SECFailure; 2546 if (key && key->pkcs11Slot && key->pkcs11ID) { 2547 key->staticflags |= SECKEY_Attributes_Cached; 2548 SECKEY_CacheAttribute(key, CKA_PRIVATE); 2549 SECKEY_CacheAttribute(key, CKA_ALWAYS_AUTHENTICATE); 2550 rv = SECSuccess; 2551 } 2552 return rv; 2553 } 2554 2555 SECOidTag 2556 SECKEY_GetECCOid(const SECKEYECParams *params) 2557 { 2558 SECItem oid = { siBuffer, NULL, 0 }; 2559 SECOidData *oidData = NULL; 2560 2561 /* 2562 * params->data needs to contain the ASN encoding of an object ID (OID) 2563 * representing a named curve. Here, we strip away everything 2564 * before the actual OID and use the OID to look up a named curve. 2565 */ 2566 if (params->data[0] != SEC_ASN1_OBJECT_ID) 2567 return 0; 2568 oid.len = params->len - 2; 2569 oid.data = params->data + 2; 2570 if ((oidData = SECOID_FindOID(&oid)) == NULL) 2571 return 0; 2572 2573 return oidData->offset; 2574 } 2575 2576 static CK_MECHANISM_TYPE 2577 sec_GetHashMechanismByOidTag(SECOidTag tag) 2578 { 2579 switch (tag) { 2580 case SEC_OID_SHA512: 2581 return CKM_SHA512; 2582 case SEC_OID_SHA384: 2583 return CKM_SHA384; 2584 case SEC_OID_SHA256: 2585 return CKM_SHA256; 2586 case SEC_OID_SHA224: 2587 return CKM_SHA224; 2588 case SEC_OID_SHA1: 2589 return CKM_SHA_1; 2590 default: 2591 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 2592 return CKM_INVALID_MECHANISM; 2593 } 2594 } 2595 2596 CK_RSA_PKCS_MGF_TYPE 2597 SEC_GetMgfTypeByOidTag(SECOidTag tag) 2598 { 2599 switch (tag) { 2600 case SEC_OID_SHA3_512: 2601 return CKG_MGF1_SHA3_512; 2602 case SEC_OID_SHA3_384: 2603 return CKG_MGF1_SHA3_384; 2604 case SEC_OID_SHA3_256: 2605 return CKG_MGF1_SHA3_256; 2606 case SEC_OID_SHA3_224: 2607 return CKG_MGF1_SHA3_224; 2608 case SEC_OID_SHA512: 2609 return CKG_MGF1_SHA512; 2610 case SEC_OID_SHA384: 2611 return CKG_MGF1_SHA384; 2612 case SEC_OID_SHA256: 2613 return CKG_MGF1_SHA256; 2614 case SEC_OID_SHA224: 2615 return CKG_MGF1_SHA224; 2616 case SEC_OID_SHA1: 2617 return CKG_MGF1_SHA1; 2618 default: 2619 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 2620 return 0; 2621 } 2622 } 2623 2624 SECStatus 2625 sec_DecodeRSAPSSParams(PLArenaPool *arena, 2626 const SECItem *params, 2627 SECOidTag *retHashAlg, SECOidTag *retMaskHashAlg, 2628 unsigned long *retSaltLength) 2629 { 2630 SECKEYRSAPSSParams pssParams; 2631 SECOidTag hashAlg; 2632 SECOidTag maskHashAlg; 2633 unsigned long saltLength; 2634 unsigned long trailerField; 2635 SECStatus rv; 2636 2637 PORT_Memset(&pssParams, 0, sizeof(pssParams)); 2638 rv = SEC_QuickDERDecodeItem(arena, &pssParams, 2639 SECKEY_RSAPSSParamsTemplate, 2640 params); 2641 if (rv != SECSuccess) { 2642 return rv; 2643 } 2644 2645 if (pssParams.hashAlg) { 2646 hashAlg = SECOID_GetAlgorithmTag(pssParams.hashAlg); 2647 } else { 2648 hashAlg = SEC_OID_SHA1; /* default, SHA-1 */ 2649 } 2650 2651 if (pssParams.maskAlg) { 2652 SECAlgorithmID algId; 2653 2654 if (SECOID_GetAlgorithmTag(pssParams.maskAlg) != SEC_OID_PKCS1_MGF1) { 2655 /* only MGF1 is known to PKCS#11 */ 2656 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 2657 return SECFailure; 2658 } 2659 2660 rv = SEC_QuickDERDecodeItem(arena, &algId, 2661 SEC_ASN1_GET(SECOID_AlgorithmIDTemplate), 2662 &pssParams.maskAlg->parameters); 2663 if (rv != SECSuccess) { 2664 return rv; 2665 } 2666 maskHashAlg = SECOID_GetAlgorithmTag(&algId); 2667 } else { 2668 maskHashAlg = SEC_OID_SHA1; /* default, MGF1 with SHA-1 */ 2669 } 2670 2671 if (pssParams.saltLength.data) { 2672 rv = SEC_ASN1DecodeInteger((SECItem *)&pssParams.saltLength, &saltLength); 2673 if (rv != SECSuccess) { 2674 return rv; 2675 } 2676 } else { 2677 saltLength = 20; /* default, 20 */ 2678 } 2679 2680 if (pssParams.trailerField.data) { 2681 rv = SEC_ASN1DecodeInteger((SECItem *)&pssParams.trailerField, &trailerField); 2682 if (rv != SECSuccess) { 2683 return rv; 2684 } 2685 if (trailerField != 1) { 2686 /* the value must be 1, which represents the trailer field 2687 * with hexadecimal value 0xBC */ 2688 PORT_SetError(SEC_ERROR_INVALID_ARGS); 2689 return SECFailure; 2690 } 2691 } 2692 2693 if (retHashAlg) { 2694 *retHashAlg = hashAlg; 2695 } 2696 if (retMaskHashAlg) { 2697 *retMaskHashAlg = maskHashAlg; 2698 } 2699 if (retSaltLength) { 2700 *retSaltLength = saltLength; 2701 } 2702 2703 return SECSuccess; 2704 } 2705 2706 SECStatus 2707 sec_DecodeRSAPSSParamsToMechanism(PLArenaPool *arena, 2708 const SECItem *params, 2709 CK_RSA_PKCS_PSS_PARAMS *mech, 2710 SECOidTag *hashAlgp) 2711 { 2712 SECOidTag hashAlg; 2713 SECOidTag maskHashAlg; 2714 unsigned long saltLength; 2715 SECStatus rv; 2716 2717 rv = sec_DecodeRSAPSSParams(arena, params, 2718 &hashAlg, &maskHashAlg, &saltLength); 2719 if (rv != SECSuccess) { 2720 return SECFailure; 2721 } 2722 *hashAlgp = hashAlg; 2723 2724 mech->hashAlg = sec_GetHashMechanismByOidTag(hashAlg); 2725 if (mech->hashAlg == CKM_INVALID_MECHANISM) { 2726 return SECFailure; 2727 } 2728 2729 mech->mgf = SEC_GetMgfTypeByOidTag(maskHashAlg); 2730 if (mech->mgf == 0) { 2731 return SECFailure; 2732 } 2733 2734 mech->sLen = saltLength; 2735 2736 return SECSuccess; 2737 }