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