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