lowkey.c (24512B)
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 "lowkeyi.h" 5 #include "secoid.h" 6 #include "secitem.h" 7 #include "secder.h" 8 #include "base64.h" 9 #include "secasn1.h" 10 #include "secerr.h" 11 #include "softoken.h" 12 #include "ec.h" 13 14 SEC_ASN1_MKSUB(SEC_AnyTemplate) 15 SEC_ASN1_MKSUB(SEC_BitStringTemplate) 16 SEC_ASN1_MKSUB(SEC_ObjectIDTemplate) 17 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) 18 SEC_ASN1_MKSUB(SEC_OctetStringTemplate) 19 20 const SEC_ASN1Template nsslowkey_AttributeTemplate[] = { 21 { SEC_ASN1_SEQUENCE, 22 0, NULL, sizeof(NSSLOWKEYAttribute) }, 23 { SEC_ASN1_OBJECT_ID, offsetof(NSSLOWKEYAttribute, attrType) }, 24 { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, 25 offsetof(NSSLOWKEYAttribute, attrValue), 26 SEC_ASN1_SUB(SEC_AnyTemplate) }, 27 { 0 } 28 }; 29 30 const SEC_ASN1Template nsslowkey_SetOfAttributeTemplate[] = { 31 { SEC_ASN1_SET_OF, 0, nsslowkey_AttributeTemplate }, 32 }; 33 /* ASN1 Templates for new decoder/encoder */ 34 const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[] = { 35 { SEC_ASN1_SEQUENCE, 36 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) }, 37 { SEC_ASN1_INTEGER, 38 offsetof(NSSLOWKEYPrivateKeyInfo, version) }, 39 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, 40 offsetof(NSSLOWKEYPrivateKeyInfo, algorithm), 41 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 42 { SEC_ASN1_OCTET_STRING, 43 offsetof(NSSLOWKEYPrivateKeyInfo, privateKey) }, 44 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, 45 offsetof(NSSLOWKEYPrivateKeyInfo, attributes), 46 nsslowkey_SetOfAttributeTemplate }, 47 { 0 } 48 }; 49 50 const SEC_ASN1Template nsslowkey_SubjectPublicKeyInfoTemplate[] = { 51 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYSubjectPublicKeyInfo) }, 52 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, 53 offsetof(NSSLOWKEYSubjectPublicKeyInfo, algorithm), 54 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 55 { SEC_ASN1_BIT_STRING, 56 offsetof(NSSLOWKEYSubjectPublicKeyInfo, subjectPublicKey) }, 57 { 0 } 58 }; 59 60 const SEC_ASN1Template nsslowkey_RSAPublicKeyTemplate[] = { 61 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPublicKey) }, 62 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey, u.rsa.modulus) }, 63 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey, u.rsa.publicExponent) }, 64 { 0 } 65 }; 66 67 const SEC_ASN1Template nsslowkey_PQGParamsTemplate[] = { 68 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PQGParams) }, 69 { SEC_ASN1_INTEGER, offsetof(PQGParams, prime) }, 70 { SEC_ASN1_INTEGER, offsetof(PQGParams, subPrime) }, 71 { SEC_ASN1_INTEGER, offsetof(PQGParams, base) }, 72 { 0 } 73 }; 74 75 const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[] = { 76 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, 77 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.version) }, 78 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.modulus) }, 79 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.publicExponent) }, 80 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.privateExponent) }, 81 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.prime1) }, 82 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.prime2) }, 83 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.exponent1) }, 84 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.exponent2) }, 85 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.rsa.coefficient) }, 86 { 0 } 87 }; 88 89 const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[] = { 90 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, 91 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.dsa.publicValue) }, 92 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.dsa.privateValue) }, 93 { 0 } 94 }; 95 96 const SEC_ASN1Template nsslowkey_PQBothSeedAndPrivateKeyTemplate[] = { 97 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, 98 { SEC_ASN1_OCTET_STRING, offsetof(NSSLOWKEYPrivateKey, u.genpq.seedItem) }, 99 { SEC_ASN1_OCTET_STRING, offsetof(NSSLOWKEYPrivateKey, u.genpq.keyItem) }, 100 { 0 } 101 }; 102 103 const SEC_ASN1Template nsslowkey_PQSeedTemplate[] = { 104 { SEC_ASN1_CONTEXT_SPECIFIC | 0, 105 offsetof(NSSLOWKEYPrivateKey, u.genpq.seedItem), 106 SEC_ASN1_SUB(SEC_OctetStringTemplate) }, 107 { 0 } 108 }; 109 const SEC_ASN1Template nsslowkey_PQPrivateKeyTemplate[] = { 110 { SEC_ASN1_OCTET_STRING, offsetof(NSSLOWKEYPrivateKey, u.genpq.keyItem) }, 111 { 0 } 112 }; 113 114 const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[] = { 115 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.dsa.privateValue) }, 116 }; 117 118 const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[] = { 119 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, 120 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.dh.publicValue) }, 121 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.dh.privateValue) }, 122 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.dh.base) }, 123 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.dh.prime) }, 124 { 0 } 125 }; 126 127 /* NOTE: The SECG specification allows the private key structure 128 * to contain curve parameters but recommends that they be stored 129 * in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo 130 * instead. 131 */ 132 const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[] = { 133 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, 134 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.ec.version) }, 135 { SEC_ASN1_OCTET_STRING, 136 offsetof(NSSLOWKEYPrivateKey, u.ec.privateValue) }, 137 /* We only support named curves for which the parameters are 138 * encoded as an object ID. 139 */ 140 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 141 SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 142 SEC_ASN1_XTRN | 0, 143 offsetof(NSSLOWKEYPrivateKey, u.ec.ecParams.curveOID), 144 SEC_ASN1_SUB(SEC_ObjectIDTemplate) }, 145 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 146 SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 147 SEC_ASN1_XTRN | 1, 148 offsetof(NSSLOWKEYPrivateKey, u.ec.publicValue), 149 SEC_ASN1_SUB(SEC_BitStringTemplate) }, 150 { 0 } 151 }; 152 /* 153 * See bugzilla bug 125359 154 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints, 155 * all of the templates above that en/decode into integers must be converted 156 * from ASN.1's signed integer type. This is done by marking either the 157 * source or destination (encoding or decoding, respectively) type as 158 * siUnsignedInteger. 159 */ 160 161 void 162 prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) 163 { 164 key->u.rsa.modulus.type = siUnsignedInteger; 165 key->u.rsa.publicExponent.type = siUnsignedInteger; 166 key->u.rsa.privateExponent.type = siUnsignedInteger; 167 key->u.rsa.prime1.type = siUnsignedInteger; 168 key->u.rsa.prime2.type = siUnsignedInteger; 169 key->u.rsa.exponent1.type = siUnsignedInteger; 170 key->u.rsa.exponent2.type = siUnsignedInteger; 171 key->u.rsa.coefficient.type = siUnsignedInteger; 172 } 173 174 void 175 prepare_low_rsa_pub_key_for_asn1(NSSLOWKEYPublicKey *key) 176 { 177 key->u.rsa.modulus.type = siUnsignedInteger; 178 key->u.rsa.publicExponent.type = siUnsignedInteger; 179 } 180 181 void 182 prepare_low_pqg_params_for_asn1(PQGParams *params) 183 { 184 params->prime.type = siUnsignedInteger; 185 params->subPrime.type = siUnsignedInteger; 186 params->base.type = siUnsignedInteger; 187 } 188 189 void 190 prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) 191 { 192 key->u.dsa.publicValue.type = siUnsignedInteger; 193 key->u.dsa.privateValue.type = siUnsignedInteger; 194 key->u.dsa.params.prime.type = siUnsignedInteger; 195 key->u.dsa.params.subPrime.type = siUnsignedInteger; 196 key->u.dsa.params.base.type = siUnsignedInteger; 197 } 198 199 void 200 prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key) 201 { 202 key->u.dsa.privateValue.type = siUnsignedInteger; 203 } 204 205 void 206 prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) 207 { 208 key->u.dh.prime.type = siUnsignedInteger; 209 key->u.dh.base.type = siUnsignedInteger; 210 key->u.dh.publicValue.type = siUnsignedInteger; 211 key->u.dh.privateValue.type = siUnsignedInteger; 212 } 213 214 void 215 prepare_low_ecparams_for_asn1(ECParams *params) 216 { 217 params->DEREncoding.type = siUnsignedInteger; 218 params->curveOID.type = siUnsignedInteger; 219 } 220 221 void 222 prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) 223 { 224 key->u.ec.version.type = siUnsignedInteger; 225 key->u.ec.ecParams.DEREncoding.type = siUnsignedInteger; 226 key->u.ec.ecParams.curveOID.type = siUnsignedInteger; 227 key->u.ec.privateValue.type = siUnsignedInteger; 228 key->u.ec.publicValue.type = siUnsignedInteger; 229 } 230 231 void 232 nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk) 233 { 234 if (privk && privk->arena) { 235 PORT_FreeArena(privk->arena, PR_TRUE); 236 } 237 } 238 239 void 240 nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk) 241 { 242 if (pubk && pubk->arena) { 243 PORT_FreeArena(pubk->arena, PR_TRUE); 244 } 245 } 246 unsigned 247 nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubk) 248 { 249 /* interpret modulus length as key strength... in 250 * fortezza that's the public key length */ 251 252 switch (pubk->keyType) { 253 case NSSLOWKEYRSAKey: 254 if (pubk->u.rsa.modulus.len == 0) { 255 return 0; 256 } 257 if (pubk->u.rsa.modulus.data[0] == 0) { 258 return pubk->u.rsa.modulus.len - 1; 259 } 260 return pubk->u.rsa.modulus.len; 261 default: 262 break; 263 } 264 return 0; 265 } 266 267 unsigned 268 nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privk) 269 { 270 switch (privk->keyType) { 271 case NSSLOWKEYRSAKey: 272 if (privk->u.rsa.modulus.len == 0) { 273 return 0; 274 } 275 if (privk->u.rsa.modulus.data[0] == 0) { 276 return privk->u.rsa.modulus.len - 1; 277 } 278 return privk->u.rsa.modulus.len; 279 default: 280 break; 281 } 282 return 0; 283 } 284 285 NSSLOWKEYPublicKey * 286 nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) 287 { 288 NSSLOWKEYPublicKey *pubk; 289 SECItem publicValue; 290 PLArenaPool *arena; 291 292 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 293 if (arena == NULL) { 294 PORT_SetError(SEC_ERROR_NO_MEMORY); 295 return NULL; 296 } 297 298 switch (privk->keyType) { 299 case NSSLOWKEYRSAKey: 300 case NSSLOWKEYNullKey: 301 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, 302 sizeof(NSSLOWKEYPublicKey)); 303 if (pubk != NULL) { 304 SECStatus rv; 305 306 pubk->arena = arena; 307 pubk->keyType = privk->keyType; 308 if (privk->keyType == NSSLOWKEYNullKey) 309 return pubk; 310 rv = SECITEM_CopyItem(arena, &pubk->u.rsa.modulus, 311 &privk->u.rsa.modulus); 312 if (rv == SECSuccess) { 313 rv = SECITEM_CopyItem(arena, &pubk->u.rsa.publicExponent, 314 &privk->u.rsa.publicExponent); 315 if (rv == SECSuccess) 316 return pubk; 317 } 318 } else { 319 PORT_SetError(SEC_ERROR_NO_MEMORY); 320 } 321 break; 322 case NSSLOWKEYDSAKey: 323 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, 324 sizeof(NSSLOWKEYPublicKey)); 325 if (pubk != NULL) { 326 SECStatus rv; 327 328 pubk->arena = arena; 329 pubk->keyType = privk->keyType; 330 /* if the public key value doesn't exist, calculate it */ 331 if (privk->u.dsa.publicValue.len == 0) { 332 rv = DH_Derive(&privk->u.dsa.params.base, &privk->u.dsa.params.prime, 333 &privk->u.dsa.privateValue, &publicValue, 0); 334 if (rv != SECSuccess) { 335 break; 336 } 337 rv = SECITEM_CopyItem(privk->arena, &privk->u.dsa.publicValue, &publicValue); 338 SECITEM_ZfreeItem(&publicValue, PR_FALSE); 339 if (rv != SECSuccess) { 340 break; 341 } 342 } 343 rv = SECITEM_CopyItem(arena, &pubk->u.dsa.publicValue, 344 &privk->u.dsa.publicValue); 345 if (rv != SECSuccess) 346 break; 347 rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime, 348 &privk->u.dsa.params.prime); 349 if (rv != SECSuccess) 350 break; 351 rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime, 352 &privk->u.dsa.params.subPrime); 353 if (rv != SECSuccess) 354 break; 355 rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base, 356 &privk->u.dsa.params.base); 357 if (rv == SECSuccess) 358 return pubk; 359 } 360 break; 361 case NSSLOWKEYDHKey: 362 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, 363 sizeof(NSSLOWKEYPublicKey)); 364 if (pubk != NULL) { 365 SECStatus rv; 366 367 pubk->arena = arena; 368 pubk->keyType = privk->keyType; 369 /* if the public key value doesn't exist, calculate it */ 370 if (privk->u.dh.publicValue.len == 0) { 371 rv = DH_Derive(&privk->u.dh.base, &privk->u.dh.prime, 372 &privk->u.dh.privateValue, &publicValue, 0); 373 if (rv != SECSuccess) { 374 break; 375 } 376 rv = SECITEM_CopyItem(privk->arena, &privk->u.dh.publicValue, &publicValue); 377 SECITEM_ZfreeItem(&publicValue, PR_FALSE); 378 if (rv != SECSuccess) { 379 break; 380 } 381 } 382 rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue, 383 &privk->u.dh.publicValue); 384 if (rv != SECSuccess) 385 break; 386 rv = SECITEM_CopyItem(arena, &pubk->u.dh.prime, 387 &privk->u.dh.prime); 388 if (rv != SECSuccess) 389 break; 390 rv = SECITEM_CopyItem(arena, &pubk->u.dh.base, 391 &privk->u.dh.base); 392 if (rv == SECSuccess) 393 return pubk; 394 } 395 break; 396 case NSSLOWKEYECKey: 397 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, 398 sizeof(NSSLOWKEYPublicKey)); 399 if (pubk != NULL) { 400 SECStatus rv; 401 402 pubk->arena = arena; 403 pubk->keyType = privk->keyType; 404 405 /* if the public key value doesn't exist, calculate it */ 406 if (privk->u.ec.publicValue.len == 0) { 407 /* Checking if it's an ed25519 or x25519 key. 408 If it's the case, we derive the public key using the private key. */ 409 SECOidTag privKeyOIDTag = SECOID_FindOIDTag(&privk->u.ec.ecParams.curveOID); 410 if (privKeyOIDTag == SEC_OID_ED25519_PUBLIC_KEY) { 411 PORT_Memset(&privk->u.ec.publicValue, 0, sizeof(privk->u.ec.publicValue)); 412 if (SECITEM_AllocItem(privk->arena, &privk->u.ec.publicValue, Ed25519_PUBLIC_KEYLEN) == NULL) { 413 break; 414 } 415 416 rv = ED_DerivePublicKey(&privk->u.ec.privateValue, &privk->u.ec.publicValue); 417 if (rv != CKR_OK) { 418 break; 419 } 420 } else if (privKeyOIDTag == SEC_OID_X25519) { 421 PORT_Memset(&privk->u.ec.publicValue, 0, sizeof(privk->u.ec.publicValue)); 422 if (SECITEM_AllocItem(privk->arena, &privk->u.ec.publicValue, X25519_PUBLIC_KEYLEN) == NULL) { 423 break; 424 } 425 426 rv = X25519_DerivePublicKey(&privk->u.ec.privateValue, &privk->u.ec.publicValue); 427 if (rv != CKR_OK) { 428 break; 429 } 430 } 431 } 432 433 rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, 434 &privk->u.ec.publicValue); 435 if (rv != SECSuccess) 436 break; 437 pubk->u.ec.ecParams.arena = arena; 438 /* Copy the rest of the params */ 439 rv = EC_CopyParams(arena, &(pubk->u.ec.ecParams), 440 &(privk->u.ec.ecParams)); 441 if (rv == SECSuccess) 442 return pubk; 443 } 444 break; 445 case NSSLOWKEYMLDSAKey: 446 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, 447 sizeof(NSSLOWKEYPublicKey)); 448 if (pubk != NULL) { 449 SECStatus rv; 450 SECItem seed = { siBuffer, NULL, 0 }; 451 MLDSAPrivateKey newPrivKey; 452 453 pubk->arena = arena; 454 pubk->keyType = privk->keyType; 455 456 /* privatekey value is encoded (rho, K, tr, s1, s2, t0) */ 457 /* publickey value is encoded (rho, t1) */ 458 /* Future, we can calculate public key directly from 459 * privatekey value as follows : 460 * A^ = ExpandA(rho); 461 * t = NTT-1(A^ o NSS(s1)) + s2 462 * (t1, t0) = Power2Round(t) 463 * we now have rho and t1 so we can encode public key. 464 * these functions are all specified in FIPS-204. For now 465 * we just use the seed if it's a available and regenerate 466 * both keys, and discard the private key. */ 467 if (privk->u.mldsa.seedLen == 0) { 468 PORT_SetError(SEC_ERROR_PKCS11_FUNCTION_FAILED); 469 rv = SECFailure; 470 break; 471 } 472 seed.data = privk->u.mldsa.seed; 473 seed.len = privk->u.mldsa.seedLen; 474 rv = MLDSA_NewKey(privk->u.mldsa.paramSet, &seed, 475 &newPrivKey, &pubk->u.mldsa); 476 if (rv != SECSuccess) { 477 break; 478 } 479 PORT_SafeZero(&newPrivKey, sizeof(newPrivKey)); 480 return pubk; 481 } 482 break; 483 /* No Fortezza in Low Key implementations (Fortezza keys aren't 484 * stored in our data base */ 485 default: 486 break; 487 } 488 489 PORT_FreeArena(arena, PR_TRUE); 490 return NULL; 491 } 492 493 NSSLOWKEYPrivateKey * 494 nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey) 495 { 496 NSSLOWKEYPrivateKey *returnKey = NULL; 497 SECStatus rv = SECFailure; 498 PLArenaPool *poolp; 499 500 if (!privKey) { 501 return NULL; 502 } 503 504 poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 505 if (!poolp) { 506 return NULL; 507 } 508 509 returnKey = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(poolp, sizeof(NSSLOWKEYPrivateKey)); 510 if (!returnKey) { 511 rv = SECFailure; 512 goto loser; 513 } 514 515 returnKey->keyType = privKey->keyType; 516 returnKey->arena = poolp; 517 518 switch (privKey->keyType) { 519 case NSSLOWKEYRSAKey: 520 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.modulus), 521 &(privKey->u.rsa.modulus)); 522 if (rv != SECSuccess) 523 break; 524 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.version), 525 &(privKey->u.rsa.version)); 526 if (rv != SECSuccess) 527 break; 528 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.publicExponent), 529 &(privKey->u.rsa.publicExponent)); 530 if (rv != SECSuccess) 531 break; 532 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.privateExponent), 533 &(privKey->u.rsa.privateExponent)); 534 if (rv != SECSuccess) 535 break; 536 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime1), 537 &(privKey->u.rsa.prime1)); 538 if (rv != SECSuccess) 539 break; 540 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime2), 541 &(privKey->u.rsa.prime2)); 542 if (rv != SECSuccess) 543 break; 544 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent1), 545 &(privKey->u.rsa.exponent1)); 546 if (rv != SECSuccess) 547 break; 548 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent2), 549 &(privKey->u.rsa.exponent2)); 550 if (rv != SECSuccess) 551 break; 552 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.coefficient), 553 &(privKey->u.rsa.coefficient)); 554 if (rv != SECSuccess) 555 break; 556 break; 557 case NSSLOWKEYDSAKey: 558 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.publicValue), 559 &(privKey->u.dsa.publicValue)); 560 if (rv != SECSuccess) 561 break; 562 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.privateValue), 563 &(privKey->u.dsa.privateValue)); 564 if (rv != SECSuccess) 565 break; 566 returnKey->u.dsa.params.arena = poolp; 567 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.prime), 568 &(privKey->u.dsa.params.prime)); 569 if (rv != SECSuccess) 570 break; 571 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.subPrime), 572 &(privKey->u.dsa.params.subPrime)); 573 if (rv != SECSuccess) 574 break; 575 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.base), 576 &(privKey->u.dsa.params.base)); 577 if (rv != SECSuccess) 578 break; 579 break; 580 case NSSLOWKEYDHKey: 581 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.publicValue), 582 &(privKey->u.dh.publicValue)); 583 if (rv != SECSuccess) 584 break; 585 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.privateValue), 586 &(privKey->u.dh.privateValue)); 587 if (rv != SECSuccess) 588 break; 589 returnKey->u.dsa.params.arena = poolp; 590 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.prime), 591 &(privKey->u.dh.prime)); 592 if (rv != SECSuccess) 593 break; 594 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.base), 595 &(privKey->u.dh.base)); 596 if (rv != SECSuccess) 597 break; 598 break; 599 case NSSLOWKEYECKey: 600 rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.version), 601 &(privKey->u.ec.version)); 602 if (rv != SECSuccess) 603 break; 604 rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.publicValue), 605 &(privKey->u.ec.publicValue)); 606 if (rv != SECSuccess) 607 break; 608 rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.privateValue), 609 &(privKey->u.ec.privateValue)); 610 if (rv != SECSuccess) 611 break; 612 returnKey->u.ec.ecParams.arena = poolp; 613 /* Copy the rest of the params */ 614 rv = EC_CopyParams(poolp, &(returnKey->u.ec.ecParams), 615 &(privKey->u.ec.ecParams)); 616 if (rv != SECSuccess) 617 break; 618 break; 619 case NSSLOWKEYMLDSAKey: 620 returnKey->u.mldsa = privKey->u.mldsa; 621 rv = SECSuccess; 622 break; 623 default: 624 rv = SECFailure; 625 } 626 627 loser: 628 629 if (rv != SECSuccess) { 630 PORT_FreeArena(poolp, PR_TRUE); 631 returnKey = NULL; 632 } 633 634 return returnKey; 635 }