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