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