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