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