security/nss/lib/softoken/lowkey.c

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

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 "base64.h"
michael@0 9 #include "secasn1.h"
michael@0 10 #include "secerr.h"
michael@0 11
michael@0 12 #ifndef NSS_DISABLE_ECC
michael@0 13 #include "softoken.h"
michael@0 14 #endif
michael@0 15
michael@0 16 SEC_ASN1_MKSUB(SEC_AnyTemplate)
michael@0 17 SEC_ASN1_MKSUB(SEC_BitStringTemplate)
michael@0 18 SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
michael@0 19 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
michael@0 20
michael@0 21 const SEC_ASN1Template nsslowkey_AttributeTemplate[] = {
michael@0 22 { SEC_ASN1_SEQUENCE,
michael@0 23 0, NULL, sizeof(NSSLOWKEYAttribute) },
michael@0 24 { SEC_ASN1_OBJECT_ID, offsetof(NSSLOWKEYAttribute, attrType) },
michael@0 25 { SEC_ASN1_SET_OF | SEC_ASN1_XTRN ,
michael@0 26 offsetof(NSSLOWKEYAttribute, attrValue),
michael@0 27 SEC_ASN1_SUB(SEC_AnyTemplate) },
michael@0 28 { 0 }
michael@0 29 };
michael@0 30
michael@0 31 const SEC_ASN1Template nsslowkey_SetOfAttributeTemplate[] = {
michael@0 32 { SEC_ASN1_SET_OF, 0, nsslowkey_AttributeTemplate },
michael@0 33 };
michael@0 34 /* ASN1 Templates for new decoder/encoder */
michael@0 35 const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[] = {
michael@0 36 { SEC_ASN1_SEQUENCE,
michael@0 37 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) },
michael@0 38 { SEC_ASN1_INTEGER,
michael@0 39 offsetof(NSSLOWKEYPrivateKeyInfo,version) },
michael@0 40 { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
michael@0 41 offsetof(NSSLOWKEYPrivateKeyInfo,algorithm),
michael@0 42 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
michael@0 43 { SEC_ASN1_OCTET_STRING,
michael@0 44 offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) },
michael@0 45 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
michael@0 46 offsetof(NSSLOWKEYPrivateKeyInfo, attributes),
michael@0 47 nsslowkey_SetOfAttributeTemplate },
michael@0 48 { 0 }
michael@0 49 };
michael@0 50
michael@0 51 const SEC_ASN1Template nsslowkey_PQGParamsTemplate[] = {
michael@0 52 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PQGParams) },
michael@0 53 { SEC_ASN1_INTEGER, offsetof(PQGParams,prime) },
michael@0 54 { SEC_ASN1_INTEGER, offsetof(PQGParams,subPrime) },
michael@0 55 { SEC_ASN1_INTEGER, offsetof(PQGParams,base) },
michael@0 56 { 0, }
michael@0 57 };
michael@0 58
michael@0 59 const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[] = {
michael@0 60 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
michael@0 61 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.version) },
michael@0 62 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.modulus) },
michael@0 63 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.publicExponent) },
michael@0 64 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.privateExponent) },
michael@0 65 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime1) },
michael@0 66 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime2) },
michael@0 67 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent1) },
michael@0 68 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent2) },
michael@0 69 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.coefficient) },
michael@0 70 { 0 }
michael@0 71 };
michael@0 72
michael@0 73
michael@0 74 const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[] = {
michael@0 75 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
michael@0 76 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.publicValue) },
michael@0 77 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) },
michael@0 78 { 0, }
michael@0 79 };
michael@0 80
michael@0 81 const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[] = {
michael@0 82 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) },
michael@0 83 };
michael@0 84
michael@0 85 const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[] = {
michael@0 86 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
michael@0 87 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.publicValue) },
michael@0 88 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.privateValue) },
michael@0 89 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.base) },
michael@0 90 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.prime) },
michael@0 91 { 0, }
michael@0 92 };
michael@0 93
michael@0 94 #ifndef NSS_DISABLE_ECC
michael@0 95
michael@0 96 /* XXX This is just a placeholder for later when we support
michael@0 97 * generic curves and need full-blown support for parsing EC
michael@0 98 * parameters. For now, we only support named curves in which
michael@0 99 * EC params are simply encoded as an object ID and we don't
michael@0 100 * use nsslowkey_ECParamsTemplate.
michael@0 101 */
michael@0 102 const SEC_ASN1Template nsslowkey_ECParamsTemplate[] = {
michael@0 103 { SEC_ASN1_CHOICE, offsetof(ECParams,type), NULL, sizeof(ECParams) },
michael@0 104 { SEC_ASN1_OBJECT_ID, offsetof(ECParams,curveOID), NULL, ec_params_named },
michael@0 105 { 0, }
michael@0 106 };
michael@0 107
michael@0 108
michael@0 109 /* NOTE: The SECG specification allows the private key structure
michael@0 110 * to contain curve parameters but recommends that they be stored
michael@0 111 * in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo
michael@0 112 * instead.
michael@0 113 */
michael@0 114 const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[] = {
michael@0 115 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
michael@0 116 { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.ec.version) },
michael@0 117 { SEC_ASN1_OCTET_STRING,
michael@0 118 offsetof(NSSLOWKEYPrivateKey,u.ec.privateValue) },
michael@0 119 /* XXX The following template works for now since we only
michael@0 120 * support named curves for which the parameters are
michael@0 121 * encoded as an object ID. When we support generic curves,
michael@0 122 * we'll need to define nsslowkey_ECParamsTemplate
michael@0 123 */
michael@0 124 #if 1
michael@0 125 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
michael@0 126 SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
michael@0 127 SEC_ASN1_XTRN | 0,
michael@0 128 offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams.curveOID),
michael@0 129 SEC_ASN1_SUB(SEC_ObjectIDTemplate) },
michael@0 130 #else
michael@0 131 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
michael@0 132 SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 0,
michael@0 133 offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams),
michael@0 134 nsslowkey_ECParamsTemplate },
michael@0 135 #endif
michael@0 136 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
michael@0 137 SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
michael@0 138 SEC_ASN1_XTRN | 1,
michael@0 139 offsetof(NSSLOWKEYPrivateKey,u.ec.publicValue),
michael@0 140 SEC_ASN1_SUB(SEC_BitStringTemplate) },
michael@0 141 { 0, }
michael@0 142 };
michael@0 143 #endif /* NSS_DISABLE_ECC */
michael@0 144 /*
michael@0 145 * See bugzilla bug 125359
michael@0 146 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
michael@0 147 * all of the templates above that en/decode into integers must be converted
michael@0 148 * from ASN.1's signed integer type. This is done by marking either the
michael@0 149 * source or destination (encoding or decoding, respectively) type as
michael@0 150 * siUnsignedInteger.
michael@0 151 */
michael@0 152
michael@0 153 void
michael@0 154 prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
michael@0 155 {
michael@0 156 key->u.rsa.modulus.type = siUnsignedInteger;
michael@0 157 key->u.rsa.publicExponent.type = siUnsignedInteger;
michael@0 158 key->u.rsa.privateExponent.type = siUnsignedInteger;
michael@0 159 key->u.rsa.prime1.type = siUnsignedInteger;
michael@0 160 key->u.rsa.prime2.type = siUnsignedInteger;
michael@0 161 key->u.rsa.exponent1.type = siUnsignedInteger;
michael@0 162 key->u.rsa.exponent2.type = siUnsignedInteger;
michael@0 163 key->u.rsa.coefficient.type = siUnsignedInteger;
michael@0 164 }
michael@0 165
michael@0 166 void
michael@0 167 prepare_low_pqg_params_for_asn1(PQGParams *params)
michael@0 168 {
michael@0 169 params->prime.type = siUnsignedInteger;
michael@0 170 params->subPrime.type = siUnsignedInteger;
michael@0 171 params->base.type = siUnsignedInteger;
michael@0 172 }
michael@0 173
michael@0 174 void
michael@0 175 prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
michael@0 176 {
michael@0 177 key->u.dsa.publicValue.type = siUnsignedInteger;
michael@0 178 key->u.dsa.privateValue.type = siUnsignedInteger;
michael@0 179 key->u.dsa.params.prime.type = siUnsignedInteger;
michael@0 180 key->u.dsa.params.subPrime.type = siUnsignedInteger;
michael@0 181 key->u.dsa.params.base.type = siUnsignedInteger;
michael@0 182 }
michael@0 183
michael@0 184 void
michael@0 185 prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key)
michael@0 186 {
michael@0 187 key->u.dsa.privateValue.type = siUnsignedInteger;
michael@0 188 }
michael@0 189
michael@0 190 void
michael@0 191 prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
michael@0 192 {
michael@0 193 key->u.dh.prime.type = siUnsignedInteger;
michael@0 194 key->u.dh.base.type = siUnsignedInteger;
michael@0 195 key->u.dh.publicValue.type = siUnsignedInteger;
michael@0 196 key->u.dh.privateValue.type = siUnsignedInteger;
michael@0 197 }
michael@0 198
michael@0 199 #ifndef NSS_DISABLE_ECC
michael@0 200 void
michael@0 201 prepare_low_ecparams_for_asn1(ECParams *params)
michael@0 202 {
michael@0 203 params->DEREncoding.type = siUnsignedInteger;
michael@0 204 params->curveOID.type = siUnsignedInteger;
michael@0 205 }
michael@0 206
michael@0 207 void
michael@0 208 prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
michael@0 209 {
michael@0 210 key->u.ec.version.type = siUnsignedInteger;
michael@0 211 key->u.ec.ecParams.DEREncoding.type = siUnsignedInteger;
michael@0 212 key->u.ec.ecParams.curveOID.type = siUnsignedInteger;
michael@0 213 key->u.ec.privateValue.type = siUnsignedInteger;
michael@0 214 key->u.ec.publicValue.type = siUnsignedInteger;
michael@0 215 }
michael@0 216 #endif /* NSS_DISABLE_ECC */
michael@0 217
michael@0 218 void
michael@0 219 nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk)
michael@0 220 {
michael@0 221 if (privk && privk->arena) {
michael@0 222 PORT_FreeArena(privk->arena, PR_TRUE);
michael@0 223 }
michael@0 224 }
michael@0 225
michael@0 226 void
michael@0 227 nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk)
michael@0 228 {
michael@0 229 if (pubk && pubk->arena) {
michael@0 230 PORT_FreeArena(pubk->arena, PR_FALSE);
michael@0 231 }
michael@0 232 }
michael@0 233 unsigned
michael@0 234 nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubk)
michael@0 235 {
michael@0 236 unsigned char b0;
michael@0 237
michael@0 238 /* interpret modulus length as key strength... in
michael@0 239 * fortezza that's the public key length */
michael@0 240
michael@0 241 switch (pubk->keyType) {
michael@0 242 case NSSLOWKEYRSAKey:
michael@0 243 b0 = pubk->u.rsa.modulus.data[0];
michael@0 244 return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1;
michael@0 245 default:
michael@0 246 break;
michael@0 247 }
michael@0 248 return 0;
michael@0 249 }
michael@0 250
michael@0 251 unsigned
michael@0 252 nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privk)
michael@0 253 {
michael@0 254
michael@0 255 unsigned char b0;
michael@0 256
michael@0 257 switch (privk->keyType) {
michael@0 258 case NSSLOWKEYRSAKey:
michael@0 259 b0 = privk->u.rsa.modulus.data[0];
michael@0 260 return b0 ? privk->u.rsa.modulus.len : privk->u.rsa.modulus.len - 1;
michael@0 261 default:
michael@0 262 break;
michael@0 263 }
michael@0 264 return 0;
michael@0 265 }
michael@0 266
michael@0 267 NSSLOWKEYPublicKey *
michael@0 268 nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
michael@0 269 {
michael@0 270 NSSLOWKEYPublicKey *pubk;
michael@0 271 PLArenaPool *arena;
michael@0 272
michael@0 273
michael@0 274 arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
michael@0 275 if (arena == NULL) {
michael@0 276 PORT_SetError (SEC_ERROR_NO_MEMORY);
michael@0 277 return NULL;
michael@0 278 }
michael@0 279
michael@0 280 switch(privk->keyType) {
michael@0 281 case NSSLOWKEYRSAKey:
michael@0 282 case NSSLOWKEYNullKey:
michael@0 283 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
michael@0 284 sizeof (NSSLOWKEYPublicKey));
michael@0 285 if (pubk != NULL) {
michael@0 286 SECStatus rv;
michael@0 287
michael@0 288 pubk->arena = arena;
michael@0 289 pubk->keyType = privk->keyType;
michael@0 290 if (privk->keyType == NSSLOWKEYNullKey) return pubk;
michael@0 291 rv = SECITEM_CopyItem(arena, &pubk->u.rsa.modulus,
michael@0 292 &privk->u.rsa.modulus);
michael@0 293 if (rv == SECSuccess) {
michael@0 294 rv = SECITEM_CopyItem (arena, &pubk->u.rsa.publicExponent,
michael@0 295 &privk->u.rsa.publicExponent);
michael@0 296 if (rv == SECSuccess)
michael@0 297 return pubk;
michael@0 298 }
michael@0 299 } else {
michael@0 300 PORT_SetError (SEC_ERROR_NO_MEMORY);
michael@0 301 }
michael@0 302 break;
michael@0 303 case NSSLOWKEYDSAKey:
michael@0 304 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
michael@0 305 sizeof(NSSLOWKEYPublicKey));
michael@0 306 if (pubk != NULL) {
michael@0 307 SECStatus rv;
michael@0 308
michael@0 309 pubk->arena = arena;
michael@0 310 pubk->keyType = privk->keyType;
michael@0 311 rv = SECITEM_CopyItem(arena, &pubk->u.dsa.publicValue,
michael@0 312 &privk->u.dsa.publicValue);
michael@0 313 if (rv != SECSuccess) break;
michael@0 314 rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime,
michael@0 315 &privk->u.dsa.params.prime);
michael@0 316 if (rv != SECSuccess) break;
michael@0 317 rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime,
michael@0 318 &privk->u.dsa.params.subPrime);
michael@0 319 if (rv != SECSuccess) break;
michael@0 320 rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base,
michael@0 321 &privk->u.dsa.params.base);
michael@0 322 if (rv == SECSuccess) return pubk;
michael@0 323 }
michael@0 324 break;
michael@0 325 case NSSLOWKEYDHKey:
michael@0 326 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
michael@0 327 sizeof(NSSLOWKEYPublicKey));
michael@0 328 if (pubk != NULL) {
michael@0 329 SECStatus rv;
michael@0 330
michael@0 331 pubk->arena = arena;
michael@0 332 pubk->keyType = privk->keyType;
michael@0 333 rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue,
michael@0 334 &privk->u.dh.publicValue);
michael@0 335 if (rv != SECSuccess) break;
michael@0 336 rv = SECITEM_CopyItem(arena, &pubk->u.dh.prime,
michael@0 337 &privk->u.dh.prime);
michael@0 338 if (rv != SECSuccess) break;
michael@0 339 rv = SECITEM_CopyItem(arena, &pubk->u.dh.base,
michael@0 340 &privk->u.dh.base);
michael@0 341 if (rv == SECSuccess) return pubk;
michael@0 342 }
michael@0 343 break;
michael@0 344 #ifndef NSS_DISABLE_ECC
michael@0 345 case NSSLOWKEYECKey:
michael@0 346 pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
michael@0 347 sizeof(NSSLOWKEYPublicKey));
michael@0 348 if (pubk != NULL) {
michael@0 349 SECStatus rv;
michael@0 350
michael@0 351 pubk->arena = arena;
michael@0 352 pubk->keyType = privk->keyType;
michael@0 353 rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue,
michael@0 354 &privk->u.ec.publicValue);
michael@0 355 if (rv != SECSuccess) break;
michael@0 356 pubk->u.ec.ecParams.arena = arena;
michael@0 357 /* Copy the rest of the params */
michael@0 358 rv = EC_CopyParams(arena, &(pubk->u.ec.ecParams),
michael@0 359 &(privk->u.ec.ecParams));
michael@0 360 if (rv == SECSuccess) return pubk;
michael@0 361 }
michael@0 362 break;
michael@0 363 #endif /* NSS_DISABLE_ECC */
michael@0 364 /* No Fortezza in Low Key implementations (Fortezza keys aren't
michael@0 365 * stored in our data base */
michael@0 366 default:
michael@0 367 break;
michael@0 368 }
michael@0 369
michael@0 370 PORT_FreeArena (arena, PR_FALSE);
michael@0 371 return NULL;
michael@0 372 }
michael@0 373
michael@0 374 NSSLOWKEYPrivateKey *
michael@0 375 nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey)
michael@0 376 {
michael@0 377 NSSLOWKEYPrivateKey *returnKey = NULL;
michael@0 378 SECStatus rv = SECFailure;
michael@0 379 PLArenaPool *poolp;
michael@0 380
michael@0 381 if(!privKey) {
michael@0 382 return NULL;
michael@0 383 }
michael@0 384
michael@0 385 poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
michael@0 386 if(!poolp) {
michael@0 387 return NULL;
michael@0 388 }
michael@0 389
michael@0 390 returnKey = (NSSLOWKEYPrivateKey*)PORT_ArenaZAlloc(poolp, sizeof(NSSLOWKEYPrivateKey));
michael@0 391 if(!returnKey) {
michael@0 392 rv = SECFailure;
michael@0 393 goto loser;
michael@0 394 }
michael@0 395
michael@0 396 returnKey->keyType = privKey->keyType;
michael@0 397 returnKey->arena = poolp;
michael@0 398
michael@0 399 switch(privKey->keyType) {
michael@0 400 case NSSLOWKEYRSAKey:
michael@0 401 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.modulus),
michael@0 402 &(privKey->u.rsa.modulus));
michael@0 403 if(rv != SECSuccess) break;
michael@0 404 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.version),
michael@0 405 &(privKey->u.rsa.version));
michael@0 406 if(rv != SECSuccess) break;
michael@0 407 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.publicExponent),
michael@0 408 &(privKey->u.rsa.publicExponent));
michael@0 409 if(rv != SECSuccess) break;
michael@0 410 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.privateExponent),
michael@0 411 &(privKey->u.rsa.privateExponent));
michael@0 412 if(rv != SECSuccess) break;
michael@0 413 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime1),
michael@0 414 &(privKey->u.rsa.prime1));
michael@0 415 if(rv != SECSuccess) break;
michael@0 416 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime2),
michael@0 417 &(privKey->u.rsa.prime2));
michael@0 418 if(rv != SECSuccess) break;
michael@0 419 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent1),
michael@0 420 &(privKey->u.rsa.exponent1));
michael@0 421 if(rv != SECSuccess) break;
michael@0 422 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent2),
michael@0 423 &(privKey->u.rsa.exponent2));
michael@0 424 if(rv != SECSuccess) break;
michael@0 425 rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.coefficient),
michael@0 426 &(privKey->u.rsa.coefficient));
michael@0 427 if(rv != SECSuccess) break;
michael@0 428 break;
michael@0 429 case NSSLOWKEYDSAKey:
michael@0 430 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.publicValue),
michael@0 431 &(privKey->u.dsa.publicValue));
michael@0 432 if(rv != SECSuccess) break;
michael@0 433 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.privateValue),
michael@0 434 &(privKey->u.dsa.privateValue));
michael@0 435 if(rv != SECSuccess) break;
michael@0 436 returnKey->u.dsa.params.arena = poolp;
michael@0 437 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.prime),
michael@0 438 &(privKey->u.dsa.params.prime));
michael@0 439 if(rv != SECSuccess) break;
michael@0 440 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.subPrime),
michael@0 441 &(privKey->u.dsa.params.subPrime));
michael@0 442 if(rv != SECSuccess) break;
michael@0 443 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.base),
michael@0 444 &(privKey->u.dsa.params.base));
michael@0 445 if(rv != SECSuccess) break;
michael@0 446 break;
michael@0 447 case NSSLOWKEYDHKey:
michael@0 448 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.publicValue),
michael@0 449 &(privKey->u.dh.publicValue));
michael@0 450 if(rv != SECSuccess) break;
michael@0 451 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.privateValue),
michael@0 452 &(privKey->u.dh.privateValue));
michael@0 453 if(rv != SECSuccess) break;
michael@0 454 returnKey->u.dsa.params.arena = poolp;
michael@0 455 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.prime),
michael@0 456 &(privKey->u.dh.prime));
michael@0 457 if(rv != SECSuccess) break;
michael@0 458 rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.base),
michael@0 459 &(privKey->u.dh.base));
michael@0 460 if(rv != SECSuccess) break;
michael@0 461 break;
michael@0 462 #ifndef NSS_DISABLE_ECC
michael@0 463 case NSSLOWKEYECKey:
michael@0 464 rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.version),
michael@0 465 &(privKey->u.ec.version));
michael@0 466 if(rv != SECSuccess) break;
michael@0 467 rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.publicValue),
michael@0 468 &(privKey->u.ec.publicValue));
michael@0 469 if(rv != SECSuccess) break;
michael@0 470 rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.privateValue),
michael@0 471 &(privKey->u.ec.privateValue));
michael@0 472 if(rv != SECSuccess) break;
michael@0 473 returnKey->u.ec.ecParams.arena = poolp;
michael@0 474 /* Copy the rest of the params */
michael@0 475 rv = EC_CopyParams(poolp, &(returnKey->u.ec.ecParams),
michael@0 476 &(privKey->u.ec.ecParams));
michael@0 477 if (rv != SECSuccess) break;
michael@0 478 break;
michael@0 479 #endif /* NSS_DISABLE_ECC */
michael@0 480 default:
michael@0 481 rv = SECFailure;
michael@0 482 }
michael@0 483
michael@0 484 loser:
michael@0 485
michael@0 486 if(rv != SECSuccess) {
michael@0 487 PORT_FreeArena(poolp, PR_TRUE);
michael@0 488 returnKey = NULL;
michael@0 489 }
michael@0 490
michael@0 491 return returnKey;
michael@0 492 }

mercurial