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