Home | History | Annotate | Download | only in kssladm
      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 /*
     23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #include <errno.h>
     28 #include <sys/sysmacros.h>
     29 #include <security/cryptoki.h>
     30 #include <security/pkcs11.h>
     31 #include <stdio.h>
     32 #include <strings.h>
     33 #include <sys/types.h>
     34 #include <sys/stat.h>
     35 #include <sys/socket.h>
     36 #include <netinet/in.h>
     37 #include <arpa/inet.h>
     38 #include <netdb.h>
     39 #include <fcntl.h>
     40 #include <inet/kssl/kssl.h>
     41 #include <cryptoutil.h>
     42 #include <libscf.h>
     43 #include "kssladm.h"
     44 
     45 #include <kmfapi.h>
     46 
     47 void
     48 usage_create(boolean_t do_print)
     49 {
     50 	if (do_print)
     51 		(void) fprintf(stderr, "Usage:\n");
     52 	(void) fprintf(stderr, "kssladm create"
     53 	    " -f pkcs11 [-d softtoken_directory] -T <token_label>"
     54 	    " -C <certificate_label> -x <proxy_port>"
     55 	    " [-h <ca_certchain_file>]"
     56 	    " [options] [<server_address>] [<server_port>]\n");
     57 
     58 	(void) fprintf(stderr, "kssladm create"
     59 	    " -f pkcs12 -i <cert_and_key_pk12file> -x <proxy_port>"
     60 	    " [options] [<server_address>] [<server_port>]\n");
     61 
     62 	(void) fprintf(stderr, "kssladm create"
     63 	    " -f pem -i <cert_and_key_pemfile> -x <proxy_port>"
     64 	    " [options] [<server_address>] [<server_port>]\n");
     65 
     66 	(void) fprintf(stderr, "options are:\n"
     67 	    "\t[-c <ciphersuites>]\n"
     68 	    "\t[-p <password_file>]\n"
     69 	    "\t[-t <ssl_session_cache_timeout>]\n"
     70 	    "\t[-z <ssl_session_cache_size>]\n"
     71 	    "\t[-v]\n");
     72 }
     73 
     74 /*
     75  * Everything is allocated in one single contiguous buffer.
     76  * The layout is the following:
     77  * . the kssl_params_t structure
     78  * . optional buffer containing pin (if key is non extractable)
     79  * . the array of key attribute structs, (value of ck_attrs)
     80  * . the key attributes values (values of ck_attrs[i].ck_value);
     81  * . the array of sizes of the certificates, (referred to as sc_sizes[])
     82  * . the certificates values (referred to as sc_certs[])
     83  *
     84  * The address of the certs and key attributes values are offsets
     85  * from the beginning of the big buffer. sc_sizes_offset points
     86  * to sc_sizes[0] and sc_certs_offset points to sc_certs[0].
     87  */
     88 static kssl_params_t *
     89 kmf_to_kssl(int nxkey, KMF_RAW_KEY_DATA *rsa, int ncerts,
     90 	KMF_X509_DER_CERT *certs, int *paramsize,
     91 	char *token_label, KMF_DATA *idstr,
     92 	KMF_CREDENTIAL *creds)
     93 {
     94 	int i, tcsize;
     95 	kssl_params_t *kssl_params;
     96 	kssl_key_t *key;
     97 	char *buf;
     98 	uint32_t bufsize;
     99 	static CK_BBOOL true = TRUE;
    100 	static CK_BBOOL false = FALSE;
    101 	static CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
    102 	static CK_KEY_TYPE keytype = CKK_RSA;
    103 	kssl_object_attribute_t kssl_attrs[MAX_ATTR_CNT];
    104 	CK_ATTRIBUTE exkey_attrs[MAX_ATTR_CNT] = {
    105 		{CKA_TOKEN, &true, sizeof (true)},
    106 		{CKA_EXTRACTABLE, &false, sizeof (false)},
    107 		{CKA_CLASS,	&class, sizeof (class) },
    108 		{CKA_KEY_TYPE,	&keytype, sizeof (keytype) },
    109 		{CKA_ID,	NULL, 0}
    110 	};
    111 	kssl_object_attribute_t kssl_tmpl_attrs[MAX_ATTR_CNT] = {
    112 		{SUN_CKA_MODULUS, NULL, 0},
    113 		{SUN_CKA_PUBLIC_EXPONENT, NULL, 0},
    114 		{SUN_CKA_PRIVATE_EXPONENT, NULL, 0},
    115 		{SUN_CKA_PRIME_1, NULL, 0},
    116 		{SUN_CKA_PRIME_2, NULL, 0},
    117 		{SUN_CKA_EXPONENT_1, NULL, 0},
    118 		{SUN_CKA_EXPONENT_2, NULL, 0},
    119 		{SUN_CKA_COEFFICIENT, NULL, 0}
    120 	};
    121 	KMF_BIGINT priv_key_bignums[MAX_ATTR_CNT];
    122 	int attr_cnt;
    123 
    124 	if (nxkey && idstr != NULL) {
    125 		exkey_attrs[4].pValue = idstr->Data;
    126 		exkey_attrs[4].ulValueLen = idstr->Length;
    127 	}
    128 	tcsize = 0;
    129 	for (i = 0; i < ncerts; i++)
    130 		tcsize += certs[i].certificate.Length;
    131 
    132 	bufsize = sizeof (kssl_params_t);
    133 	bufsize += (tcsize + (MAX_CHAIN_LENGTH * sizeof (uint32_t)));
    134 
    135 	if (!nxkey) {
    136 		bzero(priv_key_bignums, sizeof (KMF_BIGINT) *
    137 		    MAX_ATTR_CNT);
    138 		/* and the key attributes */
    139 		priv_key_bignums[0] = rsa->rawdata.rsa.mod;
    140 		priv_key_bignums[1] = rsa->rawdata.rsa.pubexp;
    141 		priv_key_bignums[2] = rsa->rawdata.rsa.priexp;
    142 		priv_key_bignums[3] = rsa->rawdata.rsa.prime1;
    143 		priv_key_bignums[4] = rsa->rawdata.rsa.prime2;
    144 		priv_key_bignums[5] = rsa->rawdata.rsa.exp1;
    145 		priv_key_bignums[6] = rsa->rawdata.rsa.exp2;
    146 		priv_key_bignums[7] = rsa->rawdata.rsa.coef;
    147 
    148 		if (rsa->rawdata.rsa.mod.val == NULL ||
    149 		    rsa->rawdata.rsa.priexp.val == NULL) {
    150 			(void) fprintf(stderr,
    151 			"missing required attributes in private key.\n");
    152 			return (NULL);
    153 		}
    154 
    155 		attr_cnt = 0;
    156 		for (i = 0; i < MAX_ATTR_CNT; i++) {
    157 			if (priv_key_bignums[i].val == NULL)
    158 				continue;
    159 			kssl_attrs[attr_cnt].ka_type =
    160 			    kssl_tmpl_attrs[i].ka_type;
    161 			kssl_attrs[attr_cnt].ka_value_len =
    162 			    priv_key_bignums[i].len;
    163 			bufsize += sizeof (crypto_object_attribute_t) +
    164 			    kssl_attrs[attr_cnt].ka_value_len;
    165 			attr_cnt++;
    166 		}
    167 	} else {
    168 		/*
    169 		 * Compute space for the attributes and values that the
    170 		 * kssl kernel module will need in order to search for
    171 		 * the private key.
    172 		 */
    173 		for (attr_cnt = 0; attr_cnt < 5; attr_cnt++) {
    174 			bufsize += sizeof (crypto_object_attribute_t) +
    175 			    exkey_attrs[attr_cnt].ulValueLen;
    176 		}
    177 		if (creds)
    178 			bufsize += creds->credlen;
    179 	}
    180 
    181 	/* Add 4-byte cushion as sc_sizes[0] needs 32-bit alignment */
    182 	bufsize += sizeof (uint32_t);
    183 
    184 	/* Now the big memory allocation */
    185 	if ((buf = calloc(bufsize, 1)) == NULL) {
    186 		(void) fprintf(stderr,
    187 		    "Cannot allocate memory for the kssl_params "
    188 		    "and values\n");
    189 		return (NULL);
    190 	}
    191 
    192 	/* LINTED */
    193 	kssl_params = (kssl_params_t *)buf;
    194 
    195 	buf = (char *)(kssl_params + 1);
    196 
    197 	if (!nxkey) {
    198 		/* the keys attributes structs array */
    199 		key = &kssl_params->kssl_privkey;
    200 		key->ks_format = CRYPTO_KEY_ATTR_LIST;
    201 		key->ks_count = attr_cnt;
    202 		key->ks_attrs_offset = buf - (char *)kssl_params;
    203 		buf += attr_cnt * sizeof (kssl_object_attribute_t);
    204 
    205 		attr_cnt = 0;
    206 		/* then the key attributes values */
    207 		for (i = 0; i < MAX_ATTR_CNT; i++) {
    208 			if (priv_key_bignums[i].val == NULL)
    209 				continue;
    210 			(void) memcpy(buf, priv_key_bignums[i].val,
    211 			    priv_key_bignums[i].len);
    212 			kssl_attrs[attr_cnt].ka_value_offset =
    213 			    buf - (char *)kssl_params;
    214 			buf += kssl_attrs[attr_cnt].ka_value_len;
    215 			attr_cnt++;
    216 		}
    217 	} else {
    218 		char tlabel[CRYPTO_EXT_SIZE_LABEL];
    219 		bzero(tlabel, sizeof (tlabel));
    220 		(void) strlcpy(tlabel, token_label, sizeof (tlabel));
    221 
    222 		/*
    223 		 * For a non-extractable key, we must provide the PIN
    224 		 * so the kssl module can access the token to find
    225 		 * the key handle.
    226 		 */
    227 		kssl_params->kssl_is_nxkey = 1;
    228 		bcopy(tlabel, kssl_params->kssl_token.toklabel,
    229 		    CRYPTO_EXT_SIZE_LABEL);
    230 		kssl_params->kssl_token.pinlen = creds->credlen;
    231 		kssl_params->kssl_token.tokpin_offset =
    232 		    buf - (char *)kssl_params;
    233 		kssl_params->kssl_token.ck_rv = 0;
    234 		bcopy(creds->cred, buf, creds->credlen);
    235 		buf += creds->credlen;
    236 
    237 		/*
    238 		 * Next in the buffer, we must provide the attributes
    239 		 * that the kssl module will use to search in the
    240 		 * token to find the protected key handle.
    241 		 */
    242 		key = &kssl_params->kssl_privkey;
    243 		key->ks_format = CRYPTO_KEY_ATTR_LIST;
    244 		key->ks_count = attr_cnt;
    245 		key->ks_attrs_offset = buf - (char *)kssl_params;
    246 
    247 		buf += attr_cnt * sizeof (kssl_object_attribute_t);
    248 		for (i = 0; i < attr_cnt; i++) {
    249 			bcopy(exkey_attrs[i].pValue, buf,
    250 			    exkey_attrs[i].ulValueLen);
    251 
    252 			kssl_attrs[i].ka_type = exkey_attrs[i].type;
    253 			kssl_attrs[i].ka_value_offset =
    254 			    buf - (char *)kssl_params;
    255 			kssl_attrs[i].ka_value_len = exkey_attrs[i].ulValueLen;
    256 
    257 			buf += exkey_attrs[i].ulValueLen;
    258 		}
    259 	}
    260 	/* Copy the key attributes array here */
    261 	bcopy(kssl_attrs, ((char *)kssl_params) + key->ks_attrs_offset,
    262 	    attr_cnt * sizeof (kssl_object_attribute_t));
    263 
    264 	buf = (char *)P2ROUNDUP((uintptr_t)buf, sizeof (uint32_t));
    265 
    266 	/*
    267 	 * Finally, add the certificate chain to the buffer.
    268 	 */
    269 	kssl_params->kssl_certs.sc_count = ncerts;
    270 
    271 	/* First, an array of certificate sizes */
    272 	for (i = 0; i < ncerts; i++) {
    273 		uint32_t certsz = (uint32_t)certs[i].certificate.Length;
    274 		char *p = buf + (i * sizeof (uint32_t));
    275 		bcopy(&certsz, p, sizeof (uint32_t));
    276 	}
    277 
    278 	kssl_params->kssl_certs.sc_sizes_offset = buf - (char *)kssl_params;
    279 	buf += MAX_CHAIN_LENGTH * sizeof (uint32_t);
    280 
    281 	kssl_params->kssl_certs.sc_certs_offset = buf - (char *)kssl_params;
    282 
    283 	/* Now add the certificate data (ASN.1 DER encoded) */
    284 	for (i = 0; i < ncerts; i++) {
    285 		bcopy(certs[i].certificate.Data, buf,
    286 		    certs[i].certificate.Length);
    287 		buf += certs[i].certificate.Length;
    288 	}
    289 
    290 	*paramsize = bufsize;
    291 	return (kssl_params);
    292 }
    293 
    294 /*
    295  * Extract a sensitive key via wrap/unwrap operations.
    296  *
    297  * This function requires that we call PKCS#11 API directly since
    298  * KMF does not yet support wrapping/unwrapping of keys.   By extracting
    299  * a sensitive key in wrapped form, we then unwrap it into a session key
    300  * object.  KMF is then used to find the session key and return it in
    301  * KMF_RAW_KEY format which is then passed along to KSSL by the caller.
    302  */
    303 static KMF_RETURN
    304 get_sensitive_key_data(KMF_HANDLE_T kmfh,
    305 	KMF_CREDENTIAL *creds, char *keylabel,
    306 	char *idstr, KMF_KEY_HANDLE *key, KMF_KEY_HANDLE *rawkey)
    307 {
    308 	KMF_RETURN rv = KMF_OK;
    309 	static CK_BYTE aes_param[16];
    310 	static CK_OBJECT_CLASS privkey_class = CKO_PRIVATE_KEY;
    311 	static CK_KEY_TYPE privkey_type = CKK_RSA;
    312 	static CK_BBOOL false = FALSE;
    313 	boolean_t kmftrue = B_TRUE;
    314 	boolean_t kmffalse = B_FALSE;
    315 	char *err = NULL;
    316 	char wrapkey_label[BUFSIZ];
    317 	int fd;
    318 	uint32_t nkeys = 0;
    319 	CK_RV ckrv;
    320 	CK_SESSION_HANDLE pk11session;
    321 	CK_BYTE aes_key_val[16];
    322 	int numattr = 0;
    323 	int idx;
    324 	KMF_ATTRIBUTE attrlist[16];
    325 	KMF_KEYSTORE_TYPE kstype;
    326 	KMF_KEY_CLASS kclass;
    327 	KMF_ENCODE_FORMAT format;
    328 
    329 	CK_MECHANISM aes_cbc_pad_mech = {CKM_AES_CBC_PAD, aes_param,
    330 		sizeof (aes_param)};
    331 	CK_OBJECT_HANDLE aes_key_obj = CK_INVALID_HANDLE;
    332 	CK_OBJECT_HANDLE sess_privkey_obj = CK_INVALID_HANDLE;
    333 	CK_BYTE *wrapped_privkey = NULL;
    334 	CK_ULONG wrapped_privkey_len = 0;
    335 
    336 	CK_ATTRIBUTE unwrap_tmpl[] = {
    337 		/* code below depends on the following attribute order */
    338 		{CKA_TOKEN, &false, sizeof (false)},
    339 		{CKA_CLASS, &privkey_class, sizeof (privkey_class)},
    340 		{CKA_KEY_TYPE, &privkey_type, sizeof (privkey_type)},
    341 		{CKA_SENSITIVE, &false, sizeof (false)},
    342 		{CKA_PRIVATE, &false, sizeof (false)},
    343 		{CKA_LABEL, NULL, 0}
    344 	};
    345 
    346 	/*
    347 	 * Create a wrap key with random data.
    348 	 */
    349 	fd = open("/dev/urandom", O_RDONLY);
    350 	if (fd == -1) {
    351 		perror("Error reading /dev/urandom");
    352 		return (KMF_ERR_INTERNAL);
    353 	}
    354 	if (read(fd, aes_key_val, sizeof (aes_key_val)) !=
    355 	    sizeof (aes_key_val)) {
    356 		perror("Error reading from /dev/urandom");
    357 		(void) close(fd);
    358 		return (KMF_ERR_INTERNAL);
    359 	}
    360 	(void) close(fd);
    361 
    362 	pk11session = kmf_get_pk11_handle(kmfh);
    363 
    364 	/*
    365 	 * Login to create the wrap key stuff.
    366 	 */
    367 	ckrv = C_Login(pk11session, CKU_USER,
    368 	    (CK_UTF8CHAR_PTR)creds->cred, creds->credlen);
    369 	if (ckrv != CKR_OK && ckrv != CKR_USER_ALREADY_LOGGED_IN) {
    370 		(void) fprintf(stderr,
    371 		    "Cannot login to the token. error = %s\n",
    372 		    pkcs11_strerror(ckrv));
    373 		return (KMF_ERR_INTERNAL);
    374 	}
    375 
    376 	/*
    377 	 * Turn the random key into a PKCS#11 session object.
    378 	 */
    379 	ckrv = SUNW_C_KeyToObject(pk11session, CKM_AES_CBC_PAD, aes_key_val,
    380 	    sizeof (aes_key_val), &aes_key_obj);
    381 	if (ckrv != CKR_OK) {
    382 		(void) fprintf(stderr,
    383 		    "Cannot create wrapping key. error = %s\n",
    384 		    pkcs11_strerror(ckrv));
    385 		return (KMF_ERR_INTERNAL);
    386 	}
    387 
    388 	/*
    389 	 * Find the original private key that we are going to wrap.
    390 	 */
    391 	kstype = KMF_KEYSTORE_PK11TOKEN;
    392 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    393 	    &kstype, sizeof (kstype));
    394 	numattr++;
    395 
    396 	kclass = KMF_ASYM_PRI;
    397 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
    398 	    &kclass, sizeof (kclass));
    399 	numattr++;
    400 
    401 	kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
    402 	    creds, sizeof (KMF_CREDENTIAL));
    403 	numattr++;
    404 
    405 	if (keylabel) {
    406 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
    407 		    keylabel, strlen(keylabel));
    408 		numattr++;
    409 	}
    410 	if (idstr) {
    411 		kmf_set_attr_at_index(attrlist, numattr, KMF_IDSTR_ATTR,
    412 		    idstr, strlen(idstr));
    413 		numattr++;
    414 	}
    415 	format = KMF_FORMAT_NATIVE;
    416 	kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
    417 	    &format, sizeof (format));
    418 	numattr++;
    419 
    420 	kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR,
    421 	    &kmftrue, sizeof (kmftrue));
    422 	numattr++;
    423 
    424 	kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVATE_BOOL_ATTR,
    425 	    &kmftrue, sizeof (kmftrue));
    426 	numattr++;
    427 
    428 	nkeys = 1;
    429 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
    430 	    &nkeys, sizeof (nkeys));
    431 	numattr++;
    432 
    433 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
    434 	    key, sizeof (KMF_KEY_HANDLE));
    435 	numattr++;
    436 
    437 	rv = kmf_find_key(kmfh, numattr, attrlist);
    438 	if (rv != KMF_OK) {
    439 		REPORT_KMF_ERROR(rv, "Error finding private key", err);
    440 		goto out;
    441 	}
    442 
    443 	/*
    444 	 * Get the size of the wrapped private key.
    445 	 */
    446 	bzero(aes_param, sizeof (aes_param));
    447 	ckrv = C_WrapKey(pk11session, &aes_cbc_pad_mech,
    448 	    aes_key_obj, (CK_OBJECT_HANDLE)key->keyp,
    449 	    NULL, &wrapped_privkey_len);
    450 	if (ckrv != CKR_OK) {
    451 		/*
    452 		 * Most common error here is that the token doesn't
    453 		 * support the wrapping mechanism or the key is
    454 		 * marked non-extractable.  Return an error and let
    455 		 * the caller deal with it gracefully.
    456 		 */
    457 		(void) fprintf(stderr,
    458 		    "Cannot get wrap key size. error = %s\n",
    459 		    pkcs11_strerror(ckrv));
    460 		rv = KMF_ERR_INTERNAL;
    461 		goto out;
    462 	}
    463 	wrapped_privkey = malloc(wrapped_privkey_len);
    464 	if (wrapped_privkey == NULL) {
    465 		rv = KMF_ERR_MEMORY;
    466 		goto out;
    467 	}
    468 	/*
    469 	 * Now get the actual wrapped key data.
    470 	 */
    471 	ckrv = C_WrapKey(pk11session, &aes_cbc_pad_mech,
    472 	    aes_key_obj, (CK_OBJECT_HANDLE)key->keyp,
    473 	    wrapped_privkey, &wrapped_privkey_len);
    474 	if (ckrv != CKR_OK) {
    475 		(void) fprintf(stderr,
    476 		    "Cannot wrap private key. error = %s\n",
    477 		    pkcs11_strerror(ckrv));
    478 		rv = KMF_ERR_INTERNAL;
    479 		goto out;
    480 	}
    481 	/*
    482 	 * Create a label for the wrapped session key so we can find
    483 	 * it easier later.
    484 	 */
    485 	(void) snprintf(wrapkey_label, sizeof (wrapkey_label), "ksslprikey_%d",
    486 	    getpid());
    487 
    488 	unwrap_tmpl[5].pValue = wrapkey_label;
    489 	unwrap_tmpl[5].ulValueLen = strlen(wrapkey_label);
    490 
    491 	/*
    492 	 * Unwrap the key into the template and create a temporary
    493 	 * session private key.
    494 	 */
    495 	ckrv = C_UnwrapKey(pk11session, &aes_cbc_pad_mech, aes_key_obj,
    496 	    wrapped_privkey, wrapped_privkey_len,
    497 	    unwrap_tmpl, 6, &sess_privkey_obj);
    498 	if (ckrv != CKR_OK) {
    499 		(void) fprintf(stderr,
    500 		    "Cannot unwrap private key. error = %s\n",
    501 		    pkcs11_strerror(ckrv));
    502 		rv = KMF_ERR_INTERNAL;
    503 		goto out;
    504 	}
    505 
    506 	/*
    507 	 * Use KMF to find the session key and return it as RAW data
    508 	 * so we can pass it along to KSSL.
    509 	 */
    510 	kclass = KMF_ASYM_PRI;
    511 	if ((idx = kmf_find_attr(KMF_KEYCLASS_ATTR, attrlist, numattr)) != -1) {
    512 		attrlist[idx].pValue = &kclass;
    513 	}
    514 
    515 	format = KMF_FORMAT_RAWKEY;
    516 	if ((idx = kmf_find_attr(KMF_ENCODE_FORMAT_ATTR, attrlist,
    517 	    numattr)) != -1) {
    518 		attrlist[idx].pValue = &format;
    519 	}
    520 	if (wrapkey_label != NULL &&
    521 	    (idx = kmf_find_attr(KMF_KEYLABEL_ATTR, attrlist, numattr)) != -1) {
    522 		attrlist[idx].pValue = wrapkey_label;
    523 		attrlist[idx].valueLen = strlen(wrapkey_label);
    524 	}
    525 
    526 	if ((idx = kmf_find_attr(KMF_PRIVATE_BOOL_ATTR, attrlist,
    527 	    numattr)) != -1) {
    528 		attrlist[idx].pValue = &kmffalse;
    529 	}
    530 	if ((idx = kmf_find_attr(KMF_TOKEN_BOOL_ATTR, attrlist,
    531 	    numattr)) != -1) {
    532 		attrlist[idx].pValue = &kmffalse;
    533 	}
    534 
    535 	if ((idx = kmf_find_attr(KMF_KEY_HANDLE_ATTR, attrlist,
    536 	    numattr)) != -1) {
    537 		attrlist[idx].pValue = rawkey;
    538 	}
    539 	/*
    540 	 * Clear the IDSTR attribute since it is not part of the
    541 	 * wrapped session key.
    542 	 */
    543 	if ((idx = kmf_find_attr(KMF_IDSTR_ATTR, attrlist,
    544 	    numattr)) != -1) {
    545 		attrlist[idx].pValue = NULL;
    546 		attrlist[idx].valueLen = 0;
    547 	}
    548 
    549 	/* The wrapped key should not be sensitive. */
    550 	kmf_set_attr_at_index(attrlist, numattr, KMF_SENSITIVE_BOOL_ATTR,
    551 	    &false, sizeof (false));
    552 	numattr++;
    553 
    554 	rv = kmf_find_key(kmfh, numattr, attrlist);
    555 	if (rv != KMF_OK) {
    556 		REPORT_KMF_ERROR(rv, "Error finding raw private key", err);
    557 		goto out;
    558 	}
    559 out:
    560 	if (wrapped_privkey)
    561 		free(wrapped_privkey);
    562 
    563 	if (aes_key_obj != CK_INVALID_HANDLE)
    564 		(void) C_DestroyObject(pk11session, aes_key_obj);
    565 
    566 	if (sess_privkey_obj != CK_INVALID_HANDLE)
    567 		(void) C_DestroyObject(pk11session, sess_privkey_obj);
    568 
    569 	return (rv);
    570 }
    571 
    572 static kssl_params_t *
    573 load_from_pkcs11(KMF_HANDLE_T kmfh,
    574     const char *token_label, const char *password_file,
    575     const char *certname, int *bufsize)
    576 {
    577 	KMF_RETURN rv;
    578 	KMF_X509_DER_CERT cert;
    579 	KMF_KEY_HANDLE key, rawkey;
    580 	KMF_CREDENTIAL creds;
    581 	KMF_DATA iddata = { NULL, 0 };
    582 	kssl_params_t *kssl_params = NULL;
    583 	uint32_t ncerts, nkeys;
    584 	char *err, *idstr = NULL;
    585 	char password_buf[1024];
    586 	int nxkey = 0;
    587 	int numattr = 0;
    588 	KMF_ATTRIBUTE attrlist[16];
    589 	KMF_KEYSTORE_TYPE kstype;
    590 	KMF_KEY_CLASS kclass;
    591 	KMF_ENCODE_FORMAT format;
    592 	boolean_t false = B_FALSE;
    593 	boolean_t true = B_TRUE;
    594 
    595 	if (get_passphrase(password_file, password_buf,
    596 	    sizeof (password_buf)) <= 0) {
    597 		perror("Unable to read passphrase");
    598 		goto done;
    599 	}
    600 	creds.cred = password_buf;
    601 	creds.credlen = strlen(password_buf);
    602 
    603 	(void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
    604 	(void) memset(&rawkey, 0, sizeof (KMF_KEY_HANDLE));
    605 
    606 	kstype = KMF_KEYSTORE_PK11TOKEN;
    607 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    608 	    &kstype, sizeof (kstype));
    609 	numattr++;
    610 
    611 	if (token_label && strlen(token_label)) {
    612 		kmf_set_attr_at_index(attrlist, numattr,
    613 		    KMF_TOKEN_LABEL_ATTR,
    614 		    (void *)token_label, strlen(token_label));
    615 		numattr++;
    616 	}
    617 
    618 	kmf_set_attr_at_index(attrlist, numattr, KMF_READONLY_ATTR,
    619 	    &false, sizeof (false));
    620 	numattr++;
    621 
    622 	rv = kmf_configure_keystore(kmfh, numattr, attrlist);
    623 	if (rv != KMF_OK) {
    624 		REPORT_KMF_ERROR(rv, "Error configuring KMF keystore", err);
    625 		goto done;
    626 	}
    627 
    628 	/*
    629 	 * Find the certificate matching the given label.
    630 	 */
    631 	numattr = 0;
    632 	kstype = KMF_KEYSTORE_PK11TOKEN;
    633 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    634 	    &kstype, sizeof (kstype));
    635 	numattr++;
    636 
    637 	if (certname) {
    638 		kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
    639 		    (void *)certname, strlen(certname));
    640 		numattr++;
    641 	}
    642 	ncerts = 1;
    643 
    644 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
    645 	    &ncerts, sizeof (ncerts));
    646 	numattr++;
    647 
    648 	kmf_set_attr_at_index(attrlist, numattr, KMF_X509_DER_CERT_ATTR,
    649 	    &cert, sizeof (cert));
    650 	numattr++;
    651 
    652 	rv = kmf_find_cert(kmfh, numattr, attrlist);
    653 	if (rv != KMF_OK || ncerts == 0)
    654 		goto done;
    655 
    656 	/*
    657 	 * Find the associated private key for this cert by
    658 	 * keying off of the label and the ASCII ID string.
    659 	 */
    660 	rv = kmf_get_cert_id_str(&cert.certificate, &idstr);
    661 	if (rv != KMF_OK)
    662 		goto done;
    663 
    664 	numattr = 1; /* attrlist[0] is already set to kstype */
    665 
    666 	kclass = KMF_ASYM_PRI;
    667 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
    668 	    &kclass, sizeof (kclass));
    669 	numattr++;
    670 
    671 	kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
    672 	    &creds, sizeof (KMF_CREDENTIAL));
    673 	numattr++;
    674 
    675 	format = KMF_FORMAT_RAWKEY;
    676 	kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
    677 	    &format, sizeof (format));
    678 	numattr++;
    679 
    680 	if (certname) {
    681 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
    682 		    (void *)certname, strlen(certname));
    683 		numattr++;
    684 	}
    685 	if (idstr) {
    686 		kmf_set_attr_at_index(attrlist, numattr, KMF_IDSTR_ATTR,
    687 		    (void *)idstr, strlen(idstr));
    688 		numattr++;
    689 	}
    690 	kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR,
    691 	    &true, sizeof (true));
    692 	numattr++;
    693 
    694 	kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVATE_BOOL_ATTR,
    695 	    &true, sizeof (true));
    696 	numattr++;
    697 
    698 	/* We only expect to find 1 key at most */
    699 	nkeys = 1;
    700 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
    701 	    &nkeys, sizeof (nkeys));
    702 	numattr++;
    703 
    704 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
    705 	    &key, sizeof (KMF_KEY_HANDLE));
    706 	numattr++;
    707 
    708 	rv = kmf_find_key(kmfh, numattr, attrlist);
    709 	if (rv == KMF_ERR_SENSITIVE_KEY) {
    710 		kmf_free_kmf_key(kmfh, &key);
    711 		/*
    712 		 * Get a normal key handle and then do a wrap/unwrap
    713 		 * in order to get the necessary raw data fields needed
    714 		 * to send to KSSL.
    715 		 */
    716 		format = KMF_FORMAT_NATIVE;
    717 		rv = get_sensitive_key_data(kmfh, &creds,
    718 		    (char *)certname, idstr, &key, &rawkey);
    719 		if (rv == KMF_OK) {
    720 			/* Swap "key" for "rawkey" */
    721 			kmf_free_kmf_key(kmfh, &key);
    722 
    723 			key = rawkey;
    724 		} else {
    725 			kmf_free_kmf_key(kmfh, &key);
    726 
    727 			/* Let kssl try to find the key. */
    728 			nxkey = 1;
    729 			rv = kmf_get_cert_id_data(&cert.certificate, &iddata);
    730 		}
    731 	} else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) {
    732 		kmf_free_kmf_key(kmfh, &key);
    733 
    734 		/* Let kssl try to find the key. */
    735 		nxkey = 1;
    736 		rv = kmf_get_cert_id_data(&cert.certificate, &iddata);
    737 	} else if (rv != KMF_OK || nkeys == 0)
    738 		goto done;
    739 
    740 	if (rv == KMF_OK)
    741 		kssl_params = kmf_to_kssl(nxkey, (KMF_RAW_KEY_DATA *)key.keyp,
    742 		    1, &cert, bufsize, (char *)token_label, &iddata, &creds);
    743 done:
    744 	if (ncerts != 0)
    745 		kmf_free_kmf_cert(kmfh, &cert);
    746 	if (nkeys != 0)
    747 		kmf_free_kmf_key(kmfh, &key);
    748 	if (idstr)
    749 		free(idstr);
    750 
    751 	return (kssl_params);
    752 }
    753 
    754 /*
    755  * add_cacerts
    756  *
    757  * Load a chain of certificates from a PEM file.
    758  */
    759 static kssl_params_t *
    760 add_cacerts(KMF_HANDLE_T kmfh,
    761 	kssl_params_t *old_params, const char *cacert_chain_file)
    762 {
    763 	int i, newlen;
    764 	uint32_t certlen = 0, ncerts;
    765 	char *buf;
    766 	KMF_RETURN rv;
    767 	KMF_X509_DER_CERT *certs = NULL;
    768 	kssl_params_t *kssl_params;
    769 	char *err = NULL;
    770 	int numattr = 0;
    771 	KMF_ATTRIBUTE attrlist[16];
    772 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
    773 
    774 	kstype = KMF_KEYSTORE_OPENSSL;
    775 
    776 	ncerts = 0;
    777 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    778 	    &kstype, sizeof (KMF_KEYSTORE_TYPE));
    779 	numattr++;
    780 
    781 	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR,
    782 	    (void *)cacert_chain_file, strlen(cacert_chain_file));
    783 	numattr++;
    784 
    785 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
    786 	    &ncerts, sizeof (ncerts));
    787 	numattr++;
    788 
    789 	rv = kmf_find_cert(kmfh, numattr, attrlist);
    790 	if (rv != KMF_OK) {
    791 		REPORT_KMF_ERROR(rv, "Error finding CA certificates", err);
    792 		return (0);
    793 	}
    794 	certs = (KMF_X509_DER_CERT *)malloc(ncerts *
    795 	    sizeof (KMF_X509_DER_CERT));
    796 	if (certs == NULL) {
    797 		(void) fprintf(stderr, "memory allocation error.\n");
    798 		return (NULL);
    799 	}
    800 	bzero(certs, ncerts * sizeof (KMF_X509_DER_CERT));
    801 
    802 	/* add new attribute for the cert list to be returned */
    803 	kmf_set_attr_at_index(attrlist, numattr, KMF_X509_DER_CERT_ATTR,
    804 	    certs, (ncerts * sizeof (KMF_X509_DER_CERT)));
    805 	numattr++;
    806 	rv = kmf_find_cert(kmfh, numattr, attrlist);
    807 
    808 	if (rv != KMF_OK || ncerts == 0) {
    809 		bzero(old_params, old_params->kssl_params_size);
    810 		free(old_params);
    811 		return (NULL);
    812 	}
    813 
    814 	if (verbose) {
    815 		(void) printf("%d certificates read successfully\n", ncerts);
    816 	}
    817 
    818 	newlen = old_params->kssl_params_size;
    819 	for (i = 0; i < ncerts; i++)
    820 		newlen += certs[i].certificate.Length;
    821 
    822 	/*
    823 	 * Get a bigger structure and update the
    824 	 * fields to account for the additional certs.
    825 	 */
    826 	kssl_params = realloc(old_params, newlen);
    827 
    828 	kssl_params->kssl_params_size = newlen;
    829 	kssl_params->kssl_certs.sc_count += ncerts;
    830 
    831 	/* Put the cert size info starting from sc_sizes[1] */
    832 	buf = (char *)kssl_params;
    833 	buf += kssl_params->kssl_certs.sc_sizes_offset;
    834 	bcopy(buf, &certlen, sizeof (uint32_t));
    835 	buf += sizeof (uint32_t);
    836 	for (i = 0; i < ncerts; i++) {
    837 		uint32_t size = (uint32_t)certs[i].certificate.Length;
    838 		bcopy(&size, buf, sizeof (uint32_t));
    839 		buf += sizeof (uint32_t);
    840 	}
    841 
    842 	/* Put the cert_bufs starting from sc_certs[1] */
    843 	buf = (char *)kssl_params;
    844 	buf += kssl_params->kssl_certs.sc_certs_offset;
    845 	buf += certlen;
    846 
    847 	/* now the certs values */
    848 	for (i = 0; i < ncerts; i++) {
    849 		bcopy(certs[i].certificate.Data, buf,
    850 		    certs[i].certificate.Length);
    851 		buf += certs[i].certificate.Length;
    852 	}
    853 
    854 	for (i = 0; i < ncerts; i++)
    855 		kmf_free_kmf_cert(kmfh, &certs[i]);
    856 	free(certs);
    857 
    858 	return (kssl_params);
    859 }
    860 
    861 /*
    862  * Find a key and certificate(s) from a single PEM file.
    863  */
    864 static kssl_params_t *
    865 load_from_pem(KMF_HANDLE_T kmfh, const char *filename,
    866 	const char *password_file, int *paramsize)
    867 {
    868 	int ncerts = 0, i;
    869 	kssl_params_t *kssl_params;
    870 	KMF_RAW_KEY_DATA *rsa = NULL;
    871 	KMF_X509_DER_CERT *certs = NULL;
    872 
    873 	ncerts = PEM_get_rsa_key_certs(kmfh,
    874 	    filename, (char *)password_file, &rsa, &certs);
    875 	if (rsa == NULL || certs == NULL || ncerts == 0) {
    876 		return (NULL);
    877 	}
    878 
    879 	if (verbose)
    880 		(void) printf("%d certificates read successfully\n", ncerts);
    881 
    882 	kssl_params = kmf_to_kssl(0, rsa, ncerts, certs, paramsize, NULL,
    883 	    NULL, NULL);
    884 
    885 	for (i = 0; i < ncerts; i++)
    886 		kmf_free_kmf_cert(kmfh, &certs[i]);
    887 	free(certs);
    888 	kmf_free_raw_key(rsa);
    889 
    890 	return (kssl_params);
    891 }
    892 
    893 /*
    894  * Load a raw key and certificate(s) from a PKCS#12 file.
    895  */
    896 static kssl_params_t *
    897 load_from_pkcs12(KMF_HANDLE_T kmfh, const char *filename,
    898     const char *password_file, int *paramsize)
    899 {
    900 	KMF_RAW_KEY_DATA *rsa = NULL;
    901 	kssl_params_t *kssl_params;
    902 	KMF_X509_DER_CERT *certs = NULL;
    903 	int ncerts = 0, i;
    904 
    905 	ncerts = PKCS12_get_rsa_key_certs(kmfh, filename,
    906 	    password_file, &rsa, &certs);
    907 
    908 	if (certs == NULL || ncerts == 0) {
    909 		(void) fprintf(stderr,
    910 		    "Unable to read cert and/or key from %s\n", filename);
    911 		return (NULL);
    912 	}
    913 
    914 	if (verbose)
    915 		(void) printf("%d certificates read successfully\n", ncerts);
    916 
    917 	kssl_params = kmf_to_kssl(0, rsa, ncerts, certs, paramsize, NULL,
    918 	    NULL, NULL);
    919 
    920 	for (i = 0; i < ncerts; i++)
    921 		kmf_free_kmf_cert(kmfh, &certs[i]);
    922 	free(certs);
    923 
    924 	kmf_free_raw_key(rsa);
    925 	return (kssl_params);
    926 }
    927 
    928 int
    929 parse_and_set_addr(char *server_address, char *server_port,
    930     struct sockaddr_in6 *addr)
    931 {
    932 	if (server_port == NULL) {
    933 		return (-1);
    934 	}
    935 
    936 	if (server_address == NULL) {
    937 		addr->sin6_addr = in6addr_any;
    938 	} else {
    939 		struct hostent *hp;
    940 		int error_num;
    941 
    942 		if ((hp = (getipnodebyname(server_address, AF_INET6,
    943 		    AI_DEFAULT, &error_num))) == NULL) {
    944 			(void) fprintf(stderr, "Error: Unknown host: %s\n",
    945 			    server_address);
    946 			return (-1);
    947 		}
    948 
    949 		(void) memcpy((caddr_t)&addr->sin6_addr, hp->h_addr,
    950 		    hp->h_length);
    951 		freehostent(hp);
    952 	}
    953 
    954 	errno = 0;
    955 	addr->sin6_port = strtol(server_port, NULL, 10);
    956 	if (addr->sin6_port == 0 || errno != 0) {
    957 		(void) fprintf(stderr, "Error: Invalid Port value: %s\n",
    958 		    server_port);
    959 		return (-1);
    960 	}
    961 
    962 	return (0);
    963 }
    964 
    965 /*
    966  * The order of the ciphers is important. It is used as the
    967  * default order (when -c is not specified).
    968  */
    969 struct csuite {
    970 	const char *suite;
    971 	uint16_t val;
    972 	boolean_t seen;
    973 } cipher_suites[CIPHER_SUITE_COUNT - 1] = {
    974 	{"rsa_rc4_128_sha", SSL_RSA_WITH_RC4_128_SHA, B_FALSE},
    975 	{"rsa_rc4_128_md5", SSL_RSA_WITH_RC4_128_MD5, B_FALSE},
    976 	{"rsa_aes_256_cbc_sha", TLS_RSA_WITH_AES_256_CBC_SHA, B_FALSE},
    977 	{"rsa_aes_128_cbc_sha", TLS_RSA_WITH_AES_128_CBC_SHA, B_FALSE},
    978 	{"rsa_3des_ede_cbc_sha", SSL_RSA_WITH_3DES_EDE_CBC_SHA, B_FALSE},
    979 	{"rsa_des_cbc_sha", SSL_RSA_WITH_DES_CBC_SHA, B_FALSE},
    980 };
    981 
    982 static int
    983 check_suites(char *suites, uint16_t *sarray)
    984 {
    985 	int i;
    986 	int err = 0;
    987 	char *suite;
    988 	int sindx = 0;
    989 
    990 	if (suites != NULL) {
    991 		for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++)
    992 			sarray[i] = CIPHER_NOTSET;
    993 	} else {
    994 		for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++)
    995 			sarray[i] = cipher_suites[i].val;
    996 		return (err);
    997 	}
    998 
    999 	suite = strtok(suites, ",");
   1000 	do {
   1001 		for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++) {
   1002 			if (strcasecmp(suite, cipher_suites[i].suite) == 0) {
   1003 				if (!cipher_suites[i].seen) {
   1004 					sarray[sindx++] = cipher_suites[i].val;
   1005 					cipher_suites[i].seen = B_TRUE;
   1006 				}
   1007 				break;
   1008 			}
   1009 		}
   1010 
   1011 		if (i == (CIPHER_SUITE_COUNT - 1)) {
   1012 			(void) fprintf(stderr,
   1013 			    "Unknown Cipher suite name: %s\n", suite);
   1014 			err++;
   1015 		}
   1016 	} while ((suite = strtok(NULL, ",")) != NULL);
   1017 
   1018 	return (err);
   1019 }
   1020 
   1021 int
   1022 do_create(int argc, char *argv[])
   1023 {
   1024 	const char *softtoken_dir = NULL;
   1025 	const char *token_label = NULL;
   1026 	const char *password_file = NULL;
   1027 	const char *cert_key_file = NULL;
   1028 	const char *cacert_chain_file = NULL;
   1029 	const char *certname = NULL;
   1030 	char *suites = NULL;
   1031 	uint32_t timeout = DEFAULT_SID_TIMEOUT;
   1032 	uint32_t scache_size = DEFAULT_SID_CACHE_NENTRIES;
   1033 	uint16_t kssl_suites[CIPHER_SUITE_COUNT - 1];
   1034 	int proxy_port = -1;
   1035 	struct sockaddr_in6 server_addr;
   1036 	char *format = NULL;
   1037 	char *port, *addr;
   1038 	char c;
   1039 	int pcnt;
   1040 	kssl_params_t *kssl_params;
   1041 	int bufsize;
   1042 	KMF_HANDLE_T kmfh = NULL;
   1043 	KMF_RETURN rv = KMF_OK;
   1044 	char *err = NULL;
   1045 
   1046 	argc -= 1;
   1047 	argv += 1;
   1048 
   1049 	while ((c = getopt(argc, argv, "vT:d:f:h:i:p:c:C:t:x:z:")) != -1) {
   1050 		switch (c) {
   1051 		case 'd':
   1052 			softtoken_dir = optarg;
   1053 			break;
   1054 		case 'c':
   1055 			suites = optarg;
   1056 			break;
   1057 		case 'C':
   1058 			certname = optarg;
   1059 			break;
   1060 		case 'f':
   1061 			format = optarg;
   1062 			break;
   1063 		case 'h':
   1064 			cacert_chain_file = optarg;
   1065 			break;
   1066 		case 'i':
   1067 			cert_key_file = optarg;
   1068 			break;
   1069 		case 'T':
   1070 			token_label = optarg;
   1071 			break;
   1072 		case 'p':
   1073 			password_file = optarg;
   1074 			break;
   1075 		case 't':
   1076 			timeout = atoi(optarg);
   1077 			break;
   1078 		case 'x':
   1079 			proxy_port = atoi(optarg);
   1080 			break;
   1081 		case 'v':
   1082 			verbose = B_TRUE;
   1083 			break;
   1084 		case 'z':
   1085 			scache_size = atoi(optarg);
   1086 			break;
   1087 		default:
   1088 			goto err;
   1089 		}
   1090 	}
   1091 
   1092 	pcnt = argc - optind;
   1093 	if (pcnt == 0) {
   1094 		port = "443";	/* default SSL port */
   1095 		addr = NULL;
   1096 	} else if (pcnt == 1) {
   1097 		port = argv[optind];
   1098 		addr = NULL;
   1099 	} else if (pcnt == 2) {
   1100 		addr = argv[optind];
   1101 		port = argv[optind + 1];
   1102 	} else {
   1103 		goto err;
   1104 	}
   1105 
   1106 	if (parse_and_set_addr(addr, port, &server_addr) < 0) {
   1107 		goto err;
   1108 	}
   1109 
   1110 	if (verbose) {
   1111 		char buffer[128];
   1112 
   1113 		(void) inet_ntop(AF_INET6, &server_addr.sin6_addr, buffer,
   1114 		    sizeof (buffer));
   1115 		(void) printf("addr = %s, port = %d\n", buffer,
   1116 		    server_addr.sin6_port);
   1117 	}
   1118 
   1119 	if (format == NULL || proxy_port == -1) {
   1120 		goto err;
   1121 	}
   1122 
   1123 	if (check_suites(suites, kssl_suites) != 0) {
   1124 		goto err;
   1125 	}
   1126 
   1127 	rv = kmf_initialize(&kmfh, NULL, NULL);
   1128 	if (rv != KMF_OK) {
   1129 		REPORT_KMF_ERROR(rv, "Error initializing KMF", err);
   1130 		return (0);
   1131 	}
   1132 
   1133 	if (strcmp(format, "pkcs11") == 0) {
   1134 		if (token_label == NULL || certname == NULL) {
   1135 			goto err;
   1136 		}
   1137 		if (softtoken_dir != NULL) {
   1138 			(void) setenv("SOFTTOKEN_DIR", softtoken_dir, 1);
   1139 			if (verbose) {
   1140 				(void) printf(
   1141 				    "SOFTTOKEN_DIR=%s\n",
   1142 				    getenv("SOFTTOKEN_DIR"));
   1143 			}
   1144 		}
   1145 		kssl_params = load_from_pkcs11(kmfh,
   1146 		    token_label, password_file, certname, &bufsize);
   1147 	} else if (strcmp(format, "pkcs12") == 0) {
   1148 		if (cert_key_file == NULL) {
   1149 			goto err;
   1150 		}
   1151 		kssl_params = load_from_pkcs12(kmfh,
   1152 		    cert_key_file, password_file, &bufsize);
   1153 	} else if (strcmp(format, "pem") == 0) {
   1154 		if (cert_key_file == NULL) {
   1155 			goto err;
   1156 		}
   1157 		kssl_params = load_from_pem(kmfh,
   1158 		    cert_key_file, password_file, &bufsize);
   1159 	} else {
   1160 		(void) fprintf(stderr, "Unsupported cert format: %s\n", format);
   1161 		goto err;
   1162 	}
   1163 
   1164 	if (kssl_params == NULL) {
   1165 		(void) kmf_finalize(kmfh);
   1166 		return (FAILURE);
   1167 	}
   1168 
   1169 	/*
   1170 	 * Add the list of supported ciphers to the buffer.
   1171 	 */
   1172 	bcopy(kssl_suites, kssl_params->kssl_suites,
   1173 	    sizeof (kssl_params->kssl_suites));
   1174 	kssl_params->kssl_params_size = bufsize;
   1175 	kssl_params->kssl_addr = server_addr;
   1176 	kssl_params->kssl_session_cache_timeout = timeout;
   1177 	kssl_params->kssl_proxy_port = proxy_port;
   1178 	kssl_params->kssl_session_cache_size = scache_size;
   1179 
   1180 	if (cacert_chain_file != NULL) {
   1181 		kssl_params = add_cacerts(kmfh, kssl_params, cacert_chain_file);
   1182 		if (kssl_params == NULL) {
   1183 			bzero(kssl_params, bufsize);
   1184 			free(kssl_params);
   1185 			(void) kmf_finalize(kmfh);
   1186 			return (FAILURE);
   1187 		}
   1188 	}
   1189 
   1190 	if (kssl_send_command((char *)kssl_params, KSSL_ADD_ENTRY) < 0) {
   1191 		int err = CRYPTO_FAILED;
   1192 
   1193 		if (kssl_params->kssl_is_nxkey)
   1194 			err = kssl_params->kssl_token.ck_rv;
   1195 		(void) fprintf(stderr,
   1196 		    "Error loading cert and key: 0x%x\n", err);
   1197 		bzero(kssl_params, bufsize);
   1198 		free(kssl_params);
   1199 		(void) kmf_finalize(kmfh);
   1200 		return (FAILURE);
   1201 	}
   1202 
   1203 	if (verbose)
   1204 		(void) printf("Successfully loaded cert and key\n");
   1205 
   1206 	bzero(kssl_params, bufsize);
   1207 	free(kssl_params);
   1208 	(void) kmf_finalize(kmfh);
   1209 	return (SUCCESS);
   1210 
   1211 err:
   1212 	usage_create(B_TRUE);
   1213 	(void) kmf_finalize(kmfh);
   1214 	return (SMF_EXIT_ERR_CONFIG);
   1215 }
   1216