Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / bin / pkcs11 / pkcs11-keygen.c
blobeabee00c66455769db2e8887774ddd171e26e03f
1 /* $NetBSD: pkcs11-keygen.c,v 1.7 2014/12/10 04:37:52 christos Exp $ */
3 /*
4 * Copyright (C) 2009,2012 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
13 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
16 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 * Portions copyright (c) 2008 Nominet UK. All rights reserved.
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the above copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
31 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
32 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
33 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
34 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
35 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 /* pkcs11-keygen - PKCS#11 key generator
45 * Create a key in the keystore of an HSM
47 * The calculation of key tag is left to the script
48 * that converts the key into a DNSKEY RR and inserts
49 * it into a zone file.
51 * usage:
52 * pkcs11-keygen [-P] [-m module] [-s slot] [-e] [-b keysize]
53 * [-i id] [-p pin] -l label
57 /*! \file */
59 #include <config.h>
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <fcntl.h>
64 #include <errno.h>
65 #include <string.h>
66 #include <sys/types.h>
68 #include <isc/commandline.h>
69 #include <isc/result.h>
70 #include <isc/types.h>
72 #include <pk11/pk11.h>
73 #include <pk11/result.h>
74 #define WANT_DH_PRIMES
75 #define WANT_ECC_CURVES
76 #include <pk11/constants.h>
78 #if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
79 #define getpassphrase(x) getpass(x)
80 #endif
82 /* Define static key template values */
83 static CK_BBOOL truevalue = TRUE;
84 static CK_BBOOL falsevalue = FALSE;
86 /* Key class: RSA, ECC, DSA, DH, or unknown */
87 typedef enum {
88 key_unknown,
89 key_rsa,
90 key_dsa,
91 key_dh,
92 key_ecc
93 } key_class_t;
96 * Private key template: usable for most key classes without
97 * modificaton; override CKA_SIGN with CKA_DERIVE for DH
99 #define PRIVATE_LABEL 0
100 #define PRIVATE_SIGN 1
101 #define PRIVATE_DERIVE 1
102 #define PRIVATE_TOKEN 2
103 #define PRIVATE_PRIVATE 3
104 #define PRIVATE_SENSITIVE 4
105 #define PRIVATE_EXTRACTABLE 5
106 #define PRIVATE_ID 6
107 #define PRIVATE_ATTRS 7
108 static CK_ATTRIBUTE private_template[] = {
109 {CKA_LABEL, NULL_PTR, 0},
110 {CKA_SIGN, &truevalue, sizeof(truevalue)},
111 {CKA_TOKEN, &truevalue, sizeof(truevalue)},
112 {CKA_PRIVATE, &truevalue, sizeof(truevalue)},
113 {CKA_SENSITIVE, &truevalue, sizeof(truevalue)},
114 {CKA_EXTRACTABLE, &falsevalue, sizeof(falsevalue)},
115 {CKA_ID, NULL_PTR, 0}
119 * Public key template for RSA keys
121 #define RSA_LABEL 0
122 #define RSA_VERIFY 1
123 #define RSA_TOKEN 2
124 #define RSA_PRIVATE 3
125 #define RSA_MODULUS_BITS 4
126 #define RSA_PUBLIC_EXPONENT 5
127 #define RSA_ID 6
128 #define RSA_ATTRS 7
129 static CK_ATTRIBUTE rsa_template[] = {
130 {CKA_LABEL, NULL_PTR, 0},
131 {CKA_VERIFY, &truevalue, sizeof(truevalue)},
132 {CKA_TOKEN, &truevalue, sizeof(truevalue)},
133 {CKA_PRIVATE, &falsevalue, sizeof(falsevalue)},
134 {CKA_MODULUS_BITS, NULL_PTR, 0},
135 {CKA_PUBLIC_EXPONENT, NULL_PTR, 0},
136 {CKA_ID, NULL_PTR, 0}
140 * Public key template for ECC keys
142 #define ECC_LABEL 0
143 #define ECC_VERIFY 1
144 #define ECC_TOKEN 2
145 #define ECC_PRIVATE 3
146 #define ECC_PARAMS 4
147 #define ECC_ID 5
148 #define ECC_ATTRS 6
149 static CK_ATTRIBUTE ecc_template[] = {
150 {CKA_LABEL, NULL_PTR, 0},
151 {CKA_VERIFY, &truevalue, sizeof(truevalue)},
152 {CKA_TOKEN, &truevalue, sizeof(truevalue)},
153 {CKA_PRIVATE, &falsevalue, sizeof(falsevalue)},
154 {CKA_EC_PARAMS, NULL_PTR, 0},
155 {CKA_ID, NULL_PTR, 0}
159 * Public key template for DSA keys
161 #define DSA_LABEL 0
162 #define DSA_VERIFY 1
163 #define DSA_TOKEN 2
164 #define DSA_PRIVATE 3
165 #define DSA_PRIME 4
166 #define DSA_SUBPRIME 5
167 #define DSA_BASE 6
168 #define DSA_ID 7
169 #define DSA_ATTRS 8
170 static CK_ATTRIBUTE dsa_template[] = {
171 {CKA_LABEL, NULL_PTR, 0},
172 {CKA_VERIFY, &truevalue, sizeof(truevalue)},
173 {CKA_TOKEN, &truevalue, sizeof(truevalue)},
174 {CKA_PRIVATE, &falsevalue, sizeof(falsevalue)},
175 {CKA_PRIME, NULL_PTR, 0},
176 {CKA_SUBPRIME, NULL_PTR, 0},
177 {CKA_BASE, NULL_PTR, 0},
178 {CKA_ID, NULL_PTR, 0}
180 #define DSA_PARAM_PRIME 0
181 #define DSA_PARAM_SUBPRIME 1
182 #define DSA_PARAM_BASE 2
183 #define DSA_PARAM_ATTRS 3
184 static CK_ATTRIBUTE dsa_param_template[] = {
185 {CKA_PRIME, NULL_PTR, 0},
186 {CKA_SUBPRIME, NULL_PTR, 0},
187 {CKA_BASE, NULL_PTR, 0},
189 #define DSA_DOMAIN_PRIMEBITS 0
190 #define DSA_DOMAIN_PRIVATE 1
191 #define DSA_DOMAIN_ATTRS 2
192 static CK_ATTRIBUTE dsa_domain_template[] = {
193 {CKA_PRIME_BITS, NULL_PTR, 0},
194 {CKA_PRIVATE, &falsevalue, sizeof(falsevalue)},
198 * Public key template for DH keys
200 #define DH_LABEL 0
201 #define DH_VERIFY 1
202 #define DH_TOKEN 2
203 #define DH_PRIVATE 3
204 #define DH_PRIME 4
205 #define DH_BASE 5
206 #define DH_ID 6
207 #define DH_ATTRS 7
208 static CK_ATTRIBUTE dh_template[] = {
209 {CKA_LABEL, NULL_PTR, 0},
210 {CKA_VERIFY, &truevalue, sizeof(truevalue)},
211 {CKA_TOKEN, &truevalue, sizeof(truevalue)},
212 {CKA_PRIVATE, &falsevalue, sizeof(falsevalue)},
213 {CKA_PRIME, NULL_PTR, 0},
214 {CKA_BASE, NULL_PTR, 0},
215 {CKA_ID, NULL_PTR, 0}
217 #define DH_PARAM_PRIME 0
218 #define DH_PARAM_BASE 1
219 #define DH_PARAM_ATTRS 2
220 static CK_ATTRIBUTE dh_param_template[] = {
221 {CKA_PRIME, NULL_PTR, 0},
222 {CKA_BASE, NULL_PTR, 0},
224 #define DH_DOMAIN_PRIMEBITS 0
225 #define DH_DOMAIN_ATTRS 1
226 static CK_ATTRIBUTE dh_domain_template[] = {
227 {CKA_PRIME_BITS, NULL_PTR, 0},
231 * Convert from text to key class. Accepts the names of DNSSEC
232 * signing algorithms, so e.g., ECDSAP256SHA256 maps to ECC and
233 * NSEC3RSASHA1 maps to RSA.
235 static key_class_t
236 keyclass_fromtext(const char *name) {
237 if (name == NULL)
238 return (key_unknown);
240 if (strncasecmp(name, "rsa", 3) == 0 ||
241 strncasecmp(name, "nsec3rsa", 8) == 0)
242 return (key_rsa);
243 else if (strncasecmp(name, "dsa", 3) == 0 ||
244 strncasecmp(name, "nsec3dsa", 8) == 0)
245 return (key_dsa);
246 else if (strcasecmp(name, "dh") == 0)
247 return (key_dh);
248 else if (strncasecmp(name, "ecc", 3) == 0 ||
249 strncasecmp(name, "ecdsa", 5) == 0)
250 return (key_ecc);
251 else
252 return (key_unknown);
255 static void
256 usage(void) {
257 fprintf(stderr,
258 "Usage:\n"
259 "\tpkcs11-keygen -a algorithm -b keysize -l label\n"
260 "\t [-P] [-m module] "
261 "[-s slot] [-e] [-S] [-i id] [-p PIN]\n");
262 exit(2);
266 main(int argc, char *argv[]) {
267 isc_result_t result;
268 CK_RV rv;
269 CK_SLOT_ID slot = 0;
270 CK_MECHANISM mech, dpmech;
271 CK_SESSION_HANDLE hSession;
272 char *lib_name = NULL;
273 char *pin = NULL;
274 CK_ULONG bits = 0;
275 CK_CHAR *label = NULL;
276 CK_OBJECT_HANDLE privatekey, publickey, domainparams;
277 CK_BYTE exponent[5];
278 CK_ULONG expsize = 0;
279 pk11_context_t pctx;
280 int error = 0;
281 int c, errflg = 0;
282 int hide = 1, special = 0, quiet = 0;
283 int idlen = 0, id_offset = 0;
284 unsigned int i;
285 unsigned long id = 0;
286 CK_BYTE idbuf[4];
287 CK_ULONG ulObjectCount;
288 CK_ATTRIBUTE search_template[] = {
289 {CKA_LABEL, NULL_PTR, 0}
291 CK_ATTRIBUTE *public_template = NULL;
292 CK_ATTRIBUTE *domain_template = NULL;
293 CK_ATTRIBUTE *param_template = NULL;
294 CK_ULONG public_attrcnt = 0, private_attrcnt = PRIVATE_ATTRS;
295 CK_ULONG domain_attrcnt = 0, param_attrcnt = 0;
296 key_class_t keyclass = key_rsa;
297 pk11_optype_t op_type = OP_ANY;
299 #define OPTIONS ":a:b:ei:l:m:Pp:qSs:"
300 while ((c = isc_commandline_parse(argc, argv, OPTIONS)) != -1) {
301 switch (c) {
302 case 'a':
303 keyclass = keyclass_fromtext(isc_commandline_argument);
304 break;
305 case 'P':
306 hide = 0;
307 break;
308 case 'm':
309 lib_name = isc_commandline_argument;
310 break;
311 case 's':
312 slot = atoi(isc_commandline_argument);
313 break;
314 case 'e':
315 expsize = 5;
316 break;
317 case 'b':
318 bits = atoi(isc_commandline_argument);
319 break;
320 case 'l':
321 /* -l option is retained for backward compatibility * */
322 label = (CK_CHAR *)isc_commandline_argument;
323 break;
324 case 'i':
325 id = strtoul(isc_commandline_argument, NULL, 0);
326 idlen = 4;
327 break;
328 case 'p':
329 pin = isc_commandline_argument;
330 break;
331 case 'q':
332 quiet = 1;
333 break;
334 case 'S':
335 special = 1;
336 break;
337 case ':':
338 fprintf(stderr,
339 "Option -%c requires an operand\n",
340 isc_commandline_option);
341 errflg++;
342 break;
343 case '?':
344 default:
345 fprintf(stderr, "Unrecognised option: -%c\n",
346 isc_commandline_option);
347 errflg++;
351 if (label == NULL && isc_commandline_index < argc)
352 label = (CK_CHAR *)argv[isc_commandline_index];
354 if (errflg || (label == NULL))
355 usage();
357 if (expsize != 0 && keyclass != key_rsa) {
358 fprintf(stderr, "The -e option is only compatible "
359 "with RSA key generation\n");
360 exit(2);
363 if (special != 0 && keyclass != key_dh) {
364 fprintf(stderr, "The -S option is only compatible "
365 "with Diffie-Hellman key generation\n");
366 exit(2);
369 switch (keyclass) {
370 case key_rsa:
371 op_type = OP_RSA;
372 if (expsize == 0)
373 expsize = 3;
374 if (bits == 0)
375 usage();
377 mech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
378 mech.pParameter = NULL;
379 mech.ulParameterLen = 0;
381 public_template = rsa_template;
382 public_attrcnt = RSA_ATTRS;
383 id_offset = RSA_ID;
385 /* Set public exponent to F4 or F5 */
386 exponent[0] = 0x01;
387 exponent[1] = 0x00;
388 if (expsize == 3)
389 exponent[2] = 0x01;
390 else {
391 exponent[2] = 0x00;
392 exponent[3] = 0x00;
393 exponent[4] = 0x01;
396 public_template[RSA_MODULUS_BITS].pValue = &bits;
397 public_template[RSA_MODULUS_BITS].ulValueLen = sizeof(bits);
398 public_template[RSA_PUBLIC_EXPONENT].pValue = &exponent;
399 public_template[RSA_PUBLIC_EXPONENT].ulValueLen = expsize;
400 break;
401 case key_ecc:
402 op_type = OP_EC;
403 if (bits == 0)
404 bits = 256;
405 else if (bits != 256 && bits != 384) {
406 fprintf(stderr, "ECC keys only support bit sizes of "
407 "256 and 384\n");
408 exit(2);
411 mech.mechanism = CKM_EC_KEY_PAIR_GEN;
412 mech.pParameter = NULL;
413 mech.ulParameterLen = 0;
415 public_template = ecc_template;
416 public_attrcnt = ECC_ATTRS;
417 id_offset = ECC_ID;
419 if (bits == 256) {
420 public_template[4].pValue = pk11_ecc_prime256v1;
421 public_template[4].ulValueLen =
422 sizeof(pk11_ecc_prime256v1);
423 } else {
424 public_template[4].pValue = pk11_ecc_secp384r1;
425 public_template[4].ulValueLen =
426 sizeof(pk11_ecc_secp384r1);
429 break;
430 case key_dsa:
431 op_type = OP_DSA;
432 if (bits == 0)
433 usage();
435 dpmech.mechanism = CKM_DSA_PARAMETER_GEN;
436 dpmech.pParameter = NULL;
437 dpmech.ulParameterLen = 0;
438 mech.mechanism = CKM_DSA_KEY_PAIR_GEN;
439 mech.pParameter = NULL;
440 mech.ulParameterLen = 0;
442 public_template = dsa_template;
443 public_attrcnt = DSA_ATTRS;
444 id_offset = DSA_ID;
446 domain_template = dsa_domain_template;
447 domain_attrcnt = DSA_DOMAIN_ATTRS;
448 param_template = dsa_param_template;
449 param_attrcnt = DSA_PARAM_ATTRS;
451 domain_template[DSA_DOMAIN_PRIMEBITS].pValue = &bits;
452 domain_template[DSA_DOMAIN_PRIMEBITS].ulValueLen = sizeof(bits);
453 break;
454 case key_dh:
455 op_type = OP_DH;
456 if (special && bits == 0)
457 bits = 1024;
458 else if (special &&
459 bits != 768 && bits != 1024 && bits != 1536)
461 fprintf(stderr, "When using the special prime (-S) "
462 "option, only key sizes of\n"
463 "768, 1024 or 1536 are supported.\n");
464 exit(2);
465 } else if (bits == 0)
466 usage();
468 dpmech.mechanism = CKM_DH_PKCS_PARAMETER_GEN;
469 dpmech.pParameter = NULL;
470 dpmech.ulParameterLen = 0;
471 mech.mechanism = CKM_DH_PKCS_KEY_PAIR_GEN;
472 mech.pParameter = NULL;
473 mech.ulParameterLen = 0;
475 /* Override CKA_SIGN attribute */
476 private_template[PRIVATE_DERIVE].type = CKA_DERIVE;
478 public_template = dh_template;
479 public_attrcnt = DH_ATTRS;
480 id_offset = DH_ID;
482 domain_template = dh_domain_template;
483 domain_attrcnt = DH_DOMAIN_ATTRS;
484 param_template = dh_param_template;
485 param_attrcnt = DH_PARAM_ATTRS;
487 domain_template[DH_DOMAIN_PRIMEBITS].pValue = &bits;
488 domain_template[DH_DOMAIN_PRIMEBITS].ulValueLen = sizeof(bits);
489 break;
490 case key_unknown:
491 usage();
494 search_template[0].pValue = label;
495 search_template[0].ulValueLen = strlen((char *)label);
496 public_template[0].pValue = label;
497 public_template[0].ulValueLen = strlen((char *)label);
498 private_template[0].pValue = label;
499 private_template[0].ulValueLen = strlen((char *)label);
501 if (idlen == 0) {
502 public_attrcnt--;
503 private_attrcnt--;
504 } else {
505 if (id <= 0xffff) {
506 idlen = 2;
507 idbuf[0] = (CK_BYTE)(id >> 8);
508 idbuf[1] = (CK_BYTE)id;
509 } else {
510 idbuf[0] = (CK_BYTE)(id >> 24);
511 idbuf[1] = (CK_BYTE)(id >> 16);
512 idbuf[2] = (CK_BYTE)(id >> 8);
513 idbuf[3] = (CK_BYTE)id;
516 public_template[id_offset].pValue = idbuf;
517 public_template[id_offset].ulValueLen = idlen;
518 private_template[PRIVATE_ID].pValue = idbuf;
519 private_template[PRIVATE_ID].ulValueLen = idlen;
522 pk11_result_register();
524 /* Initialize the CRYPTOKI library */
525 if (lib_name != NULL)
526 pk11_set_lib_name(lib_name);
528 if (pin == NULL)
529 pin = getpassphrase("Enter Pin: ");
531 result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_TRUE,
532 ISC_TRUE, (const char *) pin, slot);
533 if (result == PK11_R_NORANDOMSERVICE ||
534 result == PK11_R_NODIGESTSERVICE ||
535 result == PK11_R_NOAESSERVICE) {
536 fprintf(stderr, "Warning: %s\n", isc_result_totext(result));
537 fprintf(stderr, "This HSM will not work with BIND 9 "
538 "using native PKCS#11.\n");
539 } else if (result != ISC_R_SUCCESS) {
540 fprintf(stderr, "Unrecoverable error initializing "
541 "PKCS#11: %s\n", isc_result_totext(result));
542 exit(1);
545 memset(pin, 0, strlen(pin));
547 hSession = pctx.session;
549 /* check if a key with the same id already exists */
550 rv = pkcs_C_FindObjectsInit(hSession, search_template, 1);
551 if (rv != CKR_OK) {
552 fprintf(stderr, "C_FindObjectsInit: Error = 0x%.8lX\n", rv);
553 error = 1;
554 goto exit_session;
556 rv = pkcs_C_FindObjects(hSession, &privatekey, 1, &ulObjectCount);
557 if (rv != CKR_OK) {
558 fprintf(stderr, "C_FindObjects: Error = 0x%.8lX\n", rv);
559 error = 1;
560 goto exit_search;
562 if (ulObjectCount != 0) {
563 fprintf(stderr, "Key already exists.\n");
564 error = 1;
565 goto exit_search;
568 /* Set attributes if the key is not to be hidden */
569 if (!hide) {
570 private_template[4].pValue = &falsevalue;
571 private_template[5].pValue = &truevalue;
574 if (keyclass == key_rsa || keyclass == key_ecc)
575 goto generate_keys;
578 * Special setup for Diffie-Hellman keys
580 if (special != 0) {
581 public_template[DH_BASE].pValue = pk11_dh_bn2;
582 public_template[DH_BASE].ulValueLen = sizeof(pk11_dh_bn2);
583 if (bits == 768) {
584 public_template[DH_PRIME].pValue = pk11_dh_bn768;
585 public_template[DH_PRIME].ulValueLen =
586 sizeof(pk11_dh_bn768);
587 } else if (bits == 1024) {
588 public_template[DH_PRIME].pValue = pk11_dh_bn1024;
589 public_template[DH_PRIME].ulValueLen =
590 sizeof(pk11_dh_bn1024);
591 } else {
592 public_template[DH_PRIME].pValue = pk11_dh_bn1536;
593 public_template[DH_PRIME].ulValueLen =
594 sizeof(pk11_dh_bn1536);
596 param_attrcnt = 0;
597 goto generate_keys;
600 /* Generate Domain parameters */
601 rv = pkcs_C_GenerateKey(hSession, &dpmech, domain_template,
602 domain_attrcnt, &domainparams);
604 if (rv != CKR_OK) {
605 fprintf(stderr,
606 "C_GenerateKey: Error = 0x%.8lX\n", rv);
607 error = 1;
608 goto exit_search;
611 /* Get Domain parameters */
612 rv = pkcs_C_GetAttributeValue(hSession, domainparams,
613 param_template, param_attrcnt);
615 if (rv != CKR_OK) {
616 fprintf(stderr,
617 "C_GetAttributeValue0: Error = 0x%.8lX\n", rv);
618 error = 1;
619 goto exit_domain;
622 /* Allocate space for parameter attributes */
623 for (i = 0; i < param_attrcnt; i++)
624 param_template[i].pValue = malloc(param_template[i].ulValueLen);
626 rv = pkcs_C_GetAttributeValue(hSession, domainparams,
627 dsa_param_template, DSA_PARAM_ATTRS);
629 if (rv != CKR_OK) {
630 fprintf(stderr,
631 "C_GetAttributeValue1: Error = 0x%.8lX\n", rv);
632 error = 1;
633 goto exit_params;
636 switch (keyclass) {
637 case key_dsa:
638 public_template[DSA_PRIME].pValue =
639 param_template[DSA_PARAM_PRIME].pValue;
640 public_template[DSA_PRIME].ulValueLen =
641 param_template[DSA_PARAM_PRIME].ulValueLen;
642 public_template[DSA_SUBPRIME].pValue =
643 param_template[DSA_PARAM_SUBPRIME].pValue;
644 public_template[DSA_SUBPRIME].ulValueLen =
645 param_template[DSA_PARAM_SUBPRIME].ulValueLen;
646 public_template[DSA_BASE].pValue =
647 param_template[DSA_PARAM_BASE].pValue;
648 public_template[DSA_BASE].ulValueLen =
649 param_template[DSA_PARAM_BASE].ulValueLen;
650 break;
651 case key_dh:
652 public_template[DH_PRIME].pValue =
653 param_template[DH_PARAM_PRIME].pValue;
654 public_template[DH_PRIME].ulValueLen =
655 param_template[DH_PARAM_PRIME].ulValueLen;
656 public_template[DH_BASE].pValue =
657 param_template[DH_PARAM_BASE].pValue;
658 public_template[DH_BASE].ulValueLen =
659 param_template[DH_PARAM_BASE].ulValueLen;
660 default:
661 break;
664 generate_keys:
665 /* Generate Key pair for signing/verifying */
666 rv = pkcs_C_GenerateKeyPair(hSession, &mech,
667 public_template, public_attrcnt,
668 private_template, private_attrcnt,
669 &publickey, &privatekey);
671 if (rv != CKR_OK) {
672 fprintf(stderr, "C_GenerateKeyPair: Error = 0x%.8lX\n", rv);
673 error = 1;
674 } else if (!quiet)
675 printf("Key pair generation complete.\n");
677 exit_params:
678 /* Free parameter attributes */
679 if (keyclass == key_dsa || keyclass == key_dh)
680 for (i = 0; i < param_attrcnt; i++)
681 free(param_template[i].pValue);
683 exit_domain:
684 /* Destroy domain parameters */
685 if (keyclass == key_dsa || (keyclass == key_dh && !special)) {
686 rv = pkcs_C_DestroyObject(hSession, domainparams);
687 if (rv != CKR_OK) {
688 fprintf(stderr,
689 "C_DestroyObject: Error = 0x%.8lX\n", rv);
690 error = 1;
694 exit_search:
695 rv = pkcs_C_FindObjectsFinal(hSession);
696 if (rv != CKR_OK) {
697 fprintf(stderr, "C_FindObjectsFinal: Error = 0x%.8lX\n", rv);
698 error = 1;
701 exit_session:
702 pk11_return_session(&pctx);
703 (void) pk11_finalize();
705 exit(error);