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