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->credlen > 0) { 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 *dir, 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 if (dir != NULL) { 272 fullcertpath = get_fullpath(dir, outcert); 273 if (fullcertpath == NULL) { 274 cryptoerror(LOG_STDERR, 275 gettext("Cannot create file %s in directory %s\n"), 276 dir, outcert); 277 return (PK_ERR_USAGE); 278 } 279 } else { 280 fullcertpath = strdup(outcert); 281 } 282 if (verify_file(fullcertpath)) { 283 cryptoerror(LOG_STDERR, 284 gettext("Cannot write the indicated output " 285 "certificate file (%s).\n"), fullcertpath); 286 free(fullcertpath); 287 return (PK_ERR_USAGE); 288 } 289 if (dir != NULL) { 290 fullkeypath = get_fullpath(dir, outkey); 291 if (fullkeypath == NULL) { 292 cryptoerror(LOG_STDERR, 293 gettext("Cannot create file %s in directory %s\n"), 294 dir, outkey); 295 free(fullcertpath); 296 return (PK_ERR_USAGE); 297 } 298 } else { 299 fullkeypath = strdup(outkey); 300 } 301 if (verify_file(fullkeypath)) { 302 cryptoerror(LOG_STDERR, 303 gettext("Cannot write the indicated output " 304 "key file (%s).\n"), fullkeypath); 305 free(fullkeypath); 306 free(fullcertpath); 307 return (PK_ERR_USAGE); 308 } 309 310 /* If the subject name cannot be parsed, flag it now and exit */ 311 if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { 312 cryptoerror(LOG_STDERR, 313 gettext("Subject name cannot be parsed (%s)\n"), subject); 314 return (PK_ERR_USAGE); 315 } 316 317 /* For a self-signed cert, the issuser and subject are the same */ 318 if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) { 319 cryptoerror(LOG_STDERR, 320 gettext("Subject name cannot be parsed (%s)\n"), subject); 321 kmf_free_dn(&certSubject); 322 return (PK_ERR_USAGE); 323 } 324 325 keylength = keylen; /* bits */ 326 keytype = keyAlg; 327 format = fmt; 328 329 kmf_set_attr_at_index(attrlist, numattr, 330 KMF_KEYSTORE_TYPE_ATTR, &kstype, 331 sizeof (kstype)); 332 numattr++; 333 334 kmf_set_attr_at_index(attrlist, numattr, 335 KMF_KEYALG_ATTR, &keytype, 336 sizeof (keytype)); 337 numattr++; 338 339 kmf_set_attr_at_index(attrlist, numattr, 340 KMF_KEYLENGTH_ATTR, &keylength, 341 sizeof (keylength)); 342 numattr++; 343 344 if (fullkeypath != NULL) { 345 kmf_set_attr_at_index(attrlist, numattr, 346 KMF_KEY_FILENAME_ATTR, fullkeypath, 347 strlen(fullkeypath)); 348 numattr++; 349 } 350 351 kmf_set_attr_at_index(attrlist, numattr, 352 KMF_ENCODE_FORMAT_ATTR, &format, 353 sizeof (format)); 354 numattr++; 355 356 kmf_set_attr_at_index(attrlist, numattr, 357 KMF_PRIVKEY_HANDLE_ATTR, &prik, 358 sizeof (KMF_KEY_HANDLE)); 359 numattr++; 360 361 kmf_set_attr_at_index(attrlist, numattr, 362 KMF_PUBKEY_HANDLE_ATTR, &pubk, 363 sizeof (KMF_KEY_HANDLE)); 364 numattr++; 365 366 kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 367 if (kmfrv != KMF_OK) { 368 goto cleanup; 369 } 370 371 SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), 372 "keypair"); 373 374 SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number"); 375 376 SET_VALUE(kmf_set_cert_serial(&signedCert, serial), 377 "serial number"); 378 379 SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime), 380 "validity time"); 381 382 SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg), 383 "signature algorithm"); 384 385 SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject), 386 "subject name"); 387 388 SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer), 389 "issuer name"); 390 391 if (altname != NULL) 392 SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit, 393 alttype, altname), "subjectAltName"); 394 395 if (kubits != 0) 396 SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits), 397 "KeyUsage"); 398 399 if (ekulist != NULL) { 400 int i; 401 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 402 SET_VALUE(kmf_add_cert_eku(&signedCert, 403 &ekulist->ekulist[i], 404 ekulist->critlist[i]), "Extended Key Usage"); 405 } 406 } 407 /* 408 * Construct attributes for the kmf_sign_cert operation. 409 */ 410 numattr = 0; 411 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 412 &kstype, sizeof (kstype)); 413 numattr++; 414 415 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 416 &prik, sizeof (KMF_KEY_HANDLE_ATTR)); 417 numattr++; 418 419 /* cert data that is to be signed */ 420 kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 421 &signedCert, sizeof (KMF_X509_CERTIFICATE)); 422 numattr++; 423 424 /* output buffer for the signed cert */ 425 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 426 &x509DER, sizeof (KMF_DATA)); 427 numattr++; 428 429 if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) != 430 KMF_OK) { 431 goto cleanup; 432 } 433 434 /* 435 * Store the cert in the DB. 436 */ 437 numattr = 0; 438 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 439 &kstype, sizeof (kstype)); 440 numattr++; 441 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 442 &x509DER, sizeof (KMF_DATA)); 443 numattr++; 444 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR, 445 fullcertpath, strlen(fullcertpath)); 446 numattr++; 447 kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 448 &fmt, sizeof (fmt)); 449 numattr++; 450 451 kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist); 452 453 cleanup: 454 if (fullkeypath != NULL) 455 free(fullkeypath); 456 if (fullcertpath != NULL) 457 free(fullcertpath); 458 459 kmf_free_data(&x509DER); 460 kmf_free_dn(&certSubject); 461 kmf_free_dn(&certIssuer); 462 return (kmfrv); 463 } 464 465 static KMF_RETURN 466 gencert_nss(KMF_HANDLE_T kmfhandle, 467 char *token, char *subject, char *altname, 468 KMF_GENERALNAMECHOICES alttype, int altcrit, 469 char *nickname, char *dir, char *prefix, 470 KMF_KEY_ALG keyAlg, 471 KMF_ALGORITHM_INDEX sigAlg, 472 int keylen, char *trust, 473 uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits, 474 int kucrit, KMF_CREDENTIAL *tokencred, 475 EKU_LIST *ekulist) 476 { 477 KMF_RETURN kmfrv; 478 KMF_KEY_HANDLE pubk, prik; 479 KMF_X509_CERTIFICATE signedCert; 480 KMF_X509_NAME certSubject; 481 KMF_X509_NAME certIssuer; 482 KMF_DATA x509DER; 483 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 484 KMF_ATTRIBUTE attrlist[16]; 485 int numattr = 0; 486 KMF_KEY_ALG keytype; 487 uint32_t keylength; 488 489 if (token == NULL) 490 token = DEFAULT_NSS_TOKEN; 491 492 kmfrv = configure_nss(kmfhandle, dir, prefix); 493 if (kmfrv != KMF_OK) 494 return (kmfrv); 495 496 (void) memset(&signedCert, 0, sizeof (signedCert)); 497 (void) memset(&certSubject, 0, sizeof (certSubject)); 498 (void) memset(&certIssuer, 0, sizeof (certIssuer)); 499 (void) memset(&x509DER, 0, sizeof (x509DER)); 500 501 /* If the subject name cannot be parsed, flag it now and exit */ 502 if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { 503 cryptoerror(LOG_STDERR, 504 gettext("Subject name cannot be parsed.\n")); 505 return (PK_ERR_USAGE); 506 } 507 508 /* For a self-signed cert, the issuser and subject are the same */ 509 if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) { 510 cryptoerror(LOG_STDERR, 511 gettext("Subject name cannot be parsed.\n")); 512 return (PK_ERR_USAGE); 513 } 514 515 keylength = keylen; /* bits */ 516 keytype = keyAlg; 517 518 kmf_set_attr_at_index(attrlist, numattr, 519 KMF_KEYSTORE_TYPE_ATTR, &kstype, 520 sizeof (kstype)); 521 numattr++; 522 523 kmf_set_attr_at_index(attrlist, numattr, 524 KMF_KEYALG_ATTR, &keytype, 525 sizeof (keytype)); 526 numattr++; 527 528 kmf_set_attr_at_index(attrlist, numattr, 529 KMF_KEYLENGTH_ATTR, &keylength, 530 sizeof (keylength)); 531 numattr++; 532 533 if (nickname != NULL) { 534 kmf_set_attr_at_index(attrlist, numattr, 535 KMF_KEYLABEL_ATTR, nickname, 536 strlen(nickname)); 537 numattr++; 538 } 539 540 if (tokencred != NULL && tokencred->credlen > 0) { 541 kmf_set_attr_at_index(attrlist, numattr, 542 KMF_CREDENTIAL_ATTR, tokencred, 543 sizeof (KMF_CREDENTIAL)); 544 numattr++; 545 } 546 547 if (token != NULL) { 548 kmf_set_attr_at_index(attrlist, numattr, 549 KMF_TOKEN_LABEL_ATTR, token, 550 strlen(token)); 551 numattr++; 552 } 553 554 kmf_set_attr_at_index(attrlist, numattr, 555 KMF_PRIVKEY_HANDLE_ATTR, &prik, 556 sizeof (KMF_KEY_HANDLE)); 557 numattr++; 558 559 kmf_set_attr_at_index(attrlist, numattr, 560 KMF_PUBKEY_HANDLE_ATTR, &pubk, 561 sizeof (KMF_KEY_HANDLE)); 562 numattr++; 563 564 kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 565 if (kmfrv != KMF_OK) { 566 return (kmfrv); 567 } 568 569 SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), 570 "keypair"); 571 572 SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number"); 573 574 SET_VALUE(kmf_set_cert_serial(&signedCert, serial), 575 "serial number"); 576 577 SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime), 578 "validity time"); 579 580 SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg), 581 "signature algorithm"); 582 583 SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject), 584 "subject name"); 585 586 SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer), 587 "issuer name"); 588 589 if (altname != NULL) 590 SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit, 591 alttype, altname), "subjectAltName"); 592 593 if (kubits) 594 SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits), 595 "subjectAltName"); 596 597 if (ekulist != NULL) { 598 int i; 599 for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 600 SET_VALUE(kmf_add_cert_eku(&signedCert, 601 &ekulist->ekulist[i], 602 ekulist->critlist[i]), "Extended Key Usage"); 603 } 604 } 605 /* 606 * Construct attributes for the kmf_sign_cert operation. 607 */ 608 numattr = 0; 609 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 610 &kstype, sizeof (kstype)); 611 numattr++; 612 613 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 614 &prik, sizeof (KMF_KEY_HANDLE_ATTR)); 615 numattr++; 616 617 /* cert data that is to be signed */ 618 kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 619 &signedCert, sizeof (KMF_X509_CERTIFICATE)); 620 numattr++; 621 622 /* output buffer for the signed cert */ 623 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 624 &x509DER, sizeof (KMF_DATA)); 625 numattr++; 626 627 if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) != 628 KMF_OK) { 629 goto cleanup; 630 } 631 632 /* 633 * Store the cert in the DB. 634 */ 635 numattr = 0; 636 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 637 &kstype, sizeof (kstype)); 638 numattr++; 639 640 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 641 &x509DER, sizeof (KMF_DATA)); 642 numattr++; 643 644 if (nickname != NULL) { 645 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, 646 nickname, strlen(nickname)); 647 numattr++; 648 } 649 650 if (trust != NULL) { 651 kmf_set_attr_at_index(attrlist, numattr, KMF_TRUSTFLAG_ATTR, 652 trust, strlen(trust)); 653 numattr++; 654 } 655 656 if (token != NULL) { 657 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 658 token, strlen(token)); 659 numattr++; 660 } 661 662 kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist); 663 664 cleanup: 665 kmf_free_data(&x509DER); 666 kmf_free_dn(&certSubject); 667 kmf_free_dn(&certIssuer); 668 return (kmfrv); 669 } 670 671 int 672 pk_gencert(int argc, char *argv[]) 673 { 674 int rv; 675 int opt; 676 extern int optind_av; 677 extern char *optarg_av; 678 KMF_KEYSTORE_TYPE kstype = 0; 679 char *subject = NULL; 680 char *tokenname = NULL; 681 char *dir = NULL; 682 char *prefix = NULL; 683 char *keytype = PK_DEFAULT_KEYTYPE; 684 int keylen = PK_DEFAULT_KEYLENGTH; 685 char *trust = NULL; 686 char *lifetime = NULL; 687 char *certlabel = NULL; 688 char *outcert = NULL; 689 char *outkey = NULL; 690 char *format = NULL; 691 char *serstr = NULL; 692 char *altname = NULL; 693 char *keyusagestr = NULL; 694 char *ekustr = NULL; 695 KMF_GENERALNAMECHOICES alttype = 0; 696 KMF_BIGINT serial = { NULL, 0 }; 697 uint32_t ltime; 698 KMF_HANDLE_T kmfhandle = NULL; 699 KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1; 700 KMF_KEY_ALG keyAlg = KMF_RSA; 701 KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_MD5WithRSA; 702 boolean_t interactive = B_FALSE; 703 char *subname = NULL; 704 KMF_CREDENTIAL tokencred = {NULL, 0}; 705 uint16_t kubits = 0; 706 int altcrit = 0, kucrit = 0; 707 EKU_LIST *ekulist = NULL; 708 709 while ((opt = getopt_av(argc, argv, 710 "ik:(keystore)s:(subject)n:(nickname)A:(altname)" 711 "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)" 712 "r:(trust)L:(lifetime)l:(label)c:(outcert)e:(eku)" 713 "K:(outkey)S:(serial)F:(format)u:(keyusage)")) != EOF) { 714 715 if (opt != 'i' && EMPTYSTRING(optarg_av)) 716 return (PK_ERR_USAGE); 717 718 switch (opt) { 719 case 'A': 720 altname = optarg_av; 721 break; 722 case 'i': 723 if (interactive || subject) 724 return (PK_ERR_USAGE); 725 else 726 interactive = B_TRUE; 727 break; 728 case 'k': 729 kstype = KS2Int(optarg_av); 730 if (kstype == 0) 731 return (PK_ERR_USAGE); 732 break; 733 case 's': 734 if (interactive || subject) 735 return (PK_ERR_USAGE); 736 else 737 subject = optarg_av; 738 break; 739 case 'l': 740 case 'n': 741 if (certlabel) 742 return (PK_ERR_USAGE); 743 certlabel = optarg_av; 744 break; 745 case 'T': 746 if (tokenname) 747 return (PK_ERR_USAGE); 748 tokenname = optarg_av; 749 break; 750 case 'd': 751 if (dir) 752 return (PK_ERR_USAGE); 753 dir = optarg_av; 754 break; 755 case 'p': 756 if (prefix) 757 return (PK_ERR_USAGE); 758 prefix = optarg_av; 759 break; 760 case 't': 761 keytype = optarg_av; 762 break; 763 case 'u': 764 keyusagestr = optarg_av; 765 break; 766 case 'y': 767 if (sscanf(optarg_av, "%d", 768 &keylen) != 1) { 769 cryptoerror(LOG_STDERR, 770 gettext("key length must be" 771 "a numeric value (%s)\n"), 772 optarg_av); 773 return (PK_ERR_USAGE); 774 } 775 break; 776 case 'r': 777 if (trust) 778 return (PK_ERR_USAGE); 779 trust = optarg_av; 780 break; 781 case 'L': 782 if (lifetime) 783 return (PK_ERR_USAGE); 784 lifetime = optarg_av; 785 break; 786 case 'c': 787 if (outcert) 788 return (PK_ERR_USAGE); 789 outcert = optarg_av; 790 break; 791 case 'K': 792 if (outkey) 793 return (PK_ERR_USAGE); 794 outkey = optarg_av; 795 break; 796 case 'S': 797 serstr = optarg_av; 798 break; 799 case 'F': 800 if (format) 801 return (PK_ERR_USAGE); 802 format = optarg_av; 803 break; 804 case 'e': 805 ekustr = optarg_av; 806 break; 807 default: 808 return (PK_ERR_USAGE); 809 } 810 } 811 812 /* No additional args allowed. */ 813 argc -= optind_av; 814 argv += optind_av; 815 if (argc) { 816 return (PK_ERR_USAGE); 817 } 818 819 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 820 cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n")); 821 return (PK_ERR_USAGE); 822 } 823 824 /* Assume keystore = PKCS#11 if not specified. */ 825 if (kstype == 0) 826 kstype = KMF_KEYSTORE_PK11TOKEN; 827 828 if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) { 829 if (interactive && EMPTYSTRING(certlabel)) { 830 (void) get_certlabel(&certlabel); 831 } 832 /* It better not be empty now */ 833 if (EMPTYSTRING(certlabel)) { 834 cryptoerror(LOG_STDERR, gettext("A label must be " 835 "specified to create a self-signed certificate." 836 "\n")); 837 return (PK_ERR_USAGE); 838 } 839 } else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outcert)) { 840 cryptoerror(LOG_STDERR, gettext("A certificate filename must " 841 "be specified to create a self-signed certificate.\n")); 842 return (PK_ERR_USAGE); 843 } 844 845 if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) { 846 cryptoerror(LOG_STDERR, 847 gettext("Error parsing format string (%s).\n"), 848 format); 849 return (PK_ERR_USAGE); 850 } 851 852 if (Str2Lifetime(lifetime, <ime) != 0) { 853 cryptoerror(LOG_STDERR, 854 gettext("Error parsing lifetime string\n")); 855 return (PK_ERR_USAGE); 856 } 857 858 if (Str2KeyType(keytype, &keyAlg, &sigAlg) != 0) { 859 cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"), 860 keytype); 861 return (PK_ERR_USAGE); 862 } 863 864 /* 865 * Check the subject name. 866 * If interactive is true, get it now interactively. 867 */ 868 if (interactive) { 869 subname = NULL; 870 if (get_subname(&subname) != KMF_OK || subname == NULL) { 871 cryptoerror(LOG_STDERR, gettext("Failed to get the " 872 "subject name interactively.\n")); 873 return (PK_ERR_USAGE); 874 } 875 if (serstr == NULL) { 876 (void) get_serial(&serstr); 877 } 878 } else { 879 if (EMPTYSTRING(subject)) { 880 cryptoerror(LOG_STDERR, gettext("A subject name or " 881 "-i must be specified to create a self-signed " 882 "certificate.\n")); 883 return (PK_ERR_USAGE); 884 } else { 885 subname = strdup(subject); 886 if (subname == NULL) { 887 cryptoerror(LOG_STDERR, 888 gettext("Out of memory.\n")); 889 return (PK_ERR_SYSTEM); 890 } 891 } 892 } 893 894 if (serstr == NULL) { 895 (void) fprintf(stderr, gettext("A serial number " 896 "must be specified as a hex number when creating" 897 " a self-signed certificate " 898 "(ex: serial=0x0102030405feedface)\n")); 899 rv = PK_ERR_USAGE; 900 goto end; 901 } else { 902 uchar_t *bytes = NULL; 903 size_t bytelen; 904 905 rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); 906 if (rv != KMF_OK || bytes == NULL) { 907 (void) fprintf(stderr, gettext("serial number " 908 "must be specified as a hex number " 909 "(ex: 0x0102030405ffeeddee)\n")); 910 rv = PK_ERR_USAGE; 911 goto end; 912 } 913 serial.val = bytes; 914 serial.len = bytelen; 915 } 916 917 if (altname != NULL) { 918 rv = verify_altname(altname, &alttype, &altcrit); 919 if (rv != KMF_OK) { 920 (void) fprintf(stderr, gettext("Subject AltName " 921 "must be specified as a name=value pair. " 922 "See the man page for details.\n")); 923 rv = PK_ERR_USAGE; 924 goto end; 925 } else { 926 /* advance the altname past the '=' sign */ 927 char *p = strchr(altname, '='); 928 if (p != NULL) 929 altname = p + 1; 930 } 931 } 932 933 if (keyusagestr != NULL) { 934 rv = verify_keyusage(keyusagestr, &kubits, &kucrit); 935 if (rv != KMF_OK) { 936 (void) fprintf(stderr, gettext("KeyUsage " 937 "must be specified as a comma-separated list. " 938 "See the man page for details.\n")); 939 rv = PK_ERR_USAGE; 940 goto end; 941 } 942 } 943 if (ekustr != NULL) { 944 rv = verify_ekunames(ekustr, &ekulist); 945 if (rv != KMF_OK) { 946 (void) fprintf(stderr, gettext("EKUs must " 947 "be specified as a comma-separated list. " 948 "See the man page for details.\n")); 949 rv = PK_ERR_USAGE; 950 goto end; 951 } 952 } 953 954 if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { 955 if (tokenname == NULL || !strlen(tokenname)) { 956 if (kstype == KMF_KEYSTORE_NSS) { 957 tokenname = "internal"; 958 } else { 959 tokenname = PK_DEFAULT_PK11TOKEN; 960 } 961 } 962 963 (void) get_token_password(kstype, tokenname, &tokencred); 964 } 965 966 if (kstype == KMF_KEYSTORE_NSS) { 967 if (dir == NULL) 968 dir = PK_DEFAULT_DIRECTORY; 969 970 rv = gencert_nss(kmfhandle, 971 tokenname, subname, altname, alttype, altcrit, 972 certlabel, dir, prefix, keyAlg, sigAlg, keylen, 973 trust, ltime, &serial, kubits, kucrit, &tokencred, 974 ekulist); 975 976 } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { 977 rv = gencert_pkcs11(kmfhandle, 978 tokenname, subname, altname, alttype, altcrit, 979 certlabel, keyAlg, sigAlg, keylen, ltime, 980 &serial, kubits, kucrit, &tokencred, ekulist); 981 982 } else if (kstype == KMF_KEYSTORE_OPENSSL) { 983 rv = gencert_file(kmfhandle, 984 keyAlg, sigAlg, keylen, fmt, 985 ltime, subname, altname, alttype, altcrit, 986 &serial, kubits, kucrit, dir, outcert, outkey, 987 ekulist); 988 } 989 990 if (rv != KMF_OK) 991 display_error(kmfhandle, rv, 992 gettext("Error creating certificate and keypair")); 993 end: 994 if (ekulist != NULL) 995 free_eku_list(ekulist); 996 if (subname) 997 free(subname); 998 if (tokencred.cred != NULL) 999 free(tokencred.cred); 1000 1001 if (serial.val != NULL) 1002 free(serial.val); 1003 1004 (void) kmf_finalize(kmfhandle); 1005 return (rv); 1006 } 1007