Merge illumos-gate
[unleashed.git] / usr / src / cmd / cmd-crypto / pktool / gencert.c
blob4beed607678837d5b3efbbe346287072ea2619fd
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
21 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
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"
34 #include <kmfapi.h>
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 } \
46 static int
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)
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;
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));
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);
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);
87 keylength = keylen; /* bits */
88 keytype = keyAlg;
90 /* Select a PKCS11 token */
91 kmfrv = select_token(kmfhandle, token, FALSE);
92 if (kmfrv != KMF_OK) {
93 return (kmfrv);
97 * Share the "genkeypair" routine for creating the keypair.
99 kmfrv = genkeypair_pkcs11(kmfhandle, token, certlabel,
100 keytype, keylength, tokencred, curveoid, &prik, &pubk);
101 if (kmfrv != KMF_OK)
102 return (kmfrv);
104 SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
105 "keypair");
107 SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
109 SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
110 "serial number");
112 SET_VALUE(kmf_set_cert_validity(&signedCert, 0, ltime),
113 "validity time");
115 SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
116 "signature algorithm");
118 SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
119 "subject name");
121 SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
122 "issuer name");
124 if (altname != NULL)
125 SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
126 alttype, altname), "subjectAltName");
128 if (kubits != 0)
129 SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
130 "KeyUsage");
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");
142 * Construct attributes for the kmf_sign_cert operation.
144 numattr = 0;
145 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
146 &kstype, sizeof (kstype));
147 numattr++;
149 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
150 &prik, sizeof (KMF_KEY_HANDLE_ATTR));
151 numattr++;
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++;
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++;
163 kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
164 &sigAlg, sizeof (sigAlg));
165 numattr++;
167 if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
168 KMF_OK) {
169 goto cleanup;
173 * Store the cert in the DB.
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++;
183 if (certlabel != NULL) {
184 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
185 certlabel, strlen(certlabel));
186 numattr++;
189 kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
191 cleanup:
192 kmf_free_data(&x509DER);
193 kmf_free_dn(&certSubject);
194 kmf_free_dn(&certIssuer);
197 * If kmf_sign_cert or kmf_store_cert failed, then we need to clean up
198 * the key pair from the token.
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++;
207 kmf_set_attr_at_index(attrlist, numattr,
208 KMF_KEY_HANDLE_ATTR, &pubk, sizeof (KMF_KEY_HANDLE));
209 numattr++;
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++;
218 (void) kmf_delete_key_from_keystore(kmfhandle, numattr,
219 attrlist);
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++;
227 kmf_set_attr_at_index(attrlist, numattr,
228 KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE));
229 numattr++;
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++;
238 (void) kmf_delete_key_from_keystore(kmfhandle, numattr,
239 attrlist);
242 return (kmfrv);
245 static int
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)
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;
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));
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);
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);
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);
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);
303 * Share the "genkeypair" routine for creating the keypair.
305 kmfrv = genkeypair_file(kmfhandle, keyAlg, keylen,
306 fmt, outkey, &prik, &pubk);
307 if (kmfrv != KMF_OK)
308 return (kmfrv);
310 SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
311 "keypair");
313 SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
315 SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
316 "serial number");
318 SET_VALUE(kmf_set_cert_validity(&signedCert, 0, ltime),
319 "validity time");
321 SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
322 "signature algorithm");
324 SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
325 "subject name");
327 SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
328 "issuer name");
330 if (altname != NULL)
331 SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
332 alttype, altname), "subjectAltName");
334 if (kubits != 0)
335 SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
336 "KeyUsage");
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");
347 * Construct attributes for the kmf_sign_cert operation.
349 numattr = 0;
350 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
351 &kstype, sizeof (kstype));
352 numattr++;
354 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
355 &prik, sizeof (KMF_KEY_HANDLE_ATTR));
356 numattr++;
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++;
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++;
368 kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
369 &sigAlg, sizeof (sigAlg));
370 numattr++;
372 if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
373 KMF_OK) {
374 goto cleanup;
378 * Store the cert in the DB.
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++;
394 kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
396 cleanup:
397 free(fullkeypath);
398 free(fullcertpath);
400 kmf_free_data(&x509DER);
401 kmf_free_dn(&certSubject);
402 kmf_free_dn(&certIssuer);
403 return (kmfrv);
406 static KMF_RETURN
407 gencert_nss(KMF_HANDLE_T kmfhandle,
408 char *token, char *subject, char *altname,
409 KMF_GENERALNAMECHOICES alttype, int altcrit,
410 char *nickname, char *dir, char *prefix,
411 KMF_KEY_ALG keyAlg,
412 KMF_ALGORITHM_INDEX sigAlg,
413 int keylen, char *trust,
414 uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits,
415 int kucrit, KMF_CREDENTIAL *tokencred,
416 EKU_LIST *ekulist, KMF_OID *curveoid)
418 KMF_RETURN kmfrv;
419 KMF_KEY_HANDLE pubk, prik;
420 KMF_X509_CERTIFICATE signedCert;
421 KMF_X509_NAME certSubject;
422 KMF_X509_NAME certIssuer;
423 KMF_DATA x509DER;
424 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
425 KMF_ATTRIBUTE attrlist[16];
426 int numattr = 0;
428 if (token == NULL)
429 token = DEFAULT_NSS_TOKEN;
431 kmfrv = configure_nss(kmfhandle, dir, prefix);
432 if (kmfrv != KMF_OK)
433 return (kmfrv);
435 (void) memset(&signedCert, 0, sizeof (signedCert));
436 (void) memset(&certSubject, 0, sizeof (certSubject));
437 (void) memset(&certIssuer, 0, sizeof (certIssuer));
438 (void) memset(&x509DER, 0, sizeof (x509DER));
440 /* If the subject name cannot be parsed, flag it now and exit */
441 if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
442 cryptoerror(LOG_STDERR,
443 gettext("Subject name cannot be parsed.\n"));
444 return (PK_ERR_USAGE);
447 /* For a self-signed cert, the issuser and subject are the same */
448 if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
449 cryptoerror(LOG_STDERR,
450 gettext("Subject name cannot be parsed.\n"));
451 return (PK_ERR_USAGE);
454 kmfrv = genkeypair_nss(kmfhandle, token, nickname, dir,
455 prefix, keyAlg, keylen, tokencred, curveoid,
456 &prik, &pubk);
457 if (kmfrv != KMF_OK)
458 return (kmfrv);
460 SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
461 "keypair");
463 SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
465 SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
466 "serial number");
468 SET_VALUE(kmf_set_cert_validity(&signedCert, 0, ltime),
469 "validity time");
471 SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
472 "signature algorithm");
474 SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
475 "subject name");
477 SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
478 "issuer name");
480 if (altname != NULL)
481 SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
482 alttype, altname), "subjectAltName");
484 if (kubits)
485 SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
486 "subjectAltName");
488 if (ekulist != NULL) {
489 int i;
490 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
491 SET_VALUE(kmf_add_cert_eku(&signedCert,
492 &ekulist->ekulist[i],
493 ekulist->critlist[i]), "Extended Key Usage");
497 * Construct attributes for the kmf_sign_cert operation.
499 numattr = 0;
500 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
501 &kstype, sizeof (kstype));
502 numattr++;
504 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
505 &prik, sizeof (KMF_KEY_HANDLE_ATTR));
506 numattr++;
508 /* cert data that is to be signed */
509 kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
510 &signedCert, sizeof (KMF_X509_CERTIFICATE));
511 numattr++;
513 /* output buffer for the signed cert */
514 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
515 &x509DER, sizeof (KMF_DATA));
516 numattr++;
518 kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
519 &sigAlg, sizeof (sigAlg));
520 numattr++;
522 if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
523 KMF_OK) {
524 goto cleanup;
528 * Store the cert in the DB.
530 numattr = 0;
531 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
532 &kstype, sizeof (kstype));
533 numattr++;
535 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
536 &x509DER, sizeof (KMF_DATA));
537 numattr++;
539 if (nickname != NULL) {
540 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
541 nickname, strlen(nickname));
542 numattr++;
545 if (trust != NULL) {
546 kmf_set_attr_at_index(attrlist, numattr, KMF_TRUSTFLAG_ATTR,
547 trust, strlen(trust));
548 numattr++;
551 if (token != NULL) {
552 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
553 token, strlen(token));
554 numattr++;
557 kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
559 cleanup:
560 kmf_free_data(&x509DER);
561 kmf_free_dn(&certSubject);
562 kmf_free_dn(&certIssuer);
563 return (kmfrv);
567 pk_gencert(int argc, char *argv[])
569 int rv;
570 int opt;
571 extern int optind_av;
572 extern char *optarg_av;
573 KMF_KEYSTORE_TYPE kstype = 0;
574 char *subject = NULL;
575 char *tokenname = NULL;
576 char *dir = NULL;
577 char *prefix = NULL;
578 char *keytype = PK_DEFAULT_KEYTYPE;
579 int keylen = PK_DEFAULT_KEYLENGTH;
580 char *trust = NULL;
581 char *lifetime = NULL;
582 char *certlabel = NULL;
583 char *outcert = NULL;
584 char *outkey = NULL;
585 char *format = NULL;
586 char *serstr = NULL;
587 char *altname = NULL;
588 char *keyusagestr = NULL;
589 char *ekustr = NULL;
590 char *hashname = NULL;
591 KMF_GENERALNAMECHOICES alttype = 0;
592 KMF_BIGINT serial = { NULL, 0 };
593 uint32_t ltime;
594 KMF_HANDLE_T kmfhandle = NULL;
595 KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1;
596 KMF_KEY_ALG keyAlg = KMF_RSA;
597 KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_SHA1WithRSA;
598 boolean_t interactive = B_FALSE;
599 char *subname = NULL;
600 KMF_CREDENTIAL tokencred = { NULL, 0 };
601 uint16_t kubits = 0;
602 int altcrit = 0, kucrit = 0;
603 EKU_LIST *ekulist = NULL;
604 KMF_OID *curveoid = NULL; /* ECC */
605 KMF_OID *hashoid = NULL;
606 int y_flag = 0;
608 while ((opt = getopt_av(argc, argv,
609 "ik:(keystore)s:(subject)n:(nickname)A:(altname)"
610 "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)"
611 "r:(trust)L:(lifetime)l:(label)c:(outcert)e:(eku)"
612 "K:(outkey)S:(serial)F:(format)u:(keyusage)C:(curve)"
613 "E(listcurves)h:(hash)")) != EOF) {
615 if (opt != 'i' && opt != 'E' && EMPTYSTRING(optarg_av))
616 return (PK_ERR_USAGE);
618 switch (opt) {
619 case 'A':
620 altname = optarg_av;
621 break;
622 case 'i':
623 if (interactive || subject)
624 return (PK_ERR_USAGE);
625 else
626 interactive = B_TRUE;
627 break;
628 case 'k':
629 kstype = KS2Int(optarg_av);
630 if (kstype == 0)
631 return (PK_ERR_USAGE);
632 break;
633 case 's':
634 if (interactive || subject)
635 return (PK_ERR_USAGE);
636 else
637 subject = optarg_av;
638 break;
639 case 'l':
640 case 'n':
641 if (certlabel)
642 return (PK_ERR_USAGE);
643 certlabel = optarg_av;
644 break;
645 case 'T':
646 if (tokenname)
647 return (PK_ERR_USAGE);
648 tokenname = optarg_av;
649 break;
650 case 'd':
651 if (dir)
652 return (PK_ERR_USAGE);
653 dir = optarg_av;
654 break;
655 case 'p':
656 if (prefix)
657 return (PK_ERR_USAGE);
658 prefix = optarg_av;
659 break;
660 case 't':
661 keytype = optarg_av;
662 break;
663 case 'u':
664 keyusagestr = optarg_av;
665 break;
666 case 'y':
667 if (sscanf(optarg_av, "%d",
668 &keylen) != 1) {
669 cryptoerror(LOG_STDERR,
670 gettext("key length must be"
671 "a numeric value (%s)\n"),
672 optarg_av);
673 return (PK_ERR_USAGE);
675 y_flag++;
676 break;
677 case 'r':
678 if (trust)
679 return (PK_ERR_USAGE);
680 trust = optarg_av;
681 break;
682 case 'L':
683 if (lifetime)
684 return (PK_ERR_USAGE);
685 lifetime = optarg_av;
686 break;
687 case 'c':
688 if (outcert)
689 return (PK_ERR_USAGE);
690 outcert = optarg_av;
691 break;
692 case 'K':
693 if (outkey)
694 return (PK_ERR_USAGE);
695 outkey = optarg_av;
696 break;
697 case 'S':
698 serstr = optarg_av;
699 break;
700 case 'F':
701 if (format)
702 return (PK_ERR_USAGE);
703 format = optarg_av;
704 break;
705 case 'e':
706 ekustr = optarg_av;
707 break;
708 case 'C':
709 curveoid = ecc_name_to_oid(optarg_av);
710 if (curveoid == NULL) {
711 cryptoerror(LOG_STDERR,
712 gettext("Unrecognized ECC "
713 "curve.\n"));
714 return (PK_ERR_USAGE);
716 break;
717 case 'E':
719 * This argument is only to be used
720 * by itself, no other options should
721 * be present.
723 if (argc != 2) {
724 cryptoerror(LOG_STDERR,
725 gettext("listcurves has no other "
726 "options.\n"));
727 return (PK_ERR_USAGE);
729 show_ecc_curves();
730 return (0);
731 case 'h':
732 hashname = optarg_av;
733 hashoid = ecc_name_to_oid(optarg_av);
734 if (hashoid == NULL) {
735 cryptoerror(LOG_STDERR,
736 gettext("Unrecognized hash.\n"));
737 return (PK_ERR_USAGE);
739 break;
740 default:
741 return (PK_ERR_USAGE);
745 /* No additional args allowed. */
746 argc -= optind_av;
747 argv += optind_av;
748 if (argc) {
749 return (PK_ERR_USAGE);
752 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
753 cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
754 return (PK_ERR_USAGE);
757 /* Assume keystore = PKCS#11 if not specified. */
758 if (kstype == 0)
759 kstype = KMF_KEYSTORE_PK11TOKEN;
761 if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) {
762 if (interactive && EMPTYSTRING(certlabel)) {
763 (void) get_certlabel(&certlabel);
765 /* It better not be empty now */
766 if (EMPTYSTRING(certlabel)) {
767 cryptoerror(LOG_STDERR, gettext("A label must be "
768 "specified to create a self-signed certificate."
769 "\n"));
770 return (PK_ERR_USAGE);
772 } else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outcert)) {
773 cryptoerror(LOG_STDERR, gettext("A certificate filename must "
774 "be specified to create a self-signed certificate.\n"));
775 return (PK_ERR_USAGE);
778 DIR_OPTION_CHECK(kstype, dir);
780 if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
781 cryptoerror(LOG_STDERR,
782 gettext("Error parsing format string (%s).\n"),
783 format);
784 return (PK_ERR_USAGE);
787 if (Str2Lifetime(lifetime, &ltime) != 0) {
788 cryptoerror(LOG_STDERR,
789 gettext("Error parsing lifetime string\n"));
790 return (PK_ERR_USAGE);
793 if (Str2KeyType(keytype, hashoid, &keyAlg, &sigAlg) != 0) {
794 cryptoerror(LOG_STDERR,
795 gettext("Unsupported key/hash combination (%s/%s).\n"),
796 keytype, (hashname ? hashname : "none"));
797 return (PK_ERR_USAGE);
799 if (curveoid != NULL && keyAlg != KMF_ECDSA) {
800 cryptoerror(LOG_STDERR, gettext("EC curves are only "
801 "valid for EC keytypes.\n"));
802 return (PK_ERR_USAGE);
804 if (keyAlg == KMF_ECDSA && curveoid == NULL) {
805 cryptoerror(LOG_STDERR, gettext("A curve must be "
806 "specifed when using EC keys.\n"));
807 return (PK_ERR_USAGE);
809 /* Adjust default keylength for NSS and DSA */
810 if (keyAlg == KMF_DSA && !y_flag && kstype == KMF_KEYSTORE_NSS)
811 keylen = 1024;
814 * Check the subject name.
815 * If interactive is true, get it now interactively.
817 if (interactive) {
818 subname = NULL;
819 if (get_subname(&subname) != KMF_OK || subname == NULL) {
820 cryptoerror(LOG_STDERR, gettext("Failed to get the "
821 "subject name interactively.\n"));
822 return (PK_ERR_USAGE);
824 if (serstr == NULL) {
825 (void) get_serial(&serstr);
827 } else {
828 if (EMPTYSTRING(subject)) {
829 cryptoerror(LOG_STDERR, gettext("A subject name or "
830 "-i must be specified to create a self-signed "
831 "certificate.\n"));
832 return (PK_ERR_USAGE);
833 } else {
834 subname = strdup(subject);
835 if (subname == NULL) {
836 cryptoerror(LOG_STDERR,
837 gettext("Out of memory.\n"));
838 return (PK_ERR_SYSTEM);
843 if (serstr == NULL) {
844 (void) fprintf(stderr, gettext("A serial number "
845 "must be specified as a hex number when creating"
846 " a self-signed certificate "
847 "(ex: serial=0x0102030405feedface)\n"));
848 rv = PK_ERR_USAGE;
849 goto end;
850 } else {
851 uchar_t *bytes = NULL;
852 size_t bytelen;
854 rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
855 if (rv != KMF_OK || bytes == NULL) {
856 (void) fprintf(stderr, gettext("serial number "
857 "must be specified as a hex number "
858 "(ex: 0x0102030405ffeeddee)\n"));
859 rv = PK_ERR_USAGE;
860 goto end;
862 serial.val = bytes;
863 serial.len = bytelen;
866 if (altname != NULL) {
867 rv = verify_altname(altname, &alttype, &altcrit);
868 if (rv != KMF_OK) {
869 (void) fprintf(stderr, gettext("Subject AltName "
870 "must be specified as a name=value pair. "
871 "See the man page for details.\n"));
872 rv = PK_ERR_USAGE;
873 goto end;
874 } else {
875 /* advance the altname past the '=' sign */
876 char *p = strchr(altname, '=');
877 if (p != NULL)
878 altname = p + 1;
882 if (keyusagestr != NULL) {
883 rv = verify_keyusage(keyusagestr, &kubits, &kucrit);
884 if (rv != KMF_OK) {
885 (void) fprintf(stderr, gettext("KeyUsage "
886 "must be specified as a comma-separated list. "
887 "See the man page for details.\n"));
888 rv = PK_ERR_USAGE;
889 goto end;
892 if (ekustr != NULL) {
893 rv = verify_ekunames(ekustr, &ekulist);
894 if (rv != KMF_OK) {
895 (void) fprintf(stderr, gettext("EKUs must "
896 "be specified as a comma-separated list. "
897 "See the man page for details.\n"));
898 rv = PK_ERR_USAGE;
899 goto end;
902 if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) {
903 (void) fprintf(stderr, gettext("ECC certificates are"
904 "only supported with the pkcs11 and nss keystores\n"));
905 rv = PK_ERR_USAGE;
906 goto end;
909 if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) {
910 if (tokenname == NULL || !strlen(tokenname)) {
911 if (kstype == KMF_KEYSTORE_NSS) {
912 tokenname = "internal";
913 } else {
914 tokenname = PK_DEFAULT_PK11TOKEN;
918 (void) get_token_password(kstype, tokenname, &tokencred);
921 if (kstype == KMF_KEYSTORE_NSS) {
922 if (dir == NULL)
923 dir = PK_DEFAULT_DIRECTORY;
925 rv = gencert_nss(kmfhandle,
926 tokenname, subname, altname, alttype, altcrit,
927 certlabel, dir, prefix, keyAlg, sigAlg, keylen,
928 trust, ltime, &serial, kubits, kucrit, &tokencred,
929 ekulist, curveoid);
931 } else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
932 rv = gencert_pkcs11(kmfhandle,
933 tokenname, subname, altname, alttype, altcrit,
934 certlabel, keyAlg, sigAlg, keylen, ltime,
935 &serial, kubits, kucrit, &tokencred, ekulist,
936 curveoid);
938 } else if (kstype == KMF_KEYSTORE_OPENSSL) {
939 rv = gencert_file(kmfhandle,
940 keyAlg, sigAlg, keylen, fmt,
941 ltime, subname, altname, alttype, altcrit,
942 &serial, kubits, kucrit, outcert, outkey,
943 ekulist);
946 if (rv != KMF_OK)
947 display_error(kmfhandle, rv,
948 gettext("Error creating certificate and keypair"));
949 end:
950 if (ekulist != NULL)
951 free_eku_list(ekulist);
952 free(subname);
953 free(tokencred.cred);
955 free(serial.val);
957 (void) kmf_finalize(kmfhandle);
958 return (rv);