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 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 22 */ 23 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" 33 34 #include <kmfapi.h> 35 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; \ 43 } 44 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) 54 { 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 }; 60 61 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 62 int numattr = 0; 63 KMF_ATTRIBUTE attrlist[16]; 64 65 (void) memset(&csr, 0, sizeof (csr)); 66 (void) memset(&csrSubject, 0, sizeof (csrSubject)); 67 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); 71 72 /* Select a PKCS11 token */ 73 kmfrv = select_token(kmfhandle, token, FALSE); 74 if (kmfrv != KMF_OK) 75 return (kmfrv); 76 /* 77 * Share the "genkeypair" routine for creating the keypair. 78 */ 79 kmfrv = genkeypair_pkcs11(kmfhandle, token, certlabel, 80 keyAlg, keylen, tokencred, curveoid, &prik, &pubk); 81 if (kmfrv != KMF_OK) 82 return (kmfrv); 83 84 SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), "keypair"); 85 86 SET_VALUE(kmf_set_csr_version(&csr, 2), "version number"); 87 88 SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), "subject name"); 89 90 SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), 91 "SignatureAlgorithm"); 92 93 if (altname != NULL) { 94 SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit, 95 alttype), "SetCSRSubjectAltName"); 96 } 97 98 if (kubits != 0) { 99 SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits), 100 "SetCSRKeyUsage"); 101 } 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"); 109 } 110 } 111 if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) == 112 KMF_OK) { 113 kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile); 114 } 115 116 cleanup: 117 (void) kmf_free_data(&signedCsr); 118 (void) kmf_free_signed_csr(&csr); 119 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++; 125 126 kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, 127 &pubk, sizeof (KMF_KEY_HANDLE)); 128 numattr++; 129 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++; 134 } 135 136 (void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist); 137 138 /* 139 * If there is an error, then we need to remove the private key 140 * from the token. 141 */ 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++; 147 148 kmf_set_attr_at_index(attrlist, numattr, 149 KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE)); 150 numattr++; 151 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++; 157 } 158 159 (void) kmf_delete_key_from_keystore(kmfhandle, numattr, 160 attrlist); 161 } 162 163 (void) kmf_free_kmf_key(kmfhandle, &prik); 164 return (kmfrv); 165 } 166 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) 175 { 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; 183 184 185 (void) memset(&csr, 0, sizeof (csr)); 186 (void) memset(&csrSubject, 0, sizeof (csrSubject)); 187 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); 193 } 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); 201 } 202 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); 206 } 207 /* 208 * Share the "genkeypair" routine for creating the keypair. 209 */ 210 kmfrv = genkeypair_file(kmfhandle, keyAlg, keylen, 211 fmt, outkey, &prik, &pubk); 212 if (kmfrv != KMF_OK) 213 return (kmfrv); 214 215 SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), 216 "SetCSRPubKey"); 217 218 SET_VALUE(kmf_set_csr_version(&csr, 2), "SetCSRVersion"); 219 220 SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), 221 "kmf_set_csr_subject"); 222 223 SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg"); 224 225 if (altname != NULL) { 226 SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit, 227 alttype), "kmf_set_csr_subject_altname"); 228 } 229 if (kubits != 0) { 230 SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits), 231 "kmf_set_csr_ku"); 232 } 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"); 240 } 241 } 242 if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) == 243 KMF_OK) { 244 kmfrv = kmf_create_csr_file(&signedCsr, fmt, fullcsrpath); 245 } 246 247 cleanup: 248 if (fullkeypath) 249 free(fullkeypath); 250 if (fullcsrpath) 251 free(fullcsrpath); 252 253 kmf_free_data(&signedCsr); 254 kmf_free_kmf_key(kmfhandle, &prik); 255 kmf_free_signed_csr(&csr); 256 257 return (kmfrv); 258 } 259 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) 270 { 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 }; 276 277 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 278 int numattr = 0; 279 KMF_ATTRIBUTE attrlist[16]; 280 281 if (token == NULL) 282 token = DEFAULT_NSS_TOKEN; 283 284 kmfrv = configure_nss(kmfhandle, dir, prefix); 285 if (kmfrv != KMF_OK) 286 return (kmfrv); 287 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)); 292 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); 296 } 297 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); 303 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"); 310 311 if (altname != NULL) { 312 SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit, 313 alttype), "kmf_set_csr_subject_altname"); 314 } 315 if (kubits != 0) { 316 SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits), 317 "kmf_set_csr_ku"); 318 } 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"); 326 } 327 } 328 if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) == 329 KMF_OK) { 330 kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile); 331 } 332 333 cleanup: 334 (void) kmf_free_data(&signedCsr); 335 (void) kmf_free_kmf_key(kmfhandle, &prik); 336 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++; 342 343 kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, 344 &pubk, sizeof (KMF_KEY_HANDLE)); 345 numattr++; 346 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++; 351 } 352 353 if (token && strlen(token)) { 354 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 355 token, strlen(token)); 356 numattr++; 357 } 358 359 (void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist); 360 361 (void) kmf_free_signed_csr(&csr); 362 363 return (kmfrv); 364 } 365 366 int 367 pk_gencsr(int argc, char *argv[]) 368 { 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; 402 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) { 408 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); 474 } 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); 502 } 503 break; 504 case 'E': 505 /* 506 * This argument is only to be used 507 * by itself, no other options should 508 * be present. 509 */ 510 if (argc != 2) { 511 cryptoerror(LOG_STDERR, 512 gettext("listcurves has no other " 513 "options.\n")); 514 return (PK_ERR_USAGE); 515 } 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); 525 } 526 break; 527 default: 528 cryptoerror(LOG_STDERR, gettext( 529 "unrecognized gencsr option '%s'\n"), 530 argv[optind_av]); 531 return (PK_ERR_USAGE); 532 } 533 } 534 /* No additional args allowed. */ 535 argc -= optind_av; 536 argv += optind_av; 537 if (argc) { 538 return (PK_ERR_USAGE); 539 } 540 541 /* Assume keystore = PKCS#11 if not specified. */ 542 if (kstype == 0) 543 kstype = KMF_KEYSTORE_PK11TOKEN; 544 545 DIR_OPTION_CHECK(kstype, dir); 546 547 if (EMPTYSTRING(outcsr) && interactive) { 548 (void) get_filename("CSR", &outcsr); 549 } 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); 554 } 555 /* 556 * verify that the outcsr file does not already exist 557 * and that it can be created. 558 */ 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); 570 } 571 } else if (rv != KMF_OK) { 572 cryptoerror(LOG_STDERR, 573 gettext("Warning: error accessing \"%s\""), outcsr); 574 return (rv); 575 } 576 577 if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) { 578 if (EMPTYSTRING(certlabel) && interactive) 579 (void) get_certlabel(&certlabel); 580 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); 585 } 586 } else if (kstype == KMF_KEYSTORE_OPENSSL) { 587 if (EMPTYSTRING(outkey) && interactive) 588 (void) get_filename("private key", &outkey); 589 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); 595 } 596 } 597 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); 602 } 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); 607 } 608 609 /* 610 * Check the subject name. 611 * If interactive is true, get it now interactively. 612 */ 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); 618 } 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); 631 } 632 } 633 } 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; 646 } 647 } 648 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; 656 } 657 } 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; 666 } 667 } 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; 673 } 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); 678 } 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); 683 } 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; 689 } 690 691 /* Adjust default keylength for NSS and DSA */ 692 if (keyAlg == KMF_DSA && !y_flag && kstype == KMF_KEYSTORE_NSS) 693 keylen = 1024; 694 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; 701 } 702 } 703 704 (void) get_token_password(kstype, tokenname, &tokencred); 705 } 706 707 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 708 cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n")); 709 return (PK_ERR_USAGE); 710 } 711 712 713 if (kstype == KMF_KEYSTORE_NSS) { 714 if (dir == NULL) 715 dir = PK_DEFAULT_DIRECTORY; 716 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); 723 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); 730 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); 736 } 737 738 end: 739 if (rv != KMF_OK) { 740 display_error(kmfhandle, rv, 741 gettext("Error creating CSR or keypair")); 742 743 if (rv == KMF_ERR_RDN_PARSER) { 744 cryptoerror(LOG_STDERR, gettext("subject or " 745 "issuer name must be in proper DN format.\n")); 746 } 747 } 748 749 if (ekulist != NULL) 750 free_eku_list(ekulist); 751 752 if (subname) 753 free(subname); 754 755 if (tokencred.cred != NULL) 756 free(tokencred.cred); 757 758 (void) kmf_finalize(kmfhandle); 759 if (rv != KMF_OK) 760 return (PK_ERR_USAGE); 761 762 return (0); 763 } 764