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 2007 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 set %s: 0x%02x\n"), \ 45 s, kmfrv); \ 46 goto cleanup; \ 47 } 48 49 static int 50 gencert_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 KMF_ALGORITHM_INDEX sigAlg, 55 int keylen, uint32_t ltime, KMF_BIGINT *serial, 56 uint16_t kubits, int kucrit, KMF_CREDENTIAL *tokencred) 57 { 58 KMF_RETURN kmfrv = KMF_OK; 59 KMF_KEY_HANDLE pubk, prik; 60 KMF_X509_CERTIFICATE signedCert; 61 KMF_X509_NAME certSubject; 62 KMF_X509_NAME certIssuer; 63 KMF_DATA x509DER; 64 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 65 KMF_ATTRIBUTE attrlist[16]; 66 int numattr = 0; 67 KMF_KEY_ALG keytype; 68 uint32_t keylength; 69 70 (void) memset(&signedCert, 0, sizeof (signedCert)); 71 (void) memset(&certSubject, 0, sizeof (certSubject)); 72 (void) memset(&certIssuer, 0, sizeof (certIssuer)); 73 (void) memset(&x509DER, 0, sizeof (x509DER)); 74 75 /* If the subject name cannot be parsed, flag it now and exit */ 76 if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { 77 cryptoerror(LOG_STDERR, 78 gettext("Subject name cannot be parsed.\n")); 79 return (PK_ERR_USAGE); 80 } 81 82 /* For a self-signed cert, the issuser and subject are the same */ 83 if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) { 84 cryptoerror(LOG_STDERR, 85 gettext("Subject name cannot be parsed.\n")); 86 return (PK_ERR_USAGE); 87 } 88 89 keylength = keylen; /* bits */ 90 keytype = keyAlg; 91 92 /* Select a PKCS11 token */ 93 kmfrv = select_token(kmfhandle, token, FALSE); 94 95 if (kmfrv != KMF_OK) { 96 return (kmfrv); 97 } 98 99 kmf_set_attr_at_index(attrlist, numattr, 100 KMF_KEYSTORE_TYPE_ATTR, &kstype, 101 sizeof (kstype)); 102 numattr++; 103 104 kmf_set_attr_at_index(attrlist, numattr, 105 KMF_KEYALG_ATTR, &keytype, 106 sizeof (keytype)); 107 numattr++; 108 109 kmf_set_attr_at_index(attrlist, numattr, 110 KMF_KEYLENGTH_ATTR, &keylength, 111 sizeof (keylength)); 112 numattr++; 113 114 if (certlabel != NULL) { 115 kmf_set_attr_at_index(attrlist, numattr, 116 KMF_KEYLABEL_ATTR, certlabel, 117 strlen(certlabel)); 118 numattr++; 119 } 120 121 if (tokencred != NULL && tokencred->credlen > 0) { 122 kmf_set_attr_at_index(attrlist, numattr, 123 KMF_CREDENTIAL_ATTR, tokencred, 124 sizeof (KMF_CREDENTIAL)); 125 numattr++; 126 } 127 128 kmf_set_attr_at_index(attrlist, numattr, 129 KMF_PRIVKEY_HANDLE_ATTR, &prik, 130 sizeof (KMF_KEY_HANDLE)); 131 numattr++; 132 133 kmf_set_attr_at_index(attrlist, numattr, 134 KMF_PUBKEY_HANDLE_ATTR, &pubk, 135 sizeof (KMF_KEY_HANDLE)); 136 numattr++; 137 138 kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 139 if (kmfrv != KMF_OK) { 140 return (kmfrv); 141 } 142 143 SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), 144 "keypair"); 145 146 SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number"); 147 148 SET_VALUE(kmf_set_cert_serial(&signedCert, serial), 149 "serial number"); 150 151 SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime), 152 "validity time"); 153 154 SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg), 155 "signature algorithm"); 156 157 SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject), 158 "subject name"); 159 160 SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer), 161 "issuer name"); 162 163 if (altname != NULL) 164 SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit, 165 alttype, altname), "subjectAltName"); 166 167 if (kubits != 0) 168 SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits), 169 "KeyUsage"); 170 171 /* 172 * Construct attributes for the kmf_sign_cert operation. 173 */ 174 numattr = 0; 175 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 176 &kstype, sizeof (kstype)); 177 numattr++; 178 179 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 180 &prik, sizeof (KMF_KEY_HANDLE_ATTR)); 181 numattr++; 182 183 /* cert data that is to be signed */ 184 kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 185 &signedCert, sizeof (KMF_X509_CERTIFICATE)); 186 numattr++; 187 188 /* output buffer for the signed cert */ 189 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 190 &x509DER, sizeof (KMF_DATA)); 191 numattr++; 192 193 if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) != 194 KMF_OK) { 195 goto cleanup; 196 } 197 198 /* 199 * Store the cert in the DB. 200 */ 201 numattr = 0; 202 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 203 &kstype, sizeof (kstype)); 204 numattr++; 205 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 206 &x509DER, sizeof (KMF_DATA)); 207 numattr++; 208 209 if (certlabel != NULL) { 210 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, 211 certlabel, strlen(certlabel)); 212 numattr++; 213 } 214 215 kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist); 216 217 218 cleanup: 219 kmf_free_data(&x509DER); 220 kmf_free_dn(&certSubject); 221 kmf_free_dn(&certIssuer); 222 return (kmfrv); 223 } 224 225 static int 226 gencert_file(KMF_HANDLE_T kmfhandle, 227 KMF_KEY_ALG keyAlg, KMF_ALGORITHM_INDEX sigAlg, 228 int keylen, KMF_ENCODE_FORMAT fmt, 229 uint32_t ltime, char *subject, char *altname, 230 KMF_GENERALNAMECHOICES alttype, int altcrit, 231 KMF_BIGINT *serial, uint16_t kubits, int kucrit, 232 char *dir, char *outcert, char *outkey) 233 { 234 KMF_RETURN kmfrv; 235 KMF_KEY_HANDLE pubk, prik; 236 KMF_X509_CERTIFICATE signedCert; 237 KMF_X509_NAME certSubject; 238 KMF_X509_NAME certIssuer; 239 KMF_DATA x509DER; 240 char *fullcertpath = NULL; 241 char *fullkeypath = NULL; 242 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 243 KMF_ATTRIBUTE attrlist[10]; 244 int numattr = 0; 245 KMF_KEY_ALG keytype; 246 uint32_t keylength; 247 KMF_ENCODE_FORMAT format; 248 249 (void) memset(&signedCert, 0, sizeof (signedCert)); 250 (void) memset(&certSubject, 0, sizeof (certSubject)); 251 (void) memset(&certIssuer, 0, sizeof (certIssuer)); 252 (void) memset(&x509DER, 0, sizeof (x509DER)); 253 254 if (EMPTYSTRING(outcert) || EMPTYSTRING(outkey)) { 255 cryptoerror(LOG_STDERR, 256 gettext("No output file was specified for " 257 "the cert or key\n")); 258 return (PK_ERR_USAGE); 259 } 260 if (dir != NULL) { 261 fullcertpath = get_fullpath(dir, outcert); 262 if (fullcertpath == NULL) { 263 cryptoerror(LOG_STDERR, 264 gettext("Cannot create file %s in directory %s\n"), 265 dir, outcert); 266 return (PK_ERR_USAGE); 267 } 268 } else { 269 fullcertpath = strdup(outcert); 270 } 271 if (verify_file(fullcertpath)) { 272 cryptoerror(LOG_STDERR, 273 gettext("Cannot write the indicated output " 274 "certificate file (%s).\n"), fullcertpath); 275 free(fullcertpath); 276 return (PK_ERR_USAGE); 277 } 278 if (dir != NULL) { 279 fullkeypath = get_fullpath(dir, outkey); 280 if (fullkeypath == NULL) { 281 cryptoerror(LOG_STDERR, 282 gettext("Cannot create file %s in directory %s\n"), 283 dir, outkey); 284 free(fullcertpath); 285 return (PK_ERR_USAGE); 286 } 287 } else { 288 fullkeypath = strdup(outkey); 289 } 290 if (verify_file(fullkeypath)) { 291 cryptoerror(LOG_STDERR, 292 gettext("Cannot write the indicated output " 293 "key file (%s).\n"), fullkeypath); 294 free(fullkeypath); 295 free(fullcertpath); 296 return (PK_ERR_USAGE); 297 } 298 299 /* If the subject name cannot be parsed, flag it now and exit */ 300 if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { 301 cryptoerror(LOG_STDERR, 302 gettext("Subject name cannot be parsed (%s)\n"), subject); 303 return (PK_ERR_USAGE); 304 } 305 306 /* For a self-signed cert, the issuser and subject are the same */ 307 if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) { 308 cryptoerror(LOG_STDERR, 309 gettext("Subject name cannot be parsed (%s)\n"), subject); 310 kmf_free_dn(&certSubject); 311 return (PK_ERR_USAGE); 312 } 313 314 keylength = keylen; /* bits */ 315 keytype = keyAlg; 316 format = fmt; 317 318 kmf_set_attr_at_index(attrlist, numattr, 319 KMF_KEYSTORE_TYPE_ATTR, &kstype, 320 sizeof (kstype)); 321 numattr++; 322 323 kmf_set_attr_at_index(attrlist, numattr, 324 KMF_KEYALG_ATTR, &keytype, 325 sizeof (keytype)); 326 numattr++; 327 328 kmf_set_attr_at_index(attrlist, numattr, 329 KMF_KEYLENGTH_ATTR, &keylength, 330 sizeof (keylength)); 331 numattr++; 332 333 if (fullkeypath != NULL) { 334 kmf_set_attr_at_index(attrlist, numattr, 335 KMF_KEY_FILENAME_ATTR, fullkeypath, 336 strlen(fullkeypath)); 337 numattr++; 338 } 339 340 kmf_set_attr_at_index(attrlist, numattr, 341 KMF_ENCODE_FORMAT_ATTR, &format, 342 sizeof (format)); 343 numattr++; 344 345 kmf_set_attr_at_index(attrlist, numattr, 346 KMF_PRIVKEY_HANDLE_ATTR, &prik, 347 sizeof (KMF_KEY_HANDLE)); 348 numattr++; 349 350 kmf_set_attr_at_index(attrlist, numattr, 351 KMF_PUBKEY_HANDLE_ATTR, &pubk, 352 sizeof (KMF_KEY_HANDLE)); 353 numattr++; 354 355 kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 356 if (kmfrv != KMF_OK) { 357 goto cleanup; 358 } 359 360 SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), 361 "keypair"); 362 363 SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number"); 364 365 SET_VALUE(kmf_set_cert_serial(&signedCert, serial), 366 "serial number"); 367 368 SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime), 369 "validity time"); 370 371 SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg), 372 "signature algorithm"); 373 374 SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject), 375 "subject name"); 376 377 SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer), 378 "issuer name"); 379 380 if (altname != NULL) 381 SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit, 382 alttype, altname), "subjectAltName"); 383 384 if (kubits != 0) 385 SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits), 386 "KeyUsage"); 387 /* 388 * Construct attributes for the kmf_sign_cert operation. 389 */ 390 numattr = 0; 391 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 392 &kstype, sizeof (kstype)); 393 numattr++; 394 395 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 396 &prik, sizeof (KMF_KEY_HANDLE_ATTR)); 397 numattr++; 398 399 /* cert data that is to be signed */ 400 kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 401 &signedCert, sizeof (KMF_X509_CERTIFICATE)); 402 numattr++; 403 404 /* output buffer for the signed cert */ 405 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 406 &x509DER, sizeof (KMF_DATA)); 407 numattr++; 408 409 if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) != 410 KMF_OK) { 411 goto cleanup; 412 } 413 414 /* 415 * Store the cert in the DB. 416 */ 417 numattr = 0; 418 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 419 &kstype, sizeof (kstype)); 420 numattr++; 421 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 422 &x509DER, sizeof (KMF_DATA)); 423 numattr++; 424 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR, 425 fullcertpath, strlen(fullcertpath)); 426 numattr++; 427 kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 428 &fmt, sizeof (fmt)); 429 numattr++; 430 431 kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist); 432 433 cleanup: 434 if (fullkeypath != NULL) 435 free(fullkeypath); 436 if (fullcertpath != NULL) 437 free(fullcertpath); 438 439 kmf_free_data(&x509DER); 440 kmf_free_dn(&certSubject); 441 kmf_free_dn(&certIssuer); 442 return (kmfrv); 443 } 444 445 static KMF_RETURN 446 gencert_nss(KMF_HANDLE_T kmfhandle, 447 char *token, char *subject, char *altname, 448 KMF_GENERALNAMECHOICES alttype, int altcrit, 449 char *nickname, char *dir, char *prefix, 450 KMF_KEY_ALG keyAlg, 451 KMF_ALGORITHM_INDEX sigAlg, 452 int keylen, char *trust, 453 uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits, 454 int kucrit, KMF_CREDENTIAL *tokencred) 455 { 456 KMF_RETURN kmfrv; 457 KMF_KEY_HANDLE pubk, prik; 458 KMF_X509_CERTIFICATE signedCert; 459 KMF_X509_NAME certSubject; 460 KMF_X509_NAME certIssuer; 461 KMF_DATA x509DER; 462 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 463 KMF_ATTRIBUTE attrlist[16]; 464 int numattr = 0; 465 KMF_KEY_ALG keytype; 466 uint32_t keylength; 467 468 if (token == NULL) 469 token = DEFAULT_NSS_TOKEN; 470 471 kmfrv = configure_nss(kmfhandle, dir, prefix); 472 if (kmfrv != KMF_OK) 473 return (kmfrv); 474 475 (void) memset(&signedCert, 0, sizeof (signedCert)); 476 (void) memset(&certSubject, 0, sizeof (certSubject)); 477 (void) memset(&certIssuer, 0, sizeof (certIssuer)); 478 (void) memset(&x509DER, 0, sizeof (x509DER)); 479 480 /* If the subject name cannot be parsed, flag it now and exit */ 481 if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { 482 cryptoerror(LOG_STDERR, 483 gettext("Subject name cannot be parsed.\n")); 484 return (PK_ERR_USAGE); 485 } 486 487 /* For a self-signed cert, the issuser and subject are the same */ 488 if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) { 489 cryptoerror(LOG_STDERR, 490 gettext("Subject name cannot be parsed.\n")); 491 return (PK_ERR_USAGE); 492 } 493 494 keylength = keylen; /* bits */ 495 keytype = keyAlg; 496 497 kmf_set_attr_at_index(attrlist, numattr, 498 KMF_KEYSTORE_TYPE_ATTR, &kstype, 499 sizeof (kstype)); 500 numattr++; 501 502 kmf_set_attr_at_index(attrlist, numattr, 503 KMF_KEYALG_ATTR, &keytype, 504 sizeof (keytype)); 505 numattr++; 506 507 kmf_set_attr_at_index(attrlist, numattr, 508 KMF_KEYLENGTH_ATTR, &keylength, 509 sizeof (keylength)); 510 numattr++; 511 512 if (nickname != NULL) { 513 kmf_set_attr_at_index(attrlist, numattr, 514 KMF_KEYLABEL_ATTR, nickname, 515 strlen(nickname)); 516 numattr++; 517 } 518 519 if (tokencred != NULL && tokencred->credlen > 0) { 520 kmf_set_attr_at_index(attrlist, numattr, 521 KMF_CREDENTIAL_ATTR, tokencred, 522 sizeof (KMF_CREDENTIAL)); 523 numattr++; 524 } 525 526 if (token != NULL) { 527 kmf_set_attr_at_index(attrlist, numattr, 528 KMF_TOKEN_LABEL_ATTR, token, 529 strlen(token)); 530 numattr++; 531 } 532 533 kmf_set_attr_at_index(attrlist, numattr, 534 KMF_PRIVKEY_HANDLE_ATTR, &prik, 535 sizeof (KMF_KEY_HANDLE)); 536 numattr++; 537 538 kmf_set_attr_at_index(attrlist, numattr, 539 KMF_PUBKEY_HANDLE_ATTR, &pubk, 540 sizeof (KMF_KEY_HANDLE)); 541 numattr++; 542 543 kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 544 if (kmfrv != KMF_OK) { 545 return (kmfrv); 546 } 547 548 SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), 549 "keypair"); 550 551 SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number"); 552 553 SET_VALUE(kmf_set_cert_serial(&signedCert, serial), 554 "serial number"); 555 556 SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime), 557 "validity time"); 558 559 SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg), 560 "signature algorithm"); 561 562 SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject), 563 "subject name"); 564 565 SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer), 566 "issuer name"); 567 568 if (altname != NULL) 569 SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit, 570 alttype, altname), "subjectAltName"); 571 572 if (kubits) 573 SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits), 574 "subjectAltName"); 575 576 /* 577 * Construct attributes for the kmf_sign_cert operation. 578 */ 579 numattr = 0; 580 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 581 &kstype, sizeof (kstype)); 582 numattr++; 583 584 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 585 &prik, sizeof (KMF_KEY_HANDLE_ATTR)); 586 numattr++; 587 588 /* cert data that is to be signed */ 589 kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 590 &signedCert, sizeof (KMF_X509_CERTIFICATE)); 591 numattr++; 592 593 /* output buffer for the signed cert */ 594 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 595 &x509DER, sizeof (KMF_DATA)); 596 numattr++; 597 598 if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) != 599 KMF_OK) { 600 goto cleanup; 601 } 602 603 /* 604 * Store the cert in the DB. 605 */ 606 numattr = 0; 607 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 608 &kstype, sizeof (kstype)); 609 numattr++; 610 611 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 612 &x509DER, sizeof (KMF_DATA)); 613 numattr++; 614 615 if (nickname != NULL) { 616 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, 617 nickname, strlen(nickname)); 618 numattr++; 619 } 620 621 if (trust != NULL) { 622 kmf_set_attr_at_index(attrlist, numattr, KMF_TRUSTFLAG_ATTR, 623 trust, strlen(trust)); 624 numattr++; 625 } 626 627 if (token != NULL) { 628 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 629 token, strlen(token)); 630 numattr++; 631 } 632 633 kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist); 634 635 cleanup: 636 kmf_free_data(&x509DER); 637 kmf_free_dn(&certSubject); 638 kmf_free_dn(&certIssuer); 639 return (kmfrv); 640 } 641 642 int 643 pk_gencert(int argc, char *argv[]) 644 { 645 int rv; 646 int opt; 647 extern int optind_av; 648 extern char *optarg_av; 649 KMF_KEYSTORE_TYPE kstype = 0; 650 char *subject = NULL; 651 char *tokenname = NULL; 652 char *dir = NULL; 653 char *prefix = NULL; 654 char *keytype = PK_DEFAULT_KEYTYPE; 655 int keylen = PK_DEFAULT_KEYLENGTH; 656 char *trust = NULL; 657 char *lifetime = NULL; 658 char *certlabel = NULL; 659 char *outcert = NULL; 660 char *outkey = NULL; 661 char *format = NULL; 662 char *serstr = NULL; 663 char *altname = NULL; 664 char *keyusagestr = NULL; 665 KMF_GENERALNAMECHOICES alttype = 0; 666 KMF_BIGINT serial = { NULL, 0 }; 667 uint32_t ltime; 668 KMF_HANDLE_T kmfhandle = NULL; 669 KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1; 670 KMF_KEY_ALG keyAlg = KMF_RSA; 671 KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_MD5WithRSA; 672 boolean_t interactive = B_FALSE; 673 char *subname = NULL; 674 KMF_CREDENTIAL tokencred = {NULL, 0}; 675 uint16_t kubits = 0; 676 int altcrit = 0, kucrit = 0; 677 678 while ((opt = getopt_av(argc, argv, 679 "ik:(keystore)s:(subject)n:(nickname)A:(altname)" 680 "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)" 681 "r:(trust)L:(lifetime)l:(label)c:(outcert)" 682 "K:(outkey)S:(serial)F:(format)u:(keyusage)")) != EOF) { 683 684 if (opt != 'i' && EMPTYSTRING(optarg_av)) 685 return (PK_ERR_USAGE); 686 687 switch (opt) { 688 case 'A': 689 altname = optarg_av; 690 break; 691 case 'i': 692 if (interactive || subject) 693 return (PK_ERR_USAGE); 694 else 695 interactive = B_TRUE; 696 break; 697 case 'k': 698 kstype = KS2Int(optarg_av); 699 if (kstype == 0) 700 return (PK_ERR_USAGE); 701 break; 702 case 's': 703 if (interactive || subject) 704 return (PK_ERR_USAGE); 705 else 706 subject = optarg_av; 707 break; 708 case 'l': 709 case 'n': 710 if (certlabel) 711 return (PK_ERR_USAGE); 712 certlabel = optarg_av; 713 break; 714 case 'T': 715 if (tokenname) 716 return (PK_ERR_USAGE); 717 tokenname = optarg_av; 718 break; 719 case 'd': 720 if (dir) 721 return (PK_ERR_USAGE); 722 dir = optarg_av; 723 break; 724 case 'p': 725 if (prefix) 726 return (PK_ERR_USAGE); 727 prefix = optarg_av; 728 break; 729 case 't': 730 keytype = optarg_av; 731 break; 732 case 'u': 733 keyusagestr = optarg_av; 734 break; 735 case 'y': 736 if (sscanf(optarg_av, "%d", 737 &keylen) != 1) { 738 cryptoerror(LOG_STDERR, 739 gettext("key length must be" 740 "a numeric value (%s)\n"), 741 optarg_av); 742 return (PK_ERR_USAGE); 743 } 744 break; 745 case 'r': 746 if (trust) 747 return (PK_ERR_USAGE); 748 trust = optarg_av; 749 break; 750 case 'L': 751 if (lifetime) 752 return (PK_ERR_USAGE); 753 lifetime = optarg_av; 754 break; 755 case 'c': 756 if (outcert) 757 return (PK_ERR_USAGE); 758 outcert = optarg_av; 759 break; 760 case 'K': 761 if (outkey) 762 return (PK_ERR_USAGE); 763 outkey = optarg_av; 764 break; 765 case 'S': 766 serstr = optarg_av; 767 break; 768 case 'F': 769 if (format) 770 return (PK_ERR_USAGE); 771 format = optarg_av; 772 break; 773 default: 774 return (PK_ERR_USAGE); 775 } 776 } 777 778 /* No additional args allowed. */ 779 argc -= optind_av; 780 argv += optind_av; 781 if (argc) { 782 return (PK_ERR_USAGE); 783 } 784 785 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 786 cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n")); 787 return (PK_ERR_USAGE); 788 } 789 790 /* Assume keystore = PKCS#11 if not specified. */ 791 if (kstype == 0) 792 kstype = KMF_KEYSTORE_PK11TOKEN; 793 794 if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) { 795 if (interactive && EMPTYSTRING(certlabel)) { 796 (void) get_certlabel(&certlabel); 797 } 798 /* It better not be empty now */ 799 if (EMPTYSTRING(certlabel)) { 800 cryptoerror(LOG_STDERR, gettext("A label must be " 801 "specified to create a self-signed certificate." 802 "\n")); 803 return (PK_ERR_USAGE); 804 } 805 } else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outcert)) { 806 cryptoerror(LOG_STDERR, gettext("A certificate filename must " 807 "be specified to create a self-signed certificate.\n")); 808 return (PK_ERR_USAGE); 809 } 810 811 if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) { 812 cryptoerror(LOG_STDERR, 813 gettext("Error parsing format string (%s).\n"), 814 format); 815 return (PK_ERR_USAGE); 816 } 817 818 if (Str2Lifetime(lifetime, <ime) != 0) { 819 cryptoerror(LOG_STDERR, 820 gettext("Error parsing lifetime string\n")); 821 return (PK_ERR_USAGE); 822 } 823 824 if (Str2KeyType(keytype, &keyAlg, &sigAlg) != 0) { 825 cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"), 826 keytype); 827 return (PK_ERR_USAGE); 828 } 829 830 /* 831 * Check the subject name. 832 * If interactive is true, get it now interactively. 833 */ 834 if (interactive) { 835 subname = NULL; 836 if (get_subname(&subname) != KMF_OK || subname == NULL) { 837 cryptoerror(LOG_STDERR, gettext("Failed to get the " 838 "subject name interactively.\n")); 839 return (PK_ERR_USAGE); 840 } 841 if (serstr == NULL) { 842 (void) get_serial(&serstr); 843 } 844 } else { 845 if (EMPTYSTRING(subject)) { 846 cryptoerror(LOG_STDERR, gettext("A subject name or " 847 "-i must be specified to create a self-signed " 848 "certificate.\n")); 849 return (PK_ERR_USAGE); 850 } else { 851 subname = strdup(subject); 852 if (subname == NULL) { 853 cryptoerror(LOG_STDERR, 854 gettext("Out of memory.\n")); 855 return (PK_ERR_SYSTEM); 856 } 857 } 858 } 859 860 if (serstr == NULL) { 861 (void) fprintf(stderr, gettext("A serial number " 862 "must be specified as a hex number when creating" 863 " a self-signed certificate " 864 "(ex: serial=0x0102030405feedface)\n")); 865 rv = PK_ERR_USAGE; 866 goto end; 867 } else { 868 uchar_t *bytes = NULL; 869 size_t bytelen; 870 871 rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); 872 if (rv != KMF_OK || bytes == NULL) { 873 (void) fprintf(stderr, gettext("serial number " 874 "must be specified as a hex number " 875 "(ex: 0x0102030405ffeeddee)\n")); 876 rv = PK_ERR_USAGE; 877 goto end; 878 } 879 serial.val = bytes; 880 serial.len = bytelen; 881 } 882 883 if (altname != NULL) { 884 rv = verify_altname(altname, &alttype, &altcrit); 885 if (rv != KMF_OK) { 886 (void) fprintf(stderr, gettext("Subject AltName " 887 "must be specified as a name=value pair. " 888 "See the man page for details.\n")); 889 rv = PK_ERR_USAGE; 890 goto end; 891 } else { 892 /* advance the altname past the '=' sign */ 893 char *p = strchr(altname, '='); 894 if (p != NULL) 895 altname = p + 1; 896 } 897 } 898 899 if (keyusagestr != NULL) { 900 rv = verify_keyusage(keyusagestr, &kubits, &kucrit); 901 if (rv != KMF_OK) { 902 (void) fprintf(stderr, gettext("KeyUsage " 903 "must be specified as a comma-separated list. " 904 "See the man page for details.\n")); 905 rv = PK_ERR_USAGE; 906 goto end; 907 } 908 } 909 910 if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { 911 if (tokenname == NULL || !strlen(tokenname)) { 912 if (kstype == KMF_KEYSTORE_NSS) { 913 tokenname = "internal"; 914 } else { 915 tokenname = PK_DEFAULT_PK11TOKEN; 916 } 917 } 918 919 (void) get_token_password(kstype, tokenname, &tokencred); 920 } 921 922 if (kstype == KMF_KEYSTORE_NSS) { 923 if (dir == NULL) 924 dir = PK_DEFAULT_DIRECTORY; 925 926 rv = gencert_nss(kmfhandle, 927 tokenname, subname, altname, alttype, altcrit, 928 certlabel, dir, prefix, keyAlg, sigAlg, keylen, 929 trust, ltime, &serial, kubits, kucrit, &tokencred); 930 931 } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { 932 rv = gencert_pkcs11(kmfhandle, 933 tokenname, subname, altname, alttype, altcrit, 934 certlabel, keyAlg, sigAlg, keylen, ltime, 935 &serial, kubits, kucrit, &tokencred); 936 937 } else if (kstype == KMF_KEYSTORE_OPENSSL) { 938 rv = gencert_file(kmfhandle, 939 keyAlg, sigAlg, keylen, fmt, 940 ltime, subname, altname, alttype, altcrit, 941 &serial, kubits, kucrit, dir, outcert, outkey); 942 } 943 944 if (rv != KMF_OK) 945 display_error(kmfhandle, rv, 946 gettext("Error creating certificate and keypair")); 947 end: 948 if (subname) 949 free(subname); 950 if (tokencred.cred != NULL) 951 free(tokencred.cred); 952 953 if (serial.val != NULL) 954 free(serial.val); 955 956 (void) kmf_finalize(kmfhandle); 957 return (rv); 958 } 959