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