xref: /illumos-gate/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c (revision 150d2c5288c645a1c1a7d2bee61199a3729406c7)
1 /*
2  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 /*
6  * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
7  * project 2000.
8  */
9 /*
10  * ====================================================================
11  * Copyright (c) 2000-2004 The OpenSSL Project.  All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  *
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  *
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in
22  *    the documentation and/or other materials provided with the
23  *    distribution.
24  *
25  * 3. All advertising materials mentioning features or use of this
26  *    software must display the following acknowledgment:
27  *    "This product includes software developed by the OpenSSL Project
28  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
29  *
30  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
31  *    endorse or promote products derived from this software without
32  *    prior written permission. For written permission, please contact
33  *    licensing@OpenSSL.org.
34  *
35  * 5. Products derived from this software may not be called "OpenSSL"
36  *    nor may "OpenSSL" appear in their names without prior written
37  *    permission of the OpenSSL Project.
38  *
39  * 6. Redistributions of any form whatsoever must retain the following
40  *    acknowledgment:
41  *    "This product includes software developed by the OpenSSL Project
42  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
43  *
44  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
45  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
47  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
48  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
55  * OF THE POSSIBILITY OF SUCH DAMAGE.
56  * ====================================================================
57  *
58  * This product includes cryptographic software written by Eric Young
59  * (eay@cryptsoft.com).  This product includes software written by Tim
60  * Hudson (tjh@cryptsoft.com).
61  *
62  */
63 
64 #pragma ident	"%Z%%M%	%I%	%E% SMI"
65 
66 #include <stdlib.h>
67 #include <kmfapiP.h>
68 #include <ber_der.h>
69 #include <oidsalg.h>
70 #include <fcntl.h>
71 #include <sys/stat.h>
72 #include <dirent.h>
73 #include <cryptoutil.h>
74 #include <synch.h>
75 #include <thread.h>
76 
77 /* OPENSSL related headers */
78 #include <openssl/bio.h>
79 #include <openssl/bn.h>
80 #include <openssl/asn1.h>
81 #include <openssl/err.h>
82 #include <openssl/bn.h>
83 #include <openssl/x509.h>
84 #include <openssl/rsa.h>
85 #include <openssl/dsa.h>
86 #include <openssl/x509v3.h>
87 #include <openssl/objects.h>
88 #include <openssl/pem.h>
89 #include <openssl/pkcs12.h>
90 #include <openssl/ocsp.h>
91 #include <openssl/des.h>
92 #include <openssl/rand.h>
93 
94 #define	PRINT_ANY_EXTENSION (\
95 	KMF_X509_EXT_KEY_USAGE |\
96 	KMF_X509_EXT_CERT_POLICIES |\
97 	KMF_X509_EXT_SUBJALTNAME |\
98 	KMF_X509_EXT_BASIC_CONSTRAINTS |\
99 	KMF_X509_EXT_NAME_CONSTRAINTS |\
100 	KMF_X509_EXT_POLICY_CONSTRAINTS |\
101 	KMF_X509_EXT_EXT_KEY_USAGE |\
102 	KMF_X509_EXT_INHIBIT_ANY_POLICY |\
103 	KMF_X509_EXT_AUTH_KEY_ID |\
104 	KMF_X509_EXT_SUBJ_KEY_ID |\
105 	KMF_X509_EXT_POLICY_MAPPING)
106 
107 static BIO *bio_err = NULL;
108 static uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
109 	0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69,
110 	0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c,
111 	0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82,
112 	0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e,
113 	0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a,
114 	0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
115 	0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02,
116 	0x91 };
117 
118 static uchar_t Q[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
119 	0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4,
120 	0x8e, 0xda, 0xce, 0x91, 0x5f };
121 
122 static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
123 	0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5,
124 	0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef,
125 	0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c,
126 	0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba,
127 	0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c,
128 	0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
129 	0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
130 	0x02 };
131 
132 #define	SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \
133 	h->lasterr.errcode = c;
134 
135 #define	SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c;
136 
137 mutex_t init_lock = DEFAULTMUTEX;
138 static int ssl_initialized = 0;
139 
140 static KMF_RETURN
141 extract_objects(KMF_HANDLE *, char *, CK_UTF8CHAR *, CK_ULONG,
142 	EVP_PKEY **, KMF_DATA **, int *);
143 
144 static KMF_RETURN
145 kmf_load_cert(KMF_HANDLE *, KMF_FINDCERT_PARAMS *, char *, KMF_DATA *);
146 
147 KMF_RETURN
148 OpenSSL_FindCert(KMF_HANDLE_T,
149 	KMF_FINDCERT_PARAMS *,
150 	KMF_X509_DER_CERT *,
151 	uint32_t *);
152 
153 void
154 OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *);
155 
156 KMF_RETURN
157 OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *, KMF_DATA *);
158 
159 KMF_RETURN
160 OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *);
161 
162 KMF_RETURN
163 OpenSSL_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *,
164 	KMF_KEY_HANDLE *, KMF_KEY_HANDLE *);
165 
166 KMF_RETURN
167 OpenSSL_EncodePubKeyData(KMF_HANDLE_T,  KMF_KEY_HANDLE *, KMF_DATA *);
168 
169 KMF_RETURN
170 OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
171 	KMF_DATA *, KMF_DATA *);
172 
173 KMF_RETURN
174 OpenSSL_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *,
175 	KMF_KEY_HANDLE *, boolean_t);
176 
177 KMF_RETURN
178 OpenSSL_ImportCRL(KMF_HANDLE_T, KMF_IMPORTCRL_PARAMS *);
179 
180 KMF_RETURN
181 OpenSSL_DeleteCRL(KMF_HANDLE_T, KMF_DELETECRL_PARAMS *);
182 
183 KMF_RETURN
184 OpenSSL_ListCRL(KMF_HANDLE_T, KMF_LISTCRL_PARAMS *, char **);
185 
186 KMF_RETURN
187 OpenSSL_FindCertInCRL(KMF_HANDLE_T, KMF_FINDCERTINCRL_PARAMS *);
188 
189 KMF_RETURN
190 OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *,
191 	KMF_PRINTABLE_ITEM, char *);
192 
193 KMF_RETURN
194 OpenSSL_GetErrorString(KMF_HANDLE_T, char **);
195 
196 KMF_RETURN
197 OpenSSL_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *,
198 	KMF_KEY_HANDLE *, KMF_KEY_ALG);
199 
200 KMF_RETURN
201 OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
202 	KMF_DATA *, KMF_DATA *);
203 
204 KMF_RETURN
205 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, KMF_OCSPREQUEST_PARAMS *,
206 	char *reqfile);
207 
208 KMF_RETURN
209 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, KMF_OCSPRESPONSE_PARAMS_INPUT *,
210     KMF_OCSPRESPONSE_PARAMS_OUTPUT *);
211 
212 KMF_RETURN
213 OpenSSL_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *,
214 	KMF_KEY_HANDLE *, uint32_t *);
215 
216 KMF_RETURN
217 OpenSSL_ExportP12(KMF_HANDLE_T,
218 	KMF_EXPORTP12_PARAMS *,
219 	int, KMF_X509_DER_CERT *,
220 	int, KMF_KEY_HANDLE *,
221 	char *);
222 
223 KMF_RETURN
224 OpenSSL_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *,
225 	KMF_RAW_KEY_DATA *);
226 
227 KMF_RETURN
228 OpenSSL_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *,
229 	KMF_KEY_HANDLE *);
230 
231 KMF_RETURN
232 OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
233 
234 KMF_RETURN
235 OpenSSL_VerifyCRLFile(KMF_HANDLE_T, KMF_VERIFYCRL_PARAMS *);
236 
237 KMF_RETURN
238 OpenSSL_CheckCRLDate(KMF_HANDLE_T, KMF_CHECKCRLDATE_PARAMS *);
239 
240 static
241 KMF_PLUGIN_FUNCLIST openssl_plugin_table =
242 {
243 	1,				/* Version */
244 	NULL, /* ConfigureKeystore */
245 	OpenSSL_FindCert,
246 	OpenSSL_FreeKMFCert,
247 	OpenSSL_StoreCert,
248 	NULL, /* ImportCert */
249 	OpenSSL_ImportCRL,
250 	OpenSSL_DeleteCert,
251 	OpenSSL_DeleteCRL,
252 	OpenSSL_CreateKeypair,
253 	OpenSSL_FindKey,
254 	OpenSSL_EncodePubKeyData,
255 	OpenSSL_SignData,
256 	OpenSSL_DeleteKey,
257 	OpenSSL_ListCRL,
258 	NULL,	/* FindCRL */
259 	OpenSSL_FindCertInCRL,
260 	OpenSSL_GetErrorString,
261 	OpenSSL_GetPrikeyByCert,
262 	OpenSSL_DecryptData,
263 	OpenSSL_ExportP12,
264 	OpenSSL_StorePrivateKey,
265 	OpenSSL_CreateSymKey,
266 	OpenSSL_GetSymKeyValue,
267 	NULL,	/* SetTokenPin */
268 	NULL	/* Finalize */
269 };
270 
271 static mutex_t *lock_cs;
272 static long *lock_count;
273 
274 static void
275 /*ARGSUSED*/
276 locking_cb(int mode, int type, char *file, int line)
277 {
278 	if (mode & CRYPTO_LOCK) {
279 		(void) mutex_lock(&(lock_cs[type]));
280 		lock_count[type]++;
281 	} else {
282 		(void) mutex_unlock(&(lock_cs[type]));
283 	}
284 }
285 
286 static unsigned long
287 thread_id()
288 {
289 	return ((unsigned long)thr_self());
290 }
291 
292 KMF_PLUGIN_FUNCLIST *
293 KMF_Plugin_Initialize()
294 {
295 	int i;
296 
297 	(void) mutex_lock(&init_lock);
298 	if (!ssl_initialized) {
299 		OpenSSL_add_all_algorithms();
300 
301 		/* Enable error strings for reporting */
302 		ERR_load_crypto_strings();
303 
304 		/*
305 		 * Add support for extension OIDs that are not yet in the
306 		 * openssl default set.
307 		 */
308 		(void) OBJ_create("2.5.29.30", "nameConstraints",
309 				"X509v3 Name Constraints");
310 		(void) OBJ_create("2.5.29.33", "policyMappings",
311 				"X509v3 Policy Mappings");
312 		(void) OBJ_create("2.5.29.36", "policyConstraints",
313 			"X509v3 Policy Constraints");
314 		(void) OBJ_create("2.5.29.46", "freshestCRL",
315 			"X509v3 Freshest CRL");
316 		(void) OBJ_create("2.5.29.54", "inhibitAnyPolicy",
317 			"X509v3 Inhibit Any-Policy");
318 		/*
319 		 * Set up for thread-safe operation.
320 		 */
321 		lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t));
322 		if (lock_cs == NULL) {
323 			(void) mutex_unlock(&init_lock);
324 			return (NULL);
325 		}
326 
327 		lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long));
328 		if (lock_count == NULL) {
329 			OPENSSL_free(lock_cs);
330 			(void) mutex_unlock(&init_lock);
331 			return (NULL);
332 		}
333 
334 		for (i = 0; i < CRYPTO_num_locks(); i++) {
335 			lock_count[i] = 0;
336 			(void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL);
337 		}
338 
339 		CRYPTO_set_id_callback((unsigned long (*)())thread_id);
340 		CRYPTO_set_locking_callback((void (*)())locking_cb);
341 		ssl_initialized = 1;
342 	}
343 	(void) mutex_unlock(&init_lock);
344 
345 	return (&openssl_plugin_table);
346 }
347 /*
348  * Convert an SSL DN to a KMF DN.
349  */
350 static KMF_RETURN
351 get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN)
352 {
353 	KMF_DATA derdata;
354 	KMF_RETURN rv = KMF_OK;
355 	uchar_t *tmp;
356 
357 	/* Convert to raw DER format */
358 	derdata.Length = i2d_X509_NAME(sslDN, NULL);
359 	if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length))
360 		== NULL) {
361 		return (KMF_ERR_MEMORY);
362 	}
363 	(void) i2d_X509_NAME(sslDN, &tmp);
364 
365 	/* Decode to KMF format */
366 	rv = DerDecodeName(&derdata, kmfDN);
367 	if (rv != KMF_OK) {
368 		rv = KMF_ERR_BAD_CERT_FORMAT;
369 	}
370 	OPENSSL_free(derdata.Data);
371 
372 	return (rv);
373 }
374 
375 static int
376 isdir(char *path)
377 {
378 	struct stat s;
379 
380 	if (stat(path, &s) == -1)
381 		return (0);
382 
383 	return (s.st_mode & S_IFDIR);
384 }
385 
386 static KMF_RETURN
387 ssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert)
388 {
389 	KMF_RETURN rv = KMF_OK;
390 	unsigned char *buf = NULL, *p;
391 	int len;
392 
393 	/*
394 	 * Convert the X509 internal struct to DER encoded data
395 	 */
396 	if ((len = i2d_X509(x509cert, NULL)) < 0) {
397 		SET_ERROR(kmfh, ERR_get_error());
398 		rv = KMF_ERR_BAD_CERT_FORMAT;
399 		goto cleanup;
400 	}
401 	if ((buf = malloc(len)) == NULL) {
402 		SET_SYS_ERROR(kmfh, errno);
403 		rv = KMF_ERR_MEMORY;
404 		goto cleanup;
405 	}
406 
407 	/*
408 	 * i2d_X509 will increment the buf pointer so that we need to
409 	 * save it.
410 	 */
411 	p = buf;
412 	if ((len = i2d_X509(x509cert, &p)) < 0) {
413 		SET_ERROR(kmfh, ERR_get_error());
414 		free(buf);
415 		rv = KMF_ERR_BAD_CERT_FORMAT;
416 		goto cleanup;
417 	}
418 
419 	/* caller's responsibility to free it */
420 	cert->Data = buf;
421 	cert->Length = len;
422 
423 cleanup:
424 	if (rv != KMF_OK) {
425 		if (buf)
426 			free(buf);
427 		cert->Data = NULL;
428 		cert->Length = 0;
429 	}
430 
431 	return (rv);
432 }
433 
434 static KMF_RETURN
435 check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match)
436 {
437 	KMF_RETURN rv = KMF_OK;
438 	boolean_t findIssuer = FALSE;
439 	boolean_t findSubject = FALSE;
440 	boolean_t findSerial = FALSE;
441 	KMF_X509_NAME issuerDN, subjectDN;
442 	KMF_X509_NAME certIssuerDN, certSubjectDN;
443 
444 	*match = FALSE;
445 	if (xcert == NULL) {
446 		return (KMF_ERR_BAD_PARAMETER);
447 	}
448 
449 	(void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME));
450 	(void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME));
451 	(void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME));
452 	(void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME));
453 
454 	if (params->issuer != NULL && strlen(params->issuer)) {
455 		rv = KMF_DNParser(params->issuer, &issuerDN);
456 		if (rv != KMF_OK)
457 			return (KMF_ERR_BAD_PARAMETER);
458 
459 		rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN);
460 		if (rv != KMF_OK) {
461 			KMF_FreeDN(&issuerDN);
462 			return (KMF_ERR_BAD_PARAMETER);
463 		}
464 
465 		findIssuer = TRUE;
466 	}
467 	if (params->subject != NULL && strlen(params->subject)) {
468 		rv = KMF_DNParser(params->subject, &subjectDN);
469 		if (rv != KMF_OK) {
470 			rv = KMF_ERR_BAD_PARAMETER;
471 			goto cleanup;
472 		}
473 
474 		rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN);
475 		if (rv != KMF_OK) {
476 			rv = KMF_ERR_BAD_PARAMETER;
477 			goto cleanup;
478 		}
479 		findSubject = TRUE;
480 	}
481 	if (params->serial != NULL && params->serial->val != NULL)
482 		findSerial = TRUE;
483 
484 	if (findSerial) {
485 		BIGNUM *bn;
486 
487 		/* Comparing BIGNUMs is a pain! */
488 		bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL);
489 		if (bn != NULL) {
490 			int bnlen = BN_num_bytes(bn);
491 
492 			if (bnlen == params->serial->len) {
493 				uchar_t *a = malloc(bnlen);
494 				if (a == NULL) {
495 					rv = KMF_ERR_MEMORY;
496 					BN_free(bn);
497 					goto cleanup;
498 				}
499 				bnlen = BN_bn2bin(bn, a);
500 				*match = !memcmp(a,
501 					params->serial->val,
502 					params->serial->len);
503 				rv = KMF_OK;
504 				free(a);
505 			}
506 			BN_free(bn);
507 			if (!(*match))
508 				goto cleanup;
509 		} else {
510 			rv = KMF_OK;
511 			goto cleanup;
512 		}
513 	}
514 	if (findIssuer) {
515 		*match = !KMF_CompareRDNs(&issuerDN, &certIssuerDN);
516 		if (!(*match)) {
517 			rv = KMF_OK;
518 			goto cleanup;
519 		}
520 	}
521 	if (findSubject) {
522 		*match = !KMF_CompareRDNs(&subjectDN, &certSubjectDN);
523 		if (!(*match)) {
524 			rv = KMF_OK;
525 			goto cleanup;
526 		}
527 	}
528 
529 	*match = TRUE;
530 cleanup:
531 	if (findIssuer) {
532 		KMF_FreeDN(&issuerDN);
533 		KMF_FreeDN(&certIssuerDN);
534 	}
535 	if (findSubject) {
536 		KMF_FreeDN(&subjectDN);
537 		KMF_FreeDN(&certSubjectDN);
538 	}
539 
540 	return (rv);
541 }
542 
543 static KMF_RETURN
544 load_X509cert(KMF_HANDLE *kmfh,
545 	KMF_FINDCERT_PARAMS *params,
546 	char *pathname,
547 	X509 **outcert)
548 {
549 	KMF_RETURN rv = KMF_OK;
550 	X509 *xcert = NULL;
551 	BIO *bcert = NULL;
552 	boolean_t  match = FALSE;
553 	KMF_ENCODE_FORMAT format;
554 
555 	/*
556 	 * auto-detect the file format, regardless of what
557 	 * the 'format' parameters in the params say.
558 	 */
559 	rv = KMF_GetFileFormat(pathname, &format);
560 	if (rv != KMF_OK) {
561 		if (rv == KMF_ERR_OPEN_FILE)
562 			rv = KMF_ERR_CERT_NOT_FOUND;
563 		return (rv);
564 	}
565 
566 	/* Not ASN1(DER) format */
567 	if ((bcert = BIO_new_file(pathname, "rb")) == NULL) {
568 		SET_ERROR(kmfh, ERR_get_error());
569 		rv = KMF_ERR_OPEN_FILE;
570 		goto cleanup;
571 	}
572 
573 	if (format == KMF_FORMAT_PEM)
574 		xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL);
575 	else if (format == KMF_FORMAT_ASN1)
576 		xcert = d2i_X509_bio(bcert, NULL);
577 	else if (format == KMF_FORMAT_PKCS12) {
578 		PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL);
579 		if (p12 != NULL) {
580 			(void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL);
581 			PKCS12_free(p12);
582 			p12 = NULL;
583 		} else {
584 			SET_ERROR(kmfh, ERR_get_error());
585 			rv = KMF_ERR_BAD_CERT_FORMAT;
586 		}
587 	} else {
588 		rv = KMF_ERR_BAD_PARAMETER;
589 		goto cleanup;
590 	}
591 
592 	if (xcert == NULL) {
593 		SET_ERROR(kmfh, ERR_get_error());
594 		rv = KMF_ERR_BAD_CERT_FORMAT;
595 		goto cleanup;
596 	}
597 
598 	if (check_cert(xcert, params, &match) != KMF_OK || match == FALSE) {
599 		rv = KMF_ERR_CERT_NOT_FOUND;
600 		goto cleanup;
601 	}
602 
603 	if (outcert != NULL) {
604 		*outcert = xcert;
605 	}
606 
607 cleanup:
608 	if (bcert != NULL) (void) BIO_free(bcert);
609 	if (rv != KMF_OK && xcert != NULL)
610 		X509_free(xcert);
611 
612 	return (rv);
613 }
614 
615 static int
616 datacmp(const void *a, const void *b)
617 {
618 	KMF_DATA *adata = (KMF_DATA *)a;
619 	KMF_DATA *bdata = (KMF_DATA *)b;
620 	if (adata->Length > bdata->Length)
621 		return (-1);
622 	if (adata->Length < bdata->Length)
623 		return (1);
624 	return (0);
625 }
626 
627 static KMF_RETURN
628 load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname,
629 	KMF_DATA **certlist, uint32_t *numcerts)
630 {
631 	KMF_RETURN rv = KMF_OK;
632 	int i;
633 	KMF_DATA *certs = NULL;
634 	int nc = 0;
635 	int hits = 0;
636 	KMF_ENCODE_FORMAT format;
637 
638 	rv = KMF_GetFileFormat(pathname, &format);
639 	if (rv != KMF_OK) {
640 		if (rv == KMF_ERR_OPEN_FILE)
641 			rv = KMF_ERR_CERT_NOT_FOUND;
642 		return (rv);
643 	}
644 	if (format == KMF_FORMAT_ASN1) {
645 		/* load a single certificate */
646 		certs = (KMF_DATA *)malloc(sizeof (KMF_DATA));
647 		if (certs == NULL)
648 			return (KMF_ERR_MEMORY);
649 		certs->Data = NULL;
650 		certs->Length = 0;
651 		rv = kmf_load_cert(kmfh, params, pathname, certs);
652 		if (rv == KMF_OK) {
653 			*certlist = certs;
654 			*numcerts = 1;
655 		}
656 		return (rv);
657 	} else if (format == KMF_FORMAT_PKCS12) {
658 		/* We need a credential to access a PKCS#12 file */
659 		rv = KMF_ERR_BAD_CERT_FORMAT;
660 	} else if (format == KMF_FORMAT_PEM ||
661 		format != KMF_FORMAT_PEM_KEYPAIR) {
662 
663 		/* This function only works on PEM files */
664 		rv = extract_objects(kmfh, pathname,
665 			(uchar_t *)NULL, 0, NULL,
666 			&certs, &nc);
667 	} else {
668 		return (KMF_ERR_ENCODING);
669 	}
670 
671 	if (rv != KMF_OK)
672 		return (rv);
673 
674 	for (i = 0; i < nc; i++) {
675 		if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) {
676 			rv = KMF_CheckCertDate(kmfh, &certs[i]);
677 		} else if (params->find_cert_validity == KMF_EXPIRED_CERTS) {
678 			rv = KMF_CheckCertDate(kmfh, &certs[i]);
679 			if (rv == KMF_OK)
680 				rv = KMF_ERR_CERT_NOT_FOUND;
681 			if (rv == KMF_ERR_VALIDITY_PERIOD)
682 				rv = KMF_OK;
683 		}
684 		if (rv != KMF_OK) {
685 			/* Remove this cert from the list by clearing it. */
686 			KMF_FreeData(&certs[i]);
687 		} else {
688 			hits++; /* count valid certs found */
689 		}
690 		rv = KMF_OK;
691 	}
692 	if (rv == KMF_OK && hits == 0) {
693 		rv = KMF_ERR_CERT_NOT_FOUND;
694 	} else if (rv == KMF_OK && hits > 0) {
695 		/*
696 		 * Sort the list of certs by length to put the cleared ones
697 		 * at the end so they don't get accessed by the caller.
698 		 */
699 		qsort((void *)certs, nc, sizeof (KMF_DATA), datacmp);
700 		*certlist = certs;
701 
702 		/* since we sorted the list, just return the number of hits */
703 		*numcerts = hits;
704 	}
705 	return (rv);
706 }
707 
708 static KMF_RETURN
709 kmf_load_cert(KMF_HANDLE *kmfh,
710 	KMF_FINDCERT_PARAMS *params,
711 	char *pathname,
712 	KMF_DATA *cert)
713 {
714 	KMF_RETURN rv = KMF_OK;
715 	X509 *x509cert = NULL;
716 
717 	rv = load_X509cert(kmfh, params, pathname, &x509cert);
718 	if (rv == KMF_OK && x509cert != NULL && cert != NULL) {
719 		rv = ssl_cert2KMFDATA(kmfh, x509cert, cert);
720 		if (rv != KMF_OK) {
721 			goto cleanup;
722 		}
723 		if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) {
724 			rv = KMF_CheckCertDate(kmfh, cert);
725 		} else if (params->find_cert_validity == KMF_EXPIRED_CERTS) {
726 			rv = KMF_CheckCertDate(kmfh, cert);
727 			if (rv == KMF_OK)  {
728 				/*
729 				 * This is a valid cert so skip it.
730 				 */
731 				rv = KMF_ERR_CERT_NOT_FOUND;
732 			}
733 			if (rv == KMF_ERR_VALIDITY_PERIOD) {
734 				/*
735 				 * We want to return success when we
736 				 * find an invalid cert.
737 				 */
738 				rv = KMF_OK;
739 				goto cleanup;
740 			}
741 		}
742 	}
743 cleanup:
744 	if (x509cert != NULL)
745 		X509_free(x509cert);
746 
747 	return (rv);
748 }
749 
750 static EVP_PKEY *
751 openssl_load_key(KMF_HANDLE_T handle, const char *file)
752 {
753 	BIO *keyfile = NULL;
754 	EVP_PKEY *pkey = NULL;
755 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
756 	KMF_ENCODE_FORMAT format;
757 
758 	if (file == NULL) {
759 		return (NULL);
760 	}
761 
762 	if (KMF_GetFileFormat((char *)file, &format) != KMF_OK)
763 		return (NULL);
764 
765 	keyfile = BIO_new_file(file, "rb");
766 	if (keyfile == NULL) {
767 		goto end;
768 	}
769 
770 	if (format == KMF_FORMAT_ASN1)
771 		pkey = d2i_PrivateKey_bio(keyfile, NULL);
772 	else if (format == KMF_FORMAT_PEM ||
773 		format == KMF_FORMAT_PEM_KEYPAIR)
774 		pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL);
775 
776 end:
777 	if (pkey == NULL)
778 		SET_ERROR(kmfh, ERR_get_error());
779 
780 	if (keyfile != NULL)
781 		(void) BIO_free(keyfile);
782 
783 	return (pkey);
784 }
785 
786 KMF_RETURN
787 OpenSSL_FindCert(KMF_HANDLE_T handle,
788 	KMF_FINDCERT_PARAMS *params,
789 	KMF_X509_DER_CERT *kmf_cert,
790 	uint32_t *num_certs)
791 {
792 	KMF_RETURN rv = KMF_OK;
793 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
794 	char *fullpath;
795 	int i;
796 
797 	if (num_certs == NULL || params == NULL)
798 		return (KMF_ERR_BAD_PARAMETER);
799 
800 	*num_certs = 0;
801 
802 	fullpath = get_fullpath(params->sslparms.dirpath,
803 		params->sslparms.certfile);
804 
805 	if (fullpath == NULL)
806 		return (KMF_ERR_BAD_PARAMETER);
807 
808 	if (isdir(fullpath)) {
809 		DIR *dirp;
810 		struct dirent *dp;
811 		int n = 0;
812 
813 		/* open all files in the directory and attempt to read them */
814 		if ((dirp = opendir(fullpath)) == NULL) {
815 			return (KMF_ERR_BAD_PARAMETER);
816 		}
817 		while ((dp = readdir(dirp)) != NULL) {
818 			char *fname;
819 			KMF_DATA *certlist = NULL;
820 			uint32_t numcerts = 0;
821 
822 			if (strcmp(dp->d_name, ".") == 0 ||
823 			    strcmp(dp->d_name, "..") == 0)
824 				continue;
825 
826 			fname = get_fullpath(fullpath,
827 				(char *)&dp->d_name);
828 
829 			rv = load_certs(kmfh, params, fname, &certlist,
830 				&numcerts);
831 
832 			if (rv != KMF_OK) {
833 				free(fname);
834 				if (certlist != NULL) {
835 					for (i = 0; i < numcerts; i++)
836 						KMF_FreeData(&certlist[i]);
837 					free(certlist);
838 				}
839 				continue;
840 			}
841 
842 			/* If load succeeds, add certdata to the list */
843 			if (kmf_cert != NULL) {
844 				for (i = 0; i < numcerts; i++) {
845 					kmf_cert[n].certificate.Data =
846 						certlist[i].Data;
847 					kmf_cert[n].certificate.Length =
848 						certlist[i].Length;
849 
850 					kmf_cert[n].kmf_private.keystore_type =
851 						KMF_KEYSTORE_OPENSSL;
852 					kmf_cert[n].kmf_private.flags =
853 						KMF_FLAG_CERT_VALID;
854 					kmf_cert[n].kmf_private.label =
855 						strdup(fname);
856 					n++;
857 				}
858 				free(certlist);
859 			} else {
860 				for (i = 0; i < numcerts; i++)
861 					KMF_FreeData(&certlist[i]);
862 				free(certlist);
863 				n += numcerts;
864 			}
865 			free(fname);
866 		}
867 		(*num_certs) = n;
868 		if (*num_certs == 0)
869 			rv = KMF_ERR_CERT_NOT_FOUND;
870 		if (*num_certs > 0)
871 			rv = KMF_OK;
872 exit:
873 		(void) closedir(dirp);
874 	} else {
875 		KMF_DATA *certlist = NULL;
876 		uint32_t numcerts = 0;
877 
878 		rv = load_certs(kmfh, params, fullpath, &certlist, &numcerts);
879 		if (rv != KMF_OK) {
880 			free(fullpath);
881 			return (rv);
882 		}
883 
884 		if (kmf_cert != NULL && certlist != NULL) {
885 			for (i = 0; i < numcerts; i++) {
886 				kmf_cert[i].certificate.Data =
887 					certlist[i].Data;
888 				kmf_cert[i].certificate.Length =
889 					certlist[i].Length;
890 				kmf_cert[i].kmf_private.keystore_type =
891 					KMF_KEYSTORE_OPENSSL;
892 				kmf_cert[i].kmf_private.flags =
893 					KMF_FLAG_CERT_VALID;
894 				kmf_cert[i].kmf_private.label =
895 					strdup(fullpath);
896 			}
897 			free(certlist);
898 		} else {
899 			if (certlist != NULL) {
900 				for (i = 0; i < numcerts; i++)
901 					KMF_FreeData(&certlist[i]);
902 				free(certlist);
903 			}
904 		}
905 		*num_certs = numcerts;
906 	}
907 
908 	free(fullpath);
909 
910 	return (rv);
911 }
912 
913 void
914 /*ARGSUSED*/
915 OpenSSL_FreeKMFCert(KMF_HANDLE_T handle,
916 	KMF_X509_DER_CERT *kmf_cert)
917 {
918 	if (kmf_cert != NULL) {
919 		if (kmf_cert->certificate.Data != NULL) {
920 			free(kmf_cert->certificate.Data);
921 			kmf_cert->certificate.Data = NULL;
922 			kmf_cert->certificate.Length = 0;
923 		}
924 		if (kmf_cert->kmf_private.label)
925 			free(kmf_cert->kmf_private.label);
926 	}
927 }
928 
929 KMF_RETURN
930 OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params,
931     KMF_DATA * pcert)
932 {
933 	KMF_RETURN ret = KMF_OK;
934 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
935 	X509 *xcert = NULL;
936 	FILE *fp;
937 	unsigned char *outbuf;
938 	unsigned char *outbuf_p;
939 	char *fullpath;
940 	int outbuflen;
941 	int len;
942 	KMF_ENCODE_FORMAT format;
943 
944 	if (params == NULL || params->ks_opt_u.openssl_opts.certfile == NULL) {
945 		return (KMF_ERR_BAD_PARAMETER);
946 	}
947 
948 	/*
949 	 * check if the cert output format is supported by OPENSSL.
950 	 * however, since the keystore for OPENSSL is just a file, we have
951 	 * no way to store the format along with the file.
952 	 */
953 	format = params->sslparms.format;
954 	if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM)
955 		return (KMF_ERR_BAD_CERT_FORMAT);
956 
957 
958 	fullpath = get_fullpath(params->sslparms.dirpath,
959 		params->sslparms.certfile);
960 	if (fullpath == NULL)
961 		return (KMF_ERR_BAD_PARAMETER);
962 
963 	/*
964 	 * When storing a certificate, you must specify a filename.
965 	 */
966 	if (isdir(fullpath)) {
967 		free(fullpath);
968 		return (KMF_ERR_BAD_PARAMETER);
969 	}
970 
971 	/* copy cert data to outbuf */
972 	outbuflen = pcert->Length;
973 	outbuf = malloc(outbuflen);
974 	if (outbuf == NULL) {
975 		free(fullpath);
976 		return (KMF_ERR_MEMORY);
977 	}
978 	(void) memcpy(outbuf, pcert->Data, pcert->Length);
979 
980 	if ((fp = fopen(fullpath, "w")) ==
981 		NULL) {
982 		SET_SYS_ERROR(kmfh, errno);
983 		ret = KMF_ERR_INTERNAL;
984 		goto out;
985 	}
986 
987 	if (format == KMF_FORMAT_ASN1) {
988 		len = fwrite(outbuf, 1, outbuflen, fp);
989 		if (len != outbuflen) {
990 			SET_SYS_ERROR(kmfh, errno);
991 			ret = KMF_ERR_WRITE_FILE;
992 		} else {
993 			ret = KMF_OK;
994 		}
995 		goto out;
996 	}
997 
998 	/*
999 	 * The output format is not KMF_FORMAT_ASN1, so we will
1000 	 * Convert the cert data to OpenSSL internal X509 first.
1001 	 */
1002 	outbuf_p = outbuf; /* use a temp pointer; required by openssl */
1003 	xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, outbuflen);
1004 	if (xcert == NULL) {
1005 		SET_ERROR(kmfh, ERR_get_error());
1006 		ret = KMF_ERR_ENCODING;
1007 		goto out;
1008 	}
1009 
1010 	if (format == KMF_FORMAT_PEM) {
1011 		/* Convert to the PEM format and write it out */
1012 		if (!PEM_write_X509(fp, xcert)) {
1013 			SET_ERROR(kmfh, ERR_get_error());
1014 			ret = KMF_ERR_ENCODING;
1015 		} else {
1016 			ret = KMF_OK;
1017 		}
1018 		goto out;
1019 	}
1020 
1021 out:
1022 	if (fullpath != NULL)
1023 		free(fullpath);
1024 
1025 	if (outbuf != NULL) {
1026 		free(outbuf);
1027 	}
1028 	if (fp != NULL) {
1029 		(void) fclose(fp);
1030 	}
1031 
1032 	if (xcert != NULL) {
1033 		X509_free(xcert);
1034 	}
1035 
1036 	return (ret);
1037 }
1038 
1039 KMF_RETURN
1040 OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params)
1041 {
1042 	KMF_RETURN rv;
1043 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1044 	char *fullpath = NULL;
1045 	KMF_DATA certdata = {NULL, 0};
1046 
1047 	if (params == NULL) {
1048 		return (KMF_ERR_BAD_PARAMETER);
1049 	}
1050 
1051 	fullpath = get_fullpath(params->sslparms.dirpath,
1052 		params->sslparms.certfile);
1053 
1054 	if (fullpath == NULL)
1055 		return (KMF_ERR_BAD_PARAMETER);
1056 
1057 	if (isdir(fullpath)) {
1058 		DIR *dirp;
1059 		struct dirent *dp;
1060 
1061 		/* open all files in the directory and attempt to read them */
1062 		if ((dirp = opendir(fullpath)) == NULL) {
1063 			return (KMF_ERR_BAD_PARAMETER);
1064 		}
1065 
1066 		while ((dp = readdir(dirp)) != NULL) {
1067 			if (strcmp(dp->d_name, ".") != 0 &&
1068 			    strcmp(dp->d_name, "..") != 0) {
1069 				char *fname;
1070 
1071 				fname = get_fullpath(fullpath,
1072 					(char *)&dp->d_name);
1073 
1074 				if (fname == NULL) {
1075 					rv = KMF_ERR_MEMORY;
1076 					break;
1077 				}
1078 
1079 				rv = kmf_load_cert(kmfh, params, fname,
1080 				    &certdata);
1081 
1082 				if (rv == KMF_ERR_CERT_NOT_FOUND) {
1083 					free(fname);
1084 					if (certdata.Data)
1085 						free(certdata.Data);
1086 					rv = KMF_OK;
1087 					continue;
1088 				} else if (rv != KMF_OK) {
1089 					free(fname);
1090 					break;
1091 				}
1092 
1093 				if (unlink(fname) != 0) {
1094 					SET_SYS_ERROR(kmfh, errno);
1095 					rv = KMF_ERR_INTERNAL;
1096 					free(fname);
1097 					break;
1098 				}
1099 				free(fname);
1100 				if (certdata.Data)
1101 					free(certdata.Data);
1102 			}
1103 		}
1104 		(void) closedir(dirp);
1105 	} else {
1106 		/* Just try to load a single certificate */
1107 		rv = kmf_load_cert(kmfh, params, fullpath, &certdata);
1108 		if (rv == KMF_OK) {
1109 			if (unlink(fullpath) != 0) {
1110 				SET_SYS_ERROR(kmfh, errno);
1111 				rv = KMF_ERR_INTERNAL;
1112 			}
1113 		}
1114 	}
1115 
1116 out:
1117 	if (fullpath != NULL)
1118 		free(fullpath);
1119 
1120 	if (certdata.Data)
1121 		free(certdata.Data);
1122 
1123 	return (rv);
1124 }
1125 
1126 KMF_RETURN
1127 OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
1128 	KMF_DATA *keydata)
1129 {
1130 	KMF_RETURN rv = KMF_OK;
1131 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1132 	int n;
1133 
1134 	if (key == NULL || keydata == NULL ||
1135 	    key->keyp == NULL)
1136 		return (KMF_ERR_BAD_PARAMETER);
1137 
1138 	if (key->keyalg == KMF_RSA) {
1139 		RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp);
1140 
1141 		if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) {
1142 			SET_ERROR(kmfh, ERR_get_error());
1143 			return (KMF_ERR_ENCODING);
1144 		}
1145 		RSA_free(pubkey);
1146 	} else if (key->keyalg == KMF_DSA) {
1147 		DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp);
1148 
1149 		if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) {
1150 			SET_ERROR(kmfh, ERR_get_error());
1151 			return (KMF_ERR_ENCODING);
1152 		}
1153 		DSA_free(pubkey);
1154 	} else {
1155 	    return (KMF_ERR_BAD_PARAMETER);
1156 	}
1157 	keydata->Length = n;
1158 
1159 cleanup:
1160 	if (rv != KMF_OK) {
1161 		if (keydata->Data)
1162 			free(keydata->Data);
1163 		keydata->Data = NULL;
1164 		keydata->Length = 0;
1165 	}
1166 
1167 	return (rv);
1168 }
1169 
1170 static KMF_RETURN
1171 ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out,
1172 	KMF_CREDENTIAL *cred, EVP_PKEY *pkey)
1173 {
1174 	int rv = 0;
1175 	RSA *rsa;
1176 	DSA *dsa;
1177 
1178 	switch (format) {
1179 		case KMF_FORMAT_ASN1:
1180 			if (pkey->type == EVP_PKEY_RSA) {
1181 				rsa = EVP_PKEY_get1_RSA(pkey);
1182 				rv = i2d_RSAPrivateKey_bio(out, rsa);
1183 				RSA_free(rsa);
1184 			} else if (pkey->type == EVP_PKEY_DSA) {
1185 				dsa = EVP_PKEY_get1_DSA(pkey);
1186 				rv = i2d_DSAPrivateKey_bio(out, dsa);
1187 				DSA_free(dsa);
1188 			}
1189 			if (rv == 1) {
1190 				rv = KMF_OK;
1191 			} else {
1192 				SET_ERROR(kmfh, rv);
1193 			}
1194 			break;
1195 		case KMF_FORMAT_PEM:
1196 			if (pkey->type == EVP_PKEY_RSA) {
1197 				rsa = EVP_PKEY_get1_RSA(pkey);
1198 				rv = PEM_write_bio_RSAPrivateKey(out,
1199 					rsa,
1200 					NULL /* encryption type */,
1201 					NULL, 0, NULL,
1202 					cred->cred);
1203 				RSA_free(rsa);
1204 			} else if (pkey->type == EVP_PKEY_DSA) {
1205 				dsa = EVP_PKEY_get1_DSA(pkey);
1206 				rv = PEM_write_bio_DSAPrivateKey(out,
1207 					dsa,
1208 					NULL /* encryption type */,
1209 					NULL, 0, NULL,
1210 					cred->cred);
1211 				DSA_free(dsa);
1212 			}
1213 
1214 			if (rv == 1) {
1215 				rv = KMF_OK;
1216 			} else {
1217 				SET_ERROR(kmfh, rv);
1218 			}
1219 			break;
1220 
1221 		default:
1222 			rv = KMF_ERR_BAD_PARAMETER;
1223 	}
1224 
1225 	return (rv);
1226 }
1227 
1228 KMF_RETURN
1229 OpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params,
1230 	KMF_KEY_HANDLE *privkey, KMF_KEY_HANDLE *pubkey)
1231 {
1232 	KMF_RETURN rv = KMF_OK;
1233 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1234 	int format;
1235 	uint32_t eValue = 0x010001;
1236 	RSA *sslPrivKey = NULL;
1237 	DSA *sslDSAKey = NULL;
1238 	EVP_PKEY *eprikey = NULL;
1239 	EVP_PKEY *epubkey = NULL;
1240 	BIO *out = NULL;
1241 	char *fullpath = NULL;
1242 
1243 	if (params == NULL || params->sslparms.keyfile == NULL) {
1244 		return (KMF_ERR_BAD_PARAMETER);
1245 	}
1246 
1247 	fullpath = get_fullpath(params->sslparms.dirpath,
1248 			params->sslparms.keyfile);
1249 
1250 	if (fullpath == NULL)
1251 		return (KMF_ERR_BAD_PARAMETER);
1252 
1253 	/* If the requested file exists, return an error */
1254 	if (access(fullpath, F_OK) == 0) {
1255 		free(fullpath);
1256 		return (KMF_ERR_DUPLICATE_KEYFILE);
1257 	}
1258 
1259 	eprikey = EVP_PKEY_new();
1260 	if (eprikey == NULL) {
1261 		SET_ERROR(kmfh, ERR_get_error());
1262 		rv = KMF_ERR_KEYGEN_FAILED;
1263 		goto cleanup;
1264 	}
1265 	epubkey = EVP_PKEY_new();
1266 	if (epubkey == NULL) {
1267 		SET_ERROR(kmfh, ERR_get_error());
1268 		rv = KMF_ERR_KEYGEN_FAILED;
1269 		goto cleanup;
1270 	}
1271 	if (params->keytype == KMF_RSA) {
1272 		if (params->rsa_exponent.len > 0 &&
1273 		    params->rsa_exponent.len <= sizeof (eValue) &&
1274 		    params->rsa_exponent.val != NULL)
1275 			/*LINTED*/
1276 			eValue = *(uint32_t *)params->rsa_exponent.val;
1277 
1278 		sslPrivKey = RSA_generate_key(params->keylength, eValue,
1279 			NULL, NULL);
1280 		if (sslPrivKey == NULL) {
1281 			SET_ERROR(kmfh, ERR_get_error());
1282 			rv = KMF_ERR_KEYGEN_FAILED;
1283 		} else {
1284 			if (privkey != NULL &&
1285 				EVP_PKEY_set1_RSA(eprikey, sslPrivKey)) {
1286 				privkey->kstype = KMF_KEYSTORE_OPENSSL;
1287 				privkey->keyalg = KMF_RSA;
1288 				privkey->keyclass = KMF_ASYM_PRI;
1289 				privkey->israw = FALSE;
1290 				privkey->keylabel = (char *)strdup(fullpath);
1291 				privkey->keyp = (void *)eprikey;
1292 			}
1293 			/* OpenSSL derives the public key from the private */
1294 			if (pubkey != NULL &&
1295 				EVP_PKEY_set1_RSA(epubkey, sslPrivKey)) {
1296 				pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1297 				pubkey->keyalg = KMF_RSA;
1298 				pubkey->israw = FALSE;
1299 				pubkey->keyclass = KMF_ASYM_PUB;
1300 				pubkey->keylabel = (char *)strdup(fullpath);
1301 				pubkey->keyp = (void *)epubkey;
1302 			}
1303 		}
1304 	} else if (params->keytype == KMF_DSA) {
1305 		sslDSAKey = DSA_new();
1306 		if (sslDSAKey == NULL) {
1307 			SET_ERROR(kmfh, ERR_get_error());
1308 			return (KMF_ERR_MEMORY);
1309 		}
1310 
1311 		if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) ==
1312 			NULL) {
1313 			SET_ERROR(kmfh, ERR_get_error());
1314 			rv = KMF_ERR_KEYGEN_FAILED;
1315 			goto cleanup;
1316 		}
1317 		if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) ==
1318 			NULL) {
1319 			SET_ERROR(kmfh, ERR_get_error());
1320 			rv = KMF_ERR_KEYGEN_FAILED;
1321 			goto cleanup;
1322 		}
1323 		if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) ==
1324 			NULL) {
1325 			SET_ERROR(kmfh, ERR_get_error());
1326 			rv = KMF_ERR_KEYGEN_FAILED;
1327 			goto cleanup;
1328 		}
1329 
1330 		if (!DSA_generate_key(sslDSAKey)) {
1331 			SET_ERROR(kmfh, ERR_get_error());
1332 			rv = KMF_ERR_KEYGEN_FAILED;
1333 			goto cleanup;
1334 		}
1335 
1336 		if (privkey != NULL) {
1337 			privkey->kstype = KMF_KEYSTORE_OPENSSL;
1338 			privkey->keyalg = KMF_DSA;
1339 			privkey->keyclass = KMF_ASYM_PRI;
1340 			privkey->israw = FALSE;
1341 			privkey->keylabel = (char *)strdup(fullpath);
1342 			if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) {
1343 				privkey->keyp = (void *)eprikey;
1344 			} else {
1345 				SET_ERROR(kmfh, ERR_get_error());
1346 				rv = KMF_ERR_KEYGEN_FAILED;
1347 				goto cleanup;
1348 			}
1349 		}
1350 		if (pubkey != NULL) {
1351 			DSA *dp = DSA_new();
1352 			/* Make a copy for the public key */
1353 			if (dp != NULL) {
1354 				if ((dp->p = BN_new()) == NULL) {
1355 					SET_ERROR(kmfh, ERR_get_error());
1356 					rv = KMF_ERR_MEMORY;
1357 					DSA_free(dp);
1358 					goto cleanup;
1359 				}
1360 				if ((dp->q = BN_new()) == NULL) {
1361 					SET_ERROR(kmfh, ERR_get_error());
1362 					rv = KMF_ERR_MEMORY;
1363 					BN_free(dp->p);
1364 					DSA_free(dp);
1365 					goto cleanup;
1366 				}
1367 				if ((dp->g = BN_new()) == NULL) {
1368 					SET_ERROR(kmfh, ERR_get_error());
1369 					rv = KMF_ERR_MEMORY;
1370 					BN_free(dp->q);
1371 					BN_free(dp->p);
1372 					DSA_free(dp);
1373 					goto cleanup;
1374 				}
1375 				if ((dp->pub_key = BN_new()) == NULL) {
1376 					SET_ERROR(kmfh, ERR_get_error());
1377 					rv = KMF_ERR_MEMORY;
1378 					BN_free(dp->q);
1379 					BN_free(dp->p);
1380 					BN_free(dp->g);
1381 					DSA_free(dp);
1382 					goto cleanup;
1383 				}
1384 				(void) BN_copy(dp->p, sslDSAKey->p);
1385 				(void) BN_copy(dp->q, sslDSAKey->q);
1386 				(void) BN_copy(dp->g, sslDSAKey->g);
1387 				(void) BN_copy(dp->pub_key, sslDSAKey->pub_key);
1388 
1389 				pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1390 				pubkey->keyalg = KMF_DSA;
1391 				pubkey->keyclass = KMF_ASYM_PUB;
1392 				pubkey->israw = FALSE;
1393 				pubkey->keylabel = (char *)strdup(fullpath);
1394 
1395 				if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) {
1396 					pubkey->keyp = (void *)epubkey;
1397 				} else {
1398 					SET_ERROR(kmfh, ERR_get_error());
1399 					rv = KMF_ERR_KEYGEN_FAILED;
1400 					goto cleanup;
1401 				}
1402 			}
1403 		}
1404 	}
1405 
1406 	if (rv != KMF_OK) {
1407 		goto cleanup;
1408 	}
1409 
1410 	/* Store the private key to the keyfile */
1411 	format = params->sslparms.format;
1412 	out = BIO_new_file(fullpath, "wb");
1413 	if (out == NULL) {
1414 		SET_ERROR(kmfh, ERR_get_error());
1415 		rv = KMF_ERR_OPEN_FILE;
1416 		goto cleanup;
1417 	}
1418 	rv = ssl_write_private_key(kmfh, format, out, &params->cred, eprikey);
1419 
1420 cleanup:
1421 	if (rv != KMF_OK) {
1422 		if (eprikey != NULL)
1423 			EVP_PKEY_free(eprikey);
1424 
1425 		if (epubkey != NULL)
1426 			EVP_PKEY_free(epubkey);
1427 
1428 		if (pubkey->keylabel) {
1429 			free(pubkey->keylabel);
1430 			pubkey->keylabel = NULL;
1431 		}
1432 
1433 		if (privkey->keylabel) {
1434 			free(privkey->keylabel);
1435 			privkey->keylabel = NULL;
1436 		}
1437 
1438 		pubkey->keyp = NULL;
1439 		privkey->keyp = NULL;
1440 	}
1441 
1442 	if (sslPrivKey)
1443 		RSA_free(sslPrivKey);
1444 
1445 	if (sslDSAKey)
1446 		DSA_free(sslDSAKey);
1447 
1448 
1449 	if (out != NULL)
1450 		(void) BIO_free(out);
1451 
1452 	if (fullpath)
1453 		free(fullpath);
1454 
1455 	/* Protect the file by making it read-only */
1456 	if (rv == KMF_OK) {
1457 		(void) chmod(fullpath, 0400);
1458 	}
1459 	return (rv);
1460 }
1461 
1462 KMF_RETURN
1463 OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
1464 	KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output)
1465 {
1466 	KMF_RETURN ret = KMF_OK;
1467 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1468 	KMF_ALGORITHM_INDEX		AlgId;
1469 	EVP_MD_CTX ctx;
1470 	const EVP_MD *md;
1471 	if (key == NULL || AlgOID == NULL ||
1472 		tobesigned == NULL || output == NULL ||
1473 		tobesigned->Data == NULL ||
1474 		output->Data == NULL)
1475 		return (KMF_ERR_BAD_PARAMETER);
1476 
1477 	/* Map the OID to an OpenSSL algorithm */
1478 	AlgId = X509_AlgorithmOidToAlgId(AlgOID);
1479 	if (AlgId == KMF_ALGID_NONE)
1480 		return (KMF_ERR_BAD_PARAMETER);
1481 
1482 	if (key->keyalg == KMF_RSA) {
1483 		EVP_PKEY *pkey = (EVP_PKEY *)key->keyp;
1484 		uchar_t *p;
1485 		uint32_t len;
1486 		if (AlgId == KMF_ALGID_MD5WithRSA)
1487 			md = EVP_md5();
1488 		else if (AlgId == KMF_ALGID_MD2WithRSA)
1489 			md = EVP_md2();
1490 		else if (AlgId == KMF_ALGID_SHA1WithRSA)
1491 			md = EVP_sha1();
1492 		else
1493 			return (KMF_ERR_BAD_PARAMETER);
1494 
1495 		if (md == NULL) {
1496 			SET_ERROR(kmfh, ERR_get_error());
1497 			return (KMF_ERR_MEMORY);
1498 		}
1499 
1500 		(void) EVP_MD_CTX_init(&ctx);
1501 		(void) EVP_SignInit_ex(&ctx, md, NULL);
1502 		(void) EVP_SignUpdate(&ctx, tobesigned->Data,
1503 			(uint32_t)tobesigned->Length);
1504 		len = (uint32_t)output->Length;
1505 		p = output->Data;
1506 		if (!EVP_SignFinal(&ctx, p, &len, pkey)) {
1507 			SET_ERROR(kmfh, ERR_get_error());
1508 			output->Length = 0;
1509 		}
1510 		output->Length = len;
1511 		(void) EVP_MD_CTX_cleanup(&ctx);
1512 	} else if (key->keyalg == KMF_DSA) {
1513 		DSA *dsa = EVP_PKEY_get1_DSA(key->keyp);
1514 
1515 		uchar_t hash[EVP_MAX_MD_SIZE];
1516 		uint32_t hashlen;
1517 		DSA_SIG *dsasig;
1518 
1519 		/*
1520 		 * OpenSSL EVP_Sign operation automatically converts to
1521 		 * ASN.1 output so we do the operations separately so we
1522 		 * are assured of NOT getting ASN.1 output returned.
1523 		 * KMF does not want ASN.1 encoded results because
1524 		 * not all mechanisms return ASN.1 encodings (PKCS#11
1525 		 * and NSS return raw signature data).
1526 		 */
1527 		md = EVP_sha1();
1528 		EVP_MD_CTX_init(&ctx);
1529 		(void) EVP_DigestInit_ex(&ctx, md, NULL);
1530 		(void) EVP_DigestUpdate(&ctx, tobesigned->Data,
1531 			tobesigned->Length);
1532 		(void) EVP_DigestFinal_ex(&ctx, hash, &hashlen);
1533 		(void) EVP_MD_CTX_cleanup(&ctx);
1534 
1535 		dsasig = DSA_do_sign(hash, hashlen, dsa);
1536 		if (dsasig != NULL) {
1537 			int i;
1538 			output->Length = i = BN_bn2bin(dsasig->r, output->Data);
1539 			output->Length += BN_bn2bin(dsasig->s,
1540 				&output->Data[i]);
1541 			DSA_SIG_free(dsasig);
1542 		} else {
1543 			SET_ERROR(kmfh, ERR_get_error());
1544 		}
1545 	} else {
1546 		return (KMF_ERR_BAD_PARAMETER);
1547 	}
1548 cleanup:
1549 	return (ret);
1550 }
1551 
1552 KMF_RETURN
1553 /*ARGSUSED*/
1554 OpenSSL_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params,
1555 	KMF_KEY_HANDLE *key, boolean_t destroy)
1556 {
1557 	KMF_RETURN rv = KMF_OK;
1558 	if (key == NULL || key->keyp == NULL)
1559 		return (KMF_ERR_BAD_PARAMETER);
1560 
1561 	if (key->keyclass != KMF_ASYM_PUB &&
1562 		key->keyclass != KMF_ASYM_PRI &&
1563 		key->keyclass != KMF_SYMMETRIC)
1564 		return (KMF_ERR_BAD_KEY_CLASS);
1565 
1566 	if (key->keyclass == KMF_SYMMETRIC) {
1567 		KMF_FreeRawSymKey((KMF_RAW_SYM_KEY *)key->keyp);
1568 		key->keyp = NULL;
1569 	} else {
1570 		if (key->keyp != NULL) {
1571 			EVP_PKEY_free(key->keyp);
1572 			key->keyp = NULL;
1573 		}
1574 	}
1575 
1576 	if (key->keylabel != NULL) {
1577 		EVP_PKEY *pkey = NULL;
1578 		/* If the file exists, make sure it is a proper key. */
1579 		pkey = openssl_load_key(handle, key->keylabel);
1580 		if (pkey == NULL) {
1581 			free(key->keylabel);
1582 			key->keylabel = NULL;
1583 			return (KMF_ERR_KEY_NOT_FOUND);
1584 		}
1585 		EVP_PKEY_free(pkey);
1586 
1587 		if (destroy) {
1588 			if (unlink(key->keylabel) != 0) {
1589 				KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1590 				SET_SYS_ERROR(kmfh, errno);
1591 				rv = KMF_ERR_INTERNAL;
1592 			}
1593 		}
1594 		if (key->keylabel != NULL) {
1595 			free(key->keylabel);
1596 			key->keylabel = NULL;
1597 		}
1598 	}
1599 	return (rv);
1600 }
1601 
1602 KMF_RETURN
1603 OpenSSL_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params)
1604 {
1605 	KMF_RETURN 	ret = KMF_OK;
1606 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1607 	X509_CRL   	*xcrl = NULL;
1608 	X509		*xcert = NULL;
1609 	EVP_PKEY	*pkey;
1610 	KMF_ENCODE_FORMAT format;
1611 	BIO *in = NULL, *out = NULL;
1612 	int openssl_ret = 0;
1613 	char *outcrlfile = NULL;
1614 	KMF_ENCODE_FORMAT outformat;
1615 
1616 	if (params == NULL || params->sslparms.crlfile == NULL) {
1617 		return (KMF_ERR_BAD_PARAMETER);
1618 	}
1619 
1620 	if (params->sslparms.crl_check == B_TRUE &&
1621 	    params->sslparms.certfile == NULL) {
1622 		return (KMF_ERR_BAD_PARAMETER);
1623 	}
1624 
1625 	outcrlfile = get_fullpath(params->sslparms.dirpath,
1626 		params->sslparms.outcrlfile);
1627 
1628 	if (outcrlfile == NULL)
1629 		return (KMF_ERR_BAD_PARAMETER);
1630 
1631 	if (isdir(outcrlfile)) {
1632 		free(outcrlfile);
1633 		return (KMF_ERR_BAD_PARAMETER);
1634 	}
1635 
1636 	ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format);
1637 	if (ret != KMF_OK) {
1638 		free(outcrlfile);
1639 		return (ret);
1640 	}
1641 
1642 	in = BIO_new_file(params->sslparms.crlfile, "rb");
1643 	if (in == NULL)	{
1644 		SET_ERROR(kmfh, ERR_get_error());
1645 		ret = KMF_ERR_OPEN_FILE;
1646 		goto end;
1647 	}
1648 
1649 	if (format == KMF_FORMAT_ASN1) {
1650 		xcrl = d2i_X509_CRL_bio(in, NULL);
1651 	} else if (format == KMF_FORMAT_PEM) {
1652 		xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
1653 	}
1654 
1655 	if (xcrl == NULL) {
1656 		SET_ERROR(kmfh, ERR_get_error());
1657 		ret = KMF_ERR_BAD_CRLFILE;
1658 		goto end;
1659 	}
1660 
1661 	/* If bypasscheck is specified, no need to verify. */
1662 	if (params->sslparms.crl_check == B_FALSE) {
1663 		goto output;
1664 	}
1665 
1666 	ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format);
1667 	if (ret != KMF_OK)
1668 		goto end;
1669 
1670 	/* Read in the CA cert file and convert to X509 */
1671 	if (BIO_read_filename(in, params->sslparms.certfile) <= 0) {
1672 		SET_ERROR(kmfh, ERR_get_error());
1673 		ret = KMF_ERR_OPEN_FILE;
1674 		goto end;
1675 	}
1676 
1677 	if (format == KMF_FORMAT_ASN1) {
1678 		xcert = d2i_X509_bio(in, NULL);
1679 	} else if (format == KMF_FORMAT_PEM) {
1680 		xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
1681 	} else {
1682 		ret = KMF_ERR_BAD_CERT_FORMAT;
1683 		goto end;
1684 	}
1685 
1686 	if (xcert == NULL) {
1687 		SET_ERROR(kmfh, ERR_get_error());
1688 		ret = KMF_ERR_BAD_CERT_FORMAT;
1689 		goto end;
1690 	}
1691 	/* Now get the public key from the CA cert */
1692 	pkey = X509_get_pubkey(xcert);
1693 	if (!pkey) {
1694 		SET_ERROR(kmfh, ERR_get_error());
1695 		ret = KMF_ERR_BAD_CERTFILE;
1696 		goto end;
1697 	}
1698 
1699 	/* Verify the CRL with the CA's public key */
1700 	openssl_ret = X509_CRL_verify(xcrl, pkey);
1701 	EVP_PKEY_free(pkey);
1702 	if (openssl_ret > 0) {
1703 		ret = KMF_OK;  /* verify succeed */
1704 	} else {
1705 		SET_ERROR(kmfh, openssl_ret);
1706 		ret = KMF_ERR_BAD_CRLFILE;
1707 	}
1708 
1709 output:
1710 	outformat = params->sslparms.format;
1711 
1712 	out = BIO_new_file(outcrlfile, "wb");
1713 	if (out == NULL) {
1714 		SET_ERROR(kmfh, ERR_get_error());
1715 		ret = KMF_ERR_OPEN_FILE;
1716 		goto end;
1717 	}
1718 
1719 	if (outformat == KMF_FORMAT_ASN1) {
1720 		openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl);
1721 	} else if (outformat == KMF_FORMAT_PEM) {
1722 		openssl_ret = PEM_write_bio_X509_CRL(out, xcrl);
1723 	} else {
1724 		ret = KMF_ERR_BAD_PARAMETER;
1725 		goto end;
1726 	}
1727 
1728 	if (openssl_ret <= 0) {
1729 		SET_ERROR(kmfh, ERR_get_error());
1730 		ret = KMF_ERR_WRITE_FILE;
1731 	} else {
1732 		ret = KMF_OK;
1733 	}
1734 
1735 end:
1736 	if (xcrl != NULL)
1737 		X509_CRL_free(xcrl);
1738 
1739 	if (xcert != NULL)
1740 		X509_free(xcert);
1741 
1742 	if (in != NULL)
1743 		(void) BIO_free(in);
1744 
1745 	if (out != NULL)
1746 		(void) BIO_free(out);
1747 
1748 	if (outcrlfile != NULL)
1749 		free(outcrlfile);
1750 
1751 	return (ret);
1752 }
1753 
1754 KMF_RETURN
1755 OpenSSL_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params,
1756     char **crldata)
1757 {
1758 	KMF_RETURN ret = KMF_OK;
1759 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1760 	X509_CRL   *x = NULL;
1761 	KMF_ENCODE_FORMAT format;
1762 	char *crlfile = NULL;
1763 	BIO *in = NULL;
1764 	BIO *mem = NULL;
1765 	long len;
1766 	char *memptr;
1767 	char *data = NULL;
1768 
1769 	if (params == NULL || params->sslparms.crlfile == NULL) {
1770 		return (KMF_ERR_BAD_PARAMETER);
1771 	}
1772 
1773 	crlfile = get_fullpath(params->sslparms.dirpath,
1774 		params->sslparms.crlfile);
1775 
1776 	if (crlfile == NULL)
1777 		return (KMF_ERR_BAD_PARAMETER);
1778 
1779 	if (isdir(crlfile)) {
1780 		free(crlfile);
1781 		return (KMF_ERR_BAD_PARAMETER);
1782 	}
1783 
1784 	ret = KMF_IsCRLFile(handle, crlfile, &format);
1785 	if (ret != KMF_OK) {
1786 		free(crlfile);
1787 		return (ret);
1788 	}
1789 
1790 	if (bio_err == NULL)
1791 		bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
1792 
1793 	in = BIO_new_file(crlfile, "rb");
1794 	if (in == NULL)	{
1795 		SET_ERROR(kmfh, ERR_get_error());
1796 		ret = KMF_ERR_OPEN_FILE;
1797 		goto end;
1798 	}
1799 
1800 	if (format == KMF_FORMAT_ASN1) {
1801 		x = d2i_X509_CRL_bio(in, NULL);
1802 	} else if (format == KMF_FORMAT_PEM) {
1803 		x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
1804 	}
1805 
1806 	if (x == NULL) { /* should not happen */
1807 		SET_ERROR(kmfh, ERR_get_error());
1808 		ret = KMF_ERR_OPEN_FILE;
1809 		goto end;
1810 	}
1811 
1812 	mem = BIO_new(BIO_s_mem());
1813 	if (mem == NULL) {
1814 		SET_ERROR(kmfh, ERR_get_error());
1815 		ret = KMF_ERR_MEMORY;
1816 		goto end;
1817 	}
1818 
1819 	(void) X509_CRL_print(mem, x);
1820 	len = BIO_get_mem_data(mem, &memptr);
1821 	if (len <= 0) {
1822 		SET_ERROR(kmfh, ERR_get_error());
1823 		ret = KMF_ERR_MEMORY;
1824 		goto end;
1825 	}
1826 
1827 	data = malloc(len + 1);
1828 	if (data == NULL) {
1829 		ret = KMF_ERR_MEMORY;
1830 		goto end;
1831 	}
1832 
1833 	(void) memcpy(data, memptr, len);
1834 	data[len] = '\0';
1835 	*crldata = data;
1836 
1837 end:
1838 	if (x != NULL)
1839 		X509_CRL_free(x);
1840 
1841 	if (crlfile != NULL)
1842 		free(crlfile);
1843 
1844 	if (in != NULL)
1845 		(void) BIO_free(in);
1846 
1847 	if (mem != NULL)
1848 		(void) BIO_free(mem);
1849 
1850 	return (ret);
1851 }
1852 
1853 KMF_RETURN
1854 OpenSSL_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params)
1855 {
1856 	KMF_RETURN ret = KMF_OK;
1857 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1858 	KMF_ENCODE_FORMAT format;
1859 	char *crlfile = NULL;
1860 	BIO *in = NULL;
1861 
1862 	if (params == NULL || params->sslparms.crlfile == NULL) {
1863 		return (KMF_ERR_BAD_PARAMETER);
1864 	}
1865 
1866 	crlfile = get_fullpath(params->sslparms.dirpath,
1867 		params->sslparms.crlfile);
1868 
1869 	if (crlfile == NULL)
1870 		return (KMF_ERR_BAD_PARAMETER);
1871 
1872 	if (isdir(crlfile)) {
1873 		ret = KMF_ERR_BAD_PARAMETER;
1874 		goto end;
1875 	}
1876 
1877 	ret = KMF_IsCRLFile(handle, crlfile, &format);
1878 	if (ret != KMF_OK)
1879 		goto end;
1880 
1881 	if (unlink(crlfile) != 0) {
1882 		SET_SYS_ERROR(kmfh, errno);
1883 		ret = KMF_ERR_INTERNAL;
1884 		goto end;
1885 	}
1886 
1887 end:
1888 	if (in != NULL)
1889 		(void) BIO_free(in);
1890 	if (crlfile != NULL)
1891 		free(crlfile);
1892 
1893 	return (ret);
1894 }
1895 
1896 
1897 KMF_RETURN
1898 OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params)
1899 {
1900 	KMF_RETURN ret = KMF_OK;
1901 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1902 	KMF_ENCODE_FORMAT format;
1903 	BIO *in = NULL;
1904 	X509   *xcert = NULL;
1905 	X509_CRL   *xcrl = NULL;
1906 	STACK_OF(X509_REVOKED) *revoke_stack = NULL;
1907 	X509_REVOKED *revoke;
1908 	int i;
1909 
1910 	if (params == NULL || params->sslparms.crlfile == NULL ||
1911 	    params->sslparms.certfile == NULL) {
1912 		return (KMF_ERR_BAD_PARAMETER);
1913 	}
1914 
1915 	ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format);
1916 	if (ret != KMF_OK)
1917 		return (ret);
1918 
1919 	/* Read the CRL file and load it into a X509_CRL structure */
1920 	in = BIO_new_file(params->sslparms.crlfile, "rb");
1921 	if (in == NULL)	{
1922 		SET_ERROR(kmfh, ERR_get_error());
1923 		ret = KMF_ERR_OPEN_FILE;
1924 		goto end;
1925 	}
1926 
1927 	if (format == KMF_FORMAT_ASN1) {
1928 		xcrl = d2i_X509_CRL_bio(in, NULL);
1929 	} else if (format == KMF_FORMAT_PEM) {
1930 		xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
1931 	}
1932 
1933 	if (xcrl == NULL) {
1934 		SET_ERROR(kmfh, ERR_get_error());
1935 		ret = KMF_ERR_BAD_CRLFILE;
1936 		goto end;
1937 	}
1938 	(void) BIO_free(in);
1939 
1940 	/* Read the Certificate file and load it into a X509 structure */
1941 	ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format);
1942 	if (ret != KMF_OK)
1943 		goto end;
1944 
1945 	in = BIO_new_file(params->sslparms.certfile, "rb");
1946 	if (in == NULL)	{
1947 		SET_ERROR(kmfh, ERR_get_error());
1948 		ret = KMF_ERR_OPEN_FILE;
1949 		goto end;
1950 	}
1951 
1952 	if (format == KMF_FORMAT_ASN1) {
1953 		xcert = d2i_X509_bio(in, NULL);
1954 	} else if (format == KMF_FORMAT_PEM) {
1955 		xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
1956 	}
1957 
1958 	if (xcert == NULL) {
1959 		SET_ERROR(kmfh, ERR_get_error());
1960 		ret = KMF_ERR_BAD_CERTFILE;
1961 		goto end;
1962 	}
1963 
1964 	/* Check if the certificate and the CRL have same issuer */
1965 	if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) {
1966 		ret = KMF_ERR_ISSUER;
1967 		goto end;
1968 	}
1969 
1970 	/* Check to see if the certificate serial number is revoked */
1971 	revoke_stack = X509_CRL_get_REVOKED(xcrl);
1972 	if (sk_X509_REVOKED_num(revoke_stack) <= 0) {
1973 		/* No revoked certificates in the CRL file */
1974 		SET_ERROR(kmfh, ERR_get_error());
1975 		ret = KMF_ERR_EMPTY_CRL;
1976 		goto end;
1977 	}
1978 
1979 	for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) {
1980 		/*LINTED*/
1981 		revoke = sk_X509_REVOKED_value(revoke_stack, i);
1982 		if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber,
1983 		    revoke->serialNumber) == 0) {
1984 			break;
1985 		}
1986 	}
1987 
1988 	if (i < sk_X509_REVOKED_num(revoke_stack)) {
1989 		ret = KMF_OK;
1990 	} else {
1991 		ret = KMF_ERR_NOT_REVOKED;
1992 	}
1993 
1994 end:
1995 	if (in != NULL)
1996 		(void) BIO_free(in);
1997 	if (xcrl != NULL)
1998 		X509_CRL_free(xcrl);
1999 	if (xcert != NULL)
2000 		X509_free(xcert);
2001 
2002 	return (ret);
2003 }
2004 
2005 KMF_RETURN
2006 OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
2007 {
2008 	KMF_RETURN ret = KMF_OK;
2009 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2010 	char str[256];	/* OpenSSL needs at least 120 byte buffer */
2011 
2012 	ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str));
2013 	if (strlen(str)) {
2014 		*msgstr = (char *)strdup(str);
2015 		if ((*msgstr) == NULL)
2016 			ret = KMF_ERR_MEMORY;
2017 	} else {
2018 		*msgstr = NULL;
2019 	}
2020 
2021 	return (ret);
2022 }
2023 
2024 static int
2025 ext2NID(int kmfext)
2026 {
2027 	switch (kmfext) {
2028 		case KMF_X509_EXT_KEY_USAGE:
2029 			return (NID_key_usage);
2030 		case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
2031 			return (NID_private_key_usage_period);
2032 		case KMF_X509_EXT_CERT_POLICIES:
2033 			return (NID_certificate_policies);
2034 		case KMF_X509_EXT_SUBJ_ALTNAME:
2035 			return (NID_subject_alt_name);
2036 		case KMF_X509_EXT_ISSUER_ALTNAME:
2037 			return (NID_issuer_alt_name);
2038 		case KMF_X509_EXT_BASIC_CONSTRAINTS:
2039 			return (NID_basic_constraints);
2040 		case KMF_X509_EXT_EXT_KEY_USAGE:
2041 			return (NID_ext_key_usage);
2042 		case KMF_X509_EXT_AUTH_KEY_ID:
2043 			return (NID_authority_key_identifier);
2044 		case KMF_X509_EXT_CRL_DIST_POINTS:
2045 			return (NID_crl_distribution_points);
2046 		case KMF_X509_EXT_SUBJ_KEY_ID:
2047 			return (NID_subject_key_identifier);
2048 		case KMF_X509_EXT_POLICY_MAPPINGS:
2049 			return (OBJ_sn2nid("policyMappings"));
2050 		case KMF_X509_EXT_NAME_CONSTRAINTS:
2051 			return (OBJ_sn2nid("nameConstraints"));
2052 		case KMF_X509_EXT_POLICY_CONSTRAINTS:
2053 			return (OBJ_sn2nid("policyConstraints"));
2054 		case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2055 			return (OBJ_sn2nid("inhibitAnyPolicy"));
2056 		case KMF_X509_EXT_FRESHEST_CRL:
2057 			return (OBJ_sn2nid("freshestCRL"));
2058 		default:
2059 			return (NID_undef);
2060 	}
2061 }
2062 
2063 KMF_RETURN
2064 OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert,
2065 	KMF_PRINTABLE_ITEM flag, char *resultStr)
2066 {
2067 	KMF_RETURN ret = KMF_OK;
2068 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2069 	X509 *xcert = NULL;
2070 	unsigned char *outbuf = NULL;
2071 	unsigned char *outbuf_p;
2072 	char *tmpstr = NULL;
2073 	int j;
2074 	int ext_index, nid, len;
2075 	BIO *mem = NULL;
2076 	STACK *emlst = NULL;
2077 	X509_EXTENSION *ex;
2078 	X509_CINF *ci;
2079 
2080 	if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) {
2081 		return (KMF_ERR_BAD_PARAMETER);
2082 	}
2083 
2084 	/* copy cert data to outbuf */
2085 	outbuf = malloc(pcert->Length);
2086 	if (outbuf == NULL) {
2087 		return (KMF_ERR_MEMORY);
2088 	}
2089 	(void) memcpy(outbuf, pcert->Data, pcert->Length);
2090 
2091 	outbuf_p = outbuf; /* use a temp pointer; required by openssl */
2092 	xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length);
2093 	if (xcert == NULL) {
2094 		SET_ERROR(kmfh, ERR_get_error());
2095 		ret = KMF_ERR_ENCODING;
2096 		goto out;
2097 	}
2098 
2099 	mem = BIO_new(BIO_s_mem());
2100 	if (mem == NULL) {
2101 		SET_ERROR(kmfh, ERR_get_error());
2102 		ret = KMF_ERR_MEMORY;
2103 		goto out;
2104 	}
2105 
2106 	switch (flag) {
2107 	case KMF_CERT_ISSUER:
2108 		(void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0,
2109 		    XN_FLAG_SEP_CPLUS_SPC);
2110 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2111 		break;
2112 
2113 	case KMF_CERT_SUBJECT:
2114 		(void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0,
2115 		    XN_FLAG_SEP_CPLUS_SPC);
2116 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2117 		break;
2118 
2119 	case KMF_CERT_VERSION:
2120 		tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version);
2121 		(void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN);
2122 		OPENSSL_free(tmpstr);
2123 		len = strlen(resultStr);
2124 		break;
2125 
2126 	case KMF_CERT_SERIALNUM:
2127 		if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) {
2128 			(void) strcpy(resultStr, "0x");
2129 			len = BIO_gets(mem, &resultStr[2],
2130 				KMF_CERT_PRINTABLE_LEN - 2);
2131 		}
2132 		break;
2133 
2134 	case KMF_CERT_NOTBEFORE:
2135 		(void) ASN1_TIME_print(mem, X509_get_notBefore(xcert));
2136 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2137 		break;
2138 
2139 	case KMF_CERT_NOTAFTER:
2140 		(void) ASN1_TIME_print(mem, X509_get_notAfter(xcert));
2141 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2142 		break;
2143 
2144 	case KMF_CERT_PUBKEY_DATA:
2145 		{
2146 			EVP_PKEY *pkey = X509_get_pubkey(xcert);
2147 			if (pkey == NULL) {
2148 				SET_ERROR(kmfh, ERR_get_error());
2149 				ret = KMF_ERR_ENCODING;
2150 				goto out;
2151 			}
2152 
2153 			if (pkey->type == EVP_PKEY_RSA) {
2154 				(void) BIO_printf(mem,
2155 					"RSA Public Key: (%d bit)\n",
2156 					BN_num_bits(pkey->pkey.rsa->n));
2157 				(void) RSA_print(mem, pkey->pkey.rsa, 0);
2158 			} else if (pkey->type == EVP_PKEY_DSA) {
2159 				(void) BIO_printf(mem,
2160 					"%12sDSA Public Key:\n", "");
2161 				(void) DSA_print(mem, pkey->pkey.dsa, 0);
2162 			} else {
2163 				(void) BIO_printf(mem,
2164 					"%12sUnknown Public Key:\n", "");
2165 			}
2166 			(void) BIO_printf(mem, "\n");
2167 			EVP_PKEY_free(pkey);
2168 		}
2169 		len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2170 		break;
2171 	case KMF_CERT_SIGNATURE_ALG:
2172 	case KMF_CERT_PUBKEY_ALG:
2173 		if (flag == KMF_CERT_SIGNATURE_ALG) {
2174 			len = i2a_ASN1_OBJECT(mem,
2175 				xcert->sig_alg->algorithm);
2176 		} else {
2177 			len = i2a_ASN1_OBJECT(mem,
2178 				xcert->cert_info->key->algor->algorithm);
2179 		}
2180 
2181 		if (len > 0) {
2182 			len = BIO_read(mem, resultStr,
2183 				KMF_CERT_PRINTABLE_LEN);
2184 		}
2185 		break;
2186 
2187 	case KMF_CERT_EMAIL:
2188 		emlst = X509_get1_email(xcert);
2189 		for (j = 0; j < sk_num(emlst); j++)
2190 			(void) BIO_printf(mem, "%s\n", sk_value(emlst, j));
2191 
2192 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2193 		X509_email_free(emlst);
2194 		break;
2195 	case KMF_X509_EXT_ISSUER_ALTNAME:
2196 	case KMF_X509_EXT_SUBJ_ALTNAME:
2197 	case KMF_X509_EXT_KEY_USAGE:
2198 	case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
2199 	case KMF_X509_EXT_CERT_POLICIES:
2200 	case KMF_X509_EXT_BASIC_CONSTRAINTS:
2201 	case KMF_X509_EXT_NAME_CONSTRAINTS:
2202 	case KMF_X509_EXT_POLICY_CONSTRAINTS:
2203 	case KMF_X509_EXT_EXT_KEY_USAGE:
2204 	case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2205 	case KMF_X509_EXT_AUTH_KEY_ID:
2206 	case KMF_X509_EXT_SUBJ_KEY_ID:
2207 	case KMF_X509_EXT_POLICY_MAPPINGS:
2208 	case KMF_X509_EXT_CRL_DIST_POINTS:
2209 	case KMF_X509_EXT_FRESHEST_CRL:
2210 		nid = ext2NID(flag);
2211 		if (nid == NID_undef) {
2212 			ret = KMF_ERR_EXTENSION_NOT_FOUND;
2213 			goto out;
2214 		}
2215 		ci = xcert->cert_info;
2216 
2217 		ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1);
2218 		if (ext_index == -1) {
2219 			SET_ERROR(kmfh, ERR_get_error());
2220 
2221 			ret = KMF_ERR_EXTENSION_NOT_FOUND;
2222 			goto out;
2223 		}
2224 		ex = X509v3_get_ext(ci->extensions, ext_index);
2225 
2226 		(void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex));
2227 
2228 		if (BIO_printf(mem, ": %s\n",
2229 			X509_EXTENSION_get_critical(ex) ? "critical" : "") <=
2230 			0) {
2231 			SET_ERROR(kmfh, ERR_get_error());
2232 			ret = KMF_ERR_ENCODING;
2233 			goto out;
2234 		}
2235 		if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) {
2236 			(void) BIO_printf(mem, "%*s", 4, "");
2237 			(void) M_ASN1_OCTET_STRING_print(mem, ex->value);
2238 		}
2239 		if (BIO_write(mem, "\n", 1) <= 0) {
2240 			SET_ERROR(kmfh, ERR_get_error());
2241 			ret = KMF_ERR_ENCODING;
2242 			goto out;
2243 		}
2244 		len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2245 	}
2246 	if (len <= 0) {
2247 		SET_ERROR(kmfh, ERR_get_error());
2248 		ret = KMF_ERR_ENCODING;
2249 	}
2250 
2251 out:
2252 	if (outbuf != NULL) {
2253 		free(outbuf);
2254 	}
2255 
2256 	if (xcert != NULL) {
2257 		X509_free(xcert);
2258 	}
2259 
2260 	if (mem != NULL) {
2261 		(void) BIO_free(mem);
2262 	}
2263 
2264 	return (ret);
2265 }
2266 KMF_RETURN
2267 /*ARGSUSED*/
2268 OpenSSL_GetPrikeyByCert(KMF_HANDLE_T handle,
2269 	KMF_CRYPTOWITHCERT_PARAMS *params,
2270 	KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key,
2271 	KMF_KEY_ALG keytype)
2272 {
2273 	KMF_RETURN rv = KMF_OK;
2274 	KMF_FINDKEY_PARAMS fkparms;
2275 	uint32_t numkeys = 0;
2276 
2277 	if (params == NULL && params->sslparms.keyfile == NULL)
2278 		return (KMF_ERR_BAD_PARAMETER);
2279 
2280 	/*
2281 	 * This is really just a FindKey operation, reuse the
2282 	 * FindKey function.
2283 	 */
2284 	(void *)memset(&fkparms, 0, sizeof (fkparms));
2285 	fkparms.kstype = KMF_KEYSTORE_OPENSSL;
2286 	fkparms.keyclass = KMF_ASYM_PRI;
2287 	fkparms.keytype = keytype;
2288 	fkparms.format = params->format;
2289 	fkparms.sslparms = params->sslparms;
2290 
2291 	rv = OpenSSL_FindKey(handle, &fkparms, key, &numkeys);
2292 
2293 	return (rv);
2294 }
2295 
2296 KMF_RETURN
2297 /*ARGSUSED*/
2298 OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
2299 	KMF_OID *AlgOID, KMF_DATA *ciphertext,
2300 	KMF_DATA *output)
2301 {
2302 	KMF_RETURN		ret = KMF_OK;
2303 	RSA *rsa = NULL;
2304 	unsigned int in_len = 0, out_len = 0;
2305 	unsigned int total_decrypted = 0, modulus_len = 0;
2306 	uint8_t *in_data, *out_data;
2307 	int i, blocks;
2308 
2309 	if (key == NULL || AlgOID == NULL ||
2310 	    ciphertext == NULL || output == NULL ||
2311 	    ciphertext->Data == NULL ||
2312 	    output->Data == NULL)
2313 		return (KMF_ERR_BAD_PARAMETER);
2314 
2315 	if (key->keyalg == KMF_RSA) {
2316 		rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp);
2317 		modulus_len = RSA_size(rsa);
2318 	} else {
2319 		return (KMF_ERR_BAD_PARAMETER);
2320 	}
2321 
2322 	blocks = ciphertext->Length/modulus_len;
2323 	out_data = output->Data;
2324 	in_data = ciphertext->Data;
2325 	out_len = modulus_len - 11;
2326 	in_len = modulus_len;
2327 
2328 	for (i = 0; i < blocks; i++) {
2329 		out_len  = RSA_private_decrypt(in_len,
2330 			in_data, out_data, rsa, RSA_PKCS1_PADDING);
2331 
2332 		if (out_len == 0) {
2333 			ret = KMF_ERR_INTERNAL;
2334 			goto cleanup;
2335 		}
2336 
2337 		out_data += out_len;
2338 		total_decrypted += out_len;
2339 		in_data += in_len;
2340 	}
2341 
2342 	output->Length = total_decrypted;
2343 
2344 cleanup:
2345 	RSA_free(rsa);
2346 	if (ret != KMF_OK)
2347 		output->Length = 0;
2348 
2349 	return (ret);
2350 
2351 }
2352 
2353 /*
2354  *  This function will create a certid from issuer_cert and user_cert.
2355  *  The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2356  *  certid memory after use.
2357  */
2358 static KMF_RETURN
2359 create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert,
2360     const KMF_DATA *user_cert, OCSP_CERTID **certid)
2361 {
2362 	KMF_RETURN ret = KMF_OK;
2363 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2364 	X509   *issuer = NULL;
2365 	X509   *cert = NULL;
2366 	unsigned char *ptmp;
2367 
2368 	if (issuer_cert == NULL || user_cert == NULL) {
2369 		return (KMF_ERR_BAD_PARAMETER);
2370 	}
2371 
2372 	/* convert the DER-encoded issuer cert to an internal X509 */
2373 	ptmp = issuer_cert->Data;
2374 	issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2375 		issuer_cert->Length);
2376 	if (issuer == NULL) {
2377 		SET_ERROR(kmfh, ERR_get_error());
2378 		ret = KMF_ERR_OCSP_BAD_ISSUER;
2379 		goto end;
2380 	}
2381 
2382 	/* convert the DER-encoded user cert to an internal X509 */
2383 	ptmp = user_cert->Data;
2384 	cert = d2i_X509(NULL, (const uchar_t **)&ptmp,
2385 		user_cert->Length);
2386 	if (cert == NULL) {
2387 		SET_ERROR(kmfh, ERR_get_error());
2388 
2389 		ret = KMF_ERR_OCSP_BAD_CERT;
2390 		goto end;
2391 	}
2392 
2393 	/* create a CERTID */
2394 	*certid = OCSP_cert_to_id(NULL, cert, issuer);
2395 	if (*certid == NULL) {
2396 		SET_ERROR(kmfh, ERR_get_error());
2397 		ret = KMF_ERR_OCSP_CERTID;
2398 		goto end;
2399 	}
2400 
2401 end:
2402 	if (issuer != NULL) {
2403 		X509_free(issuer);
2404 	}
2405 
2406 	if (cert != NULL) {
2407 		X509_free(cert);
2408 	}
2409 
2410 	return (ret);
2411 }
2412 
2413 KMF_RETURN
2414 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params,
2415     char *reqfile)
2416 {
2417 	KMF_RETURN ret = KMF_OK;
2418 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2419 	OCSP_CERTID *id = NULL;
2420 	OCSP_REQUEST *req = NULL;
2421 	BIO *derbio = NULL;
2422 
2423 	if (params->user_cert == NULL || params->issuer_cert == NULL ||
2424 	    reqfile == NULL) {
2425 		return (KMF_ERR_BAD_PARAMETER);
2426 	}
2427 
2428 	ret = create_certid(handle, params->issuer_cert, params->user_cert,
2429 	    &id);
2430 	if (ret != KMF_OK) {
2431 		return (ret);
2432 	}
2433 
2434 	/* Create an OCSP request */
2435 	req = OCSP_REQUEST_new();
2436 	if (req == NULL) {
2437 		SET_ERROR(kmfh, ERR_get_error());
2438 		ret = KMF_ERR_OCSP_CREATE_REQUEST;
2439 		goto end;
2440 	}
2441 
2442 	if (!OCSP_request_add0_id(req, id)) {
2443 		ret = KMF_ERR_OCSP_CREATE_REQUEST;
2444 		goto end;
2445 	}
2446 
2447 	/* Write the request to the output file with DER encoding */
2448 	derbio = BIO_new_file(reqfile, "wb");
2449 	if (!derbio) {
2450 		SET_ERROR(kmfh, ERR_get_error());
2451 		ret = KMF_ERR_OPEN_FILE;
2452 		goto end;
2453 	}
2454 	if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) {
2455 		ret = KMF_ERR_ENCODING;
2456 	}
2457 
2458 end:
2459 	/*
2460 	 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2461 	 * will deallocate certid's space also.
2462 	 */
2463 	if (req != NULL) {
2464 		OCSP_REQUEST_free(req);
2465 	}
2466 
2467 	if (derbio != NULL) {
2468 		(void) BIO_free(derbio);
2469 	}
2470 
2471 	return (ret);
2472 }
2473 
2474 /* ocsp_find_signer_sk() is copied from openssl source */
2475 static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
2476 {
2477 	int i;
2478 	unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
2479 
2480 	/* Easy if lookup by name */
2481 	if (id->type == V_OCSP_RESPID_NAME)
2482 		return (X509_find_by_subject(certs, id->value.byName));
2483 
2484 	/* Lookup by key hash */
2485 
2486 	/* If key hash isn't SHA1 length then forget it */
2487 	if (id->value.byKey->length != SHA_DIGEST_LENGTH)
2488 		return (NULL);
2489 
2490 	keyhash = id->value.byKey->data;
2491 	/* Calculate hash of each key and compare */
2492 	for (i = 0; i < sk_X509_num(certs); i++) {
2493 		/*LINTED*/
2494 		X509 *x = sk_X509_value(certs, i);
2495 		(void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
2496 		if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
2497 			return (x);
2498 	}
2499 	return (NULL);
2500 }
2501 
2502 /* ocsp_find_signer() is copied from openssl source */
2503 /*ARGSUSED*/
2504 static int
2505 ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
2506     X509_STORE *st, unsigned long flags)
2507 {
2508 	X509 *signer;
2509 	OCSP_RESPID *rid = bs->tbsResponseData->responderId;
2510 	if ((signer = ocsp_find_signer_sk(certs, rid)))	{
2511 		*psigner = signer;
2512 		return (2);
2513 	}
2514 	if (!(flags & OCSP_NOINTERN) &&
2515 	    (signer = ocsp_find_signer_sk(bs->certs, rid))) {
2516 		*psigner = signer;
2517 		return (1);
2518 	}
2519 	/* Maybe lookup from store if by subject name */
2520 
2521 	*psigner = NULL;
2522 	return (0);
2523 }
2524 
2525 /*
2526  * This function will verify the signature of a basic response, using
2527  * the public key from the OCSP responder certificate.
2528  */
2529 static KMF_RETURN
2530 check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs,
2531     KMF_DATA *signer_cert, KMF_DATA *issuer_cert)
2532 {
2533 	KMF_RETURN ret = KMF_OK;
2534 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2535 	STACK_OF(X509) *cert_stack = NULL;
2536 	X509 *signer = NULL;
2537 	X509 *issuer = NULL;
2538 	EVP_PKEY *skey = NULL;
2539 	unsigned char *ptmp;
2540 
2541 
2542 	if (bs == NULL || issuer_cert == NULL)
2543 		return (KMF_ERR_BAD_PARAMETER);
2544 
2545 	/*
2546 	 * Find the certificate that signed the basic response.
2547 	 *
2548 	 * If signer_cert is not NULL, we will use that as the signer cert.
2549 	 * Otherwise, we will check if the issuer cert is actually the signer.
2550 	 * If we still do not find a signer, we will look for it from the
2551 	 * certificate list came with the response file.
2552 	 */
2553 	if (signer_cert != NULL) {
2554 		ptmp = signer_cert->Data;
2555 		signer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2556 		    signer_cert->Length);
2557 		if (signer == NULL) {
2558 			SET_ERROR(kmfh, ERR_get_error());
2559 			ret = KMF_ERR_OCSP_BAD_SIGNER;
2560 			goto end;
2561 		}
2562 	} else {
2563 		/*
2564 		 * Convert the issuer cert into X509 and push it into a
2565 		 * stack to be used by ocsp_find_signer().
2566 		 */
2567 		ptmp = issuer_cert->Data;
2568 		issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2569 			issuer_cert->Length);
2570 		if (issuer == NULL) {
2571 			SET_ERROR(kmfh, ERR_get_error());
2572 			ret = KMF_ERR_OCSP_BAD_ISSUER;
2573 			goto end;
2574 		}
2575 
2576 		if ((cert_stack = sk_X509_new_null()) == NULL) {
2577 			ret = KMF_ERR_INTERNAL;
2578 			goto end;
2579 		}
2580 
2581 		if (sk_X509_push(cert_stack, issuer) == NULL) {
2582 			ret = KMF_ERR_INTERNAL;
2583 			goto end;
2584 		}
2585 
2586 		ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0);
2587 		if (!ret) {
2588 			/* can not find the signer */
2589 			ret = KMF_ERR_OCSP_BAD_SIGNER;
2590 			goto end;
2591 		}
2592 	}
2593 
2594 	/* Verify the signature of the response */
2595 	skey = X509_get_pubkey(signer);
2596 	if (skey == NULL) {
2597 		ret = KMF_ERR_OCSP_BAD_SIGNER;
2598 		goto end;
2599 	}
2600 
2601 	ret = OCSP_BASICRESP_verify(bs, skey, 0);
2602 	if (ret == 0) {
2603 		ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE;
2604 		goto end;
2605 	}
2606 
2607 end:
2608 	if (issuer != NULL) {
2609 		X509_free(issuer);
2610 	}
2611 
2612 	if (signer != NULL) {
2613 		X509_free(signer);
2614 	}
2615 
2616 	if (skey != NULL) {
2617 		EVP_PKEY_free(skey);
2618 	}
2619 
2620 	if (cert_stack != NULL) {
2621 		sk_X509_free(cert_stack);
2622 	}
2623 
2624 	return (ret);
2625 }
2626 
2627 
2628 
2629 KMF_RETURN
2630 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,
2631     KMF_OCSPRESPONSE_PARAMS_INPUT *params_in,
2632     KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out)
2633 {
2634 	KMF_RETURN ret = KMF_OK;
2635 	BIO *derbio = NULL;
2636 	OCSP_RESPONSE *resp = NULL;
2637 	OCSP_BASICRESP *bs = NULL;
2638 	OCSP_CERTID *id = NULL;
2639 	OCSP_SINGLERESP *single = NULL;
2640 	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
2641 	int index, status, reason;
2642 
2643 	if (params_in == NULL || params_in->issuer_cert == NULL ||
2644 	    params_in->user_cert == NULL || params_in->response == NULL) {
2645 		return (KMF_ERR_BAD_PARAMETER);
2646 	}
2647 
2648 	if (params_out == NULL) {
2649 		return (KMF_ERR_BAD_PARAMETER);
2650 	}
2651 
2652 	/* Read in the response */
2653 	derbio = BIO_new_mem_buf(params_in->response->Data,
2654 	    params_in->response->Length);
2655 	if (!derbio) {
2656 		ret = KMF_ERR_MEMORY;
2657 		return (ret);
2658 	}
2659 
2660 	resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
2661 	if (resp == NULL) {
2662 		ret = KMF_ERR_OCSP_MALFORMED_RESPONSE;
2663 		goto end;
2664 	}
2665 
2666 	/* Check the response status */
2667 	status = OCSP_response_status(resp);
2668 	params_out->response_status = status;
2669 	if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
2670 		ret = KMF_ERR_OCSP_RESPONSE_STATUS;
2671 		goto end;
2672 	}
2673 
2674 #ifdef DEBUG
2675 	printf("Successfully checked the response file status.\n");
2676 #endif /* DEBUG */
2677 
2678 	/* Extract basic response */
2679 	bs = OCSP_response_get1_basic(resp);
2680 	if (bs == NULL) {
2681 		ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE;
2682 		goto end;
2683 	}
2684 
2685 #ifdef DEBUG
2686 	printf("Successfully retrieved the basic response.\n");
2687 #endif /* DEBUG */
2688 
2689 	/* Check the basic response signature if required */
2690 	if (params_in->ignore_response_sign == B_FALSE) {
2691 		ret = check_response_signature(handle, bs,
2692 		    params_in->signer_cert, params_in->issuer_cert);
2693 		if (ret != KMF_OK)
2694 			goto end;
2695 	}
2696 
2697 #ifdef DEBUG
2698 	printf("Successfully verified the response signature.\n");
2699 #endif /* DEBUG */
2700 
2701 	/* Create a certid for the certificate in question */
2702 	ret = create_certid(handle, params_in->issuer_cert,
2703 	    params_in->user_cert, &id);
2704 	if (ret != KMF_OK) {
2705 		ret = KMF_ERR_OCSP_CERTID;
2706 		goto end;
2707 	}
2708 
2709 #ifdef DEBUG
2710 	printf("successfully created a certid for the cert.\n");
2711 #endif /* DEBUG */
2712 
2713 	/* Find the index of the single response for the certid */
2714 	index = OCSP_resp_find(bs, id, -1);
2715 	if (index < 0) {
2716 		/* cound not find this certificate in the response */
2717 		ret = KMF_ERR_OCSP_UNKNOWN_CERT;
2718 		goto end;
2719 	}
2720 
2721 #ifdef DEBUG
2722 	printf("Successfully found the single response index for the cert.\n");
2723 #endif /* DEBUG */
2724 
2725 	/* Retrieve the single response and get the cert status */
2726 	single = OCSP_resp_get0(bs, index);
2727 	status = OCSP_single_get0_status(single, &reason, &rev, &thisupd,
2728 	    &nextupd);
2729 	if (status == V_OCSP_CERTSTATUS_GOOD) {
2730 		params_out->cert_status = OCSP_GOOD;
2731 	} else if (status == V_OCSP_CERTSTATUS_UNKNOWN) {
2732 		params_out->cert_status = OCSP_UNKNOWN;
2733 	} else { /* revoked */
2734 		params_out->cert_status = OCSP_REVOKED;
2735 		params_out->reason = reason;
2736 	}
2737 	ret = KMF_OK;
2738 
2739 	/* Verify the time */
2740 	if (!OCSP_check_validity(thisupd, nextupd, 300,
2741 	    params_in->response_lifetime)) {
2742 		ret = KMF_ERR_OCSP_STATUS_TIME_INVALID;
2743 		goto end;
2744 	}
2745 
2746 #ifdef DEBUG
2747 	printf("Successfully verify the time.\n");
2748 #endif /* DEBUG */
2749 
2750 end:
2751 	if (derbio != NULL)
2752 		(void) BIO_free(derbio);
2753 
2754 	if (resp != NULL)
2755 		OCSP_RESPONSE_free(resp);
2756 
2757 	if (bs != NULL)
2758 		OCSP_BASICRESP_free(bs);
2759 
2760 	if (id != NULL)
2761 		OCSP_CERTID_free(id);
2762 
2763 	return (ret);
2764 }
2765 
2766 static KMF_RETURN
2767 fetch_key(KMF_HANDLE_T handle, char *path,
2768 	KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key)
2769 {
2770 	KMF_RETURN rv = KMF_OK;
2771 	EVP_PKEY *pkey;
2772 	KMF_RAW_SYM_KEY *rkey = NULL;
2773 
2774 	/* Make sure the requested file actually exists. */
2775 	if (access(path, F_OK) != 0) {
2776 		return (KMF_ERR_KEY_NOT_FOUND);
2777 	}
2778 
2779 	if (keyclass == KMF_ASYM_PRI ||
2780 	    keyclass == KMF_ASYM_PUB) {
2781 		pkey = openssl_load_key(handle, path);
2782 		if (pkey == NULL) {
2783 			return (KMF_ERR_KEY_NOT_FOUND);
2784 		}
2785 		if (key != NULL) {
2786 			if (pkey->type == EVP_PKEY_RSA)
2787 				key->keyalg = KMF_RSA;
2788 			else if (pkey->type == EVP_PKEY_DSA)
2789 				key->keyalg = KMF_DSA;
2790 
2791 			key->kstype = KMF_KEYSTORE_OPENSSL;
2792 			key->keyclass = keyclass;
2793 			key->keyp = (void *)pkey;
2794 			key->israw = FALSE;
2795 			key->keylabel = path;
2796 		} else {
2797 			EVP_PKEY_free(pkey);
2798 			pkey = NULL;
2799 		}
2800 	} else if (keyclass == KMF_SYMMETRIC) {
2801 		KMF_ENCODE_FORMAT fmt;
2802 		/*
2803 		 * If the file is a recognized format,
2804 		 * then it is NOT a symmetric key.
2805 		 */
2806 		rv = KMF_GetFileFormat(path, &fmt);
2807 		if (rv == KMF_OK || fmt != 0) {
2808 			return (KMF_ERR_KEY_NOT_FOUND);
2809 		} else if (rv == KMF_ERR_ENCODING) {
2810 			/*
2811 			 * If we don't know the encoding,
2812 			 * it is probably  a symmetric key.
2813 			 */
2814 			rv = KMF_OK;
2815 		}
2816 
2817 		if (key != NULL) {
2818 			KMF_DATA keyvalue;
2819 			rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
2820 			if (rkey == NULL) {
2821 				rv = KMF_ERR_MEMORY;
2822 				goto out;
2823 			}
2824 
2825 			(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
2826 			rv = KMF_ReadInputFile(handle, path, &keyvalue);
2827 			if (rv != KMF_OK)
2828 				goto out;
2829 
2830 			rkey->keydata.len = keyvalue.Length;
2831 			rkey->keydata.val = keyvalue.Data;
2832 
2833 			key->kstype = KMF_KEYSTORE_OPENSSL;
2834 			key->keyclass = keyclass;
2835 			key->israw = TRUE;
2836 			key->keylabel = path;
2837 			key->keyp = (void *)rkey;
2838 		}
2839 	}
2840 out:
2841 	if (rv != KMF_OK) {
2842 		if (rkey != NULL) {
2843 			KMF_FreeRawSymKey(rkey);
2844 		}
2845 		if (pkey != NULL)
2846 			EVP_PKEY_free(pkey);
2847 
2848 		if (key != NULL) {
2849 			key->keyalg = KMF_KEYALG_NONE;
2850 			key->keyclass = KMF_KEYCLASS_NONE;
2851 			key->keyp = NULL;
2852 		}
2853 	}
2854 
2855 	return (rv);
2856 }
2857 
2858 KMF_RETURN
2859 OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params,
2860 	KMF_KEY_HANDLE *key, uint32_t *numkeys)
2861 {
2862 	KMF_RETURN rv = KMF_OK;
2863 	char *fullpath = NULL;
2864 
2865 	if (handle == NULL || params == NULL || numkeys == NULL)
2866 		return (KMF_ERR_BAD_PARAMETER);
2867 
2868 	if (params->keyclass != KMF_ASYM_PUB &&
2869 		params->keyclass != KMF_ASYM_PRI &&
2870 		params->keyclass != KMF_SYMMETRIC)
2871 		return (KMF_ERR_BAD_KEY_CLASS);
2872 
2873 	fullpath = get_fullpath(params->sslparms.dirpath,
2874 		params->sslparms.keyfile);
2875 
2876 	if (fullpath == NULL)
2877 		return (KMF_ERR_BAD_PARAMETER);
2878 
2879 	*numkeys = 0;
2880 
2881 	if (isdir(fullpath)) {
2882 		DIR *dirp;
2883 		struct dirent *dp;
2884 		int n = 0;
2885 
2886 		/* open all files in the directory and attempt to read them */
2887 		if ((dirp = opendir(fullpath)) == NULL) {
2888 			return (KMF_ERR_BAD_PARAMETER);
2889 		}
2890 		rewinddir(dirp);
2891 		while ((dp = readdir(dirp)) != NULL) {
2892 			if (strcmp(dp->d_name, ".") &&
2893 			    strcmp(dp->d_name, "..")) {
2894 				char *fname;
2895 
2896 				fname = get_fullpath(fullpath,
2897 					(char *)&dp->d_name);
2898 
2899 				rv = fetch_key(handle, fname,
2900 					params->keyclass,
2901 					key ? &key[n] : NULL);
2902 
2903 				if (rv == KMF_OK)
2904 					n++;
2905 
2906 				if (rv != KMF_OK || key == NULL)
2907 					free(fname);
2908 			}
2909 		}
2910 		(void) closedir(dirp);
2911 		free(fullpath);
2912 		(*numkeys) = n;
2913 	} else {
2914 		rv = fetch_key(handle, fullpath, params->keyclass, key);
2915 		if (rv == KMF_OK)
2916 			(*numkeys) = 1;
2917 
2918 		if (rv != KMF_OK || key == NULL)
2919 			free(fullpath);
2920 	}
2921 
2922 	if ((*numkeys) == 0)
2923 		rv = KMF_ERR_KEY_NOT_FOUND;
2924 
2925 	return (rv);
2926 }
2927 
2928 #define	HANDLE_PK12_ERROR { \
2929 	SET_ERROR(kmfh, ERR_get_error()); \
2930 	rv = KMF_ERR_ENCODING; \
2931 	goto out; \
2932 }
2933 
2934 static KMF_RETURN
2935 write_pkcs12(KMF_HANDLE *kmfh,
2936 	BIO *bio,
2937 	KMF_CREDENTIAL *cred,
2938 	EVP_PKEY *pkey,
2939 	X509 *sslcert)
2940 {
2941 	KMF_RETURN rv = KMF_OK;
2942 	STACK_OF(PKCS12_SAFEBAG)	*bag_stack = NULL;
2943 	PKCS12_SAFEBAG			*bag = NULL;
2944 	PKCS7				*cert_authsafe = NULL;
2945 	PKCS8_PRIV_KEY_INFO		*p8 = NULL;
2946 	PKCS7				*key_authsafe = NULL;
2947 	STACK_OF(PKCS7)			*authsafe_stack = NULL;
2948 	PKCS12				*p12_elem = NULL;
2949 	char				*lab = NULL;
2950 	int				lab_len = 0;
2951 	unsigned char keyid[EVP_MAX_MD_SIZE];
2952 	unsigned int keyidlen = 0;
2953 
2954 	/* Must have at least a cert OR a key */
2955 	if (sslcert == NULL && pkey == NULL)
2956 		return (KMF_ERR_BAD_PARAMETER);
2957 
2958 	(void) memset(keyid, 0, sizeof (keyid));
2959 	/*
2960 	 * Section 1:
2961 	 *
2962 	 * The first PKCS#12 container (safebag) will hold the certificates
2963 	 * associated with this key.  The result of this section is a
2964 	 * PIN-encrypted PKCS#7 container (authsafe).  If there are no
2965 	 * certificates, there is no point in creating the "safebag" or the
2966 	 * "authsafe" so we go to the next section.
2967 	 */
2968 	if (sslcert != NULL && pkey != NULL) {
2969 		if (X509_check_private_key(sslcert, pkey)) {
2970 			(void) X509_digest(sslcert, EVP_sha1(), keyid,
2971 				&keyidlen);
2972 		} else {
2973 			/* The key doesn't match the cert */
2974 			HANDLE_PK12_ERROR
2975 		}
2976 	}
2977 
2978 	bag_stack = sk_PKCS12_SAFEBAG_new_null();
2979 	if (bag_stack == NULL)
2980 		return (KMF_ERR_MEMORY);
2981 
2982 	if (sslcert != NULL) {
2983 		/* Convert cert from X509 struct to PKCS#12 bag */
2984 		bag = PKCS12_x5092certbag(sslcert);
2985 		if (bag == NULL) {
2986 			HANDLE_PK12_ERROR
2987 		}
2988 
2989 		/* Add the key id to the certificate bag. */
2990 		if (keyidlen > 0 &&
2991 			!PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
2992 			HANDLE_PK12_ERROR
2993 		}
2994 
2995 		/* Pile it on the bag_stack. */
2996 		if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
2997 			HANDLE_PK12_ERROR
2998 		}
2999 #if 0
3000 		/* No support for CA certs yet */
3001 		if (cacerts != NULL && ncacerts > 0) {
3002 			int i;
3003 			for (i = 0; i < ncacerts; i++) {
3004 				KMF_X509_DER_CERT *c = &cacerts[i];
3005 				X509 *ca = NULL;
3006 
3007 				uchar_t *p = (uchar_t *)c->certificate.Data;
3008 				ca = d2i_X509(NULL, &p,
3009 					c->certificate.Length);
3010 				if (ca == NULL) {
3011 					HANDLE_PK12_ERROR
3012 				}
3013 				/* Convert CA cert to PKCS#12 bag. */
3014 				bag = PKCS12_x5092certbag(ca);
3015 				if (bag == NULL) {
3016 					sk_PKCS12_SAFEBAG_pop_free(bag_stack,
3017 					    PKCS12_SAFEBAG_free);
3018 					HANDLE_PK12_ERROR
3019 				}
3020 				/* Pile it onto the bag_stack. */
3021 				if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
3022 					HANDLE_PK12_ERROR
3023 				}
3024 			}
3025 		}
3026 #endif
3027 		/* Turn bag_stack of certs into encrypted authsafe. */
3028 		cert_authsafe = PKCS12_pack_p7encdata(
3029 			NID_pbe_WithSHA1And40BitRC2_CBC,
3030 			cred->cred,
3031 			cred->credlen, NULL, 0,
3032 			PKCS12_DEFAULT_ITER,
3033 			bag_stack);
3034 
3035 		/* Clear away this bag_stack, we're done with it. */
3036 		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3037 		bag_stack = NULL;
3038 
3039 		if (cert_authsafe == NULL) {
3040 			HANDLE_PK12_ERROR
3041 		}
3042 	}
3043 	/*
3044 	 * Section 2:
3045 	 *
3046 	 * The second PKCS#12 container (safebag) will hold the private key
3047 	 * that goes with the certificates above.  The results of this section
3048 	 * is an unencrypted PKCS#7 container (authsafe).  If there is no
3049 	 * private key, there is no point in creating the "safebag" or the
3050 	 * "authsafe" so we go to the next section.
3051 	 */
3052 	if (pkey != NULL) {
3053 		p8 = EVP_PKEY2PKCS8(pkey);
3054 		if (p8 == NULL) {
3055 			HANDLE_PK12_ERROR
3056 		}
3057 		/* Put the shrouded key into a PKCS#12 bag. */
3058 		bag = PKCS12_MAKE_SHKEYBAG(
3059 			NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
3060 			cred->cred, cred->credlen,
3061 			NULL, 0, PKCS12_DEFAULT_ITER, p8);
3062 
3063 		/* Clean up the PKCS#8 shrouded key, don't need it now. */
3064 		PKCS8_PRIV_KEY_INFO_free(p8);
3065 		p8 = NULL;
3066 
3067 		if (bag == NULL) {
3068 			HANDLE_PK12_ERROR
3069 		}
3070 		if (keyidlen &&
3071 			!PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
3072 			HANDLE_PK12_ERROR
3073 		}
3074 		if (lab != NULL) {
3075 			if (!PKCS12_add_friendlyname(bag,
3076 				(char *)lab, lab_len)) {
3077 				HANDLE_PK12_ERROR
3078 			}
3079 		}
3080 		/* Start a PKCS#12 safebag container for the private key. */
3081 		bag_stack = sk_PKCS12_SAFEBAG_new_null();
3082 		if (bag_stack == NULL) {
3083 			HANDLE_PK12_ERROR
3084 		}
3085 
3086 		/* Pile on the private key on the bag_stack. */
3087 		if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
3088 			HANDLE_PK12_ERROR
3089 		}
3090 		key_authsafe = PKCS12_pack_p7data(bag_stack);
3091 
3092 		/* Clear away this bag_stack, we're done with it. */
3093 		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3094 		bag_stack = NULL;
3095 
3096 		if (key_authsafe == NULL) {
3097 			HANDLE_PK12_ERROR
3098 		}
3099 	}
3100 	/*
3101 	 * Section 3:
3102 	 *
3103 	 * This is where the two PKCS#7 containers, one for the certificates
3104 	 * and one for the private key, are put together into a PKCS#12
3105 	 * element.  This final PKCS#12 element is written to the export file.
3106 	 */
3107 
3108 	/* Start a PKCS#7 stack. */
3109 	authsafe_stack = sk_PKCS7_new_null();
3110 	if (authsafe_stack == NULL) {
3111 		HANDLE_PK12_ERROR
3112 	}
3113 	if (key_authsafe != NULL) {
3114 		if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) {
3115 			HANDLE_PK12_ERROR
3116 		}
3117 	}
3118 	if (cert_authsafe != NULL) {
3119 		if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) {
3120 			HANDLE_PK12_ERROR
3121 		}
3122 	}
3123 	p12_elem = PKCS12_init(NID_pkcs7_data);
3124 	if (p12_elem == NULL) {
3125 		sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
3126 		HANDLE_PK12_ERROR
3127 	}
3128 
3129 	/* Put the PKCS#7 stack into the PKCS#12 element. */
3130 	if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) {
3131 		HANDLE_PK12_ERROR
3132 	}
3133 	/* Clear away the PKCS#7 stack, we're done with it. */
3134 	sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
3135 	authsafe_stack = NULL;
3136 
3137 	/* Set the integrity MAC on the PKCS#12 element. */
3138 	if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen,
3139 		NULL, 0, PKCS12_DEFAULT_ITER, NULL)) {
3140 		HANDLE_PK12_ERROR
3141 	}
3142 
3143 	/* Write the PKCS#12 element to the export file. */
3144 	if (!i2d_PKCS12_bio(bio, p12_elem)) {
3145 		HANDLE_PK12_ERROR
3146 	}
3147 
3148 	PKCS12_free(p12_elem);
3149 out:
3150 	if (rv != KMF_OK) {
3151 		/* Clear away this bag_stack, we're done with it. */
3152 		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3153 		sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
3154 	}
3155 	return (rv);
3156 }
3157 
3158 static EVP_PKEY *
3159 ImportRawRSAKey(KMF_RAW_RSA_KEY *key)
3160 {
3161 	RSA		*rsa = NULL;
3162 	EVP_PKEY 	*newkey = NULL;
3163 
3164 	if ((rsa = RSA_new()) == NULL)
3165 		return (NULL);
3166 
3167 	if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL)
3168 		return (NULL);
3169 
3170 	if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) ==
3171 		NULL)
3172 		return (NULL);
3173 
3174 	if (key->priexp.val != NULL)
3175 		if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len,
3176 			rsa->d)) == NULL)
3177 			return (NULL);
3178 
3179 	if (key->prime1.val != NULL)
3180 		if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len,
3181 			rsa->p)) == NULL)
3182 			return (NULL);
3183 
3184 	if (key->prime2.val != NULL)
3185 		if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len,
3186 			rsa->q)) == NULL)
3187 			return (NULL);
3188 
3189 	if (key->exp1.val != NULL)
3190 		if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len,
3191 			rsa->dmp1)) == NULL)
3192 			return (NULL);
3193 
3194 	if (key->exp2.val != NULL)
3195 		if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len,
3196 			rsa->dmq1)) == NULL)
3197 			return (NULL);
3198 
3199 	if (key->coef.val != NULL)
3200 		if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len,
3201 			rsa->iqmp)) == NULL)
3202 			return (NULL);
3203 
3204 	if ((newkey = EVP_PKEY_new()) == NULL)
3205 		return (NULL);
3206 
3207 	(void) EVP_PKEY_set1_RSA(newkey, rsa);
3208 
3209 	/* The original key must be freed once here or it leaks memory */
3210 	RSA_free(rsa);
3211 
3212 	return (newkey);
3213 }
3214 
3215 static EVP_PKEY *
3216 ImportRawDSAKey(KMF_RAW_DSA_KEY *key)
3217 {
3218 	DSA		*dsa = NULL;
3219 	EVP_PKEY 	*newkey = NULL;
3220 
3221 	if ((dsa = DSA_new()) == NULL)
3222 		return (NULL);
3223 
3224 	if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len,
3225 		dsa->p)) == NULL)
3226 		return (NULL);
3227 
3228 	if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len,
3229 		dsa->q)) == NULL)
3230 		return (NULL);
3231 
3232 	if ((dsa->g = BN_bin2bn(key->base.val, key->base.len,
3233 		dsa->g)) == NULL)
3234 		return (NULL);
3235 
3236 	if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len,
3237 		dsa->priv_key)) == NULL)
3238 		return (NULL);
3239 
3240 	if ((newkey = EVP_PKEY_new()) == NULL)
3241 		return (NULL);
3242 
3243 	(void) EVP_PKEY_set1_DSA(newkey, dsa);
3244 
3245 	/* The original key must be freed once here or it leaks memory */
3246 	DSA_free(dsa);
3247 	return (newkey);
3248 }
3249 
3250 static KMF_RETURN
3251 ExportPK12FromRawData(KMF_HANDLE_T handle,
3252 	KMF_CREDENTIAL *cred,
3253 	int numcerts, KMF_X509_DER_CERT *certlist,
3254 	int numkeys, KMF_KEY_HANDLE *keylist,
3255 	char *filename)
3256 {
3257 	KMF_RETURN rv = KMF_OK;
3258 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3259 	BIO *bio = NULL;
3260 	X509 *xcert = NULL;
3261 	EVP_PKEY *pkey = NULL;
3262 	int i;
3263 
3264 	/*
3265 	 * Open the output file.
3266 	 */
3267 	if ((bio = BIO_new_file(filename, "wb")) == NULL) {
3268 		SET_ERROR(kmfh, ERR_get_error());
3269 		rv = KMF_ERR_OPEN_FILE;
3270 		goto cleanup;
3271 	}
3272 
3273 	if (numcerts > 0 && numkeys > 0) {
3274 		for (i = 0; rv == KMF_OK && i < numcerts; i++) {
3275 			KMF_RAW_KEY_DATA *key = NULL;
3276 			const uchar_t *p = certlist[i].certificate.Data;
3277 			long len = certlist[i].certificate.Length;
3278 
3279 			if (i < numkeys) {
3280 				key = (KMF_RAW_KEY_DATA *)keylist[i].keyp;
3281 
3282 				if (key->keytype == KMF_RSA) {
3283 					pkey = ImportRawRSAKey(
3284 						&key->rawdata.rsa);
3285 				} else if (key->keytype == KMF_DSA) {
3286 					pkey = ImportRawDSAKey(
3287 						&key->rawdata.dsa);
3288 				} else {
3289 					rv = KMF_ERR_BAD_PARAMETER;
3290 				}
3291 			}
3292 
3293 			xcert = d2i_X509(NULL, &p, len);
3294 			if (xcert == NULL) {
3295 				SET_ERROR(kmfh, ERR_get_error());
3296 				rv = KMF_ERR_ENCODING;
3297 			}
3298 			/* Stick the key and the cert into a PKCS#12 file */
3299 			rv = write_pkcs12(kmfh, bio, cred, pkey, xcert);
3300 			if (xcert)
3301 				X509_free(xcert);
3302 			if (pkey)
3303 				EVP_PKEY_free(pkey);
3304 		}
3305 	}
3306 
3307 cleanup:
3308 
3309 	if (bio != NULL)
3310 		(void) BIO_free_all(bio);
3311 
3312 	return (rv);
3313 }
3314 
3315 KMF_RETURN
3316 OpenSSL_ExportP12(KMF_HANDLE_T handle,
3317 	KMF_EXPORTP12_PARAMS *params,
3318 	int numcerts, KMF_X509_DER_CERT *certlist,
3319 	int numkeys, KMF_KEY_HANDLE *keylist,
3320 	char *filename)
3321 {
3322 	KMF_RETURN rv;
3323 	KMF_HANDLE *kmfh = (KMF_HANDLE  *)handle;
3324 	KMF_FINDCERT_PARAMS fcargs;
3325 	BIO *bio = NULL;
3326 	X509 *xcert = NULL;
3327 	char *fullpath = NULL;
3328 	EVP_PKEY *pkey = NULL;
3329 
3330 	/*
3331 	 *  First, find the certificate.
3332 	 */
3333 	if (params == NULL)
3334 		return (KMF_ERR_BAD_PARAMETER);
3335 
3336 	/*
3337 	 * If the caller already sent the raw keys and certs,
3338 	 * shortcut the search and just export that
3339 	 * data.
3340 	 *
3341 	 * One *may* export a key OR a cert by itself.
3342 	 */
3343 	if (certlist != NULL || keylist != NULL) {
3344 		rv = ExportPK12FromRawData(handle,
3345 			&params->p12cred,
3346 			numcerts, certlist,
3347 			numkeys, keylist,
3348 			filename);
3349 		return (rv);
3350 	}
3351 
3352 	if (params->sslparms.certfile != NULL) {
3353 		fullpath = get_fullpath(params->sslparms.dirpath,
3354 			params->sslparms.certfile);
3355 
3356 		if (fullpath == NULL)
3357 			return (KMF_ERR_BAD_PARAMETER);
3358 
3359 		if (isdir(fullpath)) {
3360 			free(fullpath);
3361 			return (KMF_ERR_AMBIGUOUS_PATHNAME);
3362 		}
3363 
3364 		(void *)memset(&fcargs, 0, sizeof (fcargs));
3365 		fcargs.kstype = params->kstype;
3366 		fcargs.certLabel = params->certLabel;
3367 		fcargs.issuer = params->issuer;
3368 		fcargs.subject = params->subject;
3369 		fcargs.serial = params->serial;
3370 		fcargs.idstr = params->idstr;
3371 		fcargs.sslparms.dirpath = NULL;
3372 		fcargs.sslparms.certfile = fullpath;
3373 		fcargs.sslparms.format = params->sslparms.format;
3374 
3375 		rv = load_X509cert(kmfh, &fcargs, fullpath, &xcert);
3376 		if (rv != KMF_OK)
3377 			goto end;
3378 	}
3379 
3380 	/*
3381 	 * Now find the private key.
3382 	 */
3383 	if (params->sslparms.keyfile != NULL) {
3384 		fullpath = get_fullpath(params->sslparms.dirpath,
3385 			params->sslparms.keyfile);
3386 
3387 		if (fullpath == NULL)
3388 			return (KMF_ERR_BAD_PARAMETER);
3389 
3390 		if (isdir(fullpath)) {
3391 			free(fullpath);
3392 			return (KMF_ERR_AMBIGUOUS_PATHNAME);
3393 		}
3394 
3395 		pkey = openssl_load_key(handle, fullpath);
3396 		if (pkey == NULL) {
3397 			rv = KMF_ERR_KEY_NOT_FOUND;
3398 			goto end;
3399 		}
3400 	}
3401 
3402 	/*
3403 	 * Open the output file.
3404 	 */
3405 	if ((bio = BIO_new_file(filename, "wb")) == NULL) {
3406 		SET_ERROR(kmfh, ERR_get_error());
3407 		rv = KMF_ERR_OPEN_FILE;
3408 		goto end;
3409 	}
3410 
3411 	/* Stick the key and the cert into a PKCS#12 file */
3412 	rv = write_pkcs12(kmfh, bio, &params->p12cred,
3413 		pkey, xcert);
3414 
3415 end:
3416 	if (fullpath)
3417 		free(fullpath);
3418 	if (xcert)
3419 		X509_free(xcert);
3420 	if (pkey)
3421 		EVP_PKEY_free(pkey);
3422 	if (bio)
3423 		(void) BIO_free(bio);
3424 
3425 	return (rv);
3426 }
3427 
3428 #define	MAX_CHAIN_LENGTH 100
3429 /*
3430  * Helper function to extract keys and certificates from
3431  * a single PEM file.  Typically the file should contain a
3432  * private key and an associated public key wrapped in an x509 cert.
3433  * However, the file may be just a list of X509 certs with no keys.
3434  */
3435 static KMF_RETURN
3436 extract_objects(KMF_HANDLE *kmfh, char *filename, CK_UTF8CHAR *pin,
3437 	CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs,
3438 	int *numcerts)
3439 /* ARGSUSED */
3440 {
3441 	KMF_RETURN rv = KMF_OK;
3442 	FILE *fp;
3443 	STACK_OF(X509_INFO) *x509_info_stack;
3444 	int i, ncerts = 0;
3445 	EVP_PKEY *pkey = NULL;
3446 	X509_INFO *info;
3447 	X509 *x;
3448 	X509_INFO *cert_infos[MAX_CHAIN_LENGTH];
3449 	KMF_DATA *certlist = NULL;
3450 
3451 	if (priv_key)
3452 		*priv_key = NULL;
3453 	if (certs)
3454 		*certs = NULL;
3455 	fp = fopen(filename, "r");
3456 	if (fp == NULL) {
3457 		return (KMF_ERR_OPEN_FILE);
3458 	}
3459 	x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin);
3460 	if (x509_info_stack == NULL) {
3461 		(void) fclose(fp);
3462 		return (KMF_ERR_ENCODING);
3463 	}
3464 
3465 	/*LINTED*/
3466 	while ((info = sk_X509_INFO_pop(x509_info_stack)) != NULL &&
3467 		ncerts < MAX_CHAIN_LENGTH) {
3468 		cert_infos[ncerts] = info;
3469 		ncerts++;
3470 	}
3471 
3472 	if (ncerts == 0) {
3473 		(void) fclose(fp);
3474 		return (KMF_ERR_CERT_NOT_FOUND);
3475 	}
3476 
3477 	if (priv_key != NULL) {
3478 		rewind(fp);
3479 		pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin);
3480 	}
3481 	(void) fclose(fp);
3482 
3483 	x = cert_infos[ncerts - 1]->x509;
3484 	/*
3485 	 * Make sure the private key matchs the last cert in the file.
3486 	 */
3487 	if (pkey != NULL && !X509_check_private_key(x, pkey)) {
3488 		EVP_PKEY_free(pkey);
3489 		return (KMF_ERR_KEY_MISMATCH);
3490 	}
3491 
3492 	certlist = (KMF_DATA *)malloc(ncerts * sizeof (KMF_DATA));
3493 	if (certlist == NULL) {
3494 		if (pkey != NULL)
3495 			EVP_PKEY_free(pkey);
3496 		X509_INFO_free(info);
3497 		return (KMF_ERR_MEMORY);
3498 	}
3499 
3500 	/*
3501 	 * Convert all of the certs to DER format.
3502 	 */
3503 	for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) {
3504 		info =  cert_infos[ncerts - 1 - i];
3505 
3506 		rv = ssl_cert2KMFDATA(kmfh, info->x509, &certlist[i]);
3507 
3508 		if (rv != KMF_OK) {
3509 			free(certlist);
3510 			certlist = NULL;
3511 			ncerts = 0;
3512 		}
3513 		X509_INFO_free(info);
3514 	}
3515 
3516 	if (numcerts != NULL)
3517 		*numcerts = ncerts;
3518 	if (certs != NULL)
3519 		*certs = certlist;
3520 
3521 	if (priv_key == NULL && pkey != NULL)
3522 		EVP_PKEY_free(pkey);
3523 	else if (priv_key != NULL && pkey != NULL)
3524 		*priv_key = pkey;
3525 
3526 	return (rv);
3527 }
3528 
3529 /*
3530  * Helper function to decrypt and parse PKCS#12 import file.
3531  */
3532 static KMF_RETURN
3533 extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
3534 	EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca)
3535 /* ARGSUSED */
3536 {
3537 	PKCS12		*pk12, *pk12_tmp;
3538 	EVP_PKEY	*temp_pkey = NULL;
3539 	X509		*temp_cert = NULL;
3540 	STACK_OF(X509)	*temp_ca = NULL;
3541 
3542 	if ((pk12 = PKCS12_new()) == NULL) {
3543 		return (KMF_ERR_MEMORY);
3544 	}
3545 
3546 	if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) {
3547 		/* This is ok; it seems to mean there is no more to read. */
3548 		if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 &&
3549 		    ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG)
3550 			goto end_extract_pkcs12;
3551 
3552 		PKCS12_free(pk12);
3553 		return (KMF_ERR_PKCS12_FORMAT);
3554 	}
3555 	pk12 = pk12_tmp;
3556 
3557 	if (PKCS12_parse(pk12, (char *)pin, &temp_pkey, &temp_cert,
3558 	    &temp_ca) <= 0) {
3559 		PKCS12_free(pk12);
3560 		return (KMF_ERR_PKCS12_FORMAT);
3561 	}
3562 
3563 end_extract_pkcs12:
3564 
3565 	*priv_key = temp_pkey;
3566 	*cert = temp_cert;
3567 	*ca = temp_ca;
3568 
3569 	PKCS12_free(pk12);
3570 	return (KMF_OK);
3571 }
3572 
3573 static KMF_RETURN
3574 sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to)
3575 {
3576 	KMF_RETURN rv = KMF_OK;
3577 	uint32_t sz;
3578 
3579 	sz = BN_num_bytes(from);
3580 	to->val = (uchar_t *)malloc(sz);
3581 	if (to->val == NULL)
3582 		return (KMF_ERR_MEMORY);
3583 
3584 	if ((to->len = BN_bn2bin(from, to->val)) != sz) {
3585 		free(to->val);
3586 		to->val = NULL;
3587 		to->len = 0;
3588 		rv = KMF_ERR_MEMORY;
3589 	}
3590 
3591 	return (rv);
3592 }
3593 
3594 static KMF_RETURN
3595 exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key)
3596 {
3597 	KMF_RETURN rv;
3598 	KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa;
3599 
3600 	(void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY));
3601 	if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK)
3602 		goto cleanup;
3603 
3604 	if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK)
3605 		goto cleanup;
3606 
3607 	if (rsa->d != NULL)
3608 		if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK)
3609 			goto cleanup;
3610 
3611 	if (rsa->p != NULL)
3612 		if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK)
3613 			goto cleanup;
3614 
3615 	if (rsa->q != NULL)
3616 		if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK)
3617 			goto cleanup;
3618 
3619 	if (rsa->dmp1 != NULL)
3620 		if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK)
3621 			goto cleanup;
3622 
3623 	if (rsa->dmq1 != NULL)
3624 		if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK)
3625 			goto cleanup;
3626 
3627 	if (rsa->iqmp != NULL)
3628 		if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK)
3629 			goto cleanup;
3630 cleanup:
3631 	if (rv != KMF_OK)
3632 		KMF_FreeRawKey(key);
3633 	else
3634 		key->keytype = KMF_RSA;
3635 
3636 	/*
3637 	 * Free the reference to this key, SSL will not actually free
3638 	 * the memory until the refcount == 0, so this is safe.
3639 	 */
3640 	RSA_free(rsa);
3641 
3642 	return (rv);
3643 }
3644 
3645 static KMF_RETURN
3646 exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key)
3647 {
3648 	KMF_RETURN rv;
3649 	KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa;
3650 
3651 	(void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY));
3652 	if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK)
3653 		goto cleanup;
3654 
3655 	if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK)
3656 		goto cleanup;
3657 
3658 	if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK)
3659 		goto cleanup;
3660 
3661 	if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK)
3662 		goto cleanup;
3663 
3664 cleanup:
3665 	if (rv != KMF_OK)
3666 		KMF_FreeRawKey(key);
3667 	else
3668 		key->keytype = KMF_DSA;
3669 
3670 	/*
3671 	 * Free the reference to this key, SSL will not actually free
3672 	 * the memory until the refcount == 0, so this is safe.
3673 	 */
3674 	DSA_free(dsa);
3675 
3676 	return (rv);
3677 }
3678 
3679 static KMF_RETURN
3680 add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert,
3681 	KMF_DATA **certlist, int *ncerts)
3682 {
3683 	KMF_RETURN rv = KMF_OK;
3684 	KMF_DATA *list = (*certlist);
3685 	KMF_DATA cert;
3686 	int n = (*ncerts);
3687 
3688 	if (list == NULL) {
3689 		list = (KMF_DATA *)malloc(sizeof (KMF_DATA));
3690 	} else {
3691 		list = (KMF_DATA *)realloc(list, sizeof (KMF_DATA) * (n + 1));
3692 	}
3693 
3694 	if (list == NULL)
3695 		return (KMF_ERR_MEMORY);
3696 
3697 	rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert);
3698 	if (rv == KMF_OK) {
3699 		list[n] = cert;
3700 		(*ncerts) = n + 1;
3701 
3702 		*certlist = list;
3703 	} else {
3704 		free(list);
3705 	}
3706 
3707 	return (rv);
3708 }
3709 
3710 static KMF_RETURN
3711 add_key_to_list(KMF_RAW_KEY_DATA **keylist,
3712 	KMF_RAW_KEY_DATA *newkey, int *nkeys)
3713 {
3714 	KMF_RAW_KEY_DATA *list = (*keylist);
3715 	int n = (*nkeys);
3716 
3717 	if (list == NULL) {
3718 		list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA));
3719 	} else {
3720 		list = (KMF_RAW_KEY_DATA *)realloc(list,
3721 			sizeof (KMF_RAW_KEY_DATA) * (n + 1));
3722 	}
3723 
3724 	if (list == NULL)
3725 		return (KMF_ERR_MEMORY);
3726 
3727 	list[n] = *newkey;
3728 	(*nkeys) = n + 1;
3729 
3730 	*keylist = list;
3731 
3732 	return (KMF_OK);
3733 }
3734 
3735 
3736 static KMF_RETURN
3737 convertPK12Objects(
3738 	KMF_HANDLE *kmfh,
3739 	EVP_PKEY *sslkey, X509 *sslcert, STACK_OF(X509) *sslcacerts,
3740 	KMF_RAW_KEY_DATA **keylist, int *nkeys,
3741 	KMF_DATA **certlist, int *ncerts)
3742 {
3743 	KMF_RETURN rv = KMF_OK;
3744 	KMF_RAW_KEY_DATA key;
3745 	int i;
3746 
3747 	if (sslkey != NULL) {
3748 		/* Convert SSL key to raw key */
3749 		switch (sslkey->type) {
3750 			case EVP_PKEY_RSA:
3751 				rv = exportRawRSAKey(EVP_PKEY_get1_RSA(sslkey),
3752 					&key);
3753 				if (rv != KMF_OK)
3754 					return (rv);
3755 
3756 				break;
3757 			case EVP_PKEY_DSA:
3758 				rv = exportRawDSAKey(EVP_PKEY_get1_DSA(sslkey),
3759 					&key);
3760 				if (rv != KMF_OK)
3761 					return (rv);
3762 
3763 				break;
3764 			default:
3765 				return (KMF_ERR_BAD_PARAMETER);
3766 		}
3767 
3768 		rv = add_key_to_list(keylist, &key, nkeys);
3769 		if (rv != KMF_OK)
3770 			return (rv);
3771 	}
3772 
3773 	/* Now add the certificate to the certlist */
3774 	if (sslcert != NULL) {
3775 		rv = add_cert_to_list(kmfh, sslcert, certlist, ncerts);
3776 		if (rv != KMF_OK)
3777 			return (rv);
3778 	}
3779 
3780 	/* Also add any included CA certs to the list */
3781 	for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) {
3782 		X509 *c;
3783 		/*
3784 		 * sk_X509_value() is macro that embeds a cast to (X509 *).
3785 		 * Here it translates into ((X509 *)sk_value((ca), (i))).
3786 		 * Lint is complaining about the embedded casting, and
3787 		 * to fix it, you need to fix openssl header files.
3788 		 */
3789 		/* LINTED E_BAD_PTR_CAST_ALIGN */
3790 		c = sk_X509_value(sslcacerts, i);
3791 
3792 		/* Now add the ca cert to the certlist */
3793 		rv = add_cert_to_list(kmfh, c, certlist, ncerts);
3794 		if (rv != KMF_OK)
3795 			return (rv);
3796 	}
3797 	return (rv);
3798 }
3799 
3800 KMF_RETURN
3801 openssl_read_pkcs12(KMF_HANDLE *kmfh,
3802 	char *filename, KMF_CREDENTIAL *cred,
3803 	KMF_DATA **certlist, int *ncerts,
3804 	KMF_RAW_KEY_DATA **keylist, int *nkeys)
3805 {
3806 	KMF_RETURN	rv = KMF_OK;
3807 	BIO		*bio = NULL;
3808 	EVP_PKEY	*privkey = NULL;
3809 	X509		*cert = NULL;
3810 	STACK_OF(X509)	*cacerts = NULL;
3811 
3812 	bio = BIO_new_file(filename, "rb");
3813 	if (bio == NULL) {
3814 		SET_ERROR(kmfh, ERR_get_error());
3815 		rv = KMF_ERR_OPEN_FILE;
3816 		goto end;
3817 	}
3818 
3819 	*certlist = NULL;
3820 	*keylist = NULL;
3821 	*ncerts = 0;
3822 	*nkeys = 0;
3823 	while (rv == KMF_OK) {
3824 		rv = extract_pkcs12(bio,
3825 			(uchar_t *)cred->cred,
3826 			(uint32_t)cred->credlen,
3827 			&privkey, &cert, &cacerts);
3828 
3829 		/* Reached end of import file? */
3830 		if (rv == KMF_OK && privkey == NULL &&
3831 			cert == NULL && cacerts == NULL)
3832 			break;
3833 
3834 		if (rv == KMF_OK)
3835 			/* Convert keys and certs to exportable format */
3836 			rv = convertPK12Objects(kmfh, privkey, cert, cacerts,
3837 				keylist, nkeys, certlist, ncerts);
3838 
3839 		if (privkey)
3840 			EVP_PKEY_free(privkey);
3841 
3842 		if (cert)
3843 			X509_free(cert);
3844 
3845 		if (cacerts)
3846 			sk_X509_free(cacerts);
3847 	}
3848 end:
3849 	if (bio != NULL)
3850 		(void) BIO_free(bio);
3851 
3852 	if (privkey)
3853 		EVP_PKEY_free(privkey);
3854 
3855 	if (cert)
3856 		X509_free(cert);
3857 
3858 	if (cacerts)
3859 		sk_X509_free(cacerts);
3860 
3861 	return (rv);
3862 }
3863 
3864 KMF_RETURN
3865 openssl_import_keypair(KMF_HANDLE *kmfh,
3866 	char *filename, KMF_CREDENTIAL *cred,
3867 	KMF_DATA **certlist, int *ncerts,
3868 	KMF_RAW_KEY_DATA **keylist, int *nkeys)
3869 {
3870 	KMF_RETURN	rv = KMF_OK;
3871 	EVP_PKEY	*privkey = NULL;
3872 	KMF_ENCODE_FORMAT format;
3873 
3874 	/*
3875 	 * auto-detect the file format, regardless of what
3876 	 * the 'format' parameters in the params say.
3877 	 */
3878 	rv = KMF_GetFileFormat(filename, &format);
3879 	if (rv != KMF_OK) {
3880 		if (rv == KMF_ERR_OPEN_FILE)
3881 			rv = KMF_ERR_CERT_NOT_FOUND;
3882 		return (rv);
3883 	}
3884 
3885 	/* This function only works on PEM files */
3886 	if (format != KMF_FORMAT_PEM &&
3887 		format != KMF_FORMAT_PEM_KEYPAIR)
3888 		return (KMF_ERR_ENCODING);
3889 
3890 	*certlist = NULL;
3891 	*keylist = NULL;
3892 	*ncerts = 0;
3893 	*nkeys = 0;
3894 	rv = extract_objects(kmfh, filename,
3895 		(uchar_t *)cred->cred,
3896 		(uint32_t)cred->credlen,
3897 		&privkey, certlist, ncerts);
3898 
3899 	/* Reached end of import file? */
3900 	if (rv == KMF_OK)
3901 		/* Convert keys and certs to exportable format */
3902 		rv = convertPK12Objects(kmfh, privkey, NULL, NULL,
3903 			keylist, nkeys, NULL, NULL);
3904 
3905 end:
3906 	if (privkey)
3907 		EVP_PKEY_free(privkey);
3908 
3909 	return (rv);
3910 }
3911 
3912 KMF_RETURN
3913 OpenSSL_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params,
3914 	KMF_RAW_KEY_DATA *key)
3915 {
3916 	KMF_RETURN	rv = KMF_OK;
3917 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
3918 	char		*fullpath;
3919 	EVP_PKEY	*pkey = NULL;
3920 	BIO		*bio = NULL;
3921 
3922 	if (key != NULL) {
3923 		if (key->keytype == KMF_RSA) {
3924 			pkey = ImportRawRSAKey(&key->rawdata.rsa);
3925 		} else if (key->keytype == KMF_DSA) {
3926 			pkey = ImportRawDSAKey(&key->rawdata.dsa);
3927 		} else {
3928 			rv = KMF_ERR_BAD_PARAMETER;
3929 		}
3930 	} else {
3931 		rv = KMF_ERR_BAD_PARAMETER;
3932 	}
3933 	if (rv != KMF_OK || pkey == NULL)
3934 		return (rv);
3935 
3936 	fullpath = get_fullpath(params->sslparms.dirpath,
3937 			params->sslparms.keyfile);
3938 
3939 	if (fullpath == NULL)
3940 		return (KMF_ERR_BAD_PARAMETER);
3941 
3942 	/* If the requested file exists, return an error */
3943 	if (access(fullpath, F_OK) == 0) {
3944 		free(fullpath);
3945 		return (KMF_ERR_DUPLICATE_KEYFILE);
3946 	}
3947 
3948 	bio = BIO_new_file(fullpath, "wb");
3949 	if (bio == NULL) {
3950 		SET_ERROR(kmfh, ERR_get_error());
3951 		rv = KMF_ERR_OPEN_FILE;
3952 		goto cleanup;
3953 	}
3954 
3955 	rv = ssl_write_private_key(kmfh,
3956 		params->sslparms.format,
3957 		bio, &params->cred, pkey);
3958 
3959 cleanup:
3960 	if (fullpath)
3961 		free(fullpath);
3962 
3963 	if (pkey)
3964 		EVP_PKEY_free(pkey);
3965 
3966 	if (bio)
3967 		(void) BIO_free(bio);
3968 
3969 	/* Protect the file by making it read-only */
3970 	if (rv == KMF_OK) {
3971 		(void) chmod(fullpath, 0400);
3972 	}
3973 	return (rv);
3974 }
3975 
3976 static KMF_RETURN
3977 create_deskey(DES_cblock **deskey)
3978 {
3979 	DES_cblock *key;
3980 
3981 	key = (DES_cblock *) malloc(sizeof (DES_cblock));
3982 	if (key == NULL) {
3983 		return (KMF_ERR_MEMORY);
3984 	}
3985 
3986 	if (DES_random_key(key) == 0) {
3987 		free(key);
3988 		return (KMF_ERR_KEYGEN_FAILED);
3989 	}
3990 
3991 	*deskey = key;
3992 	return (KMF_OK);
3993 }
3994 
3995 #define	KEYGEN_RETRY 3
3996 #define	DES3_KEY_SIZE 24
3997 
3998 static KMF_RETURN
3999 create_des3key(unsigned char **des3key)
4000 {
4001 	KMF_RETURN ret = KMF_OK;
4002 	DES_cblock *deskey1 = NULL;
4003 	DES_cblock *deskey2 = NULL;
4004 	DES_cblock *deskey3 = NULL;
4005 	unsigned char *newkey = NULL;
4006 	int retry;
4007 
4008 	if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) {
4009 		return (KMF_ERR_MEMORY);
4010 	}
4011 
4012 	/* create the 1st DES key */
4013 	if ((ret = create_deskey(&deskey1)) != KMF_OK) {
4014 		goto out;
4015 	}
4016 
4017 	/*
4018 	 * Create the 2nd DES key and make sure its value is different
4019 	 * from the 1st DES key.
4020 	 */
4021 	retry = 0;
4022 	do {
4023 		if (deskey2 != NULL) {
4024 			free(deskey2);
4025 			deskey2 = NULL;
4026 		}
4027 
4028 		if ((ret = create_deskey(&deskey2)) != KMF_OK) {
4029 			goto out;
4030 		}
4031 
4032 		if (memcmp((const void *) deskey1, (const void *) deskey2, 8)
4033 		    == 0) {
4034 			ret = KMF_ERR_KEYGEN_FAILED;
4035 			retry++;
4036 		}
4037 	} while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4038 
4039 	if (ret != KMF_OK) {
4040 		goto out;
4041 	}
4042 
4043 	/*
4044 	 * Create the 3rd DES key and make sure its value is different
4045 	 * from the 2nd DES key.
4046 	 */
4047 	retry = 0;
4048 	do {
4049 		if (deskey3 != NULL) {
4050 			free(deskey3);
4051 			deskey3 = NULL;
4052 		}
4053 
4054 		if ((ret = create_deskey(&deskey3)) != KMF_OK) {
4055 			goto out;
4056 		}
4057 
4058 		if (memcmp((const void *)deskey2, (const void *)deskey3, 8)
4059 		    == 0) {
4060 			ret = KMF_ERR_KEYGEN_FAILED;
4061 			retry++;
4062 		}
4063 	} while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4064 
4065 	if (ret != KMF_OK) {
4066 		goto out;
4067 	}
4068 
4069 	/* Concatenate 3 DES keys into a DES3 key */
4070 	(void) memcpy((void *)newkey, (const void *)deskey1, 8);
4071 	(void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8);
4072 	(void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8);
4073 	*des3key = newkey;
4074 
4075 out:
4076 	if (deskey1 != NULL)
4077 		free(deskey1);
4078 
4079 	if (deskey2 != NULL)
4080 		free(deskey2);
4081 
4082 	if (deskey3 != NULL)
4083 		free(deskey3);
4084 
4085 	if (ret != KMF_OK && newkey != NULL)
4086 		free(newkey);
4087 
4088 	return (ret);
4089 }
4090 
4091 KMF_RETURN
4092 OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params,
4093 	KMF_KEY_HANDLE *symkey)
4094 {
4095 	KMF_RETURN ret = KMF_OK;
4096 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4097 	char *fullpath = NULL;
4098 	KMF_RAW_SYM_KEY *rkey = NULL;
4099 	DES_cblock *deskey = NULL;
4100 	unsigned char *des3key = NULL;
4101 	unsigned char *random = NULL;
4102 	int fd = -1;
4103 
4104 	if (kmfh == NULL)
4105 		return (KMF_ERR_UNINITIALIZED);
4106 
4107 	if (params == NULL || params->sslparms.keyfile == NULL) {
4108 		return (KMF_ERR_BAD_PARAMETER);
4109 	}
4110 
4111 	fullpath = get_fullpath(params->sslparms.dirpath,
4112 		params->sslparms.keyfile);
4113 	if (fullpath == NULL)
4114 		return (KMF_ERR_BAD_PARAMETER);
4115 
4116 	/* If the requested file exists, return an error */
4117 	if (access(fullpath, F_OK) == 0) {
4118 		free(fullpath);
4119 		return (KMF_ERR_DUPLICATE_KEYFILE);
4120 	}
4121 
4122 	fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400);
4123 	if (fd == -1) {
4124 		ret = KMF_ERR_OPEN_FILE;
4125 		goto out;
4126 	}
4127 
4128 	rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
4129 	if (rkey == NULL) {
4130 		ret = KMF_ERR_MEMORY;
4131 		goto out;
4132 	}
4133 	(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
4134 
4135 	if (params->keytype == KMF_DES) {
4136 		if ((ret = create_deskey(&deskey)) != KMF_OK) {
4137 			goto out;
4138 		}
4139 		rkey->keydata.val = (uchar_t *)deskey;
4140 		rkey->keydata.len = 8;
4141 
4142 		symkey->keyalg = KMF_DES;
4143 
4144 	} else if (params->keytype == KMF_DES3) {
4145 		if ((ret = create_des3key(&des3key)) != KMF_OK) {
4146 			goto out;
4147 		}
4148 		rkey->keydata.val = (uchar_t *)des3key;
4149 		rkey->keydata.len = DES3_KEY_SIZE;
4150 		symkey->keyalg = KMF_DES3;
4151 
4152 	} else if (params->keytype == KMF_AES || params->keytype == KMF_RC4) {
4153 		int bytes;
4154 
4155 		if (params->keylength % 8 != 0) {
4156 			ret = KMF_ERR_BAD_KEY_SIZE;
4157 			goto out;
4158 		}
4159 
4160 		if (params->keytype == KMF_AES) {
4161 			if (params->keylength != 128 &&
4162 			    params->keylength != 192 &&
4163 			    params->keylength != 256) {
4164 				ret = KMF_ERR_BAD_KEY_SIZE;
4165 				goto out;
4166 			}
4167 		}
4168 
4169 		bytes = params->keylength/8;
4170 		random = malloc(bytes);
4171 		if (random == NULL) {
4172 			ret = KMF_ERR_MEMORY;
4173 			goto out;
4174 		}
4175 		if (RAND_bytes(random, bytes) != 1) {
4176 			ret = KMF_ERR_KEYGEN_FAILED;
4177 			goto out;
4178 		}
4179 
4180 		rkey->keydata.val = (uchar_t *)random;
4181 		rkey->keydata.len = bytes;
4182 		symkey->keyalg = params->keytype;
4183 
4184 	} else {
4185 		ret = KMF_ERR_BAD_KEY_TYPE;
4186 		goto out;
4187 	}
4188 
4189 	(void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len);
4190 
4191 	symkey->kstype = KMF_KEYSTORE_OPENSSL;
4192 	symkey->keyclass = KMF_SYMMETRIC;
4193 	symkey->keylabel = (char *)fullpath;
4194 	symkey->israw = TRUE;
4195 	symkey->keyp = rkey;
4196 
4197 out:
4198 	if (fd != -1)
4199 		(void) close(fd);
4200 
4201 	if (ret != KMF_OK && fullpath != NULL) {
4202 		free(fullpath);
4203 	}
4204 	if (ret != KMF_OK) {
4205 		KMF_FreeRawSymKey(rkey);
4206 		symkey->keyp = NULL;
4207 		symkey->keyalg = KMF_KEYALG_NONE;
4208 	}
4209 
4210 	return (ret);
4211 }
4212 
4213 
4214 KMF_RETURN
4215 OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, KMF_VERIFYCRL_PARAMS *params)
4216 {
4217 	KMF_RETURN	ret = KMF_OK;
4218 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4219 	BIO		*bcrl = NULL;
4220 	X509_CRL   	*xcrl = NULL;
4221 	X509		*xcert = NULL;
4222 	EVP_PKEY	*pkey;
4223 	int		sslret;
4224 	KMF_ENCODE_FORMAT crl_format;
4225 	unsigned char	*p;
4226 	long		len;
4227 
4228 	if (params->crl_name == NULL || params->tacert == NULL) {
4229 		return (KMF_ERR_BAD_PARAMETER);
4230 	}
4231 
4232 	ret = KMF_GetFileFormat(params->crl_name, &crl_format);
4233 	if (ret != KMF_OK)
4234 		return (ret);
4235 
4236 	bcrl = BIO_new_file(params->crl_name, "rb");
4237 	if (bcrl == NULL)	{
4238 		SET_ERROR(kmfh, ERR_get_error());
4239 		ret = KMF_ERR_OPEN_FILE;
4240 		goto cleanup;
4241 	}
4242 
4243 	if (crl_format == KMF_FORMAT_ASN1) {
4244 		xcrl = d2i_X509_CRL_bio(bcrl, NULL);
4245 	} else if (crl_format == KMF_FORMAT_PEM) {
4246 		xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
4247 	} else {
4248 		ret = KMF_ERR_BAD_PARAMETER;
4249 		goto cleanup;
4250 	}
4251 
4252 	if (xcrl == NULL) {
4253 		SET_ERROR(kmfh, ERR_get_error());
4254 		ret = KMF_ERR_BAD_CRLFILE;
4255 		goto cleanup;
4256 	}
4257 
4258 	p = params->tacert->Data;
4259 	len = params->tacert->Length;
4260 	xcert = d2i_X509(NULL, (const uchar_t **)&p, len);
4261 
4262 	if (xcert == NULL) {
4263 		SET_ERROR(kmfh, ERR_get_error());
4264 		ret = KMF_ERR_BAD_CERTFILE;
4265 		goto cleanup;
4266 	}
4267 
4268 	/* Get issuer certificate public key */
4269 	pkey = X509_get_pubkey(xcert);
4270 	if (!pkey) {
4271 		SET_ERROR(kmfh, ERR_get_error());
4272 		ret = KMF_ERR_BAD_CERT_FORMAT;
4273 		goto cleanup;
4274 	}
4275 
4276 	/* Verify CRL signature */
4277 	sslret = X509_CRL_verify(xcrl, pkey);
4278 	EVP_PKEY_free(pkey);
4279 	if (sslret > 0) {
4280 		ret = KMF_OK;
4281 	} else {
4282 		SET_ERROR(kmfh, sslret);
4283 		ret = KMF_ERR_BAD_CRLFILE;
4284 	}
4285 
4286 cleanup:
4287 	if (bcrl != NULL)
4288 		(void) BIO_free(bcrl);
4289 
4290 	if (xcrl != NULL)
4291 		X509_CRL_free(xcrl);
4292 
4293 	if (xcert != NULL)
4294 		X509_free(xcert);
4295 
4296 	return (ret);
4297 
4298 }
4299 
4300 KMF_RETURN
4301 OpenSSL_CheckCRLDate(KMF_HANDLE_T handle,
4302 	KMF_CHECKCRLDATE_PARAMS *params)
4303 {
4304 
4305 	KMF_RETURN	ret = KMF_OK;
4306 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4307 	KMF_ENCODE_FORMAT crl_format;
4308 	BIO		*bcrl = NULL;
4309 	X509_CRL   	*xcrl = NULL;
4310 	int		i;
4311 
4312 	if (params == NULL || params->crl_name == NULL) {
4313 		return (KMF_ERR_BAD_PARAMETER);
4314 	}
4315 
4316 	ret = KMF_IsCRLFile(handle, params->crl_name, &crl_format);
4317 	if (ret != KMF_OK)
4318 		return (ret);
4319 
4320 	bcrl = BIO_new_file(params->crl_name, "rb");
4321 	if (bcrl == NULL)	{
4322 		SET_ERROR(kmfh, ERR_get_error());
4323 		ret = KMF_ERR_OPEN_FILE;
4324 		goto cleanup;
4325 	}
4326 
4327 	if (crl_format == KMF_FORMAT_ASN1) {
4328 		xcrl = d2i_X509_CRL_bio(bcrl, NULL);
4329 	} else if (crl_format == KMF_FORMAT_PEM) {
4330 		xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
4331 	}
4332 
4333 	if (xcrl == NULL) {
4334 		SET_ERROR(kmfh, ERR_get_error());
4335 		ret = KMF_ERR_BAD_CRLFILE;
4336 		goto cleanup;
4337 	}
4338 
4339 	i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL);
4340 	if (i >= 0) {
4341 		ret = KMF_ERR_VALIDITY_PERIOD;
4342 		goto cleanup;
4343 	}
4344 
4345 	if (X509_CRL_get_nextUpdate(xcrl)) {
4346 		i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL);
4347 
4348 		if (i <= 0) {
4349 			ret = KMF_ERR_VALIDITY_PERIOD;
4350 			goto cleanup;
4351 		}
4352 	}
4353 
4354 	ret = KMF_OK;
4355 
4356 cleanup:
4357 	if (bcrl != NULL)
4358 		(void) BIO_free(bcrl);
4359 
4360 	if (xcrl != NULL)
4361 		X509_CRL_free(xcrl);
4362 
4363 	return (ret);
4364 }
4365 
4366 /*
4367  * Check a file to see if it is a CRL file with PEM or DER format.
4368  * If success, return its format in the "pformat" argument.
4369  */
4370 KMF_RETURN
4371 OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat)
4372 {
4373 	KMF_RETURN	ret = KMF_OK;
4374 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4375 	BIO		*bio = NULL;
4376 	X509_CRL   	*xcrl = NULL;
4377 
4378 	if (filename == NULL) {
4379 		return (KMF_ERR_BAD_PARAMETER);
4380 	}
4381 
4382 	bio = BIO_new_file(filename, "rb");
4383 	if (bio == NULL)	{
4384 		SET_ERROR(kmfh, ERR_get_error());
4385 		ret = KMF_ERR_OPEN_FILE;
4386 		goto out;
4387 	}
4388 
4389 	if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) {
4390 		*pformat = KMF_FORMAT_PEM;
4391 		goto out;
4392 	}
4393 	(void) BIO_free(bio);
4394 
4395 	/*
4396 	 * Now try to read it as raw DER data.
4397 	 */
4398 	bio = BIO_new_file(filename, "rb");
4399 	if (bio == NULL)	{
4400 		SET_ERROR(kmfh, ERR_get_error());
4401 		ret = KMF_ERR_OPEN_FILE;
4402 		goto out;
4403 	}
4404 
4405 	if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) {
4406 		*pformat = KMF_FORMAT_ASN1;
4407 	} else {
4408 		ret = KMF_ERR_BAD_CRLFILE;
4409 	}
4410 
4411 out:
4412 	if (bio != NULL)
4413 		(void) BIO_free(bio);
4414 
4415 	if (xcrl != NULL)
4416 		X509_CRL_free(xcrl);
4417 
4418 	return (ret);
4419 }
4420 
4421 /*
4422  * Check a file to see if it is a certficate file with PEM or DER format.
4423  * If success, return its format in the pformat argument.
4424  */
4425 KMF_RETURN
4426 OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename,
4427 	KMF_ENCODE_FORMAT *pformat)
4428 {
4429 	KMF_RETURN	ret = KMF_OK;
4430 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4431 	BIO		*bio = NULL;
4432 	X509		*xcert = NULL;
4433 
4434 	if (filename == NULL) {
4435 		return (KMF_ERR_BAD_PARAMETER);
4436 	}
4437 
4438 	ret = KMF_GetFileFormat(filename, pformat);
4439 	if (ret != KMF_OK)
4440 		return (ret);
4441 
4442 	bio = BIO_new_file(filename, "rb");
4443 	if (bio == NULL)	{
4444 		SET_ERROR(kmfh, ERR_get_error());
4445 		ret = KMF_ERR_OPEN_FILE;
4446 		goto out;
4447 	}
4448 
4449 	if ((*pformat) == KMF_FORMAT_PEM) {
4450 		if ((xcert = PEM_read_bio_X509(bio, NULL,
4451 			NULL, NULL)) == NULL) {
4452 			ret = KMF_ERR_BAD_CERTFILE;
4453 		}
4454 	} else if ((*pformat) == KMF_FORMAT_ASN1) {
4455 		if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) {
4456 			ret = KMF_ERR_BAD_CERTFILE;
4457 		}
4458 	} else {
4459 		ret = KMF_ERR_BAD_CERTFILE;
4460 	}
4461 
4462 out:
4463 	if (bio != NULL)
4464 		(void) BIO_free(bio);
4465 
4466 	if (xcert != NULL)
4467 		X509_free(xcert);
4468 
4469 	return (ret);
4470 }
4471 
4472 KMF_RETURN
4473 OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
4474     KMF_RAW_SYM_KEY *rkey)
4475 {
4476 	KMF_RETURN	rv = KMF_OK;
4477 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4478 	KMF_DATA	keyvalue;
4479 
4480 	if (kmfh == NULL)
4481 		return (KMF_ERR_UNINITIALIZED);
4482 
4483 	if (symkey == NULL || rkey == NULL)
4484 		return (KMF_ERR_BAD_PARAMETER);
4485 	else if (symkey->keyclass != KMF_SYMMETRIC)
4486 		return (KMF_ERR_BAD_KEY_CLASS);
4487 
4488 	if (symkey->israw) {
4489 		KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp;
4490 
4491 		if (rawkey == NULL ||
4492 		    rawkey->keydata.val == NULL ||
4493 		    rawkey->keydata.len == 0)
4494 			return (KMF_ERR_BAD_KEYHANDLE);
4495 
4496 		rkey->keydata.len = rawkey->keydata.len;
4497 		if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
4498 			return (KMF_ERR_MEMORY);
4499 		(void) memcpy(rkey->keydata.val, rawkey->keydata.val,
4500 		    rkey->keydata.len);
4501 	} else {
4502 		rv = KMF_ReadInputFile(handle, symkey->keylabel, &keyvalue);
4503 		if (rv != KMF_OK)
4504 			return (rv);
4505 		rkey->keydata.len = keyvalue.Length;
4506 		rkey->keydata.val = keyvalue.Data;
4507 	}
4508 
4509 	return (rv);
4510 }
4511