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