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