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