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