1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 *
21 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
22 */
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <malloc.h>
28 #include <libgen.h>
29 #include <errno.h>
30 #include <cryptoutil.h>
31 #include <security/cryptoki.h>
32 #include "common.h"
33
34 #include <kmfapi.h>
35
36 #define SET_VALUE(f, s) { \
37 kmfrv = f; \
38 if (kmfrv != KMF_OK) { \
39 cryptoerror(LOG_STDERR, \
40 gettext("Failed to set %s: 0x%02x\n"), \
41 s, kmfrv); \
42 goto cleanup; \
43 } \
44 }
45
46 static int
gencert_pkcs11(KMF_HANDLE_T kmfhandle,char * token,char * subject,char * altname,KMF_GENERALNAMECHOICES alttype,int altcrit,char * certlabel,KMF_KEY_ALG keyAlg,KMF_ALGORITHM_INDEX sigAlg,int keylen,uint32_t ltime,KMF_BIGINT * serial,uint16_t kubits,int kucrit,KMF_CREDENTIAL * tokencred,EKU_LIST * ekulist,KMF_OID * curveoid)47 gencert_pkcs11(KMF_HANDLE_T kmfhandle,
48 char *token, char *subject, char *altname,
49 KMF_GENERALNAMECHOICES alttype, int altcrit,
50 char *certlabel, KMF_KEY_ALG keyAlg,
51 KMF_ALGORITHM_INDEX sigAlg,
52 int keylen, uint32_t ltime, KMF_BIGINT *serial,
53 uint16_t kubits, int kucrit, KMF_CREDENTIAL *tokencred,
54 EKU_LIST *ekulist, KMF_OID *curveoid)
55 {
56 KMF_RETURN kmfrv = KMF_OK;
57 KMF_KEY_HANDLE pubk, prik;
58 KMF_X509_CERTIFICATE signedCert;
59 KMF_X509_NAME certSubject;
60 KMF_X509_NAME certIssuer;
61 KMF_DATA x509DER;
62 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
63 KMF_ATTRIBUTE attrlist[16];
64 int numattr = 0;
65 KMF_KEY_ALG keytype;
66 uint32_t keylength;
67
68 (void) memset(&signedCert, 0, sizeof (signedCert));
69 (void) memset(&certSubject, 0, sizeof (certSubject));
70 (void) memset(&certIssuer, 0, sizeof (certIssuer));
71 (void) memset(&x509DER, 0, sizeof (x509DER));
72
73 /* If the subject name cannot be parsed, flag it now and exit */
74 if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
75 cryptoerror(LOG_STDERR,
76 gettext("Subject name cannot be parsed.\n"));
77 return (PK_ERR_USAGE);
78 }
79
80 /* For a self-signed cert, the issuser and subject are the same */
81 if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
82 cryptoerror(LOG_STDERR,
83 gettext("Subject name cannot be parsed.\n"));
84 return (PK_ERR_USAGE);
85 }
86
87 keylength = keylen; /* bits */
88 keytype = keyAlg;
89
90 /* Select a PKCS11 token */
91 kmfrv = select_token(kmfhandle, token, FALSE);
92 if (kmfrv != KMF_OK) {
93 return (kmfrv);
94 }
95
96 /*
97 * Share the "genkeypair" routine for creating the keypair.
98 */
99 kmfrv = genkeypair_pkcs11(kmfhandle, token, certlabel,
100 keytype, keylength, tokencred, curveoid, &prik, &pubk);
101 if (kmfrv != KMF_OK)
102 return (kmfrv);
103
104 SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
105 "keypair");
106
107 SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
108
109 SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
110 "serial number");
111
112 SET_VALUE(kmf_set_cert_validity(&signedCert, 0, ltime),
113 "validity time");
114
115 SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
116 "signature algorithm");
117
118 SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
119 "subject name");
120
121 SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
122 "issuer name");
123
124 if (altname != NULL)
125 SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
126 alttype, altname), "subjectAltName");
127
128 if (kubits != 0)
129 SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
130 "KeyUsage");
131
132 if (ekulist != NULL) {
133 int i;
134 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
135 SET_VALUE(kmf_add_cert_eku(&signedCert,
136 &ekulist->ekulist[i], ekulist->critlist[i]),
137 "Extended Key Usage");
138 }
139 }
140
141 /*
142 * Construct attributes for the kmf_sign_cert operation.
143 */
144 numattr = 0;
145 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
146 &kstype, sizeof (kstype));
147 numattr++;
148
149 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
150 &prik, sizeof (KMF_KEY_HANDLE_ATTR));
151 numattr++;
152
153 /* cert data that is to be signed */
154 kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
155 &signedCert, sizeof (KMF_X509_CERTIFICATE));
156 numattr++;
157
158 /* output buffer for the signed cert */
159 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
160 &x509DER, sizeof (KMF_DATA));
161 numattr++;
162
163 kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
164 &sigAlg, sizeof (sigAlg));
165 numattr++;
166
167 if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
168 KMF_OK) {
169 goto cleanup;
170 }
171
172 /*
173 * Store the cert in the DB.
174 */
175 numattr = 0;
176 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
177 &kstype, sizeof (kstype));
178 numattr++;
179 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
180 &x509DER, sizeof (KMF_DATA));
181 numattr++;
182
183 if (certlabel != NULL) {
184 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
185 certlabel, strlen(certlabel));
186 numattr++;
187 }
188
189 kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
190
191 cleanup:
192 kmf_free_data(&x509DER);
193 kmf_free_dn(&certSubject);
194 kmf_free_dn(&certIssuer);
195
196 /*
197 * If kmf_sign_cert or kmf_store_cert failed, then we need to clean up
198 * the key pair from the token.
199 */
200 if (kmfrv != KMF_OK) {
201 /* delete the public key */
202 numattr = 0;
203 kmf_set_attr_at_index(attrlist, numattr,
204 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
205 numattr++;
206
207 kmf_set_attr_at_index(attrlist, numattr,
208 KMF_KEY_HANDLE_ATTR, &pubk, sizeof (KMF_KEY_HANDLE));
209 numattr++;
210
211 if (tokencred != NULL && tokencred->cred != NULL) {
212 kmf_set_attr_at_index(attrlist, numattr,
213 KMF_CREDENTIAL_ATTR, tokencred,
214 sizeof (KMF_CREDENTIAL));
215 numattr++;
216 }
217
218 (void) kmf_delete_key_from_keystore(kmfhandle, numattr,
219 attrlist);
220
221 /* delete the private key */
222 numattr = 0;
223 kmf_set_attr_at_index(attrlist, numattr,
224 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
225 numattr++;
226
227 kmf_set_attr_at_index(attrlist, numattr,
228 KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE));
229 numattr++;
230
231 if (tokencred != NULL && tokencred->cred != NULL) {
232 kmf_set_attr_at_index(attrlist, numattr,
233 KMF_CREDENTIAL_ATTR, tokencred,
234 sizeof (KMF_CREDENTIAL));
235 numattr++;
236 }
237
238 (void) kmf_delete_key_from_keystore(kmfhandle, numattr,
239 attrlist);
240 }
241
242 return (kmfrv);
243 }
244
245 static int
gencert_file(KMF_HANDLE_T kmfhandle,KMF_KEY_ALG keyAlg,KMF_ALGORITHM_INDEX sigAlg,int keylen,KMF_ENCODE_FORMAT fmt,uint32_t ltime,char * subject,char * altname,KMF_GENERALNAMECHOICES alttype,int altcrit,KMF_BIGINT * serial,uint16_t kubits,int kucrit,char * outcert,char * outkey,EKU_LIST * ekulist)246 gencert_file(KMF_HANDLE_T kmfhandle,
247 KMF_KEY_ALG keyAlg, KMF_ALGORITHM_INDEX sigAlg,
248 int keylen, KMF_ENCODE_FORMAT fmt,
249 uint32_t ltime, char *subject, char *altname,
250 KMF_GENERALNAMECHOICES alttype, int altcrit,
251 KMF_BIGINT *serial, uint16_t kubits, int kucrit,
252 char *outcert, char *outkey,
253 EKU_LIST *ekulist)
254 {
255 KMF_RETURN kmfrv;
256 KMF_KEY_HANDLE pubk, prik;
257 KMF_X509_CERTIFICATE signedCert;
258 KMF_X509_NAME certSubject;
259 KMF_X509_NAME certIssuer;
260 KMF_DATA x509DER;
261 char *fullcertpath = NULL;
262 char *fullkeypath = NULL;
263 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
264 KMF_ATTRIBUTE attrlist[10];
265 int numattr = 0;
266
267 (void) memset(&signedCert, 0, sizeof (signedCert));
268 (void) memset(&certSubject, 0, sizeof (certSubject));
269 (void) memset(&certIssuer, 0, sizeof (certIssuer));
270 (void) memset(&x509DER, 0, sizeof (x509DER));
271
272 if (EMPTYSTRING(outcert) || EMPTYSTRING(outkey)) {
273 cryptoerror(LOG_STDERR,
274 gettext("No output file was specified for "
275 "the cert or key\n"));
276 return (PK_ERR_USAGE);
277 }
278 fullcertpath = strdup(outcert);
279 if (verify_file(fullcertpath)) {
280 cryptoerror(LOG_STDERR,
281 gettext("Cannot write the indicated output "
282 "certificate file (%s).\n"), fullcertpath);
283 free(fullcertpath);
284 return (PK_ERR_USAGE);
285 }
286
287 /* If the subject name cannot be parsed, flag it now and exit */
288 if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
289 cryptoerror(LOG_STDERR,
290 gettext("Subject name cannot be parsed (%s)\n"), subject);
291 return (PK_ERR_USAGE);
292 }
293
294 /* For a self-signed cert, the issuser and subject are the same */
295 if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
296 cryptoerror(LOG_STDERR,
297 gettext("Subject name cannot be parsed (%s)\n"), subject);
298 kmf_free_dn(&certSubject);
299 return (PK_ERR_USAGE);
300 }
301
302 /*
303 * Share the "genkeypair" routine for creating the keypair.
304 */
305 kmfrv = genkeypair_file(kmfhandle, keyAlg, keylen,
306 fmt, outkey, &prik, &pubk);
307 if (kmfrv != KMF_OK)
308 return (kmfrv);
309
310 SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
311 "keypair");
312
313 SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
314
315 SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
316 "serial number");
317
318 SET_VALUE(kmf_set_cert_validity(&signedCert, 0, ltime),
319 "validity time");
320
321 SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
322 "signature algorithm");
323
324 SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
325 "subject name");
326
327 SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
328 "issuer name");
329
330 if (altname != NULL)
331 SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
332 alttype, altname), "subjectAltName");
333
334 if (kubits != 0)
335 SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
336 "KeyUsage");
337
338 if (ekulist != NULL) {
339 int i;
340 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
341 SET_VALUE(kmf_add_cert_eku(&signedCert,
342 &ekulist->ekulist[i],
343 ekulist->critlist[i]), "Extended Key Usage");
344 }
345 }
346 /*
347 * Construct attributes for the kmf_sign_cert operation.
348 */
349 numattr = 0;
350 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
351 &kstype, sizeof (kstype));
352 numattr++;
353
354 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
355 &prik, sizeof (KMF_KEY_HANDLE_ATTR));
356 numattr++;
357
358 /* cert data that is to be signed */
359 kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
360 &signedCert, sizeof (KMF_X509_CERTIFICATE));
361 numattr++;
362
363 /* output buffer for the signed cert */
364 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
365 &x509DER, sizeof (KMF_DATA));
366 numattr++;
367
368 kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
369 &sigAlg, sizeof (sigAlg));
370 numattr++;
371
372 if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
373 KMF_OK) {
374 goto cleanup;
375 }
376
377 /*
378 * Store the cert in the DB.
379 */
380 numattr = 0;
381 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
382 &kstype, sizeof (kstype));
383 numattr++;
384 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
385 &x509DER, sizeof (KMF_DATA));
386 numattr++;
387 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR,
388 fullcertpath, strlen(fullcertpath));
389 numattr++;
390 kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
391 &fmt, sizeof (fmt));
392 numattr++;
393
394 kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
395
396 cleanup:
397 if (fullkeypath != NULL)
398 free(fullkeypath);
399 if (fullcertpath != NULL)
400 free(fullcertpath);
401
402 kmf_free_data(&x509DER);
403 kmf_free_dn(&certSubject);
404 kmf_free_dn(&certIssuer);
405 return (kmfrv);
406 }
407
408 static KMF_RETURN
gencert_nss(KMF_HANDLE_T kmfhandle,char * token,char * subject,char * altname,KMF_GENERALNAMECHOICES alttype,int altcrit,char * nickname,char * dir,char * prefix,KMF_KEY_ALG keyAlg,KMF_ALGORITHM_INDEX sigAlg,int keylen,char * trust,uint32_t ltime,KMF_BIGINT * serial,uint16_t kubits,int kucrit,KMF_CREDENTIAL * tokencred,EKU_LIST * ekulist,KMF_OID * curveoid)409 gencert_nss(KMF_HANDLE_T kmfhandle,
410 char *token, char *subject, char *altname,
411 KMF_GENERALNAMECHOICES alttype, int altcrit,
412 char *nickname, char *dir, char *prefix,
413 KMF_KEY_ALG keyAlg,
414 KMF_ALGORITHM_INDEX sigAlg,
415 int keylen, char *trust,
416 uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits,
417 int kucrit, KMF_CREDENTIAL *tokencred,
418 EKU_LIST *ekulist, KMF_OID *curveoid)
419 {
420 KMF_RETURN kmfrv;
421 KMF_KEY_HANDLE pubk, prik;
422 KMF_X509_CERTIFICATE signedCert;
423 KMF_X509_NAME certSubject;
424 KMF_X509_NAME certIssuer;
425 KMF_DATA x509DER;
426 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
427 KMF_ATTRIBUTE attrlist[16];
428 int numattr = 0;
429
430 if (token == NULL)
431 token = DEFAULT_NSS_TOKEN;
432
433 kmfrv = configure_nss(kmfhandle, dir, prefix);
434 if (kmfrv != KMF_OK)
435 return (kmfrv);
436
437 (void) memset(&signedCert, 0, sizeof (signedCert));
438 (void) memset(&certSubject, 0, sizeof (certSubject));
439 (void) memset(&certIssuer, 0, sizeof (certIssuer));
440 (void) memset(&x509DER, 0, sizeof (x509DER));
441
442 /* If the subject name cannot be parsed, flag it now and exit */
443 if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
444 cryptoerror(LOG_STDERR,
445 gettext("Subject name cannot be parsed.\n"));
446 return (PK_ERR_USAGE);
447 }
448
449 /* For a self-signed cert, the issuser and subject are the same */
450 if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
451 cryptoerror(LOG_STDERR,
452 gettext("Subject name cannot be parsed.\n"));
453 return (PK_ERR_USAGE);
454 }
455
456 kmfrv = genkeypair_nss(kmfhandle, token, nickname, dir,
457 prefix, keyAlg, keylen, tokencred, curveoid,
458 &prik, &pubk);
459 if (kmfrv != KMF_OK)
460 return (kmfrv);
461
462 SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
463 "keypair");
464
465 SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
466
467 SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
468 "serial number");
469
470 SET_VALUE(kmf_set_cert_validity(&signedCert, 0, ltime),
471 "validity time");
472
473 SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
474 "signature algorithm");
475
476 SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
477 "subject name");
478
479 SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
480 "issuer name");
481
482 if (altname != NULL)
483 SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
484 alttype, altname), "subjectAltName");
485
486 if (kubits)
487 SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
488 "subjectAltName");
489
490 if (ekulist != NULL) {
491 int i;
492 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
493 SET_VALUE(kmf_add_cert_eku(&signedCert,
494 &ekulist->ekulist[i],
495 ekulist->critlist[i]), "Extended Key Usage");
496 }
497 }
498 /*
499 * Construct attributes for the kmf_sign_cert operation.
500 */
501 numattr = 0;
502 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
503 &kstype, sizeof (kstype));
504 numattr++;
505
506 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
507 &prik, sizeof (KMF_KEY_HANDLE_ATTR));
508 numattr++;
509
510 /* cert data that is to be signed */
511 kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
512 &signedCert, sizeof (KMF_X509_CERTIFICATE));
513 numattr++;
514
515 /* output buffer for the signed cert */
516 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
517 &x509DER, sizeof (KMF_DATA));
518 numattr++;
519
520 kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
521 &sigAlg, sizeof (sigAlg));
522 numattr++;
523
524 if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
525 KMF_OK) {
526 goto cleanup;
527 }
528
529 /*
530 * Store the cert in the DB.
531 */
532 numattr = 0;
533 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
534 &kstype, sizeof (kstype));
535 numattr++;
536
537 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
538 &x509DER, sizeof (KMF_DATA));
539 numattr++;
540
541 if (nickname != NULL) {
542 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
543 nickname, strlen(nickname));
544 numattr++;
545 }
546
547 if (trust != NULL) {
548 kmf_set_attr_at_index(attrlist, numattr, KMF_TRUSTFLAG_ATTR,
549 trust, strlen(trust));
550 numattr++;
551 }
552
553 if (token != NULL) {
554 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
555 token, strlen(token));
556 numattr++;
557 }
558
559 kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
560
561 cleanup:
562 kmf_free_data(&x509DER);
563 kmf_free_dn(&certSubject);
564 kmf_free_dn(&certIssuer);
565 return (kmfrv);
566 }
567
568 int
pk_gencert(int argc,char * argv[])569 pk_gencert(int argc, char *argv[])
570 {
571 int rv;
572 int opt;
573 extern int optind_av;
574 extern char *optarg_av;
575 KMF_KEYSTORE_TYPE kstype = 0;
576 char *subject = NULL;
577 char *tokenname = NULL;
578 char *dir = NULL;
579 char *prefix = NULL;
580 char *keytype = PK_DEFAULT_KEYTYPE;
581 int keylen = PK_DEFAULT_KEYLENGTH;
582 char *trust = NULL;
583 char *lifetime = NULL;
584 char *certlabel = NULL;
585 char *outcert = NULL;
586 char *outkey = NULL;
587 char *format = NULL;
588 char *serstr = NULL;
589 char *altname = NULL;
590 char *keyusagestr = NULL;
591 char *ekustr = NULL;
592 char *hashname = NULL;
593 KMF_GENERALNAMECHOICES alttype = 0;
594 KMF_BIGINT serial = { NULL, 0 };
595 uint32_t ltime;
596 KMF_HANDLE_T kmfhandle = NULL;
597 KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1;
598 KMF_KEY_ALG keyAlg = KMF_RSA;
599 KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_SHA1WithRSA;
600 boolean_t interactive = B_FALSE;
601 char *subname = NULL;
602 KMF_CREDENTIAL tokencred = { NULL, 0 };
603 uint16_t kubits = 0;
604 int altcrit = 0, kucrit = 0;
605 EKU_LIST *ekulist = NULL;
606 KMF_OID *curveoid = NULL; /* ECC */
607 KMF_OID *hashoid = NULL;
608 int y_flag = 0;
609
610 while ((opt = getopt_av(argc, argv,
611 "ik:(keystore)s:(subject)n:(nickname)A:(altname)"
612 "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)"
613 "r:(trust)L:(lifetime)l:(label)c:(outcert)e:(eku)"
614 "K:(outkey)S:(serial)F:(format)u:(keyusage)C:(curve)"
615 "E(listcurves)h:(hash)")) != EOF) {
616
617 if (opt != 'i' && opt != 'E' && EMPTYSTRING(optarg_av))
618 return (PK_ERR_USAGE);
619
620 switch (opt) {
621 case 'A':
622 altname = optarg_av;
623 break;
624 case 'i':
625 if (interactive || subject)
626 return (PK_ERR_USAGE);
627 else
628 interactive = B_TRUE;
629 break;
630 case 'k':
631 kstype = KS2Int(optarg_av);
632 if (kstype == 0)
633 return (PK_ERR_USAGE);
634 break;
635 case 's':
636 if (interactive || subject)
637 return (PK_ERR_USAGE);
638 else
639 subject = optarg_av;
640 break;
641 case 'l':
642 case 'n':
643 if (certlabel)
644 return (PK_ERR_USAGE);
645 certlabel = optarg_av;
646 break;
647 case 'T':
648 if (tokenname)
649 return (PK_ERR_USAGE);
650 tokenname = optarg_av;
651 break;
652 case 'd':
653 if (dir)
654 return (PK_ERR_USAGE);
655 dir = optarg_av;
656 break;
657 case 'p':
658 if (prefix)
659 return (PK_ERR_USAGE);
660 prefix = optarg_av;
661 break;
662 case 't':
663 keytype = optarg_av;
664 break;
665 case 'u':
666 keyusagestr = optarg_av;
667 break;
668 case 'y':
669 if (sscanf(optarg_av, "%d",
670 &keylen) != 1) {
671 cryptoerror(LOG_STDERR,
672 gettext("key length must be"
673 "a numeric value (%s)\n"),
674 optarg_av);
675 return (PK_ERR_USAGE);
676 }
677 y_flag++;
678 break;
679 case 'r':
680 if (trust)
681 return (PK_ERR_USAGE);
682 trust = optarg_av;
683 break;
684 case 'L':
685 if (lifetime)
686 return (PK_ERR_USAGE);
687 lifetime = optarg_av;
688 break;
689 case 'c':
690 if (outcert)
691 return (PK_ERR_USAGE);
692 outcert = optarg_av;
693 break;
694 case 'K':
695 if (outkey)
696 return (PK_ERR_USAGE);
697 outkey = optarg_av;
698 break;
699 case 'S':
700 serstr = optarg_av;
701 break;
702 case 'F':
703 if (format)
704 return (PK_ERR_USAGE);
705 format = optarg_av;
706 break;
707 case 'e':
708 ekustr = optarg_av;
709 break;
710 case 'C':
711 curveoid = ecc_name_to_oid(optarg_av);
712 if (curveoid == NULL) {
713 cryptoerror(LOG_STDERR,
714 gettext("Unrecognized ECC "
715 "curve.\n"));
716 return (PK_ERR_USAGE);
717 }
718 break;
719 case 'E':
720 /*
721 * This argument is only to be used
722 * by itself, no other options should
723 * be present.
724 */
725 if (argc != 2) {
726 cryptoerror(LOG_STDERR,
727 gettext("listcurves has no other "
728 "options.\n"));
729 return (PK_ERR_USAGE);
730 }
731 show_ecc_curves();
732 return (0);
733 case 'h':
734 hashname = optarg_av;
735 hashoid = ecc_name_to_oid(optarg_av);
736 if (hashoid == NULL) {
737 cryptoerror(LOG_STDERR,
738 gettext("Unrecognized hash.\n"));
739 return (PK_ERR_USAGE);
740 }
741 break;
742 default:
743 return (PK_ERR_USAGE);
744 }
745 }
746
747 /* No additional args allowed. */
748 argc -= optind_av;
749 argv += optind_av;
750 if (argc) {
751 return (PK_ERR_USAGE);
752 }
753
754 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
755 cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
756 return (PK_ERR_USAGE);
757 }
758
759 /* Assume keystore = PKCS#11 if not specified. */
760 if (kstype == 0)
761 kstype = KMF_KEYSTORE_PK11TOKEN;
762
763 if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) {
764 if (interactive && EMPTYSTRING(certlabel)) {
765 (void) get_certlabel(&certlabel);
766 }
767 /* It better not be empty now */
768 if (EMPTYSTRING(certlabel)) {
769 cryptoerror(LOG_STDERR, gettext("A label must be "
770 "specified to create a self-signed certificate."
771 "\n"));
772 return (PK_ERR_USAGE);
773 }
774 } else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outcert)) {
775 cryptoerror(LOG_STDERR, gettext("A certificate filename must "
776 "be specified to create a self-signed certificate.\n"));
777 return (PK_ERR_USAGE);
778 }
779
780 DIR_OPTION_CHECK(kstype, dir);
781
782 if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
783 cryptoerror(LOG_STDERR,
784 gettext("Error parsing format string (%s).\n"),
785 format);
786 return (PK_ERR_USAGE);
787 }
788
789 if (Str2Lifetime(lifetime, <ime) != 0) {
790 cryptoerror(LOG_STDERR,
791 gettext("Error parsing lifetime string\n"));
792 return (PK_ERR_USAGE);
793 }
794
795 if (Str2KeyType(keytype, hashoid, &keyAlg, &sigAlg) != 0) {
796 cryptoerror(LOG_STDERR,
797 gettext("Unsupported key/hash combination (%s/%s).\n"),
798 keytype, (hashname ? hashname : "none"));
799 return (PK_ERR_USAGE);
800 }
801 if (curveoid != NULL && keyAlg != KMF_ECDSA) {
802 cryptoerror(LOG_STDERR, gettext("EC curves are only "
803 "valid for EC keytypes.\n"));
804 return (PK_ERR_USAGE);
805 }
806 if (keyAlg == KMF_ECDSA && curveoid == NULL) {
807 cryptoerror(LOG_STDERR, gettext("A curve must be "
808 "specifed when using EC keys.\n"));
809 return (PK_ERR_USAGE);
810 }
811 /* Adjust default keylength for NSS and DSA */
812 if (keyAlg == KMF_DSA && !y_flag && kstype == KMF_KEYSTORE_NSS)
813 keylen = 1024;
814
815 /*
816 * Check the subject name.
817 * If interactive is true, get it now interactively.
818 */
819 if (interactive) {
820 subname = NULL;
821 if (get_subname(&subname) != KMF_OK || subname == NULL) {
822 cryptoerror(LOG_STDERR, gettext("Failed to get the "
823 "subject name interactively.\n"));
824 return (PK_ERR_USAGE);
825 }
826 if (serstr == NULL) {
827 (void) get_serial(&serstr);
828 }
829 } else {
830 if (EMPTYSTRING(subject)) {
831 cryptoerror(LOG_STDERR, gettext("A subject name or "
832 "-i must be specified to create a self-signed "
833 "certificate.\n"));
834 return (PK_ERR_USAGE);
835 } else {
836 subname = strdup(subject);
837 if (subname == NULL) {
838 cryptoerror(LOG_STDERR,
839 gettext("Out of memory.\n"));
840 return (PK_ERR_SYSTEM);
841 }
842 }
843 }
844
845 if (serstr == NULL) {
846 (void) fprintf(stderr, gettext("A serial number "
847 "must be specified as a hex number when creating"
848 " a self-signed certificate "
849 "(ex: serial=0x0102030405feedface)\n"));
850 rv = PK_ERR_USAGE;
851 goto end;
852 } else {
853 uchar_t *bytes = NULL;
854 size_t bytelen;
855
856 rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
857 if (rv != KMF_OK || bytes == NULL) {
858 (void) fprintf(stderr, gettext("serial number "
859 "must be specified as a hex number "
860 "(ex: 0x0102030405ffeeddee)\n"));
861 rv = PK_ERR_USAGE;
862 goto end;
863 }
864 serial.val = bytes;
865 serial.len = bytelen;
866 }
867
868 if (altname != NULL) {
869 rv = verify_altname(altname, &alttype, &altcrit);
870 if (rv != KMF_OK) {
871 (void) fprintf(stderr, gettext("Subject AltName "
872 "must be specified as a name=value pair. "
873 "See the man page for details.\n"));
874 rv = PK_ERR_USAGE;
875 goto end;
876 } else {
877 /* advance the altname past the '=' sign */
878 char *p = strchr(altname, '=');
879 if (p != NULL)
880 altname = p + 1;
881 }
882 }
883
884 if (keyusagestr != NULL) {
885 rv = verify_keyusage(keyusagestr, &kubits, &kucrit);
886 if (rv != KMF_OK) {
887 (void) fprintf(stderr, gettext("KeyUsage "
888 "must be specified as a comma-separated list. "
889 "See the man page for details.\n"));
890 rv = PK_ERR_USAGE;
891 goto end;
892 }
893 }
894 if (ekustr != NULL) {
895 rv = verify_ekunames(ekustr, &ekulist);
896 if (rv != KMF_OK) {
897 (void) fprintf(stderr, gettext("EKUs must "
898 "be specified as a comma-separated list. "
899 "See the man page for details.\n"));
900 rv = PK_ERR_USAGE;
901 goto end;
902 }
903 }
904 if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) {
905 (void) fprintf(stderr, gettext("ECC certificates are"
906 "only supported with the pkcs11 and nss keystores\n"));
907 rv = PK_ERR_USAGE;
908 goto end;
909 }
910
911 if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) {
912 if (tokenname == NULL || !strlen(tokenname)) {
913 if (kstype == KMF_KEYSTORE_NSS) {
914 tokenname = "internal";
915 } else {
916 tokenname = PK_DEFAULT_PK11TOKEN;
917 }
918 }
919
920 (void) get_token_password(kstype, tokenname, &tokencred);
921 }
922
923 if (kstype == KMF_KEYSTORE_NSS) {
924 if (dir == NULL)
925 dir = PK_DEFAULT_DIRECTORY;
926
927 rv = gencert_nss(kmfhandle,
928 tokenname, subname, altname, alttype, altcrit,
929 certlabel, dir, prefix, keyAlg, sigAlg, keylen,
930 trust, ltime, &serial, kubits, kucrit, &tokencred,
931 ekulist, curveoid);
932
933 } else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
934 rv = gencert_pkcs11(kmfhandle,
935 tokenname, subname, altname, alttype, altcrit,
936 certlabel, keyAlg, sigAlg, keylen, ltime,
937 &serial, kubits, kucrit, &tokencred, ekulist,
938 curveoid);
939
940 } else if (kstype == KMF_KEYSTORE_OPENSSL) {
941 rv = gencert_file(kmfhandle,
942 keyAlg, sigAlg, keylen, fmt,
943 ltime, subname, altname, alttype, altcrit,
944 &serial, kubits, kucrit, outcert, outkey,
945 ekulist);
946 }
947
948 if (rv != KMF_OK)
949 display_error(kmfhandle, rv,
950 gettext("Error creating certificate and keypair"));
951 end:
952 if (ekulist != NULL)
953 free_eku_list(ekulist);
954 if (subname)
955 free(subname);
956 if (tokencred.cred != NULL)
957 free(tokencred.cred);
958
959 if (serial.val != NULL)
960 free(serial.val);
961
962 (void) kmf_finalize(kmfhandle);
963 return (rv);
964 }
965