Coverage Report

Created: 2024-11-21 07:03

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