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