8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / cmd-crypto / pktool / gencsr.c
blob501e8cabe704a1ccb03d7fbbd5e4aae21eb0e590
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 != NULL) {
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 if (fullkeypath)
249 free(fullkeypath);
250 if (fullcsrpath)
251 free(fullcsrpath);
253 kmf_free_data(&signedCsr);
254 kmf_free_kmf_key(kmfhandle, &prik);
255 kmf_free_signed_csr(&csr);
257 return (kmfrv);
260 static KMF_RETURN
261 gencsr_nss(KMF_HANDLE_T kmfhandle,
262 char *token, char *subject, char *altname,
263 KMF_GENERALNAMECHOICES alttype, int altcrit,
264 char *nickname, char *dir, char *prefix,
265 KMF_KEY_ALG keyAlg, int keylen,
266 uint16_t kubits, int kucrit,
267 KMF_ENCODE_FORMAT fmt, char *csrfile,
268 KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist,
269 KMF_ALGORITHM_INDEX sigAlg, KMF_OID *curveoid)
271 KMF_RETURN kmfrv;
272 KMF_KEY_HANDLE pubk, prik;
273 KMF_X509_NAME csrSubject;
274 KMF_CSR_DATA csr;
275 KMF_DATA signedCsr = { 0, NULL };
277 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
278 int numattr = 0;
279 KMF_ATTRIBUTE attrlist[16];
281 if (token == NULL)
282 token = DEFAULT_NSS_TOKEN;
284 kmfrv = configure_nss(kmfhandle, dir, prefix);
285 if (kmfrv != KMF_OK)
286 return (kmfrv);
288 (void) memset(&csr, 0, sizeof (csr));
289 (void) memset(&csrSubject, 0, sizeof (csrSubject));
290 (void) memset(&pubk, 0, sizeof (pubk));
291 (void) memset(&prik, 0, sizeof (prik));
293 /* If the subject name cannot be parsed, flag it now and exit */
294 if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) {
295 return (kmfrv);
298 kmfrv = genkeypair_nss(kmfhandle, token, nickname, dir,
299 prefix, keyAlg, keylen, tokencred, curveoid,
300 &prik, &pubk);
301 if (kmfrv != KMF_OK)
302 return (kmfrv);
304 SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr),
305 "kmf_set_csr_pubkey");
306 SET_VALUE(kmf_set_csr_version(&csr, 2), "kmf_set_csr_version");
307 SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject),
308 "kmf_set_csr_subject");
309 SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg");
311 if (altname != NULL) {
312 SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
313 alttype), "kmf_set_csr_subject_altname");
315 if (kubits != NULL) {
316 SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
317 "kmf_set_csr_ku");
319 if (ekulist != NULL) {
320 int i;
321 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
322 SET_VALUE(kmf_add_csr_eku(&csr,
323 &ekulist->ekulist[i],
324 ekulist->critlist[i]),
325 "Extended Key Usage");
328 if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
329 KMF_OK) {
330 kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile);
333 cleanup:
334 (void) kmf_free_data(&signedCsr);
335 (void) kmf_free_kmf_key(kmfhandle, &prik);
337 /* delete the key */
338 numattr = 0;
339 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
340 &kstype, sizeof (kstype));
341 numattr++;
343 kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
344 &pubk, sizeof (KMF_KEY_HANDLE));
345 numattr++;
347 if (tokencred != NULL && tokencred->credlen > 0) {
348 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
349 tokencred, sizeof (KMF_CREDENTIAL));
350 numattr++;
353 if (token && strlen(token)) {
354 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
355 token, strlen(token));
356 numattr++;
359 (void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist);
361 (void) kmf_free_signed_csr(&csr);
363 return (kmfrv);
367 pk_gencsr(int argc, char *argv[])
369 KMF_RETURN rv;
370 int opt;
371 extern int optind_av;
372 extern char *optarg_av;
373 KMF_KEYSTORE_TYPE kstype = 0;
374 char *subject = NULL;
375 char *tokenname = NULL;
376 char *dir = NULL;
377 char *prefix = NULL;
378 int keylen = PK_DEFAULT_KEYLENGTH;
379 char *certlabel = NULL;
380 char *outcsr = NULL;
381 char *outkey = NULL;
382 char *format = NULL;
383 char *altname = NULL;
384 char *kustr = NULL;
385 char *ekustr = NULL;
386 char *hashname = NULL;
387 uint16_t kubits = 0;
388 char *keytype = PK_DEFAULT_KEYTYPE;
389 KMF_HANDLE_T kmfhandle = NULL;
390 KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1;
391 KMF_KEY_ALG keyAlg = KMF_RSA;
392 KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_SHA1WithRSA;
393 boolean_t interactive = B_FALSE;
394 char *subname = NULL;
395 KMF_CREDENTIAL tokencred = { NULL, 0 };
396 KMF_GENERALNAMECHOICES alttype = 0;
397 int altcrit = 0, kucrit = 0;
398 EKU_LIST *ekulist = NULL;
399 KMF_OID *curveoid = NULL; /* ECC */
400 KMF_OID *hashoid = NULL;
401 int y_flag = 0;
403 while ((opt = getopt_av(argc, argv,
404 "ik:(keystore)s:(subject)n:(nickname)A:(altname)"
405 "u:(keyusage)T:(token)d:(dir)p:(prefix)t:(keytype)"
406 "y:(keylen)l:(label)c:(outcsr)e:(eku)C:(curve)"
407 "K:(outkey)F:(format)E(listcurves)h:(hash)")) != EOF) {
409 switch (opt) {
410 case 'A':
411 altname = optarg_av;
412 break;
413 case 'i':
414 if (interactive)
415 return (PK_ERR_USAGE);
416 else if (subject) {
417 cryptoerror(LOG_STDERR,
418 gettext("Interactive (-i) and "
419 "subject options are mutually "
420 "exclusive.\n"));
421 return (PK_ERR_USAGE);
422 } else
423 interactive = B_TRUE;
424 break;
425 case 'k':
426 kstype = KS2Int(optarg_av);
427 if (kstype == 0)
428 return (PK_ERR_USAGE);
429 break;
430 case 's':
431 if (subject)
432 return (PK_ERR_USAGE);
433 else if (interactive) {
434 cryptoerror(LOG_STDERR,
435 gettext("Interactive (-i) and "
436 "subject options are mutually "
437 "exclusive.\n"));
438 return (PK_ERR_USAGE);
439 } else
440 subject = optarg_av;
441 break;
442 case 'l':
443 case 'n':
444 if (certlabel)
445 return (PK_ERR_USAGE);
446 certlabel = optarg_av;
447 break;
448 case 'T':
449 if (tokenname)
450 return (PK_ERR_USAGE);
451 tokenname = optarg_av;
452 break;
453 case 'd':
454 dir = optarg_av;
455 break;
456 case 'p':
457 if (prefix)
458 return (PK_ERR_USAGE);
459 prefix = optarg_av;
460 break;
461 case 't':
462 keytype = optarg_av;
463 break;
464 case 'u':
465 kustr = optarg_av;
466 break;
467 case 'y':
468 if (sscanf(optarg_av, "%d",
469 &keylen) != 1) {
470 cryptoerror(LOG_STDERR,
471 gettext("Unrecognized "
472 "key length (%s)\n"), optarg_av);
473 return (PK_ERR_USAGE);
475 y_flag++;
476 break;
477 case 'c':
478 if (outcsr)
479 return (PK_ERR_USAGE);
480 outcsr = optarg_av;
481 break;
482 case 'K':
483 if (outkey)
484 return (PK_ERR_USAGE);
485 outkey = optarg_av;
486 break;
487 case 'F':
488 if (format)
489 return (PK_ERR_USAGE);
490 format = optarg_av;
491 break;
492 case 'e':
493 ekustr = optarg_av;
494 break;
495 case 'C':
496 curveoid = ecc_name_to_oid(optarg_av);
497 if (curveoid == NULL) {
498 cryptoerror(LOG_STDERR,
499 gettext("Unrecognized ECC "
500 "curve.\n"));
501 return (PK_ERR_USAGE);
503 break;
504 case 'E':
506 * This argument is only to be used
507 * by itself, no other options should
508 * be present.
510 if (argc != 2) {
511 cryptoerror(LOG_STDERR,
512 gettext("listcurves has no other "
513 "options.\n"));
514 return (PK_ERR_USAGE);
516 show_ecc_curves();
517 return (0);
518 case 'h':
519 hashname = optarg_av;
520 hashoid = ecc_name_to_oid(optarg_av);
521 if (hashoid == NULL) {
522 cryptoerror(LOG_STDERR,
523 gettext("Unrecognized hash.\n"));
524 return (PK_ERR_USAGE);
526 break;
527 default:
528 cryptoerror(LOG_STDERR, gettext(
529 "unrecognized gencsr option '%s'\n"),
530 argv[optind_av]);
531 return (PK_ERR_USAGE);
534 /* No additional args allowed. */
535 argc -= optind_av;
536 argv += optind_av;
537 if (argc) {
538 return (PK_ERR_USAGE);
541 /* Assume keystore = PKCS#11 if not specified. */
542 if (kstype == 0)
543 kstype = KMF_KEYSTORE_PK11TOKEN;
545 DIR_OPTION_CHECK(kstype, dir);
547 if (EMPTYSTRING(outcsr) && interactive) {
548 (void) get_filename("CSR", &outcsr);
550 if (EMPTYSTRING(outcsr)) {
551 (void) printf(gettext("A filename must be specified to hold"
552 "the final certificate request data.\n"));
553 return (PK_ERR_USAGE);
556 * verify that the outcsr file does not already exist
557 * and that it can be created.
559 rv = verify_file(outcsr);
560 if (rv == KMF_ERR_OPEN_FILE) {
561 cryptoerror(LOG_STDERR,
562 gettext("Warning: file \"%s\" exists, "
563 "will be overwritten."), outcsr);
564 if (yesno(gettext("Continue with gencsr? "),
565 gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) {
566 return (0);
567 } else {
568 /* remove the file */
569 (void) unlink(outcsr);
571 } else if (rv != KMF_OK) {
572 cryptoerror(LOG_STDERR,
573 gettext("Warning: error accessing \"%s\""), outcsr);
574 return (rv);
577 if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) {
578 if (EMPTYSTRING(certlabel) && interactive)
579 (void) get_certlabel(&certlabel);
581 if (EMPTYSTRING(certlabel)) {
582 cryptoerror(LOG_STDERR, gettext("A label must be "
583 "specified to create a certificate request.\n"));
584 return (PK_ERR_USAGE);
586 } else if (kstype == KMF_KEYSTORE_OPENSSL) {
587 if (EMPTYSTRING(outkey) && interactive)
588 (void) get_filename("private key", &outkey);
590 if (EMPTYSTRING(outkey)) {
591 cryptoerror(LOG_STDERR, gettext("A key filename "
592 "must be specified to create a certificate "
593 "request.\n"));
594 return (PK_ERR_USAGE);
598 if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
599 cryptoerror(LOG_STDERR,
600 gettext("Error parsing format string (%s).\n"), format);
601 return (PK_ERR_USAGE);
603 if (format && fmt != KMF_FORMAT_ASN1 && fmt != KMF_FORMAT_PEM) {
604 cryptoerror(LOG_STDERR,
605 gettext("CSR must be DER or PEM format.\n"));
606 return (PK_ERR_USAGE);
610 * Check the subject name.
611 * If interactive is true, get it now interactively.
613 if (interactive) {
614 if (get_subname(&subname) != KMF_OK) {
615 cryptoerror(LOG_STDERR, gettext("Failed to get the "
616 "subject name interactively.\n"));
617 return (PK_ERR_USAGE);
619 } else {
620 if (EMPTYSTRING(subject)) {
621 cryptoerror(LOG_STDERR, gettext("A subject name or "
622 "-i must be specified to create a certificate "
623 "request.\n"));
624 return (PK_ERR_USAGE);
625 } else {
626 subname = strdup(subject);
627 if (subname == NULL) {
628 cryptoerror(LOG_STDERR,
629 gettext("Out of memory.\n"));
630 return (PK_ERR_SYSTEM);
634 if (altname != NULL) {
635 rv = verify_altname(altname, &alttype, &altcrit);
636 if (rv != KMF_OK) {
637 cryptoerror(LOG_STDERR, gettext("Subject AltName "
638 "must be specified as a name=value pair. "
639 "See the man page for details."));
640 goto end;
641 } else {
642 /* advance the altname past the '=' sign */
643 char *p = strchr(altname, '=');
644 if (p != NULL)
645 altname = p + 1;
649 if (kustr != NULL) {
650 rv = verify_keyusage(kustr, &kubits, &kucrit);
651 if (rv != KMF_OK) {
652 cryptoerror(LOG_STDERR, gettext("KeyUsage "
653 "must be specified as a comma-separated list. "
654 "See the man page for details."));
655 goto end;
658 if (ekustr != NULL) {
659 rv = verify_ekunames(ekustr, &ekulist);
660 if (rv != KMF_OK) {
661 (void) fprintf(stderr, gettext("EKUs must "
662 "be specified as a comma-separated list. "
663 "See the man page for details.\n"));
664 rv = PK_ERR_USAGE;
665 goto end;
668 if ((rv = Str2KeyType(keytype, hashoid, &keyAlg, &sigAlg)) != 0) {
669 cryptoerror(LOG_STDERR,
670 gettext("Unsupported key/hash combination (%s/%s).\n"),
671 keytype, (hashname ? hashname : "none"));
672 goto end;
674 if (curveoid != NULL && keyAlg != KMF_ECDSA) {
675 cryptoerror(LOG_STDERR, gettext("EC curves are only "
676 "valid for EC keytypes.\n"));
677 return (PK_ERR_USAGE);
679 if (keyAlg == KMF_ECDSA && curveoid == NULL) {
680 cryptoerror(LOG_STDERR, gettext("A curve must be "
681 "specifed when using EC keys.\n"));
682 return (PK_ERR_USAGE);
684 if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) {
685 (void) fprintf(stderr, gettext("ECC certificates are"
686 "only supported with the pkcs11 and nss keystores\n"));
687 rv = PK_ERR_USAGE;
688 goto end;
691 /* Adjust default keylength for NSS and DSA */
692 if (keyAlg == KMF_DSA && !y_flag && kstype == KMF_KEYSTORE_NSS)
693 keylen = 1024;
695 if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) {
696 if (tokenname == NULL || !strlen(tokenname)) {
697 if (kstype == KMF_KEYSTORE_NSS) {
698 tokenname = "internal";
699 } else {
700 tokenname = PK_DEFAULT_PK11TOKEN;
704 (void) get_token_password(kstype, tokenname, &tokencred);
707 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
708 cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
709 return (PK_ERR_USAGE);
713 if (kstype == KMF_KEYSTORE_NSS) {
714 if (dir == NULL)
715 dir = PK_DEFAULT_DIRECTORY;
717 rv = gencsr_nss(kmfhandle,
718 tokenname, subname, altname, alttype, altcrit,
719 certlabel, dir, prefix,
720 keyAlg, keylen, kubits, kucrit,
721 fmt, outcsr, &tokencred, ekulist,
722 sigAlg, curveoid);
724 } else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
725 rv = gencsr_pkcs11(kmfhandle,
726 tokenname, subname, altname, alttype, altcrit,
727 certlabel, keyAlg, keylen,
728 kubits, kucrit, fmt, outcsr, &tokencred,
729 ekulist, sigAlg, curveoid);
731 } else if (kstype == KMF_KEYSTORE_OPENSSL) {
732 rv = gencsr_file(kmfhandle,
733 keyAlg, keylen, fmt, subname, altname,
734 alttype, altcrit, kubits, kucrit,
735 outcsr, outkey, ekulist, sigAlg);
738 end:
739 if (rv != KMF_OK) {
740 display_error(kmfhandle, rv,
741 gettext("Error creating CSR or keypair"));
743 if (rv == KMF_ERR_RDN_PARSER) {
744 cryptoerror(LOG_STDERR, gettext("subject or "
745 "issuer name must be in proper DN format.\n"));
749 if (ekulist != NULL)
750 free_eku_list(ekulist);
752 if (subname)
753 free(subname);
755 if (tokencred.cred != NULL)
756 free(tokencred.cred);
758 (void) kmf_finalize(kmfhandle);
759 if (rv != KMF_OK)
760 return (PK_ERR_USAGE);
762 return (0);