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