security/nss/lib/softoken/legacydb/lowkey.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4 #include "lowkeyi.h"
michael@0 5 #include "secoid.h"
michael@0 6 #include "secitem.h"
michael@0 7 #include "secder.h"
michael@0 8 #include "secasn1.h"
michael@0 9 #include "secerr.h"
michael@0 10
michael@0 11 SEC_ASN1_MKSUB(SEC_AnyTemplate)
michael@0 12 SEC_ASN1_MKSUB(SEC_BitStringTemplate)
michael@0 13 SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
michael@0 14 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
michael@0 15
michael@0 16 static const SEC_ASN1Template nsslowkey_AttributeTemplate[] = {
michael@0 17 { SEC_ASN1_SEQUENCE,
michael@0 18 0, NULL, sizeof(NSSLOWKEYAttribute) },
michael@0 19 { SEC_ASN1_OBJECT_ID, offsetof(NSSLOWKEYAttribute, attrType) },
michael@0 20 { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(NSSLOWKEYAttribute, attrValue),
michael@0 21 SEC_ASN1_SUB(SEC_AnyTemplate) },
michael@0 22 { 0 }
michael@0 23 };
michael@0 24
michael@0 25 static const SEC_ASN1Template nsslowkey_SetOfAttributeTemplate[] = {
michael@0 26 { SEC_ASN1_SET_OF, 0, nsslowkey_AttributeTemplate },
michael@0 27 };
michael@0 28 /* ASN1 Templates for new decoder/encoder */
michael@0 29 const SEC_ASN1Template lg_nsslowkey_PrivateKeyInfoTemplate[] = {
michael@0 30 { SEC_ASN1_SEQUENCE,
michael@0 31 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) },
michael@0 32 { SEC_ASN1_INTEGER,
michael@0 33 offsetof(NSSLOWKEYPrivateKeyInfo,version) },
michael@0 34 { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
michael@0 35 offsetof(NSSLOWKEYPrivateKeyInfo,algorithm),
michael@0 36 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
michael@0 37 { SEC_ASN1_OCTET_STRING,
michael@0 38 offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) },
michael@0 39 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
michael@0 40 offsetof(NSSLOWKEYPrivateKeyInfo, attributes),
michael@0 41 nsslowkey_SetOfAttributeTemplate },
michael@0 42 { 0 }
michael@0 43 };
michael@0 44
michael@0 45 const SEC_ASN1Template lg_nsslowkey_PQGParamsTemplate[] = {
michael@0 46 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PQGParams) },
michael@0 47 { SEC_ASN1_INTEGER, offsetof(PQGParams,prime) },
michael@0 48 { SEC_ASN1_INTEGER, offsetof(PQGParams,subPrime) },
michael@0 49 { SEC_ASN1_INTEGER, offsetof(PQGParams,base) },
michael@0 50 { 0, }
michael@0 51 };
michael@0 52
michael@0 53 const SEC_ASN1Template lg_nsslowkey_RSAPrivateKeyTemplate[] = {
michael@0 54 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
michael@0 55 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.version) },
michael@0 56 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.modulus) },
michael@0 57 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.publicExponent) },
michael@0 58 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.privateExponent) },
michael@0 59 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime1) },
michael@0 60 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime2) },
michael@0 61 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent1) },
michael@0 62 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent2) },
michael@0 63 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.coefficient) },
michael@0 64 { 0 }
michael@0 65 };
michael@0 66
michael@0 67 /*
michael@0 68 * Allows u.rsa.modulus to be zero length for secret keys with an empty
michael@0 69 * CKA_ID incorrectly generated in NSS 3.13.3 or earlier. Only used for
michael@0 70 * decoding. See bug 715073.
michael@0 71 */
michael@0 72 const SEC_ASN1Template lg_nsslowkey_RSAPrivateKeyTemplate2[] = {
michael@0 73 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
michael@0 74 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.version) },
michael@0 75 { SEC_ASN1_ANY, offsetof(NSSLOWKEYPrivateKey,u.rsa.modulus) },
michael@0 76 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.publicExponent) },
michael@0 77 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.privateExponent) },
michael@0 78 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime1) },
michael@0 79 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime2) },
michael@0 80 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent1) },
michael@0 81 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent2) },
michael@0 82 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.coefficient) },
michael@0 83 { 0 }
michael@0 84 };
michael@0 85
michael@0 86 const SEC_ASN1Template lg_nsslowkey_DSAPrivateKeyTemplate[] = {
michael@0 87 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
michael@0 88 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.publicValue) },
michael@0 89 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) },
michael@0 90 { 0, }
michael@0 91 };
michael@0 92
michael@0 93 const SEC_ASN1Template lg_nsslowkey_DHPrivateKeyTemplate[] = {
michael@0 94 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
michael@0 95 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.publicValue) },
michael@0 96 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.privateValue) },
michael@0 97 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.base) },
michael@0 98 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.prime) },
michael@0 99 { 0, }
michael@0 100 };
michael@0 101
michael@0 102 #ifndef NSS_DISABLE_ECC
michael@0 103
michael@0 104 /* XXX This is just a placeholder for later when we support
michael@0 105 * generic curves and need full-blown support for parsing EC
michael@0 106 * parameters. For now, we only support named curves in which
michael@0 107 * EC params are simply encoded as an object ID and we don't
michael@0 108 * use lg_nsslowkey_ECParamsTemplate.
michael@0 109 */
michael@0 110 const SEC_ASN1Template lg_nsslowkey_ECParamsTemplate[] = {
michael@0 111 { SEC_ASN1_CHOICE, offsetof(ECParams,type), NULL, sizeof(ECParams) },
michael@0 112 { SEC_ASN1_OBJECT_ID, offsetof(ECParams,curveOID), NULL, ec_params_named },
michael@0 113 { 0, }
michael@0 114 };
michael@0 115
michael@0 116
michael@0 117 /* NOTE: The SECG specification allows the private key structure
michael@0 118 * to contain curve parameters but recommends that they be stored
michael@0 119 * in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo
michael@0 120 * instead.
michael@0 121 */
michael@0 122 const SEC_ASN1Template lg_nsslowkey_ECPrivateKeyTemplate[] = {
michael@0 123 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
michael@0 124 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.ec.version) },
michael@0 125 { SEC_ASN1_OCTET_STRING,
michael@0 126 offsetof(NSSLOWKEYPrivateKey,u.ec.privateValue) },
michael@0 127 /* XXX The following template works for now since we only
michael@0 128 * support named curves for which the parameters are
michael@0 129 * encoded as an object ID. When we support generic curves,
michael@0 130 * we'll need to define lg_nsslowkey_ECParamsTemplate
michael@0 131 */
michael@0 132 #if 1
michael@0 133 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
michael@0 134 SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
michael@0 135 offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams.curveOID),
michael@0 136 SEC_ASN1_SUB(SEC_ObjectIDTemplate) },
michael@0 137 #else
michael@0 138 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
michael@0 139 SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 0,
michael@0 140 offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams),
michael@0 141 lg_nsslowkey_ECParamsTemplate },
michael@0 142 #endif
michael@0 143 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
michael@0 144 SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
michael@0 145 SEC_ASN1_XTRN | 1,
michael@0 146 offsetof(NSSLOWKEYPrivateKey,u.ec.publicValue),
michael@0 147 SEC_ASN1_SUB(SEC_BitStringTemplate) },
michael@0 148 { 0, }
michael@0 149 };
michael@0 150
michael@0 151
michael@0 152 /*
michael@0 153 * smaller version of EC_FillParams. In this code, we only need
michael@0 154 * oid and DER data.
michael@0 155 */
michael@0 156 SECStatus
michael@0 157 LGEC_FillParams(PLArenaPool *arena, const SECItem *encodedParams,
michael@0 158 ECParams *params)
michael@0 159 {
michael@0 160 SECOidTag tag;
michael@0 161 SECItem oid = { siBuffer, NULL, 0};
michael@0 162
michael@0 163 #if EC_DEBUG
michael@0 164 int i;
michael@0 165
michael@0 166 printf("Encoded params in EC_DecodeParams: ");
michael@0 167 for (i = 0; i < encodedParams->len; i++) {
michael@0 168 printf("%02x:", encodedParams->data[i]);
michael@0 169 }
michael@0 170 printf("\n");
michael@0 171 #endif
michael@0 172
michael@0 173 oid.len = encodedParams->len - 2;
michael@0 174 oid.data = encodedParams->data + 2;
michael@0 175 if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
michael@0 176 ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)) {
michael@0 177 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
michael@0 178 return SECFailure;
michael@0 179 }
michael@0 180
michael@0 181 params->arena = arena;
michael@0 182
michael@0 183 /* For named curves, fill out curveOID */
michael@0 184 params->curveOID.len = oid.len;
michael@0 185 params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(arena, oid.len);
michael@0 186 if (params->curveOID.data == NULL) {
michael@0 187 return SECFailure;
michael@0 188 }
michael@0 189 memcpy(params->curveOID.data, oid.data, oid.len);
michael@0 190
michael@0 191 return SECSuccess;
michael@0 192 }
michael@0 193
michael@0 194 /* Copy all of the fields from srcParams into dstParams
michael@0 195 */
michael@0 196 SECStatus
michael@0 197 LGEC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
michael@0 198 const ECParams *srcParams)
michael@0 199 {
michael@0 200 SECStatus rv = SECFailure;
michael@0 201
michael@0 202 dstParams->arena = arena;
michael@0 203 rv = SECITEM_CopyItem(arena, &dstParams->DEREncoding,
michael@0 204 &srcParams->DEREncoding);
michael@0 205 if (rv != SECSuccess) {
michael@0 206 goto loser;
michael@0 207 }
michael@0 208 rv =SECITEM_CopyItem(arena, &dstParams->curveOID,
michael@0 209 &srcParams->curveOID);
michael@0 210 if (rv != SECSuccess) {
michael@0 211 goto loser;
michael@0 212 }
michael@0 213
michael@0 214 return SECSuccess;
michael@0 215
michael@0 216 loser:
michael@0 217 return SECFailure;
michael@0 218 }
michael@0 219 #endif /* NSS_DISABLE_ECC */
michael@0 220 /*
michael@0 221 * See bugzilla bug 125359
michael@0 222 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
michael@0 223 * all of the templates above that en/decode into integers must be converted
michael@0 224 * from ASN.1's signed integer type. This is done by marking either the
michael@0 225 * source or destination (encoding or decoding, respectively) type as
michael@0 226 * siUnsignedInteger.
michael@0 227 */
michael@0 228
michael@0 229 void
michael@0 230 lg_prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
michael@0 231 {
michael@0 232 key->u.rsa.modulus.type = siUnsignedInteger;
michael@0 233 key->u.rsa.publicExponent.type = siUnsignedInteger;
michael@0 234 key->u.rsa.privateExponent.type = siUnsignedInteger;
michael@0 235 key->u.rsa.prime1.type = siUnsignedInteger;
michael@0 236 key->u.rsa.prime2.type = siUnsignedInteger;
michael@0 237 key->u.rsa.exponent1.type = siUnsignedInteger;
michael@0 238 key->u.rsa.exponent2.type = siUnsignedInteger;
michael@0 239 key->u.rsa.coefficient.type = siUnsignedInteger;
michael@0 240 }
michael@0 241
michael@0 242 void
michael@0 243 lg_prepare_low_pqg_params_for_asn1(PQGParams *params)
michael@0 244 {
michael@0 245 params->prime.type = siUnsignedInteger;
michael@0 246 params->subPrime.type = siUnsignedInteger;
michael@0 247 params->base.type = siUnsignedInteger;
michael@0 248 }
michael@0 249
michael@0 250 void
michael@0 251 lg_prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
michael@0 252 {
michael@0 253 key->u.dsa.publicValue.type = siUnsignedInteger;
michael@0 254 key->u.dsa.privateValue.type = siUnsignedInteger;
michael@0 255 key->u.dsa.params.prime.type = siUnsignedInteger;
michael@0 256 key->u.dsa.params.subPrime.type = siUnsignedInteger;
michael@0 257 key->u.dsa.params.base.type = siUnsignedInteger;
michael@0 258 }
michael@0 259
michael@0 260 void
michael@0 261 lg_prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
michael@0 262 {
michael@0 263 key->u.dh.prime.type = siUnsignedInteger;
michael@0 264 key->u.dh.base.type = siUnsignedInteger;
michael@0 265 key->u.dh.publicValue.type = siUnsignedInteger;
michael@0 266 key->u.dh.privateValue.type = siUnsignedInteger;
michael@0 267 }
michael@0 268
michael@0 269 #ifndef NSS_DISABLE_ECC
michael@0 270 void
michael@0 271 lg_prepare_low_ecparams_for_asn1(ECParams *params)
michael@0 272 {
michael@0 273 params->DEREncoding.type = siUnsignedInteger;
michael@0 274 params->curveOID.type = siUnsignedInteger;
michael@0 275 }
michael@0 276
michael@0 277 void
michael@0 278 lg_prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
michael@0 279 {
michael@0 280 key->u.ec.version.type = siUnsignedInteger;
michael@0 281 key->u.ec.ecParams.DEREncoding.type = siUnsignedInteger;
michael@0 282 key->u.ec.ecParams.curveOID.type = siUnsignedInteger;
michael@0 283 key->u.ec.privateValue.type = siUnsignedInteger;
michael@0 284 key->u.ec.publicValue.type = siUnsignedInteger;
michael@0 285 }
michael@0 286 #endif /* NSS_DISABLE_ECC */
michael@0 287
michael@0 288 void
michael@0 289 lg_nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk)
michael@0 290 {
michael@0 291 if (privk && privk->arena) {
michael@0 292 PORT_FreeArena(privk->arena, PR_TRUE);
michael@0 293 }
michael@0 294 }
michael@0 295
michael@0 296 void
michael@0 297 lg_nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk)
michael@0 298 {
michael@0 299 if (pubk && pubk->arena) {
michael@0 300 PORT_FreeArena(pubk->arena, PR_FALSE);
michael@0 301 }
michael@0 302 }
michael@0 303
michael@0 304 NSSLOWKEYPublicKey *
michael@0 305 lg_nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
michael@0 306 {
michael@0 307 NSSLOWKEYPublicKey *pubk;
michael@0 308 PLArenaPool *arena;
michael@0 309
michael@0 310
michael@0 311 arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
michael@0 312 if (arena == NULL) {
michael@0 313 PORT_SetError (SEC_ERROR_NO_MEMORY);
michael@0 314 return NULL;
michael@0 315 }
michael@0 316
michael@0 317 switch(privk->keyType) {
michael@0 318 case NSSLOWKEYRSAKey:
michael@0 319 case NSSLOWKEYNullKey:
michael@0 320 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
michael@0 321 sizeof (NSSLOWKEYPublicKey));
michael@0 322 if (pubk != NULL) {
michael@0 323 SECStatus rv;
michael@0 324
michael@0 325 pubk->arena = arena;
michael@0 326 pubk->keyType = privk->keyType;
michael@0 327 if (privk->keyType == NSSLOWKEYNullKey) return pubk;
michael@0 328 rv = SECITEM_CopyItem(arena, &pubk->u.rsa.modulus,
michael@0 329 &privk->u.rsa.modulus);
michael@0 330 if (rv == SECSuccess) {
michael@0 331 rv = SECITEM_CopyItem (arena, &pubk->u.rsa.publicExponent,
michael@0 332 &privk->u.rsa.publicExponent);
michael@0 333 if (rv == SECSuccess)
michael@0 334 return pubk;
michael@0 335 }
michael@0 336 } else {
michael@0 337 PORT_SetError (SEC_ERROR_NO_MEMORY);
michael@0 338 }
michael@0 339 break;
michael@0 340 case NSSLOWKEYDSAKey:
michael@0 341 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
michael@0 342 sizeof(NSSLOWKEYPublicKey));
michael@0 343 if (pubk != NULL) {
michael@0 344 SECStatus rv;
michael@0 345
michael@0 346 pubk->arena = arena;
michael@0 347 pubk->keyType = privk->keyType;
michael@0 348 rv = SECITEM_CopyItem(arena, &pubk->u.dsa.publicValue,
michael@0 349 &privk->u.dsa.publicValue);
michael@0 350 if (rv != SECSuccess) break;
michael@0 351 rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime,
michael@0 352 &privk->u.dsa.params.prime);
michael@0 353 if (rv != SECSuccess) break;
michael@0 354 rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime,
michael@0 355 &privk->u.dsa.params.subPrime);
michael@0 356 if (rv != SECSuccess) break;
michael@0 357 rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base,
michael@0 358 &privk->u.dsa.params.base);
michael@0 359 if (rv == SECSuccess) return pubk;
michael@0 360 }
michael@0 361 break;
michael@0 362 case NSSLOWKEYDHKey:
michael@0 363 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
michael@0 364 sizeof(NSSLOWKEYPublicKey));
michael@0 365 if (pubk != NULL) {
michael@0 366 SECStatus rv;
michael@0 367
michael@0 368 pubk->arena = arena;
michael@0 369 pubk->keyType = privk->keyType;
michael@0 370 rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue,
michael@0 371 &privk->u.dh.publicValue);
michael@0 372 if (rv != SECSuccess) break;
michael@0 373 rv = SECITEM_CopyItem(arena, &pubk->u.dh.prime,
michael@0 374 &privk->u.dh.prime);
michael@0 375 if (rv != SECSuccess) break;
michael@0 376 rv = SECITEM_CopyItem(arena, &pubk->u.dh.base,
michael@0 377 &privk->u.dh.base);
michael@0 378 if (rv == SECSuccess) return pubk;
michael@0 379 }
michael@0 380 break;
michael@0 381 #ifndef NSS_DISABLE_ECC
michael@0 382 case NSSLOWKEYECKey:
michael@0 383 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
michael@0 384 sizeof(NSSLOWKEYPublicKey));
michael@0 385 if (pubk != NULL) {
michael@0 386 SECStatus rv;
michael@0 387
michael@0 388 pubk->arena = arena;
michael@0 389 pubk->keyType = privk->keyType;
michael@0 390 rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue,
michael@0 391 &privk->u.ec.publicValue);
michael@0 392 if (rv != SECSuccess) break;
michael@0 393 pubk->u.ec.ecParams.arena = arena;
michael@0 394 /* Copy the rest of the params */
michael@0 395 rv = LGEC_CopyParams(arena, &(pubk->u.ec.ecParams),
michael@0 396 &(privk->u.ec.ecParams));
michael@0 397 if (rv == SECSuccess) return pubk;
michael@0 398 }
michael@0 399 break;
michael@0 400 #endif /* NSS_DISABLE_ECC */
michael@0 401 /* No Fortezza in Low Key implementations (Fortezza keys aren't
michael@0 402 * stored in our data base */
michael@0 403 default:
michael@0 404 break;
michael@0 405 }
michael@0 406
michael@0 407 PORT_FreeArena (arena, PR_FALSE);
michael@0 408 return NULL;
michael@0 409 }
michael@0 410

mercurial