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