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