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