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