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