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