comparison nss/lib/pk11wrap/pk11pqg.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
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 /* Thse functions are stub functions which will get replaced with calls through
5 * PKCS #11.
6 */
7
8 #include "pk11func.h"
9 #include "secmod.h"
10 #include "secmodi.h"
11 #include "secmodti.h"
12 #include "pkcs11t.h"
13 #include "pk11pqg.h"
14 #include "secerr.h"
15
16
17 /* Generate PQGParams and PQGVerify structs.
18 * Length of P specified by L.
19 * if L is greater than 1024 then the resulting verify parameters will be
20 * DSA2.
21 * Length of Q specified by N. If zero, The PKCS #11 module will
22 * pick an appropriately sized Q for P. If N is specified and L = 1024, then
23 * the resulting verify parameters will be DSA2, Otherwise DSA1 parameters
24 * will be returned.
25 * Length of SEED in bytes specified in seedBytes.
26 *
27 * The underlying PKCS #11 module will check the values for L, N,
28 * and seedBytes. The rules for softoken are:
29 *
30 * If L <= 1024, then L must be between 512 and 1024 in increments of 64 bits.
31 * If L <= 1024, then N must be 0 or 160.
32 * If L >= 1024, then L and N must match the following table:
33 * L=1024 N=0 or 160
34 * L=2048 N=0 or 224
35 * L=2048 N=256
36 * L=3072 N=0 or 256
37 * if L <= 1024
38 * seedBbytes must be in the range [20..256].
39 * if L >= 1024
40 * seedBbytes must be in the range [20..L/16].
41 */
42 extern SECStatus
43 PK11_PQG_ParamGenV2(unsigned int L, unsigned int N,
44 unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy)
45 {
46 PK11SlotInfo *slot = NULL;
47 CK_ATTRIBUTE genTemplate[5];
48 CK_ATTRIBUTE *attrs = genTemplate;
49 int count = sizeof(genTemplate)/sizeof(genTemplate[0]);
50 CK_MECHANISM mechanism;
51 CK_OBJECT_HANDLE objectID = CK_INVALID_HANDLE;
52 CK_RV crv;
53 CK_ATTRIBUTE pTemplate[] = {
54 { CKA_PRIME, NULL, 0 },
55 { CKA_SUBPRIME, NULL, 0 },
56 { CKA_BASE, NULL, 0 },
57 };
58 CK_ATTRIBUTE vTemplate[] = {
59 { CKA_NETSCAPE_PQG_COUNTER, NULL, 0 },
60 { CKA_NETSCAPE_PQG_SEED, NULL, 0 },
61 { CKA_NETSCAPE_PQG_H, NULL, 0 },
62 };
63 CK_ULONG primeBits = L;
64 CK_ULONG subPrimeBits = N;
65 int pTemplateCount = sizeof(pTemplate)/sizeof(pTemplate[0]);
66 int vTemplateCount = sizeof(vTemplate)/sizeof(vTemplate[0]);
67 PLArenaPool *parena = NULL;
68 PLArenaPool *varena = NULL;
69 PQGParams *params = NULL;
70 PQGVerify *verify = NULL;
71 CK_ULONG seedBits = seedBytes*8;
72
73 *pParams = NULL;
74 *pVfy = NULL;
75
76 if (primeBits == (CK_ULONG)-1) {
77 PORT_SetError(SEC_ERROR_INVALID_ARGS);
78 goto loser;
79 }
80 PK11_SETATTRS(attrs, CKA_PRIME_BITS,&primeBits,sizeof(primeBits)); attrs++;
81 if (subPrimeBits != 0) {
82 PK11_SETATTRS(attrs, CKA_SUB_PRIME_BITS,
83 &subPrimeBits, sizeof(subPrimeBits)); attrs++;
84 }
85 if (seedBits != 0) {
86 PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED_BITS,
87 &seedBits, sizeof(seedBits)); attrs++;
88 }
89 count = attrs - genTemplate;
90 PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE));
91
92 slot = PK11_GetInternalSlot();
93 if (slot == NULL) {
94 /* set error */
95 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);/* shouldn't happen */
96 goto loser;
97 }
98
99 /* make sure the internal slot can handle DSA2 type parameters. */
100 if (primeBits > 1024) {
101 CK_MECHANISM_INFO mechanism_info;
102
103 if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
104 crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
105 CKM_DSA_PARAMETER_GEN, &mechanism_info);
106 if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
107 /* a bug in the old softoken left CKM_DSA_PARAMETER_GEN off of the
108 * mechanism List. If we get a failure asking for this value, we know
109 * it can't handle DSA2 */
110 if ((crv != CKR_OK) || (mechanism_info.ulMaxKeySize < primeBits)) {
111 PK11_FreeSlot(slot);
112 slot = PK11_GetBestSlotWithAttributes(CKM_DSA_PARAMETER_GEN, 0,
113 primeBits, NULL);
114 if (slot == NULL) {
115 PORT_SetError(SEC_ERROR_NO_TOKEN); /* can happen */
116 goto loser;
117 }
118 /* ditch seedBits in this case, they are NSS specific and at
119 * this point we have a token that claims to handle DSA2 */
120 if (seedBits) {
121 attrs--;
122 }
123 }
124 }
125
126 /* Initialize the Key Gen Mechanism */
127 mechanism.mechanism = CKM_DSA_PARAMETER_GEN;
128 mechanism.pParameter = NULL;
129 mechanism.ulParameterLen = 0;
130
131 PK11_EnterSlotMonitor(slot);
132 crv = PK11_GETTAB(slot)->C_GenerateKey(slot->session,
133 &mechanism, genTemplate, count, &objectID);
134 PK11_ExitSlotMonitor(slot);
135
136 if (crv != CKR_OK) {
137 PORT_SetError( PK11_MapError(crv) );
138 goto loser;
139 }
140
141 parena = PORT_NewArena(60);
142 if (!parena) {
143 goto loser;
144 }
145
146 crv = PK11_GetAttributes(parena, slot, objectID, pTemplate, pTemplateCount);
147 if (crv != CKR_OK) {
148 PORT_SetError( PK11_MapError(crv) );
149 goto loser;
150 }
151
152
153 params = (PQGParams *)PORT_ArenaAlloc(parena,sizeof(PQGParams));
154 if (params == NULL) {
155 goto loser;
156 }
157
158 /* fill in Params */
159 params->arena = parena;
160 params->prime.type = siUnsignedInteger;
161 params->prime.data = pTemplate[0].pValue;
162 params->prime.len = pTemplate[0].ulValueLen;
163 params->subPrime.type = siUnsignedInteger;
164 params->subPrime.data = pTemplate[1].pValue;
165 params->subPrime.len = pTemplate[1].ulValueLen;
166 params->base.type = siUnsignedInteger;
167 params->base.data = pTemplate[2].pValue;
168 params->base.len = pTemplate[2].ulValueLen;
169
170
171 varena = PORT_NewArena(60);
172 if (!varena) {
173 goto loser;
174 }
175
176 crv = PK11_GetAttributes(varena, slot, objectID, vTemplate, vTemplateCount);
177 if (crv != CKR_OK) {
178 PORT_SetError( PK11_MapError(crv) );
179 goto loser;
180 }
181
182
183 verify = (PQGVerify *)PORT_ArenaAlloc(varena,sizeof(PQGVerify));
184 if (verify == NULL) {
185 goto loser;
186 }
187 /* fill in Params */
188 verify->arena = varena;
189 verify->counter = (unsigned int)(*(CK_ULONG*)vTemplate[0].pValue);
190 verify->seed.type = siUnsignedInteger;
191 verify->seed.data = vTemplate[1].pValue;
192 verify->seed.len = vTemplate[1].ulValueLen;
193 verify->h.type = siUnsignedInteger;
194 verify->h.data = vTemplate[2].pValue;
195 verify->h.len = vTemplate[2].ulValueLen;
196
197 PK11_DestroyObject(slot,objectID);
198 PK11_FreeSlot(slot);
199
200 *pParams = params;
201 *pVfy = verify;
202
203 return SECSuccess;
204
205 loser:
206 if (objectID != CK_INVALID_HANDLE) {
207 PK11_DestroyObject(slot,objectID);
208 }
209 if (parena != NULL) {
210 PORT_FreeArena(parena,PR_FALSE);
211 }
212 if (varena != NULL) {
213 PORT_FreeArena(varena,PR_FALSE);
214 }
215 if (slot) {
216 PK11_FreeSlot(slot);
217 }
218 return SECFailure;
219 }
220
221 /* Generate PQGParams and PQGVerify structs.
222 * Length of P specified by j. Length of h will match length of P.
223 * Length of SEED in bytes specified in seedBytes.
224 * seedBbytes must be in the range [20..255] or an error will result.
225 */
226 extern SECStatus
227 PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes,
228 PQGParams **pParams, PQGVerify **pVfy)
229 {
230 unsigned int primeBits = PQG_INDEX_TO_PBITS(j);
231 return PK11_PQG_ParamGenV2(primeBits, 0, seedBytes, pParams, pVfy);
232 }
233
234 /* Generate PQGParams and PQGVerify structs.
235 * Length of seed and length of h both equal length of P.
236 * All lengths are specified by "j", according to the table above.
237 */
238 extern SECStatus
239 PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy)
240 {
241 unsigned int primeBits = PQG_INDEX_TO_PBITS(j);
242 return PK11_PQG_ParamGenV2(primeBits, 0, 0, pParams, pVfy);
243 }
244
245 /* Test PQGParams for validity as DSS PQG values.
246 * If vfy is non-NULL, test PQGParams to make sure they were generated
247 * using the specified seed, counter, and h values.
248 *
249 * Return value indicates whether Verification operation ran successfully
250 * to completion, but does not indicate if PQGParams are valid or not.
251 * If return value is SECSuccess, then *pResult has these meanings:
252 * SECSuccess: PQGParams are valid.
253 * SECFailure: PQGParams are invalid.
254 */
255
256 extern SECStatus
257 PK11_PQG_VerifyParams(const PQGParams *params, const PQGVerify *vfy,
258 SECStatus *result)
259 {
260 CK_ATTRIBUTE keyTempl[] = {
261 { CKA_CLASS, NULL, 0 },
262 { CKA_KEY_TYPE, NULL, 0 },
263 { CKA_PRIME, NULL, 0 },
264 { CKA_SUBPRIME, NULL, 0 },
265 { CKA_BASE, NULL, 0 },
266 { CKA_TOKEN, NULL, 0 },
267 { CKA_NETSCAPE_PQG_COUNTER, NULL, 0 },
268 { CKA_NETSCAPE_PQG_SEED, NULL, 0 },
269 { CKA_NETSCAPE_PQG_H, NULL, 0 },
270 };
271 CK_ATTRIBUTE *attrs;
272 CK_BBOOL ckfalse = CK_FALSE;
273 CK_OBJECT_CLASS class = CKO_KG_PARAMETERS;
274 CK_KEY_TYPE keyType = CKK_DSA;
275 SECStatus rv = SECSuccess;
276 PK11SlotInfo *slot;
277 int keyCount;
278 CK_OBJECT_HANDLE objectID;
279 CK_ULONG counter;
280 CK_RV crv;
281
282 attrs = keyTempl;
283 PK11_SETATTRS(attrs, CKA_CLASS, &class, sizeof(class)); attrs++;
284 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++;
285 PK11_SETATTRS(attrs, CKA_PRIME, params->prime.data,
286 params->prime.len); attrs++;
287 PK11_SETATTRS(attrs, CKA_SUBPRIME, params->subPrime.data,
288 params->subPrime.len); attrs++;
289 if (params->base.len) {
290 PK11_SETATTRS(attrs, CKA_BASE,params->base.data,params->base.len);
291 attrs++;
292 }
293 PK11_SETATTRS(attrs, CKA_TOKEN, &ckfalse, sizeof(ckfalse)); attrs++;
294 if (vfy) {
295 if (vfy->counter != -1) {
296 counter = vfy->counter;
297 PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_COUNTER,
298 &counter, sizeof(counter)); attrs++;
299 }
300 PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED,
301 vfy->seed.data, vfy->seed.len); attrs++;
302 if (vfy->h.len) {
303 PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_H,
304 vfy->h.data, vfy->h.len); attrs++;
305 }
306 }
307
308 keyCount = attrs - keyTempl;
309 PORT_Assert(keyCount <= sizeof(keyTempl)/sizeof(keyTempl[0]));
310
311
312 slot = PK11_GetInternalSlot();
313 if (slot == NULL) {
314 return SECFailure;
315 }
316
317 PK11_EnterSlotMonitor(slot);
318 crv = PK11_GETTAB(slot)->C_CreateObject(slot->session, keyTempl, keyCount,
319 &objectID);
320 PK11_ExitSlotMonitor(slot);
321
322 /* throw away the keys, we only wanted the return code */
323 PK11_DestroyObject(slot,objectID);
324 PK11_FreeSlot(slot);
325
326 *result = SECSuccess;
327 if (crv == CKR_ATTRIBUTE_VALUE_INVALID) {
328 *result = SECFailure;
329 } else if (crv != CKR_OK) {
330 PORT_SetError( PK11_MapError(crv) );
331 rv = SECFailure;
332 }
333 return rv;
334
335 }
336
337
338
339 /**************************************************************************
340 * Free the PQGParams struct and the things it points to. *
341 **************************************************************************/
342 extern void
343 PK11_PQG_DestroyParams(PQGParams *params) {
344 if (params == NULL)
345 return;
346 if (params->arena != NULL) {
347 PORT_FreeArena(params->arena, PR_FALSE); /* don't zero it */
348 } else {
349 SECITEM_FreeItem(&params->prime, PR_FALSE); /* don't free prime */
350 SECITEM_FreeItem(&params->subPrime, PR_FALSE); /* don't free subPrime */
351 SECITEM_FreeItem(&params->base, PR_FALSE); /* don't free base */
352 PORT_Free(params);
353 }
354 }
355
356 /**************************************************************************
357 * Free the PQGVerify struct and the things it points to. *
358 **************************************************************************/
359 extern void
360 PK11_PQG_DestroyVerify(PQGVerify *vfy) {
361 if (vfy == NULL)
362 return;
363 if (vfy->arena != NULL) {
364 PORT_FreeArena(vfy->arena, PR_FALSE); /* don't zero it */
365 } else {
366 SECITEM_FreeItem(&vfy->seed, PR_FALSE); /* don't free seed */
367 SECITEM_FreeItem(&vfy->h, PR_FALSE); /* don't free h */
368 PORT_Free(vfy);
369 }
370 }
371
372 #define PQG_DEFAULT_CHUNKSIZE 2048 /* bytes */
373
374 /**************************************************************************
375 * Return a pointer to a new PQGParams struct that is constructed from *
376 * copies of the arguments passed in. *
377 * Return NULL on failure. *
378 **************************************************************************/
379 extern PQGParams *
380 PK11_PQG_NewParams(const SECItem * prime, const SECItem * subPrime,
381 const SECItem * base) {
382 PLArenaPool *arena;
383 PQGParams *dest;
384 SECStatus status;
385
386 arena = PORT_NewArena(PQG_DEFAULT_CHUNKSIZE);
387 if (arena == NULL)
388 goto loser;
389
390 dest = (PQGParams*)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
391 if (dest == NULL)
392 goto loser;
393
394 dest->arena = arena;
395
396 status = SECITEM_CopyItem(arena, &dest->prime, prime);
397 if (status != SECSuccess)
398 goto loser;
399
400 status = SECITEM_CopyItem(arena, &dest->subPrime, subPrime);
401 if (status != SECSuccess)
402 goto loser;
403
404 status = SECITEM_CopyItem(arena, &dest->base, base);
405 if (status != SECSuccess)
406 goto loser;
407
408 return dest;
409
410 loser:
411 if (arena != NULL)
412 PORT_FreeArena(arena, PR_FALSE);
413 return NULL;
414 }
415
416
417 /**************************************************************************
418 * Fills in caller's "prime" SECItem with the prime value in params.
419 * Contents can be freed by calling SECITEM_FreeItem(prime, PR_FALSE);
420 **************************************************************************/
421 extern SECStatus
422 PK11_PQG_GetPrimeFromParams(const PQGParams *params, SECItem * prime) {
423 return SECITEM_CopyItem(NULL, prime, &params->prime);
424 }
425
426
427 /**************************************************************************
428 * Fills in caller's "subPrime" SECItem with the prime value in params.
429 * Contents can be freed by calling SECITEM_FreeItem(subPrime, PR_FALSE);
430 **************************************************************************/
431 extern SECStatus
432 PK11_PQG_GetSubPrimeFromParams(const PQGParams *params, SECItem * subPrime) {
433 return SECITEM_CopyItem(NULL, subPrime, &params->subPrime);
434 }
435
436
437 /**************************************************************************
438 * Fills in caller's "base" SECItem with the base value in params.
439 * Contents can be freed by calling SECITEM_FreeItem(base, PR_FALSE);
440 **************************************************************************/
441 extern SECStatus
442 PK11_PQG_GetBaseFromParams(const PQGParams *params, SECItem *base) {
443 return SECITEM_CopyItem(NULL, base, &params->base);
444 }
445
446
447 /**************************************************************************
448 * Return a pointer to a new PQGVerify struct that is constructed from *
449 * copies of the arguments passed in. *
450 * Return NULL on failure. *
451 **************************************************************************/
452 extern PQGVerify *
453 PK11_PQG_NewVerify(unsigned int counter, const SECItem * seed,
454 const SECItem * h) {
455 PLArenaPool *arena;
456 PQGVerify * dest;
457 SECStatus status;
458
459 arena = PORT_NewArena(PQG_DEFAULT_CHUNKSIZE);
460 if (arena == NULL)
461 goto loser;
462
463 dest = (PQGVerify*)PORT_ArenaZAlloc(arena, sizeof(PQGVerify));
464 if (dest == NULL)
465 goto loser;
466
467 dest->arena = arena;
468 dest->counter = counter;
469
470 status = SECITEM_CopyItem(arena, &dest->seed, seed);
471 if (status != SECSuccess)
472 goto loser;
473
474 status = SECITEM_CopyItem(arena, &dest->h, h);
475 if (status != SECSuccess)
476 goto loser;
477
478 return dest;
479
480 loser:
481 if (arena != NULL)
482 PORT_FreeArena(arena, PR_FALSE);
483 return NULL;
484 }
485
486
487 /**************************************************************************
488 * Returns "counter" value from the PQGVerify.
489 **************************************************************************/
490 extern unsigned int
491 PK11_PQG_GetCounterFromVerify(const PQGVerify *verify) {
492 return verify->counter;
493 }
494
495 /**************************************************************************
496 * Fills in caller's "seed" SECItem with the seed value in verify.
497 * Contents can be freed by calling SECITEM_FreeItem(seed, PR_FALSE);
498 **************************************************************************/
499 extern SECStatus
500 PK11_PQG_GetSeedFromVerify(const PQGVerify *verify, SECItem *seed) {
501 return SECITEM_CopyItem(NULL, seed, &verify->seed);
502 }
503
504
505 /**************************************************************************
506 * Fills in caller's "h" SECItem with the h value in verify.
507 * Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE);
508 **************************************************************************/
509 extern SECStatus
510 PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem * h) {
511 return SECITEM_CopyItem(NULL, h, &verify->h);
512 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)