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