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