dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / cmd-crypto / pktool / gencert.c
blobd86e6f7a06fc296559d98bbd717d8fd8e314442e
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; \
45 static int
46 gencert_pkcs11(KMF_HANDLE_T kmfhandle,
47 char *token, char *subject, char *altname,
48 KMF_GENERALNAMECHOICES alttype, int altcrit,
49 char *certlabel, KMF_KEY_ALG keyAlg,
50 KMF_ALGORITHM_INDEX sigAlg,
51 int keylen, uint32_t ltime, KMF_BIGINT *serial,
52 uint16_t kubits, int kucrit, KMF_CREDENTIAL *tokencred,
53 EKU_LIST *ekulist, KMF_OID *curveoid)
55 KMF_RETURN kmfrv = KMF_OK;
56 KMF_KEY_HANDLE pubk, prik;
57 KMF_X509_CERTIFICATE signedCert;
58 KMF_X509_NAME certSubject;
59 KMF_X509_NAME certIssuer;
60 KMF_DATA x509DER;
61 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
62 KMF_ATTRIBUTE attrlist[16];
63 int numattr = 0;
64 KMF_KEY_ALG keytype;
65 uint32_t keylength;
67 (void) memset(&signedCert, 0, sizeof (signedCert));
68 (void) memset(&certSubject, 0, sizeof (certSubject));
69 (void) memset(&certIssuer, 0, sizeof (certIssuer));
70 (void) memset(&x509DER, 0, sizeof (x509DER));
72 /* If the subject name cannot be parsed, flag it now and exit */
73 if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
74 cryptoerror(LOG_STDERR,
75 gettext("Subject name cannot be parsed.\n"));
76 return (PK_ERR_USAGE);
79 /* For a self-signed cert, the issuser and subject are the same */
80 if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
81 cryptoerror(LOG_STDERR,
82 gettext("Subject name cannot be parsed.\n"));
83 return (PK_ERR_USAGE);
86 keylength = keylen; /* bits */
87 keytype = keyAlg;
89 /* Select a PKCS11 token */
90 kmfrv = select_token(kmfhandle, token, FALSE);
91 if (kmfrv != KMF_OK) {
92 return (kmfrv);
96 * Share the "genkeypair" routine for creating the keypair.
98 kmfrv = genkeypair_pkcs11(kmfhandle, token, certlabel,
99 keytype, keylength, tokencred, curveoid, &prik, &pubk);
100 if (kmfrv != KMF_OK)
101 return (kmfrv);
103 SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
104 "keypair");
106 SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
108 SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
109 "serial number");
111 SET_VALUE(kmf_set_cert_validity(&signedCert, 0, ltime),
112 "validity time");
114 SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
115 "signature algorithm");
117 SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
118 "subject name");
120 SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
121 "issuer name");
123 if (altname != NULL)
124 SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
125 alttype, altname), "subjectAltName");
127 if (kubits != 0)
128 SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
129 "KeyUsage");
131 if (ekulist != NULL) {
132 int i;
133 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
134 SET_VALUE(kmf_add_cert_eku(&signedCert,
135 &ekulist->ekulist[i], ekulist->critlist[i]),
136 "Extended Key Usage");
141 * Construct attributes for the kmf_sign_cert operation.
143 numattr = 0;
144 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
145 &kstype, sizeof (kstype));
146 numattr++;
148 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
149 &prik, sizeof (KMF_KEY_HANDLE_ATTR));
150 numattr++;
152 /* cert data that is to be signed */
153 kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
154 &signedCert, sizeof (KMF_X509_CERTIFICATE));
155 numattr++;
157 /* output buffer for the signed cert */
158 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
159 &x509DER, sizeof (KMF_DATA));
160 numattr++;
162 kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
163 &sigAlg, sizeof (sigAlg));
164 numattr++;
166 if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
167 KMF_OK) {
168 goto cleanup;
172 * Store the cert in the DB.
174 numattr = 0;
175 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
176 &kstype, sizeof (kstype));
177 numattr++;
178 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
179 &x509DER, sizeof (KMF_DATA));
180 numattr++;
182 if (certlabel != NULL) {
183 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
184 certlabel, strlen(certlabel));
185 numattr++;
188 kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
190 cleanup:
191 kmf_free_data(&x509DER);
192 kmf_free_dn(&certSubject);
193 kmf_free_dn(&certIssuer);
196 * If kmf_sign_cert or kmf_store_cert failed, then we need to clean up
197 * the key pair from the token.
199 if (kmfrv != KMF_OK) {
200 /* delete the public key */
201 numattr = 0;
202 kmf_set_attr_at_index(attrlist, numattr,
203 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
204 numattr++;
206 kmf_set_attr_at_index(attrlist, numattr,
207 KMF_KEY_HANDLE_ATTR, &pubk, sizeof (KMF_KEY_HANDLE));
208 numattr++;
210 if (tokencred != NULL && tokencred->cred != NULL) {
211 kmf_set_attr_at_index(attrlist, numattr,
212 KMF_CREDENTIAL_ATTR, tokencred,
213 sizeof (KMF_CREDENTIAL));
214 numattr++;
217 (void) kmf_delete_key_from_keystore(kmfhandle, numattr,
218 attrlist);
220 /* delete the private key */
221 numattr = 0;
222 kmf_set_attr_at_index(attrlist, numattr,
223 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
224 numattr++;
226 kmf_set_attr_at_index(attrlist, numattr,
227 KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE));
228 numattr++;
230 if (tokencred != NULL && tokencred->cred != NULL) {
231 kmf_set_attr_at_index(attrlist, numattr,
232 KMF_CREDENTIAL_ATTR, tokencred,
233 sizeof (KMF_CREDENTIAL));
234 numattr++;
237 (void) kmf_delete_key_from_keystore(kmfhandle, numattr,
238 attrlist);
241 return (kmfrv);
244 static int
245 gencert_file(KMF_HANDLE_T kmfhandle,
246 KMF_KEY_ALG keyAlg, KMF_ALGORITHM_INDEX sigAlg,
247 int keylen, KMF_ENCODE_FORMAT fmt,
248 uint32_t ltime, char *subject, char *altname,
249 KMF_GENERALNAMECHOICES alttype, int altcrit,
250 KMF_BIGINT *serial, uint16_t kubits, int kucrit,
251 char *outcert, char *outkey,
252 EKU_LIST *ekulist)
254 KMF_RETURN kmfrv;
255 KMF_KEY_HANDLE pubk, prik;
256 KMF_X509_CERTIFICATE signedCert;
257 KMF_X509_NAME certSubject;
258 KMF_X509_NAME certIssuer;
259 KMF_DATA x509DER;
260 char *fullcertpath = NULL;
261 char *fullkeypath = NULL;
262 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
263 KMF_ATTRIBUTE attrlist[10];
264 int numattr = 0;
266 (void) memset(&signedCert, 0, sizeof (signedCert));
267 (void) memset(&certSubject, 0, sizeof (certSubject));
268 (void) memset(&certIssuer, 0, sizeof (certIssuer));
269 (void) memset(&x509DER, 0, sizeof (x509DER));
271 if (EMPTYSTRING(outcert) || EMPTYSTRING(outkey)) {
272 cryptoerror(LOG_STDERR,
273 gettext("No output file was specified for "
274 "the cert or key\n"));
275 return (PK_ERR_USAGE);
277 fullcertpath = strdup(outcert);
278 if (verify_file(fullcertpath)) {
279 cryptoerror(LOG_STDERR,
280 gettext("Cannot write the indicated output "
281 "certificate file (%s).\n"), fullcertpath);
282 free(fullcertpath);
283 return (PK_ERR_USAGE);
286 /* If the subject name cannot be parsed, flag it now and exit */
287 if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
288 cryptoerror(LOG_STDERR,
289 gettext("Subject name cannot be parsed (%s)\n"), subject);
290 return (PK_ERR_USAGE);
293 /* For a self-signed cert, the issuser and subject are the same */
294 if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
295 cryptoerror(LOG_STDERR,
296 gettext("Subject name cannot be parsed (%s)\n"), subject);
297 kmf_free_dn(&certSubject);
298 return (PK_ERR_USAGE);
302 * Share the "genkeypair" routine for creating the keypair.
304 kmfrv = genkeypair_file(kmfhandle, keyAlg, keylen,
305 fmt, outkey, &prik, &pubk);
306 if (kmfrv != KMF_OK)
307 return (kmfrv);
309 SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
310 "keypair");
312 SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
314 SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
315 "serial number");
317 SET_VALUE(kmf_set_cert_validity(&signedCert, 0, ltime),
318 "validity time");
320 SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
321 "signature algorithm");
323 SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
324 "subject name");
326 SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
327 "issuer name");
329 if (altname != NULL)
330 SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
331 alttype, altname), "subjectAltName");
333 if (kubits != 0)
334 SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
335 "KeyUsage");
337 if (ekulist != NULL) {
338 int i;
339 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
340 SET_VALUE(kmf_add_cert_eku(&signedCert,
341 &ekulist->ekulist[i],
342 ekulist->critlist[i]), "Extended Key Usage");
346 * Construct attributes for the kmf_sign_cert operation.
348 numattr = 0;
349 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
350 &kstype, sizeof (kstype));
351 numattr++;
353 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
354 &prik, sizeof (KMF_KEY_HANDLE_ATTR));
355 numattr++;
357 /* cert data that is to be signed */
358 kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
359 &signedCert, sizeof (KMF_X509_CERTIFICATE));
360 numattr++;
362 /* output buffer for the signed cert */
363 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
364 &x509DER, sizeof (KMF_DATA));
365 numattr++;
367 kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
368 &sigAlg, sizeof (sigAlg));
369 numattr++;
371 if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
372 KMF_OK) {
373 goto cleanup;
377 * Store the cert in the DB.
379 numattr = 0;
380 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
381 &kstype, sizeof (kstype));
382 numattr++;
383 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
384 &x509DER, sizeof (KMF_DATA));
385 numattr++;
386 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR,
387 fullcertpath, strlen(fullcertpath));
388 numattr++;
389 kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
390 &fmt, sizeof (fmt));
391 numattr++;
393 kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
395 cleanup:
396 free(fullkeypath);
397 free(fullcertpath);
399 kmf_free_data(&x509DER);
400 kmf_free_dn(&certSubject);
401 kmf_free_dn(&certIssuer);
402 return (kmfrv);
405 static KMF_RETURN
406 gencert_nss(KMF_HANDLE_T kmfhandle,
407 char *token, char *subject, char *altname,
408 KMF_GENERALNAMECHOICES alttype, int altcrit,
409 char *nickname, char *dir, char *prefix,
410 KMF_KEY_ALG keyAlg,
411 KMF_ALGORITHM_INDEX sigAlg,
412 int keylen, char *trust,
413 uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits,
414 int kucrit, KMF_CREDENTIAL *tokencred,
415 EKU_LIST *ekulist, KMF_OID *curveoid)
417 KMF_RETURN kmfrv;
418 KMF_KEY_HANDLE pubk, prik;
419 KMF_X509_CERTIFICATE signedCert;
420 KMF_X509_NAME certSubject;
421 KMF_X509_NAME certIssuer;
422 KMF_DATA x509DER;
423 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
424 KMF_ATTRIBUTE attrlist[16];
425 int numattr = 0;
427 if (token == NULL)
428 token = DEFAULT_NSS_TOKEN;
430 kmfrv = configure_nss(kmfhandle, dir, prefix);
431 if (kmfrv != KMF_OK)
432 return (kmfrv);
434 (void) memset(&signedCert, 0, sizeof (signedCert));
435 (void) memset(&certSubject, 0, sizeof (certSubject));
436 (void) memset(&certIssuer, 0, sizeof (certIssuer));
437 (void) memset(&x509DER, 0, sizeof (x509DER));
439 /* If the subject name cannot be parsed, flag it now and exit */
440 if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
441 cryptoerror(LOG_STDERR,
442 gettext("Subject name cannot be parsed.\n"));
443 return (PK_ERR_USAGE);
446 /* For a self-signed cert, the issuser and subject are the same */
447 if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
448 cryptoerror(LOG_STDERR,
449 gettext("Subject name cannot be parsed.\n"));
450 return (PK_ERR_USAGE);
453 kmfrv = genkeypair_nss(kmfhandle, token, nickname, dir,
454 prefix, keyAlg, keylen, tokencred, curveoid,
455 &prik, &pubk);
456 if (kmfrv != KMF_OK)
457 return (kmfrv);
459 SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
460 "keypair");
462 SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
464 SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
465 "serial number");
467 SET_VALUE(kmf_set_cert_validity(&signedCert, 0, ltime),
468 "validity time");
470 SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
471 "signature algorithm");
473 SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
474 "subject name");
476 SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
477 "issuer name");
479 if (altname != NULL)
480 SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
481 alttype, altname), "subjectAltName");
483 if (kubits)
484 SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
485 "subjectAltName");
487 if (ekulist != NULL) {
488 int i;
489 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
490 SET_VALUE(kmf_add_cert_eku(&signedCert,
491 &ekulist->ekulist[i],
492 ekulist->critlist[i]), "Extended Key Usage");
496 * Construct attributes for the kmf_sign_cert operation.
498 numattr = 0;
499 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
500 &kstype, sizeof (kstype));
501 numattr++;
503 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
504 &prik, sizeof (KMF_KEY_HANDLE_ATTR));
505 numattr++;
507 /* cert data that is to be signed */
508 kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
509 &signedCert, sizeof (KMF_X509_CERTIFICATE));
510 numattr++;
512 /* output buffer for the signed cert */
513 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
514 &x509DER, sizeof (KMF_DATA));
515 numattr++;
517 kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
518 &sigAlg, sizeof (sigAlg));
519 numattr++;
521 if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
522 KMF_OK) {
523 goto cleanup;
527 * Store the cert in the DB.
529 numattr = 0;
530 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
531 &kstype, sizeof (kstype));
532 numattr++;
534 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
535 &x509DER, sizeof (KMF_DATA));
536 numattr++;
538 if (nickname != NULL) {
539 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
540 nickname, strlen(nickname));
541 numattr++;
544 if (trust != NULL) {
545 kmf_set_attr_at_index(attrlist, numattr, KMF_TRUSTFLAG_ATTR,
546 trust, strlen(trust));
547 numattr++;
550 if (token != NULL) {
551 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
552 token, strlen(token));
553 numattr++;
556 kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
558 cleanup:
559 kmf_free_data(&x509DER);
560 kmf_free_dn(&certSubject);
561 kmf_free_dn(&certIssuer);
562 return (kmfrv);
566 pk_gencert(int argc, char *argv[])
568 int rv;
569 int opt;
570 extern int optind_av;
571 extern char *optarg_av;
572 KMF_KEYSTORE_TYPE kstype = 0;
573 char *subject = NULL;
574 char *tokenname = NULL;
575 char *dir = NULL;
576 char *prefix = NULL;
577 char *keytype = PK_DEFAULT_KEYTYPE;
578 int keylen = PK_DEFAULT_KEYLENGTH;
579 char *trust = NULL;
580 char *lifetime = NULL;
581 char *certlabel = NULL;
582 char *outcert = NULL;
583 char *outkey = NULL;
584 char *format = NULL;
585 char *serstr = NULL;
586 char *altname = NULL;
587 char *keyusagestr = NULL;
588 char *ekustr = NULL;
589 char *hashname = NULL;
590 KMF_GENERALNAMECHOICES alttype = 0;
591 KMF_BIGINT serial = { NULL, 0 };
592 uint32_t ltime;
593 KMF_HANDLE_T kmfhandle = NULL;
594 KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1;
595 KMF_KEY_ALG keyAlg = KMF_RSA;
596 KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_SHA1WithRSA;
597 boolean_t interactive = B_FALSE;
598 char *subname = NULL;
599 KMF_CREDENTIAL tokencred = { NULL, 0 };
600 uint16_t kubits = 0;
601 int altcrit = 0, kucrit = 0;
602 EKU_LIST *ekulist = NULL;
603 KMF_OID *curveoid = NULL; /* ECC */
604 KMF_OID *hashoid = NULL;
605 int y_flag = 0;
607 while ((opt = getopt_av(argc, argv,
608 "ik:(keystore)s:(subject)n:(nickname)A:(altname)"
609 "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)"
610 "r:(trust)L:(lifetime)l:(label)c:(outcert)e:(eku)"
611 "K:(outkey)S:(serial)F:(format)u:(keyusage)C:(curve)"
612 "E(listcurves)h:(hash)")) != EOF) {
614 if (opt != 'i' && opt != 'E' && EMPTYSTRING(optarg_av))
615 return (PK_ERR_USAGE);
617 switch (opt) {
618 case 'A':
619 altname = optarg_av;
620 break;
621 case 'i':
622 if (interactive || subject)
623 return (PK_ERR_USAGE);
624 else
625 interactive = B_TRUE;
626 break;
627 case 'k':
628 kstype = KS2Int(optarg_av);
629 if (kstype == 0)
630 return (PK_ERR_USAGE);
631 break;
632 case 's':
633 if (interactive || subject)
634 return (PK_ERR_USAGE);
635 else
636 subject = optarg_av;
637 break;
638 case 'l':
639 case 'n':
640 if (certlabel)
641 return (PK_ERR_USAGE);
642 certlabel = optarg_av;
643 break;
644 case 'T':
645 if (tokenname)
646 return (PK_ERR_USAGE);
647 tokenname = optarg_av;
648 break;
649 case 'd':
650 if (dir)
651 return (PK_ERR_USAGE);
652 dir = optarg_av;
653 break;
654 case 'p':
655 if (prefix)
656 return (PK_ERR_USAGE);
657 prefix = optarg_av;
658 break;
659 case 't':
660 keytype = optarg_av;
661 break;
662 case 'u':
663 keyusagestr = optarg_av;
664 break;
665 case 'y':
666 if (sscanf(optarg_av, "%d",
667 &keylen) != 1) {
668 cryptoerror(LOG_STDERR,
669 gettext("key length must be"
670 "a numeric value (%s)\n"),
671 optarg_av);
672 return (PK_ERR_USAGE);
674 y_flag++;
675 break;
676 case 'r':
677 if (trust)
678 return (PK_ERR_USAGE);
679 trust = optarg_av;
680 break;
681 case 'L':
682 if (lifetime)
683 return (PK_ERR_USAGE);
684 lifetime = optarg_av;
685 break;
686 case 'c':
687 if (outcert)
688 return (PK_ERR_USAGE);
689 outcert = optarg_av;
690 break;
691 case 'K':
692 if (outkey)
693 return (PK_ERR_USAGE);
694 outkey = optarg_av;
695 break;
696 case 'S':
697 serstr = optarg_av;
698 break;
699 case 'F':
700 if (format)
701 return (PK_ERR_USAGE);
702 format = optarg_av;
703 break;
704 case 'e':
705 ekustr = optarg_av;
706 break;
707 case 'C':
708 curveoid = ecc_name_to_oid(optarg_av);
709 if (curveoid == NULL) {
710 cryptoerror(LOG_STDERR,
711 gettext("Unrecognized ECC "
712 "curve.\n"));
713 return (PK_ERR_USAGE);
715 break;
716 case 'E':
718 * This argument is only to be used
719 * by itself, no other options should
720 * be present.
722 if (argc != 2) {
723 cryptoerror(LOG_STDERR,
724 gettext("listcurves has no other "
725 "options.\n"));
726 return (PK_ERR_USAGE);
728 show_ecc_curves();
729 return (0);
730 case 'h':
731 hashname = optarg_av;
732 hashoid = ecc_name_to_oid(optarg_av);
733 if (hashoid == NULL) {
734 cryptoerror(LOG_STDERR,
735 gettext("Unrecognized hash.\n"));
736 return (PK_ERR_USAGE);
738 break;
739 default:
740 return (PK_ERR_USAGE);
744 /* No additional args allowed. */
745 argc -= optind_av;
746 argv += optind_av;
747 if (argc) {
748 return (PK_ERR_USAGE);
751 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
752 cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
753 return (PK_ERR_USAGE);
756 /* Assume keystore = PKCS#11 if not specified. */
757 if (kstype == 0)
758 kstype = KMF_KEYSTORE_PK11TOKEN;
760 if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) {
761 if (interactive && EMPTYSTRING(certlabel)) {
762 (void) get_certlabel(&certlabel);
764 /* It better not be empty now */
765 if (EMPTYSTRING(certlabel)) {
766 cryptoerror(LOG_STDERR, gettext("A label must be "
767 "specified to create a self-signed certificate."
768 "\n"));
769 return (PK_ERR_USAGE);
771 } else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outcert)) {
772 cryptoerror(LOG_STDERR, gettext("A certificate filename must "
773 "be specified to create a self-signed certificate.\n"));
774 return (PK_ERR_USAGE);
777 DIR_OPTION_CHECK(kstype, dir);
779 if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
780 cryptoerror(LOG_STDERR,
781 gettext("Error parsing format string (%s).\n"),
782 format);
783 return (PK_ERR_USAGE);
786 if (Str2Lifetime(lifetime, &ltime) != 0) {
787 cryptoerror(LOG_STDERR,
788 gettext("Error parsing lifetime string\n"));
789 return (PK_ERR_USAGE);
792 if (Str2KeyType(keytype, hashoid, &keyAlg, &sigAlg) != 0) {
793 cryptoerror(LOG_STDERR,
794 gettext("Unsupported key/hash combination (%s/%s).\n"),
795 keytype, (hashname ? hashname : "none"));
796 return (PK_ERR_USAGE);
798 if (curveoid != NULL && keyAlg != KMF_ECDSA) {
799 cryptoerror(LOG_STDERR, gettext("EC curves are only "
800 "valid for EC keytypes.\n"));
801 return (PK_ERR_USAGE);
803 if (keyAlg == KMF_ECDSA && curveoid == NULL) {
804 cryptoerror(LOG_STDERR, gettext("A curve must be "
805 "specifed when using EC keys.\n"));
806 return (PK_ERR_USAGE);
808 /* Adjust default keylength for NSS and DSA */
809 if (keyAlg == KMF_DSA && !y_flag && kstype == KMF_KEYSTORE_NSS)
810 keylen = 1024;
813 * Check the subject name.
814 * If interactive is true, get it now interactively.
816 if (interactive) {
817 subname = NULL;
818 if (get_subname(&subname) != KMF_OK || subname == NULL) {
819 cryptoerror(LOG_STDERR, gettext("Failed to get the "
820 "subject name interactively.\n"));
821 return (PK_ERR_USAGE);
823 if (serstr == NULL) {
824 (void) get_serial(&serstr);
826 } else {
827 if (EMPTYSTRING(subject)) {
828 cryptoerror(LOG_STDERR, gettext("A subject name or "
829 "-i must be specified to create a self-signed "
830 "certificate.\n"));
831 return (PK_ERR_USAGE);
832 } else {
833 subname = strdup(subject);
834 if (subname == NULL) {
835 cryptoerror(LOG_STDERR,
836 gettext("Out of memory.\n"));
837 return (PK_ERR_SYSTEM);
842 if (serstr == NULL) {
843 (void) fprintf(stderr, gettext("A serial number "
844 "must be specified as a hex number when creating"
845 " a self-signed certificate "
846 "(ex: serial=0x0102030405feedface)\n"));
847 rv = PK_ERR_USAGE;
848 goto end;
849 } else {
850 uchar_t *bytes = NULL;
851 size_t bytelen;
853 rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
854 if (rv != KMF_OK || bytes == NULL) {
855 (void) fprintf(stderr, gettext("serial number "
856 "must be specified as a hex number "
857 "(ex: 0x0102030405ffeeddee)\n"));
858 rv = PK_ERR_USAGE;
859 goto end;
861 serial.val = bytes;
862 serial.len = bytelen;
865 if (altname != NULL) {
866 rv = verify_altname(altname, &alttype, &altcrit);
867 if (rv != KMF_OK) {
868 (void) fprintf(stderr, gettext("Subject AltName "
869 "must be specified as a name=value pair. "
870 "See the man page for details.\n"));
871 rv = PK_ERR_USAGE;
872 goto end;
873 } else {
874 /* advance the altname past the '=' sign */
875 char *p = strchr(altname, '=');
876 if (p != NULL)
877 altname = p + 1;
881 if (keyusagestr != NULL) {
882 rv = verify_keyusage(keyusagestr, &kubits, &kucrit);
883 if (rv != KMF_OK) {
884 (void) fprintf(stderr, gettext("KeyUsage "
885 "must be specified as a comma-separated list. "
886 "See the man page for details.\n"));
887 rv = PK_ERR_USAGE;
888 goto end;
891 if (ekustr != NULL) {
892 rv = verify_ekunames(ekustr, &ekulist);
893 if (rv != KMF_OK) {
894 (void) fprintf(stderr, gettext("EKUs must "
895 "be specified as a comma-separated list. "
896 "See the man page for details.\n"));
897 rv = PK_ERR_USAGE;
898 goto end;
901 if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) {
902 (void) fprintf(stderr, gettext("ECC certificates are"
903 "only supported with the pkcs11 and nss keystores\n"));
904 rv = PK_ERR_USAGE;
905 goto end;
908 if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) {
909 if (tokenname == NULL || !strlen(tokenname)) {
910 if (kstype == KMF_KEYSTORE_NSS) {
911 tokenname = "internal";
912 } else {
913 tokenname = PK_DEFAULT_PK11TOKEN;
917 (void) get_token_password(kstype, tokenname, &tokencred);
920 if (kstype == KMF_KEYSTORE_NSS) {
921 if (dir == NULL)
922 dir = PK_DEFAULT_DIRECTORY;
924 rv = gencert_nss(kmfhandle,
925 tokenname, subname, altname, alttype, altcrit,
926 certlabel, dir, prefix, keyAlg, sigAlg, keylen,
927 trust, ltime, &serial, kubits, kucrit, &tokencred,
928 ekulist, curveoid);
930 } else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
931 rv = gencert_pkcs11(kmfhandle,
932 tokenname, subname, altname, alttype, altcrit,
933 certlabel, keyAlg, sigAlg, keylen, ltime,
934 &serial, kubits, kucrit, &tokencred, ekulist,
935 curveoid);
937 } else if (kstype == KMF_KEYSTORE_OPENSSL) {
938 rv = gencert_file(kmfhandle,
939 keyAlg, sigAlg, keylen, fmt,
940 ltime, subname, altname, alttype, altcrit,
941 &serial, kubits, kucrit, outcert, outkey,
942 ekulist);
945 if (rv != KMF_OK)
946 display_error(kmfhandle, rv,
947 gettext("Error creating certificate and keypair"));
948 end:
949 if (ekulist != NULL)
950 free_eku_list(ekulist);
951 free(subname);
952 free(tokencred.cred);
954 free(serial.val);
956 (void) kmf_finalize(kmfhandle);
957 return (rv);