1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 * 21 * 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <stdio.h> 27 #include <string.h> 28 #include <ctype.h> 29 #include <malloc.h> 30 #include <libgen.h> 31 #include <errno.h> 32 #include <cryptoutil.h> 33 #include <security/cryptoki.h> 34 #include "common.h" 35 36 #include <kmfapi.h> 37 38 #define SET_VALUE(f, s) \ 39 kmfrv = f; \ 40 if (kmfrv != KMF_OK) { \ 41 cryptoerror(LOG_STDERR, \ 42 gettext("Failed to %s: 0x%02\n"), \ 43 s, kmfrv); \ 44 goto cleanup; \ 45 } 46 47 static KMF_RETURN 48 gencsr_pkcs11(KMF_HANDLE_T kmfhandle, 49 char *token, char *subject, char *altname, 50 KMF_GENERALNAMECHOICES alttype, int altcrit, 51 char *certlabel, KMF_KEY_ALG keyAlg, 52 int keylen, uint16_t kubits, int kucrit, 53 KMF_ENCODE_FORMAT fmt, char *csrfile, 54 KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist, 55 KMF_ALGORITHM_INDEX sigAlg, KMF_OID *curveoid) 56 { 57 KMF_RETURN kmfrv = KMF_OK; 58 KMF_KEY_HANDLE pubk, prik; 59 KMF_X509_NAME csrSubject; 60 KMF_CSR_DATA csr; 61 KMF_DATA signedCsr = {NULL, 0}; 62 63 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 64 int numattr = 0; 65 KMF_ATTRIBUTE attrlist[16]; 66 67 (void) memset(&csr, 0, sizeof (csr)); 68 (void) memset(&csrSubject, 0, sizeof (csrSubject)); 69 70 /* If the subject name cannot be parsed, flag it now and exit */ 71 if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) 72 return (kmfrv); 73 74 /* Select a PKCS11 token */ 75 kmfrv = select_token(kmfhandle, token, FALSE); 76 if (kmfrv != KMF_OK) 77 return (kmfrv); 78 /* 79 * Share the "genkeypair" routine for creating the keypair. 80 */ 81 kmfrv = genkeypair_pkcs11(kmfhandle, token, certlabel, 82 keyAlg, keylen, tokencred, curveoid, &prik, &pubk); 83 if (kmfrv != KMF_OK) 84 return (kmfrv); 85 86 SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), "keypair"); 87 88 SET_VALUE(kmf_set_csr_version(&csr, 2), "version number"); 89 90 SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), "subject name"); 91 92 SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), 93 "SignatureAlgorithm"); 94 95 if (altname != NULL) { 96 SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit, 97 alttype), "SetCSRSubjectAltName"); 98 } 99 100 if (kubits != 0) { 101 SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits), 102 "SetCSRKeyUsage"); 103 } 104 if (ekulist != NULL) { 105 int i; 106 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 107 SET_VALUE(kmf_add_csr_eku(&csr, 108 &ekulist->ekulist[i], 109 ekulist->critlist[i]), 110 "Extended Key Usage"); 111 } 112 } 113 if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) == 114 KMF_OK) { 115 kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile); 116 } 117 118 cleanup: 119 (void) kmf_free_data(&signedCsr); 120 (void) kmf_free_signed_csr(&csr); 121 122 /* delete the public key */ 123 numattr = 0; 124 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 125 &kstype, sizeof (kstype)); 126 numattr++; 127 128 kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, 129 &pubk, sizeof (KMF_KEY_HANDLE)); 130 numattr++; 131 132 if (tokencred != NULL && tokencred->cred != NULL) { 133 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 134 tokencred, sizeof (KMF_CREDENTIAL)); 135 numattr++; 136 } 137 138 (void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist); 139 140 /* 141 * If there is an error, then we need to remove the private key 142 * from the token. 143 */ 144 if (kmfrv != KMF_OK) { 145 numattr = 0; 146 kmf_set_attr_at_index(attrlist, numattr, 147 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 148 numattr++; 149 150 kmf_set_attr_at_index(attrlist, numattr, 151 KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE)); 152 numattr++; 153 154 if (tokencred != NULL && tokencred->cred != NULL) { 155 kmf_set_attr_at_index(attrlist, numattr, 156 KMF_CREDENTIAL_ATTR, tokencred, 157 sizeof (KMF_CREDENTIAL)); 158 numattr++; 159 } 160 161 (void) kmf_delete_key_from_keystore(kmfhandle, numattr, 162 attrlist); 163 } 164 165 (void) kmf_free_kmf_key(kmfhandle, &prik); 166 return (kmfrv); 167 } 168 169 static KMF_RETURN 170 gencsr_file(KMF_HANDLE_T kmfhandle, 171 KMF_KEY_ALG keyAlg, 172 int keylen, KMF_ENCODE_FORMAT fmt, 173 char *subject, char *altname, KMF_GENERALNAMECHOICES alttype, 174 int altcrit, uint16_t kubits, int kucrit, 175 char *outcsr, char *outkey, EKU_LIST *ekulist, 176 KMF_ALGORITHM_INDEX sigAlg) 177 { 178 KMF_RETURN kmfrv; 179 KMF_KEY_HANDLE pubk, prik; 180 KMF_X509_NAME csrSubject; 181 KMF_CSR_DATA csr; 182 KMF_DATA signedCsr = {NULL, 0}; 183 char *fullcsrpath = NULL; 184 char *fullkeypath = NULL; 185 186 187 (void) memset(&csr, 0, sizeof (csr)); 188 (void) memset(&csrSubject, 0, sizeof (csrSubject)); 189 190 if (EMPTYSTRING(outcsr) || EMPTYSTRING(outkey)) { 191 cryptoerror(LOG_STDERR, 192 gettext("No output file was specified for " 193 "the csr or key\n")); 194 return (KMF_ERR_BAD_PARAMETER); 195 } 196 fullcsrpath = strdup(outcsr); 197 if (verify_file(fullcsrpath)) { 198 cryptoerror(LOG_STDERR, 199 gettext("Cannot write the indicated output " 200 "certificate file (%s).\n"), fullcsrpath); 201 free(fullcsrpath); 202 return (PK_ERR_USAGE); 203 } 204 205 /* If the subject name cannot be parsed, flag it now and exit */ 206 if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) { 207 return (kmfrv); 208 } 209 /* 210 * Share the "genkeypair" routine for creating the keypair. 211 */ 212 kmfrv = genkeypair_file(kmfhandle, keyAlg, keylen, 213 fmt, outkey, &prik, &pubk); 214 if (kmfrv != KMF_OK) 215 return (kmfrv); 216 217 SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), 218 "SetCSRPubKey"); 219 220 SET_VALUE(kmf_set_csr_version(&csr, 2), "SetCSRVersion"); 221 222 SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), 223 "kmf_set_csr_subject"); 224 225 SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg"); 226 227 if (altname != NULL) { 228 SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit, 229 alttype), "kmf_set_csr_subject_altname"); 230 } 231 if (kubits != NULL) { 232 SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits), 233 "kmf_set_csr_ku"); 234 } 235 if (ekulist != NULL) { 236 int i; 237 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 238 SET_VALUE(kmf_add_csr_eku(&csr, 239 &ekulist->ekulist[i], 240 ekulist->critlist[i]), 241 "Extended Key Usage"); 242 } 243 } 244 if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) == 245 KMF_OK) { 246 kmfrv = kmf_create_csr_file(&signedCsr, fmt, fullcsrpath); 247 } 248 249 cleanup: 250 if (fullkeypath) 251 free(fullkeypath); 252 if (fullcsrpath) 253 free(fullcsrpath); 254 255 kmf_free_data(&signedCsr); 256 kmf_free_kmf_key(kmfhandle, &prik); 257 kmf_free_signed_csr(&csr); 258 259 return (kmfrv); 260 } 261 262 static KMF_RETURN 263 gencsr_nss(KMF_HANDLE_T kmfhandle, 264 char *token, char *subject, char *altname, 265 KMF_GENERALNAMECHOICES alttype, int altcrit, 266 char *nickname, char *dir, char *prefix, 267 KMF_KEY_ALG keyAlg, int keylen, 268 uint16_t kubits, int kucrit, 269 KMF_ENCODE_FORMAT fmt, char *csrfile, 270 KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist, 271 KMF_ALGORITHM_INDEX sigAlg, KMF_OID *curveoid) 272 { 273 KMF_RETURN kmfrv; 274 KMF_KEY_HANDLE pubk, prik; 275 KMF_X509_NAME csrSubject; 276 KMF_CSR_DATA csr; 277 KMF_DATA signedCsr = {NULL, 0}; 278 279 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 280 int numattr = 0; 281 KMF_ATTRIBUTE attrlist[16]; 282 283 if (token == NULL) 284 token = DEFAULT_NSS_TOKEN; 285 286 kmfrv = configure_nss(kmfhandle, dir, prefix); 287 if (kmfrv != KMF_OK) 288 return (kmfrv); 289 290 (void) memset(&csr, 0, sizeof (csr)); 291 (void) memset(&csrSubject, 0, sizeof (csrSubject)); 292 (void) memset(&pubk, 0, sizeof (pubk)); 293 (void) memset(&prik, 0, sizeof (prik)); 294 295 /* If the subject name cannot be parsed, flag it now and exit */ 296 if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) { 297 return (kmfrv); 298 } 299 300 kmfrv = genkeypair_nss(kmfhandle, token, nickname, dir, 301 prefix, keyAlg, keylen, tokencred, curveoid, 302 &prik, &pubk); 303 if (kmfrv != KMF_OK) 304 return (kmfrv); 305 306 SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), 307 "kmf_set_csr_pubkey"); 308 SET_VALUE(kmf_set_csr_version(&csr, 2), "kmf_set_csr_version"); 309 SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), 310 "kmf_set_csr_subject"); 311 SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg"); 312 313 if (altname != NULL) { 314 SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit, 315 alttype), "kmf_set_csr_subject_altname"); 316 } 317 if (kubits != NULL) { 318 SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits), 319 "kmf_set_csr_ku"); 320 } 321 if (ekulist != NULL) { 322 int i; 323 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 324 SET_VALUE(kmf_add_csr_eku(&csr, 325 &ekulist->ekulist[i], 326 ekulist->critlist[i]), 327 "Extended Key Usage"); 328 } 329 } 330 if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) == 331 KMF_OK) { 332 kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile); 333 } 334 335 cleanup: 336 (void) kmf_free_data(&signedCsr); 337 (void) kmf_free_kmf_key(kmfhandle, &prik); 338 339 /* delete the key */ 340 numattr = 0; 341 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 342 &kstype, sizeof (kstype)); 343 numattr++; 344 345 kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, 346 &pubk, sizeof (KMF_KEY_HANDLE)); 347 numattr++; 348 349 if (tokencred != NULL && tokencred->credlen > 0) { 350 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 351 tokencred, sizeof (KMF_CREDENTIAL)); 352 numattr++; 353 } 354 355 if (token && strlen(token)) { 356 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 357 token, strlen(token)); 358 numattr++; 359 } 360 361 (void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist); 362 363 (void) kmf_free_signed_csr(&csr); 364 365 return (kmfrv); 366 } 367 368 int 369 pk_gencsr(int argc, char *argv[]) 370 { 371 KMF_RETURN rv; 372 int opt; 373 extern int optind_av; 374 extern char *optarg_av; 375 KMF_KEYSTORE_TYPE kstype = 0; 376 char *subject = NULL; 377 char *tokenname = NULL; 378 char *dir = NULL; 379 char *prefix = NULL; 380 int keylen = PK_DEFAULT_KEYLENGTH; 381 char *certlabel = NULL; 382 char *outcsr = NULL; 383 char *outkey = NULL; 384 char *format = NULL; 385 char *altname = NULL; 386 char *kustr = NULL; 387 char *ekustr = NULL; 388 char *hashname = NULL; 389 uint16_t kubits = 0; 390 char *keytype = PK_DEFAULT_KEYTYPE; 391 KMF_HANDLE_T kmfhandle = NULL; 392 KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1; 393 KMF_KEY_ALG keyAlg = KMF_RSA; 394 KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_SHA1WithRSA; 395 boolean_t interactive = B_FALSE; 396 char *subname = NULL; 397 KMF_CREDENTIAL tokencred = {NULL, 0}; 398 KMF_GENERALNAMECHOICES alttype = 0; 399 int altcrit = 0, kucrit = 0; 400 EKU_LIST *ekulist = NULL; 401 KMF_OID *curveoid = NULL; /* ECC */ 402 KMF_OID *hashoid = NULL; 403 int y_flag = 0; 404 405 while ((opt = getopt_av(argc, argv, 406 "ik:(keystore)s:(subject)n:(nickname)A:(altname)" 407 "u:(keyusage)T:(token)d:(dir)p:(prefix)t:(keytype)" 408 "y:(keylen)l:(label)c:(outcsr)e:(eku)C:(curve)" 409 "K:(outkey)F:(format)E(listcurves)h:(hash)")) != EOF) { 410 411 switch (opt) { 412 case 'A': 413 altname = optarg_av; 414 break; 415 case 'i': 416 if (interactive) 417 return (PK_ERR_USAGE); 418 else if (subject) { 419 cryptoerror(LOG_STDERR, 420 gettext("Interactive (-i) and " 421 "subject options are mutually " 422 "exclusive.\n")); 423 return (PK_ERR_USAGE); 424 } else 425 interactive = B_TRUE; 426 break; 427 case 'k': 428 kstype = KS2Int(optarg_av); 429 if (kstype == 0) 430 return (PK_ERR_USAGE); 431 break; 432 case 's': 433 if (subject) 434 return (PK_ERR_USAGE); 435 else if (interactive) { 436 cryptoerror(LOG_STDERR, 437 gettext("Interactive (-i) and " 438 "subject options are mutually " 439 "exclusive.\n")); 440 return (PK_ERR_USAGE); 441 } else 442 subject = optarg_av; 443 break; 444 case 'l': 445 case 'n': 446 if (certlabel) 447 return (PK_ERR_USAGE); 448 certlabel = optarg_av; 449 break; 450 case 'T': 451 if (tokenname) 452 return (PK_ERR_USAGE); 453 tokenname = optarg_av; 454 break; 455 case 'd': 456 dir = optarg_av; 457 break; 458 case 'p': 459 if (prefix) 460 return (PK_ERR_USAGE); 461 prefix = optarg_av; 462 break; 463 case 't': 464 keytype = optarg_av; 465 break; 466 case 'u': 467 kustr = optarg_av; 468 break; 469 case 'y': 470 if (sscanf(optarg_av, "%d", 471 &keylen) != 1) { 472 cryptoerror(LOG_STDERR, 473 gettext("Unrecognized " 474 "key length (%s)\n"), optarg_av); 475 return (PK_ERR_USAGE); 476 } 477 y_flag++; 478 break; 479 case 'c': 480 if (outcsr) 481 return (PK_ERR_USAGE); 482 outcsr = optarg_av; 483 break; 484 case 'K': 485 if (outkey) 486 return (PK_ERR_USAGE); 487 outkey = optarg_av; 488 break; 489 case 'F': 490 if (format) 491 return (PK_ERR_USAGE); 492 format = optarg_av; 493 break; 494 case 'e': 495 ekustr = optarg_av; 496 break; 497 case 'C': 498 curveoid = ecc_name_to_oid(optarg_av); 499 if (curveoid == NULL) { 500 cryptoerror(LOG_STDERR, 501 gettext("Unrecognized ECC " 502 "curve.\n")); 503 return (PK_ERR_USAGE); 504 } 505 break; 506 case 'E': 507 /* 508 * This argument is only to be used 509 * by itself, no other options should 510 * be present. 511 */ 512 if (argc != 2) { 513 cryptoerror(LOG_STDERR, 514 gettext("listcurves has no other " 515 "options.\n")); 516 return (PK_ERR_USAGE); 517 } 518 show_ecc_curves(); 519 return (0); 520 case 'h': 521 hashname = optarg_av; 522 hashoid = ecc_name_to_oid(optarg_av); 523 if (hashoid == NULL) { 524 cryptoerror(LOG_STDERR, 525 gettext("Unrecognized hash.\n")); 526 return (PK_ERR_USAGE); 527 } 528 break; 529 default: 530 cryptoerror(LOG_STDERR, gettext( 531 "unrecognized gencsr option '%s'\n"), 532 argv[optind_av]); 533 return (PK_ERR_USAGE); 534 } 535 } 536 /* No additional args allowed. */ 537 argc -= optind_av; 538 argv += optind_av; 539 if (argc) { 540 return (PK_ERR_USAGE); 541 } 542 543 /* Assume keystore = PKCS#11 if not specified. */ 544 if (kstype == 0) 545 kstype = KMF_KEYSTORE_PK11TOKEN; 546 547 DIR_OPTION_CHECK(kstype, dir); 548 549 if (EMPTYSTRING(outcsr) && interactive) { 550 (void) get_filename("CSR", &outcsr); 551 } 552 if (EMPTYSTRING(outcsr)) { 553 (void) printf(gettext("A filename must be specified to hold" 554 "the final certificate request data.\n")); 555 return (PK_ERR_USAGE); 556 } 557 /* 558 * verify that the outcsr file does not already exist 559 * and that it can be created. 560 */ 561 rv = verify_file(outcsr); 562 if (rv != KMF_OK) { 563 cryptoerror(LOG_STDERR, gettext("output file (%s) " 564 "cannot be created.\n"), outcsr); 565 return (PK_ERR_USAGE); 566 } 567 568 if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) { 569 if (EMPTYSTRING(certlabel) && interactive) 570 (void) get_certlabel(&certlabel); 571 572 if (EMPTYSTRING(certlabel)) { 573 cryptoerror(LOG_STDERR, gettext("A label must be " 574 "specified to create a certificate request.\n")); 575 return (PK_ERR_USAGE); 576 } 577 } else if (kstype == KMF_KEYSTORE_OPENSSL) { 578 if (EMPTYSTRING(outkey) && interactive) 579 (void) get_filename("private key", &outkey); 580 581 if (EMPTYSTRING(outkey)) { 582 cryptoerror(LOG_STDERR, gettext("A key filename " 583 "must be specified to create a certificate " 584 "request.\n")); 585 return (PK_ERR_USAGE); 586 } 587 } 588 589 if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) { 590 cryptoerror(LOG_STDERR, 591 gettext("Error parsing format string (%s).\n"), format); 592 return (PK_ERR_USAGE); 593 } 594 if (format && fmt != KMF_FORMAT_ASN1 && fmt != KMF_FORMAT_PEM) { 595 cryptoerror(LOG_STDERR, 596 gettext("CSR must be DER or PEM format.\n")); 597 return (PK_ERR_USAGE); 598 } 599 600 /* 601 * Check the subject name. 602 * If interactive is true, get it now interactively. 603 */ 604 if (interactive) { 605 if (get_subname(&subname) != KMF_OK) { 606 cryptoerror(LOG_STDERR, gettext("Failed to get the " 607 "subject name interactively.\n")); 608 return (PK_ERR_USAGE); 609 } 610 } else { 611 if (EMPTYSTRING(subject)) { 612 cryptoerror(LOG_STDERR, gettext("A subject name or " 613 "-i must be specified to create a certificate " 614 "request.\n")); 615 return (PK_ERR_USAGE); 616 } else { 617 subname = strdup(subject); 618 if (subname == NULL) { 619 cryptoerror(LOG_STDERR, 620 gettext("Out of memory.\n")); 621 return (PK_ERR_SYSTEM); 622 } 623 } 624 } 625 if (altname != NULL) { 626 rv = verify_altname(altname, &alttype, &altcrit); 627 if (rv != KMF_OK) { 628 cryptoerror(LOG_STDERR, gettext("Subject AltName " 629 "must be specified as a name=value pair. " 630 "See the man page for details.")); 631 goto end; 632 } else { 633 /* advance the altname past the '=' sign */ 634 char *p = strchr(altname, '='); 635 if (p != NULL) 636 altname = p + 1; 637 } 638 } 639 640 if (kustr != NULL) { 641 rv = verify_keyusage(kustr, &kubits, &kucrit); 642 if (rv != KMF_OK) { 643 cryptoerror(LOG_STDERR, gettext("KeyUsage " 644 "must be specified as a comma-separated list. " 645 "See the man page for details.")); 646 goto end; 647 } 648 } 649 if (ekustr != NULL) { 650 rv = verify_ekunames(ekustr, &ekulist); 651 if (rv != KMF_OK) { 652 (void) fprintf(stderr, gettext("EKUs must " 653 "be specified as a comma-separated list. " 654 "See the man page for details.\n")); 655 rv = PK_ERR_USAGE; 656 goto end; 657 } 658 } 659 if ((rv = Str2KeyType(keytype, hashoid, &keyAlg, &sigAlg)) != 0) { 660 cryptoerror(LOG_STDERR, 661 gettext("Unsupported key/hash combination (%s/%s).\n"), 662 keytype, (hashname ? hashname : "none")); 663 goto end; 664 } 665 if (curveoid != NULL && keyAlg != KMF_ECDSA) { 666 cryptoerror(LOG_STDERR, gettext("EC curves are only " 667 "valid for EC keytypes.\n")); 668 return (PK_ERR_USAGE); 669 } 670 if (keyAlg == KMF_ECDSA && curveoid == NULL) { 671 cryptoerror(LOG_STDERR, gettext("A curve must be " 672 "specifed when using EC keys.\n")); 673 return (PK_ERR_USAGE); 674 } 675 if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) { 676 (void) fprintf(stderr, gettext("ECC certificates are" 677 "only supported with the pkcs11 and nss keystores\n")); 678 rv = PK_ERR_USAGE; 679 goto end; 680 } 681 682 /* Adjust default keylength for NSS and DSA */ 683 if (keyAlg == KMF_DSA && !y_flag && kstype == KMF_KEYSTORE_NSS) 684 keylen = 1024; 685 686 if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { 687 if (tokenname == NULL || !strlen(tokenname)) { 688 if (kstype == KMF_KEYSTORE_NSS) { 689 tokenname = "internal"; 690 } else { 691 tokenname = PK_DEFAULT_PK11TOKEN; 692 } 693 } 694 695 (void) get_token_password(kstype, tokenname, &tokencred); 696 } 697 698 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 699 cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n")); 700 return (PK_ERR_USAGE); 701 } 702 703 704 if (kstype == KMF_KEYSTORE_NSS) { 705 if (dir == NULL) 706 dir = PK_DEFAULT_DIRECTORY; 707 708 rv = gencsr_nss(kmfhandle, 709 tokenname, subname, altname, alttype, altcrit, 710 certlabel, dir, prefix, 711 keyAlg, keylen, kubits, kucrit, 712 fmt, outcsr, &tokencred, ekulist, 713 sigAlg, curveoid); 714 715 } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { 716 rv = gencsr_pkcs11(kmfhandle, 717 tokenname, subname, altname, alttype, altcrit, 718 certlabel, keyAlg, keylen, 719 kubits, kucrit, fmt, outcsr, &tokencred, 720 ekulist, sigAlg, curveoid); 721 722 } else if (kstype == KMF_KEYSTORE_OPENSSL) { 723 rv = gencsr_file(kmfhandle, 724 keyAlg, keylen, fmt, subname, altname, 725 alttype, altcrit, kubits, kucrit, 726 outcsr, outkey, ekulist, sigAlg); 727 } 728 729 end: 730 if (rv != KMF_OK) { 731 display_error(kmfhandle, rv, 732 gettext("Error creating CSR or keypair")); 733 734 if (rv == KMF_ERR_RDN_PARSER) { 735 cryptoerror(LOG_STDERR, gettext("subject or " 736 "issuer name must be in proper DN format.\n")); 737 } 738 } 739 740 if (ekulist != NULL) 741 free_eku_list(ekulist); 742 743 if (subname) 744 free(subname); 745 746 if (tokencred.cred != NULL) 747 free(tokencred.cred); 748 749 (void) kmf_finalize(kmfhandle); 750 if (rv != KMF_OK) 751 return (PK_ERR_USAGE); 752 753 return (0); 754 } 755