xref: /illumos-gate/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c (revision 44bc9120699af80bb18366ca474cb2c618608ca9)
1 /*
2  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
3  *
4  * Use is subject to license terms.
5  */
6 /*
7  * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
8  */
9 /*
10  * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
11  * project 2000.
12  */
13 /*
14  * ====================================================================
15  * Copyright (c) 2000-2004 The OpenSSL Project.  All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  *
21  * 1. Redistributions of source code must retain the above copyright
22  *    notice, this list of conditions and the following disclaimer.
23  *
24  * 2. Redistributions in binary form must reproduce the above copyright
25  *    notice, this list of conditions and the following disclaimer in
26  *    the documentation and/or other materials provided with the
27  *    distribution.
28  *
29  * 3. All advertising materials mentioning features or use of this
30  *    software must display the following acknowledgment:
31  *    "This product includes software developed by the OpenSSL Project
32  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
33  *
34  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
35  *    endorse or promote products derived from this software without
36  *    prior written permission. For written permission, please contact
37  *    licensing@OpenSSL.org.
38  *
39  * 5. Products derived from this software may not be called "OpenSSL"
40  *    nor may "OpenSSL" appear in their names without prior written
41  *    permission of the OpenSSL Project.
42  *
43  * 6. Redistributions of any form whatsoever must retain the following
44  *    acknowledgment:
45  *    "This product includes software developed by the OpenSSL Project
46  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
49  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
51  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
52  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
53  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
54  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
55  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
57  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
58  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
59  * OF THE POSSIBILITY OF SUCH DAMAGE.
60  * ====================================================================
61  *
62  * This product includes cryptographic software written by Eric Young
63  * (eay@cryptsoft.com).  This product includes software written by Tim
64  * Hudson (tjh@cryptsoft.com).
65  *
66  */
67 
68 #include <stdlib.h>
69 #include <kmfapiP.h>
70 #include <ber_der.h>
71 #include <fcntl.h>
72 #include <sys/stat.h>
73 #include <dirent.h>
74 #include <cryptoutil.h>
75 #include <synch.h>
76 #include <thread.h>
77 
78 /* OPENSSL related headers */
79 #include <openssl/bio.h>
80 #include <openssl/bn.h>
81 #include <openssl/asn1.h>
82 #include <openssl/err.h>
83 #include <openssl/bn.h>
84 #include <openssl/x509.h>
85 #include <openssl/rsa.h>
86 #include <openssl/dsa.h>
87 #include <openssl/x509v3.h>
88 #include <openssl/objects.h>
89 #include <openssl/pem.h>
90 #include <openssl/pkcs12.h>
91 #include <openssl/ocsp.h>
92 #include <openssl/des.h>
93 #include <openssl/rand.h>
94 
95 #define	PRINT_ANY_EXTENSION (\
96 	KMF_X509_EXT_KEY_USAGE |\
97 	KMF_X509_EXT_CERT_POLICIES |\
98 	KMF_X509_EXT_SUBJALTNAME |\
99 	KMF_X509_EXT_BASIC_CONSTRAINTS |\
100 	KMF_X509_EXT_NAME_CONSTRAINTS |\
101 	KMF_X509_EXT_POLICY_CONSTRAINTS |\
102 	KMF_X509_EXT_EXT_KEY_USAGE |\
103 	KMF_X509_EXT_INHIBIT_ANY_POLICY |\
104 	KMF_X509_EXT_AUTH_KEY_ID |\
105 	KMF_X509_EXT_SUBJ_KEY_ID |\
106 	KMF_X509_EXT_POLICY_MAPPING)
107 
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 /*
138  * Declare some new macros for managing stacks of EVP_PKEYS, similar to
139  * what wanboot did.
140  */
141 DECLARE_STACK_OF(EVP_PKEY)
142 
143 #define	sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY)
144 #define	sk_EVP_PKEY_free(st) SKM_sk_free(EVP_PKEY, (st))
145 #define	sk_EVP_PKEY_num(st) SKM_sk_num(EVP_PKEY, (st))
146 #define	sk_EVP_PKEY_value(st, i) SKM_sk_value(EVP_PKEY, (st), (i))
147 #define	sk_EVP_PKEY_push(st, val) SKM_sk_push(EVP_PKEY, (st), (val))
148 #define	sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \
149 	(free_func))
150 
151 mutex_t init_lock = DEFAULTMUTEX;
152 static int ssl_initialized = 0;
153 static BIO *bio_err = NULL;
154 
155 static int
156 test_for_file(char *, mode_t);
157 static KMF_RETURN
158 openssl_parse_bag(PKCS12_SAFEBAG *, char *, int,
159     STACK_OF(EVP_PKEY) *, STACK_OF(X509) *);
160 
161 static KMF_RETURN
162 local_export_pk12(KMF_HANDLE_T, KMF_CREDENTIAL *, int, KMF_X509_DER_CERT *,
163     int, KMF_KEY_HANDLE *, char *);
164 
165 static KMF_RETURN set_pkey_attrib(EVP_PKEY *, ASN1_TYPE *, int);
166 
167 static KMF_RETURN
168 extract_pem(KMF_HANDLE *, char *, char *, KMF_BIGINT *, char *,
169     CK_UTF8CHAR *, CK_ULONG, EVP_PKEY **, KMF_DATA **, int *);
170 
171 static KMF_RETURN
172 kmf_load_cert(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY,
173     char *, KMF_DATA *);
174 
175 static KMF_RETURN
176 load_certs(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY,
177     char *, KMF_DATA **, uint32_t *);
178 
179 static KMF_RETURN
180 sslBN2KMFBN(BIGNUM *, KMF_BIGINT *);
181 
182 static EVP_PKEY *
183 ImportRawRSAKey(KMF_RAW_RSA_KEY *);
184 
185 static KMF_RETURN
186 convertToRawKey(EVP_PKEY *, KMF_RAW_KEY_DATA *);
187 
188 KMF_RETURN
189 OpenSSL_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
190 
191 void
192 OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *);
193 
194 KMF_RETURN
195 OpenSSL_StoreCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *);
196 
197 KMF_RETURN
198 OpenSSL_DeleteCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *);
199 
200 KMF_RETURN
201 OpenSSL_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
202 
203 KMF_RETURN
204 OpenSSL_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
205 
206 KMF_RETURN
207 OpenSSL_EncodePubKeyData(KMF_HANDLE_T,  KMF_KEY_HANDLE *, KMF_DATA *);
208 
209 KMF_RETURN
210 OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
211 	KMF_DATA *, KMF_DATA *);
212 
213 KMF_RETURN
214 OpenSSL_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
215 
216 KMF_RETURN
217 OpenSSL_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
218 
219 KMF_RETURN
220 OpenSSL_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
221 
222 KMF_RETURN
223 OpenSSL_ListCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
224 
225 KMF_RETURN
226 OpenSSL_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
227 
228 KMF_RETURN
229 OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *,
230 	KMF_PRINTABLE_ITEM, char *);
231 
232 KMF_RETURN
233 OpenSSL_GetErrorString(KMF_HANDLE_T, char **);
234 
235 KMF_RETURN
236 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
237 
238 KMF_RETURN
239 OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
240 	KMF_DATA *, KMF_DATA *);
241 
242 KMF_RETURN
243 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
244 
245 KMF_RETURN
246 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
247 
248 KMF_RETURN
249 OpenSSL_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
250 
251 KMF_RETURN
252 OpenSSL_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
253 
254 KMF_RETURN
255 OpenSSL_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
256 
257 KMF_RETURN
258 OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
259 
260 KMF_RETURN
261 OpenSSL_VerifyCRLFile(KMF_HANDLE_T, char *, KMF_DATA *);
262 
263 KMF_RETURN
264 OpenSSL_CheckCRLDate(KMF_HANDLE_T, char *);
265 
266 static
267 KMF_PLUGIN_FUNCLIST openssl_plugin_table =
268 {
269 	1,				/* Version */
270 	NULL, /* ConfigureKeystore */
271 	OpenSSL_FindCert,
272 	OpenSSL_FreeKMFCert,
273 	OpenSSL_StoreCert,
274 	NULL, /* ImportCert */
275 	OpenSSL_ImportCRL,
276 	OpenSSL_DeleteCert,
277 	OpenSSL_DeleteCRL,
278 	OpenSSL_CreateKeypair,
279 	OpenSSL_FindKey,
280 	OpenSSL_EncodePubKeyData,
281 	OpenSSL_SignData,
282 	OpenSSL_DeleteKey,
283 	OpenSSL_ListCRL,
284 	NULL,	/* FindCRL */
285 	OpenSSL_FindCertInCRL,
286 	OpenSSL_GetErrorString,
287 	OpenSSL_FindPrikeyByCert,
288 	OpenSSL_DecryptData,
289 	OpenSSL_ExportPK12,
290 	OpenSSL_CreateSymKey,
291 	OpenSSL_GetSymKeyValue,
292 	NULL,	/* SetTokenPin */
293 	OpenSSL_StoreKey,
294 	NULL	/* Finalize */
295 };
296 
297 static mutex_t *lock_cs;
298 static long *lock_count;
299 
300 static void
301 /* ARGSUSED1 */
302 locking_cb(int mode, int type, char *file, int line)
303 {
304 	if (mode & CRYPTO_LOCK) {
305 		(void) mutex_lock(&(lock_cs[type]));
306 		lock_count[type]++;
307 	} else {
308 		(void) mutex_unlock(&(lock_cs[type]));
309 	}
310 }
311 
312 static unsigned long
313 thread_id()
314 {
315 	return ((unsigned long)thr_self());
316 }
317 
318 KMF_PLUGIN_FUNCLIST *
319 KMF_Plugin_Initialize()
320 {
321 	int i;
322 
323 	(void) mutex_lock(&init_lock);
324 	if (!ssl_initialized) {
325 		/*
326 		 * Add support for extension OIDs that are not yet in the
327 		 * openssl default set.
328 		 */
329 		(void) OBJ_create("2.5.29.30", "nameConstraints",
330 		    "X509v3 Name Constraints");
331 		(void) OBJ_create("2.5.29.33", "policyMappings",
332 		    "X509v3 Policy Mappings");
333 		(void) OBJ_create("2.5.29.36", "policyConstraints",
334 		    "X509v3 Policy Constraints");
335 		(void) OBJ_create("2.5.29.46", "freshestCRL",
336 		    "X509v3 Freshest CRL");
337 		(void) OBJ_create("2.5.29.54", "inhibitAnyPolicy",
338 		    "X509v3 Inhibit Any-Policy");
339 		/*
340 		 * Set up for thread-safe operation.
341 		 */
342 		lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t));
343 		if (lock_cs == NULL) {
344 			(void) mutex_unlock(&init_lock);
345 			return (NULL);
346 		}
347 
348 		lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long));
349 		if (lock_count == NULL) {
350 			OPENSSL_free(lock_cs);
351 			(void) mutex_unlock(&init_lock);
352 			return (NULL);
353 		}
354 
355 		for (i = 0; i < CRYPTO_num_locks(); i++) {
356 			lock_count[i] = 0;
357 			(void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL);
358 		}
359 
360 		CRYPTO_set_id_callback((unsigned long (*)())thread_id);
361 		if (CRYPTO_get_locking_callback() == NULL)
362 			CRYPTO_set_locking_callback((void (*)())locking_cb);
363 
364 		OpenSSL_add_all_algorithms();
365 
366 		/* Enable error strings for reporting */
367 		ERR_load_crypto_strings();
368 
369 		ssl_initialized = 1;
370 	}
371 	(void) mutex_unlock(&init_lock);
372 
373 	return (&openssl_plugin_table);
374 }
375 /*
376  * Convert an SSL DN to a KMF DN.
377  */
378 static KMF_RETURN
379 get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN)
380 {
381 	KMF_DATA derdata;
382 	KMF_RETURN rv = KMF_OK;
383 	uchar_t *tmp;
384 
385 	/* Convert to raw DER format */
386 	derdata.Length = i2d_X509_NAME(sslDN, NULL);
387 	if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length))
388 	    == NULL) {
389 		return (KMF_ERR_MEMORY);
390 	}
391 	(void) i2d_X509_NAME(sslDN, &tmp);
392 
393 	/* Decode to KMF format */
394 	rv = DerDecodeName(&derdata, kmfDN);
395 	if (rv != KMF_OK) {
396 		rv = KMF_ERR_BAD_CERT_FORMAT;
397 	}
398 	OPENSSL_free(derdata.Data);
399 
400 	return (rv);
401 }
402 
403 int
404 isdir(char *path)
405 {
406 	struct stat s;
407 
408 	if (stat(path, &s) == -1)
409 		return (0);
410 
411 	return ((s.st_mode & S_IFMT) == S_IFDIR);
412 }
413 
414 static KMF_RETURN
415 ssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert)
416 {
417 	KMF_RETURN rv = KMF_OK;
418 	unsigned char *buf = NULL, *p;
419 	int len;
420 
421 	/*
422 	 * Convert the X509 internal struct to DER encoded data
423 	 */
424 	if ((len = i2d_X509(x509cert, NULL)) < 0) {
425 		SET_ERROR(kmfh, ERR_get_error());
426 		rv = KMF_ERR_BAD_CERT_FORMAT;
427 		goto cleanup;
428 	}
429 	if ((buf = malloc(len)) == NULL) {
430 		SET_SYS_ERROR(kmfh, errno);
431 		rv = KMF_ERR_MEMORY;
432 		goto cleanup;
433 	}
434 
435 	/*
436 	 * i2d_X509 will increment the buf pointer so that we need to
437 	 * save it.
438 	 */
439 	p = buf;
440 	if ((len = i2d_X509(x509cert, &p)) < 0) {
441 		SET_ERROR(kmfh, ERR_get_error());
442 		free(buf);
443 		rv = KMF_ERR_BAD_CERT_FORMAT;
444 		goto cleanup;
445 	}
446 
447 	/* caller's responsibility to free it */
448 	cert->Data = buf;
449 	cert->Length = len;
450 
451 cleanup:
452 	if (rv != KMF_OK) {
453 		if (buf)
454 			free(buf);
455 		cert->Data = NULL;
456 		cert->Length = 0;
457 	}
458 
459 	return (rv);
460 }
461 
462 
463 static KMF_RETURN
464 check_cert(X509 *xcert, char *issuer, char *subject, KMF_BIGINT *serial,
465     boolean_t *match)
466 {
467 	KMF_RETURN rv = KMF_OK;
468 	boolean_t findIssuer = FALSE;
469 	boolean_t findSubject = FALSE;
470 	boolean_t findSerial = FALSE;
471 	KMF_X509_NAME issuerDN, subjectDN;
472 	KMF_X509_NAME certIssuerDN, certSubjectDN;
473 
474 	*match = FALSE;
475 	if (xcert == NULL) {
476 		return (KMF_ERR_BAD_PARAMETER);
477 	}
478 
479 	(void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME));
480 	(void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME));
481 	(void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME));
482 	(void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME));
483 
484 	if (issuer != NULL && strlen(issuer)) {
485 		rv = kmf_dn_parser(issuer, &issuerDN);
486 		if (rv != KMF_OK)
487 			return (KMF_ERR_BAD_PARAMETER);
488 
489 		rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN);
490 		if (rv != KMF_OK) {
491 			kmf_free_dn(&issuerDN);
492 			return (KMF_ERR_BAD_PARAMETER);
493 		}
494 
495 		findIssuer = TRUE;
496 	}
497 	if (subject != NULL && strlen(subject)) {
498 		rv = kmf_dn_parser(subject, &subjectDN);
499 		if (rv != KMF_OK) {
500 			rv = KMF_ERR_BAD_PARAMETER;
501 			goto cleanup;
502 		}
503 
504 		rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN);
505 		if (rv != KMF_OK) {
506 			rv = KMF_ERR_BAD_PARAMETER;
507 			goto cleanup;
508 		}
509 		findSubject = TRUE;
510 	}
511 	if (serial != NULL && serial->val != NULL)
512 		findSerial = TRUE;
513 
514 	if (findSerial) {
515 		BIGNUM *bn;
516 
517 		/* Comparing BIGNUMs is a pain! */
518 		bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL);
519 		if (bn != NULL) {
520 			int bnlen = BN_num_bytes(bn);
521 
522 			if (bnlen == serial->len) {
523 				uchar_t *a = malloc(bnlen);
524 				if (a == NULL) {
525 					rv = KMF_ERR_MEMORY;
526 					BN_free(bn);
527 					goto cleanup;
528 				}
529 				bnlen = BN_bn2bin(bn, a);
530 				*match = (memcmp(a, serial->val, serial->len) ==
531 				    0);
532 				rv = KMF_OK;
533 				free(a);
534 			}
535 			BN_free(bn);
536 			if (!(*match))
537 				goto cleanup;
538 		} else {
539 			rv = KMF_OK;
540 			goto cleanup;
541 		}
542 	}
543 	if (findIssuer) {
544 		*match = (kmf_compare_rdns(&issuerDN, &certIssuerDN) == 0);
545 		if ((*match) == B_FALSE) {
546 			/* stop checking and bail */
547 			rv = KMF_OK;
548 			goto cleanup;
549 		}
550 	}
551 	if (findSubject) {
552 		*match = (kmf_compare_rdns(&subjectDN, &certSubjectDN) == 0);
553 		if ((*match) == B_FALSE) {
554 			/* stop checking and bail */
555 			rv = KMF_OK;
556 			goto cleanup;
557 		}
558 	}
559 
560 	*match = TRUE;
561 cleanup:
562 	if (findIssuer) {
563 		kmf_free_dn(&issuerDN);
564 		kmf_free_dn(&certIssuerDN);
565 	}
566 	if (findSubject) {
567 		kmf_free_dn(&subjectDN);
568 		kmf_free_dn(&certSubjectDN);
569 	}
570 
571 	return (rv);
572 }
573 
574 
575 /*
576  * This function loads a certificate file into an X509 data structure, and
577  * checks if its issuer, subject or the serial number matches with those
578  * values.  If it matches, then return the X509 data structure.
579  */
580 static KMF_RETURN
581 load_X509cert(KMF_HANDLE *kmfh,
582     char *issuer, char *subject, KMF_BIGINT *serial,
583     char *pathname, X509 **outcert)
584 {
585 	KMF_RETURN rv = KMF_OK;
586 	X509 *xcert = NULL;
587 	BIO *bcert = NULL;
588 	boolean_t  match = FALSE;
589 	KMF_ENCODE_FORMAT format;
590 
591 	/*
592 	 * auto-detect the file format, regardless of what
593 	 * the 'format' parameters in the params say.
594 	 */
595 	rv = kmf_get_file_format(pathname, &format);
596 	if (rv != KMF_OK) {
597 		if (rv == KMF_ERR_OPEN_FILE)
598 			rv = KMF_ERR_CERT_NOT_FOUND;
599 		return (rv);
600 	}
601 
602 	/* Not ASN1(DER) format */
603 	if ((bcert = BIO_new_file(pathname, "rb")) == NULL) {
604 		SET_ERROR(kmfh, ERR_get_error());
605 		rv = KMF_ERR_OPEN_FILE;
606 		goto cleanup;
607 	}
608 
609 	if (format == KMF_FORMAT_PEM)
610 		xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL);
611 	else if (format == KMF_FORMAT_ASN1)
612 		xcert = d2i_X509_bio(bcert, NULL);
613 	else if (format == KMF_FORMAT_PKCS12) {
614 		PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL);
615 		if (p12 != NULL) {
616 			(void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL);
617 			PKCS12_free(p12);
618 			p12 = NULL;
619 		} else {
620 			SET_ERROR(kmfh, ERR_get_error());
621 			rv = KMF_ERR_BAD_CERT_FORMAT;
622 		}
623 	} else {
624 		rv = KMF_ERR_BAD_PARAMETER;
625 		goto cleanup;
626 	}
627 
628 	if (xcert == NULL) {
629 		SET_ERROR(kmfh, ERR_get_error());
630 		rv = KMF_ERR_BAD_CERT_FORMAT;
631 		goto cleanup;
632 	}
633 
634 	if (check_cert(xcert, issuer, subject, serial, &match) != KMF_OK ||
635 	    match == FALSE) {
636 		rv = KMF_ERR_CERT_NOT_FOUND;
637 		goto cleanup;
638 	}
639 
640 	if (outcert != NULL) {
641 		*outcert = xcert;
642 	}
643 
644 cleanup:
645 	if (bcert != NULL) (void) BIO_free(bcert);
646 	if (rv != KMF_OK && xcert != NULL)
647 		X509_free(xcert);
648 
649 	return (rv);
650 }
651 
652 static int
653 datacmp(const void *a, const void *b)
654 {
655 	KMF_DATA *adata = (KMF_DATA *)a;
656 	KMF_DATA *bdata = (KMF_DATA *)b;
657 	if (adata->Length > bdata->Length)
658 		return (-1);
659 	if (adata->Length < bdata->Length)
660 		return (1);
661 	return (0);
662 }
663 
664 static KMF_RETURN
665 load_certs(KMF_HANDLE *kmfh, char *issuer, char *subject, KMF_BIGINT *serial,
666     KMF_CERT_VALIDITY validity, char *pathname,
667     KMF_DATA **certlist, uint32_t *numcerts)
668 {
669 	KMF_RETURN rv = KMF_OK;
670 	int i;
671 	KMF_DATA *certs = NULL;
672 	int nc = 0;
673 	int hits = 0;
674 	KMF_ENCODE_FORMAT format;
675 
676 	rv = kmf_get_file_format(pathname, &format);
677 	if (rv != KMF_OK) {
678 		if (rv == KMF_ERR_OPEN_FILE)
679 			rv = KMF_ERR_CERT_NOT_FOUND;
680 		return (rv);
681 	}
682 	if (format == KMF_FORMAT_ASN1) {
683 		/* load a single certificate */
684 		certs = (KMF_DATA *)malloc(sizeof (KMF_DATA));
685 		if (certs == NULL)
686 			return (KMF_ERR_MEMORY);
687 		certs->Data = NULL;
688 		certs->Length = 0;
689 		rv = kmf_load_cert(kmfh, issuer, subject, serial, validity,
690 		    pathname, certs);
691 		if (rv == KMF_OK) {
692 			*certlist = certs;
693 			*numcerts = 1;
694 		} else {
695 			kmf_free_data(certs);
696 			free(certs);
697 			certs = NULL;
698 		}
699 		return (rv);
700 	} else if (format == KMF_FORMAT_PKCS12) {
701 		/* We need a credential to access a PKCS#12 file */
702 		rv = KMF_ERR_BAD_CERT_FORMAT;
703 	} else if (format == KMF_FORMAT_PEM ||
704 	    format != KMF_FORMAT_PEM_KEYPAIR) {
705 
706 		/* This function only works on PEM files */
707 		rv = extract_pem(kmfh, issuer, subject, serial, pathname,
708 		    (uchar_t *)NULL, 0, NULL, &certs, &nc);
709 	} else {
710 		return (KMF_ERR_ENCODING);
711 	}
712 
713 	if (rv != KMF_OK)
714 		return (rv);
715 
716 	for (i = 0; i < nc; i++) {
717 		if (validity == KMF_NONEXPIRED_CERTS) {
718 			rv = kmf_check_cert_date(kmfh, &certs[i]);
719 		} else if (validity == KMF_EXPIRED_CERTS) {
720 			rv = kmf_check_cert_date(kmfh, &certs[i]);
721 			if (rv == KMF_OK)
722 				rv = KMF_ERR_CERT_NOT_FOUND;
723 			if (rv == KMF_ERR_VALIDITY_PERIOD)
724 				rv = KMF_OK;
725 		}
726 		if (rv != KMF_OK) {
727 			/* Remove this cert from the list by clearing it. */
728 			kmf_free_data(&certs[i]);
729 		} else {
730 			hits++; /* count valid certs found */
731 		}
732 		rv = KMF_OK;
733 	}
734 	if (rv == KMF_OK && hits > 0) {
735 		/*
736 		 * Sort the list of certs by length to put the cleared ones
737 		 * at the end so they don't get accessed by the caller.
738 		 */
739 		qsort((void *)certs, nc, sizeof (KMF_DATA), datacmp);
740 		*certlist = certs;
741 
742 		/* since we sorted the list, just return the number of hits */
743 		*numcerts = hits;
744 	} else {
745 		if (rv == KMF_OK && hits == 0)
746 			rv = KMF_ERR_CERT_NOT_FOUND;
747 		if (certs != NULL) {
748 			free(certs);
749 			certs = NULL;
750 		}
751 	}
752 	return (rv);
753 }
754 
755 static KMF_RETURN
756 kmf_load_cert(KMF_HANDLE *kmfh,
757     char *issuer, char *subject, KMF_BIGINT *serial,
758     KMF_CERT_VALIDITY validity,
759     char *pathname,
760     KMF_DATA *cert)
761 {
762 	KMF_RETURN rv = KMF_OK;
763 	X509 *x509cert = NULL;
764 
765 	rv = load_X509cert(kmfh, issuer, subject, serial, pathname, &x509cert);
766 	if (rv == KMF_OK && x509cert != NULL && cert != NULL) {
767 		rv = ssl_cert2KMFDATA(kmfh, x509cert, cert);
768 		if (rv != KMF_OK) {
769 			goto cleanup;
770 		}
771 		if (validity == KMF_NONEXPIRED_CERTS) {
772 			rv = kmf_check_cert_date(kmfh, cert);
773 		} else if (validity == KMF_EXPIRED_CERTS) {
774 			rv = kmf_check_cert_date(kmfh, cert);
775 			if (rv == KMF_OK)  {
776 				/*
777 				 * This is a valid cert so skip it.
778 				 */
779 				rv = KMF_ERR_CERT_NOT_FOUND;
780 			}
781 			if (rv == KMF_ERR_VALIDITY_PERIOD) {
782 				/*
783 				 * We want to return success when we
784 				 * find an invalid cert.
785 				 */
786 				rv = KMF_OK;
787 				goto cleanup;
788 			}
789 		}
790 	}
791 cleanup:
792 	if (x509cert != NULL)
793 		X509_free(x509cert);
794 
795 	return (rv);
796 }
797 
798 static KMF_RETURN
799 readAltFormatPrivateKey(KMF_DATA *filedata, EVP_PKEY **pkey)
800 {
801 	KMF_RETURN ret = KMF_OK;
802 	KMF_RAW_RSA_KEY rsa;
803 	BerElement *asn1 = NULL;
804 	BerValue filebuf;
805 	BerValue OID = { NULL, 0 };
806 	BerValue *Mod = NULL, *PubExp = NULL;
807 	BerValue *PriExp = NULL, *Prime1 = NULL, *Prime2 = NULL;
808 	BerValue *Coef = NULL;
809 	BIGNUM *D = NULL, *P = NULL, *Q = NULL, *COEF = NULL;
810 	BIGNUM *Exp1 = NULL, *Exp2 = NULL, *pminus1 = NULL;
811 	BIGNUM *qminus1 = NULL;
812 	BN_CTX *ctx = NULL;
813 
814 	*pkey = NULL;
815 
816 	filebuf.bv_val = (char *)filedata->Data;
817 	filebuf.bv_len = filedata->Length;
818 
819 	asn1 = kmfder_init(&filebuf);
820 	if (asn1 == NULL) {
821 		ret = KMF_ERR_MEMORY;
822 		goto out;
823 	}
824 
825 	if (kmfber_scanf(asn1, "{{Dn{IIIIII}}}",
826 	    &OID, &Mod, &PubExp, &PriExp, &Prime1,
827 	    &Prime2, &Coef) == -1)  {
828 		ret = KMF_ERR_ENCODING;
829 		goto out;
830 	}
831 
832 	/*
833 	 * We have to derive the 2 Exponents using Bignumber math.
834 	 * Exp1 = PriExp mod (Prime1 - 1)
835 	 * Exp2 = PriExp mod (Prime2 - 1)
836 	 */
837 
838 	/* D = PrivateExponent */
839 	D = BN_bin2bn((const uchar_t *)PriExp->bv_val, PriExp->bv_len, D);
840 	if (D == NULL) {
841 		ret = KMF_ERR_MEMORY;
842 		goto out;
843 	}
844 
845 	/* P = Prime1 (first prime factor of Modulus) */
846 	P = BN_bin2bn((const uchar_t *)Prime1->bv_val, Prime1->bv_len, P);
847 	if (D == NULL) {
848 		ret = KMF_ERR_MEMORY;
849 		goto out;
850 	}
851 
852 	/* Q = Prime2 (second prime factor of Modulus) */
853 	Q = BN_bin2bn((const uchar_t *)Prime2->bv_val, Prime2->bv_len, Q);
854 
855 	if ((ctx = BN_CTX_new()) == NULL) {
856 		ret = KMF_ERR_MEMORY;
857 		goto out;
858 	}
859 
860 	/* Compute (P - 1) */
861 	pminus1 = BN_new();
862 	(void) BN_sub(pminus1, P, BN_value_one());
863 
864 	/* Exponent1 = D mod (P - 1) */
865 	Exp1 = BN_new();
866 	(void) BN_mod(Exp1, D, pminus1, ctx);
867 
868 	/* Compute (Q - 1) */
869 	qminus1 = BN_new();
870 	(void) BN_sub(qminus1, Q, BN_value_one());
871 
872 	/* Exponent2 = D mod (Q - 1) */
873 	Exp2 = BN_new();
874 	(void) BN_mod(Exp2, D, qminus1, ctx);
875 
876 	/* Coef = (Inverse Q) mod P */
877 	COEF = BN_new();
878 	(void) BN_mod_inverse(COEF, Q, P, ctx);
879 
880 	/* Convert back to KMF format */
881 	(void) memset(&rsa, 0, sizeof (rsa));
882 
883 	if ((ret = sslBN2KMFBN(Exp1, &rsa.exp1)) != KMF_OK)
884 		goto out;
885 	if ((ret = sslBN2KMFBN(Exp2, &rsa.exp2)) != KMF_OK)
886 		goto out;
887 	if ((ret = sslBN2KMFBN(COEF, &rsa.coef)) != KMF_OK)
888 		goto out;
889 
890 	rsa.mod.val = (uchar_t *)Mod->bv_val;
891 	rsa.mod.len = Mod->bv_len;
892 
893 	rsa.pubexp.val = (uchar_t *)PubExp->bv_val;
894 	rsa.pubexp.len = PubExp->bv_len;
895 
896 	rsa.priexp.val = (uchar_t *)PriExp->bv_val;
897 	rsa.priexp.len = PriExp->bv_len;
898 
899 	rsa.prime1.val = (uchar_t *)Prime1->bv_val;
900 	rsa.prime1.len = Prime1->bv_len;
901 
902 	rsa.prime2.val = (uchar_t *)Prime2->bv_val;
903 	rsa.prime2.len = Prime2->bv_len;
904 
905 	*pkey = ImportRawRSAKey(&rsa);
906 out:
907 	if (asn1 != NULL)
908 		kmfber_free(asn1, 1);
909 
910 	if (OID.bv_val) {
911 		free(OID.bv_val);
912 	}
913 	if (PriExp)
914 		free(PriExp);
915 
916 	if (Mod)
917 		free(Mod);
918 
919 	if (PubExp)
920 		free(PubExp);
921 
922 	if (Coef) {
923 		(void) memset(Coef->bv_val, 0, Coef->bv_len);
924 		free(Coef->bv_val);
925 		free(Coef);
926 	}
927 	if (Prime1)
928 		free(Prime1);
929 	if (Prime2)
930 		free(Prime2);
931 
932 	if (ctx != NULL)
933 		BN_CTX_free(ctx);
934 
935 	if (D)
936 		BN_clear_free(D);
937 	if (P)
938 		BN_clear_free(P);
939 	if (Q)
940 		BN_clear_free(Q);
941 	if (pminus1)
942 		BN_clear_free(pminus1);
943 	if (qminus1)
944 		BN_clear_free(qminus1);
945 	if (Exp1)
946 		BN_clear_free(Exp1);
947 	if (Exp2)
948 		BN_clear_free(Exp2);
949 
950 	return (ret);
951 
952 }
953 
954 static EVP_PKEY *
955 openssl_load_key(KMF_HANDLE_T handle, const char *file)
956 {
957 	BIO *keyfile = NULL;
958 	EVP_PKEY *pkey = NULL;
959 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
960 	KMF_ENCODE_FORMAT format;
961 	KMF_RETURN rv;
962 	KMF_DATA filedata;
963 
964 	if (file == NULL) {
965 		return (NULL);
966 	}
967 
968 	if (kmf_get_file_format((char *)file, &format) != KMF_OK)
969 		return (NULL);
970 
971 	keyfile = BIO_new_file(file, "rb");
972 	if (keyfile == NULL) {
973 		goto end;
974 	}
975 
976 	if (format == KMF_FORMAT_ASN1) {
977 		pkey = d2i_PrivateKey_bio(keyfile, NULL);
978 		if (pkey == NULL) {
979 
980 			(void) BIO_free(keyfile);
981 			keyfile = NULL;
982 			/* Try odd ASN.1 variations */
983 			rv = kmf_read_input_file(kmfh, (char *)file,
984 			    &filedata);
985 			if (rv == KMF_OK) {
986 				(void) readAltFormatPrivateKey(&filedata,
987 				    &pkey);
988 				kmf_free_data(&filedata);
989 			}
990 		}
991 	} else if (format == KMF_FORMAT_PEM ||
992 	    format == KMF_FORMAT_PEM_KEYPAIR) {
993 		pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL);
994 		if (pkey == NULL) {
995 			KMF_DATA derdata;
996 			/*
997 			 * Check if this is the alt. format
998 			 * RSA private key file.
999 			 */
1000 			rv = kmf_read_input_file(kmfh, (char *)file,
1001 			    &filedata);
1002 			if (rv == KMF_OK) {
1003 				uchar_t *d = NULL;
1004 				int len;
1005 				rv = kmf_pem_to_der(filedata.Data,
1006 				    filedata.Length, &d, &len);
1007 				if (rv == KMF_OK && d != NULL) {
1008 					derdata.Data = d;
1009 					derdata.Length = (size_t)len;
1010 					(void) readAltFormatPrivateKey(
1011 					    &derdata, &pkey);
1012 					free(d);
1013 				}
1014 				kmf_free_data(&filedata);
1015 			}
1016 		}
1017 	}
1018 
1019 end:
1020 	if (pkey == NULL)
1021 		SET_ERROR(kmfh, ERR_get_error());
1022 
1023 	if (keyfile != NULL)
1024 		(void) BIO_free(keyfile);
1025 
1026 	return (pkey);
1027 }
1028 
1029 KMF_RETURN
1030 OpenSSL_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1031 {
1032 	KMF_RETURN rv = KMF_OK;
1033 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1034 	int i, n;
1035 	uint32_t maxcerts = 0;
1036 	uint32_t *num_certs;
1037 	KMF_X509_DER_CERT *kmf_cert = NULL;
1038 	char *dirpath = NULL;
1039 	char *filename = NULL;
1040 	char *fullpath = NULL;
1041 	char *issuer = NULL;
1042 	char *subject = NULL;
1043 	KMF_BIGINT *serial = NULL;
1044 	KMF_CERT_VALIDITY validity;
1045 
1046 	num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
1047 	if (num_certs == NULL)
1048 		return (KMF_ERR_BAD_PARAMETER);
1049 
1050 	/* num_certs should reference the size of kmf_cert */
1051 	maxcerts = *num_certs;
1052 	if (maxcerts == 0)
1053 		maxcerts = 0xFFFFFFFF;
1054 	*num_certs = 0;
1055 
1056 	/* Get the optional returned certificate list  */
1057 	kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist,
1058 	    numattr);
1059 
1060 	/*
1061 	 * The dirpath attribute and the filename attribute can not be NULL
1062 	 * at the same time.
1063 	 */
1064 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1065 	filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
1066 	    numattr);
1067 
1068 	fullpath = get_fullpath(dirpath, filename);
1069 	if (fullpath == NULL)
1070 		return (KMF_ERR_BAD_PARAMETER);
1071 
1072 	/* Get optional search criteria attributes */
1073 	issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
1074 	subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
1075 	serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
1076 	rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
1077 	    &validity, NULL);
1078 	if (rv != KMF_OK) {
1079 		validity = KMF_ALL_CERTS;
1080 		rv = KMF_OK;
1081 	}
1082 
1083 	if (isdir(fullpath)) {
1084 		DIR *dirp;
1085 		struct dirent *dp;
1086 
1087 		n = 0;
1088 		/* open all files in the directory and attempt to read them */
1089 		if ((dirp = opendir(fullpath)) == NULL) {
1090 			return (KMF_ERR_BAD_PARAMETER);
1091 		}
1092 		while ((dp = readdir(dirp)) != NULL) {
1093 			char *fname;
1094 			KMF_DATA *certlist = NULL;
1095 			uint32_t loaded_certs = 0;
1096 
1097 			if (strcmp(dp->d_name, ".") == 0 ||
1098 			    strcmp(dp->d_name, "..") == 0)
1099 				continue;
1100 
1101 			fname = get_fullpath(fullpath, (char *)&dp->d_name);
1102 
1103 			rv = load_certs(kmfh, issuer, subject, serial,
1104 			    validity, fname, &certlist,	&loaded_certs);
1105 
1106 			if (rv != KMF_OK) {
1107 				free(fname);
1108 				if (certlist != NULL) {
1109 					for (i = 0; i < loaded_certs; i++)
1110 						kmf_free_data(&certlist[i]);
1111 					free(certlist);
1112 				}
1113 				continue;
1114 			}
1115 
1116 			/* If load succeeds, add certdata to the list */
1117 			if (kmf_cert != NULL) {
1118 				for (i = 0; i < loaded_certs &&
1119 				    n < maxcerts; i++) {
1120 					kmf_cert[n].certificate.Data =
1121 					    certlist[i].Data;
1122 					kmf_cert[n].certificate.Length =
1123 					    certlist[i].Length;
1124 
1125 					kmf_cert[n].kmf_private.keystore_type =
1126 					    KMF_KEYSTORE_OPENSSL;
1127 					kmf_cert[n].kmf_private.flags =
1128 					    KMF_FLAG_CERT_VALID;
1129 					kmf_cert[n].kmf_private.label =
1130 					    strdup(fname);
1131 					n++;
1132 				}
1133 				/*
1134 				 * If maxcerts < loaded_certs, clean up the
1135 				 * certs that were not used.
1136 				 */
1137 				for (; i < loaded_certs; i++)
1138 					kmf_free_data(&certlist[i]);
1139 			} else {
1140 				for (i = 0; i < loaded_certs; i++)
1141 					kmf_free_data(&certlist[i]);
1142 				n += loaded_certs;
1143 			}
1144 			free(certlist);
1145 			free(fname);
1146 		}
1147 		(*num_certs) = n;
1148 		if (*num_certs == 0)
1149 			rv = KMF_ERR_CERT_NOT_FOUND;
1150 		if (*num_certs > 0)
1151 			rv = KMF_OK;
1152 exit:
1153 		(void) closedir(dirp);
1154 	} else {
1155 		KMF_DATA *certlist = NULL;
1156 		uint32_t loaded_certs = 0;
1157 
1158 		rv = load_certs(kmfh, issuer, subject, serial, validity,
1159 		    fullpath, &certlist, &loaded_certs);
1160 		if (rv != KMF_OK) {
1161 			free(fullpath);
1162 			return (rv);
1163 		}
1164 
1165 		n = 0;
1166 		if (kmf_cert != NULL && certlist != NULL) {
1167 			for (i = 0; i < loaded_certs && i < maxcerts; i++) {
1168 				kmf_cert[n].certificate.Data =
1169 				    certlist[i].Data;
1170 				kmf_cert[n].certificate.Length =
1171 				    certlist[i].Length;
1172 				kmf_cert[n].kmf_private.keystore_type =
1173 				    KMF_KEYSTORE_OPENSSL;
1174 				kmf_cert[n].kmf_private.flags =
1175 				    KMF_FLAG_CERT_VALID;
1176 				kmf_cert[n].kmf_private.label =
1177 				    strdup(fullpath);
1178 				n++;
1179 			}
1180 			/* If maxcerts < loaded_certs, clean up */
1181 			for (; i < loaded_certs; i++)
1182 				kmf_free_data(&certlist[i]);
1183 		} else if (certlist != NULL) {
1184 			for (i = 0; i < loaded_certs; i++)
1185 				kmf_free_data(&certlist[i]);
1186 			n = loaded_certs;
1187 		}
1188 		if (certlist != NULL)
1189 			free(certlist);
1190 		*num_certs = n;
1191 	}
1192 
1193 	free(fullpath);
1194 
1195 	return (rv);
1196 }
1197 
1198 void
1199 /*ARGSUSED*/
1200 OpenSSL_FreeKMFCert(KMF_HANDLE_T handle,
1201 	KMF_X509_DER_CERT *kmf_cert)
1202 {
1203 	if (kmf_cert != NULL) {
1204 		if (kmf_cert->certificate.Data != NULL) {
1205 			kmf_free_data(&kmf_cert->certificate);
1206 		}
1207 		if (kmf_cert->kmf_private.label)
1208 			free(kmf_cert->kmf_private.label);
1209 	}
1210 }
1211 
1212 /*ARGSUSED*/
1213 KMF_RETURN
1214 OpenSSL_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1215 {
1216 	KMF_RETURN ret = KMF_OK;
1217 	KMF_DATA *cert = NULL;
1218 	char *outfilename = NULL;
1219 	char *dirpath = NULL;
1220 	char *fullpath = NULL;
1221 	KMF_ENCODE_FORMAT format;
1222 
1223 	/* Get the cert data */
1224 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
1225 	if (cert == NULL || cert->Data == NULL)
1226 		return (KMF_ERR_BAD_PARAMETER);
1227 
1228 	/* Check the output filename and directory attributes. */
1229 	outfilename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
1230 	    numattr);
1231 	if (outfilename == NULL)
1232 		return (KMF_ERR_BAD_PARAMETER);
1233 
1234 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1235 	fullpath = get_fullpath(dirpath, outfilename);
1236 	if (fullpath == NULL)
1237 		return (KMF_ERR_BAD_CERTFILE);
1238 
1239 	/* Check the optional format attribute */
1240 	ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
1241 	    &format, NULL);
1242 	if (ret != KMF_OK) {
1243 		/* If there is no format attribute, then default to PEM */
1244 		format = KMF_FORMAT_PEM;
1245 		ret = KMF_OK;
1246 	} else if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) {
1247 		ret = KMF_ERR_BAD_CERT_FORMAT;
1248 		goto out;
1249 	}
1250 
1251 	/* Store the certificate in the file with the specified format */
1252 	ret = kmf_create_cert_file(cert, format, fullpath);
1253 
1254 out:
1255 	if (fullpath != NULL)
1256 		free(fullpath);
1257 
1258 	return (ret);
1259 }
1260 
1261 
1262 KMF_RETURN
1263 OpenSSL_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1264 {
1265 	KMF_RETURN rv;
1266 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1267 	KMF_DATA certdata = { 0, NULL };
1268 	char *dirpath = NULL;
1269 	char *filename = NULL;
1270 	char *fullpath = NULL;
1271 	char *issuer = NULL;
1272 	char *subject = NULL;
1273 	KMF_BIGINT *serial = NULL;
1274 	KMF_CERT_VALIDITY validity;
1275 
1276 	/*
1277 	 * Get the DIRPATH and CERT_FILENAME attributes.  They can not be
1278 	 * NULL at the same time.
1279 	 */
1280 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1281 	filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
1282 	    numattr);
1283 	fullpath = get_fullpath(dirpath, filename);
1284 	if (fullpath == NULL)
1285 		return (KMF_ERR_BAD_PARAMETER);
1286 
1287 	/* Get optional search criteria attributes */
1288 	issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
1289 	subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
1290 	serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
1291 	rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
1292 	    &validity, NULL);
1293 	if (rv != KMF_OK) {
1294 		validity = KMF_ALL_CERTS;
1295 		rv = KMF_OK;
1296 	}
1297 
1298 	if (isdir(fullpath)) {
1299 		DIR *dirp;
1300 		struct dirent *dp;
1301 
1302 		/* open all files in the directory and attempt to read them */
1303 		if ((dirp = opendir(fullpath)) == NULL) {
1304 			return (KMF_ERR_BAD_PARAMETER);
1305 		}
1306 
1307 		while ((dp = readdir(dirp)) != NULL) {
1308 			if (strcmp(dp->d_name, ".") != 0 &&
1309 			    strcmp(dp->d_name, "..") != 0) {
1310 				char *fname;
1311 
1312 				fname = get_fullpath(fullpath,
1313 				    (char *)&dp->d_name);
1314 
1315 				if (fname == NULL) {
1316 					rv = KMF_ERR_MEMORY;
1317 					break;
1318 				}
1319 
1320 				rv = kmf_load_cert(kmfh, issuer, subject,
1321 				    serial, validity, fname, &certdata);
1322 
1323 				if (rv == KMF_ERR_CERT_NOT_FOUND) {
1324 					free(fname);
1325 					kmf_free_data(&certdata);
1326 					rv = KMF_OK;
1327 					continue;
1328 				} else if (rv != KMF_OK) {
1329 					free(fname);
1330 					break;
1331 				}
1332 
1333 				if (unlink(fname) != 0) {
1334 					SET_SYS_ERROR(kmfh, errno);
1335 					rv = KMF_ERR_INTERNAL;
1336 					free(fname);
1337 					break;
1338 				}
1339 				free(fname);
1340 				kmf_free_data(&certdata);
1341 			}
1342 		}
1343 		(void) closedir(dirp);
1344 	} else {
1345 		/* Just try to load a single certificate */
1346 		rv = kmf_load_cert(kmfh, issuer, subject, serial, validity,
1347 		    fullpath, &certdata);
1348 		if (rv == KMF_OK) {
1349 			if (unlink(fullpath) != 0) {
1350 				SET_SYS_ERROR(kmfh, errno);
1351 				rv = KMF_ERR_INTERNAL;
1352 			}
1353 		}
1354 	}
1355 
1356 out:
1357 	if (fullpath != NULL)
1358 		free(fullpath);
1359 
1360 	kmf_free_data(&certdata);
1361 
1362 	return (rv);
1363 }
1364 
1365 KMF_RETURN
1366 OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
1367 	KMF_DATA *keydata)
1368 {
1369 	KMF_RETURN rv = KMF_OK;
1370 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1371 	int n;
1372 
1373 	if (key == NULL || keydata == NULL ||
1374 	    key->keyp == NULL)
1375 		return (KMF_ERR_BAD_PARAMETER);
1376 
1377 	if (key->keyalg == KMF_RSA) {
1378 		RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp);
1379 
1380 		if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) {
1381 			SET_ERROR(kmfh, ERR_get_error());
1382 			return (KMF_ERR_ENCODING);
1383 		}
1384 		RSA_free(pubkey);
1385 	} else if (key->keyalg == KMF_DSA) {
1386 		DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp);
1387 
1388 		if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) {
1389 			SET_ERROR(kmfh, ERR_get_error());
1390 			return (KMF_ERR_ENCODING);
1391 		}
1392 		DSA_free(pubkey);
1393 	} else {
1394 		return (KMF_ERR_BAD_PARAMETER);
1395 	}
1396 	keydata->Length = n;
1397 
1398 cleanup:
1399 	if (rv != KMF_OK) {
1400 		if (keydata->Data)
1401 			free(keydata->Data);
1402 		keydata->Data = NULL;
1403 		keydata->Length = 0;
1404 	}
1405 
1406 	return (rv);
1407 }
1408 
1409 static KMF_RETURN
1410 ssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out,
1411 	KMF_CREDENTIAL *cred, EVP_PKEY *pkey, boolean_t private)
1412 {
1413 	int rv = 0;
1414 	RSA *rsa;
1415 	DSA *dsa;
1416 
1417 	if (pkey == NULL || out == NULL)
1418 		return (KMF_ERR_BAD_PARAMETER);
1419 
1420 	switch (format) {
1421 		case KMF_FORMAT_RAWKEY:
1422 			/* same as ASN.1 */
1423 		case KMF_FORMAT_ASN1:
1424 			if (pkey->type == EVP_PKEY_RSA) {
1425 				rsa = EVP_PKEY_get1_RSA(pkey);
1426 				if (private)
1427 					rv = i2d_RSAPrivateKey_bio(out, rsa);
1428 				else
1429 					rv = i2d_RSAPublicKey_bio(out, rsa);
1430 				RSA_free(rsa);
1431 			} else if (pkey->type == EVP_PKEY_DSA) {
1432 				dsa = EVP_PKEY_get1_DSA(pkey);
1433 				rv = i2d_DSAPrivateKey_bio(out, dsa);
1434 				DSA_free(dsa);
1435 			}
1436 			if (rv == 1) {
1437 				rv = KMF_OK;
1438 			} else {
1439 				SET_ERROR(kmfh, rv);
1440 			}
1441 			break;
1442 		case KMF_FORMAT_PEM:
1443 			if (pkey->type == EVP_PKEY_RSA) {
1444 				rsa = EVP_PKEY_get1_RSA(pkey);
1445 				if (private)
1446 					rv = PEM_write_bio_RSAPrivateKey(out,
1447 					    rsa, NULL, NULL, 0, NULL,
1448 					    (cred != NULL ? cred->cred : NULL));
1449 				else
1450 					rv = PEM_write_bio_RSAPublicKey(out,
1451 					    rsa);
1452 				RSA_free(rsa);
1453 			} else if (pkey->type == EVP_PKEY_DSA) {
1454 				dsa = EVP_PKEY_get1_DSA(pkey);
1455 				rv = PEM_write_bio_DSAPrivateKey(out,
1456 				    dsa, NULL, NULL, 0, NULL,
1457 				    (cred != NULL ? cred->cred : NULL));
1458 				DSA_free(dsa);
1459 			}
1460 
1461 			if (rv == 1) {
1462 				rv = KMF_OK;
1463 			} else {
1464 				SET_ERROR(kmfh, rv);
1465 			}
1466 			break;
1467 
1468 		default:
1469 			rv = KMF_ERR_BAD_PARAMETER;
1470 	}
1471 
1472 	return (rv);
1473 }
1474 
1475 KMF_RETURN
1476 OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr,
1477 	KMF_ATTRIBUTE *attrlist)
1478 {
1479 	KMF_RETURN rv = KMF_OK;
1480 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1481 	uint32_t eValue = 0x010001;
1482 	RSA *sslPrivKey = NULL;
1483 	DSA *sslDSAKey = NULL;
1484 	EVP_PKEY *eprikey = NULL;
1485 	EVP_PKEY *epubkey = NULL;
1486 	BIO *out = NULL;
1487 	KMF_KEY_HANDLE *pubkey = NULL, *privkey = NULL;
1488 	uint32_t keylen = 1024;
1489 	uint32_t keylen_size = sizeof (uint32_t);
1490 	boolean_t storekey = TRUE;
1491 	KMF_KEY_ALG keytype = KMF_RSA;
1492 
1493 	rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr,
1494 	    &storekey, NULL);
1495 	if (rv != KMF_OK) {
1496 		/* "storekey" is optional. Default is TRUE */
1497 		rv = KMF_OK;
1498 	}
1499 
1500 	rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
1501 	    (void *)&keytype, NULL);
1502 	if (rv != KMF_OK)
1503 		/* keytype is optional.  KMF_RSA is default */
1504 		rv = KMF_OK;
1505 
1506 	pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
1507 	if (pubkey == NULL)
1508 		return (KMF_ERR_BAD_PARAMETER);
1509 
1510 	privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
1511 	if (privkey == NULL)
1512 		return (KMF_ERR_BAD_PARAMETER);
1513 
1514 	(void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
1515 	(void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
1516 
1517 	eprikey = EVP_PKEY_new();
1518 	if (eprikey == NULL) {
1519 		SET_ERROR(kmfh, ERR_get_error());
1520 		rv = KMF_ERR_KEYGEN_FAILED;
1521 		goto cleanup;
1522 	}
1523 	epubkey = EVP_PKEY_new();
1524 	if (epubkey == NULL) {
1525 		SET_ERROR(kmfh, ERR_get_error());
1526 		rv = KMF_ERR_KEYGEN_FAILED;
1527 		goto cleanup;
1528 	}
1529 	if (keytype == KMF_RSA) {
1530 		KMF_BIGINT *rsaexp = NULL;
1531 
1532 		rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attrlist, numattr);
1533 		if (rsaexp != NULL) {
1534 			if (rsaexp->len > 0 &&
1535 			    rsaexp->len <= sizeof (eValue) &&
1536 			    rsaexp->val != NULL) {
1537 				/* LINTED E_BAD_PTR_CAST_ALIGN */
1538 				eValue = *(uint32_t *)rsaexp->val;
1539 			} else {
1540 				rv = KMF_ERR_BAD_PARAMETER;
1541 				goto cleanup;
1542 			}
1543 		} else {
1544 			/* RSA Exponent is optional. Default is 0x10001 */
1545 			rv = KMF_OK;
1546 		}
1547 
1548 		rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
1549 		    &keylen, &keylen_size);
1550 		if (rv == KMF_ERR_ATTR_NOT_FOUND)
1551 			/* keylen is optional, default is 1024 */
1552 			rv = KMF_OK;
1553 		if (rv != KMF_OK) {
1554 			rv = KMF_ERR_BAD_PARAMETER;
1555 			goto cleanup;
1556 		}
1557 
1558 		sslPrivKey = RSA_generate_key(keylen, eValue, NULL, NULL);
1559 		if (sslPrivKey == NULL) {
1560 			SET_ERROR(kmfh, ERR_get_error());
1561 			rv = KMF_ERR_KEYGEN_FAILED;
1562 		} else {
1563 			(void) EVP_PKEY_set1_RSA(eprikey, sslPrivKey);
1564 			privkey->kstype = KMF_KEYSTORE_OPENSSL;
1565 			privkey->keyalg = KMF_RSA;
1566 			privkey->keyclass = KMF_ASYM_PRI;
1567 			privkey->israw = FALSE;
1568 			privkey->keyp = (void *)eprikey;
1569 
1570 			/* OpenSSL derives the public key from the private */
1571 			(void) EVP_PKEY_set1_RSA(epubkey, sslPrivKey);
1572 			pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1573 			pubkey->keyalg = KMF_RSA;
1574 			pubkey->israw = FALSE;
1575 			pubkey->keyclass = KMF_ASYM_PUB;
1576 			pubkey->keyp = (void *)epubkey;
1577 		}
1578 	} else if (keytype == KMF_DSA) {
1579 		DSA *dp;
1580 		sslDSAKey = DSA_new();
1581 		if (sslDSAKey == NULL) {
1582 			SET_ERROR(kmfh, ERR_get_error());
1583 			return (KMF_ERR_MEMORY);
1584 		}
1585 
1586 		if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) ==
1587 		    NULL) {
1588 			SET_ERROR(kmfh, ERR_get_error());
1589 			rv = KMF_ERR_KEYGEN_FAILED;
1590 			goto cleanup;
1591 		}
1592 		if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) ==
1593 		    NULL) {
1594 			SET_ERROR(kmfh, ERR_get_error());
1595 			rv = KMF_ERR_KEYGEN_FAILED;
1596 			goto cleanup;
1597 		}
1598 		if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) ==
1599 		    NULL) {
1600 			SET_ERROR(kmfh, ERR_get_error());
1601 			rv = KMF_ERR_KEYGEN_FAILED;
1602 			goto cleanup;
1603 		}
1604 
1605 		if (!DSA_generate_key(sslDSAKey)) {
1606 			SET_ERROR(kmfh, ERR_get_error());
1607 			rv = KMF_ERR_KEYGEN_FAILED;
1608 			goto cleanup;
1609 		}
1610 
1611 		privkey->kstype = KMF_KEYSTORE_OPENSSL;
1612 		privkey->keyalg = KMF_DSA;
1613 		privkey->keyclass = KMF_ASYM_PRI;
1614 		privkey->israw = FALSE;
1615 		if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) {
1616 			privkey->keyp = (void *)eprikey;
1617 		} else {
1618 			SET_ERROR(kmfh, ERR_get_error());
1619 			rv = KMF_ERR_KEYGEN_FAILED;
1620 			goto cleanup;
1621 		}
1622 		dp = DSA_new();
1623 		/* Make a copy for the public key */
1624 		if (dp != NULL) {
1625 			if ((dp->p = BN_new()) == NULL) {
1626 				SET_ERROR(kmfh, ERR_get_error());
1627 				rv = KMF_ERR_MEMORY;
1628 				DSA_free(dp);
1629 				goto cleanup;
1630 			}
1631 			if ((dp->q = BN_new()) == NULL) {
1632 				SET_ERROR(kmfh, ERR_get_error());
1633 				rv = KMF_ERR_MEMORY;
1634 				BN_free(dp->p);
1635 				DSA_free(dp);
1636 				goto cleanup;
1637 			}
1638 			if ((dp->g = BN_new()) == NULL) {
1639 				SET_ERROR(kmfh, ERR_get_error());
1640 				rv = KMF_ERR_MEMORY;
1641 				BN_free(dp->q);
1642 				BN_free(dp->p);
1643 				DSA_free(dp);
1644 				goto cleanup;
1645 			}
1646 			if ((dp->pub_key = BN_new()) == NULL) {
1647 				SET_ERROR(kmfh, ERR_get_error());
1648 				rv = KMF_ERR_MEMORY;
1649 				BN_free(dp->q);
1650 				BN_free(dp->p);
1651 				BN_free(dp->g);
1652 				DSA_free(dp);
1653 				goto cleanup;
1654 			}
1655 			(void) BN_copy(dp->p, sslDSAKey->p);
1656 			(void) BN_copy(dp->q, sslDSAKey->q);
1657 			(void) BN_copy(dp->g, sslDSAKey->g);
1658 			(void) BN_copy(dp->pub_key, sslDSAKey->pub_key);
1659 
1660 			pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1661 			pubkey->keyalg = KMF_DSA;
1662 			pubkey->keyclass = KMF_ASYM_PUB;
1663 			pubkey->israw = FALSE;
1664 
1665 			if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) {
1666 				pubkey->keyp = (void *)epubkey;
1667 			} else {
1668 				SET_ERROR(kmfh, ERR_get_error());
1669 				rv = KMF_ERR_KEYGEN_FAILED;
1670 				goto cleanup;
1671 			}
1672 		}
1673 	}
1674 
1675 	if (rv != KMF_OK) {
1676 		goto cleanup;
1677 	}
1678 
1679 	if (storekey) {
1680 		KMF_ATTRIBUTE storeattrs[4]; /* max. 4 attributes needed */
1681 		int i = 0;
1682 		char *keyfile = NULL, *dirpath = NULL;
1683 		KMF_ENCODE_FORMAT format;
1684 		/*
1685 		 * Construct a new attribute arrray and call openssl_store_key
1686 		 */
1687 		kmf_set_attr_at_index(storeattrs, i, KMF_PRIVKEY_HANDLE_ATTR,
1688 		    privkey, sizeof (privkey));
1689 		i++;
1690 
1691 		dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1692 		if (dirpath != NULL) {
1693 			storeattrs[i].type = KMF_DIRPATH_ATTR;
1694 			storeattrs[i].pValue = dirpath;
1695 			storeattrs[i].valueLen = strlen(dirpath);
1696 			i++;
1697 		} else {
1698 			rv = KMF_OK; /* DIRPATH is optional */
1699 		}
1700 		keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR,
1701 		    attrlist, numattr);
1702 		if (keyfile != NULL) {
1703 			storeattrs[i].type = KMF_KEY_FILENAME_ATTR;
1704 			storeattrs[i].pValue = keyfile;
1705 			storeattrs[i].valueLen = strlen(keyfile);
1706 			i++;
1707 		} else {
1708 			goto cleanup; /* KEYFILE is required */
1709 		}
1710 		rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
1711 		    (void *)&format, NULL);
1712 		if (rv == KMF_OK) {
1713 			storeattrs[i].type = KMF_ENCODE_FORMAT_ATTR;
1714 			storeattrs[i].pValue = &format;
1715 			storeattrs[i].valueLen = sizeof (format);
1716 			i++;
1717 		}
1718 
1719 		rv = OpenSSL_StoreKey(handle, i, storeattrs);
1720 	}
1721 
1722 cleanup:
1723 	if (rv != KMF_OK) {
1724 		if (eprikey != NULL)
1725 			EVP_PKEY_free(eprikey);
1726 
1727 		if (epubkey != NULL)
1728 			EVP_PKEY_free(epubkey);
1729 
1730 		if (pubkey->keylabel) {
1731 			free(pubkey->keylabel);
1732 			pubkey->keylabel = NULL;
1733 		}
1734 
1735 		if (privkey->keylabel) {
1736 			free(privkey->keylabel);
1737 			privkey->keylabel = NULL;
1738 		}
1739 
1740 		pubkey->keyp = NULL;
1741 		privkey->keyp = NULL;
1742 	}
1743 
1744 	if (sslPrivKey)
1745 		RSA_free(sslPrivKey);
1746 
1747 	if (sslDSAKey)
1748 		DSA_free(sslDSAKey);
1749 
1750 	if (out != NULL)
1751 		(void) BIO_free(out);
1752 
1753 	return (rv);
1754 }
1755 
1756 /*
1757  * Make sure the BN conversion is properly padded with 0x00
1758  * bytes.  If not, signature verification for DSA signatures
1759  * may fail in the case where the bignum value does not use
1760  * all of the bits.
1761  */
1762 static int
1763 fixbnlen(BIGNUM *bn, unsigned char *buf, int len) {
1764 	int bytes = len - BN_num_bytes(bn);
1765 
1766 	/* prepend with leading 0x00 if necessary */
1767 	while (bytes-- > 0)
1768 		*buf++ = 0;
1769 
1770 	(void) BN_bn2bin(bn, buf);
1771 	/*
1772 	 * Return the desired length since we prepended it
1773 	 * with the necessary 0x00 padding.
1774 	 */
1775 	return (len);
1776 }
1777 
1778 KMF_RETURN
1779 OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
1780 	KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output)
1781 {
1782 	KMF_RETURN ret = KMF_OK;
1783 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1784 	KMF_ALGORITHM_INDEX		AlgId;
1785 	EVP_MD_CTX ctx;
1786 	const EVP_MD *md;
1787 
1788 	if (key == NULL || AlgOID == NULL ||
1789 	    tobesigned == NULL || output == NULL ||
1790 	    tobesigned->Data == NULL ||
1791 	    output->Data == NULL)
1792 		return (KMF_ERR_BAD_PARAMETER);
1793 
1794 	/* Map the OID to an OpenSSL algorithm */
1795 	AlgId = x509_algoid_to_algid(AlgOID);
1796 	if (AlgId == KMF_ALGID_NONE)
1797 		return (KMF_ERR_BAD_ALGORITHM);
1798 
1799 	if (key->keyalg == KMF_RSA) {
1800 		EVP_PKEY *pkey = (EVP_PKEY *)key->keyp;
1801 		uchar_t *p;
1802 		int len;
1803 		if (AlgId == KMF_ALGID_MD5WithRSA)
1804 			md = EVP_md5();
1805 		else if (AlgId == KMF_ALGID_MD2WithRSA)
1806 			md = EVP_md2();
1807 		else if (AlgId == KMF_ALGID_SHA1WithRSA)
1808 			md = EVP_sha1();
1809 		else if (AlgId == KMF_ALGID_SHA256WithRSA)
1810 			md = EVP_sha256();
1811 		else if (AlgId == KMF_ALGID_SHA384WithRSA)
1812 			md = EVP_sha384();
1813 		else if (AlgId == KMF_ALGID_SHA512WithRSA)
1814 			md = EVP_sha512();
1815 		else if (AlgId == KMF_ALGID_RSA)
1816 			md = NULL;
1817 		else
1818 			return (KMF_ERR_BAD_ALGORITHM);
1819 
1820 		if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) {
1821 			RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey);
1822 
1823 			p = output->Data;
1824 			if ((len = RSA_private_encrypt(tobesigned->Length,
1825 			    tobesigned->Data, p, rsa,
1826 			    RSA_PKCS1_PADDING)) <= 0) {
1827 				SET_ERROR(kmfh, ERR_get_error());
1828 				ret = KMF_ERR_INTERNAL;
1829 			}
1830 			output->Length = len;
1831 		} else {
1832 			(void) EVP_MD_CTX_init(&ctx);
1833 			(void) EVP_SignInit_ex(&ctx, md, NULL);
1834 			(void) EVP_SignUpdate(&ctx, tobesigned->Data,
1835 			    (uint32_t)tobesigned->Length);
1836 			len = (uint32_t)output->Length;
1837 			p = output->Data;
1838 			if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) {
1839 				SET_ERROR(kmfh, ERR_get_error());
1840 				len = 0;
1841 				ret = KMF_ERR_INTERNAL;
1842 			}
1843 			output->Length = len;
1844 			(void) EVP_MD_CTX_cleanup(&ctx);
1845 		}
1846 	} else if (key->keyalg == KMF_DSA) {
1847 		DSA *dsa = EVP_PKEY_get1_DSA(key->keyp);
1848 
1849 		uchar_t hash[EVP_MAX_MD_SIZE];
1850 		uint32_t hashlen;
1851 		DSA_SIG *dsasig;
1852 
1853 		if (AlgId == KMF_ALGID_DSA ||
1854 		    AlgId == KMF_ALGID_SHA1WithDSA)
1855 			md = EVP_sha1();
1856 		else if (AlgId == KMF_ALGID_SHA256WithDSA)
1857 			md = EVP_sha256();
1858 		else /* Bad algorithm */
1859 			return (KMF_ERR_BAD_ALGORITHM);
1860 
1861 		/*
1862 		 * OpenSSL EVP_Sign operation automatically converts to
1863 		 * ASN.1 output so we do the operations separately so we
1864 		 * are assured of NOT getting ASN.1 output returned.
1865 		 * KMF does not want ASN.1 encoded results because
1866 		 * not all mechanisms return ASN.1 encodings (PKCS#11
1867 		 * and NSS return raw signature data).
1868 		 */
1869 		EVP_MD_CTX_init(&ctx);
1870 		(void) EVP_DigestInit_ex(&ctx, md, NULL);
1871 		(void) EVP_DigestUpdate(&ctx, tobesigned->Data,
1872 		    tobesigned->Length);
1873 		(void) EVP_DigestFinal_ex(&ctx, hash, &hashlen);
1874 
1875 		/* Only sign first 20 bytes for SHA2 */
1876 		if (AlgId == KMF_ALGID_SHA256WithDSA)
1877 			hashlen = 20;
1878 		dsasig = DSA_do_sign(hash, hashlen, dsa);
1879 		if (dsasig != NULL) {
1880 			int i;
1881 			output->Length = i = fixbnlen(dsasig->r, output->Data,
1882 			    hashlen);
1883 
1884 			output->Length += fixbnlen(dsasig->s, &output->Data[i],
1885 			    hashlen);
1886 
1887 			DSA_SIG_free(dsasig);
1888 		} else {
1889 			SET_ERROR(kmfh, ERR_get_error());
1890 		}
1891 		(void) EVP_MD_CTX_cleanup(&ctx);
1892 	} else {
1893 		return (KMF_ERR_BAD_PARAMETER);
1894 	}
1895 cleanup:
1896 	return (ret);
1897 }
1898 
1899 KMF_RETURN
1900 /*ARGSUSED*/
1901 OpenSSL_DeleteKey(KMF_HANDLE_T handle,
1902 	int numattr, KMF_ATTRIBUTE *attrlist)
1903 {
1904 	KMF_RETURN rv = KMF_OK;
1905 	KMF_KEY_HANDLE *key;
1906 	boolean_t destroy = B_TRUE;
1907 
1908 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
1909 	if (key == NULL || key->keyp == NULL)
1910 		return (KMF_ERR_BAD_PARAMETER);
1911 
1912 	rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
1913 	    (void *)&destroy, NULL);
1914 	if (rv != KMF_OK) {
1915 		/* "destroy" is optional. Default is TRUE */
1916 		rv = KMF_OK;
1917 	}
1918 
1919 	if (key->keyclass != KMF_ASYM_PUB &&
1920 	    key->keyclass != KMF_ASYM_PRI &&
1921 	    key->keyclass != KMF_SYMMETRIC)
1922 		return (KMF_ERR_BAD_KEY_CLASS);
1923 
1924 	if (key->keyclass == KMF_SYMMETRIC) {
1925 		kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp);
1926 		key->keyp = NULL;
1927 	} else {
1928 		if (key->keyp != NULL) {
1929 			EVP_PKEY_free(key->keyp);
1930 			key->keyp = NULL;
1931 		}
1932 	}
1933 
1934 	if (key->keylabel != NULL) {
1935 		EVP_PKEY *pkey = NULL;
1936 		/* If the file exists, make sure it is a proper key. */
1937 		pkey = openssl_load_key(handle, key->keylabel);
1938 		if (pkey == NULL) {
1939 			if (key->keylabel != NULL) {
1940 				free(key->keylabel);
1941 				key->keylabel = NULL;
1942 			}
1943 			return (KMF_ERR_KEY_NOT_FOUND);
1944 		}
1945 		EVP_PKEY_free(pkey);
1946 
1947 		if (destroy) {
1948 			if (unlink(key->keylabel) != 0) {
1949 				KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1950 				SET_SYS_ERROR(kmfh, errno);
1951 				rv = KMF_ERR_INTERNAL;
1952 			}
1953 		}
1954 		if (key->keylabel != NULL) {
1955 			free(key->keylabel);
1956 			key->keylabel = NULL;
1957 		}
1958 	}
1959 	return (rv);
1960 }
1961 
1962 KMF_RETURN
1963 OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
1964 {
1965 	KMF_RETURN ret = KMF_OK;
1966 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1967 	char str[256];	/* OpenSSL needs at least 120 byte buffer */
1968 
1969 	ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str));
1970 	if (strlen(str)) {
1971 		*msgstr = (char *)strdup(str);
1972 		if ((*msgstr) == NULL)
1973 			ret = KMF_ERR_MEMORY;
1974 	} else {
1975 		*msgstr = NULL;
1976 	}
1977 
1978 	return (ret);
1979 }
1980 
1981 static int
1982 ext2NID(int kmfext)
1983 {
1984 	switch (kmfext) {
1985 		case KMF_X509_EXT_KEY_USAGE:
1986 			return (NID_key_usage);
1987 		case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
1988 			return (NID_private_key_usage_period);
1989 		case KMF_X509_EXT_CERT_POLICIES:
1990 			return (NID_certificate_policies);
1991 		case KMF_X509_EXT_SUBJ_ALTNAME:
1992 			return (NID_subject_alt_name);
1993 		case KMF_X509_EXT_ISSUER_ALTNAME:
1994 			return (NID_issuer_alt_name);
1995 		case KMF_X509_EXT_BASIC_CONSTRAINTS:
1996 			return (NID_basic_constraints);
1997 		case KMF_X509_EXT_EXT_KEY_USAGE:
1998 			return (NID_ext_key_usage);
1999 		case KMF_X509_EXT_AUTH_KEY_ID:
2000 			return (NID_authority_key_identifier);
2001 		case KMF_X509_EXT_CRL_DIST_POINTS:
2002 			return (NID_crl_distribution_points);
2003 		case KMF_X509_EXT_SUBJ_KEY_ID:
2004 			return (NID_subject_key_identifier);
2005 		case KMF_X509_EXT_POLICY_MAPPINGS:
2006 			return (OBJ_sn2nid("policyMappings"));
2007 		case KMF_X509_EXT_NAME_CONSTRAINTS:
2008 			return (OBJ_sn2nid("nameConstraints"));
2009 		case KMF_X509_EXT_POLICY_CONSTRAINTS:
2010 			return (OBJ_sn2nid("policyConstraints"));
2011 		case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2012 			return (OBJ_sn2nid("inhibitAnyPolicy"));
2013 		case KMF_X509_EXT_FRESHEST_CRL:
2014 			return (OBJ_sn2nid("freshestCRL"));
2015 		default:
2016 			return (NID_undef);
2017 	}
2018 }
2019 
2020 KMF_RETURN
2021 OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert,
2022 	KMF_PRINTABLE_ITEM flag, char *resultStr)
2023 {
2024 	KMF_RETURN ret = KMF_OK;
2025 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2026 	X509 *xcert = NULL;
2027 	unsigned char *outbuf = NULL;
2028 	unsigned char *outbuf_p;
2029 	char *tmpstr = NULL;
2030 	int j;
2031 	int ext_index, nid, len;
2032 	BIO *mem = NULL;
2033 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2034 	STACK *emlst = NULL;
2035 #else
2036 	STACK_OF(OPENSSL_STRING) *emlst = NULL;
2037 #endif
2038 	X509_EXTENSION *ex;
2039 	X509_CINF *ci;
2040 
2041 	if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) {
2042 		return (KMF_ERR_BAD_PARAMETER);
2043 	}
2044 
2045 	/* copy cert data to outbuf */
2046 	outbuf = malloc(pcert->Length);
2047 	if (outbuf == NULL) {
2048 		return (KMF_ERR_MEMORY);
2049 	}
2050 	(void) memcpy(outbuf, pcert->Data, pcert->Length);
2051 
2052 	outbuf_p = outbuf; /* use a temp pointer; required by openssl */
2053 	xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length);
2054 	if (xcert == NULL) {
2055 		SET_ERROR(kmfh, ERR_get_error());
2056 		ret = KMF_ERR_ENCODING;
2057 		goto out;
2058 	}
2059 
2060 	mem = BIO_new(BIO_s_mem());
2061 	if (mem == NULL) {
2062 		SET_ERROR(kmfh, ERR_get_error());
2063 		ret = KMF_ERR_MEMORY;
2064 		goto out;
2065 	}
2066 
2067 	switch (flag) {
2068 	case KMF_CERT_ISSUER:
2069 		(void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0,
2070 		    XN_FLAG_SEP_CPLUS_SPC);
2071 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2072 		break;
2073 
2074 	case KMF_CERT_SUBJECT:
2075 		(void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0,
2076 		    XN_FLAG_SEP_CPLUS_SPC);
2077 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2078 		break;
2079 
2080 	case KMF_CERT_VERSION:
2081 		tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version);
2082 		(void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN);
2083 		OPENSSL_free(tmpstr);
2084 		len = strlen(resultStr);
2085 		break;
2086 
2087 	case KMF_CERT_SERIALNUM:
2088 		if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) {
2089 			(void) strcpy(resultStr, "0x");
2090 			len = BIO_gets(mem, &resultStr[2],
2091 			    KMF_CERT_PRINTABLE_LEN - 2);
2092 		}
2093 		break;
2094 
2095 	case KMF_CERT_NOTBEFORE:
2096 		(void) ASN1_TIME_print(mem, X509_get_notBefore(xcert));
2097 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2098 		break;
2099 
2100 	case KMF_CERT_NOTAFTER:
2101 		(void) ASN1_TIME_print(mem, X509_get_notAfter(xcert));
2102 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2103 		break;
2104 
2105 	case KMF_CERT_PUBKEY_DATA:
2106 		{
2107 			EVP_PKEY *pkey = X509_get_pubkey(xcert);
2108 			if (pkey == NULL) {
2109 				SET_ERROR(kmfh, ERR_get_error());
2110 				ret = KMF_ERR_ENCODING;
2111 				goto out;
2112 			}
2113 
2114 			if (pkey->type == EVP_PKEY_RSA) {
2115 				(void) BIO_printf(mem,
2116 				    "RSA Public Key: (%d bit)\n",
2117 				    BN_num_bits(pkey->pkey.rsa->n));
2118 				(void) RSA_print(mem, pkey->pkey.rsa, 0);
2119 			} else if (pkey->type == EVP_PKEY_DSA) {
2120 				(void) BIO_printf(mem,
2121 				    "%12sDSA Public Key:\n", "");
2122 				(void) DSA_print(mem, pkey->pkey.dsa, 0);
2123 			} else {
2124 				(void) BIO_printf(mem,
2125 				    "%12sUnknown Public Key:\n", "");
2126 			}
2127 			(void) BIO_printf(mem, "\n");
2128 			EVP_PKEY_free(pkey);
2129 		}
2130 		len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2131 		break;
2132 	case KMF_CERT_SIGNATURE_ALG:
2133 	case KMF_CERT_PUBKEY_ALG:
2134 		if (flag == KMF_CERT_SIGNATURE_ALG) {
2135 			len = i2a_ASN1_OBJECT(mem,
2136 			    xcert->sig_alg->algorithm);
2137 		} else {
2138 			len = i2a_ASN1_OBJECT(mem,
2139 			    xcert->cert_info->key->algor->algorithm);
2140 		}
2141 
2142 		if (len > 0) {
2143 			len = BIO_read(mem, resultStr,
2144 			    KMF_CERT_PRINTABLE_LEN);
2145 		}
2146 		break;
2147 
2148 	case KMF_CERT_EMAIL:
2149 		emlst = X509_get1_email(xcert);
2150 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2151 		for (j = 0; j < sk_num(emlst); j++)
2152 			(void) BIO_printf(mem, "%s\n", sk_value(emlst, j));
2153 #else
2154 		for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
2155 			(void) BIO_printf(mem, "%s\n",
2156 			    sk_OPENSSL_STRING_value(emlst, j));
2157 #endif
2158 
2159 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2160 		X509_email_free(emlst);
2161 		break;
2162 	case KMF_X509_EXT_ISSUER_ALTNAME:
2163 	case KMF_X509_EXT_SUBJ_ALTNAME:
2164 	case KMF_X509_EXT_KEY_USAGE:
2165 	case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
2166 	case KMF_X509_EXT_CERT_POLICIES:
2167 	case KMF_X509_EXT_BASIC_CONSTRAINTS:
2168 	case KMF_X509_EXT_NAME_CONSTRAINTS:
2169 	case KMF_X509_EXT_POLICY_CONSTRAINTS:
2170 	case KMF_X509_EXT_EXT_KEY_USAGE:
2171 	case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2172 	case KMF_X509_EXT_AUTH_KEY_ID:
2173 	case KMF_X509_EXT_SUBJ_KEY_ID:
2174 	case KMF_X509_EXT_POLICY_MAPPINGS:
2175 	case KMF_X509_EXT_CRL_DIST_POINTS:
2176 	case KMF_X509_EXT_FRESHEST_CRL:
2177 		nid = ext2NID(flag);
2178 		if (nid == NID_undef) {
2179 			ret = KMF_ERR_EXTENSION_NOT_FOUND;
2180 			goto out;
2181 		}
2182 		ci = xcert->cert_info;
2183 
2184 		ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1);
2185 		if (ext_index == -1) {
2186 			SET_ERROR(kmfh, ERR_get_error());
2187 
2188 			ret = KMF_ERR_EXTENSION_NOT_FOUND;
2189 			goto out;
2190 		}
2191 		ex = X509v3_get_ext(ci->extensions, ext_index);
2192 
2193 		(void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex));
2194 
2195 		if (BIO_printf(mem, ": %s\n",
2196 		    X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) {
2197 			SET_ERROR(kmfh, ERR_get_error());
2198 			ret = KMF_ERR_ENCODING;
2199 			goto out;
2200 		}
2201 		if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) {
2202 			(void) BIO_printf(mem, "%*s", 4, "");
2203 			(void) M_ASN1_OCTET_STRING_print(mem, ex->value);
2204 		}
2205 		if (BIO_write(mem, "\n", 1) <= 0) {
2206 			SET_ERROR(kmfh, ERR_get_error());
2207 			ret = KMF_ERR_ENCODING;
2208 			goto out;
2209 		}
2210 		len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2211 	}
2212 	if (len <= 0) {
2213 		SET_ERROR(kmfh, ERR_get_error());
2214 		ret = KMF_ERR_ENCODING;
2215 	}
2216 
2217 out:
2218 	if (outbuf != NULL) {
2219 		free(outbuf);
2220 	}
2221 
2222 	if (xcert != NULL) {
2223 		X509_free(xcert);
2224 	}
2225 
2226 	if (mem != NULL) {
2227 		(void) BIO_free(mem);
2228 	}
2229 
2230 	return (ret);
2231 }
2232 
2233 KMF_RETURN
2234 /*ARGSUSED*/
2235 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
2236     KMF_ATTRIBUTE *attrlist)
2237 {
2238 	KMF_RETURN rv = KMF_OK;
2239 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
2240 	KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
2241 	KMF_KEY_HANDLE *key = NULL;
2242 	uint32_t numkeys = 1; /* 1 key only */
2243 	char *dirpath = NULL;
2244 	char *keyfile = NULL;
2245 	KMF_ATTRIBUTE new_attrlist[16];
2246 	int i = 0;
2247 
2248 	/*
2249 	 * This is really just a FindKey operation, reuse the
2250 	 * FindKey function.
2251 	 */
2252 	kmf_set_attr_at_index(new_attrlist, i,
2253 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2254 	i++;
2255 
2256 	kmf_set_attr_at_index(new_attrlist, i,
2257 	    KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t));
2258 	i++;
2259 
2260 	kmf_set_attr_at_index(new_attrlist, i,
2261 	    KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass));
2262 	i++;
2263 
2264 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2265 	if (key == NULL) {
2266 		return (KMF_ERR_BAD_PARAMETER);
2267 	} else {
2268 		kmf_set_attr_at_index(new_attrlist, i,
2269 		    KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
2270 		i++;
2271 	}
2272 
2273 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2274 	if (dirpath != NULL) {
2275 		kmf_set_attr_at_index(new_attrlist, i,
2276 		    KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
2277 		i++;
2278 	}
2279 
2280 	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
2281 	if (keyfile == NULL)
2282 		return (KMF_ERR_BAD_PARAMETER);
2283 	else {
2284 		kmf_set_attr_at_index(new_attrlist, i,
2285 		    KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
2286 		i++;
2287 	}
2288 
2289 	rv = OpenSSL_FindKey(handle, i, new_attrlist);
2290 	return (rv);
2291 }
2292 
2293 KMF_RETURN
2294 /*ARGSUSED*/
2295 OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
2296 	KMF_OID *AlgOID, KMF_DATA *ciphertext,
2297 	KMF_DATA *output)
2298 {
2299 	KMF_RETURN		ret = KMF_OK;
2300 	RSA *rsa = NULL;
2301 	unsigned int in_len = 0, out_len = 0;
2302 	unsigned int total_decrypted = 0, modulus_len = 0;
2303 	uint8_t *in_data, *out_data;
2304 	int i, blocks;
2305 
2306 	if (key == NULL || AlgOID == NULL ||
2307 	    ciphertext == NULL || output == NULL ||
2308 	    ciphertext->Data == NULL ||
2309 	    output->Data == NULL)
2310 		return (KMF_ERR_BAD_PARAMETER);
2311 
2312 	if (key->keyalg == KMF_RSA) {
2313 		rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp);
2314 		modulus_len = RSA_size(rsa);
2315 	} else {
2316 		return (KMF_ERR_BAD_PARAMETER);
2317 	}
2318 
2319 	blocks = ciphertext->Length/modulus_len;
2320 	out_data = output->Data;
2321 	in_data = ciphertext->Data;
2322 	out_len = modulus_len - 11;
2323 	in_len = modulus_len;
2324 
2325 	for (i = 0; i < blocks; i++) {
2326 		out_len  = RSA_private_decrypt(in_len,
2327 		    in_data, out_data, rsa, RSA_PKCS1_PADDING);
2328 
2329 		if (out_len == 0) {
2330 			ret = KMF_ERR_INTERNAL;
2331 			goto cleanup;
2332 		}
2333 
2334 		out_data += out_len;
2335 		total_decrypted += out_len;
2336 		in_data += in_len;
2337 	}
2338 
2339 	output->Length = total_decrypted;
2340 
2341 cleanup:
2342 	RSA_free(rsa);
2343 	if (ret != KMF_OK)
2344 		output->Length = 0;
2345 
2346 	return (ret);
2347 
2348 }
2349 
2350 /*
2351  *  This function will create a certid from issuer_cert and user_cert.
2352  *  The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2353  *  certid memory after use.
2354  */
2355 static KMF_RETURN
2356 create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert,
2357     const KMF_DATA *user_cert, OCSP_CERTID **certid)
2358 {
2359 	KMF_RETURN ret = KMF_OK;
2360 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2361 	X509   *issuer = NULL;
2362 	X509   *cert = NULL;
2363 	unsigned char *ptmp;
2364 
2365 	if (issuer_cert == NULL || user_cert == NULL) {
2366 		return (KMF_ERR_BAD_PARAMETER);
2367 	}
2368 
2369 	/* convert the DER-encoded issuer cert to an internal X509 */
2370 	ptmp = issuer_cert->Data;
2371 	issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2372 	    issuer_cert->Length);
2373 	if (issuer == NULL) {
2374 		SET_ERROR(kmfh, ERR_get_error());
2375 		ret = KMF_ERR_OCSP_BAD_ISSUER;
2376 		goto end;
2377 	}
2378 
2379 	/* convert the DER-encoded user cert to an internal X509 */
2380 	ptmp = user_cert->Data;
2381 	cert = d2i_X509(NULL, (const uchar_t **)&ptmp,
2382 	    user_cert->Length);
2383 	if (cert == NULL) {
2384 		SET_ERROR(kmfh, ERR_get_error());
2385 
2386 		ret = KMF_ERR_OCSP_BAD_CERT;
2387 		goto end;
2388 	}
2389 
2390 	/* create a CERTID */
2391 	*certid = OCSP_cert_to_id(NULL, cert, issuer);
2392 	if (*certid == NULL) {
2393 		SET_ERROR(kmfh, ERR_get_error());
2394 		ret = KMF_ERR_OCSP_CERTID;
2395 		goto end;
2396 	}
2397 
2398 end:
2399 	if (issuer != NULL) {
2400 		X509_free(issuer);
2401 	}
2402 
2403 	if (cert != NULL) {
2404 		X509_free(cert);
2405 	}
2406 
2407 	return (ret);
2408 }
2409 
2410 KMF_RETURN
2411 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle,
2412 	int numattr, KMF_ATTRIBUTE *attrlist)
2413 {
2414 	KMF_RETURN ret = KMF_OK;
2415 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2416 	OCSP_CERTID *id = NULL;
2417 	OCSP_REQUEST *req = NULL;
2418 	BIO *derbio = NULL;
2419 	char *reqfile;
2420 	KMF_DATA *issuer_cert;
2421 	KMF_DATA *user_cert;
2422 
2423 	user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
2424 	    attrlist, numattr);
2425 	if (user_cert == NULL)
2426 		return (KMF_ERR_BAD_PARAMETER);
2427 
2428 	issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
2429 	    attrlist, numattr);
2430 	if (issuer_cert == NULL)
2431 		return (KMF_ERR_BAD_PARAMETER);
2432 
2433 	reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR,
2434 	    attrlist, numattr);
2435 	if (reqfile == NULL)
2436 		return (KMF_ERR_BAD_PARAMETER);
2437 
2438 	ret = create_certid(handle, issuer_cert, user_cert, &id);
2439 	if (ret != KMF_OK) {
2440 		return (ret);
2441 	}
2442 
2443 	/* Create an OCSP request */
2444 	req = OCSP_REQUEST_new();
2445 	if (req == NULL) {
2446 		SET_ERROR(kmfh, ERR_get_error());
2447 		ret = KMF_ERR_OCSP_CREATE_REQUEST;
2448 		goto end;
2449 	}
2450 
2451 	if (!OCSP_request_add0_id(req, id)) {
2452 		ret = KMF_ERR_OCSP_CREATE_REQUEST;
2453 		goto end;
2454 	}
2455 
2456 	/* Write the request to the output file with DER encoding */
2457 	derbio = BIO_new_file(reqfile, "wb");
2458 	if (!derbio) {
2459 		SET_ERROR(kmfh, ERR_get_error());
2460 		ret = KMF_ERR_OPEN_FILE;
2461 		goto end;
2462 	}
2463 	if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) {
2464 		ret = KMF_ERR_ENCODING;
2465 	}
2466 
2467 end:
2468 	/*
2469 	 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2470 	 * will also deallocate certid's space.
2471 	 */
2472 	if (req != NULL) {
2473 		OCSP_REQUEST_free(req);
2474 	}
2475 
2476 	if (derbio != NULL) {
2477 		(void) BIO_free(derbio);
2478 	}
2479 
2480 	return (ret);
2481 }
2482 
2483 /* ocsp_find_signer_sk() is copied from openssl source */
2484 static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
2485 {
2486 	int i;
2487 	unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
2488 
2489 	/* Easy if lookup by name */
2490 	if (id->type == V_OCSP_RESPID_NAME)
2491 		return (X509_find_by_subject(certs, id->value.byName));
2492 
2493 	/* Lookup by key hash */
2494 
2495 	/* If key hash isn't SHA1 length then forget it */
2496 	if (id->value.byKey->length != SHA_DIGEST_LENGTH)
2497 		return (NULL);
2498 
2499 	keyhash = id->value.byKey->data;
2500 	/* Calculate hash of each key and compare */
2501 	for (i = 0; i < sk_X509_num(certs); i++) {
2502 		/* LINTED E_BAD_PTR_CAST_ALIGN */
2503 		X509 *x = sk_X509_value(certs, i);
2504 		/* Use pubkey_digest to get the key ID value */
2505 		(void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
2506 		if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
2507 			return (x);
2508 	}
2509 	return (NULL);
2510 }
2511 
2512 /* ocsp_find_signer() is copied from openssl source */
2513 /* ARGSUSED2 */
2514 static int
2515 ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
2516     X509_STORE *st, unsigned long flags)
2517 {
2518 	X509 *signer;
2519 	OCSP_RESPID *rid = bs->tbsResponseData->responderId;
2520 	if ((signer = ocsp_find_signer_sk(certs, rid)))	{
2521 		*psigner = signer;
2522 		return (2);
2523 	}
2524 	if (!(flags & OCSP_NOINTERN) &&
2525 	    (signer = ocsp_find_signer_sk(bs->certs, rid))) {
2526 		*psigner = signer;
2527 		return (1);
2528 	}
2529 	/* Maybe lookup from store if by subject name */
2530 
2531 	*psigner = NULL;
2532 	return (0);
2533 }
2534 
2535 /*
2536  * This function will verify the signature of a basic response, using
2537  * the public key from the OCSP responder certificate.
2538  */
2539 static KMF_RETURN
2540 check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs,
2541     KMF_DATA *signer_cert, KMF_DATA *issuer_cert)
2542 {
2543 	KMF_RETURN ret = KMF_OK;
2544 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2545 	STACK_OF(X509) *cert_stack = NULL;
2546 	X509 *signer = NULL;
2547 	X509 *issuer = NULL;
2548 	EVP_PKEY *skey = NULL;
2549 	unsigned char *ptmp;
2550 
2551 
2552 	if (bs == NULL || issuer_cert == NULL)
2553 		return (KMF_ERR_BAD_PARAMETER);
2554 
2555 	/*
2556 	 * Find the certificate that signed the basic response.
2557 	 *
2558 	 * If signer_cert is not NULL, we will use that as the signer cert.
2559 	 * Otherwise, we will check if the issuer cert is actually the signer.
2560 	 * If we still do not find a signer, we will look for it from the
2561 	 * certificate list came with the response file.
2562 	 */
2563 	if (signer_cert != NULL) {
2564 		ptmp = signer_cert->Data;
2565 		signer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2566 		    signer_cert->Length);
2567 		if (signer == NULL) {
2568 			SET_ERROR(kmfh, ERR_get_error());
2569 			ret = KMF_ERR_OCSP_BAD_SIGNER;
2570 			goto end;
2571 		}
2572 	} else {
2573 		/*
2574 		 * Convert the issuer cert into X509 and push it into a
2575 		 * stack to be used by ocsp_find_signer().
2576 		 */
2577 		ptmp = issuer_cert->Data;
2578 		issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2579 		    issuer_cert->Length);
2580 		if (issuer == NULL) {
2581 			SET_ERROR(kmfh, ERR_get_error());
2582 			ret = KMF_ERR_OCSP_BAD_ISSUER;
2583 			goto end;
2584 		}
2585 
2586 		if ((cert_stack = sk_X509_new_null()) == NULL) {
2587 			ret = KMF_ERR_INTERNAL;
2588 			goto end;
2589 		}
2590 
2591 		if (sk_X509_push(cert_stack, issuer) == NULL) {
2592 			ret = KMF_ERR_INTERNAL;
2593 			goto end;
2594 		}
2595 
2596 		ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0);
2597 		if (!ret) {
2598 			/* can not find the signer */
2599 			ret = KMF_ERR_OCSP_BAD_SIGNER;
2600 			goto end;
2601 		}
2602 	}
2603 
2604 	/* Verify the signature of the response */
2605 	skey = X509_get_pubkey(signer);
2606 	if (skey == NULL) {
2607 		ret = KMF_ERR_OCSP_BAD_SIGNER;
2608 		goto end;
2609 	}
2610 
2611 	ret = OCSP_BASICRESP_verify(bs, skey, 0);
2612 	if (ret == 0) {
2613 		ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE;
2614 		goto end;
2615 	}
2616 
2617 end:
2618 	if (issuer != NULL) {
2619 		X509_free(issuer);
2620 	}
2621 
2622 	if (signer != NULL) {
2623 		X509_free(signer);
2624 	}
2625 
2626 	if (skey != NULL) {
2627 		EVP_PKEY_free(skey);
2628 	}
2629 
2630 	if (cert_stack != NULL) {
2631 		sk_X509_free(cert_stack);
2632 	}
2633 
2634 	return (ret);
2635 }
2636 
2637 
2638 
2639 KMF_RETURN
2640 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,
2641 	int numattr, KMF_ATTRIBUTE *attrlist)
2642 {
2643 	KMF_RETURN ret = KMF_OK;
2644 	BIO *derbio = NULL;
2645 	OCSP_RESPONSE *resp = NULL;
2646 	OCSP_BASICRESP *bs = NULL;
2647 	OCSP_CERTID *id = NULL;
2648 	OCSP_SINGLERESP *single = NULL;
2649 	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
2650 	int index, status, reason;
2651 	KMF_DATA *issuer_cert;
2652 	KMF_DATA *user_cert;
2653 	KMF_DATA *signer_cert;
2654 	KMF_DATA *response;
2655 	int *response_reason, *response_status, *cert_status;
2656 	boolean_t ignore_response_sign = B_FALSE;	/* default is FALSE */
2657 	uint32_t response_lifetime;
2658 
2659 	issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
2660 	    attrlist, numattr);
2661 	if (issuer_cert == NULL)
2662 		return (KMF_ERR_BAD_PARAMETER);
2663 
2664 	user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
2665 	    attrlist, numattr);
2666 	if (user_cert == NULL)
2667 		return (KMF_ERR_BAD_PARAMETER);
2668 
2669 	response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR,
2670 	    attrlist, numattr);
2671 	if (response == NULL)
2672 		return (KMF_ERR_BAD_PARAMETER);
2673 
2674 	response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR,
2675 	    attrlist, numattr);
2676 	if (response_status == NULL)
2677 		return (KMF_ERR_BAD_PARAMETER);
2678 
2679 	response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR,
2680 	    attrlist, numattr);
2681 	if (response_reason == NULL)
2682 		return (KMF_ERR_BAD_PARAMETER);
2683 
2684 	cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR,
2685 	    attrlist, numattr);
2686 	if (cert_status == NULL)
2687 		return (KMF_ERR_BAD_PARAMETER);
2688 
2689 	/* Read in the response */
2690 	derbio = BIO_new_mem_buf(response->Data, response->Length);
2691 	if (!derbio) {
2692 		ret = KMF_ERR_MEMORY;
2693 		return (ret);
2694 	}
2695 
2696 	resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
2697 	if (resp == NULL) {
2698 		ret = KMF_ERR_OCSP_MALFORMED_RESPONSE;
2699 		goto end;
2700 	}
2701 
2702 	/* Check the response status */
2703 	status = OCSP_response_status(resp);
2704 	*response_status = status;
2705 	if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
2706 		ret = KMF_ERR_OCSP_RESPONSE_STATUS;
2707 		goto end;
2708 	}
2709 
2710 #ifdef DEBUG
2711 	printf("Successfully checked the response file status.\n");
2712 #endif /* DEBUG */
2713 
2714 	/* Extract basic response */
2715 	bs = OCSP_response_get1_basic(resp);
2716 	if (bs == NULL) {
2717 		ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE;
2718 		goto end;
2719 	}
2720 
2721 #ifdef DEBUG
2722 	printf("Successfully retrieved the basic response.\n");
2723 #endif /* DEBUG */
2724 
2725 	/* Check the basic response signature if required */
2726 	ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr,
2727 	    (void *)&ignore_response_sign, NULL);
2728 	if (ret != KMF_OK)
2729 		ret = KMF_OK;
2730 
2731 	signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR,
2732 	    attrlist, numattr);
2733 
2734 	if (ignore_response_sign == B_FALSE) {
2735 		ret = check_response_signature(handle, bs,
2736 		    signer_cert, issuer_cert);
2737 		if (ret != KMF_OK)
2738 			goto end;
2739 	}
2740 
2741 #ifdef DEBUG
2742 	printf("Successfully verified the response signature.\n");
2743 #endif /* DEBUG */
2744 
2745 	/* Create a certid for the certificate in question */
2746 	ret = create_certid(handle, issuer_cert, user_cert, &id);
2747 	if (ret != KMF_OK) {
2748 		ret = KMF_ERR_OCSP_CERTID;
2749 		goto end;
2750 	}
2751 
2752 #ifdef DEBUG
2753 	printf("successfully created a certid for the cert.\n");
2754 #endif /* DEBUG */
2755 
2756 	/* Find the index of the single response for the certid */
2757 	index = OCSP_resp_find(bs, id, -1);
2758 	if (index < 0) {
2759 		/* cound not find this certificate in the response */
2760 		ret = KMF_ERR_OCSP_UNKNOWN_CERT;
2761 		goto end;
2762 	}
2763 
2764 #ifdef DEBUG
2765 	printf("Successfully found the single response index for the cert.\n");
2766 #endif /* DEBUG */
2767 
2768 	/* Retrieve the single response and get the cert status */
2769 	single = OCSP_resp_get0(bs, index);
2770 	status = OCSP_single_get0_status(single, &reason, &rev, &thisupd,
2771 	    &nextupd);
2772 	if (status == V_OCSP_CERTSTATUS_GOOD) {
2773 		*cert_status = OCSP_GOOD;
2774 	} else if (status == V_OCSP_CERTSTATUS_UNKNOWN) {
2775 		*cert_status = OCSP_UNKNOWN;
2776 	} else { /* revoked */
2777 		*cert_status = OCSP_REVOKED;
2778 		*response_reason = reason;
2779 	}
2780 	ret = KMF_OK;
2781 
2782 	/* resp. time is optional, so we don't care about the return code. */
2783 	(void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr,
2784 	    (void *)&response_lifetime, NULL);
2785 
2786 	if (!OCSP_check_validity(thisupd, nextupd, 300,
2787 	    response_lifetime)) {
2788 		ret = KMF_ERR_OCSP_STATUS_TIME_INVALID;
2789 		goto end;
2790 	}
2791 
2792 #ifdef DEBUG
2793 	printf("Successfully verify the time.\n");
2794 #endif /* DEBUG */
2795 
2796 end:
2797 	if (derbio != NULL)
2798 		(void) BIO_free(derbio);
2799 
2800 	if (resp != NULL)
2801 		OCSP_RESPONSE_free(resp);
2802 
2803 	if (bs != NULL)
2804 		OCSP_BASICRESP_free(bs);
2805 
2806 	if (id != NULL)
2807 		OCSP_CERTID_free(id);
2808 
2809 	return (ret);
2810 }
2811 
2812 static KMF_RETURN
2813 fetch_key(KMF_HANDLE_T handle, char *path,
2814 	KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key)
2815 {
2816 	KMF_RETURN rv = KMF_OK;
2817 	EVP_PKEY *pkey = NULL;
2818 	KMF_RAW_SYM_KEY *rkey = NULL;
2819 
2820 	if (keyclass == KMF_ASYM_PRI ||
2821 	    keyclass == KMF_ASYM_PUB) {
2822 		pkey = openssl_load_key(handle, path);
2823 		if (pkey == NULL) {
2824 			return (KMF_ERR_KEY_NOT_FOUND);
2825 		}
2826 		if (key != NULL) {
2827 			if (pkey->type == EVP_PKEY_RSA)
2828 				key->keyalg = KMF_RSA;
2829 			else if (pkey->type == EVP_PKEY_DSA)
2830 				key->keyalg = KMF_DSA;
2831 
2832 			key->kstype = KMF_KEYSTORE_OPENSSL;
2833 			key->keyclass = keyclass;
2834 			key->keyp = (void *)pkey;
2835 			key->israw = FALSE;
2836 			if (path != NULL &&
2837 			    ((key->keylabel = strdup(path)) == NULL)) {
2838 				EVP_PKEY_free(pkey);
2839 				return (KMF_ERR_MEMORY);
2840 			}
2841 		} else {
2842 			EVP_PKEY_free(pkey);
2843 			pkey = NULL;
2844 		}
2845 	} else if (keyclass == KMF_SYMMETRIC) {
2846 		KMF_ENCODE_FORMAT fmt;
2847 		/*
2848 		 * If the file is a recognized format,
2849 		 * then it is NOT a symmetric key.
2850 		 */
2851 		rv = kmf_get_file_format(path, &fmt);
2852 		if (rv == KMF_OK || fmt != 0) {
2853 			return (KMF_ERR_KEY_NOT_FOUND);
2854 		} else if (rv == KMF_ERR_ENCODING) {
2855 			/*
2856 			 * If we don't know the encoding,
2857 			 * it is probably  a symmetric key.
2858 			 */
2859 			rv = KMF_OK;
2860 		} else if (rv == KMF_ERR_OPEN_FILE) {
2861 			return (KMF_ERR_KEY_NOT_FOUND);
2862 		}
2863 
2864 		if (key != NULL) {
2865 			KMF_DATA keyvalue;
2866 			rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
2867 			if (rkey == NULL) {
2868 				rv = KMF_ERR_MEMORY;
2869 				goto out;
2870 			}
2871 
2872 			(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
2873 			rv = kmf_read_input_file(handle, path, &keyvalue);
2874 			if (rv != KMF_OK)
2875 				goto out;
2876 
2877 			rkey->keydata.len = keyvalue.Length;
2878 			rkey->keydata.val = keyvalue.Data;
2879 
2880 			key->kstype = KMF_KEYSTORE_OPENSSL;
2881 			key->keyclass = keyclass;
2882 			key->israw = TRUE;
2883 			key->keyp = (void *)rkey;
2884 			if (path != NULL &&
2885 			    ((key->keylabel = strdup(path)) == NULL)) {
2886 				rv = KMF_ERR_MEMORY;
2887 			}
2888 		}
2889 	}
2890 out:
2891 	if (rv != KMF_OK) {
2892 		if (rkey != NULL) {
2893 			kmf_free_raw_sym_key(rkey);
2894 		}
2895 		if (pkey != NULL)
2896 			EVP_PKEY_free(pkey);
2897 
2898 		if (key != NULL) {
2899 			key->keyalg = KMF_KEYALG_NONE;
2900 			key->keyclass = KMF_KEYCLASS_NONE;
2901 			key->keyp = NULL;
2902 		}
2903 	}
2904 
2905 	return (rv);
2906 }
2907 
2908 KMF_RETURN
2909 OpenSSL_FindKey(KMF_HANDLE_T handle,
2910 	int numattr, KMF_ATTRIBUTE *attrlist)
2911 {
2912 	KMF_RETURN rv = KMF_OK;
2913 	char *fullpath = NULL;
2914 	uint32_t maxkeys;
2915 	KMF_KEY_HANDLE *key;
2916 	uint32_t *numkeys;
2917 	KMF_KEY_CLASS keyclass;
2918 	KMF_RAW_KEY_DATA *rawkey;
2919 	char *dirpath;
2920 	char *keyfile;
2921 
2922 	if (handle == NULL)
2923 		return (KMF_ERR_BAD_PARAMETER);
2924 
2925 	numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
2926 	if (numkeys == NULL)
2927 		return (KMF_ERR_BAD_PARAMETER);
2928 
2929 	rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
2930 	    (void *)&keyclass, NULL);
2931 	if (rv != KMF_OK)
2932 		return (KMF_ERR_BAD_PARAMETER);
2933 
2934 	if (keyclass != KMF_ASYM_PUB &&
2935 	    keyclass != KMF_ASYM_PRI &&
2936 	    keyclass != KMF_SYMMETRIC)
2937 		return (KMF_ERR_BAD_KEY_CLASS);
2938 
2939 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2940 	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
2941 
2942 	fullpath = get_fullpath(dirpath, keyfile);
2943 
2944 	if (fullpath == NULL)
2945 		return (KMF_ERR_BAD_PARAMETER);
2946 
2947 	maxkeys = *numkeys;
2948 	if (maxkeys == 0)
2949 		maxkeys = 0xFFFFFFFF;
2950 	*numkeys = 0;
2951 
2952 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2953 	/* it is okay to have "keys" contains NULL */
2954 
2955 	/*
2956 	 * The caller may want a list of the raw key data as well.
2957 	 * Useful for importing keys from a file into other keystores.
2958 	 */
2959 	rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
2960 
2961 	if (isdir(fullpath)) {
2962 		DIR *dirp;
2963 		struct dirent *dp;
2964 		int n = 0;
2965 
2966 		/* open all files in the directory and attempt to read them */
2967 		if ((dirp = opendir(fullpath)) == NULL) {
2968 			return (KMF_ERR_BAD_PARAMETER);
2969 		}
2970 		rewinddir(dirp);
2971 		while ((dp = readdir(dirp)) != NULL && n < maxkeys) {
2972 			if (strcmp(dp->d_name, ".") &&
2973 			    strcmp(dp->d_name, "..")) {
2974 				char *fname;
2975 
2976 				fname = get_fullpath(fullpath,
2977 				    (char *)&dp->d_name);
2978 
2979 				rv = fetch_key(handle, fname,
2980 				    keyclass, key ? &key[n] : NULL);
2981 
2982 				if (rv == KMF_OK) {
2983 					if (key != NULL && rawkey != NULL)
2984 						rv = convertToRawKey(
2985 						    key[n].keyp, &rawkey[n]);
2986 					n++;
2987 				}
2988 
2989 				if (rv != KMF_OK || key == NULL)
2990 					free(fname);
2991 			}
2992 		}
2993 		(void) closedir(dirp);
2994 		free(fullpath);
2995 		(*numkeys) = n;
2996 	} else {
2997 		rv = fetch_key(handle, fullpath, keyclass, key);
2998 		if (rv == KMF_OK)
2999 			(*numkeys) = 1;
3000 
3001 		if (rv != KMF_OK || key == NULL)
3002 			free(fullpath);
3003 
3004 		if (rv == KMF_OK && key != NULL && rawkey != NULL) {
3005 			rv = convertToRawKey(key->keyp, rawkey);
3006 		}
3007 	}
3008 
3009 	if (rv == KMF_OK && (*numkeys) == 0)
3010 		rv = KMF_ERR_KEY_NOT_FOUND;
3011 	else if (rv == KMF_ERR_KEY_NOT_FOUND && (*numkeys) > 0)
3012 		rv = KMF_OK;
3013 
3014 	return (rv);
3015 }
3016 
3017 #define	HANDLE_PK12_ERROR { \
3018 	SET_ERROR(kmfh, ERR_get_error()); \
3019 	rv = KMF_ERR_ENCODING; \
3020 	goto out; \
3021 }
3022 
3023 static int
3024 add_alias_to_bag(PKCS12_SAFEBAG *bag, X509 *xcert)
3025 {
3026 	if (xcert != NULL && xcert->aux != NULL &&
3027 	    xcert->aux->alias != NULL) {
3028 		if (PKCS12_add_friendlyname_asc(bag,
3029 		    (const char *)xcert->aux->alias->data,
3030 		    xcert->aux->alias->length) == 0)
3031 			return (0);
3032 	}
3033 	return (1);
3034 }
3035 
3036 static PKCS7 *
3037 add_cert_to_safe(X509 *sslcert, KMF_CREDENTIAL *cred,
3038 	uchar_t *keyid, unsigned int keyidlen)
3039 {
3040 	PKCS12_SAFEBAG *bag = NULL;
3041 	PKCS7 *cert_authsafe = NULL;
3042 	STACK_OF(PKCS12_SAFEBAG) *bag_stack;
3043 
3044 	bag_stack = sk_PKCS12_SAFEBAG_new_null();
3045 	if (bag_stack == NULL)
3046 		return (NULL);
3047 
3048 	/* Convert cert from X509 struct to PKCS#12 bag */
3049 	bag = PKCS12_x5092certbag(sslcert);
3050 	if (bag == NULL) {
3051 		goto out;
3052 	}
3053 
3054 	/* Add the key id to the certificate bag. */
3055 	if (keyidlen > 0 && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
3056 		goto out;
3057 	}
3058 
3059 	if (!add_alias_to_bag(bag, sslcert))
3060 		goto out;
3061 
3062 	/* Pile it on the bag_stack. */
3063 	if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
3064 		goto out;
3065 	}
3066 	/* Turn bag_stack of certs into encrypted authsafe. */
3067 	cert_authsafe = PKCS12_pack_p7encdata(
3068 	    NID_pbe_WithSHA1And40BitRC2_CBC,
3069 	    cred->cred, cred->credlen, NULL, 0,
3070 	    PKCS12_DEFAULT_ITER, bag_stack);
3071 
3072 out:
3073 	if (bag_stack != NULL)
3074 		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3075 
3076 	return (cert_authsafe);
3077 }
3078 
3079 static PKCS7 *
3080 add_key_to_safe(EVP_PKEY *pkey, KMF_CREDENTIAL *cred,
3081 	uchar_t *keyid,  unsigned int keyidlen,
3082 	char *label, int label_len)
3083 {
3084 	PKCS8_PRIV_KEY_INFO *p8 = NULL;
3085 	STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL;
3086 	PKCS12_SAFEBAG *bag = NULL;
3087 	PKCS7 *key_authsafe = NULL;
3088 
3089 	p8 = EVP_PKEY2PKCS8(pkey);
3090 	if (p8 == NULL) {
3091 		return (NULL);
3092 	}
3093 	/* Put the shrouded key into a PKCS#12 bag. */
3094 	bag = PKCS12_MAKE_SHKEYBAG(
3095 	    NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
3096 	    cred->cred, cred->credlen,
3097 	    NULL, 0, PKCS12_DEFAULT_ITER, p8);
3098 
3099 	/* Clean up the PKCS#8 shrouded key, don't need it now. */
3100 	PKCS8_PRIV_KEY_INFO_free(p8);
3101 	p8 = NULL;
3102 
3103 	if (bag == NULL) {
3104 		return (NULL);
3105 	}
3106 	if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
3107 		goto out;
3108 	if (label != NULL && !PKCS12_add_friendlyname(bag, label, label_len))
3109 		goto out;
3110 
3111 	/* Start a PKCS#12 safebag container for the private key. */
3112 	bag_stack = sk_PKCS12_SAFEBAG_new_null();
3113 	if (bag_stack == NULL)
3114 		goto out;
3115 
3116 	/* Pile on the private key on the bag_stack. */
3117 	if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag))
3118 		goto out;
3119 
3120 	key_authsafe = PKCS12_pack_p7data(bag_stack);
3121 
3122 out:
3123 	if (bag_stack != NULL)
3124 		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3125 	bag_stack = NULL;
3126 	return (key_authsafe);
3127 }
3128 
3129 static EVP_PKEY *
3130 ImportRawRSAKey(KMF_RAW_RSA_KEY *key)
3131 {
3132 	RSA		*rsa = NULL;
3133 	EVP_PKEY 	*newkey = NULL;
3134 
3135 	if ((rsa = RSA_new()) == NULL)
3136 		return (NULL);
3137 
3138 	if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL)
3139 		return (NULL);
3140 
3141 	if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) ==
3142 	    NULL)
3143 		return (NULL);
3144 
3145 	if (key->priexp.val != NULL)
3146 		if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len,
3147 		    rsa->d)) == NULL)
3148 			return (NULL);
3149 
3150 	if (key->prime1.val != NULL)
3151 		if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len,
3152 		    rsa->p)) == NULL)
3153 			return (NULL);
3154 
3155 	if (key->prime2.val != NULL)
3156 		if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len,
3157 		    rsa->q)) == NULL)
3158 			return (NULL);
3159 
3160 	if (key->exp1.val != NULL)
3161 		if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len,
3162 		    rsa->dmp1)) == NULL)
3163 			return (NULL);
3164 
3165 	if (key->exp2.val != NULL)
3166 		if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len,
3167 		    rsa->dmq1)) == NULL)
3168 			return (NULL);
3169 
3170 	if (key->coef.val != NULL)
3171 		if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len,
3172 		    rsa->iqmp)) == NULL)
3173 			return (NULL);
3174 
3175 	if ((newkey = EVP_PKEY_new()) == NULL)
3176 		return (NULL);
3177 
3178 	(void) EVP_PKEY_set1_RSA(newkey, rsa);
3179 
3180 	/* The original key must be freed once here or it leaks memory */
3181 	RSA_free(rsa);
3182 
3183 	return (newkey);
3184 }
3185 
3186 static EVP_PKEY *
3187 ImportRawDSAKey(KMF_RAW_DSA_KEY *key)
3188 {
3189 	DSA		*dsa = NULL;
3190 	EVP_PKEY 	*newkey = NULL;
3191 
3192 	if ((dsa = DSA_new()) == NULL)
3193 		return (NULL);
3194 
3195 	if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len,
3196 	    dsa->p)) == NULL)
3197 		return (NULL);
3198 
3199 	if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len,
3200 	    dsa->q)) == NULL)
3201 		return (NULL);
3202 
3203 	if ((dsa->g = BN_bin2bn(key->base.val, key->base.len,
3204 	    dsa->g)) == NULL)
3205 		return (NULL);
3206 
3207 	if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len,
3208 	    dsa->priv_key)) == NULL)
3209 		return (NULL);
3210 
3211 	if (key->pubvalue.val != NULL) {
3212 		if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val,
3213 		    key->pubvalue.len, dsa->pub_key)) == NULL)
3214 			return (NULL);
3215 	}
3216 
3217 	if ((newkey = EVP_PKEY_new()) == NULL)
3218 		return (NULL);
3219 
3220 	(void) EVP_PKEY_set1_DSA(newkey, dsa);
3221 
3222 	/* The original key must be freed once here or it leaks memory */
3223 	DSA_free(dsa);
3224 	return (newkey);
3225 }
3226 
3227 static EVP_PKEY *
3228 raw_key_to_pkey(KMF_KEY_HANDLE *key)
3229 {
3230 	EVP_PKEY *pkey = NULL;
3231 	KMF_RAW_KEY_DATA *rawkey;
3232 	ASN1_TYPE *attr = NULL;
3233 	KMF_RETURN ret;
3234 
3235 	if (key == NULL || !key->israw)
3236 		return (NULL);
3237 
3238 	rawkey = (KMF_RAW_KEY_DATA *)key->keyp;
3239 	if (rawkey->keytype == KMF_RSA) {
3240 		pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
3241 	} else if (rawkey->keytype == KMF_DSA) {
3242 		pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
3243 	} else if (rawkey->keytype == KMF_ECDSA) {
3244 		/*
3245 		 * OpenSSL in Solaris does not support EC for
3246 		 * legal reasons
3247 		 */
3248 		return (NULL);
3249 	} else {
3250 		/* wrong kind of key */
3251 		return (NULL);
3252 	}
3253 
3254 	if (rawkey->label != NULL) {
3255 		if ((attr = ASN1_TYPE_new()) == NULL) {
3256 			EVP_PKEY_free(pkey);
3257 			return (NULL);
3258 		}
3259 		attr->value.bmpstring = ASN1_STRING_type_new(V_ASN1_BMPSTRING);
3260 		(void) ASN1_STRING_set(attr->value.bmpstring, rawkey->label,
3261 		    strlen(rawkey->label));
3262 		attr->type = V_ASN1_BMPSTRING;
3263 		attr->value.ptr = (char *)attr->value.bmpstring;
3264 		ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
3265 		if (ret != KMF_OK) {
3266 			EVP_PKEY_free(pkey);
3267 			ASN1_TYPE_free(attr);
3268 			return (NULL);
3269 		}
3270 	}
3271 	if (rawkey->id.Data != NULL) {
3272 		if ((attr = ASN1_TYPE_new()) == NULL) {
3273 			EVP_PKEY_free(pkey);
3274 			return (NULL);
3275 		}
3276 		attr->value.octet_string =
3277 		    ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
3278 		attr->type = V_ASN1_OCTET_STRING;
3279 		(void) ASN1_STRING_set(attr->value.octet_string,
3280 		    rawkey->id.Data, rawkey->id.Length);
3281 		attr->value.ptr = (char *)attr->value.octet_string;
3282 		ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
3283 		if (ret != KMF_OK) {
3284 			EVP_PKEY_free(pkey);
3285 			ASN1_TYPE_free(attr);
3286 			return (NULL);
3287 		}
3288 	}
3289 	return (pkey);
3290 }
3291 
3292 /*
3293  * Search a list of private keys to find one that goes with the certificate.
3294  */
3295 static EVP_PKEY *
3296 find_matching_key(X509 *xcert, int numkeys, KMF_KEY_HANDLE *keylist)
3297 {
3298 	int i;
3299 	EVP_PKEY *pkey = NULL;
3300 
3301 	if (numkeys == 0 || keylist == NULL || xcert == NULL)
3302 		return (NULL);
3303 	for (i = 0; i < numkeys; i++) {
3304 		if (keylist[i].israw)
3305 			pkey = raw_key_to_pkey(&keylist[i]);
3306 		else
3307 			pkey = (EVP_PKEY *)keylist[i].keyp;
3308 		if (pkey != NULL) {
3309 			if (X509_check_private_key(xcert, pkey)) {
3310 				return (pkey);
3311 			} else {
3312 				EVP_PKEY_free(pkey);
3313 				pkey = NULL;
3314 			}
3315 		}
3316 	}
3317 	return (pkey);
3318 }
3319 
3320 static KMF_RETURN
3321 local_export_pk12(KMF_HANDLE_T handle,
3322 	KMF_CREDENTIAL *cred,
3323 	int numcerts, KMF_X509_DER_CERT *certlist,
3324 	int numkeys, KMF_KEY_HANDLE *keylist,
3325 	char *filename)
3326 {
3327 	KMF_RETURN rv = KMF_OK;
3328 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3329 	BIO *bio = NULL;
3330 	PKCS7 *cert_authsafe = NULL;
3331 	PKCS7 *key_authsafe = NULL;
3332 	STACK_OF(PKCS7) *authsafe_stack = NULL;
3333 	PKCS12 *p12_elem = NULL;
3334 	int i;
3335 
3336 	if (numcerts == 0 && numkeys == 0)
3337 		return (KMF_ERR_BAD_PARAMETER);
3338 
3339 	/*
3340 	 * Open the output file.
3341 	 */
3342 	if ((bio = BIO_new_file(filename, "wb")) == NULL) {
3343 		SET_ERROR(kmfh, ERR_get_error());
3344 		rv = KMF_ERR_OPEN_FILE;
3345 		goto cleanup;
3346 	}
3347 
3348 	/* Start a PKCS#7 stack. */
3349 	authsafe_stack = sk_PKCS7_new_null();
3350 	if (authsafe_stack == NULL) {
3351 		rv = KMF_ERR_MEMORY;
3352 		goto cleanup;
3353 	}
3354 	if (numcerts > 0) {
3355 		for (i = 0; rv == KMF_OK && i < numcerts; i++) {
3356 			const uchar_t *p = certlist[i].certificate.Data;
3357 			long len = certlist[i].certificate.Length;
3358 			X509 *xcert = NULL;
3359 			EVP_PKEY *pkey = NULL;
3360 			unsigned char keyid[EVP_MAX_MD_SIZE];
3361 			unsigned int keyidlen = 0;
3362 
3363 			xcert = d2i_X509(NULL, &p, len);
3364 			if (xcert == NULL) {
3365 				SET_ERROR(kmfh, ERR_get_error());
3366 				rv = KMF_ERR_ENCODING;
3367 			}
3368 			if (certlist[i].kmf_private.label != NULL) {
3369 				/* Set alias attribute */
3370 				(void) X509_alias_set1(xcert,
3371 				    (uchar_t *)certlist[i].kmf_private.label,
3372 				    strlen(certlist[i].kmf_private.label));
3373 			}
3374 			/* Check if there is a key corresponding to this cert */
3375 			pkey = find_matching_key(xcert, numkeys, keylist);
3376 
3377 			/*
3378 			 * If key is found, get fingerprint and create a
3379 			 * safebag.
3380 			 */
3381 			if (pkey != NULL) {
3382 				(void) X509_digest(xcert, EVP_sha1(),
3383 				    keyid, &keyidlen);
3384 				key_authsafe = add_key_to_safe(pkey, cred,
3385 				    keyid, keyidlen,
3386 				    certlist[i].kmf_private.label,
3387 				    (certlist[i].kmf_private.label ?
3388 				    strlen(certlist[i].kmf_private.label) : 0));
3389 
3390 				if (key_authsafe == NULL) {
3391 					X509_free(xcert);
3392 					EVP_PKEY_free(pkey);
3393 					goto cleanup;
3394 				}
3395 				/* Put the key safe into the Auth Safe */
3396 				if (!sk_PKCS7_push(authsafe_stack,
3397 				    key_authsafe)) {
3398 					X509_free(xcert);
3399 					EVP_PKEY_free(pkey);
3400 					goto cleanup;
3401 				}
3402 			}
3403 
3404 			/* create a certificate safebag */
3405 			cert_authsafe = add_cert_to_safe(xcert, cred, keyid,
3406 			    keyidlen);
3407 			if (cert_authsafe == NULL) {
3408 				X509_free(xcert);
3409 				EVP_PKEY_free(pkey);
3410 				goto cleanup;
3411 			}
3412 			if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) {
3413 				X509_free(xcert);
3414 				EVP_PKEY_free(pkey);
3415 				goto cleanup;
3416 			}
3417 
3418 			X509_free(xcert);
3419 			if (pkey)
3420 				EVP_PKEY_free(pkey);
3421 		}
3422 	} else if (numcerts == 0 && numkeys > 0) {
3423 		/*
3424 		 * If only adding keys to the file.
3425 		 */
3426 		for (i = 0; i < numkeys; i++) {
3427 			EVP_PKEY *pkey = NULL;
3428 
3429 			if (keylist[i].israw)
3430 				pkey = raw_key_to_pkey(&keylist[i]);
3431 			else
3432 				pkey = (EVP_PKEY *)keylist[i].keyp;
3433 
3434 			if (pkey == NULL)
3435 				continue;
3436 
3437 			key_authsafe = add_key_to_safe(pkey, cred,
3438 			    NULL, 0, NULL, 0);
3439 
3440 			if (key_authsafe == NULL) {
3441 				EVP_PKEY_free(pkey);
3442 				goto cleanup;
3443 			}
3444 			if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) {
3445 				EVP_PKEY_free(pkey);
3446 				goto cleanup;
3447 			}
3448 		}
3449 	}
3450 	p12_elem = PKCS12_init(NID_pkcs7_data);
3451 	if (p12_elem == NULL) {
3452 		goto cleanup;
3453 	}
3454 
3455 	/* Put the PKCS#7 stack into the PKCS#12 element. */
3456 	if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) {
3457 		goto cleanup;
3458 	}
3459 
3460 	/* Set the integrity MAC on the PKCS#12 element. */
3461 	if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen,
3462 	    NULL, 0, PKCS12_DEFAULT_ITER, NULL)) {
3463 		goto cleanup;
3464 	}
3465 
3466 	/* Write the PKCS#12 element to the export file. */
3467 	if (!i2d_PKCS12_bio(bio, p12_elem)) {
3468 		goto cleanup;
3469 	}
3470 	PKCS12_free(p12_elem);
3471 
3472 cleanup:
3473 	/* Clear away the PKCS#7 stack, we're done with it. */
3474 	if (authsafe_stack)
3475 		sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
3476 
3477 	if (bio != NULL)
3478 		(void) BIO_free_all(bio);
3479 
3480 	return (rv);
3481 }
3482 
3483 KMF_RETURN
3484 openssl_build_pk12(KMF_HANDLE_T handle, int numcerts,
3485     KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist,
3486     KMF_CREDENTIAL *p12cred, char *filename)
3487 {
3488 	KMF_RETURN rv;
3489 
3490 	if (certlist == NULL && keylist == NULL)
3491 		return (KMF_ERR_BAD_PARAMETER);
3492 
3493 	rv = local_export_pk12(handle, p12cred, numcerts, certlist,
3494 	    numkeys, keylist, filename);
3495 
3496 	return (rv);
3497 }
3498 
3499 KMF_RETURN
3500 OpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
3501 {
3502 	KMF_RETURN rv;
3503 	KMF_HANDLE *kmfh = (KMF_HANDLE  *)handle;
3504 	char *fullpath = NULL;
3505 	char *dirpath = NULL;
3506 	char *certfile = NULL;
3507 	char *keyfile = NULL;
3508 	char *filename = NULL;
3509 	KMF_CREDENTIAL *p12cred = NULL;
3510 	KMF_X509_DER_CERT certdata;
3511 	KMF_KEY_HANDLE key;
3512 	int gotkey = 0;
3513 	int gotcert = 0;
3514 
3515 	if (handle == NULL)
3516 		return (KMF_ERR_BAD_PARAMETER);
3517 
3518 	/*
3519 	 *  First, find the certificate.
3520 	 */
3521 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
3522 	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
3523 	if (certfile != NULL) {
3524 		fullpath = get_fullpath(dirpath, certfile);
3525 		if (fullpath == NULL)
3526 			return (KMF_ERR_BAD_PARAMETER);
3527 
3528 		if (isdir(fullpath)) {
3529 			free(fullpath);
3530 			return (KMF_ERR_AMBIGUOUS_PATHNAME);
3531 		}
3532 
3533 		(void) memset(&certdata, 0, sizeof (certdata));
3534 		rv = kmf_load_cert(kmfh, NULL, NULL, NULL, NULL,
3535 		    fullpath, &certdata.certificate);
3536 		if (rv != KMF_OK)
3537 			goto end;
3538 
3539 		gotcert++;
3540 		certdata.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
3541 		free(fullpath);
3542 	}
3543 
3544 	/*
3545 	 * Now find the private key.
3546 	 */
3547 	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
3548 	if (keyfile != NULL) {
3549 		fullpath = get_fullpath(dirpath, keyfile);
3550 		if (fullpath == NULL)
3551 			return (KMF_ERR_BAD_PARAMETER);
3552 
3553 		if (isdir(fullpath)) {
3554 			free(fullpath);
3555 			return (KMF_ERR_AMBIGUOUS_PATHNAME);
3556 		}
3557 
3558 		(void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
3559 		rv = fetch_key(handle, fullpath, KMF_ASYM_PRI, &key);
3560 		if (rv != KMF_OK)
3561 			goto end;
3562 		gotkey++;
3563 	}
3564 
3565 	/*
3566 	 * Open the output file.
3567 	 */
3568 	filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
3569 	    numattr);
3570 	if (filename == NULL) {
3571 		rv = KMF_ERR_BAD_PARAMETER;
3572 		goto end;
3573 	}
3574 
3575 	/* Stick the key and the cert into a PKCS#12 file */
3576 	p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
3577 	if (p12cred == NULL) {
3578 		rv = KMF_ERR_BAD_PARAMETER;
3579 		goto end;
3580 	}
3581 
3582 	rv = local_export_pk12(handle, p12cred, 1, &certdata,
3583 	    1, &key, filename);
3584 
3585 end:
3586 	if (fullpath)
3587 		free(fullpath);
3588 
3589 	if (gotcert)
3590 		kmf_free_kmf_cert(handle, &certdata);
3591 	if (gotkey)
3592 		kmf_free_kmf_key(handle, &key);
3593 	return (rv);
3594 }
3595 
3596 /*
3597  * Helper function to extract keys and certificates from
3598  * a single PEM file.  Typically the file should contain a
3599  * private key and an associated public key wrapped in an x509 cert.
3600  * However, the file may be just a list of X509 certs with no keys.
3601  */
3602 static KMF_RETURN
3603 extract_pem(KMF_HANDLE *kmfh,
3604 	char *issuer, char *subject, KMF_BIGINT *serial,
3605 	char *filename, CK_UTF8CHAR *pin,
3606 	CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs,
3607 	int *numcerts)
3608 /* ARGSUSED6 */
3609 {
3610 	KMF_RETURN rv = KMF_OK;
3611 	FILE *fp;
3612 	STACK_OF(X509_INFO) *x509_info_stack = NULL;
3613 	int i, ncerts = 0, matchcerts = 0;
3614 	EVP_PKEY *pkey = NULL;
3615 	X509_INFO *info;
3616 	X509 *x;
3617 	X509_INFO **cert_infos = NULL;
3618 	KMF_DATA *certlist = NULL;
3619 
3620 	if (priv_key)
3621 		*priv_key = NULL;
3622 	if (certs)
3623 		*certs = NULL;
3624 	fp = fopen(filename, "r");
3625 	if (fp == NULL)
3626 		return (KMF_ERR_OPEN_FILE);
3627 
3628 	x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin);
3629 	if (x509_info_stack == NULL) {
3630 		(void) fclose(fp);
3631 		return (KMF_ERR_ENCODING);
3632 	}
3633 	cert_infos = (X509_INFO **)malloc(sk_X509_INFO_num(x509_info_stack) *
3634 	    sizeof (X509_INFO *));
3635 	if (cert_infos == NULL) {
3636 		(void) fclose(fp);
3637 		rv = KMF_ERR_MEMORY;
3638 		goto err;
3639 	}
3640 
3641 	for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
3642 		/* LINTED E_BAD_PTR_CAST_ALIGN */
3643 		cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i);
3644 		ncerts++;
3645 	}
3646 
3647 	if (ncerts == 0) {
3648 		(void) fclose(fp);
3649 		rv = KMF_ERR_CERT_NOT_FOUND;
3650 		goto err;
3651 	}
3652 
3653 	if (priv_key != NULL) {
3654 		rewind(fp);
3655 		pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin);
3656 	}
3657 	(void) fclose(fp);
3658 
3659 	x = cert_infos[ncerts - 1]->x509;
3660 	/*
3661 	 * Make sure the private key matchs the last cert in the file.
3662 	 */
3663 	if (pkey != NULL && !X509_check_private_key(x, pkey)) {
3664 		EVP_PKEY_free(pkey);
3665 		rv = KMF_ERR_KEY_MISMATCH;
3666 		goto err;
3667 	}
3668 
3669 	certlist = (KMF_DATA *)calloc(ncerts, sizeof (KMF_DATA));
3670 	if (certlist == NULL) {
3671 		if (pkey != NULL)
3672 			EVP_PKEY_free(pkey);
3673 		rv = KMF_ERR_MEMORY;
3674 		goto err;
3675 	}
3676 
3677 	/*
3678 	 * Convert all of the certs to DER format.
3679 	 */
3680 	matchcerts = 0;
3681 	for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) {
3682 		boolean_t match = FALSE;
3683 		info =  cert_infos[ncerts - 1 - i];
3684 
3685 		rv = check_cert(info->x509, issuer, subject, serial, &match);
3686 		if (rv != KMF_OK || match != TRUE) {
3687 			rv = KMF_OK;
3688 			continue;
3689 		}
3690 
3691 		rv = ssl_cert2KMFDATA(kmfh, info->x509,
3692 			&certlist[matchcerts++]);
3693 
3694 		if (rv != KMF_OK) {
3695 			int j;
3696 			for (j = 0; j < matchcerts; j++)
3697 				kmf_free_data(&certlist[j]);
3698 			free(certlist);
3699 			certlist = NULL;
3700 			ncerts = matchcerts = 0;
3701 		}
3702 	}
3703 
3704 	if (numcerts != NULL)
3705 		*numcerts = matchcerts;
3706 
3707 	if (certs != NULL)
3708 		*certs = certlist;
3709 	else if (certlist != NULL) {
3710 		for (i = 0; i < ncerts; i++)
3711 			kmf_free_data(&certlist[i]);
3712 		free(certlist);
3713 		certlist = NULL;
3714 	}
3715 
3716 	if (priv_key == NULL && pkey != NULL)
3717 		EVP_PKEY_free(pkey);
3718 	else if (priv_key != NULL && pkey != NULL)
3719 		*priv_key = pkey;
3720 
3721 err:
3722 	/* Cleanup the stack of X509 info records */
3723 	for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
3724 		/* LINTED E_BAD_PTR_CAST_ALIGN */
3725 		info = (X509_INFO *)sk_X509_INFO_value(x509_info_stack, i);
3726 		X509_INFO_free(info);
3727 	}
3728 	if (x509_info_stack)
3729 		sk_X509_INFO_free(x509_info_stack);
3730 
3731 	if (cert_infos != NULL)
3732 		free(cert_infos);
3733 
3734 	return (rv);
3735 }
3736 
3737 static KMF_RETURN
3738 openssl_parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *pin,
3739 	STACK_OF(EVP_PKEY) *keys, STACK_OF(X509) *certs)
3740 {
3741 	KMF_RETURN ret;
3742 	int i;
3743 
3744 	for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
3745 		/* LINTED E_BAD_PTR_CAST_ALIGN */
3746 		PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value(bags, i);
3747 		ret = openssl_parse_bag(bag, pin, (pin ? strlen(pin) : 0),
3748 		    keys, certs);
3749 
3750 		if (ret != KMF_OK)
3751 			return (ret);
3752 	}
3753 
3754 	return (ret);
3755 }
3756 
3757 static KMF_RETURN
3758 set_pkey_attrib(EVP_PKEY *pkey, ASN1_TYPE *attrib, int nid)
3759 {
3760 	X509_ATTRIBUTE *attr = NULL;
3761 
3762 	if (pkey == NULL || attrib == NULL)
3763 		return (KMF_ERR_BAD_PARAMETER);
3764 
3765 	if (pkey->attributes == NULL) {
3766 		pkey->attributes = sk_X509_ATTRIBUTE_new_null();
3767 		if (pkey->attributes == NULL)
3768 			return (KMF_ERR_MEMORY);
3769 	}
3770 	attr = X509_ATTRIBUTE_create(nid, attrib->type, attrib->value.ptr);
3771 	if (attr != NULL) {
3772 		int i;
3773 		X509_ATTRIBUTE *a;
3774 		for (i = 0;
3775 		    i < sk_X509_ATTRIBUTE_num(pkey->attributes); i++) {
3776 			/* LINTED E_BAD_PTR_CASE_ALIGN */
3777 			a = sk_X509_ATTRIBUTE_value(pkey->attributes, i);
3778 			if (OBJ_obj2nid(a->object) == nid) {
3779 				X509_ATTRIBUTE_free(a);
3780 				/* LINTED E_BAD_PTR_CAST_ALIGN */
3781 				sk_X509_ATTRIBUTE_set(pkey->attributes,
3782 				    i, attr);
3783 				return (KMF_OK);
3784 			}
3785 		}
3786 		if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == NULL) {
3787 			X509_ATTRIBUTE_free(attr);
3788 			return (KMF_ERR_MEMORY);
3789 		}
3790 	} else {
3791 		return (KMF_ERR_MEMORY);
3792 	}
3793 
3794 	return (KMF_OK);
3795 }
3796 
3797 static KMF_RETURN
3798 openssl_parse_bag(PKCS12_SAFEBAG *bag, char *pass, int passlen,
3799 	STACK_OF(EVP_PKEY) *keylist, STACK_OF(X509) *certlist)
3800 {
3801 	KMF_RETURN ret = KMF_OK;
3802 	PKCS8_PRIV_KEY_INFO *p8 = NULL;
3803 	EVP_PKEY *pkey = NULL;
3804 	X509 *xcert = NULL;
3805 	ASN1_TYPE *keyid = NULL;
3806 	ASN1_TYPE *fname = NULL;
3807 	uchar_t *data = NULL;
3808 
3809 	keyid = PKCS12_get_attr(bag, NID_localKeyID);
3810 	fname = PKCS12_get_attr(bag, NID_friendlyName);
3811 
3812 	switch (M_PKCS12_bag_type(bag)) {
3813 		case NID_keyBag:
3814 			if (keylist == NULL)
3815 				goto end;
3816 			pkey = EVP_PKCS82PKEY(bag->value.keybag);
3817 			if (pkey == NULL)
3818 				ret = KMF_ERR_PKCS12_FORMAT;
3819 
3820 			break;
3821 		case NID_pkcs8ShroudedKeyBag:
3822 			if (keylist == NULL)
3823 				goto end;
3824 			p8 = M_PKCS12_decrypt_skey(bag, pass, passlen);
3825 			if (p8 == NULL)
3826 				return (KMF_ERR_AUTH_FAILED);
3827 			pkey = EVP_PKCS82PKEY(p8);
3828 			PKCS8_PRIV_KEY_INFO_free(p8);
3829 			if (pkey == NULL)
3830 				ret = KMF_ERR_PKCS12_FORMAT;
3831 			break;
3832 		case NID_certBag:
3833 			if (certlist == NULL)
3834 				goto end;
3835 			if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
3836 				return (KMF_ERR_PKCS12_FORMAT);
3837 			xcert = M_PKCS12_certbag2x509(bag);
3838 			if (xcert == NULL) {
3839 				ret = KMF_ERR_PKCS12_FORMAT;
3840 				goto end;
3841 			}
3842 			if (keyid != NULL) {
3843 				if (X509_keyid_set1(xcert,
3844 				    keyid->value.octet_string->data,
3845 				    keyid->value.octet_string->length) == 0) {
3846 					ret = KMF_ERR_PKCS12_FORMAT;
3847 					goto end;
3848 				}
3849 			}
3850 			if (fname != NULL) {
3851 				int len, r;
3852 				len = ASN1_STRING_to_UTF8(&data,
3853 				    fname->value.asn1_string);
3854 				if (len > 0 && data != NULL) {
3855 					r = X509_alias_set1(xcert, data, len);
3856 					if (r == NULL) {
3857 						ret = KMF_ERR_PKCS12_FORMAT;
3858 						goto end;
3859 					}
3860 				} else {
3861 					ret = KMF_ERR_PKCS12_FORMAT;
3862 					goto end;
3863 				}
3864 			}
3865 			if (sk_X509_push(certlist, xcert) == 0)
3866 				ret = KMF_ERR_MEMORY;
3867 			else
3868 				xcert = NULL;
3869 			break;
3870 		case NID_safeContentsBag:
3871 			return (openssl_parse_bags(bag->value.safes, pass,
3872 			    keylist, certlist));
3873 		default:
3874 			ret = KMF_ERR_PKCS12_FORMAT;
3875 			break;
3876 	}
3877 
3878 	/*
3879 	 * Set the ID and/or FriendlyName attributes on the key.
3880 	 * If converting to PKCS11 objects, these can translate to CKA_ID
3881 	 * and CKA_LABEL values.
3882 	 */
3883 	if (pkey != NULL && ret == KMF_OK) {
3884 		ASN1_TYPE *attr = NULL;
3885 		if (keyid != NULL && keyid->type == V_ASN1_OCTET_STRING) {
3886 			if ((attr = ASN1_TYPE_new()) == NULL)
3887 				return (KMF_ERR_MEMORY);
3888 			attr->value.octet_string =
3889 			    ASN1_STRING_dup(keyid->value.octet_string);
3890 			attr->type = V_ASN1_OCTET_STRING;
3891 			attr->value.ptr = (char *)attr->value.octet_string;
3892 			ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
3893 			OPENSSL_free(attr);
3894 		}
3895 
3896 		if (ret == KMF_OK && fname != NULL &&
3897 		    fname->type == V_ASN1_BMPSTRING) {
3898 			if ((attr = ASN1_TYPE_new()) == NULL)
3899 				return (KMF_ERR_MEMORY);
3900 			attr->value.bmpstring =
3901 			    ASN1_STRING_dup(fname->value.bmpstring);
3902 			attr->type = V_ASN1_BMPSTRING;
3903 			attr->value.ptr = (char *)attr->value.bmpstring;
3904 			ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
3905 			OPENSSL_free(attr);
3906 		}
3907 
3908 		if (ret == KMF_OK && keylist != NULL &&
3909 		    sk_EVP_PKEY_push(keylist, pkey) == 0)
3910 			ret = KMF_ERR_MEMORY;
3911 	}
3912 	if (ret == KMF_OK && keylist != NULL)
3913 		pkey = NULL;
3914 end:
3915 	if (pkey != NULL)
3916 		EVP_PKEY_free(pkey);
3917 	if (xcert != NULL)
3918 		X509_free(xcert);
3919 	if (data != NULL)
3920 		OPENSSL_free(data);
3921 
3922 	return (ret);
3923 }
3924 
3925 static KMF_RETURN
3926 openssl_pkcs12_parse(PKCS12 *p12, char *pin,
3927 	STACK_OF(EVP_PKEY) *keys,
3928 	STACK_OF(X509) *certs,
3929 	STACK_OF(X509) *ca)
3930 /* ARGSUSED3 */
3931 {
3932 	KMF_RETURN ret = KMF_OK;
3933 	STACK_OF(PKCS7) *asafes = NULL;
3934 	STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
3935 	int i, bagnid;
3936 	PKCS7 *p7;
3937 
3938 	if (p12 == NULL || (keys == NULL && certs == NULL))
3939 		return (KMF_ERR_BAD_PARAMETER);
3940 
3941 	if (pin == NULL || *pin == NULL) {
3942 		if (PKCS12_verify_mac(p12, NULL, 0)) {
3943 			pin = NULL;
3944 		} else if (PKCS12_verify_mac(p12, "", 0)) {
3945 			pin = "";
3946 		} else {
3947 			return (KMF_ERR_AUTH_FAILED);
3948 		}
3949 	} else if (!PKCS12_verify_mac(p12, pin, -1)) {
3950 		return (KMF_ERR_AUTH_FAILED);
3951 	}
3952 
3953 	if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
3954 		return (KMF_ERR_PKCS12_FORMAT);
3955 
3956 	for (i = 0; ret == KMF_OK && i < sk_PKCS7_num(asafes); i++) {
3957 		bags = NULL;
3958 		/* LINTED E_BAD_PTR_CAST_ALIGN */
3959 		p7 = sk_PKCS7_value(asafes, i);
3960 		bagnid = OBJ_obj2nid(p7->type);
3961 
3962 		if (bagnid == NID_pkcs7_data) {
3963 			bags = PKCS12_unpack_p7data(p7);
3964 		} else if (bagnid == NID_pkcs7_encrypted) {
3965 			bags = PKCS12_unpack_p7encdata(p7, pin,
3966 			    (pin ? strlen(pin) : 0));
3967 		} else {
3968 			continue;
3969 		}
3970 		if (bags == NULL) {
3971 			ret = KMF_ERR_PKCS12_FORMAT;
3972 			goto out;
3973 		}
3974 
3975 		if (openssl_parse_bags(bags, pin, keys, certs) != KMF_OK)
3976 			ret = KMF_ERR_PKCS12_FORMAT;
3977 
3978 		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
3979 	}
3980 out:
3981 	if (asafes != NULL)
3982 		sk_PKCS7_pop_free(asafes, PKCS7_free);
3983 
3984 	return (ret);
3985 }
3986 
3987 /*
3988  * Helper function to decrypt and parse PKCS#12 import file.
3989  */
3990 static KMF_RETURN
3991 extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
3992 	STACK_OF(EVP_PKEY) **priv_key, STACK_OF(X509) **certs,
3993 	STACK_OF(X509) **ca)
3994 /* ARGSUSED2 */
3995 {
3996 	PKCS12			*pk12, *pk12_tmp;
3997 	STACK_OF(EVP_PKEY)	*pkeylist = NULL;
3998 	STACK_OF(X509)		*xcertlist = NULL;
3999 	STACK_OF(X509)		*cacertlist = NULL;
4000 
4001 	if ((pk12 = PKCS12_new()) == NULL) {
4002 		return (KMF_ERR_MEMORY);
4003 	}
4004 
4005 	if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) {
4006 		/* This is ok; it seems to mean there is no more to read. */
4007 		if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 &&
4008 		    ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG)
4009 			goto end_extract_pkcs12;
4010 
4011 		PKCS12_free(pk12);
4012 		return (KMF_ERR_PKCS12_FORMAT);
4013 	}
4014 	pk12 = pk12_tmp;
4015 
4016 	xcertlist = sk_X509_new_null();
4017 	if (xcertlist == NULL) {
4018 		PKCS12_free(pk12);
4019 		return (KMF_ERR_MEMORY);
4020 	}
4021 	pkeylist = sk_EVP_PKEY_new_null();
4022 	if (pkeylist == NULL) {
4023 		sk_X509_pop_free(xcertlist, X509_free);
4024 		PKCS12_free(pk12);
4025 		return (KMF_ERR_MEMORY);
4026 	}
4027 
4028 	if (openssl_pkcs12_parse(pk12, (char *)pin, pkeylist, xcertlist,
4029 	    cacertlist) != KMF_OK) {
4030 		sk_X509_pop_free(xcertlist, X509_free);
4031 		sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
4032 		PKCS12_free(pk12);
4033 		return (KMF_ERR_PKCS12_FORMAT);
4034 	}
4035 
4036 	if (priv_key && pkeylist)
4037 		*priv_key = pkeylist;
4038 	else if (pkeylist)
4039 		sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
4040 	if (certs && xcertlist)
4041 		*certs = xcertlist;
4042 	else if (xcertlist)
4043 		sk_X509_pop_free(xcertlist, X509_free);
4044 	if (ca && cacertlist)
4045 		*ca = cacertlist;
4046 	else if (cacertlist)
4047 		sk_X509_pop_free(cacertlist, X509_free);
4048 
4049 end_extract_pkcs12:
4050 
4051 	PKCS12_free(pk12);
4052 	return (KMF_OK);
4053 }
4054 
4055 static KMF_RETURN
4056 sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to)
4057 {
4058 	KMF_RETURN rv = KMF_OK;
4059 	uint32_t sz;
4060 
4061 	sz = BN_num_bytes(from);
4062 	to->val = (uchar_t *)malloc(sz);
4063 	if (to->val == NULL)
4064 		return (KMF_ERR_MEMORY);
4065 
4066 	if ((to->len = BN_bn2bin(from, to->val)) != sz) {
4067 		free(to->val);
4068 		to->val = NULL;
4069 		to->len = 0;
4070 		rv = KMF_ERR_MEMORY;
4071 	}
4072 
4073 	return (rv);
4074 }
4075 
4076 static KMF_RETURN
4077 exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key)
4078 {
4079 	KMF_RETURN rv;
4080 	KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa;
4081 
4082 	(void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY));
4083 	if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK)
4084 		goto cleanup;
4085 
4086 	if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK)
4087 		goto cleanup;
4088 
4089 	if (rsa->d != NULL)
4090 		if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK)
4091 			goto cleanup;
4092 
4093 	if (rsa->p != NULL)
4094 		if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK)
4095 			goto cleanup;
4096 
4097 	if (rsa->q != NULL)
4098 		if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK)
4099 			goto cleanup;
4100 
4101 	if (rsa->dmp1 != NULL)
4102 		if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK)
4103 			goto cleanup;
4104 
4105 	if (rsa->dmq1 != NULL)
4106 		if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK)
4107 			goto cleanup;
4108 
4109 	if (rsa->iqmp != NULL)
4110 		if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK)
4111 			goto cleanup;
4112 cleanup:
4113 	if (rv != KMF_OK)
4114 		kmf_free_raw_key(key);
4115 	else
4116 		key->keytype = KMF_RSA;
4117 
4118 	/*
4119 	 * Free the reference to this key, SSL will not actually free
4120 	 * the memory until the refcount == 0, so this is safe.
4121 	 */
4122 	RSA_free(rsa);
4123 
4124 	return (rv);
4125 }
4126 
4127 static KMF_RETURN
4128 exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key)
4129 {
4130 	KMF_RETURN rv;
4131 	KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa;
4132 
4133 	(void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY));
4134 	if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK)
4135 		goto cleanup;
4136 
4137 	if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK)
4138 		goto cleanup;
4139 
4140 	if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK)
4141 		goto cleanup;
4142 
4143 	if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK)
4144 		goto cleanup;
4145 
4146 cleanup:
4147 	if (rv != KMF_OK)
4148 		kmf_free_raw_key(key);
4149 	else
4150 		key->keytype = KMF_DSA;
4151 
4152 	/*
4153 	 * Free the reference to this key, SSL will not actually free
4154 	 * the memory until the refcount == 0, so this is safe.
4155 	 */
4156 	DSA_free(dsa);
4157 
4158 	return (rv);
4159 }
4160 
4161 static KMF_RETURN
4162 add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert,
4163 	KMF_X509_DER_CERT **certlist, int *ncerts)
4164 {
4165 	KMF_RETURN rv = KMF_OK;
4166 	KMF_X509_DER_CERT *list = (*certlist);
4167 	KMF_X509_DER_CERT cert;
4168 	int n = (*ncerts);
4169 
4170 	if (list == NULL) {
4171 		list = (KMF_X509_DER_CERT *)malloc(sizeof (KMF_X509_DER_CERT));
4172 	} else {
4173 		list = (KMF_X509_DER_CERT *)realloc(list,
4174 		    sizeof (KMF_X509_DER_CERT) * (n + 1));
4175 	}
4176 
4177 	if (list == NULL)
4178 		return (KMF_ERR_MEMORY);
4179 
4180 	(void) memset(&cert, 0, sizeof (cert));
4181 	rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert.certificate);
4182 	if (rv == KMF_OK) {
4183 		int len = 0;
4184 		/* Get the alias name for the cert if there is one */
4185 		char *a = (char *)X509_alias_get0(sslcert, &len);
4186 		if (a != NULL)
4187 			cert.kmf_private.label = strdup(a);
4188 		cert.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
4189 
4190 		list[n] = cert;
4191 		(*ncerts) = n + 1;
4192 
4193 		*certlist = list;
4194 	} else {
4195 		free(list);
4196 	}
4197 
4198 	return (rv);
4199 }
4200 
4201 static KMF_RETURN
4202 add_key_to_list(KMF_RAW_KEY_DATA **keylist,
4203 	KMF_RAW_KEY_DATA *newkey, int *nkeys)
4204 {
4205 	KMF_RAW_KEY_DATA *list = (*keylist);
4206 	int n = (*nkeys);
4207 
4208 	if (list == NULL) {
4209 		list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA));
4210 	} else {
4211 		list = (KMF_RAW_KEY_DATA *)realloc(list,
4212 		    sizeof (KMF_RAW_KEY_DATA) * (n + 1));
4213 	}
4214 
4215 	if (list == NULL)
4216 		return (KMF_ERR_MEMORY);
4217 
4218 	list[n] = *newkey;
4219 	(*nkeys) = n + 1;
4220 
4221 	*keylist = list;
4222 
4223 	return (KMF_OK);
4224 }
4225 
4226 static X509_ATTRIBUTE *
4227 find_attr(STACK_OF(X509_ATTRIBUTE) *attrs, int nid)
4228 {
4229 	X509_ATTRIBUTE *a;
4230 	int i;
4231 
4232 	if (attrs == NULL)
4233 		return (NULL);
4234 
4235 	for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) {
4236 		/* LINTED E_BAD_PTR_CAST_ALIGN */
4237 		a = sk_X509_ATTRIBUTE_value(attrs, i);
4238 		if (OBJ_obj2nid(a->object) == nid)
4239 			return (a);
4240 	}
4241 	return (NULL);
4242 }
4243 
4244 static KMF_RETURN
4245 convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key)
4246 {
4247 	KMF_RETURN rv = KMF_OK;
4248 	X509_ATTRIBUTE *attr;
4249 
4250 	if (pkey == NULL || key == NULL)
4251 		return (KMF_ERR_BAD_PARAMETER);
4252 	/* Convert SSL key to raw key */
4253 	switch (pkey->type) {
4254 		case EVP_PKEY_RSA:
4255 			rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey),
4256 			    key);
4257 			if (rv != KMF_OK)
4258 				return (rv);
4259 			break;
4260 		case EVP_PKEY_DSA:
4261 			rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey),
4262 			    key);
4263 			if (rv != KMF_OK)
4264 				return (rv);
4265 			break;
4266 		default:
4267 			return (KMF_ERR_BAD_PARAMETER);
4268 	}
4269 	/*
4270 	 * If friendlyName, add it to record.
4271 	 */
4272 	attr = find_attr(pkey->attributes, NID_friendlyName);
4273 	if (attr != NULL) {
4274 		ASN1_TYPE *ty = NULL;
4275 		int numattr = sk_ASN1_TYPE_num(attr->value.set);
4276 		if (attr->single == 0 && numattr > 0) {
4277 			/* LINTED E_BAD_PTR_CAST_ALIGN */
4278 			ty = sk_ASN1_TYPE_value(attr->value.set, 0);
4279 		}
4280 		if (ty != NULL) {
4281 #if OPENSSL_VERSION_NUMBER < 0x10000000L
4282 			key->label = uni2asc(ty->value.bmpstring->data,
4283 			    ty->value.bmpstring->length);
4284 #else
4285 			key->label = OPENSSL_uni2asc(ty->value.bmpstring->data,
4286 			    ty->value.bmpstring->length);
4287 #endif
4288 		}
4289 	} else {
4290 		key->label = NULL;
4291 	}
4292 
4293 	/*
4294 	 * If KeyID, add it to record as a KMF_DATA object.
4295 	 */
4296 	attr = find_attr(pkey->attributes, NID_localKeyID);
4297 	if (attr != NULL) {
4298 		ASN1_TYPE *ty = NULL;
4299 		int numattr = sk_ASN1_TYPE_num(attr->value.set);
4300 		if (attr->single == 0 && numattr > 0) {
4301 			/* LINTED E_BAD_PTR_CAST_ALIGN */
4302 			ty = sk_ASN1_TYPE_value(attr->value.set, 0);
4303 		}
4304 		key->id.Data = (uchar_t *)malloc(
4305 		    ty->value.octet_string->length);
4306 		if (key->id.Data == NULL)
4307 			return (KMF_ERR_MEMORY);
4308 		(void) memcpy(key->id.Data, ty->value.octet_string->data,
4309 		    ty->value.octet_string->length);
4310 		key->id.Length = ty->value.octet_string->length;
4311 	} else {
4312 		(void) memset(&key->id, 0, sizeof (KMF_DATA));
4313 	}
4314 
4315 	return (rv);
4316 }
4317 
4318 static KMF_RETURN
4319 convertPK12Objects(
4320 	KMF_HANDLE *kmfh,
4321 	STACK_OF(EVP_PKEY) *sslkeys,
4322 	STACK_OF(X509) *sslcert,
4323 	STACK_OF(X509) *sslcacerts,
4324 	KMF_RAW_KEY_DATA **keylist, int *nkeys,
4325 	KMF_X509_DER_CERT **certlist, int *ncerts)
4326 {
4327 	KMF_RETURN rv = KMF_OK;
4328 	KMF_RAW_KEY_DATA key;
4329 	int i;
4330 
4331 	for (i = 0; sslkeys != NULL && i < sk_EVP_PKEY_num(sslkeys); i++) {
4332 		/* LINTED E_BAD_PTR_CAST_ALIGN */
4333 		EVP_PKEY *pkey = sk_EVP_PKEY_value(sslkeys, i);
4334 		rv = convertToRawKey(pkey, &key);
4335 		if (rv == KMF_OK)
4336 			rv = add_key_to_list(keylist, &key, nkeys);
4337 
4338 		if (rv != KMF_OK)
4339 			return (rv);
4340 	}
4341 
4342 	/* Now add the certificate to the certlist */
4343 	for (i = 0; sslcert != NULL && i < sk_X509_num(sslcert); i++) {
4344 		/* LINTED E_BAD_PTR_CAST_ALIGN */
4345 		X509 *cert = sk_X509_value(sslcert, i);
4346 		rv = add_cert_to_list(kmfh, cert, certlist, ncerts);
4347 		if (rv != KMF_OK)
4348 			return (rv);
4349 	}
4350 
4351 	/* Also add any included CA certs to the list */
4352 	for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) {
4353 		X509 *c;
4354 		/*
4355 		 * sk_X509_value() is macro that embeds a cast to (X509 *).
4356 		 * Here it translates into ((X509 *)sk_value((ca), (i))).
4357 		 * Lint is complaining about the embedded casting, and
4358 		 * to fix it, you need to fix openssl header files.
4359 		 */
4360 		/* LINTED E_BAD_PTR_CAST_ALIGN */
4361 		c = sk_X509_value(sslcacerts, i);
4362 
4363 		/* Now add the ca cert to the certlist */
4364 		rv = add_cert_to_list(kmfh, c, certlist, ncerts);
4365 		if (rv != KMF_OK)
4366 			return (rv);
4367 	}
4368 	return (rv);
4369 }
4370 
4371 KMF_RETURN
4372 openssl_import_objects(KMF_HANDLE *kmfh,
4373 	char *filename, KMF_CREDENTIAL *cred,
4374 	KMF_X509_DER_CERT **certlist, int *ncerts,
4375 	KMF_RAW_KEY_DATA **keylist, int *nkeys)
4376 {
4377 	KMF_RETURN	rv = KMF_OK;
4378 	KMF_ENCODE_FORMAT format;
4379 	BIO		*bio = NULL;
4380 	STACK_OF(EVP_PKEY)	*privkeys = NULL;
4381 	STACK_OF(X509)		*certs = NULL;
4382 	STACK_OF(X509)		*cacerts = NULL;
4383 
4384 	/*
4385 	 * auto-detect the file format, regardless of what
4386 	 * the 'format' parameters in the params say.
4387 	 */
4388 	rv = kmf_get_file_format(filename, &format);
4389 	if (rv != KMF_OK) {
4390 		return (rv);
4391 	}
4392 
4393 	/* This function only works for PEM or PKCS#12 files */
4394 	if (format != KMF_FORMAT_PEM &&
4395 	    format != KMF_FORMAT_PEM_KEYPAIR &&
4396 	    format != KMF_FORMAT_PKCS12)
4397 		return (KMF_ERR_ENCODING);
4398 
4399 	*certlist = NULL;
4400 	*keylist = NULL;
4401 	*ncerts = 0;
4402 	*nkeys = 0;
4403 
4404 	if (format == KMF_FORMAT_PKCS12) {
4405 		bio = BIO_new_file(filename, "rb");
4406 		if (bio == NULL) {
4407 			SET_ERROR(kmfh, ERR_get_error());
4408 			rv = KMF_ERR_OPEN_FILE;
4409 			goto end;
4410 		}
4411 
4412 		rv = extract_pkcs12(bio, (uchar_t *)cred->cred,
4413 		    (uint32_t)cred->credlen, &privkeys, &certs, &cacerts);
4414 
4415 		if (rv  == KMF_OK)
4416 			/* Convert keys and certs to exportable format */
4417 			rv = convertPK12Objects(kmfh, privkeys, certs, cacerts,
4418 			    keylist, nkeys, certlist, ncerts);
4419 	} else {
4420 		EVP_PKEY *pkey;
4421 		KMF_DATA *certdata = NULL;
4422 		KMF_X509_DER_CERT *kmfcerts = NULL;
4423 		int i;
4424 		rv = extract_pem(kmfh, NULL, NULL, NULL, filename,
4425 		    (uchar_t *)cred->cred, (uint32_t)cred->credlen,
4426 		    &pkey, &certdata, ncerts);
4427 
4428 		/* Reached end of import file? */
4429 		if (rv == KMF_OK && pkey != NULL) {
4430 			privkeys = sk_EVP_PKEY_new_null();
4431 			if (privkeys == NULL) {
4432 				rv = KMF_ERR_MEMORY;
4433 				goto end;
4434 			}
4435 			(void) sk_EVP_PKEY_push(privkeys, pkey);
4436 			/* convert the certificate list here */
4437 			if (*ncerts > 0 && certlist != NULL) {
4438 				kmfcerts = (KMF_X509_DER_CERT *)calloc(*ncerts,
4439 				    sizeof (KMF_X509_DER_CERT));
4440 				if (kmfcerts == NULL) {
4441 					rv = KMF_ERR_MEMORY;
4442 					goto end;
4443 				}
4444 				for (i = 0; i < *ncerts; i++) {
4445 					kmfcerts[i].certificate = certdata[i];
4446 					kmfcerts[i].kmf_private.keystore_type =
4447 					    KMF_KEYSTORE_OPENSSL;
4448 				}
4449 				*certlist = kmfcerts;
4450 			}
4451 			/*
4452 			 * Convert keys to exportable format, the certs
4453 			 * are already OK.
4454 			 */
4455 			rv = convertPK12Objects(kmfh, privkeys, NULL, NULL,
4456 			    keylist, nkeys, NULL, NULL);
4457 		}
4458 	}
4459 end:
4460 	if (bio != NULL)
4461 		(void) BIO_free(bio);
4462 
4463 	if (privkeys)
4464 		sk_EVP_PKEY_pop_free(privkeys, EVP_PKEY_free);
4465 	if (certs)
4466 		sk_X509_pop_free(certs, X509_free);
4467 	if (cacerts)
4468 		sk_X509_pop_free(cacerts, X509_free);
4469 
4470 	return (rv);
4471 }
4472 
4473 static KMF_RETURN
4474 create_deskey(DES_cblock **deskey)
4475 {
4476 	DES_cblock *key;
4477 
4478 	key = (DES_cblock *) malloc(sizeof (DES_cblock));
4479 	if (key == NULL) {
4480 		return (KMF_ERR_MEMORY);
4481 	}
4482 
4483 	if (DES_random_key(key) == 0) {
4484 		free(key);
4485 		return (KMF_ERR_KEYGEN_FAILED);
4486 	}
4487 
4488 	*deskey = key;
4489 	return (KMF_OK);
4490 }
4491 
4492 #define	KEYGEN_RETRY 3
4493 #define	DES3_KEY_SIZE 24
4494 
4495 static KMF_RETURN
4496 create_des3key(unsigned char **des3key)
4497 {
4498 	KMF_RETURN ret = KMF_OK;
4499 	DES_cblock *deskey1 = NULL;
4500 	DES_cblock *deskey2 = NULL;
4501 	DES_cblock *deskey3 = NULL;
4502 	unsigned char *newkey = NULL;
4503 	int retry;
4504 
4505 	if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) {
4506 		return (KMF_ERR_MEMORY);
4507 	}
4508 
4509 	/* create the 1st DES key */
4510 	if ((ret = create_deskey(&deskey1)) != KMF_OK) {
4511 		goto out;
4512 	}
4513 
4514 	/*
4515 	 * Create the 2nd DES key and make sure its value is different
4516 	 * from the 1st DES key.
4517 	 */
4518 	retry = 0;
4519 	do {
4520 		if (deskey2 != NULL) {
4521 			free(deskey2);
4522 			deskey2 = NULL;
4523 		}
4524 
4525 		if ((ret = create_deskey(&deskey2)) != KMF_OK) {
4526 			goto out;
4527 		}
4528 
4529 		if (memcmp((const void *) deskey1, (const void *) deskey2, 8)
4530 		    == 0) {
4531 			ret = KMF_ERR_KEYGEN_FAILED;
4532 			retry++;
4533 		}
4534 	} while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4535 
4536 	if (ret != KMF_OK) {
4537 		goto out;
4538 	}
4539 
4540 	/*
4541 	 * Create the 3rd DES key and make sure its value is different
4542 	 * from the 2nd DES key.
4543 	 */
4544 	retry = 0;
4545 	do {
4546 		if (deskey3 != NULL) {
4547 			free(deskey3);
4548 			deskey3 = NULL;
4549 		}
4550 
4551 		if ((ret = create_deskey(&deskey3)) != KMF_OK) {
4552 			goto out;
4553 		}
4554 
4555 		if (memcmp((const void *)deskey2, (const void *)deskey3, 8)
4556 		    == 0) {
4557 			ret = KMF_ERR_KEYGEN_FAILED;
4558 			retry++;
4559 		}
4560 	} while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4561 
4562 	if (ret != KMF_OK) {
4563 		goto out;
4564 	}
4565 
4566 	/* Concatenate 3 DES keys into a DES3 key */
4567 	(void) memcpy((void *)newkey, (const void *)deskey1, 8);
4568 	(void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8);
4569 	(void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8);
4570 	*des3key = newkey;
4571 
4572 out:
4573 	if (deskey1 != NULL)
4574 		free(deskey1);
4575 
4576 	if (deskey2 != NULL)
4577 		free(deskey2);
4578 
4579 	if (deskey3 != NULL)
4580 		free(deskey3);
4581 
4582 	if (ret != KMF_OK && newkey != NULL)
4583 		free(newkey);
4584 
4585 	return (ret);
4586 }
4587 
4588 KMF_RETURN
4589 OpenSSL_CreateSymKey(KMF_HANDLE_T handle,
4590 	int numattr, KMF_ATTRIBUTE *attrlist)
4591 {
4592 	KMF_RETURN ret = KMF_OK;
4593 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4594 	char *fullpath = NULL;
4595 	KMF_RAW_SYM_KEY *rkey = NULL;
4596 	DES_cblock *deskey = NULL;
4597 	unsigned char *des3key = NULL;
4598 	unsigned char *random = NULL;
4599 	int fd = -1;
4600 	KMF_KEY_HANDLE *symkey;
4601 	KMF_KEY_ALG keytype;
4602 	uint32_t keylen;
4603 	uint32_t keylen_size = sizeof (keylen);
4604 	char *dirpath;
4605 	char *keyfile;
4606 
4607 	if (kmfh == NULL)
4608 		return (KMF_ERR_UNINITIALIZED);
4609 
4610 	symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
4611 	if (symkey == NULL)
4612 		return (KMF_ERR_BAD_PARAMETER);
4613 
4614 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
4615 
4616 	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
4617 	if (keyfile == NULL)
4618 		return (KMF_ERR_BAD_PARAMETER);
4619 
4620 	ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
4621 	    (void *)&keytype, NULL);
4622 	if (ret != KMF_OK)
4623 		return (KMF_ERR_BAD_PARAMETER);
4624 
4625 	ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
4626 	    &keylen, &keylen_size);
4627 	if (ret == KMF_ERR_ATTR_NOT_FOUND &&
4628 	    (keytype == KMF_DES || keytype == KMF_DES3))
4629 		/* keylength is not required for DES and 3DES */
4630 		ret = KMF_OK;
4631 	if (ret != KMF_OK)
4632 		return (KMF_ERR_BAD_PARAMETER);
4633 
4634 	fullpath = get_fullpath(dirpath, keyfile);
4635 	if (fullpath == NULL)
4636 		return (KMF_ERR_BAD_PARAMETER);
4637 
4638 	/* If the requested file exists, return an error */
4639 	if (test_for_file(fullpath, 0400) == 1) {
4640 		free(fullpath);
4641 		return (KMF_ERR_DUPLICATE_KEYFILE);
4642 	}
4643 
4644 	fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400);
4645 	if (fd == -1) {
4646 		ret = KMF_ERR_OPEN_FILE;
4647 		goto out;
4648 	}
4649 
4650 	rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
4651 	if (rkey == NULL) {
4652 		ret = KMF_ERR_MEMORY;
4653 		goto out;
4654 	}
4655 	(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
4656 
4657 	if (keytype == KMF_DES) {
4658 		if ((ret = create_deskey(&deskey)) != KMF_OK) {
4659 			goto out;
4660 		}
4661 		rkey->keydata.val = (uchar_t *)deskey;
4662 		rkey->keydata.len = 8;
4663 
4664 		symkey->keyalg = KMF_DES;
4665 
4666 	} else if (keytype == KMF_DES3) {
4667 		if ((ret = create_des3key(&des3key)) != KMF_OK) {
4668 			goto out;
4669 		}
4670 		rkey->keydata.val = (uchar_t *)des3key;
4671 		rkey->keydata.len = DES3_KEY_SIZE;
4672 		symkey->keyalg = KMF_DES3;
4673 
4674 	} else if (keytype == KMF_AES || keytype == KMF_RC4 ||
4675 	    keytype == KMF_GENERIC_SECRET) {
4676 		int bytes;
4677 
4678 		if (keylen % 8 != 0) {
4679 			ret = KMF_ERR_BAD_KEY_SIZE;
4680 			goto out;
4681 		}
4682 
4683 		if (keytype == KMF_AES) {
4684 			if (keylen != 128 &&
4685 			    keylen != 192 &&
4686 			    keylen != 256) {
4687 				ret = KMF_ERR_BAD_KEY_SIZE;
4688 				goto out;
4689 			}
4690 		}
4691 
4692 		bytes = keylen/8;
4693 		random = malloc(bytes);
4694 		if (random == NULL) {
4695 			ret = KMF_ERR_MEMORY;
4696 			goto out;
4697 		}
4698 		if (RAND_bytes(random, bytes) != 1) {
4699 			ret = KMF_ERR_KEYGEN_FAILED;
4700 			goto out;
4701 		}
4702 
4703 		rkey->keydata.val = (uchar_t *)random;
4704 		rkey->keydata.len = bytes;
4705 		symkey->keyalg = keytype;
4706 
4707 	} else {
4708 		ret = KMF_ERR_BAD_KEY_TYPE;
4709 		goto out;
4710 	}
4711 
4712 	(void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len);
4713 
4714 	symkey->kstype = KMF_KEYSTORE_OPENSSL;
4715 	symkey->keyclass = KMF_SYMMETRIC;
4716 	symkey->keylabel = (char *)fullpath;
4717 	symkey->israw = TRUE;
4718 	symkey->keyp = rkey;
4719 
4720 out:
4721 	if (fd != -1)
4722 		(void) close(fd);
4723 
4724 	if (ret != KMF_OK && fullpath != NULL) {
4725 		free(fullpath);
4726 	}
4727 	if (ret != KMF_OK) {
4728 		kmf_free_raw_sym_key(rkey);
4729 		symkey->keyp = NULL;
4730 		symkey->keyalg = KMF_KEYALG_NONE;
4731 	}
4732 
4733 	return (ret);
4734 }
4735 
4736 /*
4737  * Check a file to see if it is a CRL file with PEM or DER format.
4738  * If success, return its format in the "pformat" argument.
4739  */
4740 KMF_RETURN
4741 OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat)
4742 {
4743 	KMF_RETURN	ret = KMF_OK;
4744 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4745 	BIO		*bio = NULL;
4746 	X509_CRL   	*xcrl = NULL;
4747 
4748 	if (filename == NULL) {
4749 		return (KMF_ERR_BAD_PARAMETER);
4750 	}
4751 
4752 	bio = BIO_new_file(filename, "rb");
4753 	if (bio == NULL)	{
4754 		SET_ERROR(kmfh, ERR_get_error());
4755 		ret = KMF_ERR_OPEN_FILE;
4756 		goto out;
4757 	}
4758 
4759 	if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) {
4760 		*pformat = KMF_FORMAT_PEM;
4761 		goto out;
4762 	}
4763 	(void) BIO_free(bio);
4764 
4765 	/*
4766 	 * Now try to read it as raw DER data.
4767 	 */
4768 	bio = BIO_new_file(filename, "rb");
4769 	if (bio == NULL)	{
4770 		SET_ERROR(kmfh, ERR_get_error());
4771 		ret = KMF_ERR_OPEN_FILE;
4772 		goto out;
4773 	}
4774 
4775 	if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) {
4776 		*pformat = KMF_FORMAT_ASN1;
4777 	} else {
4778 		ret = KMF_ERR_BAD_CRLFILE;
4779 	}
4780 
4781 out:
4782 	if (bio != NULL)
4783 		(void) BIO_free(bio);
4784 
4785 	if (xcrl != NULL)
4786 		X509_CRL_free(xcrl);
4787 
4788 	return (ret);
4789 }
4790 
4791 KMF_RETURN
4792 OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
4793     KMF_RAW_SYM_KEY *rkey)
4794 {
4795 	KMF_RETURN	rv = KMF_OK;
4796 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4797 	KMF_DATA	keyvalue;
4798 
4799 	if (kmfh == NULL)
4800 		return (KMF_ERR_UNINITIALIZED);
4801 
4802 	if (symkey == NULL || rkey == NULL)
4803 		return (KMF_ERR_BAD_PARAMETER);
4804 	else if (symkey->keyclass != KMF_SYMMETRIC)
4805 		return (KMF_ERR_BAD_KEY_CLASS);
4806 
4807 	if (symkey->israw) {
4808 		KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp;
4809 
4810 		if (rawkey == NULL ||
4811 		    rawkey->keydata.val == NULL ||
4812 		    rawkey->keydata.len == 0)
4813 			return (KMF_ERR_BAD_KEYHANDLE);
4814 
4815 		rkey->keydata.len = rawkey->keydata.len;
4816 		if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
4817 			return (KMF_ERR_MEMORY);
4818 		(void) memcpy(rkey->keydata.val, rawkey->keydata.val,
4819 		    rkey->keydata.len);
4820 	} else {
4821 		rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue);
4822 		if (rv != KMF_OK)
4823 			return (rv);
4824 		rkey->keydata.len = keyvalue.Length;
4825 		rkey->keydata.val = keyvalue.Data;
4826 	}
4827 
4828 	return (rv);
4829 }
4830 
4831 /*
4832  * substitute for the unsafe access(2) function.
4833  * If the file in question already exists, return 1.
4834  * else 0.  If an error occurs during testing (other
4835  * than EEXIST), return -1.
4836  */
4837 static int
4838 test_for_file(char *filename, mode_t mode)
4839 {
4840 	int fd;
4841 
4842 	/*
4843 	 * Try to create the file with the EXCL flag.
4844 	 * The call should fail if the file exists.
4845 	 */
4846 	fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode);
4847 	if (fd == -1 && errno == EEXIST)
4848 		return (1);
4849 	else if (fd == -1) /* some other error */
4850 		return (-1);
4851 
4852 	/* The file did NOT exist.  Delete the testcase. */
4853 	(void) close(fd);
4854 	(void) unlink(filename);
4855 	return (0);
4856 }
4857 
4858 KMF_RETURN
4859 OpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr,
4860 	KMF_ATTRIBUTE *attrlist)
4861 {
4862 	KMF_RETURN rv = KMF_OK;
4863 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4864 	KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL;
4865 	KMF_RAW_KEY_DATA *rawkey;
4866 	EVP_PKEY *pkey = NULL;
4867 	KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM;
4868 	KMF_CREDENTIAL cred = { NULL, 0 };
4869 	BIO *out = NULL;
4870 	int keys = 0;
4871 	char *fullpath = NULL;
4872 	char *keyfile = NULL;
4873 	char *dirpath = NULL;
4874 
4875 	pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
4876 	if (pubkey != NULL)
4877 		keys++;
4878 
4879 	prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
4880 	if (prikey != NULL)
4881 		keys++;
4882 
4883 	rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
4884 	if (rawkey != NULL)
4885 		keys++;
4886 
4887 	/*
4888 	 * Exactly 1 type of key must be passed to this function.
4889 	 */
4890 	if (keys != 1)
4891 		return (KMF_ERR_BAD_PARAMETER);
4892 
4893 	keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist,
4894 	    numattr);
4895 	if (keyfile == NULL)
4896 		return (KMF_ERR_BAD_PARAMETER);
4897 
4898 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
4899 
4900 	fullpath = get_fullpath(dirpath, keyfile);
4901 
4902 	/* Once we have the full path, we don't need the pieces */
4903 	if (fullpath == NULL)
4904 		return (KMF_ERR_BAD_PARAMETER);
4905 
4906 	/* If the requested file exists, return an error */
4907 	if (test_for_file(fullpath, 0400) == 1) {
4908 		free(fullpath);
4909 		return (KMF_ERR_DUPLICATE_KEYFILE);
4910 	}
4911 
4912 	rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
4913 	    &format, NULL);
4914 	if (rv != KMF_OK)
4915 		/* format is optional. */
4916 		rv = KMF_OK;
4917 
4918 	/* CRED is not required for OpenSSL files */
4919 	(void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
4920 	    &cred, NULL);
4921 
4922 	/* Store the private key to the keyfile */
4923 	out = BIO_new_file(fullpath, "wb");
4924 	if (out == NULL) {
4925 		SET_ERROR(kmfh, ERR_get_error());
4926 		rv = KMF_ERR_OPEN_FILE;
4927 		goto end;
4928 	}
4929 
4930 	if (prikey != NULL && prikey->keyp != NULL) {
4931 		if (prikey->keyalg == KMF_RSA ||
4932 		    prikey->keyalg == KMF_DSA) {
4933 			pkey = (EVP_PKEY *)prikey->keyp;
4934 
4935 			rv = ssl_write_key(kmfh, format,
4936 			    out, &cred, pkey, TRUE);
4937 
4938 			if (rv == KMF_OK && prikey->keylabel == NULL) {
4939 				prikey->keylabel = strdup(fullpath);
4940 				if (prikey->keylabel == NULL)
4941 					rv = KMF_ERR_MEMORY;
4942 			}
4943 		}
4944 	} else if (pubkey != NULL && pubkey->keyp != NULL) {
4945 		if (pubkey->keyalg == KMF_RSA ||
4946 		    pubkey->keyalg == KMF_DSA) {
4947 			pkey = (EVP_PKEY *)pubkey->keyp;
4948 
4949 			rv = ssl_write_key(kmfh, format,
4950 			    out, &cred, pkey, FALSE);
4951 
4952 			if (rv == KMF_OK && pubkey->keylabel == NULL) {
4953 				pubkey->keylabel = strdup(fullpath);
4954 				if (pubkey->keylabel == NULL)
4955 					rv = KMF_ERR_MEMORY;
4956 			}
4957 		}
4958 	} else if (rawkey != NULL) {
4959 		if (rawkey->keytype == KMF_RSA) {
4960 			pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
4961 		} else if (rawkey->keytype == KMF_DSA) {
4962 			pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
4963 		} else {
4964 			rv = KMF_ERR_BAD_PARAMETER;
4965 		}
4966 		if (pkey != NULL) {
4967 			KMF_KEY_CLASS kclass = KMF_ASYM_PRI;
4968 
4969 			rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
4970 			    (void *)&kclass, NULL);
4971 			if (rv != KMF_OK)
4972 				rv = KMF_OK;
4973 			rv = ssl_write_key(kmfh, format, out,
4974 			    &cred, pkey, (kclass == KMF_ASYM_PRI));
4975 			EVP_PKEY_free(pkey);
4976 		}
4977 	}
4978 
4979 end:
4980 
4981 	if (out)
4982 		(void) BIO_free(out);
4983 
4984 
4985 	if (rv == KMF_OK)
4986 		(void) chmod(fullpath, 0400);
4987 
4988 	free(fullpath);
4989 	return (rv);
4990 }
4991 
4992 KMF_RETURN
4993 OpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
4994 {
4995 	KMF_RETURN ret = KMF_OK;
4996 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4997 	X509_CRL *xcrl = NULL;
4998 	X509 *xcert = NULL;
4999 	EVP_PKEY *pkey;
5000 	KMF_ENCODE_FORMAT format;
5001 	BIO *in = NULL, *out = NULL;
5002 	int openssl_ret = 0;
5003 	KMF_ENCODE_FORMAT outformat;
5004 	boolean_t crlcheck = FALSE;
5005 	char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile;
5006 
5007 	if (numattr == 0 || attrlist == NULL) {
5008 		return (KMF_ERR_BAD_PARAMETER);
5009 	}
5010 
5011 	/* CRL check is optional */
5012 	(void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr,
5013 	    &crlcheck, NULL);
5014 
5015 	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
5016 	if (crlcheck == B_TRUE && certfile == NULL) {
5017 		return (KMF_ERR_BAD_CERTFILE);
5018 	}
5019 
5020 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5021 	incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr);
5022 	outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr);
5023 
5024 	crlfile = get_fullpath(dirpath, incrl);
5025 
5026 	if (crlfile == NULL)
5027 		return (KMF_ERR_BAD_CRLFILE);
5028 
5029 	outcrlfile = get_fullpath(dirpath, outcrl);
5030 	if (outcrlfile == NULL)
5031 		return (KMF_ERR_BAD_CRLFILE);
5032 
5033 	if (isdir(outcrlfile)) {
5034 		free(outcrlfile);
5035 		return (KMF_ERR_BAD_CRLFILE);
5036 	}
5037 
5038 	ret = kmf_is_crl_file(handle, crlfile, &format);
5039 	if (ret != KMF_OK) {
5040 		free(outcrlfile);
5041 		return (ret);
5042 	}
5043 
5044 	in = BIO_new_file(crlfile, "rb");
5045 	if (in == NULL)	{
5046 		SET_ERROR(kmfh, ERR_get_error());
5047 		ret = KMF_ERR_OPEN_FILE;
5048 		goto end;
5049 	}
5050 
5051 	if (format == KMF_FORMAT_ASN1) {
5052 		xcrl = d2i_X509_CRL_bio(in, NULL);
5053 	} else if (format == KMF_FORMAT_PEM) {
5054 		xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5055 	}
5056 
5057 	if (xcrl == NULL) {
5058 		SET_ERROR(kmfh, ERR_get_error());
5059 		ret = KMF_ERR_BAD_CRLFILE;
5060 		goto end;
5061 	}
5062 
5063 	/* If bypasscheck is specified, no need to verify. */
5064 	if (crlcheck == B_FALSE)
5065 		goto output;
5066 
5067 	ret = kmf_is_cert_file(handle, certfile, &format);
5068 	if (ret != KMF_OK)
5069 		goto end;
5070 
5071 	/* Read in the CA cert file and convert to X509 */
5072 	if (BIO_read_filename(in, certfile) <= 0) {
5073 		SET_ERROR(kmfh, ERR_get_error());
5074 		ret = KMF_ERR_OPEN_FILE;
5075 		goto end;
5076 	}
5077 
5078 	if (format == KMF_FORMAT_ASN1) {
5079 		xcert = d2i_X509_bio(in, NULL);
5080 	} else if (format == KMF_FORMAT_PEM) {
5081 		xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
5082 	} else {
5083 		ret = KMF_ERR_BAD_CERT_FORMAT;
5084 		goto end;
5085 	}
5086 
5087 	if (xcert == NULL) {
5088 		SET_ERROR(kmfh, ERR_get_error());
5089 		ret = KMF_ERR_BAD_CERT_FORMAT;
5090 		goto end;
5091 	}
5092 	/* Now get the public key from the CA cert */
5093 	pkey = X509_get_pubkey(xcert);
5094 	if (pkey == NULL) {
5095 		SET_ERROR(kmfh, ERR_get_error());
5096 		ret = KMF_ERR_BAD_CERTFILE;
5097 		goto end;
5098 	}
5099 
5100 	/* Verify the CRL with the CA's public key */
5101 	openssl_ret = X509_CRL_verify(xcrl, pkey);
5102 	EVP_PKEY_free(pkey);
5103 	if (openssl_ret > 0) {
5104 		ret = KMF_OK;  /* verify succeed */
5105 	} else {
5106 		SET_ERROR(kmfh, openssl_ret);
5107 		ret = KMF_ERR_BAD_CRLFILE;
5108 	}
5109 
5110 output:
5111 	ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
5112 	    &outformat, NULL);
5113 	if (ret != KMF_OK) {
5114 		ret = KMF_OK;
5115 		outformat = KMF_FORMAT_PEM;
5116 	}
5117 
5118 	out = BIO_new_file(outcrlfile, "wb");
5119 	if (out == NULL) {
5120 		SET_ERROR(kmfh, ERR_get_error());
5121 		ret = KMF_ERR_OPEN_FILE;
5122 		goto end;
5123 	}
5124 
5125 	if (outformat == KMF_FORMAT_ASN1) {
5126 		openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl);
5127 	} else if (outformat == KMF_FORMAT_PEM) {
5128 		openssl_ret = PEM_write_bio_X509_CRL(out, xcrl);
5129 	} else {
5130 		ret = KMF_ERR_BAD_PARAMETER;
5131 		goto end;
5132 	}
5133 
5134 	if (openssl_ret <= 0) {
5135 		SET_ERROR(kmfh, ERR_get_error());
5136 		ret = KMF_ERR_WRITE_FILE;
5137 	} else {
5138 		ret = KMF_OK;
5139 	}
5140 
5141 end:
5142 	if (xcrl != NULL)
5143 		X509_CRL_free(xcrl);
5144 
5145 	if (xcert != NULL)
5146 		X509_free(xcert);
5147 
5148 	if (in != NULL)
5149 		(void) BIO_free(in);
5150 
5151 	if (out != NULL)
5152 		(void) BIO_free(out);
5153 
5154 	if (outcrlfile != NULL)
5155 		free(outcrlfile);
5156 
5157 	return (ret);
5158 }
5159 
5160 KMF_RETURN
5161 OpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5162 {
5163 	KMF_RETURN ret = KMF_OK;
5164 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5165 	X509_CRL   *x = NULL;
5166 	KMF_ENCODE_FORMAT format;
5167 	char *crlfile = NULL;
5168 	BIO *in = NULL;
5169 	BIO *mem = NULL;
5170 	long len;
5171 	char *memptr;
5172 	char *data = NULL;
5173 	char **crldata;
5174 	char *crlfilename, *dirpath;
5175 
5176 	if (numattr == 0 || attrlist == NULL) {
5177 		return (KMF_ERR_BAD_PARAMETER);
5178 	}
5179 	crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5180 	    attrlist, numattr);
5181 	if (crlfilename == NULL)
5182 		return (KMF_ERR_BAD_CRLFILE);
5183 
5184 	crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR,
5185 	    attrlist, numattr);
5186 
5187 	if (crldata == NULL)
5188 		return (KMF_ERR_BAD_PARAMETER);
5189 
5190 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5191 
5192 	crlfile = get_fullpath(dirpath, crlfilename);
5193 
5194 	if (crlfile == NULL)
5195 		return (KMF_ERR_BAD_CRLFILE);
5196 
5197 	if (isdir(crlfile)) {
5198 		free(crlfile);
5199 		return (KMF_ERR_BAD_CRLFILE);
5200 	}
5201 
5202 	ret = kmf_is_crl_file(handle, crlfile, &format);
5203 	if (ret != KMF_OK) {
5204 		free(crlfile);
5205 		return (ret);
5206 	}
5207 
5208 	if (bio_err == NULL)
5209 		bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
5210 
5211 	in = BIO_new_file(crlfile, "rb");
5212 	if (in == NULL)	{
5213 		SET_ERROR(kmfh, ERR_get_error());
5214 		ret = KMF_ERR_OPEN_FILE;
5215 		goto end;
5216 	}
5217 
5218 	if (format == KMF_FORMAT_ASN1) {
5219 		x = d2i_X509_CRL_bio(in, NULL);
5220 	} else if (format == KMF_FORMAT_PEM) {
5221 		x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5222 	}
5223 
5224 	if (x == NULL) { /* should not happen */
5225 		SET_ERROR(kmfh, ERR_get_error());
5226 		ret = KMF_ERR_OPEN_FILE;
5227 		goto end;
5228 	}
5229 
5230 	mem = BIO_new(BIO_s_mem());
5231 	if (mem == NULL) {
5232 		SET_ERROR(kmfh, ERR_get_error());
5233 		ret = KMF_ERR_MEMORY;
5234 		goto end;
5235 	}
5236 
5237 	(void) X509_CRL_print(mem, x);
5238 	len = BIO_get_mem_data(mem, &memptr);
5239 	if (len <= 0) {
5240 		SET_ERROR(kmfh, ERR_get_error());
5241 		ret = KMF_ERR_MEMORY;
5242 		goto end;
5243 	}
5244 
5245 	data = malloc(len + 1);
5246 	if (data == NULL) {
5247 		ret = KMF_ERR_MEMORY;
5248 		goto end;
5249 	}
5250 
5251 	(void) memcpy(data, memptr, len);
5252 	data[len] = '\0';
5253 	*crldata = data;
5254 
5255 end:
5256 	if (x != NULL)
5257 		X509_CRL_free(x);
5258 
5259 	if (crlfile != NULL)
5260 		free(crlfile);
5261 
5262 	if (in != NULL)
5263 		(void) BIO_free(in);
5264 
5265 	if (mem != NULL)
5266 		(void) BIO_free(mem);
5267 
5268 	return (ret);
5269 }
5270 
5271 KMF_RETURN
5272 OpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5273 {
5274 	KMF_RETURN ret = KMF_OK;
5275 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5276 	KMF_ENCODE_FORMAT format;
5277 	char *crlfile = NULL;
5278 	BIO *in = NULL;
5279 	char *crlfilename, *dirpath;
5280 
5281 	if (numattr == 0 || attrlist == NULL) {
5282 		return (KMF_ERR_BAD_PARAMETER);
5283 	}
5284 
5285 	crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5286 	    attrlist, numattr);
5287 
5288 	if (crlfilename == NULL)
5289 		return (KMF_ERR_BAD_CRLFILE);
5290 
5291 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5292 
5293 	crlfile = get_fullpath(dirpath, crlfilename);
5294 
5295 	if (crlfile == NULL)
5296 		return (KMF_ERR_BAD_CRLFILE);
5297 
5298 	if (isdir(crlfile)) {
5299 		ret = KMF_ERR_BAD_CRLFILE;
5300 		goto end;
5301 	}
5302 
5303 	ret = kmf_is_crl_file(handle, crlfile, &format);
5304 	if (ret != KMF_OK)
5305 		goto end;
5306 
5307 	if (unlink(crlfile) != 0) {
5308 		SET_SYS_ERROR(kmfh, errno);
5309 		ret = KMF_ERR_INTERNAL;
5310 		goto end;
5311 	}
5312 
5313 end:
5314 	if (in != NULL)
5315 		(void) BIO_free(in);
5316 	if (crlfile != NULL)
5317 		free(crlfile);
5318 
5319 	return (ret);
5320 }
5321 
5322 KMF_RETURN
5323 OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5324 {
5325 	KMF_RETURN ret = KMF_OK;
5326 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5327 	KMF_ENCODE_FORMAT format;
5328 	BIO *in = NULL;
5329 	X509   *xcert = NULL;
5330 	X509_CRL   *xcrl = NULL;
5331 	STACK_OF(X509_REVOKED) *revoke_stack = NULL;
5332 	X509_REVOKED *revoke;
5333 	int i;
5334 	char *crlfilename, *crlfile, *dirpath, *certfile;
5335 
5336 	if (numattr == 0 || attrlist == NULL) {
5337 		return (KMF_ERR_BAD_PARAMETER);
5338 	}
5339 
5340 	crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5341 	    attrlist, numattr);
5342 
5343 	if (crlfilename == NULL)
5344 		return (KMF_ERR_BAD_CRLFILE);
5345 
5346 	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
5347 	if (certfile == NULL)
5348 		return (KMF_ERR_BAD_CRLFILE);
5349 
5350 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5351 
5352 	crlfile = get_fullpath(dirpath, crlfilename);
5353 
5354 	if (crlfile == NULL)
5355 		return (KMF_ERR_BAD_CRLFILE);
5356 
5357 	if (isdir(crlfile)) {
5358 		ret = KMF_ERR_BAD_CRLFILE;
5359 		goto end;
5360 	}
5361 
5362 	ret = kmf_is_crl_file(handle, crlfile, &format);
5363 	if (ret != KMF_OK)
5364 		goto end;
5365 
5366 	/* Read the CRL file and load it into a X509_CRL structure */
5367 	in = BIO_new_file(crlfilename, "rb");
5368 	if (in == NULL)	{
5369 		SET_ERROR(kmfh, ERR_get_error());
5370 		ret = KMF_ERR_OPEN_FILE;
5371 		goto end;
5372 	}
5373 
5374 	if (format == KMF_FORMAT_ASN1) {
5375 		xcrl = d2i_X509_CRL_bio(in, NULL);
5376 	} else if (format == KMF_FORMAT_PEM) {
5377 		xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5378 	}
5379 
5380 	if (xcrl == NULL) {
5381 		SET_ERROR(kmfh, ERR_get_error());
5382 		ret = KMF_ERR_BAD_CRLFILE;
5383 		goto end;
5384 	}
5385 	(void) BIO_free(in);
5386 
5387 	/* Read the Certificate file and load it into a X509 structure */
5388 	ret = kmf_is_cert_file(handle, certfile, &format);
5389 	if (ret != KMF_OK)
5390 		goto end;
5391 
5392 	in = BIO_new_file(certfile, "rb");
5393 	if (in == NULL)	{
5394 		SET_ERROR(kmfh, ERR_get_error());
5395 		ret = KMF_ERR_OPEN_FILE;
5396 		goto end;
5397 	}
5398 
5399 	if (format == KMF_FORMAT_ASN1) {
5400 		xcert = d2i_X509_bio(in, NULL);
5401 	} else if (format == KMF_FORMAT_PEM) {
5402 		xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
5403 	}
5404 
5405 	if (xcert == NULL) {
5406 		SET_ERROR(kmfh, ERR_get_error());
5407 		ret = KMF_ERR_BAD_CERTFILE;
5408 		goto end;
5409 	}
5410 
5411 	/* Check if the certificate and the CRL have same issuer */
5412 	if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) {
5413 		ret = KMF_ERR_ISSUER;
5414 		goto end;
5415 	}
5416 
5417 	/* Check to see if the certificate serial number is revoked */
5418 	revoke_stack = X509_CRL_get_REVOKED(xcrl);
5419 	if (sk_X509_REVOKED_num(revoke_stack) <= 0) {
5420 		/* No revoked certificates in the CRL file */
5421 		SET_ERROR(kmfh, ERR_get_error());
5422 		ret = KMF_ERR_EMPTY_CRL;
5423 		goto end;
5424 	}
5425 
5426 	for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) {
5427 		/* LINTED E_BAD_PTR_CAST_ALIGN */
5428 		revoke = sk_X509_REVOKED_value(revoke_stack, i);
5429 		if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber,
5430 		    revoke->serialNumber) == 0) {
5431 			break;
5432 		}
5433 	}
5434 
5435 	if (i < sk_X509_REVOKED_num(revoke_stack)) {
5436 		ret = KMF_OK;
5437 	} else {
5438 		ret = KMF_ERR_NOT_REVOKED;
5439 	}
5440 
5441 end:
5442 	if (in != NULL)
5443 		(void) BIO_free(in);
5444 	if (xcrl != NULL)
5445 		X509_CRL_free(xcrl);
5446 	if (xcert != NULL)
5447 		X509_free(xcert);
5448 
5449 	return (ret);
5450 }
5451 
5452 KMF_RETURN
5453 OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert)
5454 {
5455 	KMF_RETURN	ret = KMF_OK;
5456 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
5457 	BIO		*bcrl = NULL;
5458 	X509_CRL   	*xcrl = NULL;
5459 	X509		*xcert = NULL;
5460 	EVP_PKEY	*pkey;
5461 	int		sslret;
5462 	KMF_ENCODE_FORMAT crl_format;
5463 	unsigned char	*p;
5464 	long		len;
5465 
5466 	if (handle == NULL || crlname == NULL || tacert == NULL) {
5467 		return (KMF_ERR_BAD_PARAMETER);
5468 	}
5469 
5470 	ret = kmf_get_file_format(crlname, &crl_format);
5471 	if (ret != KMF_OK)
5472 		return (ret);
5473 
5474 	bcrl = BIO_new_file(crlname, "rb");
5475 	if (bcrl == NULL)	{
5476 		SET_ERROR(kmfh, ERR_get_error());
5477 		ret = KMF_ERR_OPEN_FILE;
5478 		goto cleanup;
5479 	}
5480 
5481 	if (crl_format == KMF_FORMAT_ASN1) {
5482 		xcrl = d2i_X509_CRL_bio(bcrl, NULL);
5483 	} else if (crl_format == KMF_FORMAT_PEM) {
5484 		xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
5485 	} else {
5486 		ret = KMF_ERR_BAD_PARAMETER;
5487 		goto cleanup;
5488 	}
5489 
5490 	if (xcrl == NULL) {
5491 		SET_ERROR(kmfh, ERR_get_error());
5492 		ret = KMF_ERR_BAD_CRLFILE;
5493 		goto cleanup;
5494 	}
5495 
5496 	p = tacert->Data;
5497 	len = tacert->Length;
5498 	xcert = d2i_X509(NULL, (const uchar_t **)&p, len);
5499 
5500 	if (xcert == NULL) {
5501 		SET_ERROR(kmfh, ERR_get_error());
5502 		ret = KMF_ERR_BAD_CERTFILE;
5503 		goto cleanup;
5504 	}
5505 
5506 	/* Get issuer certificate public key */
5507 	pkey = X509_get_pubkey(xcert);
5508 	if (pkey == NULL) {
5509 		SET_ERROR(kmfh, ERR_get_error());
5510 		ret = KMF_ERR_BAD_CERT_FORMAT;
5511 		goto cleanup;
5512 	}
5513 
5514 	/* Verify CRL signature */
5515 	sslret = X509_CRL_verify(xcrl, pkey);
5516 	EVP_PKEY_free(pkey);
5517 	if (sslret > 0) {
5518 		ret = KMF_OK;
5519 	} else {
5520 		SET_ERROR(kmfh, sslret);
5521 		ret = KMF_ERR_BAD_CRLFILE;
5522 	}
5523 
5524 cleanup:
5525 	if (bcrl != NULL)
5526 		(void) BIO_free(bcrl);
5527 
5528 	if (xcrl != NULL)
5529 		X509_CRL_free(xcrl);
5530 
5531 	if (xcert != NULL)
5532 		X509_free(xcert);
5533 
5534 	return (ret);
5535 
5536 }
5537 
5538 KMF_RETURN
5539 OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname)
5540 {
5541 	KMF_RETURN	ret = KMF_OK;
5542 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
5543 	KMF_ENCODE_FORMAT crl_format;
5544 	BIO		*bcrl = NULL;
5545 	X509_CRL   	*xcrl = NULL;
5546 	int		i;
5547 
5548 	if (handle == NULL || crlname == NULL) {
5549 		return (KMF_ERR_BAD_PARAMETER);
5550 	}
5551 
5552 	ret = kmf_is_crl_file(handle, crlname, &crl_format);
5553 	if (ret != KMF_OK)
5554 		return (ret);
5555 
5556 	bcrl = BIO_new_file(crlname, "rb");
5557 	if (bcrl == NULL) {
5558 		SET_ERROR(kmfh, ERR_get_error());
5559 		ret = KMF_ERR_OPEN_FILE;
5560 		goto cleanup;
5561 	}
5562 
5563 	if (crl_format == KMF_FORMAT_ASN1)
5564 		xcrl = d2i_X509_CRL_bio(bcrl, NULL);
5565 	else if (crl_format == KMF_FORMAT_PEM)
5566 		xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
5567 
5568 	if (xcrl == NULL) {
5569 		SET_ERROR(kmfh, ERR_get_error());
5570 		ret = KMF_ERR_BAD_CRLFILE;
5571 		goto cleanup;
5572 	}
5573 	i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL);
5574 	if (i >= 0) {
5575 		ret = KMF_ERR_VALIDITY_PERIOD;
5576 		goto cleanup;
5577 	}
5578 	if (X509_CRL_get_nextUpdate(xcrl)) {
5579 		i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL);
5580 
5581 		if (i <= 0) {
5582 			ret = KMF_ERR_VALIDITY_PERIOD;
5583 			goto cleanup;
5584 		}
5585 	}
5586 
5587 	ret = KMF_OK;
5588 
5589 cleanup:
5590 	if (bcrl != NULL)
5591 		(void) BIO_free(bcrl);
5592 
5593 	if (xcrl != NULL)
5594 		X509_CRL_free(xcrl);
5595 
5596 	return (ret);
5597 }
5598