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 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * This file implements the sign CSR operation for this tool. 28 */ 29 30 #include <stdio.h> 31 #include <errno.h> 32 #include <string.h> 33 #include <cryptoutil.h> 34 #include <security/cryptoki.h> 35 #include "common.h" 36 37 #include <kmfapi.h> 38 #include <kmfapiP.h> 39 40 #define SET_VALUE(f, s) \ 41 rv = f; \ 42 if (rv != KMF_OK) { \ 43 cryptoerror(LOG_STDERR, \ 44 gettext("Failed to set %s: 0x%02x\n"), s, rv); \ 45 goto cleanup; \ 46 } 47 48 49 static int 50 read_csrdata(KMF_HANDLE_T handle, char *csrfile, KMF_CSR_DATA *csrdata) 51 { 52 KMF_RETURN rv = KMF_OK; 53 KMF_ENCODE_FORMAT csrfmt; 54 KMF_DATA csrfiledata = {NULL, 0}; 55 KMF_DATA rawcsr = {NULL, 0}; 56 57 rv = kmf_get_file_format(csrfile, &csrfmt); 58 if (rv != KMF_OK) 59 return (rv); 60 61 rv = kmf_read_input_file(handle, csrfile, &csrfiledata); 62 if (rv != KMF_OK) 63 return (rv); 64 65 if (csrfmt == KMF_FORMAT_PEM) { 66 rv = kmf_pem_to_der(csrfiledata.Data, csrfiledata.Length, 67 &rawcsr.Data, (int *)&rawcsr.Length); 68 if (rv != KMF_OK) 69 return (rv); 70 71 kmf_free_data(&csrfiledata); 72 } else { 73 rawcsr.Data = csrfiledata.Data; 74 rawcsr.Length = csrfiledata.Length; 75 } 76 77 rv = kmf_decode_csr(handle, &rawcsr, csrdata); 78 kmf_free_data(&rawcsr); 79 80 return (rv); 81 } 82 83 static KMF_RETURN 84 find_csr_extn(KMF_X509_EXTENSIONS *extnlist, KMF_OID *extoid, 85 KMF_X509_EXTENSION *outextn) 86 { 87 int i, found = 0; 88 KMF_X509_EXTENSION *eptr; 89 KMF_RETURN rv = KMF_OK; 90 91 (void) memset(outextn, 0, sizeof (KMF_X509_EXTENSION)); 92 for (i = 0; !found && i < extnlist->numberOfExtensions; i++) { 93 eptr = &extnlist->extensions[i]; 94 if (IsEqualOid(extoid, &eptr->extnId)) { 95 rv = copy_extension_data(outextn, eptr); 96 found++; 97 } 98 } 99 if (found == 0 || rv != KMF_OK) 100 return (1); 101 else 102 return (rv); 103 } 104 105 static int 106 build_cert_from_csr(KMF_CSR_DATA *csrdata, 107 KMF_X509_CERTIFICATE *signedCert, 108 KMF_BIGINT *serial, 109 uint32_t ltime, 110 char *issuer, char *subject, 111 char *altname, 112 KMF_GENERALNAMECHOICES alttype, 113 int altcrit, 114 uint16_t kubits, 115 int kucrit, 116 EKU_LIST *ekulist) 117 { 118 KMF_RETURN rv = KMF_OK; 119 KMF_X509_NAME issuerDN, subjectDN; 120 121 /* 122 * If the CSR is ok, now we can generate the final certificate. 123 */ 124 (void) memset(signedCert, 0, sizeof (KMF_X509_CERTIFICATE)); 125 (void) memset(&issuerDN, 0, sizeof (issuerDN)); 126 (void) memset(&subjectDN, 0, sizeof (subjectDN)); 127 128 SET_VALUE(kmf_set_cert_version(signedCert, 2), "version number"); 129 130 SET_VALUE(kmf_set_cert_serial(signedCert, serial), "serial number"); 131 132 SET_VALUE(kmf_set_cert_validity(signedCert, NULL, ltime), 133 "validity time"); 134 135 if (issuer) { 136 if (kmf_dn_parser(issuer, &issuerDN) != KMF_OK) { 137 cryptoerror(LOG_STDERR, 138 gettext("Issuer name cannot be parsed\n")); 139 return (PK_ERR_USAGE); 140 } 141 SET_VALUE(kmf_set_cert_issuer(signedCert, &issuerDN), 142 "Issuer Name"); 143 } 144 if (subject) { 145 if (kmf_dn_parser(subject, &subjectDN) != KMF_OK) { 146 cryptoerror(LOG_STDERR, 147 gettext("Subject name cannot be parsed\n")); 148 return (PK_ERR_USAGE); 149 } 150 SET_VALUE(kmf_set_cert_subject(signedCert, &subjectDN), 151 "Subject Name"); 152 } else { 153 signedCert->certificate.subject = csrdata->csr.subject; 154 } 155 156 signedCert->certificate.subjectPublicKeyInfo = 157 csrdata->csr.subjectPublicKeyInfo; 158 159 signedCert->certificate.extensions = csrdata->csr.extensions; 160 161 signedCert->certificate.signature = 162 csrdata->signature.algorithmIdentifier; 163 164 if (kubits != 0) { 165 KMF_X509_EXTENSION extn; 166 uint16_t oldbits; 167 /* 168 * If the CSR already has KU, merge them. 169 */ 170 rv = find_csr_extn(&csrdata->csr.extensions, 171 (KMF_OID *)&KMFOID_KeyUsage, &extn); 172 if (rv == KMF_OK) { 173 extn.critical |= kucrit; 174 if (extn.value.tagAndValue->value.Length > 1) { 175 oldbits = 176 extn.value.tagAndValue->value.Data[1] << 8; 177 } else { 178 oldbits = 179 extn.value.tagAndValue->value.Data[0]; 180 } 181 oldbits |= kubits; 182 } else { 183 SET_VALUE(kmf_set_cert_ku(signedCert, kucrit, kubits), 184 "KeyUsage"); 185 } 186 } 187 if (altname != NULL) { 188 SET_VALUE(kmf_set_cert_subject_altname(signedCert, 189 altcrit, alttype, altname), "subjectAltName"); 190 } 191 if (ekulist != NULL) { 192 int i; 193 for (i = 0; rv == KMF_OK && i < ekulist->eku_count; i++) { 194 SET_VALUE(kmf_add_cert_eku(signedCert, 195 &ekulist->ekulist[i], 196 ekulist->critlist[i]), "Extended Key Usage"); 197 } 198 } 199 cleanup: 200 if (issuer != NULL) 201 kmf_free_dn(&issuerDN); 202 if (subject != NULL) 203 kmf_free_dn(&subjectDN); 204 205 return (rv); 206 } 207 208 static int 209 pk_sign_cert(KMF_HANDLE_T handle, KMF_X509_CERTIFICATE *cert, 210 KMF_KEY_HANDLE *key, KMF_DATA *outdata) 211 { 212 KMF_RETURN rv; 213 int numattr; 214 KMF_ATTRIBUTE attrlist[4]; 215 216 numattr = 0; 217 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 218 &key->kstype, sizeof (KMF_KEYSTORE_TYPE)); 219 numattr++; 220 221 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 222 key, sizeof (KMF_KEY_HANDLE_ATTR)); 223 numattr++; 224 225 /* cert data that is to be signed */ 226 kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 227 cert, sizeof (KMF_X509_CERTIFICATE)); 228 numattr++; 229 230 /* output buffer for the signed cert */ 231 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 232 outdata, sizeof (KMF_DATA)); 233 numattr++; 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 = {NULL, 0}; 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, &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 = {NULL, 0}; 365 KMF_CSR_DATA csrdata; 366 KMF_KEY_HANDLE casignkey; 367 KMF_KEY_CLASS keyclass = KMF_ASYM_PRI; 368 int numattr = 0; 369 int keys = 1; 370 KMF_ATTRIBUTE attrlist[16]; 371 KMF_X509_CERTIFICATE signedCert; 372 boolean_t token_bool = B_TRUE; 373 boolean_t private_bool = B_TRUE; 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 /* 461 * If we found the key, now we can sign the cert. 462 */ 463 rv = pk_sign_cert(handle, &signedCert, &casignkey, &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