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