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 2009 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 { 56 KMF_RETURN kmfrv = KMF_OK; 57 KMF_KEY_HANDLE pubk, prik; 58 KMF_X509_NAME csrSubject; 59 KMF_CSR_DATA csr; 60 KMF_ALGORITHM_INDEX sigAlg; 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 boolean_t storekey = TRUE; 67 68 (void) memset(&csr, 0, sizeof (csr)); 69 (void) memset(&csrSubject, 0, sizeof (csrSubject)); 70 71 if (keyAlg == KMF_DSA) 72 sigAlg = KMF_ALGID_SHA1WithDSA; 73 else 74 sigAlg = KMF_ALGID_MD5WithRSA; 75 76 77 /* If the subject name cannot be parsed, flag it now and exit */ 78 if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) { 79 return (kmfrv); 80 } 81 82 /* Select a PKCS11 token */ 83 kmfrv = select_token(kmfhandle, token, FALSE); 84 if (kmfrv != KMF_OK) { 85 return (kmfrv); 86 } 87 88 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 89 &kstype, sizeof (kstype)); 90 numattr++; 91 92 if (certlabel != NULL && strlen(certlabel)) { 93 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, 94 certlabel, strlen(certlabel)); 95 numattr++; 96 } 97 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR, 98 &keylen, sizeof (keylen)); 99 numattr++; 100 101 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR, 102 &keyAlg, sizeof (keyAlg)); 103 numattr++; 104 105 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 106 tokencred, sizeof (KMF_CREDENTIAL)); 107 numattr++; 108 109 if (token && strlen(token)) { 110 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 111 token, strlen(token)); 112 numattr++; 113 } 114 kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, 115 &pubk, sizeof (KMF_KEY_HANDLE)); 116 numattr++; 117 118 kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR, 119 &prik, sizeof (KMF_KEY_HANDLE)); 120 numattr++; 121 122 kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR, 123 &storekey, sizeof (storekey)); 124 numattr++; 125 126 kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 127 if (kmfrv != KMF_OK) { 128 return (kmfrv); 129 } 130 131 SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), "keypair"); 132 133 SET_VALUE(kmf_set_csr_version(&csr, 2), "version number"); 134 135 SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), "subject name"); 136 137 SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), 138 "SignatureAlgorithm"); 139 140 if (altname != NULL) { 141 SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit, 142 alttype), "SetCSRSubjectAltName"); 143 } 144 145 if (kubits != 0) { 146 SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits), 147 "SetCSRKeyUsage"); 148 } 149 if (ekulist != NULL) { 150 int i; 151 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 152 SET_VALUE(kmf_add_csr_eku(&csr, 153 &ekulist->ekulist[i], 154 ekulist->critlist[i]), 155 "Extended Key Usage"); 156 } 157 } 158 if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) == 159 KMF_OK) { 160 kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile); 161 } 162 163 cleanup: 164 (void) kmf_free_data(&signedCsr); 165 (void) kmf_free_signed_csr(&csr); 166 167 /* delete the public key */ 168 numattr = 0; 169 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 170 &kstype, sizeof (kstype)); 171 numattr++; 172 173 kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, 174 &pubk, sizeof (KMF_KEY_HANDLE)); 175 numattr++; 176 177 if (tokencred != NULL && tokencred->cred != NULL) { 178 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 179 tokencred, sizeof (KMF_CREDENTIAL)); 180 numattr++; 181 } 182 183 (void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist); 184 185 /* 186 * If there is an error, then we need to remove the private key 187 * from the token. 188 */ 189 if (kmfrv != KMF_OK) { 190 numattr = 0; 191 kmf_set_attr_at_index(attrlist, numattr, 192 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 193 numattr++; 194 195 kmf_set_attr_at_index(attrlist, numattr, 196 KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE)); 197 numattr++; 198 199 if (tokencred != NULL && tokencred->cred != NULL) { 200 kmf_set_attr_at_index(attrlist, numattr, 201 KMF_CREDENTIAL_ATTR, tokencred, 202 sizeof (KMF_CREDENTIAL)); 203 numattr++; 204 } 205 206 (void) kmf_delete_key_from_keystore(kmfhandle, numattr, 207 attrlist); 208 } 209 210 (void) kmf_free_kmf_key(kmfhandle, &prik); 211 return (kmfrv); 212 } 213 214 static KMF_RETURN 215 gencsr_file(KMF_HANDLE_T kmfhandle, 216 KMF_KEY_ALG keyAlg, 217 int keylen, KMF_ENCODE_FORMAT fmt, 218 char *subject, char *altname, KMF_GENERALNAMECHOICES alttype, 219 int altcrit, uint16_t kubits, int kucrit, 220 char *outcsr, char *outkey, EKU_LIST *ekulist) 221 { 222 KMF_RETURN kmfrv; 223 KMF_KEY_HANDLE pubk, prik; 224 KMF_X509_NAME csrSubject; 225 KMF_CSR_DATA csr; 226 KMF_ALGORITHM_INDEX sigAlg; 227 KMF_DATA signedCsr = {NULL, 0}; 228 char *fullcsrpath = NULL; 229 char *fullkeypath = NULL; 230 231 int numattr = 0; 232 KMF_ATTRIBUTE attrlist[16]; 233 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 234 boolean_t storekey = TRUE; 235 236 (void) memset(&csr, 0, sizeof (csr)); 237 (void) memset(&csrSubject, 0, sizeof (csrSubject)); 238 239 if (EMPTYSTRING(outcsr) || EMPTYSTRING(outkey)) { 240 cryptoerror(LOG_STDERR, 241 gettext("No output file was specified for " 242 "the csr or key\n")); 243 return (KMF_ERR_BAD_PARAMETER); 244 } 245 fullcsrpath = strdup(outcsr); 246 if (verify_file(fullcsrpath)) { 247 cryptoerror(LOG_STDERR, 248 gettext("Cannot write the indicated output " 249 "certificate file (%s).\n"), fullcsrpath); 250 free(fullcsrpath); 251 return (PK_ERR_USAGE); 252 } 253 254 fullkeypath = strdup(outkey); 255 if (verify_file(fullcsrpath)) { 256 cryptoerror(LOG_STDERR, 257 gettext("Cannot write the indicated output " 258 "key file (%s).\n"), fullkeypath); 259 free(fullcsrpath); 260 return (PK_ERR_USAGE); 261 } 262 263 if (keyAlg == KMF_DSA) 264 sigAlg = KMF_ALGID_SHA1WithDSA; 265 else 266 sigAlg = KMF_ALGID_MD5WithRSA; 267 268 /* If the subject name cannot be parsed, flag it now and exit */ 269 if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) { 270 return (kmfrv); 271 } 272 273 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 274 &kstype, sizeof (kstype)); 275 numattr++; 276 277 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, 278 fullkeypath, strlen(fullkeypath)); 279 numattr++; 280 281 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR, 282 &keylen, sizeof (keylen)); 283 numattr++; 284 285 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR, 286 &keyAlg, sizeof (keyAlg)); 287 numattr++; 288 289 kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 290 &fmt, sizeof (fmt)); 291 numattr++; 292 293 (void) memset(&prik, 0, sizeof (prik)); 294 kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR, 295 &prik, sizeof (KMF_KEY_HANDLE)); 296 numattr++; 297 298 (void) memset(&pubk, 0, sizeof (pubk)); 299 kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, 300 &pubk, sizeof (KMF_KEY_HANDLE)); 301 numattr++; 302 303 kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR, 304 &storekey, sizeof (storekey)); 305 numattr++; 306 307 kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 308 if (kmfrv != KMF_OK) { 309 goto cleanup; 310 } 311 SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), 312 "SetCSRPubKey"); 313 314 SET_VALUE(kmf_set_csr_version(&csr, 2), "SetCSRVersion"); 315 316 SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), 317 "kmf_set_csr_subject"); 318 319 SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg"); 320 321 if (altname != NULL) { 322 SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit, 323 alttype), "kmf_set_csr_subject_altname"); 324 } 325 if (kubits != NULL) { 326 SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits), 327 "kmf_set_csr_ku"); 328 } 329 if (ekulist != NULL) { 330 int i; 331 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 332 SET_VALUE(kmf_add_csr_eku(&csr, 333 &ekulist->ekulist[i], 334 ekulist->critlist[i]), 335 "Extended Key Usage"); 336 } 337 } 338 if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) == 339 KMF_OK) { 340 kmfrv = kmf_create_csr_file(&signedCsr, fmt, fullcsrpath); 341 } 342 343 cleanup: 344 if (fullkeypath) 345 free(fullkeypath); 346 if (fullcsrpath) 347 free(fullcsrpath); 348 349 kmf_free_data(&signedCsr); 350 kmf_free_kmf_key(kmfhandle, &prik); 351 kmf_free_signed_csr(&csr); 352 353 return (kmfrv); 354 } 355 356 static KMF_RETURN 357 gencsr_nss(KMF_HANDLE_T kmfhandle, 358 char *token, char *subject, char *altname, 359 KMF_GENERALNAMECHOICES alttype, int altcrit, 360 char *nickname, char *dir, char *prefix, 361 KMF_KEY_ALG keyAlg, int keylen, 362 uint16_t kubits, int kucrit, 363 KMF_ENCODE_FORMAT fmt, char *csrfile, 364 KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist) 365 { 366 KMF_RETURN kmfrv; 367 KMF_KEY_HANDLE pubk, prik; 368 KMF_X509_NAME csrSubject; 369 KMF_CSR_DATA csr; 370 KMF_ALGORITHM_INDEX sigAlg; 371 KMF_DATA signedCsr = {NULL, 0}; 372 373 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 374 int numattr = 0; 375 KMF_ATTRIBUTE attrlist[16]; 376 boolean_t storekey = TRUE; 377 378 if (token == NULL) 379 token = DEFAULT_NSS_TOKEN; 380 381 if (keyAlg == KMF_DSA) 382 sigAlg = KMF_ALGID_SHA1WithDSA; 383 else 384 sigAlg = KMF_ALGID_MD5WithRSA; 385 386 kmfrv = configure_nss(kmfhandle, dir, prefix); 387 if (kmfrv != KMF_OK) 388 return (kmfrv); 389 390 (void) memset(&csr, 0, sizeof (csr)); 391 (void) memset(&csrSubject, 0, sizeof (csrSubject)); 392 (void) memset(&pubk, 0, sizeof (pubk)); 393 (void) memset(&prik, 0, sizeof (prik)); 394 395 /* If the subject name cannot be parsed, flag it now and exit */ 396 if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) { 397 return (kmfrv); 398 } 399 400 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 401 &kstype, sizeof (kstype)); 402 numattr++; 403 404 if (nickname != NULL && strlen(nickname)) { 405 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, 406 nickname, strlen(nickname)); 407 numattr++; 408 } 409 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR, 410 &keylen, sizeof (keylen)); 411 numattr++; 412 413 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR, 414 &keyAlg, sizeof (keyAlg)); 415 numattr++; 416 417 if (tokencred != NULL && tokencred->credlen > 0) { 418 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 419 tokencred, sizeof (KMF_CREDENTIAL)); 420 numattr++; 421 } 422 423 if (token && strlen(token)) { 424 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 425 token, strlen(token)); 426 numattr++; 427 } 428 kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, 429 &pubk, sizeof (KMF_KEY_HANDLE)); 430 numattr++; 431 432 kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR, 433 &prik, sizeof (KMF_KEY_HANDLE)); 434 numattr++; 435 436 kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR, 437 &storekey, sizeof (storekey)); 438 numattr++; 439 440 kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 441 if (kmfrv != KMF_OK) { 442 goto cleanup; 443 } 444 445 SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), 446 "kmf_set_csr_pubkey"); 447 SET_VALUE(kmf_set_csr_version(&csr, 2), "kmf_set_csr_version"); 448 SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), 449 "kmf_set_csr_subject"); 450 SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg"); 451 452 if (altname != NULL) { 453 SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit, 454 alttype), "kmf_set_csr_subject_altname"); 455 } 456 if (kubits != NULL) { 457 SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits), 458 "kmf_set_csr_ku"); 459 } 460 if (ekulist != NULL) { 461 int i; 462 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 463 SET_VALUE(kmf_add_csr_eku(&csr, 464 &ekulist->ekulist[i], 465 ekulist->critlist[i]), 466 "Extended Key Usage"); 467 } 468 } 469 if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) == 470 KMF_OK) { 471 kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile); 472 } 473 474 cleanup: 475 (void) kmf_free_data(&signedCsr); 476 (void) kmf_free_kmf_key(kmfhandle, &prik); 477 478 /* delete the key */ 479 numattr = 0; 480 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 481 &kstype, sizeof (kstype)); 482 numattr++; 483 484 kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, 485 &pubk, sizeof (KMF_KEY_HANDLE)); 486 numattr++; 487 488 if (tokencred != NULL && tokencred->credlen > 0) { 489 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 490 tokencred, sizeof (KMF_CREDENTIAL)); 491 numattr++; 492 } 493 494 if (token && strlen(token)) { 495 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 496 token, strlen(token)); 497 numattr++; 498 } 499 500 (void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist); 501 502 (void) kmf_free_signed_csr(&csr); 503 504 return (kmfrv); 505 } 506 507 int 508 pk_gencsr(int argc, char *argv[]) 509 { 510 KMF_RETURN rv; 511 int opt; 512 extern int optind_av; 513 extern char *optarg_av; 514 KMF_KEYSTORE_TYPE kstype = 0; 515 char *subject = NULL; 516 char *tokenname = NULL; 517 char *dir = NULL; 518 char *prefix = NULL; 519 int keylen = PK_DEFAULT_KEYLENGTH; 520 char *certlabel = NULL; 521 char *outcsr = NULL; 522 char *outkey = NULL; 523 char *format = NULL; 524 char *altname = NULL; 525 char *kustr = NULL; 526 char *ekustr = NULL; 527 uint16_t kubits = 0; 528 char *keytype = PK_DEFAULT_KEYTYPE; 529 KMF_HANDLE_T kmfhandle = NULL; 530 KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1; 531 KMF_KEY_ALG keyAlg = KMF_RSA; 532 KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_MD5WithRSA; 533 boolean_t interactive = B_FALSE; 534 char *subname = NULL; 535 KMF_CREDENTIAL tokencred = {NULL, 0}; 536 KMF_GENERALNAMECHOICES alttype = 0; 537 int altcrit = 0, kucrit = 0; 538 EKU_LIST *ekulist = NULL; 539 540 while ((opt = getopt_av(argc, argv, 541 "ik:(keystore)s:(subject)n:(nickname)A:(altname)" 542 "u:(keyusage)T:(token)d:(dir)p:(prefix)t:(keytype)" 543 "y:(keylen)l:(label)c:(outcsr)e:(eku)" 544 "K:(outkey)F:(format)")) != EOF) { 545 546 if (opt != 'i' && EMPTYSTRING(optarg_av)) 547 return (PK_ERR_USAGE); 548 549 switch (opt) { 550 case 'A': 551 altname = optarg_av; 552 break; 553 case 'i': 554 if (interactive || subject) 555 return (PK_ERR_USAGE); 556 else 557 interactive = B_TRUE; 558 break; 559 case 'k': 560 kstype = KS2Int(optarg_av); 561 if (kstype == 0) 562 return (PK_ERR_USAGE); 563 break; 564 case 's': 565 if (interactive || subject) 566 return (PK_ERR_USAGE); 567 else 568 subject = optarg_av; 569 break; 570 case 'l': 571 case 'n': 572 if (certlabel) 573 return (PK_ERR_USAGE); 574 certlabel = optarg_av; 575 break; 576 case 'T': 577 if (tokenname) 578 return (PK_ERR_USAGE); 579 tokenname = optarg_av; 580 break; 581 case 'd': 582 dir = optarg_av; 583 break; 584 case 'p': 585 if (prefix) 586 return (PK_ERR_USAGE); 587 prefix = optarg_av; 588 break; 589 case 't': 590 keytype = optarg_av; 591 break; 592 case 'u': 593 kustr = optarg_av; 594 break; 595 case 'y': 596 if (sscanf(optarg_av, "%d", 597 &keylen) != 1) { 598 cryptoerror(LOG_STDERR, 599 gettext("Unrecognized " 600 "key length (%s)\n"), optarg_av); 601 return (PK_ERR_USAGE); 602 } 603 break; 604 case 'c': 605 if (outcsr) 606 return (PK_ERR_USAGE); 607 outcsr = optarg_av; 608 break; 609 case 'K': 610 if (outkey) 611 return (PK_ERR_USAGE); 612 outkey = optarg_av; 613 break; 614 case 'F': 615 if (format) 616 return (PK_ERR_USAGE); 617 format = optarg_av; 618 break; 619 case 'e': 620 ekustr = optarg_av; 621 break; 622 default: 623 cryptoerror(LOG_STDERR, gettext( 624 "unrecognized gencsr option '%s'\n"), 625 argv[optind_av]); 626 return (PK_ERR_USAGE); 627 } 628 } 629 /* No additional args allowed. */ 630 argc -= optind_av; 631 argv += optind_av; 632 if (argc) { 633 return (PK_ERR_USAGE); 634 } 635 636 /* Assume keystore = PKCS#11 if not specified. */ 637 if (kstype == 0) 638 kstype = KMF_KEYSTORE_PK11TOKEN; 639 640 DIR_OPTION_CHECK(kstype, dir); 641 642 if (EMPTYSTRING(outcsr) && interactive) { 643 (void) get_filename("CSR", &outcsr); 644 } 645 if (EMPTYSTRING(outcsr)) { 646 (void) printf(gettext("A filename must be specified to hold" 647 "the final certificate request data.\n")); 648 return (PK_ERR_USAGE); 649 } 650 /* 651 * verify that the outcsr file does not already exist 652 * and that it can be created. 653 */ 654 rv = verify_file(outcsr); 655 if (rv != KMF_OK) { 656 cryptoerror(LOG_STDERR, gettext("output file (%s) " 657 "cannot be created.\n"), outcsr); 658 return (PK_ERR_USAGE); 659 } 660 661 if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) { 662 if (EMPTYSTRING(certlabel) && interactive) 663 (void) get_certlabel(&certlabel); 664 665 if (EMPTYSTRING(certlabel)) { 666 cryptoerror(LOG_STDERR, gettext("A label must be " 667 "specified to create a certificate request.\n")); 668 return (PK_ERR_USAGE); 669 } 670 } else if (kstype == KMF_KEYSTORE_OPENSSL) { 671 if (EMPTYSTRING(outkey) && interactive) 672 (void) get_filename("private key", &outkey); 673 674 if (EMPTYSTRING(outkey)) { 675 cryptoerror(LOG_STDERR, gettext("A key filename " 676 "must be specified to create a certificate " 677 "request.\n")); 678 return (PK_ERR_USAGE); 679 } 680 } 681 682 if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) { 683 cryptoerror(LOG_STDERR, 684 gettext("Error parsing format string (%s).\n"), format); 685 return (PK_ERR_USAGE); 686 } 687 if (format && fmt != KMF_FORMAT_ASN1 && fmt != KMF_FORMAT_PEM) { 688 cryptoerror(LOG_STDERR, 689 gettext("CSR must be DER or PEM format.\n")); 690 return (PK_ERR_USAGE); 691 } 692 693 /* 694 * Check the subject name. 695 * If interactive is true, get it now interactively. 696 */ 697 if (interactive) { 698 if (get_subname(&subname) != KMF_OK) { 699 cryptoerror(LOG_STDERR, gettext("Failed to get the " 700 "subject name interactively.\n")); 701 return (PK_ERR_USAGE); 702 } 703 } else { 704 if (EMPTYSTRING(subject)) { 705 cryptoerror(LOG_STDERR, gettext("A subject name or " 706 "-i must be specified to create a certificate " 707 "request.\n")); 708 return (PK_ERR_USAGE); 709 } else { 710 subname = strdup(subject); 711 if (subname == NULL) { 712 cryptoerror(LOG_STDERR, 713 gettext("Out of memory.\n")); 714 return (PK_ERR_SYSTEM); 715 } 716 } 717 } 718 if (altname != NULL) { 719 rv = verify_altname(altname, &alttype, &altcrit); 720 if (rv != KMF_OK) { 721 cryptoerror(LOG_STDERR, gettext("Subject AltName " 722 "must be specified as a name=value pair. " 723 "See the man page for details.")); 724 goto end; 725 } else { 726 /* advance the altname past the '=' sign */ 727 char *p = strchr(altname, '='); 728 if (p != NULL) 729 altname = p + 1; 730 } 731 } 732 733 if (kustr != NULL) { 734 rv = verify_keyusage(kustr, &kubits, &kucrit); 735 if (rv != KMF_OK) { 736 cryptoerror(LOG_STDERR, gettext("KeyUsage " 737 "must be specified as a comma-separated list. " 738 "See the man page for details.")); 739 goto end; 740 } 741 } 742 if (ekustr != NULL) { 743 rv = verify_ekunames(ekustr, &ekulist); 744 if (rv != KMF_OK) { 745 (void) fprintf(stderr, gettext("EKUs must " 746 "be specified as a comma-separated list. " 747 "See the man page for details.\n")); 748 rv = PK_ERR_USAGE; 749 goto end; 750 } 751 } 752 753 if ((rv = Str2KeyType(keytype, &keyAlg, &sigAlg)) != 0) { 754 cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"), 755 keytype); 756 goto end; 757 } 758 759 if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { 760 if (tokenname == NULL || !strlen(tokenname)) { 761 if (kstype == KMF_KEYSTORE_NSS) { 762 tokenname = "internal"; 763 } else { 764 tokenname = PK_DEFAULT_PK11TOKEN; 765 } 766 } 767 768 (void) get_token_password(kstype, tokenname, &tokencred); 769 } 770 771 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 772 cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n")); 773 return (PK_ERR_USAGE); 774 } 775 776 777 if (kstype == KMF_KEYSTORE_NSS) { 778 if (dir == NULL) 779 dir = PK_DEFAULT_DIRECTORY; 780 781 rv = gencsr_nss(kmfhandle, 782 tokenname, subname, altname, alttype, altcrit, 783 certlabel, dir, prefix, 784 keyAlg, keylen, kubits, kucrit, 785 fmt, outcsr, &tokencred, ekulist); 786 787 } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { 788 rv = gencsr_pkcs11(kmfhandle, 789 tokenname, subname, altname, alttype, altcrit, 790 certlabel, keyAlg, keylen, 791 kubits, kucrit, fmt, outcsr, &tokencred, ekulist); 792 793 } else if (kstype == KMF_KEYSTORE_OPENSSL) { 794 rv = gencsr_file(kmfhandle, 795 keyAlg, keylen, fmt, subname, altname, 796 alttype, altcrit, kubits, kucrit, 797 outcsr, outkey, ekulist); 798 } 799 800 end: 801 if (rv != KMF_OK) 802 display_error(kmfhandle, rv, 803 gettext("Error creating CSR or keypair")); 804 805 if (ekulist != NULL) 806 free_eku_list(ekulist); 807 808 if (subname) 809 free(subname); 810 811 if (tokencred.cred != NULL) 812 free(tokencred.cred); 813 814 (void) kmf_finalize(kmfhandle); 815 if (rv != KMF_OK) 816 return (PK_ERR_USAGE); 817 818 return (0); 819 } 820