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