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