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