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