xref: /titanic_52/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c (revision 38379e9254628617dd4995589f23b06c84ffe16e)
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_SHA1WithRSA)
1806 			md = EVP_sha1();
1807 		else if (AlgId == KMF_ALGID_SHA256WithRSA)
1808 			md = EVP_sha256();
1809 		else if (AlgId == KMF_ALGID_SHA384WithRSA)
1810 			md = EVP_sha384();
1811 		else if (AlgId == KMF_ALGID_SHA512WithRSA)
1812 			md = EVP_sha512();
1813 		else if (AlgId == KMF_ALGID_RSA)
1814 			md = NULL;
1815 		else
1816 			return (KMF_ERR_BAD_ALGORITHM);
1817 
1818 		if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) {
1819 			RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey);
1820 
1821 			p = output->Data;
1822 			if ((len = RSA_private_encrypt(tobesigned->Length,
1823 			    tobesigned->Data, p, rsa,
1824 			    RSA_PKCS1_PADDING)) <= 0) {
1825 				SET_ERROR(kmfh, ERR_get_error());
1826 				ret = KMF_ERR_INTERNAL;
1827 			}
1828 			output->Length = len;
1829 		} else {
1830 			(void) EVP_MD_CTX_init(&ctx);
1831 			(void) EVP_SignInit_ex(&ctx, md, NULL);
1832 			(void) EVP_SignUpdate(&ctx, tobesigned->Data,
1833 			    (uint32_t)tobesigned->Length);
1834 			len = (uint32_t)output->Length;
1835 			p = output->Data;
1836 			if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) {
1837 				SET_ERROR(kmfh, ERR_get_error());
1838 				len = 0;
1839 				ret = KMF_ERR_INTERNAL;
1840 			}
1841 			output->Length = len;
1842 			(void) EVP_MD_CTX_cleanup(&ctx);
1843 		}
1844 	} else if (key->keyalg == KMF_DSA) {
1845 		DSA *dsa = EVP_PKEY_get1_DSA(key->keyp);
1846 
1847 		uchar_t hash[EVP_MAX_MD_SIZE];
1848 		uint32_t hashlen;
1849 		DSA_SIG *dsasig;
1850 
1851 		if (AlgId == KMF_ALGID_DSA ||
1852 		    AlgId == KMF_ALGID_SHA1WithDSA)
1853 			md = EVP_sha1();
1854 		else if (AlgId == KMF_ALGID_SHA256WithDSA)
1855 			md = EVP_sha256();
1856 		else /* Bad algorithm */
1857 			return (KMF_ERR_BAD_ALGORITHM);
1858 
1859 		/*
1860 		 * OpenSSL EVP_Sign operation automatically converts to
1861 		 * ASN.1 output so we do the operations separately so we
1862 		 * are assured of NOT getting ASN.1 output returned.
1863 		 * KMF does not want ASN.1 encoded results because
1864 		 * not all mechanisms return ASN.1 encodings (PKCS#11
1865 		 * and NSS return raw signature data).
1866 		 */
1867 		EVP_MD_CTX_init(&ctx);
1868 		(void) EVP_DigestInit_ex(&ctx, md, NULL);
1869 		(void) EVP_DigestUpdate(&ctx, tobesigned->Data,
1870 		    tobesigned->Length);
1871 		(void) EVP_DigestFinal_ex(&ctx, hash, &hashlen);
1872 
1873 		/* Only sign first 20 bytes for SHA2 */
1874 		if (AlgId == KMF_ALGID_SHA256WithDSA)
1875 			hashlen = 20;
1876 		dsasig = DSA_do_sign(hash, hashlen, dsa);
1877 		if (dsasig != NULL) {
1878 			int i;
1879 			output->Length = i = fixbnlen(dsasig->r, output->Data,
1880 			    hashlen);
1881 
1882 			output->Length += fixbnlen(dsasig->s, &output->Data[i],
1883 			    hashlen);
1884 
1885 			DSA_SIG_free(dsasig);
1886 		} else {
1887 			SET_ERROR(kmfh, ERR_get_error());
1888 		}
1889 		(void) EVP_MD_CTX_cleanup(&ctx);
1890 	} else {
1891 		return (KMF_ERR_BAD_PARAMETER);
1892 	}
1893 cleanup:
1894 	return (ret);
1895 }
1896 
1897 KMF_RETURN
1898 /*ARGSUSED*/
1899 OpenSSL_DeleteKey(KMF_HANDLE_T handle,
1900 	int numattr, KMF_ATTRIBUTE *attrlist)
1901 {
1902 	KMF_RETURN rv = KMF_OK;
1903 	KMF_KEY_HANDLE *key;
1904 	boolean_t destroy = B_TRUE;
1905 
1906 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
1907 	if (key == NULL || key->keyp == NULL)
1908 		return (KMF_ERR_BAD_PARAMETER);
1909 
1910 	rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
1911 	    (void *)&destroy, NULL);
1912 	if (rv != KMF_OK) {
1913 		/* "destroy" is optional. Default is TRUE */
1914 		rv = KMF_OK;
1915 	}
1916 
1917 	if (key->keyclass != KMF_ASYM_PUB &&
1918 	    key->keyclass != KMF_ASYM_PRI &&
1919 	    key->keyclass != KMF_SYMMETRIC)
1920 		return (KMF_ERR_BAD_KEY_CLASS);
1921 
1922 	if (key->keyclass == KMF_SYMMETRIC) {
1923 		kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp);
1924 		key->keyp = NULL;
1925 	} else {
1926 		if (key->keyp != NULL) {
1927 			EVP_PKEY_free(key->keyp);
1928 			key->keyp = NULL;
1929 		}
1930 	}
1931 
1932 	if (key->keylabel != NULL) {
1933 		EVP_PKEY *pkey = NULL;
1934 		/* If the file exists, make sure it is a proper key. */
1935 		pkey = openssl_load_key(handle, key->keylabel);
1936 		if (pkey == NULL) {
1937 			if (key->keylabel != NULL) {
1938 				free(key->keylabel);
1939 				key->keylabel = NULL;
1940 			}
1941 			return (KMF_ERR_KEY_NOT_FOUND);
1942 		}
1943 		EVP_PKEY_free(pkey);
1944 
1945 		if (destroy) {
1946 			if (unlink(key->keylabel) != 0) {
1947 				KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1948 				SET_SYS_ERROR(kmfh, errno);
1949 				rv = KMF_ERR_INTERNAL;
1950 			}
1951 		}
1952 		if (key->keylabel != NULL) {
1953 			free(key->keylabel);
1954 			key->keylabel = NULL;
1955 		}
1956 	}
1957 	return (rv);
1958 }
1959 
1960 KMF_RETURN
1961 OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
1962 {
1963 	KMF_RETURN ret = KMF_OK;
1964 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1965 	char str[256];	/* OpenSSL needs at least 120 byte buffer */
1966 
1967 	ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str));
1968 	if (strlen(str)) {
1969 		*msgstr = (char *)strdup(str);
1970 		if ((*msgstr) == NULL)
1971 			ret = KMF_ERR_MEMORY;
1972 	} else {
1973 		*msgstr = NULL;
1974 	}
1975 
1976 	return (ret);
1977 }
1978 
1979 static int
1980 ext2NID(int kmfext)
1981 {
1982 	switch (kmfext) {
1983 		case KMF_X509_EXT_KEY_USAGE:
1984 			return (NID_key_usage);
1985 		case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
1986 			return (NID_private_key_usage_period);
1987 		case KMF_X509_EXT_CERT_POLICIES:
1988 			return (NID_certificate_policies);
1989 		case KMF_X509_EXT_SUBJ_ALTNAME:
1990 			return (NID_subject_alt_name);
1991 		case KMF_X509_EXT_ISSUER_ALTNAME:
1992 			return (NID_issuer_alt_name);
1993 		case KMF_X509_EXT_BASIC_CONSTRAINTS:
1994 			return (NID_basic_constraints);
1995 		case KMF_X509_EXT_EXT_KEY_USAGE:
1996 			return (NID_ext_key_usage);
1997 		case KMF_X509_EXT_AUTH_KEY_ID:
1998 			return (NID_authority_key_identifier);
1999 		case KMF_X509_EXT_CRL_DIST_POINTS:
2000 			return (NID_crl_distribution_points);
2001 		case KMF_X509_EXT_SUBJ_KEY_ID:
2002 			return (NID_subject_key_identifier);
2003 		case KMF_X509_EXT_POLICY_MAPPINGS:
2004 			return (OBJ_sn2nid("policyMappings"));
2005 		case KMF_X509_EXT_NAME_CONSTRAINTS:
2006 			return (OBJ_sn2nid("nameConstraints"));
2007 		case KMF_X509_EXT_POLICY_CONSTRAINTS:
2008 			return (OBJ_sn2nid("policyConstraints"));
2009 		case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2010 			return (OBJ_sn2nid("inhibitAnyPolicy"));
2011 		case KMF_X509_EXT_FRESHEST_CRL:
2012 			return (OBJ_sn2nid("freshestCRL"));
2013 		default:
2014 			return (NID_undef);
2015 	}
2016 }
2017 
2018 KMF_RETURN
2019 OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert,
2020 	KMF_PRINTABLE_ITEM flag, char *resultStr)
2021 {
2022 	KMF_RETURN ret = KMF_OK;
2023 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2024 	X509 *xcert = NULL;
2025 	unsigned char *outbuf = NULL;
2026 	unsigned char *outbuf_p;
2027 	char *tmpstr = NULL;
2028 	int j;
2029 	int ext_index, nid, len;
2030 	BIO *mem = NULL;
2031 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2032 	STACK *emlst = NULL;
2033 #else
2034 	STACK_OF(OPENSSL_STRING) *emlst = NULL;
2035 #endif
2036 	X509_EXTENSION *ex;
2037 	X509_CINF *ci;
2038 
2039 	if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) {
2040 		return (KMF_ERR_BAD_PARAMETER);
2041 	}
2042 
2043 	/* copy cert data to outbuf */
2044 	outbuf = malloc(pcert->Length);
2045 	if (outbuf == NULL) {
2046 		return (KMF_ERR_MEMORY);
2047 	}
2048 	(void) memcpy(outbuf, pcert->Data, pcert->Length);
2049 
2050 	outbuf_p = outbuf; /* use a temp pointer; required by openssl */
2051 	xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length);
2052 	if (xcert == NULL) {
2053 		SET_ERROR(kmfh, ERR_get_error());
2054 		ret = KMF_ERR_ENCODING;
2055 		goto out;
2056 	}
2057 
2058 	mem = BIO_new(BIO_s_mem());
2059 	if (mem == NULL) {
2060 		SET_ERROR(kmfh, ERR_get_error());
2061 		ret = KMF_ERR_MEMORY;
2062 		goto out;
2063 	}
2064 
2065 	switch (flag) {
2066 	case KMF_CERT_ISSUER:
2067 		(void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0,
2068 		    XN_FLAG_SEP_CPLUS_SPC);
2069 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2070 		break;
2071 
2072 	case KMF_CERT_SUBJECT:
2073 		(void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0,
2074 		    XN_FLAG_SEP_CPLUS_SPC);
2075 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2076 		break;
2077 
2078 	case KMF_CERT_VERSION:
2079 		tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version);
2080 		(void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN);
2081 		OPENSSL_free(tmpstr);
2082 		len = strlen(resultStr);
2083 		break;
2084 
2085 	case KMF_CERT_SERIALNUM:
2086 		if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) {
2087 			(void) strcpy(resultStr, "0x");
2088 			len = BIO_gets(mem, &resultStr[2],
2089 			    KMF_CERT_PRINTABLE_LEN - 2);
2090 		}
2091 		break;
2092 
2093 	case KMF_CERT_NOTBEFORE:
2094 		(void) ASN1_TIME_print(mem, X509_get_notBefore(xcert));
2095 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2096 		break;
2097 
2098 	case KMF_CERT_NOTAFTER:
2099 		(void) ASN1_TIME_print(mem, X509_get_notAfter(xcert));
2100 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2101 		break;
2102 
2103 	case KMF_CERT_PUBKEY_DATA:
2104 		{
2105 			EVP_PKEY *pkey = X509_get_pubkey(xcert);
2106 			if (pkey == NULL) {
2107 				SET_ERROR(kmfh, ERR_get_error());
2108 				ret = KMF_ERR_ENCODING;
2109 				goto out;
2110 			}
2111 
2112 			if (pkey->type == EVP_PKEY_RSA) {
2113 				(void) BIO_printf(mem,
2114 				    "RSA Public Key: (%d bit)\n",
2115 				    BN_num_bits(pkey->pkey.rsa->n));
2116 				(void) RSA_print(mem, pkey->pkey.rsa, 0);
2117 			} else if (pkey->type == EVP_PKEY_DSA) {
2118 				(void) BIO_printf(mem,
2119 				    "%12sDSA Public Key:\n", "");
2120 				(void) DSA_print(mem, pkey->pkey.dsa, 0);
2121 			} else {
2122 				(void) BIO_printf(mem,
2123 				    "%12sUnknown Public Key:\n", "");
2124 			}
2125 			(void) BIO_printf(mem, "\n");
2126 			EVP_PKEY_free(pkey);
2127 		}
2128 		len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2129 		break;
2130 	case KMF_CERT_SIGNATURE_ALG:
2131 	case KMF_CERT_PUBKEY_ALG:
2132 		if (flag == KMF_CERT_SIGNATURE_ALG) {
2133 			len = i2a_ASN1_OBJECT(mem,
2134 			    xcert->sig_alg->algorithm);
2135 		} else {
2136 			len = i2a_ASN1_OBJECT(mem,
2137 			    xcert->cert_info->key->algor->algorithm);
2138 		}
2139 
2140 		if (len > 0) {
2141 			len = BIO_read(mem, resultStr,
2142 			    KMF_CERT_PRINTABLE_LEN);
2143 		}
2144 		break;
2145 
2146 	case KMF_CERT_EMAIL:
2147 		emlst = X509_get1_email(xcert);
2148 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2149 		for (j = 0; j < sk_num(emlst); j++)
2150 			(void) BIO_printf(mem, "%s\n", sk_value(emlst, j));
2151 #else
2152 		for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
2153 			(void) BIO_printf(mem, "%s\n",
2154 			    sk_OPENSSL_STRING_value(emlst, j));
2155 #endif
2156 
2157 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2158 		X509_email_free(emlst);
2159 		break;
2160 	case KMF_X509_EXT_ISSUER_ALTNAME:
2161 	case KMF_X509_EXT_SUBJ_ALTNAME:
2162 	case KMF_X509_EXT_KEY_USAGE:
2163 	case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
2164 	case KMF_X509_EXT_CERT_POLICIES:
2165 	case KMF_X509_EXT_BASIC_CONSTRAINTS:
2166 	case KMF_X509_EXT_NAME_CONSTRAINTS:
2167 	case KMF_X509_EXT_POLICY_CONSTRAINTS:
2168 	case KMF_X509_EXT_EXT_KEY_USAGE:
2169 	case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2170 	case KMF_X509_EXT_AUTH_KEY_ID:
2171 	case KMF_X509_EXT_SUBJ_KEY_ID:
2172 	case KMF_X509_EXT_POLICY_MAPPINGS:
2173 	case KMF_X509_EXT_CRL_DIST_POINTS:
2174 	case KMF_X509_EXT_FRESHEST_CRL:
2175 		nid = ext2NID(flag);
2176 		if (nid == NID_undef) {
2177 			ret = KMF_ERR_EXTENSION_NOT_FOUND;
2178 			goto out;
2179 		}
2180 		ci = xcert->cert_info;
2181 
2182 		ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1);
2183 		if (ext_index == -1) {
2184 			SET_ERROR(kmfh, ERR_get_error());
2185 
2186 			ret = KMF_ERR_EXTENSION_NOT_FOUND;
2187 			goto out;
2188 		}
2189 		ex = X509v3_get_ext(ci->extensions, ext_index);
2190 
2191 		(void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex));
2192 
2193 		if (BIO_printf(mem, ": %s\n",
2194 		    X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) {
2195 			SET_ERROR(kmfh, ERR_get_error());
2196 			ret = KMF_ERR_ENCODING;
2197 			goto out;
2198 		}
2199 		if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) {
2200 			(void) BIO_printf(mem, "%*s", 4, "");
2201 			(void) M_ASN1_OCTET_STRING_print(mem, ex->value);
2202 		}
2203 		if (BIO_write(mem, "\n", 1) <= 0) {
2204 			SET_ERROR(kmfh, ERR_get_error());
2205 			ret = KMF_ERR_ENCODING;
2206 			goto out;
2207 		}
2208 		len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2209 	}
2210 	if (len <= 0) {
2211 		SET_ERROR(kmfh, ERR_get_error());
2212 		ret = KMF_ERR_ENCODING;
2213 	}
2214 
2215 out:
2216 	if (outbuf != NULL) {
2217 		free(outbuf);
2218 	}
2219 
2220 	if (xcert != NULL) {
2221 		X509_free(xcert);
2222 	}
2223 
2224 	if (mem != NULL) {
2225 		(void) BIO_free(mem);
2226 	}
2227 
2228 	return (ret);
2229 }
2230 
2231 KMF_RETURN
2232 /*ARGSUSED*/
2233 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
2234     KMF_ATTRIBUTE *attrlist)
2235 {
2236 	KMF_RETURN rv = KMF_OK;
2237 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
2238 	KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
2239 	KMF_KEY_HANDLE *key = NULL;
2240 	uint32_t numkeys = 1; /* 1 key only */
2241 	char *dirpath = NULL;
2242 	char *keyfile = NULL;
2243 	KMF_ATTRIBUTE new_attrlist[16];
2244 	int i = 0;
2245 
2246 	/*
2247 	 * This is really just a FindKey operation, reuse the
2248 	 * FindKey function.
2249 	 */
2250 	kmf_set_attr_at_index(new_attrlist, i,
2251 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2252 	i++;
2253 
2254 	kmf_set_attr_at_index(new_attrlist, i,
2255 	    KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t));
2256 	i++;
2257 
2258 	kmf_set_attr_at_index(new_attrlist, i,
2259 	    KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass));
2260 	i++;
2261 
2262 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2263 	if (key == NULL) {
2264 		return (KMF_ERR_BAD_PARAMETER);
2265 	} else {
2266 		kmf_set_attr_at_index(new_attrlist, i,
2267 		    KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
2268 		i++;
2269 	}
2270 
2271 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2272 	if (dirpath != NULL) {
2273 		kmf_set_attr_at_index(new_attrlist, i,
2274 		    KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
2275 		i++;
2276 	}
2277 
2278 	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
2279 	if (keyfile == NULL)
2280 		return (KMF_ERR_BAD_PARAMETER);
2281 	else {
2282 		kmf_set_attr_at_index(new_attrlist, i,
2283 		    KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
2284 		i++;
2285 	}
2286 
2287 	rv = OpenSSL_FindKey(handle, i, new_attrlist);
2288 	return (rv);
2289 }
2290 
2291 KMF_RETURN
2292 /*ARGSUSED*/
2293 OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
2294 	KMF_OID *AlgOID, KMF_DATA *ciphertext,
2295 	KMF_DATA *output)
2296 {
2297 	KMF_RETURN		ret = KMF_OK;
2298 	RSA *rsa = NULL;
2299 	unsigned int in_len = 0, out_len = 0;
2300 	unsigned int total_decrypted = 0, modulus_len = 0;
2301 	uint8_t *in_data, *out_data;
2302 	int i, blocks;
2303 
2304 	if (key == NULL || AlgOID == NULL ||
2305 	    ciphertext == NULL || output == NULL ||
2306 	    ciphertext->Data == NULL ||
2307 	    output->Data == NULL)
2308 		return (KMF_ERR_BAD_PARAMETER);
2309 
2310 	if (key->keyalg == KMF_RSA) {
2311 		rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp);
2312 		modulus_len = RSA_size(rsa);
2313 	} else {
2314 		return (KMF_ERR_BAD_PARAMETER);
2315 	}
2316 
2317 	blocks = ciphertext->Length/modulus_len;
2318 	out_data = output->Data;
2319 	in_data = ciphertext->Data;
2320 	out_len = modulus_len - 11;
2321 	in_len = modulus_len;
2322 
2323 	for (i = 0; i < blocks; i++) {
2324 		out_len  = RSA_private_decrypt(in_len,
2325 		    in_data, out_data, rsa, RSA_PKCS1_PADDING);
2326 
2327 		if (out_len == 0) {
2328 			ret = KMF_ERR_INTERNAL;
2329 			goto cleanup;
2330 		}
2331 
2332 		out_data += out_len;
2333 		total_decrypted += out_len;
2334 		in_data += in_len;
2335 	}
2336 
2337 	output->Length = total_decrypted;
2338 
2339 cleanup:
2340 	RSA_free(rsa);
2341 	if (ret != KMF_OK)
2342 		output->Length = 0;
2343 
2344 	return (ret);
2345 
2346 }
2347 
2348 /*
2349  *  This function will create a certid from issuer_cert and user_cert.
2350  *  The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2351  *  certid memory after use.
2352  */
2353 static KMF_RETURN
2354 create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert,
2355     const KMF_DATA *user_cert, OCSP_CERTID **certid)
2356 {
2357 	KMF_RETURN ret = KMF_OK;
2358 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2359 	X509   *issuer = NULL;
2360 	X509   *cert = NULL;
2361 	unsigned char *ptmp;
2362 
2363 	if (issuer_cert == NULL || user_cert == NULL) {
2364 		return (KMF_ERR_BAD_PARAMETER);
2365 	}
2366 
2367 	/* convert the DER-encoded issuer cert to an internal X509 */
2368 	ptmp = issuer_cert->Data;
2369 	issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2370 	    issuer_cert->Length);
2371 	if (issuer == NULL) {
2372 		SET_ERROR(kmfh, ERR_get_error());
2373 		ret = KMF_ERR_OCSP_BAD_ISSUER;
2374 		goto end;
2375 	}
2376 
2377 	/* convert the DER-encoded user cert to an internal X509 */
2378 	ptmp = user_cert->Data;
2379 	cert = d2i_X509(NULL, (const uchar_t **)&ptmp,
2380 	    user_cert->Length);
2381 	if (cert == NULL) {
2382 		SET_ERROR(kmfh, ERR_get_error());
2383 
2384 		ret = KMF_ERR_OCSP_BAD_CERT;
2385 		goto end;
2386 	}
2387 
2388 	/* create a CERTID */
2389 	*certid = OCSP_cert_to_id(NULL, cert, issuer);
2390 	if (*certid == NULL) {
2391 		SET_ERROR(kmfh, ERR_get_error());
2392 		ret = KMF_ERR_OCSP_CERTID;
2393 		goto end;
2394 	}
2395 
2396 end:
2397 	if (issuer != NULL) {
2398 		X509_free(issuer);
2399 	}
2400 
2401 	if (cert != NULL) {
2402 		X509_free(cert);
2403 	}
2404 
2405 	return (ret);
2406 }
2407 
2408 KMF_RETURN
2409 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle,
2410 	int numattr, KMF_ATTRIBUTE *attrlist)
2411 {
2412 	KMF_RETURN ret = KMF_OK;
2413 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2414 	OCSP_CERTID *id = NULL;
2415 	OCSP_REQUEST *req = NULL;
2416 	BIO *derbio = NULL;
2417 	char *reqfile;
2418 	KMF_DATA *issuer_cert;
2419 	KMF_DATA *user_cert;
2420 
2421 	user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
2422 	    attrlist, numattr);
2423 	if (user_cert == NULL)
2424 		return (KMF_ERR_BAD_PARAMETER);
2425 
2426 	issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
2427 	    attrlist, numattr);
2428 	if (issuer_cert == NULL)
2429 		return (KMF_ERR_BAD_PARAMETER);
2430 
2431 	reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR,
2432 	    attrlist, numattr);
2433 	if (reqfile == NULL)
2434 		return (KMF_ERR_BAD_PARAMETER);
2435 
2436 	ret = create_certid(handle, issuer_cert, user_cert, &id);
2437 	if (ret != KMF_OK) {
2438 		return (ret);
2439 	}
2440 
2441 	/* Create an OCSP request */
2442 	req = OCSP_REQUEST_new();
2443 	if (req == NULL) {
2444 		SET_ERROR(kmfh, ERR_get_error());
2445 		ret = KMF_ERR_OCSP_CREATE_REQUEST;
2446 		goto end;
2447 	}
2448 
2449 	if (!OCSP_request_add0_id(req, id)) {
2450 		ret = KMF_ERR_OCSP_CREATE_REQUEST;
2451 		goto end;
2452 	}
2453 
2454 	/* Write the request to the output file with DER encoding */
2455 	derbio = BIO_new_file(reqfile, "wb");
2456 	if (!derbio) {
2457 		SET_ERROR(kmfh, ERR_get_error());
2458 		ret = KMF_ERR_OPEN_FILE;
2459 		goto end;
2460 	}
2461 	if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) {
2462 		ret = KMF_ERR_ENCODING;
2463 	}
2464 
2465 end:
2466 	/*
2467 	 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2468 	 * will also deallocate certid's space.
2469 	 */
2470 	if (req != NULL) {
2471 		OCSP_REQUEST_free(req);
2472 	}
2473 
2474 	if (derbio != NULL) {
2475 		(void) BIO_free(derbio);
2476 	}
2477 
2478 	return (ret);
2479 }
2480 
2481 /* ocsp_find_signer_sk() is copied from openssl source */
2482 static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
2483 {
2484 	int i;
2485 	unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
2486 
2487 	/* Easy if lookup by name */
2488 	if (id->type == V_OCSP_RESPID_NAME)
2489 		return (X509_find_by_subject(certs, id->value.byName));
2490 
2491 	/* Lookup by key hash */
2492 
2493 	/* If key hash isn't SHA1 length then forget it */
2494 	if (id->value.byKey->length != SHA_DIGEST_LENGTH)
2495 		return (NULL);
2496 
2497 	keyhash = id->value.byKey->data;
2498 	/* Calculate hash of each key and compare */
2499 	for (i = 0; i < sk_X509_num(certs); i++) {
2500 		/* LINTED E_BAD_PTR_CAST_ALIGN */
2501 		X509 *x = sk_X509_value(certs, i);
2502 		/* Use pubkey_digest to get the key ID value */
2503 		(void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
2504 		if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
2505 			return (x);
2506 	}
2507 	return (NULL);
2508 }
2509 
2510 /* ocsp_find_signer() is copied from openssl source */
2511 /* ARGSUSED2 */
2512 static int
2513 ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
2514     X509_STORE *st, unsigned long flags)
2515 {
2516 	X509 *signer;
2517 	OCSP_RESPID *rid = bs->tbsResponseData->responderId;
2518 	if ((signer = ocsp_find_signer_sk(certs, rid)))	{
2519 		*psigner = signer;
2520 		return (2);
2521 	}
2522 	if (!(flags & OCSP_NOINTERN) &&
2523 	    (signer = ocsp_find_signer_sk(bs->certs, rid))) {
2524 		*psigner = signer;
2525 		return (1);
2526 	}
2527 	/* Maybe lookup from store if by subject name */
2528 
2529 	*psigner = NULL;
2530 	return (0);
2531 }
2532 
2533 /*
2534  * This function will verify the signature of a basic response, using
2535  * the public key from the OCSP responder certificate.
2536  */
2537 static KMF_RETURN
2538 check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs,
2539     KMF_DATA *signer_cert, KMF_DATA *issuer_cert)
2540 {
2541 	KMF_RETURN ret = KMF_OK;
2542 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2543 	STACK_OF(X509) *cert_stack = NULL;
2544 	X509 *signer = NULL;
2545 	X509 *issuer = NULL;
2546 	EVP_PKEY *skey = NULL;
2547 	unsigned char *ptmp;
2548 
2549 
2550 	if (bs == NULL || issuer_cert == NULL)
2551 		return (KMF_ERR_BAD_PARAMETER);
2552 
2553 	/*
2554 	 * Find the certificate that signed the basic response.
2555 	 *
2556 	 * If signer_cert is not NULL, we will use that as the signer cert.
2557 	 * Otherwise, we will check if the issuer cert is actually the signer.
2558 	 * If we still do not find a signer, we will look for it from the
2559 	 * certificate list came with the response file.
2560 	 */
2561 	if (signer_cert != NULL) {
2562 		ptmp = signer_cert->Data;
2563 		signer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2564 		    signer_cert->Length);
2565 		if (signer == NULL) {
2566 			SET_ERROR(kmfh, ERR_get_error());
2567 			ret = KMF_ERR_OCSP_BAD_SIGNER;
2568 			goto end;
2569 		}
2570 	} else {
2571 		/*
2572 		 * Convert the issuer cert into X509 and push it into a
2573 		 * stack to be used by ocsp_find_signer().
2574 		 */
2575 		ptmp = issuer_cert->Data;
2576 		issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2577 		    issuer_cert->Length);
2578 		if (issuer == NULL) {
2579 			SET_ERROR(kmfh, ERR_get_error());
2580 			ret = KMF_ERR_OCSP_BAD_ISSUER;
2581 			goto end;
2582 		}
2583 
2584 		if ((cert_stack = sk_X509_new_null()) == NULL) {
2585 			ret = KMF_ERR_INTERNAL;
2586 			goto end;
2587 		}
2588 
2589 		if (sk_X509_push(cert_stack, issuer) == NULL) {
2590 			ret = KMF_ERR_INTERNAL;
2591 			goto end;
2592 		}
2593 
2594 		ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0);
2595 		if (!ret) {
2596 			/* can not find the signer */
2597 			ret = KMF_ERR_OCSP_BAD_SIGNER;
2598 			goto end;
2599 		}
2600 	}
2601 
2602 	/* Verify the signature of the response */
2603 	skey = X509_get_pubkey(signer);
2604 	if (skey == NULL) {
2605 		ret = KMF_ERR_OCSP_BAD_SIGNER;
2606 		goto end;
2607 	}
2608 
2609 	ret = OCSP_BASICRESP_verify(bs, skey, 0);
2610 	if (ret == 0) {
2611 		ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE;
2612 		goto end;
2613 	}
2614 
2615 end:
2616 	if (issuer != NULL) {
2617 		X509_free(issuer);
2618 	}
2619 
2620 	if (signer != NULL) {
2621 		X509_free(signer);
2622 	}
2623 
2624 	if (skey != NULL) {
2625 		EVP_PKEY_free(skey);
2626 	}
2627 
2628 	if (cert_stack != NULL) {
2629 		sk_X509_free(cert_stack);
2630 	}
2631 
2632 	return (ret);
2633 }
2634 
2635 
2636 
2637 KMF_RETURN
2638 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,
2639 	int numattr, KMF_ATTRIBUTE *attrlist)
2640 {
2641 	KMF_RETURN ret = KMF_OK;
2642 	BIO *derbio = NULL;
2643 	OCSP_RESPONSE *resp = NULL;
2644 	OCSP_BASICRESP *bs = NULL;
2645 	OCSP_CERTID *id = NULL;
2646 	OCSP_SINGLERESP *single = NULL;
2647 	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
2648 	int index, status, reason;
2649 	KMF_DATA *issuer_cert;
2650 	KMF_DATA *user_cert;
2651 	KMF_DATA *signer_cert;
2652 	KMF_DATA *response;
2653 	int *response_reason, *response_status, *cert_status;
2654 	boolean_t ignore_response_sign = B_FALSE;	/* default is FALSE */
2655 	uint32_t response_lifetime;
2656 
2657 	issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
2658 	    attrlist, numattr);
2659 	if (issuer_cert == NULL)
2660 		return (KMF_ERR_BAD_PARAMETER);
2661 
2662 	user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
2663 	    attrlist, numattr);
2664 	if (user_cert == NULL)
2665 		return (KMF_ERR_BAD_PARAMETER);
2666 
2667 	response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR,
2668 	    attrlist, numattr);
2669 	if (response == NULL)
2670 		return (KMF_ERR_BAD_PARAMETER);
2671 
2672 	response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR,
2673 	    attrlist, numattr);
2674 	if (response_status == NULL)
2675 		return (KMF_ERR_BAD_PARAMETER);
2676 
2677 	response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR,
2678 	    attrlist, numattr);
2679 	if (response_reason == NULL)
2680 		return (KMF_ERR_BAD_PARAMETER);
2681 
2682 	cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR,
2683 	    attrlist, numattr);
2684 	if (cert_status == NULL)
2685 		return (KMF_ERR_BAD_PARAMETER);
2686 
2687 	/* Read in the response */
2688 	derbio = BIO_new_mem_buf(response->Data, response->Length);
2689 	if (!derbio) {
2690 		ret = KMF_ERR_MEMORY;
2691 		return (ret);
2692 	}
2693 
2694 	resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
2695 	if (resp == NULL) {
2696 		ret = KMF_ERR_OCSP_MALFORMED_RESPONSE;
2697 		goto end;
2698 	}
2699 
2700 	/* Check the response status */
2701 	status = OCSP_response_status(resp);
2702 	*response_status = status;
2703 	if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
2704 		ret = KMF_ERR_OCSP_RESPONSE_STATUS;
2705 		goto end;
2706 	}
2707 
2708 #ifdef DEBUG
2709 	printf("Successfully checked the response file status.\n");
2710 #endif /* DEBUG */
2711 
2712 	/* Extract basic response */
2713 	bs = OCSP_response_get1_basic(resp);
2714 	if (bs == NULL) {
2715 		ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE;
2716 		goto end;
2717 	}
2718 
2719 #ifdef DEBUG
2720 	printf("Successfully retrieved the basic response.\n");
2721 #endif /* DEBUG */
2722 
2723 	/* Check the basic response signature if required */
2724 	ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr,
2725 	    (void *)&ignore_response_sign, NULL);
2726 	if (ret != KMF_OK)
2727 		ret = KMF_OK;
2728 
2729 	signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR,
2730 	    attrlist, numattr);
2731 
2732 	if (ignore_response_sign == B_FALSE) {
2733 		ret = check_response_signature(handle, bs,
2734 		    signer_cert, issuer_cert);
2735 		if (ret != KMF_OK)
2736 			goto end;
2737 	}
2738 
2739 #ifdef DEBUG
2740 	printf("Successfully verified the response signature.\n");
2741 #endif /* DEBUG */
2742 
2743 	/* Create a certid for the certificate in question */
2744 	ret = create_certid(handle, issuer_cert, user_cert, &id);
2745 	if (ret != KMF_OK) {
2746 		ret = KMF_ERR_OCSP_CERTID;
2747 		goto end;
2748 	}
2749 
2750 #ifdef DEBUG
2751 	printf("successfully created a certid for the cert.\n");
2752 #endif /* DEBUG */
2753 
2754 	/* Find the index of the single response for the certid */
2755 	index = OCSP_resp_find(bs, id, -1);
2756 	if (index < 0) {
2757 		/* cound not find this certificate in the response */
2758 		ret = KMF_ERR_OCSP_UNKNOWN_CERT;
2759 		goto end;
2760 	}
2761 
2762 #ifdef DEBUG
2763 	printf("Successfully found the single response index for the cert.\n");
2764 #endif /* DEBUG */
2765 
2766 	/* Retrieve the single response and get the cert status */
2767 	single = OCSP_resp_get0(bs, index);
2768 	status = OCSP_single_get0_status(single, &reason, &rev, &thisupd,
2769 	    &nextupd);
2770 	if (status == V_OCSP_CERTSTATUS_GOOD) {
2771 		*cert_status = OCSP_GOOD;
2772 	} else if (status == V_OCSP_CERTSTATUS_UNKNOWN) {
2773 		*cert_status = OCSP_UNKNOWN;
2774 	} else { /* revoked */
2775 		*cert_status = OCSP_REVOKED;
2776 		*response_reason = reason;
2777 	}
2778 	ret = KMF_OK;
2779 
2780 	/* resp. time is optional, so we don't care about the return code. */
2781 	(void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr,
2782 	    (void *)&response_lifetime, NULL);
2783 
2784 	if (!OCSP_check_validity(thisupd, nextupd, 300,
2785 	    response_lifetime)) {
2786 		ret = KMF_ERR_OCSP_STATUS_TIME_INVALID;
2787 		goto end;
2788 	}
2789 
2790 #ifdef DEBUG
2791 	printf("Successfully verify the time.\n");
2792 #endif /* DEBUG */
2793 
2794 end:
2795 	if (derbio != NULL)
2796 		(void) BIO_free(derbio);
2797 
2798 	if (resp != NULL)
2799 		OCSP_RESPONSE_free(resp);
2800 
2801 	if (bs != NULL)
2802 		OCSP_BASICRESP_free(bs);
2803 
2804 	if (id != NULL)
2805 		OCSP_CERTID_free(id);
2806 
2807 	return (ret);
2808 }
2809 
2810 static KMF_RETURN
2811 fetch_key(KMF_HANDLE_T handle, char *path,
2812 	KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key)
2813 {
2814 	KMF_RETURN rv = KMF_OK;
2815 	EVP_PKEY *pkey = NULL;
2816 	KMF_RAW_SYM_KEY *rkey = NULL;
2817 
2818 	if (keyclass == KMF_ASYM_PRI ||
2819 	    keyclass == KMF_ASYM_PUB) {
2820 		pkey = openssl_load_key(handle, path);
2821 		if (pkey == NULL) {
2822 			return (KMF_ERR_KEY_NOT_FOUND);
2823 		}
2824 		if (key != NULL) {
2825 			if (pkey->type == EVP_PKEY_RSA)
2826 				key->keyalg = KMF_RSA;
2827 			else if (pkey->type == EVP_PKEY_DSA)
2828 				key->keyalg = KMF_DSA;
2829 
2830 			key->kstype = KMF_KEYSTORE_OPENSSL;
2831 			key->keyclass = keyclass;
2832 			key->keyp = (void *)pkey;
2833 			key->israw = FALSE;
2834 			if (path != NULL &&
2835 			    ((key->keylabel = strdup(path)) == NULL)) {
2836 				EVP_PKEY_free(pkey);
2837 				return (KMF_ERR_MEMORY);
2838 			}
2839 		} else {
2840 			EVP_PKEY_free(pkey);
2841 			pkey = NULL;
2842 		}
2843 	} else if (keyclass == KMF_SYMMETRIC) {
2844 		KMF_ENCODE_FORMAT fmt;
2845 		/*
2846 		 * If the file is a recognized format,
2847 		 * then it is NOT a symmetric key.
2848 		 */
2849 		rv = kmf_get_file_format(path, &fmt);
2850 		if (rv == KMF_OK || fmt != 0) {
2851 			return (KMF_ERR_KEY_NOT_FOUND);
2852 		} else if (rv == KMF_ERR_ENCODING) {
2853 			/*
2854 			 * If we don't know the encoding,
2855 			 * it is probably  a symmetric key.
2856 			 */
2857 			rv = KMF_OK;
2858 		} else if (rv == KMF_ERR_OPEN_FILE) {
2859 			return (KMF_ERR_KEY_NOT_FOUND);
2860 		}
2861 
2862 		if (key != NULL) {
2863 			KMF_DATA keyvalue;
2864 			rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
2865 			if (rkey == NULL) {
2866 				rv = KMF_ERR_MEMORY;
2867 				goto out;
2868 			}
2869 
2870 			(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
2871 			rv = kmf_read_input_file(handle, path, &keyvalue);
2872 			if (rv != KMF_OK)
2873 				goto out;
2874 
2875 			rkey->keydata.len = keyvalue.Length;
2876 			rkey->keydata.val = keyvalue.Data;
2877 
2878 			key->kstype = KMF_KEYSTORE_OPENSSL;
2879 			key->keyclass = keyclass;
2880 			key->israw = TRUE;
2881 			key->keyp = (void *)rkey;
2882 			if (path != NULL &&
2883 			    ((key->keylabel = strdup(path)) == NULL)) {
2884 				rv = KMF_ERR_MEMORY;
2885 			}
2886 		}
2887 	}
2888 out:
2889 	if (rv != KMF_OK) {
2890 		if (rkey != NULL) {
2891 			kmf_free_raw_sym_key(rkey);
2892 		}
2893 		if (pkey != NULL)
2894 			EVP_PKEY_free(pkey);
2895 
2896 		if (key != NULL) {
2897 			key->keyalg = KMF_KEYALG_NONE;
2898 			key->keyclass = KMF_KEYCLASS_NONE;
2899 			key->keyp = NULL;
2900 		}
2901 	}
2902 
2903 	return (rv);
2904 }
2905 
2906 KMF_RETURN
2907 OpenSSL_FindKey(KMF_HANDLE_T handle,
2908 	int numattr, KMF_ATTRIBUTE *attrlist)
2909 {
2910 	KMF_RETURN rv = KMF_OK;
2911 	char *fullpath = NULL;
2912 	uint32_t maxkeys;
2913 	KMF_KEY_HANDLE *key;
2914 	uint32_t *numkeys;
2915 	KMF_KEY_CLASS keyclass;
2916 	KMF_RAW_KEY_DATA *rawkey;
2917 	char *dirpath;
2918 	char *keyfile;
2919 
2920 	if (handle == NULL)
2921 		return (KMF_ERR_BAD_PARAMETER);
2922 
2923 	numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
2924 	if (numkeys == NULL)
2925 		return (KMF_ERR_BAD_PARAMETER);
2926 
2927 	rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
2928 	    (void *)&keyclass, NULL);
2929 	if (rv != KMF_OK)
2930 		return (KMF_ERR_BAD_PARAMETER);
2931 
2932 	if (keyclass != KMF_ASYM_PUB &&
2933 	    keyclass != KMF_ASYM_PRI &&
2934 	    keyclass != KMF_SYMMETRIC)
2935 		return (KMF_ERR_BAD_KEY_CLASS);
2936 
2937 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2938 	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
2939 
2940 	fullpath = get_fullpath(dirpath, keyfile);
2941 
2942 	if (fullpath == NULL)
2943 		return (KMF_ERR_BAD_PARAMETER);
2944 
2945 	maxkeys = *numkeys;
2946 	if (maxkeys == 0)
2947 		maxkeys = 0xFFFFFFFF;
2948 	*numkeys = 0;
2949 
2950 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2951 	/* it is okay to have "keys" contains NULL */
2952 
2953 	/*
2954 	 * The caller may want a list of the raw key data as well.
2955 	 * Useful for importing keys from a file into other keystores.
2956 	 */
2957 	rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
2958 
2959 	if (isdir(fullpath)) {
2960 		DIR *dirp;
2961 		struct dirent *dp;
2962 		int n = 0;
2963 
2964 		/* open all files in the directory and attempt to read them */
2965 		if ((dirp = opendir(fullpath)) == NULL) {
2966 			return (KMF_ERR_BAD_PARAMETER);
2967 		}
2968 		rewinddir(dirp);
2969 		while ((dp = readdir(dirp)) != NULL && n < maxkeys) {
2970 			if (strcmp(dp->d_name, ".") &&
2971 			    strcmp(dp->d_name, "..")) {
2972 				char *fname;
2973 
2974 				fname = get_fullpath(fullpath,
2975 				    (char *)&dp->d_name);
2976 
2977 				rv = fetch_key(handle, fname,
2978 				    keyclass, key ? &key[n] : NULL);
2979 
2980 				if (rv == KMF_OK) {
2981 					if (key != NULL && rawkey != NULL)
2982 						rv = convertToRawKey(
2983 						    key[n].keyp, &rawkey[n]);
2984 					n++;
2985 				}
2986 
2987 				if (rv != KMF_OK || key == NULL)
2988 					free(fname);
2989 			}
2990 		}
2991 		(void) closedir(dirp);
2992 		free(fullpath);
2993 		(*numkeys) = n;
2994 	} else {
2995 		rv = fetch_key(handle, fullpath, keyclass, key);
2996 		if (rv == KMF_OK)
2997 			(*numkeys) = 1;
2998 
2999 		if (rv != KMF_OK || key == NULL)
3000 			free(fullpath);
3001 
3002 		if (rv == KMF_OK && key != NULL && rawkey != NULL) {
3003 			rv = convertToRawKey(key->keyp, rawkey);
3004 		}
3005 	}
3006 
3007 	if (rv == KMF_OK && (*numkeys) == 0)
3008 		rv = KMF_ERR_KEY_NOT_FOUND;
3009 	else if (rv == KMF_ERR_KEY_NOT_FOUND && (*numkeys) > 0)
3010 		rv = KMF_OK;
3011 
3012 	return (rv);
3013 }
3014 
3015 #define	HANDLE_PK12_ERROR { \
3016 	SET_ERROR(kmfh, ERR_get_error()); \
3017 	rv = KMF_ERR_ENCODING; \
3018 	goto out; \
3019 }
3020 
3021 static int
3022 add_alias_to_bag(PKCS12_SAFEBAG *bag, X509 *xcert)
3023 {
3024 	if (xcert != NULL && xcert->aux != NULL &&
3025 	    xcert->aux->alias != NULL) {
3026 		if (PKCS12_add_friendlyname_asc(bag,
3027 		    (const char *)xcert->aux->alias->data,
3028 		    xcert->aux->alias->length) == 0)
3029 			return (0);
3030 	}
3031 	return (1);
3032 }
3033 
3034 static PKCS7 *
3035 add_cert_to_safe(X509 *sslcert, KMF_CREDENTIAL *cred,
3036 	uchar_t *keyid, unsigned int keyidlen)
3037 {
3038 	PKCS12_SAFEBAG *bag = NULL;
3039 	PKCS7 *cert_authsafe = NULL;
3040 	STACK_OF(PKCS12_SAFEBAG) *bag_stack;
3041 
3042 	bag_stack = sk_PKCS12_SAFEBAG_new_null();
3043 	if (bag_stack == NULL)
3044 		return (NULL);
3045 
3046 	/* Convert cert from X509 struct to PKCS#12 bag */
3047 	bag = PKCS12_x5092certbag(sslcert);
3048 	if (bag == NULL) {
3049 		goto out;
3050 	}
3051 
3052 	/* Add the key id to the certificate bag. */
3053 	if (keyidlen > 0 && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
3054 		goto out;
3055 	}
3056 
3057 	if (!add_alias_to_bag(bag, sslcert))
3058 		goto out;
3059 
3060 	/* Pile it on the bag_stack. */
3061 	if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
3062 		goto out;
3063 	}
3064 	/* Turn bag_stack of certs into encrypted authsafe. */
3065 	cert_authsafe = PKCS12_pack_p7encdata(
3066 	    NID_pbe_WithSHA1And40BitRC2_CBC,
3067 	    cred->cred, cred->credlen, NULL, 0,
3068 	    PKCS12_DEFAULT_ITER, bag_stack);
3069 
3070 out:
3071 	if (bag_stack != NULL)
3072 		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3073 
3074 	return (cert_authsafe);
3075 }
3076 
3077 static PKCS7 *
3078 add_key_to_safe(EVP_PKEY *pkey, KMF_CREDENTIAL *cred,
3079 	uchar_t *keyid,  unsigned int keyidlen,
3080 	char *label, int label_len)
3081 {
3082 	PKCS8_PRIV_KEY_INFO *p8 = NULL;
3083 	STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL;
3084 	PKCS12_SAFEBAG *bag = NULL;
3085 	PKCS7 *key_authsafe = NULL;
3086 
3087 	p8 = EVP_PKEY2PKCS8(pkey);
3088 	if (p8 == NULL) {
3089 		return (NULL);
3090 	}
3091 	/* Put the shrouded key into a PKCS#12 bag. */
3092 	bag = PKCS12_MAKE_SHKEYBAG(
3093 	    NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
3094 	    cred->cred, cred->credlen,
3095 	    NULL, 0, PKCS12_DEFAULT_ITER, p8);
3096 
3097 	/* Clean up the PKCS#8 shrouded key, don't need it now. */
3098 	PKCS8_PRIV_KEY_INFO_free(p8);
3099 	p8 = NULL;
3100 
3101 	if (bag == NULL) {
3102 		return (NULL);
3103 	}
3104 	if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
3105 		goto out;
3106 	if (label != NULL && !PKCS12_add_friendlyname(bag, label, label_len))
3107 		goto out;
3108 
3109 	/* Start a PKCS#12 safebag container for the private key. */
3110 	bag_stack = sk_PKCS12_SAFEBAG_new_null();
3111 	if (bag_stack == NULL)
3112 		goto out;
3113 
3114 	/* Pile on the private key on the bag_stack. */
3115 	if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag))
3116 		goto out;
3117 
3118 	key_authsafe = PKCS12_pack_p7data(bag_stack);
3119 
3120 out:
3121 	if (bag_stack != NULL)
3122 		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3123 	bag_stack = NULL;
3124 	return (key_authsafe);
3125 }
3126 
3127 static EVP_PKEY *
3128 ImportRawRSAKey(KMF_RAW_RSA_KEY *key)
3129 {
3130 	RSA		*rsa = NULL;
3131 	EVP_PKEY 	*newkey = NULL;
3132 
3133 	if ((rsa = RSA_new()) == NULL)
3134 		return (NULL);
3135 
3136 	if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL)
3137 		return (NULL);
3138 
3139 	if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) ==
3140 	    NULL)
3141 		return (NULL);
3142 
3143 	if (key->priexp.val != NULL)
3144 		if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len,
3145 		    rsa->d)) == NULL)
3146 			return (NULL);
3147 
3148 	if (key->prime1.val != NULL)
3149 		if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len,
3150 		    rsa->p)) == NULL)
3151 			return (NULL);
3152 
3153 	if (key->prime2.val != NULL)
3154 		if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len,
3155 		    rsa->q)) == NULL)
3156 			return (NULL);
3157 
3158 	if (key->exp1.val != NULL)
3159 		if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len,
3160 		    rsa->dmp1)) == NULL)
3161 			return (NULL);
3162 
3163 	if (key->exp2.val != NULL)
3164 		if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len,
3165 		    rsa->dmq1)) == NULL)
3166 			return (NULL);
3167 
3168 	if (key->coef.val != NULL)
3169 		if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len,
3170 		    rsa->iqmp)) == NULL)
3171 			return (NULL);
3172 
3173 	if ((newkey = EVP_PKEY_new()) == NULL)
3174 		return (NULL);
3175 
3176 	(void) EVP_PKEY_set1_RSA(newkey, rsa);
3177 
3178 	/* The original key must be freed once here or it leaks memory */
3179 	RSA_free(rsa);
3180 
3181 	return (newkey);
3182 }
3183 
3184 static EVP_PKEY *
3185 ImportRawDSAKey(KMF_RAW_DSA_KEY *key)
3186 {
3187 	DSA		*dsa = NULL;
3188 	EVP_PKEY 	*newkey = NULL;
3189 
3190 	if ((dsa = DSA_new()) == NULL)
3191 		return (NULL);
3192 
3193 	if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len,
3194 	    dsa->p)) == NULL)
3195 		return (NULL);
3196 
3197 	if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len,
3198 	    dsa->q)) == NULL)
3199 		return (NULL);
3200 
3201 	if ((dsa->g = BN_bin2bn(key->base.val, key->base.len,
3202 	    dsa->g)) == NULL)
3203 		return (NULL);
3204 
3205 	if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len,
3206 	    dsa->priv_key)) == NULL)
3207 		return (NULL);
3208 
3209 	if (key->pubvalue.val != NULL) {
3210 		if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val,
3211 		    key->pubvalue.len, dsa->pub_key)) == NULL)
3212 			return (NULL);
3213 	}
3214 
3215 	if ((newkey = EVP_PKEY_new()) == NULL)
3216 		return (NULL);
3217 
3218 	(void) EVP_PKEY_set1_DSA(newkey, dsa);
3219 
3220 	/* The original key must be freed once here or it leaks memory */
3221 	DSA_free(dsa);
3222 	return (newkey);
3223 }
3224 
3225 static EVP_PKEY *
3226 raw_key_to_pkey(KMF_KEY_HANDLE *key)
3227 {
3228 	EVP_PKEY *pkey = NULL;
3229 	KMF_RAW_KEY_DATA *rawkey;
3230 	ASN1_TYPE *attr = NULL;
3231 	KMF_RETURN ret;
3232 
3233 	if (key == NULL || !key->israw)
3234 		return (NULL);
3235 
3236 	rawkey = (KMF_RAW_KEY_DATA *)key->keyp;
3237 	if (rawkey->keytype == KMF_RSA) {
3238 		pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
3239 	} else if (rawkey->keytype == KMF_DSA) {
3240 		pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
3241 	} else if (rawkey->keytype == KMF_ECDSA) {
3242 		/*
3243 		 * OpenSSL in Solaris does not support EC for
3244 		 * legal reasons
3245 		 */
3246 		return (NULL);
3247 	} else {
3248 		/* wrong kind of key */
3249 		return (NULL);
3250 	}
3251 
3252 	if (rawkey->label != NULL) {
3253 		if ((attr = ASN1_TYPE_new()) == NULL) {
3254 			EVP_PKEY_free(pkey);
3255 			return (NULL);
3256 		}
3257 		attr->value.bmpstring = ASN1_STRING_type_new(V_ASN1_BMPSTRING);
3258 		(void) ASN1_STRING_set(attr->value.bmpstring, rawkey->label,
3259 		    strlen(rawkey->label));
3260 		attr->type = V_ASN1_BMPSTRING;
3261 		attr->value.ptr = (char *)attr->value.bmpstring;
3262 		ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
3263 		if (ret != KMF_OK) {
3264 			EVP_PKEY_free(pkey);
3265 			ASN1_TYPE_free(attr);
3266 			return (NULL);
3267 		}
3268 	}
3269 	if (rawkey->id.Data != NULL) {
3270 		if ((attr = ASN1_TYPE_new()) == NULL) {
3271 			EVP_PKEY_free(pkey);
3272 			return (NULL);
3273 		}
3274 		attr->value.octet_string =
3275 		    ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
3276 		attr->type = V_ASN1_OCTET_STRING;
3277 		(void) ASN1_STRING_set(attr->value.octet_string,
3278 		    rawkey->id.Data, rawkey->id.Length);
3279 		attr->value.ptr = (char *)attr->value.octet_string;
3280 		ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
3281 		if (ret != KMF_OK) {
3282 			EVP_PKEY_free(pkey);
3283 			ASN1_TYPE_free(attr);
3284 			return (NULL);
3285 		}
3286 	}
3287 	return (pkey);
3288 }
3289 
3290 /*
3291  * Search a list of private keys to find one that goes with the certificate.
3292  */
3293 static EVP_PKEY *
3294 find_matching_key(X509 *xcert, int numkeys, KMF_KEY_HANDLE *keylist)
3295 {
3296 	int i;
3297 	EVP_PKEY *pkey = NULL;
3298 
3299 	if (numkeys == 0 || keylist == NULL || xcert == NULL)
3300 		return (NULL);
3301 	for (i = 0; i < numkeys; i++) {
3302 		if (keylist[i].israw)
3303 			pkey = raw_key_to_pkey(&keylist[i]);
3304 		else
3305 			pkey = (EVP_PKEY *)keylist[i].keyp;
3306 		if (pkey != NULL) {
3307 			if (X509_check_private_key(xcert, pkey)) {
3308 				return (pkey);
3309 			} else {
3310 				EVP_PKEY_free(pkey);
3311 				pkey = NULL;
3312 			}
3313 		}
3314 	}
3315 	return (pkey);
3316 }
3317 
3318 static KMF_RETURN
3319 local_export_pk12(KMF_HANDLE_T handle,
3320 	KMF_CREDENTIAL *cred,
3321 	int numcerts, KMF_X509_DER_CERT *certlist,
3322 	int numkeys, KMF_KEY_HANDLE *keylist,
3323 	char *filename)
3324 {
3325 	KMF_RETURN rv = KMF_OK;
3326 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3327 	BIO *bio = NULL;
3328 	PKCS7 *cert_authsafe = NULL;
3329 	PKCS7 *key_authsafe = NULL;
3330 	STACK_OF(PKCS7) *authsafe_stack = NULL;
3331 	PKCS12 *p12_elem = NULL;
3332 	int i;
3333 
3334 	if (numcerts == 0 && numkeys == 0)
3335 		return (KMF_ERR_BAD_PARAMETER);
3336 
3337 	/*
3338 	 * Open the output file.
3339 	 */
3340 	if ((bio = BIO_new_file(filename, "wb")) == NULL) {
3341 		SET_ERROR(kmfh, ERR_get_error());
3342 		rv = KMF_ERR_OPEN_FILE;
3343 		goto cleanup;
3344 	}
3345 
3346 	/* Start a PKCS#7 stack. */
3347 	authsafe_stack = sk_PKCS7_new_null();
3348 	if (authsafe_stack == NULL) {
3349 		rv = KMF_ERR_MEMORY;
3350 		goto cleanup;
3351 	}
3352 	if (numcerts > 0) {
3353 		for (i = 0; rv == KMF_OK && i < numcerts; i++) {
3354 			const uchar_t *p = certlist[i].certificate.Data;
3355 			long len = certlist[i].certificate.Length;
3356 			X509 *xcert = NULL;
3357 			EVP_PKEY *pkey = NULL;
3358 			unsigned char keyid[EVP_MAX_MD_SIZE];
3359 			unsigned int keyidlen = 0;
3360 
3361 			xcert = d2i_X509(NULL, &p, len);
3362 			if (xcert == NULL) {
3363 				SET_ERROR(kmfh, ERR_get_error());
3364 				rv = KMF_ERR_ENCODING;
3365 			}
3366 			if (certlist[i].kmf_private.label != NULL) {
3367 				/* Set alias attribute */
3368 				(void) X509_alias_set1(xcert,
3369 				    (uchar_t *)certlist[i].kmf_private.label,
3370 				    strlen(certlist[i].kmf_private.label));
3371 			}
3372 			/* Check if there is a key corresponding to this cert */
3373 			pkey = find_matching_key(xcert, numkeys, keylist);
3374 
3375 			/*
3376 			 * If key is found, get fingerprint and create a
3377 			 * safebag.
3378 			 */
3379 			if (pkey != NULL) {
3380 				(void) X509_digest(xcert, EVP_sha1(),
3381 				    keyid, &keyidlen);
3382 				key_authsafe = add_key_to_safe(pkey, cred,
3383 				    keyid, keyidlen,
3384 				    certlist[i].kmf_private.label,
3385 				    (certlist[i].kmf_private.label ?
3386 				    strlen(certlist[i].kmf_private.label) : 0));
3387 
3388 				if (key_authsafe == NULL) {
3389 					X509_free(xcert);
3390 					EVP_PKEY_free(pkey);
3391 					goto cleanup;
3392 				}
3393 				/* Put the key safe into the Auth Safe */
3394 				if (!sk_PKCS7_push(authsafe_stack,
3395 				    key_authsafe)) {
3396 					X509_free(xcert);
3397 					EVP_PKEY_free(pkey);
3398 					goto cleanup;
3399 				}
3400 			}
3401 
3402 			/* create a certificate safebag */
3403 			cert_authsafe = add_cert_to_safe(xcert, cred, keyid,
3404 			    keyidlen);
3405 			if (cert_authsafe == NULL) {
3406 				X509_free(xcert);
3407 				EVP_PKEY_free(pkey);
3408 				goto cleanup;
3409 			}
3410 			if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) {
3411 				X509_free(xcert);
3412 				EVP_PKEY_free(pkey);
3413 				goto cleanup;
3414 			}
3415 
3416 			X509_free(xcert);
3417 			if (pkey)
3418 				EVP_PKEY_free(pkey);
3419 		}
3420 	} else if (numcerts == 0 && numkeys > 0) {
3421 		/*
3422 		 * If only adding keys to the file.
3423 		 */
3424 		for (i = 0; i < numkeys; i++) {
3425 			EVP_PKEY *pkey = NULL;
3426 
3427 			if (keylist[i].israw)
3428 				pkey = raw_key_to_pkey(&keylist[i]);
3429 			else
3430 				pkey = (EVP_PKEY *)keylist[i].keyp;
3431 
3432 			if (pkey == NULL)
3433 				continue;
3434 
3435 			key_authsafe = add_key_to_safe(pkey, cred,
3436 			    NULL, 0, NULL, 0);
3437 
3438 			if (key_authsafe == NULL) {
3439 				EVP_PKEY_free(pkey);
3440 				goto cleanup;
3441 			}
3442 			if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) {
3443 				EVP_PKEY_free(pkey);
3444 				goto cleanup;
3445 			}
3446 		}
3447 	}
3448 	p12_elem = PKCS12_init(NID_pkcs7_data);
3449 	if (p12_elem == NULL) {
3450 		goto cleanup;
3451 	}
3452 
3453 	/* Put the PKCS#7 stack into the PKCS#12 element. */
3454 	if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) {
3455 		goto cleanup;
3456 	}
3457 
3458 	/* Set the integrity MAC on the PKCS#12 element. */
3459 	if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen,
3460 	    NULL, 0, PKCS12_DEFAULT_ITER, NULL)) {
3461 		goto cleanup;
3462 	}
3463 
3464 	/* Write the PKCS#12 element to the export file. */
3465 	if (!i2d_PKCS12_bio(bio, p12_elem)) {
3466 		goto cleanup;
3467 	}
3468 	PKCS12_free(p12_elem);
3469 
3470 cleanup:
3471 	/* Clear away the PKCS#7 stack, we're done with it. */
3472 	if (authsafe_stack)
3473 		sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
3474 
3475 	if (bio != NULL)
3476 		(void) BIO_free_all(bio);
3477 
3478 	return (rv);
3479 }
3480 
3481 KMF_RETURN
3482 openssl_build_pk12(KMF_HANDLE_T handle, int numcerts,
3483     KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist,
3484     KMF_CREDENTIAL *p12cred, char *filename)
3485 {
3486 	KMF_RETURN rv;
3487 
3488 	if (certlist == NULL && keylist == NULL)
3489 		return (KMF_ERR_BAD_PARAMETER);
3490 
3491 	rv = local_export_pk12(handle, p12cred, numcerts, certlist,
3492 	    numkeys, keylist, filename);
3493 
3494 	return (rv);
3495 }
3496 
3497 KMF_RETURN
3498 OpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
3499 {
3500 	KMF_RETURN rv;
3501 	KMF_HANDLE *kmfh = (KMF_HANDLE  *)handle;
3502 	char *fullpath = NULL;
3503 	char *dirpath = NULL;
3504 	char *certfile = NULL;
3505 	char *keyfile = NULL;
3506 	char *filename = NULL;
3507 	KMF_CREDENTIAL *p12cred = NULL;
3508 	KMF_X509_DER_CERT certdata;
3509 	KMF_KEY_HANDLE key;
3510 	int gotkey = 0;
3511 	int gotcert = 0;
3512 
3513 	if (handle == NULL)
3514 		return (KMF_ERR_BAD_PARAMETER);
3515 
3516 	/*
3517 	 *  First, find the certificate.
3518 	 */
3519 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
3520 	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
3521 	if (certfile != NULL) {
3522 		fullpath = get_fullpath(dirpath, certfile);
3523 		if (fullpath == NULL)
3524 			return (KMF_ERR_BAD_PARAMETER);
3525 
3526 		if (isdir(fullpath)) {
3527 			free(fullpath);
3528 			return (KMF_ERR_AMBIGUOUS_PATHNAME);
3529 		}
3530 
3531 		(void) memset(&certdata, 0, sizeof (certdata));
3532 		rv = kmf_load_cert(kmfh, NULL, NULL, NULL, NULL,
3533 		    fullpath, &certdata.certificate);
3534 		if (rv != KMF_OK)
3535 			goto end;
3536 
3537 		gotcert++;
3538 		certdata.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
3539 		free(fullpath);
3540 	}
3541 
3542 	/*
3543 	 * Now find the private key.
3544 	 */
3545 	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
3546 	if (keyfile != NULL) {
3547 		fullpath = get_fullpath(dirpath, keyfile);
3548 		if (fullpath == NULL)
3549 			return (KMF_ERR_BAD_PARAMETER);
3550 
3551 		if (isdir(fullpath)) {
3552 			free(fullpath);
3553 			return (KMF_ERR_AMBIGUOUS_PATHNAME);
3554 		}
3555 
3556 		(void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
3557 		rv = fetch_key(handle, fullpath, KMF_ASYM_PRI, &key);
3558 		if (rv != KMF_OK)
3559 			goto end;
3560 		gotkey++;
3561 	}
3562 
3563 	/*
3564 	 * Open the output file.
3565 	 */
3566 	filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
3567 	    numattr);
3568 	if (filename == NULL) {
3569 		rv = KMF_ERR_BAD_PARAMETER;
3570 		goto end;
3571 	}
3572 
3573 	/* Stick the key and the cert into a PKCS#12 file */
3574 	p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
3575 	if (p12cred == NULL) {
3576 		rv = KMF_ERR_BAD_PARAMETER;
3577 		goto end;
3578 	}
3579 
3580 	rv = local_export_pk12(handle, p12cred, 1, &certdata,
3581 	    1, &key, filename);
3582 
3583 end:
3584 	if (fullpath)
3585 		free(fullpath);
3586 
3587 	if (gotcert)
3588 		kmf_free_kmf_cert(handle, &certdata);
3589 	if (gotkey)
3590 		kmf_free_kmf_key(handle, &key);
3591 	return (rv);
3592 }
3593 
3594 /*
3595  * Helper function to extract keys and certificates from
3596  * a single PEM file.  Typically the file should contain a
3597  * private key and an associated public key wrapped in an x509 cert.
3598  * However, the file may be just a list of X509 certs with no keys.
3599  */
3600 static KMF_RETURN
3601 extract_pem(KMF_HANDLE *kmfh,
3602 	char *issuer, char *subject, KMF_BIGINT *serial,
3603 	char *filename, CK_UTF8CHAR *pin,
3604 	CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs,
3605 	int *numcerts)
3606 /* ARGSUSED6 */
3607 {
3608 	KMF_RETURN rv = KMF_OK;
3609 	FILE *fp;
3610 	STACK_OF(X509_INFO) *x509_info_stack = NULL;
3611 	int i, ncerts = 0, matchcerts = 0;
3612 	EVP_PKEY *pkey = NULL;
3613 	X509_INFO *info;
3614 	X509 *x;
3615 	X509_INFO **cert_infos = NULL;
3616 	KMF_DATA *certlist = NULL;
3617 
3618 	if (priv_key)
3619 		*priv_key = NULL;
3620 	if (certs)
3621 		*certs = NULL;
3622 	fp = fopen(filename, "r");
3623 	if (fp == NULL)
3624 		return (KMF_ERR_OPEN_FILE);
3625 
3626 	x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin);
3627 	if (x509_info_stack == NULL) {
3628 		(void) fclose(fp);
3629 		return (KMF_ERR_ENCODING);
3630 	}
3631 	cert_infos = (X509_INFO **)malloc(sk_X509_INFO_num(x509_info_stack) *
3632 	    sizeof (X509_INFO *));
3633 	if (cert_infos == NULL) {
3634 		(void) fclose(fp);
3635 		rv = KMF_ERR_MEMORY;
3636 		goto err;
3637 	}
3638 
3639 	for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
3640 		/* LINTED E_BAD_PTR_CAST_ALIGN */
3641 		cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i);
3642 		ncerts++;
3643 	}
3644 
3645 	if (ncerts == 0) {
3646 		(void) fclose(fp);
3647 		rv = KMF_ERR_CERT_NOT_FOUND;
3648 		goto err;
3649 	}
3650 
3651 	if (priv_key != NULL) {
3652 		rewind(fp);
3653 		pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin);
3654 	}
3655 	(void) fclose(fp);
3656 
3657 	x = cert_infos[ncerts - 1]->x509;
3658 	/*
3659 	 * Make sure the private key matchs the last cert in the file.
3660 	 */
3661 	if (pkey != NULL && !X509_check_private_key(x, pkey)) {
3662 		EVP_PKEY_free(pkey);
3663 		rv = KMF_ERR_KEY_MISMATCH;
3664 		goto err;
3665 	}
3666 
3667 	certlist = (KMF_DATA *)calloc(ncerts, sizeof (KMF_DATA));
3668 	if (certlist == NULL) {
3669 		if (pkey != NULL)
3670 			EVP_PKEY_free(pkey);
3671 		rv = KMF_ERR_MEMORY;
3672 		goto err;
3673 	}
3674 
3675 	/*
3676 	 * Convert all of the certs to DER format.
3677 	 */
3678 	matchcerts = 0;
3679 	for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) {
3680 		boolean_t match = FALSE;
3681 		info =  cert_infos[ncerts - 1 - i];
3682 
3683 		rv = check_cert(info->x509, issuer, subject, serial, &match);
3684 		if (rv != KMF_OK || match != TRUE) {
3685 			rv = KMF_OK;
3686 			continue;
3687 		}
3688 
3689 		rv = ssl_cert2KMFDATA(kmfh, info->x509,
3690 			&certlist[matchcerts++]);
3691 
3692 		if (rv != KMF_OK) {
3693 			int j;
3694 			for (j = 0; j < matchcerts; j++)
3695 				kmf_free_data(&certlist[j]);
3696 			free(certlist);
3697 			certlist = NULL;
3698 			ncerts = matchcerts = 0;
3699 		}
3700 	}
3701 
3702 	if (numcerts != NULL)
3703 		*numcerts = matchcerts;
3704 
3705 	if (certs != NULL)
3706 		*certs = certlist;
3707 	else if (certlist != NULL) {
3708 		for (i = 0; i < ncerts; i++)
3709 			kmf_free_data(&certlist[i]);
3710 		free(certlist);
3711 		certlist = NULL;
3712 	}
3713 
3714 	if (priv_key == NULL && pkey != NULL)
3715 		EVP_PKEY_free(pkey);
3716 	else if (priv_key != NULL && pkey != NULL)
3717 		*priv_key = pkey;
3718 
3719 err:
3720 	/* Cleanup the stack of X509 info records */
3721 	for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
3722 		/* LINTED E_BAD_PTR_CAST_ALIGN */
3723 		info = (X509_INFO *)sk_X509_INFO_value(x509_info_stack, i);
3724 		X509_INFO_free(info);
3725 	}
3726 	if (x509_info_stack)
3727 		sk_X509_INFO_free(x509_info_stack);
3728 
3729 	if (cert_infos != NULL)
3730 		free(cert_infos);
3731 
3732 	return (rv);
3733 }
3734 
3735 static KMF_RETURN
3736 openssl_parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *pin,
3737 	STACK_OF(EVP_PKEY) *keys, STACK_OF(X509) *certs)
3738 {
3739 	KMF_RETURN ret;
3740 	int i;
3741 
3742 	for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
3743 		/* LINTED E_BAD_PTR_CAST_ALIGN */
3744 		PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value(bags, i);
3745 		ret = openssl_parse_bag(bag, pin, (pin ? strlen(pin) : 0),
3746 		    keys, certs);
3747 
3748 		if (ret != KMF_OK)
3749 			return (ret);
3750 	}
3751 
3752 	return (ret);
3753 }
3754 
3755 static KMF_RETURN
3756 set_pkey_attrib(EVP_PKEY *pkey, ASN1_TYPE *attrib, int nid)
3757 {
3758 	X509_ATTRIBUTE *attr = NULL;
3759 
3760 	if (pkey == NULL || attrib == NULL)
3761 		return (KMF_ERR_BAD_PARAMETER);
3762 
3763 	if (pkey->attributes == NULL) {
3764 		pkey->attributes = sk_X509_ATTRIBUTE_new_null();
3765 		if (pkey->attributes == NULL)
3766 			return (KMF_ERR_MEMORY);
3767 	}
3768 	attr = X509_ATTRIBUTE_create(nid, attrib->type, attrib->value.ptr);
3769 	if (attr != NULL) {
3770 		int i;
3771 		X509_ATTRIBUTE *a;
3772 		for (i = 0;
3773 		    i < sk_X509_ATTRIBUTE_num(pkey->attributes); i++) {
3774 			/* LINTED E_BAD_PTR_CASE_ALIGN */
3775 			a = sk_X509_ATTRIBUTE_value(pkey->attributes, i);
3776 			if (OBJ_obj2nid(a->object) == nid) {
3777 				X509_ATTRIBUTE_free(a);
3778 				/* LINTED E_BAD_PTR_CAST_ALIGN */
3779 				(void) sk_X509_ATTRIBUTE_set(pkey->attributes,
3780 				    i, attr);
3781 				return (KMF_OK);
3782 			}
3783 		}
3784 		if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == NULL) {
3785 			X509_ATTRIBUTE_free(attr);
3786 			return (KMF_ERR_MEMORY);
3787 		}
3788 	} else {
3789 		return (KMF_ERR_MEMORY);
3790 	}
3791 
3792 	return (KMF_OK);
3793 }
3794 
3795 static KMF_RETURN
3796 openssl_parse_bag(PKCS12_SAFEBAG *bag, char *pass, int passlen,
3797 	STACK_OF(EVP_PKEY) *keylist, STACK_OF(X509) *certlist)
3798 {
3799 	KMF_RETURN ret = KMF_OK;
3800 	PKCS8_PRIV_KEY_INFO *p8 = NULL;
3801 	EVP_PKEY *pkey = NULL;
3802 	X509 *xcert = NULL;
3803 	ASN1_TYPE *keyid = NULL;
3804 	ASN1_TYPE *fname = NULL;
3805 	uchar_t *data = NULL;
3806 
3807 	keyid = PKCS12_get_attr(bag, NID_localKeyID);
3808 	fname = PKCS12_get_attr(bag, NID_friendlyName);
3809 
3810 	switch (M_PKCS12_bag_type(bag)) {
3811 		case NID_keyBag:
3812 			if (keylist == NULL)
3813 				goto end;
3814 			pkey = EVP_PKCS82PKEY(bag->value.keybag);
3815 			if (pkey == NULL)
3816 				ret = KMF_ERR_PKCS12_FORMAT;
3817 
3818 			break;
3819 		case NID_pkcs8ShroudedKeyBag:
3820 			if (keylist == NULL)
3821 				goto end;
3822 			p8 = M_PKCS12_decrypt_skey(bag, pass, passlen);
3823 			if (p8 == NULL)
3824 				return (KMF_ERR_AUTH_FAILED);
3825 			pkey = EVP_PKCS82PKEY(p8);
3826 			PKCS8_PRIV_KEY_INFO_free(p8);
3827 			if (pkey == NULL)
3828 				ret = KMF_ERR_PKCS12_FORMAT;
3829 			break;
3830 		case NID_certBag:
3831 			if (certlist == NULL)
3832 				goto end;
3833 			if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
3834 				return (KMF_ERR_PKCS12_FORMAT);
3835 			xcert = M_PKCS12_certbag2x509(bag);
3836 			if (xcert == NULL) {
3837 				ret = KMF_ERR_PKCS12_FORMAT;
3838 				goto end;
3839 			}
3840 			if (keyid != NULL) {
3841 				if (X509_keyid_set1(xcert,
3842 				    keyid->value.octet_string->data,
3843 				    keyid->value.octet_string->length) == 0) {
3844 					ret = KMF_ERR_PKCS12_FORMAT;
3845 					goto end;
3846 				}
3847 			}
3848 			if (fname != NULL) {
3849 				int len, r;
3850 				len = ASN1_STRING_to_UTF8(&data,
3851 				    fname->value.asn1_string);
3852 				if (len > 0 && data != NULL) {
3853 					r = X509_alias_set1(xcert, data, len);
3854 					if (r == NULL) {
3855 						ret = KMF_ERR_PKCS12_FORMAT;
3856 						goto end;
3857 					}
3858 				} else {
3859 					ret = KMF_ERR_PKCS12_FORMAT;
3860 					goto end;
3861 				}
3862 			}
3863 			if (sk_X509_push(certlist, xcert) == 0)
3864 				ret = KMF_ERR_MEMORY;
3865 			else
3866 				xcert = NULL;
3867 			break;
3868 		case NID_safeContentsBag:
3869 			return (openssl_parse_bags(bag->value.safes, pass,
3870 			    keylist, certlist));
3871 		default:
3872 			ret = KMF_ERR_PKCS12_FORMAT;
3873 			break;
3874 	}
3875 
3876 	/*
3877 	 * Set the ID and/or FriendlyName attributes on the key.
3878 	 * If converting to PKCS11 objects, these can translate to CKA_ID
3879 	 * and CKA_LABEL values.
3880 	 */
3881 	if (pkey != NULL && ret == KMF_OK) {
3882 		ASN1_TYPE *attr = NULL;
3883 		if (keyid != NULL && keyid->type == V_ASN1_OCTET_STRING) {
3884 			if ((attr = ASN1_TYPE_new()) == NULL)
3885 				return (KMF_ERR_MEMORY);
3886 			attr->value.octet_string =
3887 			    ASN1_STRING_dup(keyid->value.octet_string);
3888 			attr->type = V_ASN1_OCTET_STRING;
3889 			attr->value.ptr = (char *)attr->value.octet_string;
3890 			ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
3891 			OPENSSL_free(attr);
3892 		}
3893 
3894 		if (ret == KMF_OK && fname != NULL &&
3895 		    fname->type == V_ASN1_BMPSTRING) {
3896 			if ((attr = ASN1_TYPE_new()) == NULL)
3897 				return (KMF_ERR_MEMORY);
3898 			attr->value.bmpstring =
3899 			    ASN1_STRING_dup(fname->value.bmpstring);
3900 			attr->type = V_ASN1_BMPSTRING;
3901 			attr->value.ptr = (char *)attr->value.bmpstring;
3902 			ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
3903 			OPENSSL_free(attr);
3904 		}
3905 
3906 		if (ret == KMF_OK && keylist != NULL &&
3907 		    sk_EVP_PKEY_push(keylist, pkey) == 0)
3908 			ret = KMF_ERR_MEMORY;
3909 	}
3910 	if (ret == KMF_OK && keylist != NULL)
3911 		pkey = NULL;
3912 end:
3913 	if (pkey != NULL)
3914 		EVP_PKEY_free(pkey);
3915 	if (xcert != NULL)
3916 		X509_free(xcert);
3917 	if (data != NULL)
3918 		OPENSSL_free(data);
3919 
3920 	return (ret);
3921 }
3922 
3923 static KMF_RETURN
3924 openssl_pkcs12_parse(PKCS12 *p12, char *pin,
3925 	STACK_OF(EVP_PKEY) *keys,
3926 	STACK_OF(X509) *certs,
3927 	STACK_OF(X509) *ca)
3928 /* ARGSUSED3 */
3929 {
3930 	KMF_RETURN ret = KMF_OK;
3931 	STACK_OF(PKCS7) *asafes = NULL;
3932 	STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
3933 	int i, bagnid;
3934 	PKCS7 *p7;
3935 
3936 	if (p12 == NULL || (keys == NULL && certs == NULL))
3937 		return (KMF_ERR_BAD_PARAMETER);
3938 
3939 	if (pin == NULL || *pin == NULL) {
3940 		if (PKCS12_verify_mac(p12, NULL, 0)) {
3941 			pin = NULL;
3942 		} else if (PKCS12_verify_mac(p12, "", 0)) {
3943 			pin = "";
3944 		} else {
3945 			return (KMF_ERR_AUTH_FAILED);
3946 		}
3947 	} else if (!PKCS12_verify_mac(p12, pin, -1)) {
3948 		return (KMF_ERR_AUTH_FAILED);
3949 	}
3950 
3951 	if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
3952 		return (KMF_ERR_PKCS12_FORMAT);
3953 
3954 	for (i = 0; ret == KMF_OK && i < sk_PKCS7_num(asafes); i++) {
3955 		bags = NULL;
3956 		/* LINTED E_BAD_PTR_CAST_ALIGN */
3957 		p7 = sk_PKCS7_value(asafes, i);
3958 		bagnid = OBJ_obj2nid(p7->type);
3959 
3960 		if (bagnid == NID_pkcs7_data) {
3961 			bags = PKCS12_unpack_p7data(p7);
3962 		} else if (bagnid == NID_pkcs7_encrypted) {
3963 			bags = PKCS12_unpack_p7encdata(p7, pin,
3964 			    (pin ? strlen(pin) : 0));
3965 		} else {
3966 			continue;
3967 		}
3968 		if (bags == NULL) {
3969 			ret = KMF_ERR_PKCS12_FORMAT;
3970 			goto out;
3971 		}
3972 
3973 		if (openssl_parse_bags(bags, pin, keys, certs) != KMF_OK)
3974 			ret = KMF_ERR_PKCS12_FORMAT;
3975 
3976 		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
3977 	}
3978 out:
3979 	if (asafes != NULL)
3980 		sk_PKCS7_pop_free(asafes, PKCS7_free);
3981 
3982 	return (ret);
3983 }
3984 
3985 /*
3986  * Helper function to decrypt and parse PKCS#12 import file.
3987  */
3988 static KMF_RETURN
3989 extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
3990 	STACK_OF(EVP_PKEY) **priv_key, STACK_OF(X509) **certs,
3991 	STACK_OF(X509) **ca)
3992 /* ARGSUSED2 */
3993 {
3994 	PKCS12			*pk12, *pk12_tmp;
3995 	STACK_OF(EVP_PKEY)	*pkeylist = NULL;
3996 	STACK_OF(X509)		*xcertlist = NULL;
3997 	STACK_OF(X509)		*cacertlist = NULL;
3998 
3999 	if ((pk12 = PKCS12_new()) == NULL) {
4000 		return (KMF_ERR_MEMORY);
4001 	}
4002 
4003 	if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) {
4004 		/* This is ok; it seems to mean there is no more to read. */
4005 		if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 &&
4006 		    ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG)
4007 			goto end_extract_pkcs12;
4008 
4009 		PKCS12_free(pk12);
4010 		return (KMF_ERR_PKCS12_FORMAT);
4011 	}
4012 	pk12 = pk12_tmp;
4013 
4014 	xcertlist = sk_X509_new_null();
4015 	if (xcertlist == NULL) {
4016 		PKCS12_free(pk12);
4017 		return (KMF_ERR_MEMORY);
4018 	}
4019 	pkeylist = sk_EVP_PKEY_new_null();
4020 	if (pkeylist == NULL) {
4021 		sk_X509_pop_free(xcertlist, X509_free);
4022 		PKCS12_free(pk12);
4023 		return (KMF_ERR_MEMORY);
4024 	}
4025 
4026 	if (openssl_pkcs12_parse(pk12, (char *)pin, pkeylist, xcertlist,
4027 	    cacertlist) != KMF_OK) {
4028 		sk_X509_pop_free(xcertlist, X509_free);
4029 		sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
4030 		PKCS12_free(pk12);
4031 		return (KMF_ERR_PKCS12_FORMAT);
4032 	}
4033 
4034 	if (priv_key && pkeylist)
4035 		*priv_key = pkeylist;
4036 	else if (pkeylist)
4037 		sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
4038 	if (certs && xcertlist)
4039 		*certs = xcertlist;
4040 	else if (xcertlist)
4041 		sk_X509_pop_free(xcertlist, X509_free);
4042 	if (ca && cacertlist)
4043 		*ca = cacertlist;
4044 	else if (cacertlist)
4045 		sk_X509_pop_free(cacertlist, X509_free);
4046 
4047 end_extract_pkcs12:
4048 
4049 	PKCS12_free(pk12);
4050 	return (KMF_OK);
4051 }
4052 
4053 static KMF_RETURN
4054 sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to)
4055 {
4056 	KMF_RETURN rv = KMF_OK;
4057 	uint32_t sz;
4058 
4059 	sz = BN_num_bytes(from);
4060 	to->val = (uchar_t *)malloc(sz);
4061 	if (to->val == NULL)
4062 		return (KMF_ERR_MEMORY);
4063 
4064 	if ((to->len = BN_bn2bin(from, to->val)) != sz) {
4065 		free(to->val);
4066 		to->val = NULL;
4067 		to->len = 0;
4068 		rv = KMF_ERR_MEMORY;
4069 	}
4070 
4071 	return (rv);
4072 }
4073 
4074 static KMF_RETURN
4075 exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key)
4076 {
4077 	KMF_RETURN rv;
4078 	KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa;
4079 
4080 	(void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY));
4081 	if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK)
4082 		goto cleanup;
4083 
4084 	if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK)
4085 		goto cleanup;
4086 
4087 	if (rsa->d != NULL)
4088 		if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK)
4089 			goto cleanup;
4090 
4091 	if (rsa->p != NULL)
4092 		if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK)
4093 			goto cleanup;
4094 
4095 	if (rsa->q != NULL)
4096 		if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK)
4097 			goto cleanup;
4098 
4099 	if (rsa->dmp1 != NULL)
4100 		if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK)
4101 			goto cleanup;
4102 
4103 	if (rsa->dmq1 != NULL)
4104 		if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK)
4105 			goto cleanup;
4106 
4107 	if (rsa->iqmp != NULL)
4108 		if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK)
4109 			goto cleanup;
4110 cleanup:
4111 	if (rv != KMF_OK)
4112 		kmf_free_raw_key(key);
4113 	else
4114 		key->keytype = KMF_RSA;
4115 
4116 	/*
4117 	 * Free the reference to this key, SSL will not actually free
4118 	 * the memory until the refcount == 0, so this is safe.
4119 	 */
4120 	RSA_free(rsa);
4121 
4122 	return (rv);
4123 }
4124 
4125 static KMF_RETURN
4126 exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key)
4127 {
4128 	KMF_RETURN rv;
4129 	KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa;
4130 
4131 	(void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY));
4132 	if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK)
4133 		goto cleanup;
4134 
4135 	if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK)
4136 		goto cleanup;
4137 
4138 	if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK)
4139 		goto cleanup;
4140 
4141 	if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK)
4142 		goto cleanup;
4143 
4144 cleanup:
4145 	if (rv != KMF_OK)
4146 		kmf_free_raw_key(key);
4147 	else
4148 		key->keytype = KMF_DSA;
4149 
4150 	/*
4151 	 * Free the reference to this key, SSL will not actually free
4152 	 * the memory until the refcount == 0, so this is safe.
4153 	 */
4154 	DSA_free(dsa);
4155 
4156 	return (rv);
4157 }
4158 
4159 static KMF_RETURN
4160 add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert,
4161 	KMF_X509_DER_CERT **certlist, int *ncerts)
4162 {
4163 	KMF_RETURN rv = KMF_OK;
4164 	KMF_X509_DER_CERT *list = (*certlist);
4165 	KMF_X509_DER_CERT cert;
4166 	int n = (*ncerts);
4167 
4168 	if (list == NULL) {
4169 		list = (KMF_X509_DER_CERT *)malloc(sizeof (KMF_X509_DER_CERT));
4170 	} else {
4171 		list = (KMF_X509_DER_CERT *)realloc(list,
4172 		    sizeof (KMF_X509_DER_CERT) * (n + 1));
4173 	}
4174 
4175 	if (list == NULL)
4176 		return (KMF_ERR_MEMORY);
4177 
4178 	(void) memset(&cert, 0, sizeof (cert));
4179 	rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert.certificate);
4180 	if (rv == KMF_OK) {
4181 		int len = 0;
4182 		/* Get the alias name for the cert if there is one */
4183 		char *a = (char *)X509_alias_get0(sslcert, &len);
4184 		if (a != NULL)
4185 			cert.kmf_private.label = strdup(a);
4186 		cert.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
4187 
4188 		list[n] = cert;
4189 		(*ncerts) = n + 1;
4190 
4191 		*certlist = list;
4192 	} else {
4193 		free(list);
4194 	}
4195 
4196 	return (rv);
4197 }
4198 
4199 static KMF_RETURN
4200 add_key_to_list(KMF_RAW_KEY_DATA **keylist,
4201 	KMF_RAW_KEY_DATA *newkey, int *nkeys)
4202 {
4203 	KMF_RAW_KEY_DATA *list = (*keylist);
4204 	int n = (*nkeys);
4205 
4206 	if (list == NULL) {
4207 		list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA));
4208 	} else {
4209 		list = (KMF_RAW_KEY_DATA *)realloc(list,
4210 		    sizeof (KMF_RAW_KEY_DATA) * (n + 1));
4211 	}
4212 
4213 	if (list == NULL)
4214 		return (KMF_ERR_MEMORY);
4215 
4216 	list[n] = *newkey;
4217 	(*nkeys) = n + 1;
4218 
4219 	*keylist = list;
4220 
4221 	return (KMF_OK);
4222 }
4223 
4224 static X509_ATTRIBUTE *
4225 find_attr(STACK_OF(X509_ATTRIBUTE) *attrs, int nid)
4226 {
4227 	X509_ATTRIBUTE *a;
4228 	int i;
4229 
4230 	if (attrs == NULL)
4231 		return (NULL);
4232 
4233 	for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) {
4234 		/* LINTED E_BAD_PTR_CAST_ALIGN */
4235 		a = sk_X509_ATTRIBUTE_value(attrs, i);
4236 		if (OBJ_obj2nid(a->object) == nid)
4237 			return (a);
4238 	}
4239 	return (NULL);
4240 }
4241 
4242 static KMF_RETURN
4243 convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key)
4244 {
4245 	KMF_RETURN rv = KMF_OK;
4246 	X509_ATTRIBUTE *attr;
4247 
4248 	if (pkey == NULL || key == NULL)
4249 		return (KMF_ERR_BAD_PARAMETER);
4250 	/* Convert SSL key to raw key */
4251 	switch (pkey->type) {
4252 		case EVP_PKEY_RSA:
4253 			rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey),
4254 			    key);
4255 			if (rv != KMF_OK)
4256 				return (rv);
4257 			break;
4258 		case EVP_PKEY_DSA:
4259 			rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey),
4260 			    key);
4261 			if (rv != KMF_OK)
4262 				return (rv);
4263 			break;
4264 		default:
4265 			return (KMF_ERR_BAD_PARAMETER);
4266 	}
4267 	/*
4268 	 * If friendlyName, add it to record.
4269 	 */
4270 	attr = find_attr(pkey->attributes, NID_friendlyName);
4271 	if (attr != NULL) {
4272 		ASN1_TYPE *ty = NULL;
4273 		int numattr = sk_ASN1_TYPE_num(attr->value.set);
4274 		if (attr->single == 0 && numattr > 0) {
4275 			/* LINTED E_BAD_PTR_CAST_ALIGN */
4276 			ty = sk_ASN1_TYPE_value(attr->value.set, 0);
4277 		}
4278 		if (ty != NULL) {
4279 #if OPENSSL_VERSION_NUMBER < 0x10000000L
4280 			key->label = uni2asc(ty->value.bmpstring->data,
4281 			    ty->value.bmpstring->length);
4282 #else
4283 			key->label = OPENSSL_uni2asc(ty->value.bmpstring->data,
4284 			    ty->value.bmpstring->length);
4285 #endif
4286 		}
4287 	} else {
4288 		key->label = NULL;
4289 	}
4290 
4291 	/*
4292 	 * If KeyID, add it to record as a KMF_DATA object.
4293 	 */
4294 	attr = find_attr(pkey->attributes, NID_localKeyID);
4295 	if (attr != NULL) {
4296 		ASN1_TYPE *ty = NULL;
4297 		int numattr = sk_ASN1_TYPE_num(attr->value.set);
4298 		if (attr->single == 0 && numattr > 0) {
4299 			/* LINTED E_BAD_PTR_CAST_ALIGN */
4300 			ty = sk_ASN1_TYPE_value(attr->value.set, 0);
4301 		}
4302 		key->id.Data = (uchar_t *)malloc(
4303 		    ty->value.octet_string->length);
4304 		if (key->id.Data == NULL)
4305 			return (KMF_ERR_MEMORY);
4306 		(void) memcpy(key->id.Data, ty->value.octet_string->data,
4307 		    ty->value.octet_string->length);
4308 		key->id.Length = ty->value.octet_string->length;
4309 	} else {
4310 		(void) memset(&key->id, 0, sizeof (KMF_DATA));
4311 	}
4312 
4313 	return (rv);
4314 }
4315 
4316 static KMF_RETURN
4317 convertPK12Objects(
4318 	KMF_HANDLE *kmfh,
4319 	STACK_OF(EVP_PKEY) *sslkeys,
4320 	STACK_OF(X509) *sslcert,
4321 	STACK_OF(X509) *sslcacerts,
4322 	KMF_RAW_KEY_DATA **keylist, int *nkeys,
4323 	KMF_X509_DER_CERT **certlist, int *ncerts)
4324 {
4325 	KMF_RETURN rv = KMF_OK;
4326 	KMF_RAW_KEY_DATA key;
4327 	int i;
4328 
4329 	for (i = 0; sslkeys != NULL && i < sk_EVP_PKEY_num(sslkeys); i++) {
4330 		/* LINTED E_BAD_PTR_CAST_ALIGN */
4331 		EVP_PKEY *pkey = sk_EVP_PKEY_value(sslkeys, i);
4332 		rv = convertToRawKey(pkey, &key);
4333 		if (rv == KMF_OK)
4334 			rv = add_key_to_list(keylist, &key, nkeys);
4335 
4336 		if (rv != KMF_OK)
4337 			return (rv);
4338 	}
4339 
4340 	/* Now add the certificate to the certlist */
4341 	for (i = 0; sslcert != NULL && i < sk_X509_num(sslcert); i++) {
4342 		/* LINTED E_BAD_PTR_CAST_ALIGN */
4343 		X509 *cert = sk_X509_value(sslcert, i);
4344 		rv = add_cert_to_list(kmfh, cert, certlist, ncerts);
4345 		if (rv != KMF_OK)
4346 			return (rv);
4347 	}
4348 
4349 	/* Also add any included CA certs to the list */
4350 	for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) {
4351 		X509 *c;
4352 		/*
4353 		 * sk_X509_value() is macro that embeds a cast to (X509 *).
4354 		 * Here it translates into ((X509 *)sk_value((ca), (i))).
4355 		 * Lint is complaining about the embedded casting, and
4356 		 * to fix it, you need to fix openssl header files.
4357 		 */
4358 		/* LINTED E_BAD_PTR_CAST_ALIGN */
4359 		c = sk_X509_value(sslcacerts, i);
4360 
4361 		/* Now add the ca cert to the certlist */
4362 		rv = add_cert_to_list(kmfh, c, certlist, ncerts);
4363 		if (rv != KMF_OK)
4364 			return (rv);
4365 	}
4366 	return (rv);
4367 }
4368 
4369 KMF_RETURN
4370 openssl_import_objects(KMF_HANDLE *kmfh,
4371 	char *filename, KMF_CREDENTIAL *cred,
4372 	KMF_X509_DER_CERT **certlist, int *ncerts,
4373 	KMF_RAW_KEY_DATA **keylist, int *nkeys)
4374 {
4375 	KMF_RETURN	rv = KMF_OK;
4376 	KMF_ENCODE_FORMAT format;
4377 	BIO		*bio = NULL;
4378 	STACK_OF(EVP_PKEY)	*privkeys = NULL;
4379 	STACK_OF(X509)		*certs = NULL;
4380 	STACK_OF(X509)		*cacerts = NULL;
4381 
4382 	/*
4383 	 * auto-detect the file format, regardless of what
4384 	 * the 'format' parameters in the params say.
4385 	 */
4386 	rv = kmf_get_file_format(filename, &format);
4387 	if (rv != KMF_OK) {
4388 		return (rv);
4389 	}
4390 
4391 	/* This function only works for PEM or PKCS#12 files */
4392 	if (format != KMF_FORMAT_PEM &&
4393 	    format != KMF_FORMAT_PEM_KEYPAIR &&
4394 	    format != KMF_FORMAT_PKCS12)
4395 		return (KMF_ERR_ENCODING);
4396 
4397 	*certlist = NULL;
4398 	*keylist = NULL;
4399 	*ncerts = 0;
4400 	*nkeys = 0;
4401 
4402 	if (format == KMF_FORMAT_PKCS12) {
4403 		bio = BIO_new_file(filename, "rb");
4404 		if (bio == NULL) {
4405 			SET_ERROR(kmfh, ERR_get_error());
4406 			rv = KMF_ERR_OPEN_FILE;
4407 			goto end;
4408 		}
4409 
4410 		rv = extract_pkcs12(bio, (uchar_t *)cred->cred,
4411 		    (uint32_t)cred->credlen, &privkeys, &certs, &cacerts);
4412 
4413 		if (rv  == KMF_OK)
4414 			/* Convert keys and certs to exportable format */
4415 			rv = convertPK12Objects(kmfh, privkeys, certs, cacerts,
4416 			    keylist, nkeys, certlist, ncerts);
4417 	} else {
4418 		EVP_PKEY *pkey;
4419 		KMF_DATA *certdata = NULL;
4420 		KMF_X509_DER_CERT *kmfcerts = NULL;
4421 		int i;
4422 		rv = extract_pem(kmfh, NULL, NULL, NULL, filename,
4423 		    (uchar_t *)cred->cred, (uint32_t)cred->credlen,
4424 		    &pkey, &certdata, ncerts);
4425 
4426 		/* Reached end of import file? */
4427 		if (rv == KMF_OK && pkey != NULL) {
4428 			privkeys = sk_EVP_PKEY_new_null();
4429 			if (privkeys == NULL) {
4430 				rv = KMF_ERR_MEMORY;
4431 				goto end;
4432 			}
4433 			(void) sk_EVP_PKEY_push(privkeys, pkey);
4434 			/* convert the certificate list here */
4435 			if (*ncerts > 0 && certlist != NULL) {
4436 				kmfcerts = (KMF_X509_DER_CERT *)calloc(*ncerts,
4437 				    sizeof (KMF_X509_DER_CERT));
4438 				if (kmfcerts == NULL) {
4439 					rv = KMF_ERR_MEMORY;
4440 					goto end;
4441 				}
4442 				for (i = 0; i < *ncerts; i++) {
4443 					kmfcerts[i].certificate = certdata[i];
4444 					kmfcerts[i].kmf_private.keystore_type =
4445 					    KMF_KEYSTORE_OPENSSL;
4446 				}
4447 				*certlist = kmfcerts;
4448 			}
4449 			/*
4450 			 * Convert keys to exportable format, the certs
4451 			 * are already OK.
4452 			 */
4453 			rv = convertPK12Objects(kmfh, privkeys, NULL, NULL,
4454 			    keylist, nkeys, NULL, NULL);
4455 		}
4456 	}
4457 end:
4458 	if (bio != NULL)
4459 		(void) BIO_free(bio);
4460 
4461 	if (privkeys)
4462 		sk_EVP_PKEY_pop_free(privkeys, EVP_PKEY_free);
4463 	if (certs)
4464 		sk_X509_pop_free(certs, X509_free);
4465 	if (cacerts)
4466 		sk_X509_pop_free(cacerts, X509_free);
4467 
4468 	return (rv);
4469 }
4470 
4471 static KMF_RETURN
4472 create_deskey(DES_cblock **deskey)
4473 {
4474 	DES_cblock *key;
4475 
4476 	key = (DES_cblock *) malloc(sizeof (DES_cblock));
4477 	if (key == NULL) {
4478 		return (KMF_ERR_MEMORY);
4479 	}
4480 
4481 	if (DES_random_key(key) == 0) {
4482 		free(key);
4483 		return (KMF_ERR_KEYGEN_FAILED);
4484 	}
4485 
4486 	*deskey = key;
4487 	return (KMF_OK);
4488 }
4489 
4490 #define	KEYGEN_RETRY 3
4491 #define	DES3_KEY_SIZE 24
4492 
4493 static KMF_RETURN
4494 create_des3key(unsigned char **des3key)
4495 {
4496 	KMF_RETURN ret = KMF_OK;
4497 	DES_cblock *deskey1 = NULL;
4498 	DES_cblock *deskey2 = NULL;
4499 	DES_cblock *deskey3 = NULL;
4500 	unsigned char *newkey = NULL;
4501 	int retry;
4502 
4503 	if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) {
4504 		return (KMF_ERR_MEMORY);
4505 	}
4506 
4507 	/* create the 1st DES key */
4508 	if ((ret = create_deskey(&deskey1)) != KMF_OK) {
4509 		goto out;
4510 	}
4511 
4512 	/*
4513 	 * Create the 2nd DES key and make sure its value is different
4514 	 * from the 1st DES key.
4515 	 */
4516 	retry = 0;
4517 	do {
4518 		if (deskey2 != NULL) {
4519 			free(deskey2);
4520 			deskey2 = NULL;
4521 		}
4522 
4523 		if ((ret = create_deskey(&deskey2)) != KMF_OK) {
4524 			goto out;
4525 		}
4526 
4527 		if (memcmp((const void *) deskey1, (const void *) deskey2, 8)
4528 		    == 0) {
4529 			ret = KMF_ERR_KEYGEN_FAILED;
4530 			retry++;
4531 		}
4532 	} while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4533 
4534 	if (ret != KMF_OK) {
4535 		goto out;
4536 	}
4537 
4538 	/*
4539 	 * Create the 3rd DES key and make sure its value is different
4540 	 * from the 2nd DES key.
4541 	 */
4542 	retry = 0;
4543 	do {
4544 		if (deskey3 != NULL) {
4545 			free(deskey3);
4546 			deskey3 = NULL;
4547 		}
4548 
4549 		if ((ret = create_deskey(&deskey3)) != KMF_OK) {
4550 			goto out;
4551 		}
4552 
4553 		if (memcmp((const void *)deskey2, (const void *)deskey3, 8)
4554 		    == 0) {
4555 			ret = KMF_ERR_KEYGEN_FAILED;
4556 			retry++;
4557 		}
4558 	} while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4559 
4560 	if (ret != KMF_OK) {
4561 		goto out;
4562 	}
4563 
4564 	/* Concatenate 3 DES keys into a DES3 key */
4565 	(void) memcpy((void *)newkey, (const void *)deskey1, 8);
4566 	(void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8);
4567 	(void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8);
4568 	*des3key = newkey;
4569 
4570 out:
4571 	if (deskey1 != NULL)
4572 		free(deskey1);
4573 
4574 	if (deskey2 != NULL)
4575 		free(deskey2);
4576 
4577 	if (deskey3 != NULL)
4578 		free(deskey3);
4579 
4580 	if (ret != KMF_OK && newkey != NULL)
4581 		free(newkey);
4582 
4583 	return (ret);
4584 }
4585 
4586 KMF_RETURN
4587 OpenSSL_CreateSymKey(KMF_HANDLE_T handle,
4588 	int numattr, KMF_ATTRIBUTE *attrlist)
4589 {
4590 	KMF_RETURN ret = KMF_OK;
4591 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4592 	char *fullpath = NULL;
4593 	KMF_RAW_SYM_KEY *rkey = NULL;
4594 	DES_cblock *deskey = NULL;
4595 	unsigned char *des3key = NULL;
4596 	unsigned char *random = NULL;
4597 	int fd = -1;
4598 	KMF_KEY_HANDLE *symkey;
4599 	KMF_KEY_ALG keytype;
4600 	uint32_t keylen;
4601 	uint32_t keylen_size = sizeof (keylen);
4602 	char *dirpath;
4603 	char *keyfile;
4604 
4605 	if (kmfh == NULL)
4606 		return (KMF_ERR_UNINITIALIZED);
4607 
4608 	symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
4609 	if (symkey == NULL)
4610 		return (KMF_ERR_BAD_PARAMETER);
4611 
4612 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
4613 
4614 	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
4615 	if (keyfile == NULL)
4616 		return (KMF_ERR_BAD_PARAMETER);
4617 
4618 	ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
4619 	    (void *)&keytype, NULL);
4620 	if (ret != KMF_OK)
4621 		return (KMF_ERR_BAD_PARAMETER);
4622 
4623 	ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
4624 	    &keylen, &keylen_size);
4625 	if (ret == KMF_ERR_ATTR_NOT_FOUND &&
4626 	    (keytype == KMF_DES || keytype == KMF_DES3))
4627 		/* keylength is not required for DES and 3DES */
4628 		ret = KMF_OK;
4629 	if (ret != KMF_OK)
4630 		return (KMF_ERR_BAD_PARAMETER);
4631 
4632 	fullpath = get_fullpath(dirpath, keyfile);
4633 	if (fullpath == NULL)
4634 		return (KMF_ERR_BAD_PARAMETER);
4635 
4636 	/* If the requested file exists, return an error */
4637 	if (test_for_file(fullpath, 0400) == 1) {
4638 		free(fullpath);
4639 		return (KMF_ERR_DUPLICATE_KEYFILE);
4640 	}
4641 
4642 	fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400);
4643 	if (fd == -1) {
4644 		ret = KMF_ERR_OPEN_FILE;
4645 		goto out;
4646 	}
4647 
4648 	rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
4649 	if (rkey == NULL) {
4650 		ret = KMF_ERR_MEMORY;
4651 		goto out;
4652 	}
4653 	(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
4654 
4655 	if (keytype == KMF_DES) {
4656 		if ((ret = create_deskey(&deskey)) != KMF_OK) {
4657 			goto out;
4658 		}
4659 		rkey->keydata.val = (uchar_t *)deskey;
4660 		rkey->keydata.len = 8;
4661 
4662 		symkey->keyalg = KMF_DES;
4663 
4664 	} else if (keytype == KMF_DES3) {
4665 		if ((ret = create_des3key(&des3key)) != KMF_OK) {
4666 			goto out;
4667 		}
4668 		rkey->keydata.val = (uchar_t *)des3key;
4669 		rkey->keydata.len = DES3_KEY_SIZE;
4670 		symkey->keyalg = KMF_DES3;
4671 
4672 	} else if (keytype == KMF_AES || keytype == KMF_RC4 ||
4673 	    keytype == KMF_GENERIC_SECRET) {
4674 		int bytes;
4675 
4676 		if (keylen % 8 != 0) {
4677 			ret = KMF_ERR_BAD_KEY_SIZE;
4678 			goto out;
4679 		}
4680 
4681 		if (keytype == KMF_AES) {
4682 			if (keylen != 128 &&
4683 			    keylen != 192 &&
4684 			    keylen != 256) {
4685 				ret = KMF_ERR_BAD_KEY_SIZE;
4686 				goto out;
4687 			}
4688 		}
4689 
4690 		bytes = keylen/8;
4691 		random = malloc(bytes);
4692 		if (random == NULL) {
4693 			ret = KMF_ERR_MEMORY;
4694 			goto out;
4695 		}
4696 		if (RAND_bytes(random, bytes) != 1) {
4697 			ret = KMF_ERR_KEYGEN_FAILED;
4698 			goto out;
4699 		}
4700 
4701 		rkey->keydata.val = (uchar_t *)random;
4702 		rkey->keydata.len = bytes;
4703 		symkey->keyalg = keytype;
4704 
4705 	} else {
4706 		ret = KMF_ERR_BAD_KEY_TYPE;
4707 		goto out;
4708 	}
4709 
4710 	(void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len);
4711 
4712 	symkey->kstype = KMF_KEYSTORE_OPENSSL;
4713 	symkey->keyclass = KMF_SYMMETRIC;
4714 	symkey->keylabel = (char *)fullpath;
4715 	symkey->israw = TRUE;
4716 	symkey->keyp = rkey;
4717 
4718 out:
4719 	if (fd != -1)
4720 		(void) close(fd);
4721 
4722 	if (ret != KMF_OK && fullpath != NULL) {
4723 		free(fullpath);
4724 	}
4725 	if (ret != KMF_OK) {
4726 		kmf_free_raw_sym_key(rkey);
4727 		symkey->keyp = NULL;
4728 		symkey->keyalg = KMF_KEYALG_NONE;
4729 	}
4730 
4731 	return (ret);
4732 }
4733 
4734 /*
4735  * Check a file to see if it is a CRL file with PEM or DER format.
4736  * If success, return its format in the "pformat" argument.
4737  */
4738 KMF_RETURN
4739 OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat)
4740 {
4741 	KMF_RETURN	ret = KMF_OK;
4742 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4743 	BIO		*bio = NULL;
4744 	X509_CRL   	*xcrl = NULL;
4745 
4746 	if (filename == NULL) {
4747 		return (KMF_ERR_BAD_PARAMETER);
4748 	}
4749 
4750 	bio = BIO_new_file(filename, "rb");
4751 	if (bio == NULL)	{
4752 		SET_ERROR(kmfh, ERR_get_error());
4753 		ret = KMF_ERR_OPEN_FILE;
4754 		goto out;
4755 	}
4756 
4757 	if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) {
4758 		*pformat = KMF_FORMAT_PEM;
4759 		goto out;
4760 	}
4761 	(void) BIO_free(bio);
4762 
4763 	/*
4764 	 * Now try to read it as raw DER data.
4765 	 */
4766 	bio = BIO_new_file(filename, "rb");
4767 	if (bio == NULL)	{
4768 		SET_ERROR(kmfh, ERR_get_error());
4769 		ret = KMF_ERR_OPEN_FILE;
4770 		goto out;
4771 	}
4772 
4773 	if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) {
4774 		*pformat = KMF_FORMAT_ASN1;
4775 	} else {
4776 		ret = KMF_ERR_BAD_CRLFILE;
4777 	}
4778 
4779 out:
4780 	if (bio != NULL)
4781 		(void) BIO_free(bio);
4782 
4783 	if (xcrl != NULL)
4784 		X509_CRL_free(xcrl);
4785 
4786 	return (ret);
4787 }
4788 
4789 KMF_RETURN
4790 OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
4791     KMF_RAW_SYM_KEY *rkey)
4792 {
4793 	KMF_RETURN	rv = KMF_OK;
4794 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4795 	KMF_DATA	keyvalue;
4796 
4797 	if (kmfh == NULL)
4798 		return (KMF_ERR_UNINITIALIZED);
4799 
4800 	if (symkey == NULL || rkey == NULL)
4801 		return (KMF_ERR_BAD_PARAMETER);
4802 	else if (symkey->keyclass != KMF_SYMMETRIC)
4803 		return (KMF_ERR_BAD_KEY_CLASS);
4804 
4805 	if (symkey->israw) {
4806 		KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp;
4807 
4808 		if (rawkey == NULL ||
4809 		    rawkey->keydata.val == NULL ||
4810 		    rawkey->keydata.len == 0)
4811 			return (KMF_ERR_BAD_KEYHANDLE);
4812 
4813 		rkey->keydata.len = rawkey->keydata.len;
4814 		if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
4815 			return (KMF_ERR_MEMORY);
4816 		(void) memcpy(rkey->keydata.val, rawkey->keydata.val,
4817 		    rkey->keydata.len);
4818 	} else {
4819 		rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue);
4820 		if (rv != KMF_OK)
4821 			return (rv);
4822 		rkey->keydata.len = keyvalue.Length;
4823 		rkey->keydata.val = keyvalue.Data;
4824 	}
4825 
4826 	return (rv);
4827 }
4828 
4829 /*
4830  * substitute for the unsafe access(2) function.
4831  * If the file in question already exists, return 1.
4832  * else 0.  If an error occurs during testing (other
4833  * than EEXIST), return -1.
4834  */
4835 static int
4836 test_for_file(char *filename, mode_t mode)
4837 {
4838 	int fd;
4839 
4840 	/*
4841 	 * Try to create the file with the EXCL flag.
4842 	 * The call should fail if the file exists.
4843 	 */
4844 	fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode);
4845 	if (fd == -1 && errno == EEXIST)
4846 		return (1);
4847 	else if (fd == -1) /* some other error */
4848 		return (-1);
4849 
4850 	/* The file did NOT exist.  Delete the testcase. */
4851 	(void) close(fd);
4852 	(void) unlink(filename);
4853 	return (0);
4854 }
4855 
4856 KMF_RETURN
4857 OpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr,
4858 	KMF_ATTRIBUTE *attrlist)
4859 {
4860 	KMF_RETURN rv = KMF_OK;
4861 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4862 	KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL;
4863 	KMF_RAW_KEY_DATA *rawkey;
4864 	EVP_PKEY *pkey = NULL;
4865 	KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM;
4866 	KMF_CREDENTIAL cred = { NULL, 0 };
4867 	BIO *out = NULL;
4868 	int keys = 0;
4869 	char *fullpath = NULL;
4870 	char *keyfile = NULL;
4871 	char *dirpath = NULL;
4872 
4873 	pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
4874 	if (pubkey != NULL)
4875 		keys++;
4876 
4877 	prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
4878 	if (prikey != NULL)
4879 		keys++;
4880 
4881 	rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
4882 	if (rawkey != NULL)
4883 		keys++;
4884 
4885 	/*
4886 	 * Exactly 1 type of key must be passed to this function.
4887 	 */
4888 	if (keys != 1)
4889 		return (KMF_ERR_BAD_PARAMETER);
4890 
4891 	keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist,
4892 	    numattr);
4893 	if (keyfile == NULL)
4894 		return (KMF_ERR_BAD_PARAMETER);
4895 
4896 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
4897 
4898 	fullpath = get_fullpath(dirpath, keyfile);
4899 
4900 	/* Once we have the full path, we don't need the pieces */
4901 	if (fullpath == NULL)
4902 		return (KMF_ERR_BAD_PARAMETER);
4903 
4904 	/* If the requested file exists, return an error */
4905 	if (test_for_file(fullpath, 0400) == 1) {
4906 		free(fullpath);
4907 		return (KMF_ERR_DUPLICATE_KEYFILE);
4908 	}
4909 
4910 	rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
4911 	    &format, NULL);
4912 	if (rv != KMF_OK)
4913 		/* format is optional. */
4914 		rv = KMF_OK;
4915 
4916 	/* CRED is not required for OpenSSL files */
4917 	(void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
4918 	    &cred, NULL);
4919 
4920 	/* Store the private key to the keyfile */
4921 	out = BIO_new_file(fullpath, "wb");
4922 	if (out == NULL) {
4923 		SET_ERROR(kmfh, ERR_get_error());
4924 		rv = KMF_ERR_OPEN_FILE;
4925 		goto end;
4926 	}
4927 
4928 	if (prikey != NULL && prikey->keyp != NULL) {
4929 		if (prikey->keyalg == KMF_RSA ||
4930 		    prikey->keyalg == KMF_DSA) {
4931 			pkey = (EVP_PKEY *)prikey->keyp;
4932 
4933 			rv = ssl_write_key(kmfh, format,
4934 			    out, &cred, pkey, TRUE);
4935 
4936 			if (rv == KMF_OK && prikey->keylabel == NULL) {
4937 				prikey->keylabel = strdup(fullpath);
4938 				if (prikey->keylabel == NULL)
4939 					rv = KMF_ERR_MEMORY;
4940 			}
4941 		}
4942 	} else if (pubkey != NULL && pubkey->keyp != NULL) {
4943 		if (pubkey->keyalg == KMF_RSA ||
4944 		    pubkey->keyalg == KMF_DSA) {
4945 			pkey = (EVP_PKEY *)pubkey->keyp;
4946 
4947 			rv = ssl_write_key(kmfh, format,
4948 			    out, &cred, pkey, FALSE);
4949 
4950 			if (rv == KMF_OK && pubkey->keylabel == NULL) {
4951 				pubkey->keylabel = strdup(fullpath);
4952 				if (pubkey->keylabel == NULL)
4953 					rv = KMF_ERR_MEMORY;
4954 			}
4955 		}
4956 	} else if (rawkey != NULL) {
4957 		if (rawkey->keytype == KMF_RSA) {
4958 			pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
4959 		} else if (rawkey->keytype == KMF_DSA) {
4960 			pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
4961 		} else {
4962 			rv = KMF_ERR_BAD_PARAMETER;
4963 		}
4964 		if (pkey != NULL) {
4965 			KMF_KEY_CLASS kclass = KMF_ASYM_PRI;
4966 
4967 			rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
4968 			    (void *)&kclass, NULL);
4969 			if (rv != KMF_OK)
4970 				rv = KMF_OK;
4971 			rv = ssl_write_key(kmfh, format, out,
4972 			    &cred, pkey, (kclass == KMF_ASYM_PRI));
4973 			EVP_PKEY_free(pkey);
4974 		}
4975 	}
4976 
4977 end:
4978 
4979 	if (out)
4980 		(void) BIO_free(out);
4981 
4982 
4983 	if (rv == KMF_OK)
4984 		(void) chmod(fullpath, 0400);
4985 
4986 	free(fullpath);
4987 	return (rv);
4988 }
4989 
4990 KMF_RETURN
4991 OpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
4992 {
4993 	KMF_RETURN ret = KMF_OK;
4994 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4995 	X509_CRL *xcrl = NULL;
4996 	X509 *xcert = NULL;
4997 	EVP_PKEY *pkey;
4998 	KMF_ENCODE_FORMAT format;
4999 	BIO *in = NULL, *out = NULL;
5000 	int openssl_ret = 0;
5001 	KMF_ENCODE_FORMAT outformat;
5002 	boolean_t crlcheck = FALSE;
5003 	char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile;
5004 
5005 	if (numattr == 0 || attrlist == NULL) {
5006 		return (KMF_ERR_BAD_PARAMETER);
5007 	}
5008 
5009 	/* CRL check is optional */
5010 	(void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr,
5011 	    &crlcheck, NULL);
5012 
5013 	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
5014 	if (crlcheck == B_TRUE && certfile == NULL) {
5015 		return (KMF_ERR_BAD_CERTFILE);
5016 	}
5017 
5018 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5019 	incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr);
5020 	outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr);
5021 
5022 	crlfile = get_fullpath(dirpath, incrl);
5023 
5024 	if (crlfile == NULL)
5025 		return (KMF_ERR_BAD_CRLFILE);
5026 
5027 	outcrlfile = get_fullpath(dirpath, outcrl);
5028 	if (outcrlfile == NULL)
5029 		return (KMF_ERR_BAD_CRLFILE);
5030 
5031 	if (isdir(outcrlfile)) {
5032 		free(outcrlfile);
5033 		return (KMF_ERR_BAD_CRLFILE);
5034 	}
5035 
5036 	ret = kmf_is_crl_file(handle, crlfile, &format);
5037 	if (ret != KMF_OK) {
5038 		free(outcrlfile);
5039 		return (ret);
5040 	}
5041 
5042 	in = BIO_new_file(crlfile, "rb");
5043 	if (in == NULL)	{
5044 		SET_ERROR(kmfh, ERR_get_error());
5045 		ret = KMF_ERR_OPEN_FILE;
5046 		goto end;
5047 	}
5048 
5049 	if (format == KMF_FORMAT_ASN1) {
5050 		xcrl = d2i_X509_CRL_bio(in, NULL);
5051 	} else if (format == KMF_FORMAT_PEM) {
5052 		xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5053 	}
5054 
5055 	if (xcrl == NULL) {
5056 		SET_ERROR(kmfh, ERR_get_error());
5057 		ret = KMF_ERR_BAD_CRLFILE;
5058 		goto end;
5059 	}
5060 
5061 	/* If bypasscheck is specified, no need to verify. */
5062 	if (crlcheck == B_FALSE)
5063 		goto output;
5064 
5065 	ret = kmf_is_cert_file(handle, certfile, &format);
5066 	if (ret != KMF_OK)
5067 		goto end;
5068 
5069 	/* Read in the CA cert file and convert to X509 */
5070 	if (BIO_read_filename(in, certfile) <= 0) {
5071 		SET_ERROR(kmfh, ERR_get_error());
5072 		ret = KMF_ERR_OPEN_FILE;
5073 		goto end;
5074 	}
5075 
5076 	if (format == KMF_FORMAT_ASN1) {
5077 		xcert = d2i_X509_bio(in, NULL);
5078 	} else if (format == KMF_FORMAT_PEM) {
5079 		xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
5080 	} else {
5081 		ret = KMF_ERR_BAD_CERT_FORMAT;
5082 		goto end;
5083 	}
5084 
5085 	if (xcert == NULL) {
5086 		SET_ERROR(kmfh, ERR_get_error());
5087 		ret = KMF_ERR_BAD_CERT_FORMAT;
5088 		goto end;
5089 	}
5090 	/* Now get the public key from the CA cert */
5091 	pkey = X509_get_pubkey(xcert);
5092 	if (pkey == NULL) {
5093 		SET_ERROR(kmfh, ERR_get_error());
5094 		ret = KMF_ERR_BAD_CERTFILE;
5095 		goto end;
5096 	}
5097 
5098 	/* Verify the CRL with the CA's public key */
5099 	openssl_ret = X509_CRL_verify(xcrl, pkey);
5100 	EVP_PKEY_free(pkey);
5101 	if (openssl_ret > 0) {
5102 		ret = KMF_OK;  /* verify succeed */
5103 	} else {
5104 		SET_ERROR(kmfh, openssl_ret);
5105 		ret = KMF_ERR_BAD_CRLFILE;
5106 	}
5107 
5108 output:
5109 	ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
5110 	    &outformat, NULL);
5111 	if (ret != KMF_OK) {
5112 		ret = KMF_OK;
5113 		outformat = KMF_FORMAT_PEM;
5114 	}
5115 
5116 	out = BIO_new_file(outcrlfile, "wb");
5117 	if (out == NULL) {
5118 		SET_ERROR(kmfh, ERR_get_error());
5119 		ret = KMF_ERR_OPEN_FILE;
5120 		goto end;
5121 	}
5122 
5123 	if (outformat == KMF_FORMAT_ASN1) {
5124 		openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl);
5125 	} else if (outformat == KMF_FORMAT_PEM) {
5126 		openssl_ret = PEM_write_bio_X509_CRL(out, xcrl);
5127 	} else {
5128 		ret = KMF_ERR_BAD_PARAMETER;
5129 		goto end;
5130 	}
5131 
5132 	if (openssl_ret <= 0) {
5133 		SET_ERROR(kmfh, ERR_get_error());
5134 		ret = KMF_ERR_WRITE_FILE;
5135 	} else {
5136 		ret = KMF_OK;
5137 	}
5138 
5139 end:
5140 	if (xcrl != NULL)
5141 		X509_CRL_free(xcrl);
5142 
5143 	if (xcert != NULL)
5144 		X509_free(xcert);
5145 
5146 	if (in != NULL)
5147 		(void) BIO_free(in);
5148 
5149 	if (out != NULL)
5150 		(void) BIO_free(out);
5151 
5152 	if (outcrlfile != NULL)
5153 		free(outcrlfile);
5154 
5155 	return (ret);
5156 }
5157 
5158 KMF_RETURN
5159 OpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5160 {
5161 	KMF_RETURN ret = KMF_OK;
5162 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5163 	X509_CRL   *x = NULL;
5164 	KMF_ENCODE_FORMAT format;
5165 	char *crlfile = NULL;
5166 	BIO *in = NULL;
5167 	BIO *mem = NULL;
5168 	long len;
5169 	char *memptr;
5170 	char *data = NULL;
5171 	char **crldata;
5172 	char *crlfilename, *dirpath;
5173 
5174 	if (numattr == 0 || attrlist == NULL) {
5175 		return (KMF_ERR_BAD_PARAMETER);
5176 	}
5177 	crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5178 	    attrlist, numattr);
5179 	if (crlfilename == NULL)
5180 		return (KMF_ERR_BAD_CRLFILE);
5181 
5182 	crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR,
5183 	    attrlist, numattr);
5184 
5185 	if (crldata == NULL)
5186 		return (KMF_ERR_BAD_PARAMETER);
5187 
5188 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5189 
5190 	crlfile = get_fullpath(dirpath, crlfilename);
5191 
5192 	if (crlfile == NULL)
5193 		return (KMF_ERR_BAD_CRLFILE);
5194 
5195 	if (isdir(crlfile)) {
5196 		free(crlfile);
5197 		return (KMF_ERR_BAD_CRLFILE);
5198 	}
5199 
5200 	ret = kmf_is_crl_file(handle, crlfile, &format);
5201 	if (ret != KMF_OK) {
5202 		free(crlfile);
5203 		return (ret);
5204 	}
5205 
5206 	if (bio_err == NULL)
5207 		bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
5208 
5209 	in = BIO_new_file(crlfile, "rb");
5210 	if (in == NULL)	{
5211 		SET_ERROR(kmfh, ERR_get_error());
5212 		ret = KMF_ERR_OPEN_FILE;
5213 		goto end;
5214 	}
5215 
5216 	if (format == KMF_FORMAT_ASN1) {
5217 		x = d2i_X509_CRL_bio(in, NULL);
5218 	} else if (format == KMF_FORMAT_PEM) {
5219 		x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5220 	}
5221 
5222 	if (x == NULL) { /* should not happen */
5223 		SET_ERROR(kmfh, ERR_get_error());
5224 		ret = KMF_ERR_OPEN_FILE;
5225 		goto end;
5226 	}
5227 
5228 	mem = BIO_new(BIO_s_mem());
5229 	if (mem == NULL) {
5230 		SET_ERROR(kmfh, ERR_get_error());
5231 		ret = KMF_ERR_MEMORY;
5232 		goto end;
5233 	}
5234 
5235 	(void) X509_CRL_print(mem, x);
5236 	len = BIO_get_mem_data(mem, &memptr);
5237 	if (len <= 0) {
5238 		SET_ERROR(kmfh, ERR_get_error());
5239 		ret = KMF_ERR_MEMORY;
5240 		goto end;
5241 	}
5242 
5243 	data = malloc(len + 1);
5244 	if (data == NULL) {
5245 		ret = KMF_ERR_MEMORY;
5246 		goto end;
5247 	}
5248 
5249 	(void) memcpy(data, memptr, len);
5250 	data[len] = '\0';
5251 	*crldata = data;
5252 
5253 end:
5254 	if (x != NULL)
5255 		X509_CRL_free(x);
5256 
5257 	if (crlfile != NULL)
5258 		free(crlfile);
5259 
5260 	if (in != NULL)
5261 		(void) BIO_free(in);
5262 
5263 	if (mem != NULL)
5264 		(void) BIO_free(mem);
5265 
5266 	return (ret);
5267 }
5268 
5269 KMF_RETURN
5270 OpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5271 {
5272 	KMF_RETURN ret = KMF_OK;
5273 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5274 	KMF_ENCODE_FORMAT format;
5275 	char *crlfile = NULL;
5276 	BIO *in = NULL;
5277 	char *crlfilename, *dirpath;
5278 
5279 	if (numattr == 0 || attrlist == NULL) {
5280 		return (KMF_ERR_BAD_PARAMETER);
5281 	}
5282 
5283 	crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5284 	    attrlist, numattr);
5285 
5286 	if (crlfilename == NULL)
5287 		return (KMF_ERR_BAD_CRLFILE);
5288 
5289 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5290 
5291 	crlfile = get_fullpath(dirpath, crlfilename);
5292 
5293 	if (crlfile == NULL)
5294 		return (KMF_ERR_BAD_CRLFILE);
5295 
5296 	if (isdir(crlfile)) {
5297 		ret = KMF_ERR_BAD_CRLFILE;
5298 		goto end;
5299 	}
5300 
5301 	ret = kmf_is_crl_file(handle, crlfile, &format);
5302 	if (ret != KMF_OK)
5303 		goto end;
5304 
5305 	if (unlink(crlfile) != 0) {
5306 		SET_SYS_ERROR(kmfh, errno);
5307 		ret = KMF_ERR_INTERNAL;
5308 		goto end;
5309 	}
5310 
5311 end:
5312 	if (in != NULL)
5313 		(void) BIO_free(in);
5314 	if (crlfile != NULL)
5315 		free(crlfile);
5316 
5317 	return (ret);
5318 }
5319 
5320 KMF_RETURN
5321 OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5322 {
5323 	KMF_RETURN ret = KMF_OK;
5324 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5325 	KMF_ENCODE_FORMAT format;
5326 	BIO *in = NULL;
5327 	X509   *xcert = NULL;
5328 	X509_CRL   *xcrl = NULL;
5329 	STACK_OF(X509_REVOKED) *revoke_stack = NULL;
5330 	X509_REVOKED *revoke;
5331 	int i;
5332 	char *crlfilename, *crlfile, *dirpath, *certfile;
5333 
5334 	if (numattr == 0 || attrlist == NULL) {
5335 		return (KMF_ERR_BAD_PARAMETER);
5336 	}
5337 
5338 	crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5339 	    attrlist, numattr);
5340 
5341 	if (crlfilename == NULL)
5342 		return (KMF_ERR_BAD_CRLFILE);
5343 
5344 	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
5345 	if (certfile == NULL)
5346 		return (KMF_ERR_BAD_CRLFILE);
5347 
5348 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5349 
5350 	crlfile = get_fullpath(dirpath, crlfilename);
5351 
5352 	if (crlfile == NULL)
5353 		return (KMF_ERR_BAD_CRLFILE);
5354 
5355 	if (isdir(crlfile)) {
5356 		ret = KMF_ERR_BAD_CRLFILE;
5357 		goto end;
5358 	}
5359 
5360 	ret = kmf_is_crl_file(handle, crlfile, &format);
5361 	if (ret != KMF_OK)
5362 		goto end;
5363 
5364 	/* Read the CRL file and load it into a X509_CRL structure */
5365 	in = BIO_new_file(crlfilename, "rb");
5366 	if (in == NULL)	{
5367 		SET_ERROR(kmfh, ERR_get_error());
5368 		ret = KMF_ERR_OPEN_FILE;
5369 		goto end;
5370 	}
5371 
5372 	if (format == KMF_FORMAT_ASN1) {
5373 		xcrl = d2i_X509_CRL_bio(in, NULL);
5374 	} else if (format == KMF_FORMAT_PEM) {
5375 		xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5376 	}
5377 
5378 	if (xcrl == NULL) {
5379 		SET_ERROR(kmfh, ERR_get_error());
5380 		ret = KMF_ERR_BAD_CRLFILE;
5381 		goto end;
5382 	}
5383 	(void) BIO_free(in);
5384 
5385 	/* Read the Certificate file and load it into a X509 structure */
5386 	ret = kmf_is_cert_file(handle, certfile, &format);
5387 	if (ret != KMF_OK)
5388 		goto end;
5389 
5390 	in = BIO_new_file(certfile, "rb");
5391 	if (in == NULL)	{
5392 		SET_ERROR(kmfh, ERR_get_error());
5393 		ret = KMF_ERR_OPEN_FILE;
5394 		goto end;
5395 	}
5396 
5397 	if (format == KMF_FORMAT_ASN1) {
5398 		xcert = d2i_X509_bio(in, NULL);
5399 	} else if (format == KMF_FORMAT_PEM) {
5400 		xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
5401 	}
5402 
5403 	if (xcert == NULL) {
5404 		SET_ERROR(kmfh, ERR_get_error());
5405 		ret = KMF_ERR_BAD_CERTFILE;
5406 		goto end;
5407 	}
5408 
5409 	/* Check if the certificate and the CRL have same issuer */
5410 	if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) {
5411 		ret = KMF_ERR_ISSUER;
5412 		goto end;
5413 	}
5414 
5415 	/* Check to see if the certificate serial number is revoked */
5416 	revoke_stack = X509_CRL_get_REVOKED(xcrl);
5417 	if (sk_X509_REVOKED_num(revoke_stack) <= 0) {
5418 		/* No revoked certificates in the CRL file */
5419 		SET_ERROR(kmfh, ERR_get_error());
5420 		ret = KMF_ERR_EMPTY_CRL;
5421 		goto end;
5422 	}
5423 
5424 	for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) {
5425 		/* LINTED E_BAD_PTR_CAST_ALIGN */
5426 		revoke = sk_X509_REVOKED_value(revoke_stack, i);
5427 		if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber,
5428 		    revoke->serialNumber) == 0) {
5429 			break;
5430 		}
5431 	}
5432 
5433 	if (i < sk_X509_REVOKED_num(revoke_stack)) {
5434 		ret = KMF_OK;
5435 	} else {
5436 		ret = KMF_ERR_NOT_REVOKED;
5437 	}
5438 
5439 end:
5440 	if (in != NULL)
5441 		(void) BIO_free(in);
5442 	if (xcrl != NULL)
5443 		X509_CRL_free(xcrl);
5444 	if (xcert != NULL)
5445 		X509_free(xcert);
5446 
5447 	return (ret);
5448 }
5449 
5450 KMF_RETURN
5451 OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert)
5452 {
5453 	KMF_RETURN	ret = KMF_OK;
5454 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
5455 	BIO		*bcrl = NULL;
5456 	X509_CRL   	*xcrl = NULL;
5457 	X509		*xcert = NULL;
5458 	EVP_PKEY	*pkey;
5459 	int		sslret;
5460 	KMF_ENCODE_FORMAT crl_format;
5461 	unsigned char	*p;
5462 	long		len;
5463 
5464 	if (handle == NULL || crlname == NULL || tacert == NULL) {
5465 		return (KMF_ERR_BAD_PARAMETER);
5466 	}
5467 
5468 	ret = kmf_get_file_format(crlname, &crl_format);
5469 	if (ret != KMF_OK)
5470 		return (ret);
5471 
5472 	bcrl = BIO_new_file(crlname, "rb");
5473 	if (bcrl == NULL)	{
5474 		SET_ERROR(kmfh, ERR_get_error());
5475 		ret = KMF_ERR_OPEN_FILE;
5476 		goto cleanup;
5477 	}
5478 
5479 	if (crl_format == KMF_FORMAT_ASN1) {
5480 		xcrl = d2i_X509_CRL_bio(bcrl, NULL);
5481 	} else if (crl_format == KMF_FORMAT_PEM) {
5482 		xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
5483 	} else {
5484 		ret = KMF_ERR_BAD_PARAMETER;
5485 		goto cleanup;
5486 	}
5487 
5488 	if (xcrl == NULL) {
5489 		SET_ERROR(kmfh, ERR_get_error());
5490 		ret = KMF_ERR_BAD_CRLFILE;
5491 		goto cleanup;
5492 	}
5493 
5494 	p = tacert->Data;
5495 	len = tacert->Length;
5496 	xcert = d2i_X509(NULL, (const uchar_t **)&p, len);
5497 
5498 	if (xcert == NULL) {
5499 		SET_ERROR(kmfh, ERR_get_error());
5500 		ret = KMF_ERR_BAD_CERTFILE;
5501 		goto cleanup;
5502 	}
5503 
5504 	/* Get issuer certificate public key */
5505 	pkey = X509_get_pubkey(xcert);
5506 	if (pkey == NULL) {
5507 		SET_ERROR(kmfh, ERR_get_error());
5508 		ret = KMF_ERR_BAD_CERT_FORMAT;
5509 		goto cleanup;
5510 	}
5511 
5512 	/* Verify CRL signature */
5513 	sslret = X509_CRL_verify(xcrl, pkey);
5514 	EVP_PKEY_free(pkey);
5515 	if (sslret > 0) {
5516 		ret = KMF_OK;
5517 	} else {
5518 		SET_ERROR(kmfh, sslret);
5519 		ret = KMF_ERR_BAD_CRLFILE;
5520 	}
5521 
5522 cleanup:
5523 	if (bcrl != NULL)
5524 		(void) BIO_free(bcrl);
5525 
5526 	if (xcrl != NULL)
5527 		X509_CRL_free(xcrl);
5528 
5529 	if (xcert != NULL)
5530 		X509_free(xcert);
5531 
5532 	return (ret);
5533 
5534 }
5535 
5536 KMF_RETURN
5537 OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname)
5538 {
5539 	KMF_RETURN	ret = KMF_OK;
5540 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
5541 	KMF_ENCODE_FORMAT crl_format;
5542 	BIO		*bcrl = NULL;
5543 	X509_CRL   	*xcrl = NULL;
5544 	int		i;
5545 
5546 	if (handle == NULL || crlname == NULL) {
5547 		return (KMF_ERR_BAD_PARAMETER);
5548 	}
5549 
5550 	ret = kmf_is_crl_file(handle, crlname, &crl_format);
5551 	if (ret != KMF_OK)
5552 		return (ret);
5553 
5554 	bcrl = BIO_new_file(crlname, "rb");
5555 	if (bcrl == NULL) {
5556 		SET_ERROR(kmfh, ERR_get_error());
5557 		ret = KMF_ERR_OPEN_FILE;
5558 		goto cleanup;
5559 	}
5560 
5561 	if (crl_format == KMF_FORMAT_ASN1)
5562 		xcrl = d2i_X509_CRL_bio(bcrl, NULL);
5563 	else if (crl_format == KMF_FORMAT_PEM)
5564 		xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
5565 
5566 	if (xcrl == NULL) {
5567 		SET_ERROR(kmfh, ERR_get_error());
5568 		ret = KMF_ERR_BAD_CRLFILE;
5569 		goto cleanup;
5570 	}
5571 	i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL);
5572 	if (i >= 0) {
5573 		ret = KMF_ERR_VALIDITY_PERIOD;
5574 		goto cleanup;
5575 	}
5576 	if (X509_CRL_get_nextUpdate(xcrl)) {
5577 		i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL);
5578 
5579 		if (i <= 0) {
5580 			ret = KMF_ERR_VALIDITY_PERIOD;
5581 			goto cleanup;
5582 		}
5583 	}
5584 
5585 	ret = KMF_OK;
5586 
5587 cleanup:
5588 	if (bcrl != NULL)
5589 		(void) BIO_free(bcrl);
5590 
5591 	if (xcrl != NULL)
5592 		X509_CRL_free(xcrl);
5593 
5594 	return (ret);
5595 }
5596