No empty .Rs/.Re
[netbsd-mini2440.git] / external / bsd / bind / dist / bin / pkcs11 / pkcs11-keygen.c
blob4893d10f63d77ef3b7fb52b881a4180f718fe4fc
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2009 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 /* Id: pkcs11-keygen.c,v 1.9 2009/10/26 23:36:53 each Exp */
45 /* pkcs11-keygen - pkcs11 rsa key generator
47 * create RSASHA1 key in the keystore of an SCA6000
48 * The calculation of key tag is left to the script
49 * that converts the key into a DNSKEY RR and inserts
50 * it into a zone file.
52 * usage:
53 * pkcs11-keygen [-P] [-m module] [-s slot] [-e] -b keysize
54 * -l label [-i id] [-p pin]
58 /*! \file */
60 #include <config.h>
62 #include <stdio.h>
63 #include <stdlib.h>
64 #include <fcntl.h>
65 #include <errno.h>
66 #include <string.h>
67 #include <sys/types.h>
68 #include "cryptoki.h"
70 #ifdef WIN32
71 #include "win32.c"
72 #else
73 #ifndef FORCE_STATIC_PROVIDER
74 #include "unix.c"
75 #endif
76 #endif
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 int
87 main(int argc, char *argv[])
89 CK_RV rv;
90 CK_SLOT_ID slot = 0;
91 CK_MECHANISM genmech;
92 CK_SESSION_HANDLE hSession;
93 CK_UTF8CHAR *pin = NULL;
94 CK_ULONG modulusbits = 0;
95 CK_CHAR *label = NULL;
96 CK_OBJECT_HANDLE privatekey, publickey;
97 CK_BYTE public_exponent[5];
98 CK_ULONG expsize = 3;
99 int error = 0;
100 int c, errflg = 0;
101 int hide = 1;
102 int idlen = 0;
103 unsigned long id = 0;
104 CK_BYTE idbuf[4];
105 CK_ULONG ulObjectCount;
106 /* Set search template */
107 CK_ATTRIBUTE search_template[] = {
108 {CKA_LABEL, NULL_PTR, 0}
110 CK_ATTRIBUTE publickey_template[] = {
111 {CKA_LABEL, NULL_PTR, 0},
112 {CKA_VERIFY, &truevalue, sizeof(truevalue)},
113 {CKA_TOKEN, &truevalue, sizeof(truevalue)},
114 {CKA_MODULUS_BITS, &modulusbits, sizeof(modulusbits)},
115 {CKA_PUBLIC_EXPONENT, &public_exponent, expsize},
116 {CKA_ID, &idbuf, idlen}
118 CK_ULONG publickey_attrcnt = 6;
119 CK_ATTRIBUTE privatekey_template[] = {
120 {CKA_LABEL, NULL_PTR, 0},
121 {CKA_SIGN, &truevalue, sizeof(truevalue)},
122 {CKA_TOKEN, &truevalue, sizeof(truevalue)},
123 {CKA_PRIVATE, &truevalue, sizeof(truevalue)},
124 {CKA_SENSITIVE, &truevalue, sizeof(truevalue)},
125 {CKA_EXTRACTABLE, &falsevalue, sizeof(falsevalue)},
126 {CKA_ID, &idbuf, idlen}
128 CK_ULONG privatekey_attrcnt = 7;
129 char *pk11_provider;
130 extern char *optarg;
131 extern int optopt;
133 pk11_provider = getenv("PKCS11_PROVIDER");
134 if (pk11_provider != NULL)
135 pk11_libname = pk11_provider;
137 while ((c = getopt(argc, argv, ":Pm:s:b:ei:l:p:")) != -1) {
138 switch (c) {
139 case 'P':
140 hide = 0;
141 break;
142 case 'm':
143 pk11_libname = optarg;
144 break;
145 case 's':
146 slot = atoi(optarg);
147 break;
148 case 'e':
149 expsize = 5;
150 break;
151 case 'b':
152 modulusbits = atoi(optarg);
153 break;
154 case 'l':
155 label = (CK_CHAR *)optarg;
156 break;
157 case 'i':
158 id = strtoul(optarg, NULL, 0);
159 idlen = 4;
160 break;
161 case 'p':
162 pin = (CK_UTF8CHAR *)optarg;
163 break;
164 case ':':
165 fprintf(stderr,
166 "Option -%c requires an operand\n",
167 optopt);
168 errflg++;
169 break;
170 case '?':
171 default:
172 fprintf(stderr, "Unrecognised option: -%c\n", optopt);
173 errflg++;
177 if (errflg || !modulusbits || (label == NULL)) {
178 fprintf(stderr, "Usage:\n");
179 fprintf(stderr, "\tpkcs11-keygen -b keysize -l label\n");
180 fprintf(stderr, "\t [-P] [-m module] "
181 "[-s slot] [-e] [-i id] [-p PIN]\n");
182 exit(2);
185 search_template[0].pValue = label;
186 search_template[0].ulValueLen = strlen((char *)label);
187 publickey_template[0].pValue = label;
188 publickey_template[0].ulValueLen = strlen((char *)label);
189 privatekey_template[0].pValue = label;
190 privatekey_template[0].ulValueLen = strlen((char *)label);
192 /* Set public exponent to F4 or F5 */
193 public_exponent[0] = 0x01;
194 public_exponent[1] = 0x00;
195 if (expsize == 3)
196 public_exponent[2] = 0x01;
197 else {
198 publickey_template[4].ulValueLen = expsize;
199 public_exponent[2] = 0x00;
200 public_exponent[3] = 0x00;
201 public_exponent[4] = 0x01;
204 /* Set up mechanism for generating key pair */
205 genmech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
206 genmech.pParameter = NULL_PTR;
207 genmech.ulParameterLen = 0;
209 if (idlen == 0) {
210 publickey_attrcnt--;
211 privatekey_attrcnt--;
212 } else if (id <= 0xffff) {
213 idlen = 2;
214 publickey_template[5].ulValueLen = idlen;
215 privatekey_template[6].ulValueLen = idlen;
216 idbuf[0] = (CK_BYTE)(id >> 8);
217 idbuf[1] = (CK_BYTE)id;
218 } else {
219 idbuf[0] = (CK_BYTE)(id >> 24);
220 idbuf[1] = (CK_BYTE)(id >> 16);
221 idbuf[2] = (CK_BYTE)(id >> 8);
222 idbuf[3] = (CK_BYTE)id;
225 /* Initialize the CRYPTOKI library */
226 rv = C_Initialize(NULL_PTR);
228 if (rv != CKR_OK) {
229 if (rv == 0xfe)
230 fprintf(stderr,
231 "Can't load or link module \"%s\"\n",
232 pk11_libname);
233 else
234 fprintf(stderr, "C_Initialize: Error = 0x%.8lX\n", rv);
235 exit(1);
238 /* Open a session on the slot found */
239 rv = C_OpenSession(slot, CKF_RW_SESSION+CKF_SERIAL_SESSION,
240 NULL_PTR, NULL_PTR, &hSession);
242 if (rv != CKR_OK) {
243 fprintf(stderr, "C_OpenSession: Error = 0x%.8lX\n", rv);
244 error = 1;
245 goto exit_program;
248 /* Login to the Token (Keystore) */
249 if (pin == NULL)
250 pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: ");
252 rv = C_Login(hSession, CKU_USER, pin, strlen((char *)pin));
253 memset(pin, 0, strlen((char *)pin));
254 if (rv != CKR_OK) {
255 fprintf(stderr, "C_Login: Error = 0x%.8lX\n", rv);
256 error = 1;
257 goto exit_session;
260 /* check if a key with the same id already exists */
261 rv = C_FindObjectsInit(hSession, search_template, 1);
262 if (rv != CKR_OK) {
263 fprintf(stderr, "C_FindObjectsInit: Error = 0x%.8lX\n", rv);
264 error = 1;
265 goto exit_session;
267 rv = C_FindObjects(hSession, &privatekey, 1, &ulObjectCount);
268 if (rv != CKR_OK) {
269 fprintf(stderr, "C_FindObjects: Error = 0x%.8lX\n", rv);
270 error = 1;
271 goto exit_search;
273 if (ulObjectCount != 0) {
274 fprintf(stderr, "Key already exists.\n");
275 error = 1;
276 goto exit_search;
279 /* Set attributes if the key is not to be hidden */
280 if (!hide) {
281 privatekey_template[4].pValue = &falsevalue;
282 privatekey_template[5].pValue = &truevalue;
285 /* Generate Key pair for signing/verifying */
286 rv = C_GenerateKeyPair(hSession, &genmech,
287 publickey_template, publickey_attrcnt,
288 privatekey_template, privatekey_attrcnt,
289 &publickey, &privatekey);
291 if (rv != CKR_OK) {
292 fprintf(stderr, "C_GenerateKeyPair: Error = 0x%.8lX\n", rv);
293 error = 1;
296 exit_search:
297 rv = C_FindObjectsFinal(hSession);
298 if (rv != CKR_OK) {
299 fprintf(stderr, "C_FindObjectsFinal: Error = 0x%.8lX\n", rv);
300 error = 1;
303 exit_session:
304 (void)C_CloseSession(hSession);
306 exit_program:
307 (void)C_Finalize(NULL_PTR);
309 exit(error);