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