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