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
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)