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 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 22 */ 23 24 /* 25 * This file implements the sign CSR operation for this tool. 26 */ 27 28 #include <stdio.h> 29 #include <errno.h> 30 #include <string.h> 31 #include <cryptoutil.h> 32 #include <security/cryptoki.h> 33 #include "common.h" 34 35 #include <kmfapi.h> 36 #include <kmfapiP.h> 37 38 #define SET_VALUE(f, s) \ 39 rv = f; \ 40 if (rv != KMF_OK) { \ 41 cryptoerror(LOG_STDERR, \ 42 gettext("Failed to set %s: 0x%02x\n"), s, rv); \ 43 goto cleanup; \ 44 } 45 46 47 static int 48 read_csrdata(KMF_HANDLE_T handle, char *csrfile, KMF_CSR_DATA *csrdata) 49 { 50 KMF_RETURN rv = KMF_OK; 51 KMF_ENCODE_FORMAT csrfmt; 52 KMF_DATA csrfiledata = { 0, NULL }; 53 KMF_DATA rawcsr = { 0, NULL }; 54 55 rv = kmf_get_file_format(csrfile, &csrfmt); 56 if (rv != KMF_OK) 57 return (rv); 58 59 rv = kmf_read_input_file(handle, csrfile, &csrfiledata); 60 if (rv != KMF_OK) 61 return (rv); 62 63 if (csrfmt == KMF_FORMAT_PEM) { 64 rv = kmf_pem_to_der(csrfiledata.Data, csrfiledata.Length, 65 &rawcsr.Data, (int *)&rawcsr.Length); 66 if (rv != KMF_OK) 67 return (rv); 68 69 kmf_free_data(&csrfiledata); 70 } else { 71 rawcsr.Data = csrfiledata.Data; 72 rawcsr.Length = csrfiledata.Length; 73 } 74 75 rv = kmf_decode_csr(handle, &rawcsr, csrdata); 76 kmf_free_data(&rawcsr); 77 78 return (rv); 79 } 80 81 static KMF_RETURN 82 find_csr_extn(KMF_X509_EXTENSIONS *extnlist, KMF_OID *extoid, 83 KMF_X509_EXTENSION *outextn) 84 { 85 int i, found = 0; 86 KMF_X509_EXTENSION *eptr; 87 KMF_RETURN rv = KMF_OK; 88 89 (void) memset(outextn, 0, sizeof (KMF_X509_EXTENSION)); 90 for (i = 0; !found && i < extnlist->numberOfExtensions; i++) { 91 eptr = &extnlist->extensions[i]; 92 if (IsEqualOid(extoid, &eptr->extnId)) { 93 rv = copy_extension_data(outextn, eptr); 94 found++; 95 } 96 } 97 if (found == 0 || rv != KMF_OK) 98 return (1); 99 else 100 return (rv); 101 } 102 103 static int 104 build_cert_from_csr(KMF_CSR_DATA *csrdata, 105 KMF_X509_CERTIFICATE *signedCert, 106 KMF_BIGINT *serial, 107 uint32_t ltime, 108 char *issuer, char *subject, 109 char *altname, 110 KMF_GENERALNAMECHOICES alttype, 111 int altcrit, 112 uint16_t kubits, 113 int kucrit, 114 EKU_LIST *ekulist) 115 { 116 KMF_RETURN rv = KMF_OK; 117 KMF_X509_NAME issuerDN, subjectDN; 118 119 /* 120 * If the CSR is ok, now we can generate the final certificate. 121 */ 122 (void) memset(signedCert, 0, sizeof (KMF_X509_CERTIFICATE)); 123 (void) memset(&issuerDN, 0, sizeof (issuerDN)); 124 (void) memset(&subjectDN, 0, sizeof (subjectDN)); 125 126 SET_VALUE(kmf_set_cert_version(signedCert, 2), "version number"); 127 128 SET_VALUE(kmf_set_cert_serial(signedCert, serial), "serial number"); 129 130 SET_VALUE(kmf_set_cert_validity(signedCert, NULL, ltime), 131 "validity time"); 132 133 if (issuer) { 134 if (kmf_dn_parser(issuer, &issuerDN) != KMF_OK) { 135 cryptoerror(LOG_STDERR, 136 gettext("Issuer name cannot be parsed\n")); 137 return (PK_ERR_USAGE); 138 } 139 SET_VALUE(kmf_set_cert_issuer(signedCert, &issuerDN), 140 "Issuer Name"); 141 } 142 if (subject) { 143 if (kmf_dn_parser(subject, &subjectDN) != KMF_OK) { 144 cryptoerror(LOG_STDERR, 145 gettext("Subject name cannot be parsed\n")); 146 return (PK_ERR_USAGE); 147 } 148 SET_VALUE(kmf_set_cert_subject(signedCert, &subjectDN), 149 "Subject Name"); 150 } else { 151 signedCert->certificate.subject = csrdata->csr.subject; 152 } 153 154 signedCert->certificate.subjectPublicKeyInfo = 155 csrdata->csr.subjectPublicKeyInfo; 156 157 signedCert->certificate.extensions = csrdata->csr.extensions; 158 159 signedCert->certificate.signature = 160 csrdata->signature.algorithmIdentifier; 161 162 if (kubits != 0) { 163 KMF_X509_EXTENSION extn; 164 uint16_t oldbits; 165 /* 166 * If the CSR already has KU, merge them. 167 */ 168 rv = find_csr_extn(&csrdata->csr.extensions, 169 (KMF_OID *)&KMFOID_KeyUsage, &extn); 170 if (rv == KMF_OK) { 171 extn.critical |= kucrit; 172 if (extn.value.tagAndValue->value.Length > 1) { 173 oldbits = 174 extn.value.tagAndValue->value.Data[1] << 8; 175 } else { 176 oldbits = 177 extn.value.tagAndValue->value.Data[0]; 178 } 179 oldbits |= kubits; 180 } else { 181 SET_VALUE(kmf_set_cert_ku(signedCert, kucrit, kubits), 182 "KeyUsage"); 183 } 184 } 185 if (altname != NULL) { 186 SET_VALUE(kmf_set_cert_subject_altname(signedCert, 187 altcrit, alttype, altname), "subjectAltName"); 188 } 189 if (ekulist != NULL) { 190 int i; 191 for (i = 0; rv == KMF_OK && i < ekulist->eku_count; i++) { 192 SET_VALUE(kmf_add_cert_eku(signedCert, 193 &ekulist->ekulist[i], 194 ekulist->critlist[i]), "Extended Key Usage"); 195 } 196 } 197 cleanup: 198 if (issuer != NULL) 199 kmf_free_dn(&issuerDN); 200 if (subject != NULL) 201 kmf_free_dn(&subjectDN); 202 203 return (rv); 204 } 205 206 static int 207 pk_sign_cert(KMF_HANDLE_T handle, KMF_X509_CERTIFICATE *cert, 208 KMF_KEY_HANDLE *key, KMF_OID *sigoid, KMF_DATA *outdata) 209 { 210 KMF_RETURN rv; 211 int numattr; 212 KMF_ATTRIBUTE attrlist[4]; 213 214 numattr = 0; 215 kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYSTORE_TYPE_ATTR, 216 &key->kstype, sizeof (KMF_KEYSTORE_TYPE)); 217 218 kmf_set_attr_at_index(attrlist, numattr++, KMF_KEY_HANDLE_ATTR, 219 key, sizeof (KMF_KEY_HANDLE_ATTR)); 220 221 /* cert data that is to be signed */ 222 kmf_set_attr_at_index(attrlist, numattr++, KMF_X509_CERTIFICATE_ATTR, 223 cert, sizeof (KMF_X509_CERTIFICATE)); 224 225 /* output buffer for the signed cert */ 226 kmf_set_attr_at_index(attrlist, numattr++, KMF_CERT_DATA_ATTR, 227 outdata, sizeof (KMF_DATA)); 228 229 /* Set the signature OID value so KMF knows how to generate the sig */ 230 if (sigoid) { 231 kmf_set_attr_at_index(attrlist, numattr++, KMF_OID_ATTR, 232 sigoid, sizeof (KMF_OID)); 233 } 234 235 if ((rv = kmf_sign_cert(handle, numattr, attrlist)) != KMF_OK) { 236 cryptoerror(LOG_STDERR, 237 gettext("Failed to sign certificate.\n")); 238 return (rv); 239 } 240 241 return (rv); 242 } 243 244 static int 245 pk_signcsr_files(KMF_HANDLE_T handle, 246 char *signkey, 247 char *csrfile, 248 KMF_BIGINT *serial, 249 char *certfile, 250 char *issuer, 251 char *subject, 252 char *altname, 253 KMF_GENERALNAMECHOICES alttype, 254 int altcrit, 255 uint16_t kubits, 256 int kucrit, 257 EKU_LIST *ekulist, 258 uint32_t ltime, 259 KMF_ENCODE_FORMAT fmt) 260 { 261 KMF_RETURN rv = KMF_OK; 262 KMF_CSR_DATA csrdata; 263 KMF_ATTRIBUTE attrlist[16]; 264 KMF_X509_CERTIFICATE signedCert; 265 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 266 KMF_KEY_CLASS keyclass = KMF_ASYM_PRI; 267 KMF_KEY_HANDLE cakey; 268 KMF_DATA certdata = { 0, NULL }; 269 int numattr, count; 270 271 (void) memset(&cakey, 0, sizeof (cakey)); 272 (void) memset(&signedCert, 0, sizeof (signedCert)); 273 274 rv = read_csrdata(handle, csrfile, &csrdata); 275 if (rv != KMF_OK) { 276 cryptoerror(LOG_STDERR, 277 gettext("Error reading CSR data\n")); 278 return (rv); 279 } 280 281 /* verify the signature first */ 282 numattr = 0; 283 kmf_set_attr_at_index(attrlist, numattr, KMF_CSR_DATA_ATTR, 284 &csrdata, sizeof (csrdata)); 285 numattr++; 286 287 rv = kmf_verify_csr(handle, numattr, attrlist); 288 if (rv != KMF_OK) { 289 cryptoerror(LOG_STDERR, gettext("CSR signature " 290 "verification failed.\n")); 291 goto cleanup; 292 } 293 294 rv = build_cert_from_csr(&csrdata, &signedCert, serial, ltime, 295 issuer, subject, altname, alttype, altcrit, kubits, 296 kucrit, ekulist); 297 298 if (rv != KMF_OK) 299 goto cleanup; 300 301 /* 302 * Find the signing key. 303 */ 304 (void) memset(&cakey, 0, sizeof (cakey)); 305 306 numattr = 0; 307 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 308 &kstype, sizeof (kstype)); 309 numattr++; 310 311 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, 312 signkey, strlen(signkey)); 313 numattr++; 314 315 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, 316 &keyclass, sizeof (keyclass)); 317 numattr++; 318 319 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 320 &cakey, sizeof (cakey)); 321 numattr++; 322 323 count = 1; 324 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 325 &count, sizeof (count)); 326 numattr++; 327 328 rv = kmf_find_key(handle, numattr, attrlist); 329 if (rv != KMF_OK) { 330 cryptoerror(LOG_STDERR, gettext( 331 "Error finding CA signing key\n")); 332 goto cleanup; 333 } 334 335 rv = pk_sign_cert(handle, &signedCert, &cakey, NULL, &certdata); 336 if (rv != KMF_OK) { 337 cryptoerror(LOG_STDERR, gettext( 338 "Error signing certificate.\n")); 339 goto cleanup; 340 } 341 342 rv = kmf_create_cert_file(&certdata, fmt, certfile); 343 344 cleanup: 345 kmf_free_signed_csr(&csrdata); 346 kmf_free_data(&certdata); 347 kmf_free_kmf_key(handle, &cakey); 348 return (rv); 349 } 350 351 static int 352 pk_signcsr_pk11_nss(KMF_HANDLE_T handle, 353 KMF_KEYSTORE_TYPE kstype, 354 char *dir, char *prefix, 355 char *token, KMF_CREDENTIAL *cred, 356 char *signkey, char *csrfile, 357 KMF_BIGINT *serial, char *certfile, char *issuer, char *subject, 358 char *altname, KMF_GENERALNAMECHOICES alttype, int altcrit, 359 uint16_t kubits, int kucrit, 360 EKU_LIST *ekulist, uint32_t ltime, 361 KMF_ENCODE_FORMAT fmt, int store, char *outlabel) 362 { 363 KMF_RETURN rv = KMF_OK; 364 KMF_DATA outcert = { 0, NULL }; 365 KMF_CSR_DATA csrdata = { 0, NULL }; 366 KMF_KEY_HANDLE casignkey; 367 KMF_KEY_CLASS keyclass = KMF_ASYM_PRI; 368 KMF_ATTRIBUTE attrlist[16]; 369 KMF_X509_CERTIFICATE signedCert; 370 boolean_t token_bool = B_TRUE; 371 boolean_t private_bool = B_TRUE; 372 int numattr = 0; 373 int keys = 1; 374 375 (void) memset(&casignkey, 0, sizeof (KMF_KEY_HANDLE)); 376 (void) memset(&signedCert, 0, sizeof (signedCert)); 377 378 rv = read_csrdata(handle, csrfile, &csrdata); 379 if (rv != KMF_OK) { 380 cryptoerror(LOG_STDERR, 381 gettext("Error reading CSR data\n")); 382 return (rv); 383 } 384 385 if (kstype == KMF_KEYSTORE_PK11TOKEN) { 386 rv = select_token(handle, token, FALSE); 387 } else if (kstype == KMF_KEYSTORE_NSS) { 388 rv = configure_nss(handle, dir, prefix); 389 } 390 391 /* verify the signature first */ 392 kmf_set_attr_at_index(attrlist, numattr, KMF_CSR_DATA_ATTR, 393 &csrdata, sizeof (csrdata)); 394 numattr++; 395 396 rv = kmf_verify_csr(handle, numattr, attrlist); 397 if (rv != KMF_OK) { 398 cryptoerror(LOG_STDERR, gettext("CSR signature " 399 "verification failed.\n")); 400 goto cleanup; 401 } 402 403 rv = build_cert_from_csr(&csrdata, 404 &signedCert, serial, ltime, 405 issuer, subject, altname, 406 alttype, altcrit, kubits, 407 kucrit, ekulist); 408 409 if (rv != KMF_OK) 410 goto cleanup; 411 412 /* 413 * Find the signing key. 414 */ 415 numattr = 0; 416 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 417 &kstype, sizeof (kstype)); 418 numattr++; 419 if (kstype == KMF_KEYSTORE_NSS) { 420 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 421 token, strlen(token)); 422 numattr++; 423 } 424 425 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, signkey, 426 strlen(signkey)); 427 numattr++; 428 429 kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVATE_BOOL_ATTR, 430 &private_bool, sizeof (private_bool)); 431 numattr++; 432 433 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR, 434 &token_bool, sizeof (token_bool)); 435 numattr++; 436 437 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR, 438 &keyclass, sizeof (keyclass)); 439 numattr++; 440 441 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 442 cred, sizeof (KMF_CREDENTIAL_ATTR)); 443 numattr++; 444 445 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, 446 &keys, sizeof (keys)); 447 numattr++; 448 449 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 450 &casignkey, sizeof (casignkey)); 451 numattr++; 452 453 rv = kmf_find_key(handle, numattr, attrlist); 454 if (rv != KMF_OK) { 455 cryptoerror(LOG_STDERR, 456 gettext("Failed to find signing key\n")); 457 goto cleanup; 458 } 459 /* 460 * If we found the key, now we can sign the cert. 461 */ 462 rv = pk_sign_cert(handle, &signedCert, &casignkey, NULL, 463 &outcert); 464 if (rv != KMF_OK) { 465 cryptoerror(LOG_STDERR, gettext( 466 "Error signing certificate.\n")); 467 goto cleanup; 468 } 469 470 /* 471 * Store it on the token if the user asked for it. 472 */ 473 if (store) { 474 numattr = 0; 475 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 476 &kstype, sizeof (kstype)); 477 numattr++; 478 479 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 480 &outcert, sizeof (KMF_DATA)); 481 numattr++; 482 483 if (outlabel != NULL) { 484 kmf_set_attr_at_index(attrlist, numattr, 485 KMF_CERT_LABEL_ATTR, 486 outlabel, strlen(outlabel)); 487 numattr++; 488 } 489 490 if (kstype == KMF_KEYSTORE_NSS) { 491 if (token != NULL) 492 kmf_set_attr_at_index(attrlist, numattr, 493 KMF_TOKEN_LABEL_ATTR, 494 token, strlen(token)); 495 numattr++; 496 } 497 498 rv = kmf_store_cert(handle, numattr, attrlist); 499 if (rv != KMF_OK) { 500 display_error(handle, rv, 501 gettext("Failed to store cert " 502 "on PKCS#11 token.\n")); 503 rv = KMF_OK; 504 /* Not fatal, we can still write it to a file. */ 505 } 506 } 507 rv = kmf_create_cert_file(&outcert, fmt, certfile); 508 509 cleanup: 510 kmf_free_signed_csr(&csrdata); 511 kmf_free_data(&outcert); 512 kmf_free_kmf_key(handle, &casignkey); 513 514 return (rv); 515 } 516 517 /* 518 * sign a CSR and generate an x509v3 certificate file. 519 */ 520 int 521 pk_signcsr(int argc, char *argv[]) 522 { 523 int opt; 524 extern int optind_av; 525 extern char *optarg_av; 526 char *token_spec = NULL; 527 char *subject = NULL; 528 char *issuer = NULL; 529 char *dir = NULL; 530 char *prefix = NULL; 531 char *csrfile = NULL; 532 char *serstr = NULL; 533 char *ekustr = NULL; 534 char *kustr = NULL; 535 char *format = NULL; 536 char *storestr = NULL; 537 char *altname = NULL; 538 char *certfile = NULL; 539 char *lifetime = NULL; 540 char *signkey = NULL; 541 char *outlabel = NULL; 542 uint32_t ltime = 365 * 24 * 60 * 60; /* 1 Year */ 543 int store = 0; 544 uint16_t kubits = 0; 545 int altcrit = 0, kucrit = 0; 546 KMF_BIGINT serial = { NULL, 0 }; 547 EKU_LIST *ekulist = NULL; 548 KMF_KEYSTORE_TYPE kstype = 0; 549 KMF_RETURN rv = KMF_OK; 550 KMF_HANDLE_T kmfhandle = NULL; 551 KMF_CREDENTIAL tokencred = { NULL, 0 }; 552 KMF_GENERALNAMECHOICES alttype = 0; 553 KMF_ENCODE_FORMAT fmt = KMF_FORMAT_PEM; 554 555 /* Parse command line options. Do NOT i18n/l10n. */ 556 while ((opt = getopt_av(argc, argv, 557 "k:(keystore)c:(csr)T:(token)d:(dir)" 558 "p:(prefix)S:(serial)s:(subject)a:(altname)" 559 "t:(store)F:(format)K:(keyusage)l:(signkey)" 560 "L:(lifetime)e:(eku)i:(issuer)" 561 "n:(outlabel)o:(outcert)")) != EOF) { 562 if (EMPTYSTRING(optarg_av)) 563 return (PK_ERR_USAGE); 564 switch (opt) { 565 case 'k': 566 if (kstype != 0) 567 return (PK_ERR_USAGE); 568 kstype = KS2Int(optarg_av); 569 if (kstype == 0) 570 return (PK_ERR_USAGE); 571 break; 572 case 't': 573 if (storestr != NULL) 574 return (PK_ERR_USAGE); 575 storestr = optarg_av; 576 store = yn_to_int(optarg_av); 577 if (store == -1) 578 return (PK_ERR_USAGE); 579 break; 580 case 'a': 581 if (altname) 582 return (PK_ERR_USAGE); 583 altname = optarg_av; 584 break; 585 case 's': 586 if (subject) 587 return (PK_ERR_USAGE); 588 subject = optarg_av; 589 break; 590 case 'i': 591 if (issuer) 592 return (PK_ERR_USAGE); 593 issuer = optarg_av; 594 break; 595 case 'd': 596 if (dir) 597 return (PK_ERR_USAGE); 598 dir = optarg_av; 599 break; 600 case 'p': 601 if (prefix) 602 return (PK_ERR_USAGE); 603 prefix = optarg_av; 604 break; 605 case 'S': 606 if (serstr != NULL) 607 return (PK_ERR_USAGE); 608 serstr = optarg_av; 609 break; 610 case 'c': 611 if (csrfile) 612 return (PK_ERR_USAGE); 613 csrfile = optarg_av; 614 break; 615 case 'T': /* token specifier */ 616 if (token_spec) 617 return (PK_ERR_USAGE); 618 token_spec = optarg_av; 619 break; 620 case 'l': /* object with specific label */ 621 if (signkey) 622 return (PK_ERR_USAGE); 623 signkey = optarg_av; 624 break; 625 case 'e': 626 if (ekustr != NULL) 627 return (PK_ERR_USAGE); 628 ekustr = optarg_av; 629 break; 630 case 'K': 631 if (kustr != NULL) 632 return (PK_ERR_USAGE); 633 kustr = optarg_av; 634 break; 635 case 'F': 636 if (format != NULL) 637 return (PK_ERR_USAGE); 638 format = optarg_av; 639 break; 640 case 'o': 641 if (certfile != NULL) 642 return (PK_ERR_USAGE); 643 certfile = optarg_av; 644 break; 645 case 'L': 646 if (lifetime != NULL) 647 return (PK_ERR_USAGE); 648 lifetime = optarg_av; 649 break; 650 case 'n': 651 if (outlabel != NULL) 652 return (PK_ERR_USAGE); 653 outlabel = optarg_av; 654 break; 655 default: 656 return (PK_ERR_USAGE); 657 } 658 } 659 /* No additional args allowed. */ 660 argc -= optind_av; 661 argv += optind_av; 662 if (argc) 663 return (PK_ERR_USAGE); 664 665 666 /* Assume keystore = PKCS#11 if not specified. */ 667 if (kstype == 0) 668 kstype = KMF_KEYSTORE_PK11TOKEN; 669 670 DIR_OPTION_CHECK(kstype, dir); 671 672 if (signkey == NULL) { 673 (void) fprintf(stderr, gettext("The signing key label " 674 "or filename was not specified\n")); 675 return (PK_ERR_USAGE); 676 } 677 if (csrfile == NULL) { 678 (void) fprintf(stderr, gettext("The CSR filename was not" 679 " specified\n")); 680 return (PK_ERR_USAGE); 681 } 682 if (certfile == NULL) { 683 (void) fprintf(stderr, gettext("The output certificate file " 684 "was not specified\n")); 685 return (PK_ERR_USAGE); 686 } 687 if (issuer == NULL) { 688 (void) fprintf(stderr, gettext("The issuer DN " 689 "was not specified\n")); 690 return (PK_ERR_USAGE); 691 } 692 if (lifetime != NULL) { 693 if (Str2Lifetime(lifetime, <ime) != 0) { 694 cryptoerror(LOG_STDERR, 695 gettext("Error parsing lifetime string\n")); 696 return (PK_ERR_USAGE); 697 } 698 } 699 if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) { 700 token_spec = PK_DEFAULT_PK11TOKEN; 701 } else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) { 702 token_spec = DEFAULT_NSS_TOKEN; 703 } 704 705 if (serstr != NULL) { 706 uchar_t *bytes = NULL; 707 size_t bytelen; 708 709 rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); 710 if (rv != KMF_OK || bytes == NULL) { 711 (void) fprintf(stderr, gettext("Serial number " 712 "must be specified as a hex number " 713 "(ex: 0x0102030405ffeeddee)\n")); 714 return (PK_ERR_USAGE); 715 } 716 serial.val = bytes; 717 serial.len = bytelen; 718 } else { 719 (void) fprintf(stderr, gettext("The serial number was not" 720 " specified\n")); 721 return (PK_ERR_USAGE); 722 } 723 724 if ((kstype == KMF_KEYSTORE_PK11TOKEN || 725 kstype == KMF_KEYSTORE_NSS)) { 726 /* Need to get password for private key access */ 727 (void) get_token_password(kstype, token_spec, 728 &tokencred); 729 } 730 if (kustr != NULL) { 731 rv = verify_keyusage(kustr, &kubits, &kucrit); 732 if (rv != KMF_OK) { 733 (void) fprintf(stderr, gettext("KeyUsage " 734 "must be specified as a comma-separated list. " 735 "See the man page for details.\n")); 736 rv = PK_ERR_USAGE; 737 goto end; 738 } 739 } 740 if (ekustr != NULL) { 741 rv = verify_ekunames(ekustr, &ekulist); 742 if (rv != KMF_OK) { 743 (void) fprintf(stderr, gettext("EKUs must " 744 "be specified as a comma-separated list. " 745 "See the man page for details.\n")); 746 rv = PK_ERR_USAGE; 747 goto end; 748 } 749 } 750 if (altname != NULL) { 751 char *p; 752 rv = verify_altname(altname, &alttype, &altcrit); 753 if (rv != KMF_OK) { 754 (void) fprintf(stderr, gettext("Subject AltName " 755 "must be specified as a name=value pair. " 756 "See the man page for details.\n")); 757 rv = PK_ERR_USAGE; 758 goto end; 759 } 760 /* advance the altname past the '=' sign */ 761 p = strchr(altname, '='); 762 if (p != NULL) 763 altname = p + 1; 764 } 765 if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) { 766 cryptoerror(LOG_STDERR, 767 gettext("Error parsing format string (%s).\n"), 768 format); 769 return (PK_ERR_USAGE); 770 } 771 772 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 773 return (rv); 774 } 775 776 if (kstype == KMF_KEYSTORE_PK11TOKEN) { 777 rv = pk_signcsr_pk11_nss(kmfhandle, 778 kstype, dir, prefix, token_spec, &tokencred, 779 signkey, csrfile, &serial, certfile, issuer, subject, 780 altname, alttype, altcrit, kubits, kucrit, 781 ekulist, ltime, fmt, store, outlabel); 782 783 } else if (kstype == KMF_KEYSTORE_NSS) { 784 if (dir == NULL) 785 dir = PK_DEFAULT_DIRECTORY; 786 787 rv = pk_signcsr_pk11_nss(kmfhandle, 788 kstype, dir, prefix, token_spec, &tokencred, 789 signkey, csrfile, &serial, certfile, issuer, subject, 790 altname, alttype, altcrit, kubits, kucrit, 791 ekulist, ltime, fmt, store, outlabel); 792 793 } else if (kstype == KMF_KEYSTORE_OPENSSL) { 794 rv = pk_signcsr_files(kmfhandle, 795 signkey, csrfile, &serial, certfile, issuer, subject, 796 altname, alttype, altcrit, kubits, kucrit, 797 ekulist, ltime, fmt); 798 } 799 800 end: 801 if (rv != KMF_OK) { 802 display_error(kmfhandle, rv, 803 gettext("Error listing objects")); 804 } 805 806 if (serial.val != NULL) 807 free(serial.val); 808 809 if (tokencred.cred != NULL) 810 free(tokencred.cred); 811 812 free_eku_list(ekulist); 813 814 (void) kmf_finalize(kmfhandle); 815 return (rv); 816 } 817