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_SHA1WithRSA; 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_SHA1WithRSA; 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_SHA1WithRSA; 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_SHA1WithRSA; 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) 555 return (PK_ERR_USAGE); 556 else if (subject) { 557 cryptoerror(LOG_STDERR, 558 gettext("Interactive (-i) and " 559 "subject options are mutually " 560 "exclusive.\n")); 561 return (PK_ERR_USAGE); 562 } else 563 interactive = B_TRUE; 564 break; 565 case 'k': 566 kstype = KS2Int(optarg_av); 567 if (kstype == 0) 568 return (PK_ERR_USAGE); 569 break; 570 case 's': 571 if (subject) 572 return (PK_ERR_USAGE); 573 else if (interactive) { 574 cryptoerror(LOG_STDERR, 575 gettext("Interactive (-i) and " 576 "subject options are mutually " 577 "exclusive.\n")); 578 return (PK_ERR_USAGE); 579 } else 580 subject = optarg_av; 581 break; 582 case 'l': 583 case 'n': 584 if (certlabel) 585 return (PK_ERR_USAGE); 586 certlabel = optarg_av; 587 break; 588 case 'T': 589 if (tokenname) 590 return (PK_ERR_USAGE); 591 tokenname = optarg_av; 592 break; 593 case 'd': 594 dir = optarg_av; 595 break; 596 case 'p': 597 if (prefix) 598 return (PK_ERR_USAGE); 599 prefix = optarg_av; 600 break; 601 case 't': 602 keytype = optarg_av; 603 break; 604 case 'u': 605 kustr = optarg_av; 606 break; 607 case 'y': 608 if (sscanf(optarg_av, "%d", 609 &keylen) != 1) { 610 cryptoerror(LOG_STDERR, 611 gettext("Unrecognized " 612 "key length (%s)\n"), optarg_av); 613 return (PK_ERR_USAGE); 614 } 615 break; 616 case 'c': 617 if (outcsr) 618 return (PK_ERR_USAGE); 619 outcsr = optarg_av; 620 break; 621 case 'K': 622 if (outkey) 623 return (PK_ERR_USAGE); 624 outkey = optarg_av; 625 break; 626 case 'F': 627 if (format) 628 return (PK_ERR_USAGE); 629 format = optarg_av; 630 break; 631 case 'e': 632 ekustr = optarg_av; 633 break; 634 default: 635 cryptoerror(LOG_STDERR, gettext( 636 "unrecognized gencsr option '%s'\n"), 637 argv[optind_av]); 638 return (PK_ERR_USAGE); 639 } 640 } 641 /* No additional args allowed. */ 642 argc -= optind_av; 643 argv += optind_av; 644 if (argc) { 645 return (PK_ERR_USAGE); 646 } 647 648 /* Assume keystore = PKCS#11 if not specified. */ 649 if (kstype == 0) 650 kstype = KMF_KEYSTORE_PK11TOKEN; 651 652 DIR_OPTION_CHECK(kstype, dir); 653 654 if (EMPTYSTRING(outcsr) && interactive) { 655 (void) get_filename("CSR", &outcsr); 656 } 657 if (EMPTYSTRING(outcsr)) { 658 (void) printf(gettext("A filename must be specified to hold" 659 "the final certificate request data.\n")); 660 return (PK_ERR_USAGE); 661 } 662 /* 663 * verify that the outcsr file does not already exist 664 * and that it can be created. 665 */ 666 rv = verify_file(outcsr); 667 if (rv != KMF_OK) { 668 cryptoerror(LOG_STDERR, gettext("output file (%s) " 669 "cannot be created.\n"), outcsr); 670 return (PK_ERR_USAGE); 671 } 672 673 if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) { 674 if (EMPTYSTRING(certlabel) && interactive) 675 (void) get_certlabel(&certlabel); 676 677 if (EMPTYSTRING(certlabel)) { 678 cryptoerror(LOG_STDERR, gettext("A label must be " 679 "specified to create a certificate request.\n")); 680 return (PK_ERR_USAGE); 681 } 682 } else if (kstype == KMF_KEYSTORE_OPENSSL) { 683 if (EMPTYSTRING(outkey) && interactive) 684 (void) get_filename("private key", &outkey); 685 686 if (EMPTYSTRING(outkey)) { 687 cryptoerror(LOG_STDERR, gettext("A key filename " 688 "must be specified to create a certificate " 689 "request.\n")); 690 return (PK_ERR_USAGE); 691 } 692 } 693 694 if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) { 695 cryptoerror(LOG_STDERR, 696 gettext("Error parsing format string (%s).\n"), format); 697 return (PK_ERR_USAGE); 698 } 699 if (format && fmt != KMF_FORMAT_ASN1 && fmt != KMF_FORMAT_PEM) { 700 cryptoerror(LOG_STDERR, 701 gettext("CSR must be DER or PEM format.\n")); 702 return (PK_ERR_USAGE); 703 } 704 705 /* 706 * Check the subject name. 707 * If interactive is true, get it now interactively. 708 */ 709 if (interactive) { 710 if (get_subname(&subname) != KMF_OK) { 711 cryptoerror(LOG_STDERR, gettext("Failed to get the " 712 "subject name interactively.\n")); 713 return (PK_ERR_USAGE); 714 } 715 } else { 716 if (EMPTYSTRING(subject)) { 717 cryptoerror(LOG_STDERR, gettext("A subject name or " 718 "-i must be specified to create a certificate " 719 "request.\n")); 720 return (PK_ERR_USAGE); 721 } else { 722 subname = strdup(subject); 723 if (subname == NULL) { 724 cryptoerror(LOG_STDERR, 725 gettext("Out of memory.\n")); 726 return (PK_ERR_SYSTEM); 727 } 728 } 729 } 730 if (altname != NULL) { 731 rv = verify_altname(altname, &alttype, &altcrit); 732 if (rv != KMF_OK) { 733 cryptoerror(LOG_STDERR, gettext("Subject AltName " 734 "must be specified as a name=value pair. " 735 "See the man page for details.")); 736 goto end; 737 } else { 738 /* advance the altname past the '=' sign */ 739 char *p = strchr(altname, '='); 740 if (p != NULL) 741 altname = p + 1; 742 } 743 } 744 745 if (kustr != NULL) { 746 rv = verify_keyusage(kustr, &kubits, &kucrit); 747 if (rv != KMF_OK) { 748 cryptoerror(LOG_STDERR, gettext("KeyUsage " 749 "must be specified as a comma-separated list. " 750 "See the man page for details.")); 751 goto end; 752 } 753 } 754 if (ekustr != NULL) { 755 rv = verify_ekunames(ekustr, &ekulist); 756 if (rv != KMF_OK) { 757 (void) fprintf(stderr, gettext("EKUs must " 758 "be specified as a comma-separated list. " 759 "See the man page for details.\n")); 760 rv = PK_ERR_USAGE; 761 goto end; 762 } 763 } 764 765 if ((rv = Str2KeyType(keytype, &keyAlg, &sigAlg)) != 0) { 766 cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"), 767 keytype); 768 goto end; 769 } 770 771 if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { 772 if (tokenname == NULL || !strlen(tokenname)) { 773 if (kstype == KMF_KEYSTORE_NSS) { 774 tokenname = "internal"; 775 } else { 776 tokenname = PK_DEFAULT_PK11TOKEN; 777 } 778 } 779 780 (void) get_token_password(kstype, tokenname, &tokencred); 781 } 782 783 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 784 cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n")); 785 return (PK_ERR_USAGE); 786 } 787 788 789 if (kstype == KMF_KEYSTORE_NSS) { 790 if (dir == NULL) 791 dir = PK_DEFAULT_DIRECTORY; 792 793 rv = gencsr_nss(kmfhandle, 794 tokenname, subname, altname, alttype, altcrit, 795 certlabel, dir, prefix, 796 keyAlg, keylen, kubits, kucrit, 797 fmt, outcsr, &tokencred, ekulist); 798 799 } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { 800 rv = gencsr_pkcs11(kmfhandle, 801 tokenname, subname, altname, alttype, altcrit, 802 certlabel, keyAlg, keylen, 803 kubits, kucrit, fmt, outcsr, &tokencred, ekulist); 804 805 } else if (kstype == KMF_KEYSTORE_OPENSSL) { 806 rv = gencsr_file(kmfhandle, 807 keyAlg, keylen, fmt, subname, altname, 808 alttype, altcrit, kubits, kucrit, 809 outcsr, outkey, ekulist); 810 } 811 812 end: 813 if (rv != KMF_OK) { 814 display_error(kmfhandle, rv, 815 gettext("Error creating CSR or keypair")); 816 817 if (rv == KMF_ERR_RDN_PARSER) { 818 cryptoerror(LOG_STDERR, gettext("subject or " 819 "issuer name must be in proper DN format.\n")); 820 } 821 } 822 823 if (ekulist != NULL) 824 free_eku_list(ekulist); 825 826 if (subname) 827 free(subname); 828 829 if (tokencred.cred != NULL) 830 free(tokencred.cred); 831 832 (void) kmf_finalize(kmfhandle); 833 if (rv != KMF_OK) 834 return (PK_ERR_USAGE); 835 836 return (0); 837 } 838