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