dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / cmd-crypto / pktool / gencsr.c
blobad6772eb7e9eae9337143ec8d2bba173df22122a
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 %s: 0x%02\n"), \
41 s, kmfrv); \
42 goto cleanup; \
45 static KMF_RETURN
46 gencsr_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 int keylen, uint16_t kubits, int kucrit,
51 KMF_ENCODE_FORMAT fmt, char *csrfile,
52 KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist,
53 KMF_ALGORITHM_INDEX sigAlg, KMF_OID *curveoid)
55 KMF_RETURN kmfrv = KMF_OK;
56 KMF_KEY_HANDLE pubk, prik;
57 KMF_X509_NAME csrSubject;
58 KMF_CSR_DATA csr;
59 KMF_DATA signedCsr = { 0, NULL };
61 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
62 int numattr = 0;
63 KMF_ATTRIBUTE attrlist[16];
65 (void) memset(&csr, 0, sizeof (csr));
66 (void) memset(&csrSubject, 0, sizeof (csrSubject));
68 /* If the subject name cannot be parsed, flag it now and exit */
69 if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK)
70 return (kmfrv);
72 /* Select a PKCS11 token */
73 kmfrv = select_token(kmfhandle, token, FALSE);
74 if (kmfrv != KMF_OK)
75 return (kmfrv);
77 * Share the "genkeypair" routine for creating the keypair.
79 kmfrv = genkeypair_pkcs11(kmfhandle, token, certlabel,
80 keyAlg, keylen, tokencred, curveoid, &prik, &pubk);
81 if (kmfrv != KMF_OK)
82 return (kmfrv);
84 SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), "keypair");
86 SET_VALUE(kmf_set_csr_version(&csr, 2), "version number");
88 SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), "subject name");
90 SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg),
91 "SignatureAlgorithm");
93 if (altname != NULL) {
94 SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
95 alttype), "SetCSRSubjectAltName");
98 if (kubits != 0) {
99 SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
100 "SetCSRKeyUsage");
102 if (ekulist != NULL) {
103 int i;
104 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
105 SET_VALUE(kmf_add_csr_eku(&csr,
106 &ekulist->ekulist[i],
107 ekulist->critlist[i]),
108 "Extended Key Usage");
111 if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
112 KMF_OK) {
113 kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile);
116 cleanup:
117 (void) kmf_free_data(&signedCsr);
118 (void) kmf_free_signed_csr(&csr);
120 /* delete the public key */
121 numattr = 0;
122 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
123 &kstype, sizeof (kstype));
124 numattr++;
126 kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
127 &pubk, sizeof (KMF_KEY_HANDLE));
128 numattr++;
130 if (tokencred != NULL && tokencred->cred != NULL) {
131 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
132 tokencred, sizeof (KMF_CREDENTIAL));
133 numattr++;
136 (void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist);
139 * If there is an error, then we need to remove the private key
140 * from the token.
142 if (kmfrv != KMF_OK) {
143 numattr = 0;
144 kmf_set_attr_at_index(attrlist, numattr,
145 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
146 numattr++;
148 kmf_set_attr_at_index(attrlist, numattr,
149 KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE));
150 numattr++;
152 if (tokencred != NULL && tokencred->cred != NULL) {
153 kmf_set_attr_at_index(attrlist, numattr,
154 KMF_CREDENTIAL_ATTR, tokencred,
155 sizeof (KMF_CREDENTIAL));
156 numattr++;
159 (void) kmf_delete_key_from_keystore(kmfhandle, numattr,
160 attrlist);
163 (void) kmf_free_kmf_key(kmfhandle, &prik);
164 return (kmfrv);
167 static KMF_RETURN
168 gencsr_file(KMF_HANDLE_T kmfhandle,
169 KMF_KEY_ALG keyAlg,
170 int keylen, KMF_ENCODE_FORMAT fmt,
171 char *subject, char *altname, KMF_GENERALNAMECHOICES alttype,
172 int altcrit, uint16_t kubits, int kucrit,
173 char *outcsr, char *outkey, EKU_LIST *ekulist,
174 KMF_ALGORITHM_INDEX sigAlg)
176 KMF_RETURN kmfrv;
177 KMF_KEY_HANDLE pubk, prik;
178 KMF_X509_NAME csrSubject;
179 KMF_CSR_DATA csr;
180 KMF_DATA signedCsr = { 0, NULL };
181 char *fullcsrpath = NULL;
182 char *fullkeypath = NULL;
185 (void) memset(&csr, 0, sizeof (csr));
186 (void) memset(&csrSubject, 0, sizeof (csrSubject));
188 if (EMPTYSTRING(outcsr) || EMPTYSTRING(outkey)) {
189 cryptoerror(LOG_STDERR,
190 gettext("No output file was specified for "
191 "the csr or key\n"));
192 return (KMF_ERR_BAD_PARAMETER);
194 fullcsrpath = strdup(outcsr);
195 if (verify_file(fullcsrpath)) {
196 cryptoerror(LOG_STDERR,
197 gettext("Cannot write the indicated output "
198 "certificate file (%s).\n"), fullcsrpath);
199 free(fullcsrpath);
200 return (PK_ERR_USAGE);
203 /* If the subject name cannot be parsed, flag it now and exit */
204 if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) {
205 return (kmfrv);
208 * Share the "genkeypair" routine for creating the keypair.
210 kmfrv = genkeypair_file(kmfhandle, keyAlg, keylen,
211 fmt, outkey, &prik, &pubk);
212 if (kmfrv != KMF_OK)
213 return (kmfrv);
215 SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr),
216 "SetCSRPubKey");
218 SET_VALUE(kmf_set_csr_version(&csr, 2), "SetCSRVersion");
220 SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject),
221 "kmf_set_csr_subject");
223 SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg");
225 if (altname != NULL) {
226 SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
227 alttype), "kmf_set_csr_subject_altname");
229 if (kubits != 0) {
230 SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
231 "kmf_set_csr_ku");
233 if (ekulist != NULL) {
234 int i;
235 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
236 SET_VALUE(kmf_add_csr_eku(&csr,
237 &ekulist->ekulist[i],
238 ekulist->critlist[i]),
239 "Extended Key Usage");
242 if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
243 KMF_OK) {
244 kmfrv = kmf_create_csr_file(&signedCsr, fmt, fullcsrpath);
247 cleanup:
248 free(fullkeypath);
249 free(fullcsrpath);
251 kmf_free_data(&signedCsr);
252 kmf_free_kmf_key(kmfhandle, &prik);
253 kmf_free_signed_csr(&csr);
255 return (kmfrv);
258 static KMF_RETURN
259 gencsr_nss(KMF_HANDLE_T kmfhandle,
260 char *token, char *subject, char *altname,
261 KMF_GENERALNAMECHOICES alttype, int altcrit,
262 char *nickname, char *dir, char *prefix,
263 KMF_KEY_ALG keyAlg, int keylen,
264 uint16_t kubits, int kucrit,
265 KMF_ENCODE_FORMAT fmt, char *csrfile,
266 KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist,
267 KMF_ALGORITHM_INDEX sigAlg, KMF_OID *curveoid)
269 KMF_RETURN kmfrv;
270 KMF_KEY_HANDLE pubk, prik;
271 KMF_X509_NAME csrSubject;
272 KMF_CSR_DATA csr;
273 KMF_DATA signedCsr = { 0, NULL };
275 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
276 int numattr = 0;
277 KMF_ATTRIBUTE attrlist[16];
279 if (token == NULL)
280 token = DEFAULT_NSS_TOKEN;
282 kmfrv = configure_nss(kmfhandle, dir, prefix);
283 if (kmfrv != KMF_OK)
284 return (kmfrv);
286 (void) memset(&csr, 0, sizeof (csr));
287 (void) memset(&csrSubject, 0, sizeof (csrSubject));
288 (void) memset(&pubk, 0, sizeof (pubk));
289 (void) memset(&prik, 0, sizeof (prik));
291 /* If the subject name cannot be parsed, flag it now and exit */
292 if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) {
293 return (kmfrv);
296 kmfrv = genkeypair_nss(kmfhandle, token, nickname, dir,
297 prefix, keyAlg, keylen, tokencred, curveoid,
298 &prik, &pubk);
299 if (kmfrv != KMF_OK)
300 return (kmfrv);
302 SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr),
303 "kmf_set_csr_pubkey");
304 SET_VALUE(kmf_set_csr_version(&csr, 2), "kmf_set_csr_version");
305 SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject),
306 "kmf_set_csr_subject");
307 SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg");
309 if (altname != NULL) {
310 SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
311 alttype), "kmf_set_csr_subject_altname");
313 if (kubits != 0) {
314 SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
315 "kmf_set_csr_ku");
317 if (ekulist != NULL) {
318 int i;
319 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
320 SET_VALUE(kmf_add_csr_eku(&csr,
321 &ekulist->ekulist[i],
322 ekulist->critlist[i]),
323 "Extended Key Usage");
326 if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
327 KMF_OK) {
328 kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile);
331 cleanup:
332 (void) kmf_free_data(&signedCsr);
333 (void) kmf_free_kmf_key(kmfhandle, &prik);
335 /* delete the key */
336 numattr = 0;
337 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
338 &kstype, sizeof (kstype));
339 numattr++;
341 kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
342 &pubk, sizeof (KMF_KEY_HANDLE));
343 numattr++;
345 if (tokencred != NULL && tokencred->credlen > 0) {
346 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
347 tokencred, sizeof (KMF_CREDENTIAL));
348 numattr++;
351 if (token && strlen(token)) {
352 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
353 token, strlen(token));
354 numattr++;
357 (void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist);
359 (void) kmf_free_signed_csr(&csr);
361 return (kmfrv);
365 pk_gencsr(int argc, char *argv[])
367 KMF_RETURN rv;
368 int opt;
369 extern int optind_av;
370 extern char *optarg_av;
371 KMF_KEYSTORE_TYPE kstype = 0;
372 char *subject = NULL;
373 char *tokenname = NULL;
374 char *dir = NULL;
375 char *prefix = NULL;
376 int keylen = PK_DEFAULT_KEYLENGTH;
377 char *certlabel = NULL;
378 char *outcsr = NULL;
379 char *outkey = NULL;
380 char *format = NULL;
381 char *altname = NULL;
382 char *kustr = NULL;
383 char *ekustr = NULL;
384 char *hashname = NULL;
385 uint16_t kubits = 0;
386 char *keytype = PK_DEFAULT_KEYTYPE;
387 KMF_HANDLE_T kmfhandle = NULL;
388 KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1;
389 KMF_KEY_ALG keyAlg = KMF_RSA;
390 KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_SHA1WithRSA;
391 boolean_t interactive = B_FALSE;
392 char *subname = NULL;
393 KMF_CREDENTIAL tokencred = { NULL, 0 };
394 KMF_GENERALNAMECHOICES alttype = 0;
395 int altcrit = 0, kucrit = 0;
396 EKU_LIST *ekulist = NULL;
397 KMF_OID *curveoid = NULL; /* ECC */
398 KMF_OID *hashoid = NULL;
399 int y_flag = 0;
401 while ((opt = getopt_av(argc, argv,
402 "ik:(keystore)s:(subject)n:(nickname)A:(altname)"
403 "u:(keyusage)T:(token)d:(dir)p:(prefix)t:(keytype)"
404 "y:(keylen)l:(label)c:(outcsr)e:(eku)C:(curve)"
405 "K:(outkey)F:(format)E(listcurves)h:(hash)")) != EOF) {
407 switch (opt) {
408 case 'A':
409 altname = optarg_av;
410 break;
411 case 'i':
412 if (interactive)
413 return (PK_ERR_USAGE);
414 else if (subject) {
415 cryptoerror(LOG_STDERR,
416 gettext("Interactive (-i) and "
417 "subject options are mutually "
418 "exclusive.\n"));
419 return (PK_ERR_USAGE);
420 } else
421 interactive = B_TRUE;
422 break;
423 case 'k':
424 kstype = KS2Int(optarg_av);
425 if (kstype == 0)
426 return (PK_ERR_USAGE);
427 break;
428 case 's':
429 if (subject)
430 return (PK_ERR_USAGE);
431 else if (interactive) {
432 cryptoerror(LOG_STDERR,
433 gettext("Interactive (-i) and "
434 "subject options are mutually "
435 "exclusive.\n"));
436 return (PK_ERR_USAGE);
437 } else
438 subject = optarg_av;
439 break;
440 case 'l':
441 case 'n':
442 if (certlabel)
443 return (PK_ERR_USAGE);
444 certlabel = optarg_av;
445 break;
446 case 'T':
447 if (tokenname)
448 return (PK_ERR_USAGE);
449 tokenname = optarg_av;
450 break;
451 case 'd':
452 dir = optarg_av;
453 break;
454 case 'p':
455 if (prefix)
456 return (PK_ERR_USAGE);
457 prefix = optarg_av;
458 break;
459 case 't':
460 keytype = optarg_av;
461 break;
462 case 'u':
463 kustr = optarg_av;
464 break;
465 case 'y':
466 if (sscanf(optarg_av, "%d",
467 &keylen) != 1) {
468 cryptoerror(LOG_STDERR,
469 gettext("Unrecognized "
470 "key length (%s)\n"), optarg_av);
471 return (PK_ERR_USAGE);
473 y_flag++;
474 break;
475 case 'c':
476 if (outcsr)
477 return (PK_ERR_USAGE);
478 outcsr = optarg_av;
479 break;
480 case 'K':
481 if (outkey)
482 return (PK_ERR_USAGE);
483 outkey = optarg_av;
484 break;
485 case 'F':
486 if (format)
487 return (PK_ERR_USAGE);
488 format = optarg_av;
489 break;
490 case 'e':
491 ekustr = optarg_av;
492 break;
493 case 'C':
494 curveoid = ecc_name_to_oid(optarg_av);
495 if (curveoid == NULL) {
496 cryptoerror(LOG_STDERR,
497 gettext("Unrecognized ECC "
498 "curve.\n"));
499 return (PK_ERR_USAGE);
501 break;
502 case 'E':
504 * This argument is only to be used
505 * by itself, no other options should
506 * be present.
508 if (argc != 2) {
509 cryptoerror(LOG_STDERR,
510 gettext("listcurves has no other "
511 "options.\n"));
512 return (PK_ERR_USAGE);
514 show_ecc_curves();
515 return (0);
516 case 'h':
517 hashname = optarg_av;
518 hashoid = ecc_name_to_oid(optarg_av);
519 if (hashoid == NULL) {
520 cryptoerror(LOG_STDERR,
521 gettext("Unrecognized hash.\n"));
522 return (PK_ERR_USAGE);
524 break;
525 default:
526 cryptoerror(LOG_STDERR, gettext(
527 "unrecognized gencsr option '%s'\n"),
528 argv[optind_av]);
529 return (PK_ERR_USAGE);
532 /* No additional args allowed. */
533 argc -= optind_av;
534 argv += optind_av;
535 if (argc) {
536 return (PK_ERR_USAGE);
539 /* Assume keystore = PKCS#11 if not specified. */
540 if (kstype == 0)
541 kstype = KMF_KEYSTORE_PK11TOKEN;
543 DIR_OPTION_CHECK(kstype, dir);
545 if (EMPTYSTRING(outcsr) && interactive) {
546 (void) get_filename("CSR", &outcsr);
548 if (EMPTYSTRING(outcsr)) {
549 (void) printf(gettext("A filename must be specified to hold"
550 "the final certificate request data.\n"));
551 return (PK_ERR_USAGE);
554 * verify that the outcsr file does not already exist
555 * and that it can be created.
557 rv = verify_file(outcsr);
558 if (rv == KMF_ERR_OPEN_FILE) {
559 cryptoerror(LOG_STDERR,
560 gettext("Warning: file \"%s\" exists, "
561 "will be overwritten."), outcsr);
562 if (yesno(gettext("Continue with gencsr? "),
563 gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) {
564 return (0);
565 } else {
566 /* remove the file */
567 (void) unlink(outcsr);
569 } else if (rv != KMF_OK) {
570 cryptoerror(LOG_STDERR,
571 gettext("Warning: error accessing \"%s\""), outcsr);
572 return (rv);
575 if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) {
576 if (EMPTYSTRING(certlabel) && interactive)
577 (void) get_certlabel(&certlabel);
579 if (EMPTYSTRING(certlabel)) {
580 cryptoerror(LOG_STDERR, gettext("A label must be "
581 "specified to create a certificate request.\n"));
582 return (PK_ERR_USAGE);
584 } else if (kstype == KMF_KEYSTORE_OPENSSL) {
585 if (EMPTYSTRING(outkey) && interactive)
586 (void) get_filename("private key", &outkey);
588 if (EMPTYSTRING(outkey)) {
589 cryptoerror(LOG_STDERR, gettext("A key filename "
590 "must be specified to create a certificate "
591 "request.\n"));
592 return (PK_ERR_USAGE);
596 if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
597 cryptoerror(LOG_STDERR,
598 gettext("Error parsing format string (%s).\n"), format);
599 return (PK_ERR_USAGE);
601 if (format && fmt != KMF_FORMAT_ASN1 && fmt != KMF_FORMAT_PEM) {
602 cryptoerror(LOG_STDERR,
603 gettext("CSR must be DER or PEM format.\n"));
604 return (PK_ERR_USAGE);
608 * Check the subject name.
609 * If interactive is true, get it now interactively.
611 if (interactive) {
612 if (get_subname(&subname) != KMF_OK) {
613 cryptoerror(LOG_STDERR, gettext("Failed to get the "
614 "subject name interactively.\n"));
615 return (PK_ERR_USAGE);
617 } else {
618 if (EMPTYSTRING(subject)) {
619 cryptoerror(LOG_STDERR, gettext("A subject name or "
620 "-i must be specified to create a certificate "
621 "request.\n"));
622 return (PK_ERR_USAGE);
623 } else {
624 subname = strdup(subject);
625 if (subname == NULL) {
626 cryptoerror(LOG_STDERR,
627 gettext("Out of memory.\n"));
628 return (PK_ERR_SYSTEM);
632 if (altname != NULL) {
633 rv = verify_altname(altname, &alttype, &altcrit);
634 if (rv != KMF_OK) {
635 cryptoerror(LOG_STDERR, gettext("Subject AltName "
636 "must be specified as a name=value pair. "
637 "See the man page for details."));
638 goto end;
639 } else {
640 /* advance the altname past the '=' sign */
641 char *p = strchr(altname, '=');
642 if (p != NULL)
643 altname = p + 1;
647 if (kustr != NULL) {
648 rv = verify_keyusage(kustr, &kubits, &kucrit);
649 if (rv != KMF_OK) {
650 cryptoerror(LOG_STDERR, gettext("KeyUsage "
651 "must be specified as a comma-separated list. "
652 "See the man page for details."));
653 goto end;
656 if (ekustr != NULL) {
657 rv = verify_ekunames(ekustr, &ekulist);
658 if (rv != KMF_OK) {
659 (void) fprintf(stderr, gettext("EKUs must "
660 "be specified as a comma-separated list. "
661 "See the man page for details.\n"));
662 rv = PK_ERR_USAGE;
663 goto end;
666 if ((rv = Str2KeyType(keytype, hashoid, &keyAlg, &sigAlg)) != 0) {
667 cryptoerror(LOG_STDERR,
668 gettext("Unsupported key/hash combination (%s/%s).\n"),
669 keytype, (hashname ? hashname : "none"));
670 goto end;
672 if (curveoid != NULL && keyAlg != KMF_ECDSA) {
673 cryptoerror(LOG_STDERR, gettext("EC curves are only "
674 "valid for EC keytypes.\n"));
675 return (PK_ERR_USAGE);
677 if (keyAlg == KMF_ECDSA && curveoid == NULL) {
678 cryptoerror(LOG_STDERR, gettext("A curve must be "
679 "specifed when using EC keys.\n"));
680 return (PK_ERR_USAGE);
682 if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) {
683 (void) fprintf(stderr, gettext("ECC certificates are"
684 "only supported with the pkcs11 and nss keystores\n"));
685 rv = PK_ERR_USAGE;
686 goto end;
689 /* Adjust default keylength for NSS and DSA */
690 if (keyAlg == KMF_DSA && !y_flag && kstype == KMF_KEYSTORE_NSS)
691 keylen = 1024;
693 if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) {
694 if (tokenname == NULL || !strlen(tokenname)) {
695 if (kstype == KMF_KEYSTORE_NSS) {
696 tokenname = "internal";
697 } else {
698 tokenname = PK_DEFAULT_PK11TOKEN;
702 (void) get_token_password(kstype, tokenname, &tokencred);
705 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
706 cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
707 return (PK_ERR_USAGE);
711 if (kstype == KMF_KEYSTORE_NSS) {
712 if (dir == NULL)
713 dir = PK_DEFAULT_DIRECTORY;
715 rv = gencsr_nss(kmfhandle,
716 tokenname, subname, altname, alttype, altcrit,
717 certlabel, dir, prefix,
718 keyAlg, keylen, kubits, kucrit,
719 fmt, outcsr, &tokencred, ekulist,
720 sigAlg, curveoid);
722 } else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
723 rv = gencsr_pkcs11(kmfhandle,
724 tokenname, subname, altname, alttype, altcrit,
725 certlabel, keyAlg, keylen,
726 kubits, kucrit, fmt, outcsr, &tokencred,
727 ekulist, sigAlg, curveoid);
729 } else if (kstype == KMF_KEYSTORE_OPENSSL) {
730 rv = gencsr_file(kmfhandle,
731 keyAlg, keylen, fmt, subname, altname,
732 alttype, altcrit, kubits, kucrit,
733 outcsr, outkey, ekulist, sigAlg);
736 end:
737 if (rv != KMF_OK) {
738 display_error(kmfhandle, rv,
739 gettext("Error creating CSR or keypair"));
741 if (rv == KMF_ERR_RDN_PARSER) {
742 cryptoerror(LOG_STDERR, gettext("subject or "
743 "issuer name must be in proper DN format.\n"));
747 if (ekulist != NULL)
748 free_eku_list(ekulist);
750 free(subname);
752 free(tokencred.cred);
754 (void) kmf_finalize(kmfhandle);
755 if (rv != KMF_OK)
756 return (PK_ERR_USAGE);
758 return (0);