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