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