openssl_spi.c revision 4067:54aaa1fa93ec
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, n;
1001	uint32_t maxcerts = 0;
1002
1003	if (num_certs == NULL || params == NULL)
1004		return (KMF_ERR_BAD_PARAMETER);
1005
1006	maxcerts = *num_certs;
1007	if (maxcerts == 0)
1008		maxcerts = 0xFFFFFFFF;
1009	*num_certs = 0;
1010
1011	fullpath = get_fullpath(params->sslparms.dirpath,
1012		params->sslparms.certfile);
1013
1014	if (fullpath == NULL)
1015		return (KMF_ERR_BAD_PARAMETER);
1016
1017	if (isdir(fullpath)) {
1018		DIR *dirp;
1019		struct dirent *dp;
1020
1021		n = 0;
1022		/* open all files in the directory and attempt to read them */
1023		if ((dirp = opendir(fullpath)) == NULL) {
1024			return (KMF_ERR_BAD_PARAMETER);
1025		}
1026		while ((dp = readdir(dirp)) != NULL) {
1027			char *fname;
1028			KMF_DATA *certlist = NULL;
1029			uint32_t loaded_certs = 0;
1030
1031			if (strcmp(dp->d_name, ".") == 0 ||
1032			    strcmp(dp->d_name, "..") == 0)
1033				continue;
1034
1035			fname = get_fullpath(fullpath,
1036				(char *)&dp->d_name);
1037
1038			rv = load_certs(kmfh, params, fname, &certlist,
1039				&loaded_certs);
1040
1041			if (rv != KMF_OK) {
1042				free(fname);
1043				if (certlist != NULL) {
1044					for (i = 0; i < loaded_certs; i++)
1045						KMF_FreeData(&certlist[i]);
1046					free(certlist);
1047				}
1048				continue;
1049			}
1050
1051			/* If load succeeds, add certdata to the list */
1052			if (kmf_cert != NULL) {
1053				for (i = 0; i < loaded_certs &&
1054				    i < maxcerts; i++) {
1055					kmf_cert[n].certificate.Data =
1056						certlist[i].Data;
1057					kmf_cert[n].certificate.Length =
1058						certlist[i].Length;
1059
1060					kmf_cert[n].kmf_private.keystore_type =
1061						KMF_KEYSTORE_OPENSSL;
1062					kmf_cert[n].kmf_private.flags =
1063						KMF_FLAG_CERT_VALID;
1064					kmf_cert[n].kmf_private.label =
1065						strdup(fname);
1066					n++;
1067				}
1068				/* If maxcerts < loaded_certs, clean up */
1069				for (; i < loaded_certs; i++)
1070					KMF_FreeData(&certlist[i]);
1071			} else {
1072				for (i = 0; i < loaded_certs; i++)
1073					KMF_FreeData(&certlist[i]);
1074				n += loaded_certs;
1075			}
1076			free(certlist);
1077			free(fname);
1078		}
1079		(*num_certs) = n;
1080		if (*num_certs == 0)
1081			rv = KMF_ERR_CERT_NOT_FOUND;
1082		else
1083			rv = KMF_OK;
1084exit:
1085		(void) closedir(dirp);
1086	} else {
1087		KMF_DATA *certlist = NULL;
1088		uint32_t loaded_certs = 0;
1089
1090		rv = load_certs(kmfh, params, fullpath,
1091			&certlist, &loaded_certs);
1092		if (rv != KMF_OK) {
1093			free(fullpath);
1094			return (rv);
1095		}
1096
1097		n = 0;
1098		if (kmf_cert != NULL && certlist != NULL) {
1099			for (i = 0; i < loaded_certs && i < maxcerts; i++) {
1100				kmf_cert[n].certificate.Data =
1101					certlist[i].Data;
1102				kmf_cert[n].certificate.Length =
1103					certlist[i].Length;
1104				kmf_cert[n].kmf_private.keystore_type =
1105					KMF_KEYSTORE_OPENSSL;
1106				kmf_cert[n].kmf_private.flags =
1107					KMF_FLAG_CERT_VALID;
1108				kmf_cert[n].kmf_private.label =
1109					strdup(fullpath);
1110				n++;
1111			}
1112			/* If maxcerts < loaded_certs, clean up */
1113			for (; i < loaded_certs; i++)
1114				KMF_FreeData(&certlist[i]);
1115		} else if (certlist != NULL) {
1116			for (i = 0; i < loaded_certs; i++)
1117				KMF_FreeData(&certlist[i]);
1118			n = loaded_certs;
1119		}
1120		if (certlist)
1121			free(certlist);
1122
1123		*num_certs = n;
1124	}
1125
1126	free(fullpath);
1127
1128	return (rv);
1129}
1130
1131void
1132/*ARGSUSED*/
1133OpenSSL_FreeKMFCert(KMF_HANDLE_T handle,
1134	KMF_X509_DER_CERT *kmf_cert)
1135{
1136	if (kmf_cert != NULL) {
1137		if (kmf_cert->certificate.Data != NULL) {
1138			free(kmf_cert->certificate.Data);
1139			kmf_cert->certificate.Data = NULL;
1140			kmf_cert->certificate.Length = 0;
1141		}
1142		if (kmf_cert->kmf_private.label)
1143			free(kmf_cert->kmf_private.label);
1144	}
1145}
1146
1147KMF_RETURN
1148OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params,
1149    KMF_DATA * pcert)
1150{
1151	KMF_RETURN ret = KMF_OK;
1152	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1153	X509 *xcert = NULL;
1154	FILE *fp;
1155	unsigned char *outbuf;
1156	unsigned char *outbuf_p;
1157	char *fullpath;
1158	int outbuflen;
1159	int len;
1160	KMF_ENCODE_FORMAT format;
1161
1162	if (params == NULL || params->ks_opt_u.openssl_opts.certfile == NULL) {
1163		return (KMF_ERR_BAD_PARAMETER);
1164	}
1165
1166	/*
1167	 * check if the cert output format is supported by OPENSSL.
1168	 * however, since the keystore for OPENSSL is just a file, we have
1169	 * no way to store the format along with the file.
1170	 */
1171	format = params->sslparms.format;
1172	if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM)
1173		return (KMF_ERR_BAD_CERT_FORMAT);
1174
1175
1176	fullpath = get_fullpath(params->sslparms.dirpath,
1177		params->sslparms.certfile);
1178	if (fullpath == NULL)
1179		return (KMF_ERR_BAD_PARAMETER);
1180
1181	/*
1182	 * When storing a certificate, you must specify a filename.
1183	 */
1184	if (isdir(fullpath)) {
1185		free(fullpath);
1186		return (KMF_ERR_BAD_PARAMETER);
1187	}
1188
1189	/* copy cert data to outbuf */
1190	outbuflen = pcert->Length;
1191	outbuf = malloc(outbuflen);
1192	if (outbuf == NULL) {
1193		free(fullpath);
1194		return (KMF_ERR_MEMORY);
1195	}
1196	(void) memcpy(outbuf, pcert->Data, pcert->Length);
1197
1198	if ((fp = fopen(fullpath, "w")) ==
1199		NULL) {
1200		SET_SYS_ERROR(kmfh, errno);
1201		ret = KMF_ERR_INTERNAL;
1202		goto out;
1203	}
1204
1205	if (format == KMF_FORMAT_ASN1) {
1206		len = fwrite(outbuf, 1, outbuflen, fp);
1207		if (len != outbuflen) {
1208			SET_SYS_ERROR(kmfh, errno);
1209			ret = KMF_ERR_WRITE_FILE;
1210		} else {
1211			ret = KMF_OK;
1212		}
1213		goto out;
1214	}
1215
1216	/*
1217	 * The output format is not KMF_FORMAT_ASN1, so we will
1218	 * Convert the cert data to OpenSSL internal X509 first.
1219	 */
1220	outbuf_p = outbuf; /* use a temp pointer; required by openssl */
1221	xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, outbuflen);
1222	if (xcert == NULL) {
1223		SET_ERROR(kmfh, ERR_get_error());
1224		ret = KMF_ERR_ENCODING;
1225		goto out;
1226	}
1227
1228	if (format == KMF_FORMAT_PEM) {
1229		/* Convert to the PEM format and write it out */
1230		if (!PEM_write_X509(fp, xcert)) {
1231			SET_ERROR(kmfh, ERR_get_error());
1232			ret = KMF_ERR_ENCODING;
1233		} else {
1234			ret = KMF_OK;
1235		}
1236		goto out;
1237	}
1238
1239out:
1240	if (fullpath != NULL)
1241		free(fullpath);
1242
1243	if (outbuf != NULL) {
1244		free(outbuf);
1245	}
1246	if (fp != NULL) {
1247		(void) fclose(fp);
1248	}
1249
1250	if (xcert != NULL) {
1251		X509_free(xcert);
1252	}
1253
1254	return (ret);
1255}
1256
1257KMF_RETURN
1258OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params)
1259{
1260	KMF_RETURN rv;
1261	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1262	char *fullpath = NULL;
1263	KMF_DATA certdata = {NULL, 0};
1264
1265	if (params == NULL) {
1266		return (KMF_ERR_BAD_PARAMETER);
1267	}
1268
1269	fullpath = get_fullpath(params->sslparms.dirpath,
1270		params->sslparms.certfile);
1271
1272	if (fullpath == NULL)
1273		return (KMF_ERR_BAD_PARAMETER);
1274
1275	if (isdir(fullpath)) {
1276		DIR *dirp;
1277		struct dirent *dp;
1278
1279		/* open all files in the directory and attempt to read them */
1280		if ((dirp = opendir(fullpath)) == NULL) {
1281			return (KMF_ERR_BAD_PARAMETER);
1282		}
1283
1284		while ((dp = readdir(dirp)) != NULL) {
1285			if (strcmp(dp->d_name, ".") != 0 &&
1286			    strcmp(dp->d_name, "..") != 0) {
1287				char *fname;
1288
1289				fname = get_fullpath(fullpath,
1290					(char *)&dp->d_name);
1291
1292				if (fname == NULL) {
1293					rv = KMF_ERR_MEMORY;
1294					break;
1295				}
1296
1297				rv = kmf_load_cert(kmfh, params, fname,
1298				    &certdata);
1299
1300				if (rv == KMF_ERR_CERT_NOT_FOUND) {
1301					free(fname);
1302					if (certdata.Data)
1303						free(certdata.Data);
1304					rv = KMF_OK;
1305					continue;
1306				} else if (rv != KMF_OK) {
1307					free(fname);
1308					break;
1309				}
1310
1311				if (unlink(fname) != 0) {
1312					SET_SYS_ERROR(kmfh, errno);
1313					rv = KMF_ERR_INTERNAL;
1314					free(fname);
1315					break;
1316				}
1317				free(fname);
1318				if (certdata.Data)
1319					free(certdata.Data);
1320			}
1321		}
1322		(void) closedir(dirp);
1323	} else {
1324		/* Just try to load a single certificate */
1325		rv = kmf_load_cert(kmfh, params, fullpath, &certdata);
1326		if (rv == KMF_OK) {
1327			if (unlink(fullpath) != 0) {
1328				SET_SYS_ERROR(kmfh, errno);
1329				rv = KMF_ERR_INTERNAL;
1330			}
1331		}
1332	}
1333
1334out:
1335	if (fullpath != NULL)
1336		free(fullpath);
1337
1338	if (certdata.Data)
1339		free(certdata.Data);
1340
1341	return (rv);
1342}
1343
1344KMF_RETURN
1345OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
1346	KMF_DATA *keydata)
1347{
1348	KMF_RETURN rv = KMF_OK;
1349	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1350	int n;
1351
1352	if (key == NULL || keydata == NULL ||
1353	    key->keyp == NULL)
1354		return (KMF_ERR_BAD_PARAMETER);
1355
1356	if (key->keyalg == KMF_RSA) {
1357		RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp);
1358
1359		if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) {
1360			SET_ERROR(kmfh, ERR_get_error());
1361			return (KMF_ERR_ENCODING);
1362		}
1363		RSA_free(pubkey);
1364	} else if (key->keyalg == KMF_DSA) {
1365		DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp);
1366
1367		if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) {
1368			SET_ERROR(kmfh, ERR_get_error());
1369			return (KMF_ERR_ENCODING);
1370		}
1371		DSA_free(pubkey);
1372	} else {
1373	    return (KMF_ERR_BAD_PARAMETER);
1374	}
1375	keydata->Length = n;
1376
1377cleanup:
1378	if (rv != KMF_OK) {
1379		if (keydata->Data)
1380			free(keydata->Data);
1381		keydata->Data = NULL;
1382		keydata->Length = 0;
1383	}
1384
1385	return (rv);
1386}
1387
1388static KMF_RETURN
1389ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out,
1390	KMF_CREDENTIAL *cred, EVP_PKEY *pkey)
1391{
1392	int rv = 0;
1393	RSA *rsa;
1394	DSA *dsa;
1395
1396	switch (format) {
1397		case KMF_FORMAT_ASN1:
1398			if (pkey->type == EVP_PKEY_RSA) {
1399				rsa = EVP_PKEY_get1_RSA(pkey);
1400				rv = i2d_RSAPrivateKey_bio(out, rsa);
1401				RSA_free(rsa);
1402			} else if (pkey->type == EVP_PKEY_DSA) {
1403				dsa = EVP_PKEY_get1_DSA(pkey);
1404				rv = i2d_DSAPrivateKey_bio(out, dsa);
1405				DSA_free(dsa);
1406			}
1407			if (rv == 1) {
1408				rv = KMF_OK;
1409			} else {
1410				SET_ERROR(kmfh, rv);
1411			}
1412			break;
1413		case KMF_FORMAT_PEM:
1414			if (pkey->type == EVP_PKEY_RSA) {
1415				rsa = EVP_PKEY_get1_RSA(pkey);
1416				rv = PEM_write_bio_RSAPrivateKey(out,
1417					rsa,
1418					NULL /* encryption type */,
1419					NULL, 0, NULL,
1420					cred->cred);
1421				RSA_free(rsa);
1422			} else if (pkey->type == EVP_PKEY_DSA) {
1423				dsa = EVP_PKEY_get1_DSA(pkey);
1424				rv = PEM_write_bio_DSAPrivateKey(out,
1425					dsa,
1426					NULL /* encryption type */,
1427					NULL, 0, NULL,
1428					cred->cred);
1429				DSA_free(dsa);
1430			}
1431
1432			if (rv == 1) {
1433				rv = KMF_OK;
1434			} else {
1435				SET_ERROR(kmfh, rv);
1436			}
1437			break;
1438
1439		default:
1440			rv = KMF_ERR_BAD_PARAMETER;
1441	}
1442
1443	return (rv);
1444}
1445
1446KMF_RETURN
1447OpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params,
1448	KMF_KEY_HANDLE *privkey, KMF_KEY_HANDLE *pubkey)
1449{
1450	KMF_RETURN rv = KMF_OK;
1451	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1452	int format;
1453	uint32_t eValue = 0x010001;
1454	RSA *sslPrivKey = NULL;
1455	DSA *sslDSAKey = NULL;
1456	EVP_PKEY *eprikey = NULL;
1457	EVP_PKEY *epubkey = NULL;
1458	BIO *out = NULL;
1459	char *fullpath = NULL;
1460
1461	if (params == NULL || params->sslparms.keyfile == NULL) {
1462		return (KMF_ERR_BAD_PARAMETER);
1463	}
1464
1465	fullpath = get_fullpath(params->sslparms.dirpath,
1466			params->sslparms.keyfile);
1467
1468	if (fullpath == NULL)
1469		return (KMF_ERR_BAD_PARAMETER);
1470
1471	/* If the requested file exists, return an error */
1472	if (access(fullpath, F_OK) == 0) {
1473		free(fullpath);
1474		return (KMF_ERR_DUPLICATE_KEYFILE);
1475	}
1476
1477	eprikey = EVP_PKEY_new();
1478	if (eprikey == NULL) {
1479		SET_ERROR(kmfh, ERR_get_error());
1480		rv = KMF_ERR_KEYGEN_FAILED;
1481		goto cleanup;
1482	}
1483	epubkey = EVP_PKEY_new();
1484	if (epubkey == NULL) {
1485		SET_ERROR(kmfh, ERR_get_error());
1486		rv = KMF_ERR_KEYGEN_FAILED;
1487		goto cleanup;
1488	}
1489	if (params->keytype == KMF_RSA) {
1490		if (params->rsa_exponent.len > 0 &&
1491		    params->rsa_exponent.len <= sizeof (eValue) &&
1492		    params->rsa_exponent.val != NULL)
1493			/*LINTED*/
1494			eValue = *(uint32_t *)params->rsa_exponent.val;
1495
1496		sslPrivKey = RSA_generate_key(params->keylength, eValue,
1497			NULL, NULL);
1498		if (sslPrivKey == NULL) {
1499			SET_ERROR(kmfh, ERR_get_error());
1500			rv = KMF_ERR_KEYGEN_FAILED;
1501		} else {
1502			if (privkey != NULL &&
1503				EVP_PKEY_set1_RSA(eprikey, sslPrivKey)) {
1504				privkey->kstype = KMF_KEYSTORE_OPENSSL;
1505				privkey->keyalg = KMF_RSA;
1506				privkey->keyclass = KMF_ASYM_PRI;
1507				privkey->israw = FALSE;
1508				privkey->keylabel = (char *)strdup(fullpath);
1509				privkey->keyp = (void *)eprikey;
1510			}
1511			/* OpenSSL derives the public key from the private */
1512			if (pubkey != NULL &&
1513				EVP_PKEY_set1_RSA(epubkey, sslPrivKey)) {
1514				pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1515				pubkey->keyalg = KMF_RSA;
1516				pubkey->israw = FALSE;
1517				pubkey->keyclass = KMF_ASYM_PUB;
1518				pubkey->keylabel = (char *)strdup(fullpath);
1519				pubkey->keyp = (void *)epubkey;
1520			}
1521		}
1522	} else if (params->keytype == KMF_DSA) {
1523		sslDSAKey = DSA_new();
1524		if (sslDSAKey == NULL) {
1525			SET_ERROR(kmfh, ERR_get_error());
1526			return (KMF_ERR_MEMORY);
1527		}
1528
1529		if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) ==
1530			NULL) {
1531			SET_ERROR(kmfh, ERR_get_error());
1532			rv = KMF_ERR_KEYGEN_FAILED;
1533			goto cleanup;
1534		}
1535		if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) ==
1536			NULL) {
1537			SET_ERROR(kmfh, ERR_get_error());
1538			rv = KMF_ERR_KEYGEN_FAILED;
1539			goto cleanup;
1540		}
1541		if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) ==
1542			NULL) {
1543			SET_ERROR(kmfh, ERR_get_error());
1544			rv = KMF_ERR_KEYGEN_FAILED;
1545			goto cleanup;
1546		}
1547
1548		if (!DSA_generate_key(sslDSAKey)) {
1549			SET_ERROR(kmfh, ERR_get_error());
1550			rv = KMF_ERR_KEYGEN_FAILED;
1551			goto cleanup;
1552		}
1553
1554		if (privkey != NULL) {
1555			privkey->kstype = KMF_KEYSTORE_OPENSSL;
1556			privkey->keyalg = KMF_DSA;
1557			privkey->keyclass = KMF_ASYM_PRI;
1558			privkey->israw = FALSE;
1559			privkey->keylabel = (char *)strdup(fullpath);
1560			if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) {
1561				privkey->keyp = (void *)eprikey;
1562			} else {
1563				SET_ERROR(kmfh, ERR_get_error());
1564				rv = KMF_ERR_KEYGEN_FAILED;
1565				goto cleanup;
1566			}
1567		}
1568		if (pubkey != NULL) {
1569			DSA *dp = DSA_new();
1570			/* Make a copy for the public key */
1571			if (dp != NULL) {
1572				if ((dp->p = BN_new()) == NULL) {
1573					SET_ERROR(kmfh, ERR_get_error());
1574					rv = KMF_ERR_MEMORY;
1575					DSA_free(dp);
1576					goto cleanup;
1577				}
1578				if ((dp->q = BN_new()) == NULL) {
1579					SET_ERROR(kmfh, ERR_get_error());
1580					rv = KMF_ERR_MEMORY;
1581					BN_free(dp->p);
1582					DSA_free(dp);
1583					goto cleanup;
1584				}
1585				if ((dp->g = BN_new()) == NULL) {
1586					SET_ERROR(kmfh, ERR_get_error());
1587					rv = KMF_ERR_MEMORY;
1588					BN_free(dp->q);
1589					BN_free(dp->p);
1590					DSA_free(dp);
1591					goto cleanup;
1592				}
1593				if ((dp->pub_key = BN_new()) == NULL) {
1594					SET_ERROR(kmfh, ERR_get_error());
1595					rv = KMF_ERR_MEMORY;
1596					BN_free(dp->q);
1597					BN_free(dp->p);
1598					BN_free(dp->g);
1599					DSA_free(dp);
1600					goto cleanup;
1601				}
1602				(void) BN_copy(dp->p, sslDSAKey->p);
1603				(void) BN_copy(dp->q, sslDSAKey->q);
1604				(void) BN_copy(dp->g, sslDSAKey->g);
1605				(void) BN_copy(dp->pub_key, sslDSAKey->pub_key);
1606
1607				pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1608				pubkey->keyalg = KMF_DSA;
1609				pubkey->keyclass = KMF_ASYM_PUB;
1610				pubkey->israw = FALSE;
1611				pubkey->keylabel = (char *)strdup(fullpath);
1612
1613				if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) {
1614					pubkey->keyp = (void *)epubkey;
1615				} else {
1616					SET_ERROR(kmfh, ERR_get_error());
1617					rv = KMF_ERR_KEYGEN_FAILED;
1618					goto cleanup;
1619				}
1620			}
1621		}
1622	}
1623
1624	if (rv != KMF_OK) {
1625		goto cleanup;
1626	}
1627
1628	/* Store the private key to the keyfile */
1629	format = params->sslparms.format;
1630	out = BIO_new_file(fullpath, "wb");
1631	if (out == NULL) {
1632		SET_ERROR(kmfh, ERR_get_error());
1633		rv = KMF_ERR_OPEN_FILE;
1634		goto cleanup;
1635	}
1636	rv = ssl_write_private_key(kmfh, format, out, &params->cred, eprikey);
1637
1638cleanup:
1639	if (rv != KMF_OK) {
1640		if (eprikey != NULL)
1641			EVP_PKEY_free(eprikey);
1642
1643		if (epubkey != NULL)
1644			EVP_PKEY_free(epubkey);
1645
1646		if (pubkey->keylabel) {
1647			free(pubkey->keylabel);
1648			pubkey->keylabel = NULL;
1649		}
1650
1651		if (privkey->keylabel) {
1652			free(privkey->keylabel);
1653			privkey->keylabel = NULL;
1654		}
1655
1656		pubkey->keyp = NULL;
1657		privkey->keyp = NULL;
1658	}
1659
1660	if (sslPrivKey)
1661		RSA_free(sslPrivKey);
1662
1663	if (sslDSAKey)
1664		DSA_free(sslDSAKey);
1665
1666
1667	if (out != NULL)
1668		(void) BIO_free(out);
1669
1670	if (fullpath)
1671		free(fullpath);
1672
1673	/* Protect the file by making it read-only */
1674	if (rv == KMF_OK) {
1675		(void) chmod(fullpath, 0400);
1676	}
1677	return (rv);
1678}
1679
1680KMF_RETURN
1681OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
1682	KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output)
1683{
1684	KMF_RETURN ret = KMF_OK;
1685	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1686	KMF_ALGORITHM_INDEX		AlgId;
1687	EVP_MD_CTX ctx;
1688	const EVP_MD *md;
1689
1690	if (key == NULL || AlgOID == NULL ||
1691		tobesigned == NULL || output == NULL ||
1692		tobesigned->Data == NULL ||
1693		output->Data == NULL)
1694		return (KMF_ERR_BAD_PARAMETER);
1695
1696	/* Map the OID to an OpenSSL algorithm */
1697	AlgId = X509_AlgorithmOidToAlgId(AlgOID);
1698	if (AlgId == KMF_ALGID_NONE)
1699		return (KMF_ERR_BAD_PARAMETER);
1700
1701	if (key->keyalg == KMF_RSA) {
1702		EVP_PKEY *pkey = (EVP_PKEY *)key->keyp;
1703		uchar_t *p;
1704		int len;
1705		if (AlgId == KMF_ALGID_MD5WithRSA)
1706			md = EVP_md5();
1707		else if (AlgId == KMF_ALGID_MD2WithRSA)
1708			md = EVP_md2();
1709		else if (AlgId == KMF_ALGID_SHA1WithRSA)
1710			md = EVP_sha1();
1711		else if (AlgId == KMF_ALGID_RSA)
1712			md = NULL;
1713		else
1714			return (KMF_ERR_BAD_PARAMETER);
1715
1716		if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) {
1717			RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey);
1718
1719			p = output->Data;
1720			if ((len = RSA_private_encrypt(tobesigned->Length,
1721				tobesigned->Data, p, rsa,
1722				RSA_PKCS1_PADDING)) <= 0) {
1723				SET_ERROR(kmfh, ERR_get_error());
1724				ret = KMF_ERR_INTERNAL;
1725			}
1726			output->Length = len;
1727		} else {
1728			(void) EVP_MD_CTX_init(&ctx);
1729			(void) EVP_SignInit_ex(&ctx, md, NULL);
1730			(void) EVP_SignUpdate(&ctx, tobesigned->Data,
1731				(uint32_t)tobesigned->Length);
1732			len = (uint32_t)output->Length;
1733			p = output->Data;
1734			if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) {
1735				SET_ERROR(kmfh, ERR_get_error());
1736				len = 0;
1737				ret = KMF_ERR_INTERNAL;
1738			}
1739			output->Length = len;
1740			(void) EVP_MD_CTX_cleanup(&ctx);
1741		}
1742	} else if (key->keyalg == KMF_DSA) {
1743		DSA *dsa = EVP_PKEY_get1_DSA(key->keyp);
1744
1745		uchar_t hash[EVP_MAX_MD_SIZE];
1746		uint32_t hashlen;
1747		DSA_SIG *dsasig;
1748
1749		/*
1750		 * OpenSSL EVP_Sign operation automatically converts to
1751		 * ASN.1 output so we do the operations separately so we
1752		 * are assured of NOT getting ASN.1 output returned.
1753		 * KMF does not want ASN.1 encoded results because
1754		 * not all mechanisms return ASN.1 encodings (PKCS#11
1755		 * and NSS return raw signature data).
1756		 */
1757		md = EVP_sha1();
1758		EVP_MD_CTX_init(&ctx);
1759		(void) EVP_DigestInit_ex(&ctx, md, NULL);
1760		(void) EVP_DigestUpdate(&ctx, tobesigned->Data,
1761			tobesigned->Length);
1762		(void) EVP_DigestFinal_ex(&ctx, hash, &hashlen);
1763		(void) EVP_MD_CTX_cleanup(&ctx);
1764
1765		dsasig = DSA_do_sign(hash, hashlen, dsa);
1766		if (dsasig != NULL) {
1767			int i;
1768			output->Length = i = BN_bn2bin(dsasig->r, output->Data);
1769			output->Length += BN_bn2bin(dsasig->s,
1770				&output->Data[i]);
1771			DSA_SIG_free(dsasig);
1772		} else {
1773			SET_ERROR(kmfh, ERR_get_error());
1774		}
1775	} else {
1776		return (KMF_ERR_BAD_PARAMETER);
1777	}
1778cleanup:
1779	return (ret);
1780}
1781
1782KMF_RETURN
1783/*ARGSUSED*/
1784OpenSSL_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params,
1785	KMF_KEY_HANDLE *key, boolean_t destroy)
1786{
1787	KMF_RETURN rv = KMF_OK;
1788	if (key == NULL || key->keyp == NULL)
1789		return (KMF_ERR_BAD_PARAMETER);
1790
1791	if (key->keyclass != KMF_ASYM_PUB &&
1792		key->keyclass != KMF_ASYM_PRI &&
1793		key->keyclass != KMF_SYMMETRIC)
1794		return (KMF_ERR_BAD_KEY_CLASS);
1795
1796	if (key->keyclass == KMF_SYMMETRIC) {
1797		KMF_FreeRawSymKey((KMF_RAW_SYM_KEY *)key->keyp);
1798		key->keyp = NULL;
1799	} else {
1800		if (key->keyp != NULL) {
1801			EVP_PKEY_free(key->keyp);
1802			key->keyp = NULL;
1803		}
1804	}
1805
1806	if (key->keylabel != NULL) {
1807		EVP_PKEY *pkey = NULL;
1808		/* If the file exists, make sure it is a proper key. */
1809		pkey = openssl_load_key(handle, key->keylabel);
1810		if (pkey == NULL) {
1811			free(key->keylabel);
1812			key->keylabel = NULL;
1813			return (KMF_ERR_KEY_NOT_FOUND);
1814		}
1815		EVP_PKEY_free(pkey);
1816
1817		if (destroy) {
1818			if (unlink(key->keylabel) != 0) {
1819				KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1820				SET_SYS_ERROR(kmfh, errno);
1821				rv = KMF_ERR_INTERNAL;
1822			}
1823		}
1824		if (key->keylabel != NULL) {
1825			free(key->keylabel);
1826			key->keylabel = NULL;
1827		}
1828	}
1829	return (rv);
1830}
1831
1832KMF_RETURN
1833OpenSSL_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params)
1834{
1835	KMF_RETURN 	ret = KMF_OK;
1836	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1837	X509_CRL   	*xcrl = NULL;
1838	X509		*xcert = NULL;
1839	EVP_PKEY	*pkey;
1840	KMF_ENCODE_FORMAT format;
1841	BIO *in = NULL, *out = NULL;
1842	int openssl_ret = 0;
1843	char *outcrlfile = NULL;
1844	KMF_ENCODE_FORMAT outformat;
1845
1846	if (params == NULL || params->sslparms.crlfile == NULL) {
1847		return (KMF_ERR_BAD_PARAMETER);
1848	}
1849
1850	if (params->sslparms.crl_check == B_TRUE &&
1851	    params->sslparms.certfile == NULL) {
1852		return (KMF_ERR_BAD_PARAMETER);
1853	}
1854
1855	outcrlfile = get_fullpath(params->sslparms.dirpath,
1856		params->sslparms.outcrlfile);
1857
1858	if (outcrlfile == NULL)
1859		return (KMF_ERR_BAD_PARAMETER);
1860
1861	if (isdir(outcrlfile)) {
1862		free(outcrlfile);
1863		return (KMF_ERR_BAD_PARAMETER);
1864	}
1865
1866	ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format);
1867	if (ret != KMF_OK) {
1868		free(outcrlfile);
1869		return (ret);
1870	}
1871
1872	in = BIO_new_file(params->sslparms.crlfile, "rb");
1873	if (in == NULL)	{
1874		SET_ERROR(kmfh, ERR_get_error());
1875		ret = KMF_ERR_OPEN_FILE;
1876		goto end;
1877	}
1878
1879	if (format == KMF_FORMAT_ASN1) {
1880		xcrl = d2i_X509_CRL_bio(in, NULL);
1881	} else if (format == KMF_FORMAT_PEM) {
1882		xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
1883	}
1884
1885	if (xcrl == NULL) {
1886		SET_ERROR(kmfh, ERR_get_error());
1887		ret = KMF_ERR_BAD_CRLFILE;
1888		goto end;
1889	}
1890
1891	/* If bypasscheck is specified, no need to verify. */
1892	if (params->sslparms.crl_check == B_FALSE) {
1893		goto output;
1894	}
1895
1896	ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format);
1897	if (ret != KMF_OK)
1898		goto end;
1899
1900	/* Read in the CA cert file and convert to X509 */
1901	if (BIO_read_filename(in, params->sslparms.certfile) <= 0) {
1902		SET_ERROR(kmfh, ERR_get_error());
1903		ret = KMF_ERR_OPEN_FILE;
1904		goto end;
1905	}
1906
1907	if (format == KMF_FORMAT_ASN1) {
1908		xcert = d2i_X509_bio(in, NULL);
1909	} else if (format == KMF_FORMAT_PEM) {
1910		xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
1911	} else {
1912		ret = KMF_ERR_BAD_CERT_FORMAT;
1913		goto end;
1914	}
1915
1916	if (xcert == NULL) {
1917		SET_ERROR(kmfh, ERR_get_error());
1918		ret = KMF_ERR_BAD_CERT_FORMAT;
1919		goto end;
1920	}
1921	/* Now get the public key from the CA cert */
1922	pkey = X509_get_pubkey(xcert);
1923	if (!pkey) {
1924		SET_ERROR(kmfh, ERR_get_error());
1925		ret = KMF_ERR_BAD_CERTFILE;
1926		goto end;
1927	}
1928
1929	/* Verify the CRL with the CA's public key */
1930	openssl_ret = X509_CRL_verify(xcrl, pkey);
1931	EVP_PKEY_free(pkey);
1932	if (openssl_ret > 0) {
1933		ret = KMF_OK;  /* verify succeed */
1934	} else {
1935		SET_ERROR(kmfh, openssl_ret);
1936		ret = KMF_ERR_BAD_CRLFILE;
1937	}
1938
1939output:
1940	outformat = params->sslparms.format;
1941
1942	out = BIO_new_file(outcrlfile, "wb");
1943	if (out == NULL) {
1944		SET_ERROR(kmfh, ERR_get_error());
1945		ret = KMF_ERR_OPEN_FILE;
1946		goto end;
1947	}
1948
1949	if (outformat == KMF_FORMAT_ASN1) {
1950		openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl);
1951	} else if (outformat == KMF_FORMAT_PEM) {
1952		openssl_ret = PEM_write_bio_X509_CRL(out, xcrl);
1953	} else {
1954		ret = KMF_ERR_BAD_PARAMETER;
1955		goto end;
1956	}
1957
1958	if (openssl_ret <= 0) {
1959		SET_ERROR(kmfh, ERR_get_error());
1960		ret = KMF_ERR_WRITE_FILE;
1961	} else {
1962		ret = KMF_OK;
1963	}
1964
1965end:
1966	if (xcrl != NULL)
1967		X509_CRL_free(xcrl);
1968
1969	if (xcert != NULL)
1970		X509_free(xcert);
1971
1972	if (in != NULL)
1973		(void) BIO_free(in);
1974
1975	if (out != NULL)
1976		(void) BIO_free(out);
1977
1978	if (outcrlfile != NULL)
1979		free(outcrlfile);
1980
1981	return (ret);
1982}
1983
1984KMF_RETURN
1985OpenSSL_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params,
1986    char **crldata)
1987{
1988	KMF_RETURN ret = KMF_OK;
1989	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1990	X509_CRL   *x = NULL;
1991	KMF_ENCODE_FORMAT format;
1992	char *crlfile = NULL;
1993	BIO *in = NULL;
1994	BIO *mem = NULL;
1995	long len;
1996	char *memptr;
1997	char *data = NULL;
1998
1999	if (params == NULL || params->sslparms.crlfile == NULL) {
2000		return (KMF_ERR_BAD_PARAMETER);
2001	}
2002
2003	crlfile = get_fullpath(params->sslparms.dirpath,
2004		params->sslparms.crlfile);
2005
2006	if (crlfile == NULL)
2007		return (KMF_ERR_BAD_PARAMETER);
2008
2009	if (isdir(crlfile)) {
2010		free(crlfile);
2011		return (KMF_ERR_BAD_PARAMETER);
2012	}
2013
2014	ret = KMF_IsCRLFile(handle, crlfile, &format);
2015	if (ret != KMF_OK) {
2016		free(crlfile);
2017		return (ret);
2018	}
2019
2020	if (bio_err == NULL)
2021		bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
2022
2023	in = BIO_new_file(crlfile, "rb");
2024	if (in == NULL)	{
2025		SET_ERROR(kmfh, ERR_get_error());
2026		ret = KMF_ERR_OPEN_FILE;
2027		goto end;
2028	}
2029
2030	if (format == KMF_FORMAT_ASN1) {
2031		x = d2i_X509_CRL_bio(in, NULL);
2032	} else if (format == KMF_FORMAT_PEM) {
2033		x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
2034	}
2035
2036	if (x == NULL) { /* should not happen */
2037		SET_ERROR(kmfh, ERR_get_error());
2038		ret = KMF_ERR_OPEN_FILE;
2039		goto end;
2040	}
2041
2042	mem = BIO_new(BIO_s_mem());
2043	if (mem == NULL) {
2044		SET_ERROR(kmfh, ERR_get_error());
2045		ret = KMF_ERR_MEMORY;
2046		goto end;
2047	}
2048
2049	(void) X509_CRL_print(mem, x);
2050	len = BIO_get_mem_data(mem, &memptr);
2051	if (len <= 0) {
2052		SET_ERROR(kmfh, ERR_get_error());
2053		ret = KMF_ERR_MEMORY;
2054		goto end;
2055	}
2056
2057	data = malloc(len + 1);
2058	if (data == NULL) {
2059		ret = KMF_ERR_MEMORY;
2060		goto end;
2061	}
2062
2063	(void) memcpy(data, memptr, len);
2064	data[len] = '\0';
2065	*crldata = data;
2066
2067end:
2068	if (x != NULL)
2069		X509_CRL_free(x);
2070
2071	if (crlfile != NULL)
2072		free(crlfile);
2073
2074	if (in != NULL)
2075		(void) BIO_free(in);
2076
2077	if (mem != NULL)
2078		(void) BIO_free(mem);
2079
2080	return (ret);
2081}
2082
2083KMF_RETURN
2084OpenSSL_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params)
2085{
2086	KMF_RETURN ret = KMF_OK;
2087	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2088	KMF_ENCODE_FORMAT format;
2089	char *crlfile = NULL;
2090	BIO *in = NULL;
2091
2092	if (params == NULL || params->sslparms.crlfile == NULL) {
2093		return (KMF_ERR_BAD_PARAMETER);
2094	}
2095
2096	crlfile = get_fullpath(params->sslparms.dirpath,
2097		params->sslparms.crlfile);
2098
2099	if (crlfile == NULL)
2100		return (KMF_ERR_BAD_PARAMETER);
2101
2102	if (isdir(crlfile)) {
2103		ret = KMF_ERR_BAD_PARAMETER;
2104		goto end;
2105	}
2106
2107	ret = KMF_IsCRLFile(handle, crlfile, &format);
2108	if (ret != KMF_OK)
2109		goto end;
2110
2111	if (unlink(crlfile) != 0) {
2112		SET_SYS_ERROR(kmfh, errno);
2113		ret = KMF_ERR_INTERNAL;
2114		goto end;
2115	}
2116
2117end:
2118	if (in != NULL)
2119		(void) BIO_free(in);
2120	if (crlfile != NULL)
2121		free(crlfile);
2122
2123	return (ret);
2124}
2125
2126
2127KMF_RETURN
2128OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params)
2129{
2130	KMF_RETURN ret = KMF_OK;
2131	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2132	KMF_ENCODE_FORMAT format;
2133	BIO *in = NULL;
2134	X509   *xcert = NULL;
2135	X509_CRL   *xcrl = NULL;
2136	STACK_OF(X509_REVOKED) *revoke_stack = NULL;
2137	X509_REVOKED *revoke;
2138	int i;
2139
2140	if (params == NULL || params->sslparms.crlfile == NULL ||
2141	    params->sslparms.certfile == NULL) {
2142		return (KMF_ERR_BAD_PARAMETER);
2143	}
2144
2145	ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format);
2146	if (ret != KMF_OK)
2147		return (ret);
2148
2149	/* Read the CRL file and load it into a X509_CRL structure */
2150	in = BIO_new_file(params->sslparms.crlfile, "rb");
2151	if (in == NULL)	{
2152		SET_ERROR(kmfh, ERR_get_error());
2153		ret = KMF_ERR_OPEN_FILE;
2154		goto end;
2155	}
2156
2157	if (format == KMF_FORMAT_ASN1) {
2158		xcrl = d2i_X509_CRL_bio(in, NULL);
2159	} else if (format == KMF_FORMAT_PEM) {
2160		xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
2161	}
2162
2163	if (xcrl == NULL) {
2164		SET_ERROR(kmfh, ERR_get_error());
2165		ret = KMF_ERR_BAD_CRLFILE;
2166		goto end;
2167	}
2168	(void) BIO_free(in);
2169
2170	/* Read the Certificate file and load it into a X509 structure */
2171	ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format);
2172	if (ret != KMF_OK)
2173		goto end;
2174
2175	in = BIO_new_file(params->sslparms.certfile, "rb");
2176	if (in == NULL)	{
2177		SET_ERROR(kmfh, ERR_get_error());
2178		ret = KMF_ERR_OPEN_FILE;
2179		goto end;
2180	}
2181
2182	if (format == KMF_FORMAT_ASN1) {
2183		xcert = d2i_X509_bio(in, NULL);
2184	} else if (format == KMF_FORMAT_PEM) {
2185		xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
2186	}
2187
2188	if (xcert == NULL) {
2189		SET_ERROR(kmfh, ERR_get_error());
2190		ret = KMF_ERR_BAD_CERTFILE;
2191		goto end;
2192	}
2193
2194	/* Check if the certificate and the CRL have same issuer */
2195	if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) {
2196		ret = KMF_ERR_ISSUER;
2197		goto end;
2198	}
2199
2200	/* Check to see if the certificate serial number is revoked */
2201	revoke_stack = X509_CRL_get_REVOKED(xcrl);
2202	if (sk_X509_REVOKED_num(revoke_stack) <= 0) {
2203		/* No revoked certificates in the CRL file */
2204		SET_ERROR(kmfh, ERR_get_error());
2205		ret = KMF_ERR_EMPTY_CRL;
2206		goto end;
2207	}
2208
2209	for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) {
2210		/*LINTED*/
2211		revoke = sk_X509_REVOKED_value(revoke_stack, i);
2212		if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber,
2213		    revoke->serialNumber) == 0) {
2214			break;
2215		}
2216	}
2217
2218	if (i < sk_X509_REVOKED_num(revoke_stack)) {
2219		ret = KMF_OK;
2220	} else {
2221		ret = KMF_ERR_NOT_REVOKED;
2222	}
2223
2224end:
2225	if (in != NULL)
2226		(void) BIO_free(in);
2227	if (xcrl != NULL)
2228		X509_CRL_free(xcrl);
2229	if (xcert != NULL)
2230		X509_free(xcert);
2231
2232	return (ret);
2233}
2234
2235KMF_RETURN
2236OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
2237{
2238	KMF_RETURN ret = KMF_OK;
2239	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2240	char str[256];	/* OpenSSL needs at least 120 byte buffer */
2241
2242	ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str));
2243	if (strlen(str)) {
2244		*msgstr = (char *)strdup(str);
2245		if ((*msgstr) == NULL)
2246			ret = KMF_ERR_MEMORY;
2247	} else {
2248		*msgstr = NULL;
2249	}
2250
2251	return (ret);
2252}
2253
2254static int
2255ext2NID(int kmfext)
2256{
2257	switch (kmfext) {
2258		case KMF_X509_EXT_KEY_USAGE:
2259			return (NID_key_usage);
2260		case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
2261			return (NID_private_key_usage_period);
2262		case KMF_X509_EXT_CERT_POLICIES:
2263			return (NID_certificate_policies);
2264		case KMF_X509_EXT_SUBJ_ALTNAME:
2265			return (NID_subject_alt_name);
2266		case KMF_X509_EXT_ISSUER_ALTNAME:
2267			return (NID_issuer_alt_name);
2268		case KMF_X509_EXT_BASIC_CONSTRAINTS:
2269			return (NID_basic_constraints);
2270		case KMF_X509_EXT_EXT_KEY_USAGE:
2271			return (NID_ext_key_usage);
2272		case KMF_X509_EXT_AUTH_KEY_ID:
2273			return (NID_authority_key_identifier);
2274		case KMF_X509_EXT_CRL_DIST_POINTS:
2275			return (NID_crl_distribution_points);
2276		case KMF_X509_EXT_SUBJ_KEY_ID:
2277			return (NID_subject_key_identifier);
2278		case KMF_X509_EXT_POLICY_MAPPINGS:
2279			return (OBJ_sn2nid("policyMappings"));
2280		case KMF_X509_EXT_NAME_CONSTRAINTS:
2281			return (OBJ_sn2nid("nameConstraints"));
2282		case KMF_X509_EXT_POLICY_CONSTRAINTS:
2283			return (OBJ_sn2nid("policyConstraints"));
2284		case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2285			return (OBJ_sn2nid("inhibitAnyPolicy"));
2286		case KMF_X509_EXT_FRESHEST_CRL:
2287			return (OBJ_sn2nid("freshestCRL"));
2288		default:
2289			return (NID_undef);
2290	}
2291}
2292
2293KMF_RETURN
2294OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert,
2295	KMF_PRINTABLE_ITEM flag, char *resultStr)
2296{
2297	KMF_RETURN ret = KMF_OK;
2298	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2299	X509 *xcert = NULL;
2300	unsigned char *outbuf = NULL;
2301	unsigned char *outbuf_p;
2302	char *tmpstr = NULL;
2303	int j;
2304	int ext_index, nid, len;
2305	BIO *mem = NULL;
2306	STACK *emlst = NULL;
2307	X509_EXTENSION *ex;
2308	X509_CINF *ci;
2309
2310	if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) {
2311		return (KMF_ERR_BAD_PARAMETER);
2312	}
2313
2314	/* copy cert data to outbuf */
2315	outbuf = malloc(pcert->Length);
2316	if (outbuf == NULL) {
2317		return (KMF_ERR_MEMORY);
2318	}
2319	(void) memcpy(outbuf, pcert->Data, pcert->Length);
2320
2321	outbuf_p = outbuf; /* use a temp pointer; required by openssl */
2322	xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length);
2323	if (xcert == NULL) {
2324		SET_ERROR(kmfh, ERR_get_error());
2325		ret = KMF_ERR_ENCODING;
2326		goto out;
2327	}
2328
2329	mem = BIO_new(BIO_s_mem());
2330	if (mem == NULL) {
2331		SET_ERROR(kmfh, ERR_get_error());
2332		ret = KMF_ERR_MEMORY;
2333		goto out;
2334	}
2335
2336	switch (flag) {
2337	case KMF_CERT_ISSUER:
2338		(void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0,
2339		    XN_FLAG_SEP_CPLUS_SPC);
2340		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2341		break;
2342
2343	case KMF_CERT_SUBJECT:
2344		(void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0,
2345		    XN_FLAG_SEP_CPLUS_SPC);
2346		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2347		break;
2348
2349	case KMF_CERT_VERSION:
2350		tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version);
2351		(void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN);
2352		OPENSSL_free(tmpstr);
2353		len = strlen(resultStr);
2354		break;
2355
2356	case KMF_CERT_SERIALNUM:
2357		if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) {
2358			(void) strcpy(resultStr, "0x");
2359			len = BIO_gets(mem, &resultStr[2],
2360				KMF_CERT_PRINTABLE_LEN - 2);
2361		}
2362		break;
2363
2364	case KMF_CERT_NOTBEFORE:
2365		(void) ASN1_TIME_print(mem, X509_get_notBefore(xcert));
2366		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2367		break;
2368
2369	case KMF_CERT_NOTAFTER:
2370		(void) ASN1_TIME_print(mem, X509_get_notAfter(xcert));
2371		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2372		break;
2373
2374	case KMF_CERT_PUBKEY_DATA:
2375		{
2376			EVP_PKEY *pkey = X509_get_pubkey(xcert);
2377			if (pkey == NULL) {
2378				SET_ERROR(kmfh, ERR_get_error());
2379				ret = KMF_ERR_ENCODING;
2380				goto out;
2381			}
2382
2383			if (pkey->type == EVP_PKEY_RSA) {
2384				(void) BIO_printf(mem,
2385					"RSA Public Key: (%d bit)\n",
2386					BN_num_bits(pkey->pkey.rsa->n));
2387				(void) RSA_print(mem, pkey->pkey.rsa, 0);
2388			} else if (pkey->type == EVP_PKEY_DSA) {
2389				(void) BIO_printf(mem,
2390					"%12sDSA Public Key:\n", "");
2391				(void) DSA_print(mem, pkey->pkey.dsa, 0);
2392			} else {
2393				(void) BIO_printf(mem,
2394					"%12sUnknown Public Key:\n", "");
2395			}
2396			(void) BIO_printf(mem, "\n");
2397			EVP_PKEY_free(pkey);
2398		}
2399		len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2400		break;
2401	case KMF_CERT_SIGNATURE_ALG:
2402	case KMF_CERT_PUBKEY_ALG:
2403		if (flag == KMF_CERT_SIGNATURE_ALG) {
2404			len = i2a_ASN1_OBJECT(mem,
2405				xcert->sig_alg->algorithm);
2406		} else {
2407			len = i2a_ASN1_OBJECT(mem,
2408				xcert->cert_info->key->algor->algorithm);
2409		}
2410
2411		if (len > 0) {
2412			len = BIO_read(mem, resultStr,
2413				KMF_CERT_PRINTABLE_LEN);
2414		}
2415		break;
2416
2417	case KMF_CERT_EMAIL:
2418		emlst = X509_get1_email(xcert);
2419		for (j = 0; j < sk_num(emlst); j++)
2420			(void) BIO_printf(mem, "%s\n", sk_value(emlst, j));
2421
2422		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2423		X509_email_free(emlst);
2424		break;
2425	case KMF_X509_EXT_ISSUER_ALTNAME:
2426	case KMF_X509_EXT_SUBJ_ALTNAME:
2427	case KMF_X509_EXT_KEY_USAGE:
2428	case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
2429	case KMF_X509_EXT_CERT_POLICIES:
2430	case KMF_X509_EXT_BASIC_CONSTRAINTS:
2431	case KMF_X509_EXT_NAME_CONSTRAINTS:
2432	case KMF_X509_EXT_POLICY_CONSTRAINTS:
2433	case KMF_X509_EXT_EXT_KEY_USAGE:
2434	case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2435	case KMF_X509_EXT_AUTH_KEY_ID:
2436	case KMF_X509_EXT_SUBJ_KEY_ID:
2437	case KMF_X509_EXT_POLICY_MAPPINGS:
2438	case KMF_X509_EXT_CRL_DIST_POINTS:
2439	case KMF_X509_EXT_FRESHEST_CRL:
2440		nid = ext2NID(flag);
2441		if (nid == NID_undef) {
2442			ret = KMF_ERR_EXTENSION_NOT_FOUND;
2443			goto out;
2444		}
2445		ci = xcert->cert_info;
2446
2447		ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1);
2448		if (ext_index == -1) {
2449			SET_ERROR(kmfh, ERR_get_error());
2450
2451			ret = KMF_ERR_EXTENSION_NOT_FOUND;
2452			goto out;
2453		}
2454		ex = X509v3_get_ext(ci->extensions, ext_index);
2455
2456		(void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex));
2457
2458		if (BIO_printf(mem, ": %s\n",
2459			X509_EXTENSION_get_critical(ex) ? "critical" : "") <=
2460			0) {
2461			SET_ERROR(kmfh, ERR_get_error());
2462			ret = KMF_ERR_ENCODING;
2463			goto out;
2464		}
2465		if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) {
2466			(void) BIO_printf(mem, "%*s", 4, "");
2467			(void) M_ASN1_OCTET_STRING_print(mem, ex->value);
2468		}
2469		if (BIO_write(mem, "\n", 1) <= 0) {
2470			SET_ERROR(kmfh, ERR_get_error());
2471			ret = KMF_ERR_ENCODING;
2472			goto out;
2473		}
2474		len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2475	}
2476	if (len <= 0) {
2477		SET_ERROR(kmfh, ERR_get_error());
2478		ret = KMF_ERR_ENCODING;
2479	}
2480
2481out:
2482	if (outbuf != NULL) {
2483		free(outbuf);
2484	}
2485
2486	if (xcert != NULL) {
2487		X509_free(xcert);
2488	}
2489
2490	if (mem != NULL) {
2491		(void) BIO_free(mem);
2492	}
2493
2494	return (ret);
2495}
2496KMF_RETURN
2497/*ARGSUSED*/
2498OpenSSL_GetPrikeyByCert(KMF_HANDLE_T handle,
2499	KMF_CRYPTOWITHCERT_PARAMS *params,
2500	KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key,
2501	KMF_KEY_ALG keytype)
2502{
2503	KMF_RETURN rv = KMF_OK;
2504	KMF_FINDKEY_PARAMS fkparms;
2505	uint32_t numkeys = 0;
2506
2507	if (params == NULL || params->sslparms.keyfile == NULL)
2508		return (KMF_ERR_BAD_PARAMETER);
2509
2510	/*
2511	 * This is really just a FindKey operation, reuse the
2512	 * FindKey function.
2513	 */
2514	(void *)memset(&fkparms, 0, sizeof (fkparms));
2515	fkparms.kstype = KMF_KEYSTORE_OPENSSL;
2516	fkparms.keyclass = KMF_ASYM_PRI;
2517	fkparms.keytype = keytype;
2518	fkparms.format = params->format;
2519	fkparms.sslparms = params->sslparms;
2520
2521	rv = OpenSSL_FindKey(handle, &fkparms, key, &numkeys);
2522
2523	return (rv);
2524}
2525
2526KMF_RETURN
2527/*ARGSUSED*/
2528OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
2529	KMF_OID *AlgOID, KMF_DATA *ciphertext,
2530	KMF_DATA *output)
2531{
2532	KMF_RETURN		ret = KMF_OK;
2533	RSA *rsa = NULL;
2534	unsigned int in_len = 0, out_len = 0;
2535	unsigned int total_decrypted = 0, modulus_len = 0;
2536	uint8_t *in_data, *out_data;
2537	int i, blocks;
2538
2539	if (key == NULL || AlgOID == NULL ||
2540	    ciphertext == NULL || output == NULL ||
2541	    ciphertext->Data == NULL ||
2542	    output->Data == NULL)
2543		return (KMF_ERR_BAD_PARAMETER);
2544
2545	if (key->keyalg == KMF_RSA) {
2546		rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp);
2547		modulus_len = RSA_size(rsa);
2548	} else {
2549		return (KMF_ERR_BAD_PARAMETER);
2550	}
2551
2552	blocks = ciphertext->Length/modulus_len;
2553	out_data = output->Data;
2554	in_data = ciphertext->Data;
2555	out_len = modulus_len - 11;
2556	in_len = modulus_len;
2557
2558	for (i = 0; i < blocks; i++) {
2559		out_len  = RSA_private_decrypt(in_len,
2560			in_data, out_data, rsa, RSA_PKCS1_PADDING);
2561
2562		if (out_len == 0) {
2563			ret = KMF_ERR_INTERNAL;
2564			goto cleanup;
2565		}
2566
2567		out_data += out_len;
2568		total_decrypted += out_len;
2569		in_data += in_len;
2570	}
2571
2572	output->Length = total_decrypted;
2573
2574cleanup:
2575	RSA_free(rsa);
2576	if (ret != KMF_OK)
2577		output->Length = 0;
2578
2579	return (ret);
2580
2581}
2582
2583/*
2584 *  This function will create a certid from issuer_cert and user_cert.
2585 *  The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2586 *  certid memory after use.
2587 */
2588static KMF_RETURN
2589create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert,
2590    const KMF_DATA *user_cert, OCSP_CERTID **certid)
2591{
2592	KMF_RETURN ret = KMF_OK;
2593	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2594	X509   *issuer = NULL;
2595	X509   *cert = NULL;
2596	unsigned char *ptmp;
2597
2598	if (issuer_cert == NULL || user_cert == NULL) {
2599		return (KMF_ERR_BAD_PARAMETER);
2600	}
2601
2602	/* convert the DER-encoded issuer cert to an internal X509 */
2603	ptmp = issuer_cert->Data;
2604	issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2605		issuer_cert->Length);
2606	if (issuer == NULL) {
2607		SET_ERROR(kmfh, ERR_get_error());
2608		ret = KMF_ERR_OCSP_BAD_ISSUER;
2609		goto end;
2610	}
2611
2612	/* convert the DER-encoded user cert to an internal X509 */
2613	ptmp = user_cert->Data;
2614	cert = d2i_X509(NULL, (const uchar_t **)&ptmp,
2615		user_cert->Length);
2616	if (cert == NULL) {
2617		SET_ERROR(kmfh, ERR_get_error());
2618
2619		ret = KMF_ERR_OCSP_BAD_CERT;
2620		goto end;
2621	}
2622
2623	/* create a CERTID */
2624	*certid = OCSP_cert_to_id(NULL, cert, issuer);
2625	if (*certid == NULL) {
2626		SET_ERROR(kmfh, ERR_get_error());
2627		ret = KMF_ERR_OCSP_CERTID;
2628		goto end;
2629	}
2630
2631end:
2632	if (issuer != NULL) {
2633		X509_free(issuer);
2634	}
2635
2636	if (cert != NULL) {
2637		X509_free(cert);
2638	}
2639
2640	return (ret);
2641}
2642
2643KMF_RETURN
2644OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params,
2645    char *reqfile)
2646{
2647	KMF_RETURN ret = KMF_OK;
2648	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2649	OCSP_CERTID *id = NULL;
2650	OCSP_REQUEST *req = NULL;
2651	BIO *derbio = NULL;
2652
2653	if (params->user_cert == NULL || params->issuer_cert == NULL ||
2654	    reqfile == NULL) {
2655		return (KMF_ERR_BAD_PARAMETER);
2656	}
2657
2658	ret = create_certid(handle, params->issuer_cert, params->user_cert,
2659	    &id);
2660	if (ret != KMF_OK) {
2661		return (ret);
2662	}
2663
2664	/* Create an OCSP request */
2665	req = OCSP_REQUEST_new();
2666	if (req == NULL) {
2667		SET_ERROR(kmfh, ERR_get_error());
2668		ret = KMF_ERR_OCSP_CREATE_REQUEST;
2669		goto end;
2670	}
2671
2672	if (!OCSP_request_add0_id(req, id)) {
2673		ret = KMF_ERR_OCSP_CREATE_REQUEST;
2674		goto end;
2675	}
2676
2677	/* Write the request to the output file with DER encoding */
2678	derbio = BIO_new_file(reqfile, "wb");
2679	if (!derbio) {
2680		SET_ERROR(kmfh, ERR_get_error());
2681		ret = KMF_ERR_OPEN_FILE;
2682		goto end;
2683	}
2684	if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) {
2685		ret = KMF_ERR_ENCODING;
2686	}
2687
2688end:
2689	/*
2690	 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2691	 * will deallocate certid's space also.
2692	 */
2693	if (req != NULL) {
2694		OCSP_REQUEST_free(req);
2695	}
2696
2697	if (derbio != NULL) {
2698		(void) BIO_free(derbio);
2699	}
2700
2701	return (ret);
2702}
2703
2704/* ocsp_find_signer_sk() is copied from openssl source */
2705static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
2706{
2707	int i;
2708	unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
2709
2710	/* Easy if lookup by name */
2711	if (id->type == V_OCSP_RESPID_NAME)
2712		return (X509_find_by_subject(certs, id->value.byName));
2713
2714	/* Lookup by key hash */
2715
2716	/* If key hash isn't SHA1 length then forget it */
2717	if (id->value.byKey->length != SHA_DIGEST_LENGTH)
2718		return (NULL);
2719
2720	keyhash = id->value.byKey->data;
2721	/* Calculate hash of each key and compare */
2722	for (i = 0; i < sk_X509_num(certs); i++) {
2723		/*LINTED*/
2724		X509 *x = sk_X509_value(certs, i);
2725		(void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
2726		if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
2727			return (x);
2728	}
2729	return (NULL);
2730}
2731
2732/* ocsp_find_signer() is copied from openssl source */
2733/*ARGSUSED*/
2734static int
2735ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
2736    X509_STORE *st, unsigned long flags)
2737{
2738	X509 *signer;
2739	OCSP_RESPID *rid = bs->tbsResponseData->responderId;
2740	if ((signer = ocsp_find_signer_sk(certs, rid)))	{
2741		*psigner = signer;
2742		return (2);
2743	}
2744	if (!(flags & OCSP_NOINTERN) &&
2745	    (signer = ocsp_find_signer_sk(bs->certs, rid))) {
2746		*psigner = signer;
2747		return (1);
2748	}
2749	/* Maybe lookup from store if by subject name */
2750
2751	*psigner = NULL;
2752	return (0);
2753}
2754
2755/*
2756 * This function will verify the signature of a basic response, using
2757 * the public key from the OCSP responder certificate.
2758 */
2759static KMF_RETURN
2760check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs,
2761    KMF_DATA *signer_cert, KMF_DATA *issuer_cert)
2762{
2763	KMF_RETURN ret = KMF_OK;
2764	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2765	STACK_OF(X509) *cert_stack = NULL;
2766	X509 *signer = NULL;
2767	X509 *issuer = NULL;
2768	EVP_PKEY *skey = NULL;
2769	unsigned char *ptmp;
2770
2771
2772	if (bs == NULL || issuer_cert == NULL)
2773		return (KMF_ERR_BAD_PARAMETER);
2774
2775	/*
2776	 * Find the certificate that signed the basic response.
2777	 *
2778	 * If signer_cert is not NULL, we will use that as the signer cert.
2779	 * Otherwise, we will check if the issuer cert is actually the signer.
2780	 * If we still do not find a signer, we will look for it from the
2781	 * certificate list came with the response file.
2782	 */
2783	if (signer_cert != NULL) {
2784		ptmp = signer_cert->Data;
2785		signer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2786		    signer_cert->Length);
2787		if (signer == NULL) {
2788			SET_ERROR(kmfh, ERR_get_error());
2789			ret = KMF_ERR_OCSP_BAD_SIGNER;
2790			goto end;
2791		}
2792	} else {
2793		/*
2794		 * Convert the issuer cert into X509 and push it into a
2795		 * stack to be used by ocsp_find_signer().
2796		 */
2797		ptmp = issuer_cert->Data;
2798		issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2799			issuer_cert->Length);
2800		if (issuer == NULL) {
2801			SET_ERROR(kmfh, ERR_get_error());
2802			ret = KMF_ERR_OCSP_BAD_ISSUER;
2803			goto end;
2804		}
2805
2806		if ((cert_stack = sk_X509_new_null()) == NULL) {
2807			ret = KMF_ERR_INTERNAL;
2808			goto end;
2809		}
2810
2811		if (sk_X509_push(cert_stack, issuer) == NULL) {
2812			ret = KMF_ERR_INTERNAL;
2813			goto end;
2814		}
2815
2816		ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0);
2817		if (!ret) {
2818			/* can not find the signer */
2819			ret = KMF_ERR_OCSP_BAD_SIGNER;
2820			goto end;
2821		}
2822	}
2823
2824	/* Verify the signature of the response */
2825	skey = X509_get_pubkey(signer);
2826	if (skey == NULL) {
2827		ret = KMF_ERR_OCSP_BAD_SIGNER;
2828		goto end;
2829	}
2830
2831	ret = OCSP_BASICRESP_verify(bs, skey, 0);
2832	if (ret == 0) {
2833		ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE;
2834		goto end;
2835	}
2836
2837end:
2838	if (issuer != NULL) {
2839		X509_free(issuer);
2840	}
2841
2842	if (signer != NULL) {
2843		X509_free(signer);
2844	}
2845
2846	if (skey != NULL) {
2847		EVP_PKEY_free(skey);
2848	}
2849
2850	if (cert_stack != NULL) {
2851		sk_X509_free(cert_stack);
2852	}
2853
2854	return (ret);
2855}
2856
2857
2858
2859KMF_RETURN
2860OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,
2861    KMF_OCSPRESPONSE_PARAMS_INPUT *params_in,
2862    KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out)
2863{
2864	KMF_RETURN ret = KMF_OK;
2865	BIO *derbio = NULL;
2866	OCSP_RESPONSE *resp = NULL;
2867	OCSP_BASICRESP *bs = NULL;
2868	OCSP_CERTID *id = NULL;
2869	OCSP_SINGLERESP *single = NULL;
2870	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
2871	int index, status, reason;
2872
2873	if (params_in == NULL || params_in->issuer_cert == NULL ||
2874	    params_in->user_cert == NULL || params_in->response == NULL) {
2875		return (KMF_ERR_BAD_PARAMETER);
2876	}
2877
2878	if (params_out == NULL) {
2879		return (KMF_ERR_BAD_PARAMETER);
2880	}
2881
2882	/* Read in the response */
2883	derbio = BIO_new_mem_buf(params_in->response->Data,
2884	    params_in->response->Length);
2885	if (!derbio) {
2886		ret = KMF_ERR_MEMORY;
2887		return (ret);
2888	}
2889
2890	resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
2891	if (resp == NULL) {
2892		ret = KMF_ERR_OCSP_MALFORMED_RESPONSE;
2893		goto end;
2894	}
2895
2896	/* Check the response status */
2897	status = OCSP_response_status(resp);
2898	params_out->response_status = status;
2899	if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
2900		ret = KMF_ERR_OCSP_RESPONSE_STATUS;
2901		goto end;
2902	}
2903
2904#ifdef DEBUG
2905	printf("Successfully checked the response file status.\n");
2906#endif /* DEBUG */
2907
2908	/* Extract basic response */
2909	bs = OCSP_response_get1_basic(resp);
2910	if (bs == NULL) {
2911		ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE;
2912		goto end;
2913	}
2914
2915#ifdef DEBUG
2916	printf("Successfully retrieved the basic response.\n");
2917#endif /* DEBUG */
2918
2919	/* Check the basic response signature if required */
2920	if (params_in->ignore_response_sign == B_FALSE) {
2921		ret = check_response_signature(handle, bs,
2922		    params_in->signer_cert, params_in->issuer_cert);
2923		if (ret != KMF_OK)
2924			goto end;
2925	}
2926
2927#ifdef DEBUG
2928	printf("Successfully verified the response signature.\n");
2929#endif /* DEBUG */
2930
2931	/* Create a certid for the certificate in question */
2932	ret = create_certid(handle, params_in->issuer_cert,
2933	    params_in->user_cert, &id);
2934	if (ret != KMF_OK) {
2935		ret = KMF_ERR_OCSP_CERTID;
2936		goto end;
2937	}
2938
2939#ifdef DEBUG
2940	printf("successfully created a certid for the cert.\n");
2941#endif /* DEBUG */
2942
2943	/* Find the index of the single response for the certid */
2944	index = OCSP_resp_find(bs, id, -1);
2945	if (index < 0) {
2946		/* cound not find this certificate in the response */
2947		ret = KMF_ERR_OCSP_UNKNOWN_CERT;
2948		goto end;
2949	}
2950
2951#ifdef DEBUG
2952	printf("Successfully found the single response index for the cert.\n");
2953#endif /* DEBUG */
2954
2955	/* Retrieve the single response and get the cert status */
2956	single = OCSP_resp_get0(bs, index);
2957	status = OCSP_single_get0_status(single, &reason, &rev, &thisupd,
2958	    &nextupd);
2959	if (status == V_OCSP_CERTSTATUS_GOOD) {
2960		params_out->cert_status = OCSP_GOOD;
2961	} else if (status == V_OCSP_CERTSTATUS_UNKNOWN) {
2962		params_out->cert_status = OCSP_UNKNOWN;
2963	} else { /* revoked */
2964		params_out->cert_status = OCSP_REVOKED;
2965		params_out->reason = reason;
2966	}
2967	ret = KMF_OK;
2968
2969	/* Verify the time */
2970	if (!OCSP_check_validity(thisupd, nextupd, 300,
2971	    params_in->response_lifetime)) {
2972		ret = KMF_ERR_OCSP_STATUS_TIME_INVALID;
2973		goto end;
2974	}
2975
2976#ifdef DEBUG
2977	printf("Successfully verify the time.\n");
2978#endif /* DEBUG */
2979
2980end:
2981	if (derbio != NULL)
2982		(void) BIO_free(derbio);
2983
2984	if (resp != NULL)
2985		OCSP_RESPONSE_free(resp);
2986
2987	if (bs != NULL)
2988		OCSP_BASICRESP_free(bs);
2989
2990	if (id != NULL)
2991		OCSP_CERTID_free(id);
2992
2993	return (ret);
2994}
2995
2996static KMF_RETURN
2997fetch_key(KMF_HANDLE_T handle, char *path,
2998	KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key)
2999{
3000	KMF_RETURN rv = KMF_OK;
3001	EVP_PKEY *pkey;
3002	KMF_RAW_SYM_KEY *rkey = NULL;
3003
3004	/* Make sure the requested file actually exists. */
3005	if (access(path, F_OK) != 0) {
3006		return (KMF_ERR_KEY_NOT_FOUND);
3007	}
3008
3009	if (keyclass == KMF_ASYM_PRI ||
3010	    keyclass == KMF_ASYM_PUB) {
3011		pkey = openssl_load_key(handle, path);
3012		if (pkey == NULL) {
3013			return (KMF_ERR_KEY_NOT_FOUND);
3014		}
3015		if (key != NULL) {
3016			if (pkey->type == EVP_PKEY_RSA)
3017				key->keyalg = KMF_RSA;
3018			else if (pkey->type == EVP_PKEY_DSA)
3019				key->keyalg = KMF_DSA;
3020
3021			key->kstype = KMF_KEYSTORE_OPENSSL;
3022			key->keyclass = keyclass;
3023			key->keyp = (void *)pkey;
3024			key->israw = FALSE;
3025			key->keylabel = path;
3026		} else {
3027			EVP_PKEY_free(pkey);
3028			pkey = NULL;
3029		}
3030	} else if (keyclass == KMF_SYMMETRIC) {
3031		KMF_ENCODE_FORMAT fmt;
3032		/*
3033		 * If the file is a recognized format,
3034		 * then it is NOT a symmetric key.
3035		 */
3036		rv = KMF_GetFileFormat(path, &fmt);
3037		if (rv == KMF_OK || fmt != 0) {
3038			return (KMF_ERR_KEY_NOT_FOUND);
3039		} else if (rv == KMF_ERR_ENCODING) {
3040			/*
3041			 * If we don't know the encoding,
3042			 * it is probably  a symmetric key.
3043			 */
3044			rv = KMF_OK;
3045		}
3046
3047		if (key != NULL) {
3048			KMF_DATA keyvalue;
3049			rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
3050			if (rkey == NULL) {
3051				rv = KMF_ERR_MEMORY;
3052				goto out;
3053			}
3054
3055			(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
3056			rv = KMF_ReadInputFile(handle, path, &keyvalue);
3057			if (rv != KMF_OK)
3058				goto out;
3059
3060			rkey->keydata.len = keyvalue.Length;
3061			rkey->keydata.val = keyvalue.Data;
3062
3063			key->kstype = KMF_KEYSTORE_OPENSSL;
3064			key->keyclass = keyclass;
3065			key->israw = TRUE;
3066			key->keylabel = path;
3067			key->keyp = (void *)rkey;
3068		}
3069	}
3070out:
3071	if (rv != KMF_OK) {
3072		if (rkey != NULL) {
3073			KMF_FreeRawSymKey(rkey);
3074		}
3075		if (pkey != NULL)
3076			EVP_PKEY_free(pkey);
3077
3078		if (key != NULL) {
3079			key->keyalg = KMF_KEYALG_NONE;
3080			key->keyclass = KMF_KEYCLASS_NONE;
3081			key->keyp = NULL;
3082		}
3083	}
3084
3085	return (rv);
3086}
3087
3088KMF_RETURN
3089OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params,
3090	KMF_KEY_HANDLE *key, uint32_t *numkeys)
3091{
3092	KMF_RETURN rv = KMF_OK;
3093	char *fullpath = NULL;
3094	uint32_t maxkeys;
3095
3096	if (handle == NULL || params == NULL || numkeys == NULL)
3097		return (KMF_ERR_BAD_PARAMETER);
3098
3099	if (params->keyclass != KMF_ASYM_PUB &&
3100		params->keyclass != KMF_ASYM_PRI &&
3101		params->keyclass != KMF_SYMMETRIC)
3102		return (KMF_ERR_BAD_KEY_CLASS);
3103
3104	fullpath = get_fullpath(params->sslparms.dirpath,
3105		params->sslparms.keyfile);
3106
3107	if (fullpath == NULL)
3108		return (KMF_ERR_BAD_PARAMETER);
3109
3110	maxkeys = *numkeys;
3111	if (maxkeys == 0)
3112		maxkeys = 0xFFFFFFFF;
3113
3114	*numkeys = 0;
3115
3116	if (isdir(fullpath)) {
3117		DIR *dirp;
3118		struct dirent *dp;
3119		int n = 0;
3120
3121		/* open all files in the directory and attempt to read them */
3122		if ((dirp = opendir(fullpath)) == NULL) {
3123			return (KMF_ERR_BAD_PARAMETER);
3124		}
3125		rewinddir(dirp);
3126		while ((dp = readdir(dirp)) != NULL && n < maxkeys) {
3127			if (strcmp(dp->d_name, ".") &&
3128			    strcmp(dp->d_name, "..")) {
3129				char *fname;
3130
3131				fname = get_fullpath(fullpath,
3132					(char *)&dp->d_name);
3133
3134				rv = fetch_key(handle, fname,
3135					params->keyclass,
3136					key ? &key[n] : NULL);
3137
3138				if (rv == KMF_OK)
3139					n++;
3140
3141				if (rv != KMF_OK || key == NULL)
3142					free(fname);
3143			}
3144		}
3145		(void) closedir(dirp);
3146		free(fullpath);
3147		(*numkeys) = n;
3148	} else {
3149		rv = fetch_key(handle, fullpath, params->keyclass, key);
3150		if (rv == KMF_OK)
3151			(*numkeys) = 1;
3152
3153		if (rv != KMF_OK || key == NULL)
3154			free(fullpath);
3155	}
3156
3157	if (rv == KMF_OK && (*numkeys) == 0)
3158		rv = KMF_ERR_KEY_NOT_FOUND;
3159
3160	return (rv);
3161}
3162
3163#define	HANDLE_PK12_ERROR { \
3164	SET_ERROR(kmfh, ERR_get_error()); \
3165	rv = KMF_ERR_ENCODING; \
3166	goto out; \
3167}
3168
3169static KMF_RETURN
3170write_pkcs12(KMF_HANDLE *kmfh,
3171	BIO *bio,
3172	KMF_CREDENTIAL *cred,
3173	EVP_PKEY *pkey,
3174	X509 *sslcert)
3175{
3176	KMF_RETURN rv = KMF_OK;
3177	STACK_OF(PKCS12_SAFEBAG)	*bag_stack = NULL;
3178	PKCS12_SAFEBAG			*bag = NULL;
3179	PKCS7				*cert_authsafe = NULL;
3180	PKCS8_PRIV_KEY_INFO		*p8 = NULL;
3181	PKCS7				*key_authsafe = NULL;
3182	STACK_OF(PKCS7)			*authsafe_stack = NULL;
3183	PKCS12				*p12_elem = NULL;
3184	char				*lab = NULL;
3185	int				lab_len = 0;
3186	unsigned char keyid[EVP_MAX_MD_SIZE];
3187	unsigned int keyidlen = 0;
3188
3189	/* Must have at least a cert OR a key */
3190	if (sslcert == NULL && pkey == NULL)
3191		return (KMF_ERR_BAD_PARAMETER);
3192
3193	(void) memset(keyid, 0, sizeof (keyid));
3194	/*
3195	 * Section 1:
3196	 *
3197	 * The first PKCS#12 container (safebag) will hold the certificates
3198	 * associated with this key.  The result of this section is a
3199	 * PIN-encrypted PKCS#7 container (authsafe).  If there are no
3200	 * certificates, there is no point in creating the "safebag" or the
3201	 * "authsafe" so we go to the next section.
3202	 */
3203	if (sslcert != NULL && pkey != NULL) {
3204		if (X509_check_private_key(sslcert, pkey)) {
3205			(void) X509_digest(sslcert, EVP_sha1(), keyid,
3206				&keyidlen);
3207		} else {
3208			/* The key doesn't match the cert */
3209			HANDLE_PK12_ERROR
3210		}
3211	}
3212
3213	bag_stack = sk_PKCS12_SAFEBAG_new_null();
3214	if (bag_stack == NULL)
3215		return (KMF_ERR_MEMORY);
3216
3217	if (sslcert != NULL) {
3218		/* Convert cert from X509 struct to PKCS#12 bag */
3219		bag = PKCS12_x5092certbag(sslcert);
3220		if (bag == NULL) {
3221			HANDLE_PK12_ERROR
3222		}
3223
3224		/* Add the key id to the certificate bag. */
3225		if (keyidlen > 0 &&
3226			!PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
3227			HANDLE_PK12_ERROR
3228		}
3229
3230		/* Pile it on the bag_stack. */
3231		if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
3232			HANDLE_PK12_ERROR
3233		}
3234#if 0
3235		/* No support for CA certs yet */
3236		if (cacerts != NULL && ncacerts > 0) {
3237			int i;
3238			for (i = 0; i < ncacerts; i++) {
3239				KMF_X509_DER_CERT *c = &cacerts[i];
3240				X509 *ca = NULL;
3241
3242				uchar_t *p = (uchar_t *)c->certificate.Data;
3243				ca = d2i_X509(NULL, &p,
3244					c->certificate.Length);
3245				if (ca == NULL) {
3246					HANDLE_PK12_ERROR
3247				}
3248				/* Convert CA cert to PKCS#12 bag. */
3249				bag = PKCS12_x5092certbag(ca);
3250				if (bag == NULL) {
3251					sk_PKCS12_SAFEBAG_pop_free(bag_stack,
3252					    PKCS12_SAFEBAG_free);
3253					HANDLE_PK12_ERROR
3254				}
3255				/* Pile it onto the bag_stack. */
3256				if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
3257					HANDLE_PK12_ERROR
3258				}
3259			}
3260		}
3261#endif
3262		/* Turn bag_stack of certs into encrypted authsafe. */
3263		cert_authsafe = PKCS12_pack_p7encdata(
3264			NID_pbe_WithSHA1And40BitRC2_CBC,
3265			cred->cred,
3266			cred->credlen, NULL, 0,
3267			PKCS12_DEFAULT_ITER,
3268			bag_stack);
3269
3270		/* Clear away this bag_stack, we're done with it. */
3271		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3272		bag_stack = NULL;
3273
3274		if (cert_authsafe == NULL) {
3275			HANDLE_PK12_ERROR
3276		}
3277	}
3278	/*
3279	 * Section 2:
3280	 *
3281	 * The second PKCS#12 container (safebag) will hold the private key
3282	 * that goes with the certificates above.  The results of this section
3283	 * is an unencrypted PKCS#7 container (authsafe).  If there is no
3284	 * private key, there is no point in creating the "safebag" or the
3285	 * "authsafe" so we go to the next section.
3286	 */
3287	if (pkey != NULL) {
3288		p8 = EVP_PKEY2PKCS8(pkey);
3289		if (p8 == NULL) {
3290			HANDLE_PK12_ERROR
3291		}
3292		/* Put the shrouded key into a PKCS#12 bag. */
3293		bag = PKCS12_MAKE_SHKEYBAG(
3294			NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
3295			cred->cred, cred->credlen,
3296			NULL, 0, PKCS12_DEFAULT_ITER, p8);
3297
3298		/* Clean up the PKCS#8 shrouded key, don't need it now. */
3299		PKCS8_PRIV_KEY_INFO_free(p8);
3300		p8 = NULL;
3301
3302		if (bag == NULL) {
3303			HANDLE_PK12_ERROR
3304		}
3305		if (keyidlen &&
3306			!PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
3307			HANDLE_PK12_ERROR
3308		}
3309		if (lab != NULL) {
3310			if (!PKCS12_add_friendlyname(bag,
3311				(char *)lab, lab_len)) {
3312				HANDLE_PK12_ERROR
3313			}
3314		}
3315		/* Start a PKCS#12 safebag container for the private key. */
3316		bag_stack = sk_PKCS12_SAFEBAG_new_null();
3317		if (bag_stack == NULL) {
3318			HANDLE_PK12_ERROR
3319		}
3320
3321		/* Pile on the private key on the bag_stack. */
3322		if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
3323			HANDLE_PK12_ERROR
3324		}
3325		key_authsafe = PKCS12_pack_p7data(bag_stack);
3326
3327		/* Clear away this bag_stack, we're done with it. */
3328		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3329		bag_stack = NULL;
3330
3331		if (key_authsafe == NULL) {
3332			HANDLE_PK12_ERROR
3333		}
3334	}
3335	/*
3336	 * Section 3:
3337	 *
3338	 * This is where the two PKCS#7 containers, one for the certificates
3339	 * and one for the private key, are put together into a PKCS#12
3340	 * element.  This final PKCS#12 element is written to the export file.
3341	 */
3342
3343	/* Start a PKCS#7 stack. */
3344	authsafe_stack = sk_PKCS7_new_null();
3345	if (authsafe_stack == NULL) {
3346		HANDLE_PK12_ERROR
3347	}
3348	if (key_authsafe != NULL) {
3349		if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) {
3350			HANDLE_PK12_ERROR
3351		}
3352	}
3353	if (cert_authsafe != NULL) {
3354		if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) {
3355			HANDLE_PK12_ERROR
3356		}
3357	}
3358	p12_elem = PKCS12_init(NID_pkcs7_data);
3359	if (p12_elem == NULL) {
3360		sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
3361		HANDLE_PK12_ERROR
3362	}
3363
3364	/* Put the PKCS#7 stack into the PKCS#12 element. */
3365	if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) {
3366		HANDLE_PK12_ERROR
3367	}
3368	/* Clear away the PKCS#7 stack, we're done with it. */
3369	sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
3370	authsafe_stack = NULL;
3371
3372	/* Set the integrity MAC on the PKCS#12 element. */
3373	if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen,
3374		NULL, 0, PKCS12_DEFAULT_ITER, NULL)) {
3375		HANDLE_PK12_ERROR
3376	}
3377
3378	/* Write the PKCS#12 element to the export file. */
3379	if (!i2d_PKCS12_bio(bio, p12_elem)) {
3380		HANDLE_PK12_ERROR
3381	}
3382
3383	PKCS12_free(p12_elem);
3384out:
3385	if (rv != KMF_OK) {
3386		/* Clear away this bag_stack, we're done with it. */
3387		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3388		sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
3389	}
3390	return (rv);
3391}
3392
3393static EVP_PKEY *
3394ImportRawRSAKey(KMF_RAW_RSA_KEY *key)
3395{
3396	RSA		*rsa = NULL;
3397	EVP_PKEY 	*newkey = NULL;
3398
3399	if ((rsa = RSA_new()) == NULL)
3400		return (NULL);
3401
3402	if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL)
3403		return (NULL);
3404
3405	if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) ==
3406		NULL)
3407		return (NULL);
3408
3409	if (key->priexp.val != NULL)
3410		if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len,
3411			rsa->d)) == NULL)
3412			return (NULL);
3413
3414	if (key->prime1.val != NULL)
3415		if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len,
3416			rsa->p)) == NULL)
3417			return (NULL);
3418
3419	if (key->prime2.val != NULL)
3420		if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len,
3421			rsa->q)) == NULL)
3422			return (NULL);
3423
3424	if (key->exp1.val != NULL)
3425		if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len,
3426			rsa->dmp1)) == NULL)
3427			return (NULL);
3428
3429	if (key->exp2.val != NULL)
3430		if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len,
3431			rsa->dmq1)) == NULL)
3432			return (NULL);
3433
3434	if (key->coef.val != NULL)
3435		if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len,
3436			rsa->iqmp)) == NULL)
3437			return (NULL);
3438
3439	if ((newkey = EVP_PKEY_new()) == NULL)
3440		return (NULL);
3441
3442	(void) EVP_PKEY_set1_RSA(newkey, rsa);
3443
3444	/* The original key must be freed once here or it leaks memory */
3445	RSA_free(rsa);
3446
3447	return (newkey);
3448}
3449
3450static EVP_PKEY *
3451ImportRawDSAKey(KMF_RAW_DSA_KEY *key)
3452{
3453	DSA		*dsa = NULL;
3454	EVP_PKEY 	*newkey = NULL;
3455
3456	if ((dsa = DSA_new()) == NULL)
3457		return (NULL);
3458
3459	if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len,
3460		dsa->p)) == NULL)
3461		return (NULL);
3462
3463	if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len,
3464		dsa->q)) == NULL)
3465		return (NULL);
3466
3467	if ((dsa->g = BN_bin2bn(key->base.val, key->base.len,
3468		dsa->g)) == NULL)
3469		return (NULL);
3470
3471	if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len,
3472		dsa->priv_key)) == NULL)
3473		return (NULL);
3474
3475	if ((newkey = EVP_PKEY_new()) == NULL)
3476		return (NULL);
3477
3478	(void) EVP_PKEY_set1_DSA(newkey, dsa);
3479
3480	/* The original key must be freed once here or it leaks memory */
3481	DSA_free(dsa);
3482	return (newkey);
3483}
3484
3485static KMF_RETURN
3486ExportPK12FromRawData(KMF_HANDLE_T handle,
3487	KMF_CREDENTIAL *cred,
3488	int numcerts, KMF_X509_DER_CERT *certlist,
3489	int numkeys, KMF_KEY_HANDLE *keylist,
3490	char *filename)
3491{
3492	KMF_RETURN rv = KMF_OK;
3493	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3494	BIO *bio = NULL;
3495	X509 *xcert = NULL;
3496	EVP_PKEY *pkey = NULL;
3497	int i;
3498
3499	/*
3500	 * Open the output file.
3501	 */
3502	if ((bio = BIO_new_file(filename, "wb")) == NULL) {
3503		SET_ERROR(kmfh, ERR_get_error());
3504		rv = KMF_ERR_OPEN_FILE;
3505		goto cleanup;
3506	}
3507
3508	if (numcerts > 0 && numkeys > 0) {
3509		for (i = 0; rv == KMF_OK && i < numcerts; i++) {
3510			KMF_RAW_KEY_DATA *key = NULL;
3511			const uchar_t *p = certlist[i].certificate.Data;
3512			long len = certlist[i].certificate.Length;
3513
3514			if (i < numkeys) {
3515				key = (KMF_RAW_KEY_DATA *)keylist[i].keyp;
3516
3517				if (key->keytype == KMF_RSA) {
3518					pkey = ImportRawRSAKey(
3519						&key->rawdata.rsa);
3520				} else if (key->keytype == KMF_DSA) {
3521					pkey = ImportRawDSAKey(
3522						&key->rawdata.dsa);
3523				} else {
3524					rv = KMF_ERR_BAD_PARAMETER;
3525				}
3526			}
3527
3528			xcert = d2i_X509(NULL, &p, len);
3529			if (xcert == NULL) {
3530				SET_ERROR(kmfh, ERR_get_error());
3531				rv = KMF_ERR_ENCODING;
3532			}
3533			/* Stick the key and the cert into a PKCS#12 file */
3534			rv = write_pkcs12(kmfh, bio, cred, pkey, xcert);
3535			if (xcert)
3536				X509_free(xcert);
3537			if (pkey)
3538				EVP_PKEY_free(pkey);
3539		}
3540	}
3541
3542cleanup:
3543
3544	if (bio != NULL)
3545		(void) BIO_free_all(bio);
3546
3547	return (rv);
3548}
3549
3550KMF_RETURN
3551OpenSSL_ExportP12(KMF_HANDLE_T handle,
3552	KMF_EXPORTP12_PARAMS *params,
3553	int numcerts, KMF_X509_DER_CERT *certlist,
3554	int numkeys, KMF_KEY_HANDLE *keylist,
3555	char *filename)
3556{
3557	KMF_RETURN rv;
3558	KMF_HANDLE *kmfh = (KMF_HANDLE  *)handle;
3559	KMF_FINDCERT_PARAMS fcargs;
3560	BIO *bio = NULL;
3561	X509 *xcert = NULL;
3562	char *fullpath = NULL;
3563	EVP_PKEY *pkey = NULL;
3564
3565	/*
3566	 *  First, find the certificate.
3567	 */
3568	if (params == NULL)
3569		return (KMF_ERR_BAD_PARAMETER);
3570
3571	/*
3572	 * If the caller already sent the raw keys and certs,
3573	 * shortcut the search and just export that
3574	 * data.
3575	 *
3576	 * One *may* export a key OR a cert by itself.
3577	 */
3578	if (certlist != NULL || keylist != NULL) {
3579		rv = ExportPK12FromRawData(handle,
3580			&params->p12cred,
3581			numcerts, certlist,
3582			numkeys, keylist,
3583			filename);
3584		return (rv);
3585	}
3586
3587	if (params->sslparms.certfile != NULL) {
3588		fullpath = get_fullpath(params->sslparms.dirpath,
3589			params->sslparms.certfile);
3590
3591		if (fullpath == NULL)
3592			return (KMF_ERR_BAD_PARAMETER);
3593
3594		if (isdir(fullpath)) {
3595			free(fullpath);
3596			return (KMF_ERR_AMBIGUOUS_PATHNAME);
3597		}
3598
3599		(void *)memset(&fcargs, 0, sizeof (fcargs));
3600		fcargs.kstype = params->kstype;
3601		fcargs.certLabel = params->certLabel;
3602		fcargs.issuer = params->issuer;
3603		fcargs.subject = params->subject;
3604		fcargs.serial = params->serial;
3605		fcargs.idstr = params->idstr;
3606		fcargs.sslparms.dirpath = NULL;
3607		fcargs.sslparms.certfile = fullpath;
3608		fcargs.sslparms.format = params->sslparms.format;
3609
3610		rv = load_X509cert(kmfh, &fcargs, fullpath, &xcert);
3611		if (rv != KMF_OK)
3612			goto end;
3613	}
3614
3615	/*
3616	 * Now find the private key.
3617	 */
3618	if (params->sslparms.keyfile != NULL) {
3619		fullpath = get_fullpath(params->sslparms.dirpath,
3620			params->sslparms.keyfile);
3621
3622		if (fullpath == NULL)
3623			return (KMF_ERR_BAD_PARAMETER);
3624
3625		if (isdir(fullpath)) {
3626			free(fullpath);
3627			return (KMF_ERR_AMBIGUOUS_PATHNAME);
3628		}
3629
3630		pkey = openssl_load_key(handle, fullpath);
3631		if (pkey == NULL) {
3632			rv = KMF_ERR_KEY_NOT_FOUND;
3633			goto end;
3634		}
3635	}
3636
3637	/*
3638	 * Open the output file.
3639	 */
3640	if ((bio = BIO_new_file(filename, "wb")) == NULL) {
3641		SET_ERROR(kmfh, ERR_get_error());
3642		rv = KMF_ERR_OPEN_FILE;
3643		goto end;
3644	}
3645
3646	/* Stick the key and the cert into a PKCS#12 file */
3647	rv = write_pkcs12(kmfh, bio, &params->p12cred,
3648		pkey, xcert);
3649
3650end:
3651	if (fullpath)
3652		free(fullpath);
3653	if (xcert)
3654		X509_free(xcert);
3655	if (pkey)
3656		EVP_PKEY_free(pkey);
3657	if (bio)
3658		(void) BIO_free(bio);
3659
3660	return (rv);
3661}
3662
3663#define	MAX_CHAIN_LENGTH 100
3664/*
3665 * Helper function to extract keys and certificates from
3666 * a single PEM file.  Typically the file should contain a
3667 * private key and an associated public key wrapped in an x509 cert.
3668 * However, the file may be just a list of X509 certs with no keys.
3669 */
3670static KMF_RETURN
3671extract_objects(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params,
3672	char *filename, CK_UTF8CHAR *pin,
3673	CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs,
3674	int *numcerts)
3675/* ARGSUSED */
3676{
3677	KMF_RETURN rv = KMF_OK;
3678	FILE *fp;
3679	STACK_OF(X509_INFO) *x509_info_stack;
3680	int i, ncerts = 0, matchcerts = 0;
3681	EVP_PKEY *pkey = NULL;
3682	X509_INFO *info;
3683	X509 *x;
3684	X509_INFO *cert_infos[MAX_CHAIN_LENGTH];
3685	KMF_DATA *certlist = NULL;
3686
3687	if (priv_key)
3688		*priv_key = NULL;
3689	if (certs)
3690		*certs = NULL;
3691	fp = fopen(filename, "r");
3692	if (fp == NULL) {
3693		return (KMF_ERR_OPEN_FILE);
3694	}
3695	x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin);
3696	if (x509_info_stack == NULL) {
3697		(void) fclose(fp);
3698		return (KMF_ERR_ENCODING);
3699	}
3700
3701	/*LINTED*/
3702	while ((info = sk_X509_INFO_pop(x509_info_stack)) != NULL &&
3703		info->x509 != NULL && ncerts < MAX_CHAIN_LENGTH) {
3704		cert_infos[ncerts] = info;
3705		ncerts++;
3706	}
3707
3708	if (ncerts == 0) {
3709		(void) fclose(fp);
3710		return (KMF_ERR_CERT_NOT_FOUND);
3711	}
3712
3713	if (priv_key != NULL) {
3714		rewind(fp);
3715		pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin);
3716	}
3717	(void) fclose(fp);
3718
3719	x = cert_infos[ncerts - 1]->x509;
3720	/*
3721	 * Make sure the private key matchs the last cert in the file.
3722	 */
3723	if (pkey != NULL && !X509_check_private_key(x, pkey)) {
3724		EVP_PKEY_free(pkey);
3725		return (KMF_ERR_KEY_MISMATCH);
3726	}
3727
3728	certlist = (KMF_DATA *)malloc(ncerts * sizeof (KMF_DATA));
3729	if (certlist == NULL) {
3730		if (pkey != NULL)
3731			EVP_PKEY_free(pkey);
3732		X509_INFO_free(info);
3733		return (KMF_ERR_MEMORY);
3734	}
3735
3736	/*
3737	 * Convert all of the certs to DER format.
3738	 */
3739	matchcerts = 0;
3740	for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) {
3741		boolean_t match = FALSE;
3742		info =  cert_infos[ncerts - 1 - i];
3743
3744		if (params != NULL) {
3745			rv = check_cert(info->x509, params, &match);
3746			if (rv != KMF_OK || match != TRUE) {
3747				X509_INFO_free(info);
3748				rv = KMF_OK;
3749				continue;
3750			}
3751		}
3752
3753		rv = ssl_cert2KMFDATA(kmfh, info->x509,
3754			&certlist[matchcerts++]);
3755
3756		if (rv != KMF_OK) {
3757			free(certlist);
3758			certlist = NULL;
3759			ncerts = matchcerts = 0;
3760		}
3761
3762		X509_INFO_free(info);
3763	}
3764
3765	if (numcerts != NULL)
3766		*numcerts = matchcerts;
3767	if (certs != NULL)
3768		*certs = certlist;
3769
3770	if (priv_key == NULL && pkey != NULL)
3771		EVP_PKEY_free(pkey);
3772	else if (priv_key != NULL && pkey != NULL)
3773		*priv_key = pkey;
3774
3775	return (rv);
3776}
3777
3778/*
3779 * Helper function to decrypt and parse PKCS#12 import file.
3780 */
3781static KMF_RETURN
3782extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
3783	EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca)
3784/* ARGSUSED */
3785{
3786	PKCS12		*pk12, *pk12_tmp;
3787	EVP_PKEY	*temp_pkey = NULL;
3788	X509		*temp_cert = NULL;
3789	STACK_OF(X509)	*temp_ca = NULL;
3790
3791	if ((pk12 = PKCS12_new()) == NULL) {
3792		return (KMF_ERR_MEMORY);
3793	}
3794
3795	if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) {
3796		/* This is ok; it seems to mean there is no more to read. */
3797		if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 &&
3798		    ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG)
3799			goto end_extract_pkcs12;
3800
3801		PKCS12_free(pk12);
3802		return (KMF_ERR_PKCS12_FORMAT);
3803	}
3804	pk12 = pk12_tmp;
3805
3806	if (PKCS12_parse(pk12, (char *)pin, &temp_pkey, &temp_cert,
3807	    &temp_ca) <= 0) {
3808		PKCS12_free(pk12);
3809		return (KMF_ERR_PKCS12_FORMAT);
3810	}
3811
3812end_extract_pkcs12:
3813
3814	*priv_key = temp_pkey;
3815	*cert = temp_cert;
3816	*ca = temp_ca;
3817
3818	PKCS12_free(pk12);
3819	return (KMF_OK);
3820}
3821
3822static KMF_RETURN
3823sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to)
3824{
3825	KMF_RETURN rv = KMF_OK;
3826	uint32_t sz;
3827
3828	sz = BN_num_bytes(from);
3829	to->val = (uchar_t *)malloc(sz);
3830	if (to->val == NULL)
3831		return (KMF_ERR_MEMORY);
3832
3833	if ((to->len = BN_bn2bin(from, to->val)) != sz) {
3834		free(to->val);
3835		to->val = NULL;
3836		to->len = 0;
3837		rv = KMF_ERR_MEMORY;
3838	}
3839
3840	return (rv);
3841}
3842
3843static KMF_RETURN
3844exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key)
3845{
3846	KMF_RETURN rv;
3847	KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa;
3848
3849	(void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY));
3850	if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK)
3851		goto cleanup;
3852
3853	if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK)
3854		goto cleanup;
3855
3856	if (rsa->d != NULL)
3857		if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK)
3858			goto cleanup;
3859
3860	if (rsa->p != NULL)
3861		if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK)
3862			goto cleanup;
3863
3864	if (rsa->q != NULL)
3865		if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK)
3866			goto cleanup;
3867
3868	if (rsa->dmp1 != NULL)
3869		if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK)
3870			goto cleanup;
3871
3872	if (rsa->dmq1 != NULL)
3873		if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK)
3874			goto cleanup;
3875
3876	if (rsa->iqmp != NULL)
3877		if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK)
3878			goto cleanup;
3879cleanup:
3880	if (rv != KMF_OK)
3881		KMF_FreeRawKey(key);
3882	else
3883		key->keytype = KMF_RSA;
3884
3885	/*
3886	 * Free the reference to this key, SSL will not actually free
3887	 * the memory until the refcount == 0, so this is safe.
3888	 */
3889	RSA_free(rsa);
3890
3891	return (rv);
3892}
3893
3894static KMF_RETURN
3895exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key)
3896{
3897	KMF_RETURN rv;
3898	KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa;
3899
3900	(void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY));
3901	if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK)
3902		goto cleanup;
3903
3904	if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK)
3905		goto cleanup;
3906
3907	if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK)
3908		goto cleanup;
3909
3910	if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK)
3911		goto cleanup;
3912
3913cleanup:
3914	if (rv != KMF_OK)
3915		KMF_FreeRawKey(key);
3916	else
3917		key->keytype = KMF_DSA;
3918
3919	/*
3920	 * Free the reference to this key, SSL will not actually free
3921	 * the memory until the refcount == 0, so this is safe.
3922	 */
3923	DSA_free(dsa);
3924
3925	return (rv);
3926}
3927
3928static KMF_RETURN
3929add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert,
3930	KMF_DATA **certlist, int *ncerts)
3931{
3932	KMF_RETURN rv = KMF_OK;
3933	KMF_DATA *list = (*certlist);
3934	KMF_DATA cert;
3935	int n = (*ncerts);
3936
3937	if (list == NULL) {
3938		list = (KMF_DATA *)malloc(sizeof (KMF_DATA));
3939	} else {
3940		list = (KMF_DATA *)realloc(list, sizeof (KMF_DATA) * (n + 1));
3941	}
3942
3943	if (list == NULL)
3944		return (KMF_ERR_MEMORY);
3945
3946	rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert);
3947	if (rv == KMF_OK) {
3948		list[n] = cert;
3949		(*ncerts) = n + 1;
3950
3951		*certlist = list;
3952	} else {
3953		free(list);
3954	}
3955
3956	return (rv);
3957}
3958
3959static KMF_RETURN
3960add_key_to_list(KMF_RAW_KEY_DATA **keylist,
3961	KMF_RAW_KEY_DATA *newkey, int *nkeys)
3962{
3963	KMF_RAW_KEY_DATA *list = (*keylist);
3964	int n = (*nkeys);
3965
3966	if (list == NULL) {
3967		list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA));
3968	} else {
3969		list = (KMF_RAW_KEY_DATA *)realloc(list,
3970			sizeof (KMF_RAW_KEY_DATA) * (n + 1));
3971	}
3972
3973	if (list == NULL)
3974		return (KMF_ERR_MEMORY);
3975
3976	list[n] = *newkey;
3977	(*nkeys) = n + 1;
3978
3979	*keylist = list;
3980
3981	return (KMF_OK);
3982}
3983
3984
3985static KMF_RETURN
3986convertPK12Objects(
3987	KMF_HANDLE *kmfh,
3988	EVP_PKEY *sslkey, X509 *sslcert, STACK_OF(X509) *sslcacerts,
3989	KMF_RAW_KEY_DATA **keylist, int *nkeys,
3990	KMF_DATA **certlist, int *ncerts)
3991{
3992	KMF_RETURN rv = KMF_OK;
3993	KMF_RAW_KEY_DATA key;
3994	int i;
3995
3996	if (sslkey != NULL) {
3997		/* Convert SSL key to raw key */
3998		switch (sslkey->type) {
3999			case EVP_PKEY_RSA:
4000				rv = exportRawRSAKey(EVP_PKEY_get1_RSA(sslkey),
4001					&key);
4002				if (rv != KMF_OK)
4003					return (rv);
4004
4005				break;
4006			case EVP_PKEY_DSA:
4007				rv = exportRawDSAKey(EVP_PKEY_get1_DSA(sslkey),
4008					&key);
4009				if (rv != KMF_OK)
4010					return (rv);
4011
4012				break;
4013			default:
4014				return (KMF_ERR_BAD_PARAMETER);
4015		}
4016
4017		rv = add_key_to_list(keylist, &key, nkeys);
4018		if (rv != KMF_OK)
4019			return (rv);
4020	}
4021
4022	/* Now add the certificate to the certlist */
4023	if (sslcert != NULL) {
4024		rv = add_cert_to_list(kmfh, sslcert, certlist, ncerts);
4025		if (rv != KMF_OK)
4026			return (rv);
4027	}
4028
4029	/* Also add any included CA certs to the list */
4030	for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) {
4031		X509 *c;
4032		/*
4033		 * sk_X509_value() is macro that embeds a cast to (X509 *).
4034		 * Here it translates into ((X509 *)sk_value((ca), (i))).
4035		 * Lint is complaining about the embedded casting, and
4036		 * to fix it, you need to fix openssl header files.
4037		 */
4038		/* LINTED E_BAD_PTR_CAST_ALIGN */
4039		c = sk_X509_value(sslcacerts, i);
4040
4041		/* Now add the ca cert to the certlist */
4042		rv = add_cert_to_list(kmfh, c, certlist, ncerts);
4043		if (rv != KMF_OK)
4044			return (rv);
4045	}
4046	return (rv);
4047}
4048
4049KMF_RETURN
4050openssl_read_pkcs12(KMF_HANDLE *kmfh,
4051	char *filename, KMF_CREDENTIAL *cred,
4052	KMF_DATA **certlist, int *ncerts,
4053	KMF_RAW_KEY_DATA **keylist, int *nkeys)
4054{
4055	KMF_RETURN	rv = KMF_OK;
4056	BIO		*bio = NULL;
4057	EVP_PKEY	*privkey = NULL;
4058	X509		*cert = NULL;
4059	STACK_OF(X509)	*cacerts = NULL;
4060
4061	bio = BIO_new_file(filename, "rb");
4062	if (bio == NULL) {
4063		SET_ERROR(kmfh, ERR_get_error());
4064		rv = KMF_ERR_OPEN_FILE;
4065		goto end;
4066	}
4067
4068	*certlist = NULL;
4069	*keylist = NULL;
4070	*ncerts = 0;
4071	*nkeys = 0;
4072
4073	rv = extract_pkcs12(bio,
4074		(uchar_t *)cred->cred,
4075		(uint32_t)cred->credlen,
4076		&privkey, &cert, &cacerts);
4077
4078	if (rv == KMF_OK)
4079		/* Convert keys and certs to exportable format */
4080		rv = convertPK12Objects(kmfh, privkey, cert, cacerts,
4081			keylist, nkeys, certlist, ncerts);
4082
4083end:
4084	if (bio != NULL)
4085		(void) BIO_free(bio);
4086
4087	if (privkey)
4088		EVP_PKEY_free(privkey);
4089
4090	if (cert)
4091		X509_free(cert);
4092
4093	if (cacerts)
4094		sk_X509_free(cacerts);
4095
4096	return (rv);
4097}
4098
4099KMF_RETURN
4100openssl_import_keypair(KMF_HANDLE *kmfh,
4101	char *filename, KMF_CREDENTIAL *cred,
4102	KMF_DATA **certlist, int *ncerts,
4103	KMF_RAW_KEY_DATA **keylist, int *nkeys)
4104{
4105	KMF_RETURN	rv = KMF_OK;
4106	EVP_PKEY	*privkey = NULL;
4107	KMF_ENCODE_FORMAT format;
4108
4109	/*
4110	 * auto-detect the file format, regardless of what
4111	 * the 'format' parameters in the params say.
4112	 */
4113	rv = KMF_GetFileFormat(filename, &format);
4114	if (rv != KMF_OK) {
4115		if (rv == KMF_ERR_OPEN_FILE)
4116			rv = KMF_ERR_CERT_NOT_FOUND;
4117		return (rv);
4118	}
4119
4120	/* This function only works on PEM files */
4121	if (format != KMF_FORMAT_PEM &&
4122		format != KMF_FORMAT_PEM_KEYPAIR)
4123		return (KMF_ERR_ENCODING);
4124
4125	*certlist = NULL;
4126	*keylist = NULL;
4127	*ncerts = 0;
4128	*nkeys = 0;
4129	rv = extract_objects(kmfh, NULL, filename,
4130		(uchar_t *)cred->cred,
4131		(uint32_t)cred->credlen,
4132		&privkey, certlist, ncerts);
4133
4134	/* Reached end of import file? */
4135	if (rv == KMF_OK)
4136		/* Convert keys and certs to exportable format */
4137		rv = convertPK12Objects(kmfh, privkey, NULL, NULL,
4138			keylist, nkeys, NULL, NULL);
4139
4140end:
4141	if (privkey)
4142		EVP_PKEY_free(privkey);
4143
4144	return (rv);
4145}
4146
4147KMF_RETURN
4148OpenSSL_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params,
4149	KMF_RAW_KEY_DATA *key)
4150{
4151	KMF_RETURN	rv = KMF_OK;
4152	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4153	char		*fullpath;
4154	EVP_PKEY	*pkey = NULL;
4155	BIO		*bio = NULL;
4156
4157	if (key != NULL) {
4158		if (key->keytype == KMF_RSA) {
4159			pkey = ImportRawRSAKey(&key->rawdata.rsa);
4160		} else if (key->keytype == KMF_DSA) {
4161			pkey = ImportRawDSAKey(&key->rawdata.dsa);
4162		} else {
4163			rv = KMF_ERR_BAD_PARAMETER;
4164		}
4165	} else {
4166		rv = KMF_ERR_BAD_PARAMETER;
4167	}
4168	if (rv != KMF_OK || pkey == NULL)
4169		return (rv);
4170
4171	fullpath = get_fullpath(params->sslparms.dirpath,
4172			params->sslparms.keyfile);
4173
4174	if (fullpath == NULL)
4175		return (KMF_ERR_BAD_PARAMETER);
4176
4177	/* If the requested file exists, return an error */
4178	if (access(fullpath, F_OK) == 0) {
4179		free(fullpath);
4180		return (KMF_ERR_DUPLICATE_KEYFILE);
4181	}
4182
4183	bio = BIO_new_file(fullpath, "wb");
4184	if (bio == NULL) {
4185		SET_ERROR(kmfh, ERR_get_error());
4186		rv = KMF_ERR_OPEN_FILE;
4187		goto cleanup;
4188	}
4189
4190	rv = ssl_write_private_key(kmfh,
4191		params->sslparms.format,
4192		bio, &params->cred, pkey);
4193
4194cleanup:
4195	if (fullpath)
4196		free(fullpath);
4197
4198	if (pkey)
4199		EVP_PKEY_free(pkey);
4200
4201	if (bio)
4202		(void) BIO_free(bio);
4203
4204	/* Protect the file by making it read-only */
4205	if (rv == KMF_OK) {
4206		(void) chmod(fullpath, 0400);
4207	}
4208	return (rv);
4209}
4210
4211static KMF_RETURN
4212create_deskey(DES_cblock **deskey)
4213{
4214	DES_cblock *key;
4215
4216	key = (DES_cblock *) malloc(sizeof (DES_cblock));
4217	if (key == NULL) {
4218		return (KMF_ERR_MEMORY);
4219	}
4220
4221	if (DES_random_key(key) == 0) {
4222		free(key);
4223		return (KMF_ERR_KEYGEN_FAILED);
4224	}
4225
4226	*deskey = key;
4227	return (KMF_OK);
4228}
4229
4230#define	KEYGEN_RETRY 3
4231#define	DES3_KEY_SIZE 24
4232
4233static KMF_RETURN
4234create_des3key(unsigned char **des3key)
4235{
4236	KMF_RETURN ret = KMF_OK;
4237	DES_cblock *deskey1 = NULL;
4238	DES_cblock *deskey2 = NULL;
4239	DES_cblock *deskey3 = NULL;
4240	unsigned char *newkey = NULL;
4241	int retry;
4242
4243	if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) {
4244		return (KMF_ERR_MEMORY);
4245	}
4246
4247	/* create the 1st DES key */
4248	if ((ret = create_deskey(&deskey1)) != KMF_OK) {
4249		goto out;
4250	}
4251
4252	/*
4253	 * Create the 2nd DES key and make sure its value is different
4254	 * from the 1st DES key.
4255	 */
4256	retry = 0;
4257	do {
4258		if (deskey2 != NULL) {
4259			free(deskey2);
4260			deskey2 = NULL;
4261		}
4262
4263		if ((ret = create_deskey(&deskey2)) != KMF_OK) {
4264			goto out;
4265		}
4266
4267		if (memcmp((const void *) deskey1, (const void *) deskey2, 8)
4268		    == 0) {
4269			ret = KMF_ERR_KEYGEN_FAILED;
4270			retry++;
4271		}
4272	} while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4273
4274	if (ret != KMF_OK) {
4275		goto out;
4276	}
4277
4278	/*
4279	 * Create the 3rd DES key and make sure its value is different
4280	 * from the 2nd DES key.
4281	 */
4282	retry = 0;
4283	do {
4284		if (deskey3 != NULL) {
4285			free(deskey3);
4286			deskey3 = NULL;
4287		}
4288
4289		if ((ret = create_deskey(&deskey3)) != KMF_OK) {
4290			goto out;
4291		}
4292
4293		if (memcmp((const void *)deskey2, (const void *)deskey3, 8)
4294		    == 0) {
4295			ret = KMF_ERR_KEYGEN_FAILED;
4296			retry++;
4297		}
4298	} while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4299
4300	if (ret != KMF_OK) {
4301		goto out;
4302	}
4303
4304	/* Concatenate 3 DES keys into a DES3 key */
4305	(void) memcpy((void *)newkey, (const void *)deskey1, 8);
4306	(void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8);
4307	(void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8);
4308	*des3key = newkey;
4309
4310out:
4311	if (deskey1 != NULL)
4312		free(deskey1);
4313
4314	if (deskey2 != NULL)
4315		free(deskey2);
4316
4317	if (deskey3 != NULL)
4318		free(deskey3);
4319
4320	if (ret != KMF_OK && newkey != NULL)
4321		free(newkey);
4322
4323	return (ret);
4324}
4325
4326KMF_RETURN
4327OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params,
4328	KMF_KEY_HANDLE *symkey)
4329{
4330	KMF_RETURN ret = KMF_OK;
4331	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4332	char *fullpath = NULL;
4333	KMF_RAW_SYM_KEY *rkey = NULL;
4334	DES_cblock *deskey = NULL;
4335	unsigned char *des3key = NULL;
4336	unsigned char *random = NULL;
4337	int fd = -1;
4338
4339	if (kmfh == NULL)
4340		return (KMF_ERR_UNINITIALIZED);
4341
4342	if (params == NULL || params->sslparms.keyfile == NULL) {
4343		return (KMF_ERR_BAD_PARAMETER);
4344	}
4345
4346	fullpath = get_fullpath(params->sslparms.dirpath,
4347		params->sslparms.keyfile);
4348	if (fullpath == NULL)
4349		return (KMF_ERR_BAD_PARAMETER);
4350
4351	/* If the requested file exists, return an error */
4352	if (access(fullpath, F_OK) == 0) {
4353		free(fullpath);
4354		return (KMF_ERR_DUPLICATE_KEYFILE);
4355	}
4356
4357	fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400);
4358	if (fd == -1) {
4359		ret = KMF_ERR_OPEN_FILE;
4360		goto out;
4361	}
4362
4363	rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
4364	if (rkey == NULL) {
4365		ret = KMF_ERR_MEMORY;
4366		goto out;
4367	}
4368	(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
4369
4370	if (params->keytype == KMF_DES) {
4371		if ((ret = create_deskey(&deskey)) != KMF_OK) {
4372			goto out;
4373		}
4374		rkey->keydata.val = (uchar_t *)deskey;
4375		rkey->keydata.len = 8;
4376
4377		symkey->keyalg = KMF_DES;
4378
4379	} else if (params->keytype == KMF_DES3) {
4380		if ((ret = create_des3key(&des3key)) != KMF_OK) {
4381			goto out;
4382		}
4383		rkey->keydata.val = (uchar_t *)des3key;
4384		rkey->keydata.len = DES3_KEY_SIZE;
4385		symkey->keyalg = KMF_DES3;
4386
4387	} else if (params->keytype == KMF_AES || params->keytype == KMF_RC4 ||
4388	    params->keytype == KMF_GENERIC_SECRET) {
4389		int bytes;
4390
4391		if (params->keylength % 8 != 0) {
4392			ret = KMF_ERR_BAD_KEY_SIZE;
4393			goto out;
4394		}
4395
4396		if (params->keytype == KMF_AES) {
4397			if (params->keylength != 128 &&
4398			    params->keylength != 192 &&
4399			    params->keylength != 256) {
4400				ret = KMF_ERR_BAD_KEY_SIZE;
4401				goto out;
4402			}
4403		}
4404
4405		bytes = params->keylength/8;
4406		random = malloc(bytes);
4407		if (random == NULL) {
4408			ret = KMF_ERR_MEMORY;
4409			goto out;
4410		}
4411		if (RAND_bytes(random, bytes) != 1) {
4412			ret = KMF_ERR_KEYGEN_FAILED;
4413			goto out;
4414		}
4415
4416		rkey->keydata.val = (uchar_t *)random;
4417		rkey->keydata.len = bytes;
4418		symkey->keyalg = params->keytype;
4419
4420	} else {
4421		ret = KMF_ERR_BAD_KEY_TYPE;
4422		goto out;
4423	}
4424
4425	(void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len);
4426
4427	symkey->kstype = KMF_KEYSTORE_OPENSSL;
4428	symkey->keyclass = KMF_SYMMETRIC;
4429	symkey->keylabel = (char *)fullpath;
4430	symkey->israw = TRUE;
4431	symkey->keyp = rkey;
4432
4433out:
4434	if (fd != -1)
4435		(void) close(fd);
4436
4437	if (ret != KMF_OK && fullpath != NULL) {
4438		free(fullpath);
4439	}
4440	if (ret != KMF_OK) {
4441		KMF_FreeRawSymKey(rkey);
4442		symkey->keyp = NULL;
4443		symkey->keyalg = KMF_KEYALG_NONE;
4444	}
4445
4446	return (ret);
4447}
4448
4449
4450KMF_RETURN
4451OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, KMF_VERIFYCRL_PARAMS *params)
4452{
4453	KMF_RETURN	ret = KMF_OK;
4454	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4455	BIO		*bcrl = NULL;
4456	X509_CRL   	*xcrl = NULL;
4457	X509		*xcert = NULL;
4458	EVP_PKEY	*pkey;
4459	int		sslret;
4460	KMF_ENCODE_FORMAT crl_format;
4461	unsigned char	*p;
4462	long		len;
4463
4464	if (params->crl_name == NULL || params->tacert == NULL) {
4465		return (KMF_ERR_BAD_PARAMETER);
4466	}
4467
4468	ret = KMF_GetFileFormat(params->crl_name, &crl_format);
4469	if (ret != KMF_OK)
4470		return (ret);
4471
4472	bcrl = BIO_new_file(params->crl_name, "rb");
4473	if (bcrl == NULL)	{
4474		SET_ERROR(kmfh, ERR_get_error());
4475		ret = KMF_ERR_OPEN_FILE;
4476		goto cleanup;
4477	}
4478
4479	if (crl_format == KMF_FORMAT_ASN1) {
4480		xcrl = d2i_X509_CRL_bio(bcrl, NULL);
4481	} else if (crl_format == KMF_FORMAT_PEM) {
4482		xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
4483	} else {
4484		ret = KMF_ERR_BAD_PARAMETER;
4485		goto cleanup;
4486	}
4487
4488	if (xcrl == NULL) {
4489		SET_ERROR(kmfh, ERR_get_error());
4490		ret = KMF_ERR_BAD_CRLFILE;
4491		goto cleanup;
4492	}
4493
4494	p = params->tacert->Data;
4495	len = params->tacert->Length;
4496	xcert = d2i_X509(NULL, (const uchar_t **)&p, len);
4497
4498	if (xcert == NULL) {
4499		SET_ERROR(kmfh, ERR_get_error());
4500		ret = KMF_ERR_BAD_CERTFILE;
4501		goto cleanup;
4502	}
4503
4504	/* Get issuer certificate public key */
4505	pkey = X509_get_pubkey(xcert);
4506	if (!pkey) {
4507		SET_ERROR(kmfh, ERR_get_error());
4508		ret = KMF_ERR_BAD_CERT_FORMAT;
4509		goto cleanup;
4510	}
4511
4512	/* Verify CRL signature */
4513	sslret = X509_CRL_verify(xcrl, pkey);
4514	EVP_PKEY_free(pkey);
4515	if (sslret > 0) {
4516		ret = KMF_OK;
4517	} else {
4518		SET_ERROR(kmfh, sslret);
4519		ret = KMF_ERR_BAD_CRLFILE;
4520	}
4521
4522cleanup:
4523	if (bcrl != NULL)
4524		(void) BIO_free(bcrl);
4525
4526	if (xcrl != NULL)
4527		X509_CRL_free(xcrl);
4528
4529	if (xcert != NULL)
4530		X509_free(xcert);
4531
4532	return (ret);
4533
4534}
4535
4536KMF_RETURN
4537OpenSSL_CheckCRLDate(KMF_HANDLE_T handle,
4538	KMF_CHECKCRLDATE_PARAMS *params)
4539{
4540
4541	KMF_RETURN	ret = KMF_OK;
4542	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4543	KMF_ENCODE_FORMAT crl_format;
4544	BIO		*bcrl = NULL;
4545	X509_CRL   	*xcrl = NULL;
4546	int		i;
4547
4548	if (params == NULL || params->crl_name == NULL) {
4549		return (KMF_ERR_BAD_PARAMETER);
4550	}
4551
4552	ret = KMF_IsCRLFile(handle, params->crl_name, &crl_format);
4553	if (ret != KMF_OK)
4554		return (ret);
4555
4556	bcrl = BIO_new_file(params->crl_name, "rb");
4557	if (bcrl == NULL)	{
4558		SET_ERROR(kmfh, ERR_get_error());
4559		ret = KMF_ERR_OPEN_FILE;
4560		goto cleanup;
4561	}
4562
4563	if (crl_format == KMF_FORMAT_ASN1) {
4564		xcrl = d2i_X509_CRL_bio(bcrl, NULL);
4565	} else if (crl_format == KMF_FORMAT_PEM) {
4566		xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
4567	}
4568
4569	if (xcrl == NULL) {
4570		SET_ERROR(kmfh, ERR_get_error());
4571		ret = KMF_ERR_BAD_CRLFILE;
4572		goto cleanup;
4573	}
4574
4575	i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL);
4576	if (i >= 0) {
4577		ret = KMF_ERR_VALIDITY_PERIOD;
4578		goto cleanup;
4579	}
4580
4581	if (X509_CRL_get_nextUpdate(xcrl)) {
4582		i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL);
4583
4584		if (i <= 0) {
4585			ret = KMF_ERR_VALIDITY_PERIOD;
4586			goto cleanup;
4587		}
4588	}
4589
4590	ret = KMF_OK;
4591
4592cleanup:
4593	if (bcrl != NULL)
4594		(void) BIO_free(bcrl);
4595
4596	if (xcrl != NULL)
4597		X509_CRL_free(xcrl);
4598
4599	return (ret);
4600}
4601
4602/*
4603 * Check a file to see if it is a CRL file with PEM or DER format.
4604 * If success, return its format in the "pformat" argument.
4605 */
4606KMF_RETURN
4607OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat)
4608{
4609	KMF_RETURN	ret = KMF_OK;
4610	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4611	BIO		*bio = NULL;
4612	X509_CRL   	*xcrl = NULL;
4613
4614	if (filename == NULL) {
4615		return (KMF_ERR_BAD_PARAMETER);
4616	}
4617
4618	bio = BIO_new_file(filename, "rb");
4619	if (bio == NULL)	{
4620		SET_ERROR(kmfh, ERR_get_error());
4621		ret = KMF_ERR_OPEN_FILE;
4622		goto out;
4623	}
4624
4625	if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) {
4626		*pformat = KMF_FORMAT_PEM;
4627		goto out;
4628	}
4629	(void) BIO_free(bio);
4630
4631	/*
4632	 * Now try to read it as raw DER data.
4633	 */
4634	bio = BIO_new_file(filename, "rb");
4635	if (bio == NULL)	{
4636		SET_ERROR(kmfh, ERR_get_error());
4637		ret = KMF_ERR_OPEN_FILE;
4638		goto out;
4639	}
4640
4641	if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) {
4642		*pformat = KMF_FORMAT_ASN1;
4643	} else {
4644		ret = KMF_ERR_BAD_CRLFILE;
4645	}
4646
4647out:
4648	if (bio != NULL)
4649		(void) BIO_free(bio);
4650
4651	if (xcrl != NULL)
4652		X509_CRL_free(xcrl);
4653
4654	return (ret);
4655}
4656
4657/*
4658 * Check a file to see if it is a certficate file with PEM or DER format.
4659 * If success, return its format in the pformat argument.
4660 */
4661KMF_RETURN
4662OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename,
4663	KMF_ENCODE_FORMAT *pformat)
4664{
4665	KMF_RETURN	ret = KMF_OK;
4666	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4667	BIO		*bio = NULL;
4668	X509		*xcert = NULL;
4669
4670	if (filename == NULL) {
4671		return (KMF_ERR_BAD_PARAMETER);
4672	}
4673
4674	ret = KMF_GetFileFormat(filename, pformat);
4675	if (ret != KMF_OK)
4676		return (ret);
4677
4678	bio = BIO_new_file(filename, "rb");
4679	if (bio == NULL)	{
4680		SET_ERROR(kmfh, ERR_get_error());
4681		ret = KMF_ERR_OPEN_FILE;
4682		goto out;
4683	}
4684
4685	if ((*pformat) == KMF_FORMAT_PEM) {
4686		if ((xcert = PEM_read_bio_X509(bio, NULL,
4687			NULL, NULL)) == NULL) {
4688			ret = KMF_ERR_BAD_CERTFILE;
4689		}
4690	} else if ((*pformat) == KMF_FORMAT_ASN1) {
4691		if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) {
4692			ret = KMF_ERR_BAD_CERTFILE;
4693		}
4694	} else {
4695		ret = KMF_ERR_BAD_CERTFILE;
4696	}
4697
4698out:
4699	if (bio != NULL)
4700		(void) BIO_free(bio);
4701
4702	if (xcert != NULL)
4703		X509_free(xcert);
4704
4705	return (ret);
4706}
4707
4708KMF_RETURN
4709OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
4710    KMF_RAW_SYM_KEY *rkey)
4711{
4712	KMF_RETURN	rv = KMF_OK;
4713	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4714	KMF_DATA	keyvalue;
4715
4716	if (kmfh == NULL)
4717		return (KMF_ERR_UNINITIALIZED);
4718
4719	if (symkey == NULL || rkey == NULL)
4720		return (KMF_ERR_BAD_PARAMETER);
4721	else if (symkey->keyclass != KMF_SYMMETRIC)
4722		return (KMF_ERR_BAD_KEY_CLASS);
4723
4724	if (symkey->israw) {
4725		KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp;
4726
4727		if (rawkey == NULL ||
4728		    rawkey->keydata.val == NULL ||
4729		    rawkey->keydata.len == 0)
4730			return (KMF_ERR_BAD_KEYHANDLE);
4731
4732		rkey->keydata.len = rawkey->keydata.len;
4733		if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
4734			return (KMF_ERR_MEMORY);
4735		(void) memcpy(rkey->keydata.val, rawkey->keydata.val,
4736		    rkey->keydata.len);
4737	} else {
4738		rv = KMF_ReadInputFile(handle, symkey->keylabel, &keyvalue);
4739		if (rv != KMF_OK)
4740			return (rv);
4741		rkey->keydata.len = keyvalue.Length;
4742		rkey->keydata.val = keyvalue.Data;
4743	}
4744
4745	return (rv);
4746}
4747
4748/*
4749 * id-sha1    OBJECT IDENTIFIER ::= {
4750 *     iso(1) identified-organization(3) oiw(14) secsig(3)
4751 *     algorithms(2) 26
4752 * }
4753 */
4754#define	ASN1_SHA1_OID_PREFIX_LEN 15
4755static uchar_t SHA1_DER_PREFIX[ASN1_SHA1_OID_PREFIX_LEN] = {
4756	0x30, 0x21, 0x30, 0x09,
4757	0x06, 0x05, 0x2b, 0x0e,
4758	0x03, 0x02, 0x1a, 0x05,
4759	0x00, 0x04, 0x14
4760};
4761
4762/*
4763 * id-md2 OBJECT IDENTIFIER ::= {
4764 *     iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2
4765 * }
4766 */
4767#define	ASN1_MD2_OID_PREFIX_LEN 18
4768static uchar_t MD2_DER_PREFIX[ASN1_MD2_OID_PREFIX_LEN] = {
4769	0x30, 0x20, 0x30, 0x0c,
4770	0x06, 0x08, 0x2a, 0x86,
4771	0x48, 0x86, 0xf7, 0x0d,
4772	0x02, 0x02, 0x05, 0x00,
4773	0x04, 0x10
4774};
4775
4776/*
4777 * id-md5 OBJECT IDENTIFIER ::= {
4778 *     iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5
4779 * }
4780 */
4781#define	ASN1_MD5_OID_PREFIX_LEN 18
4782static uchar_t MD5_DER_PREFIX[ASN1_MD5_OID_PREFIX_LEN] = {
4783	0x30, 0x20, 0x30, 0x0c,
4784	0x06, 0x08, 0x2a, 0x86,
4785	0x48, 0x86, 0xf7, 0x0d,
4786	0x02, 0x05, 0x05, 0x00,
4787	0x04, 0x10
4788};
4789
4790KMF_RETURN
4791OpenSSL_VerifyDataWithCert(KMF_HANDLE_T handle,
4792	KMF_ALGORITHM_INDEX algid, KMF_DATA *indata,
4793	KMF_DATA *insig, KMF_DATA *cert)
4794{
4795	KMF_RETURN ret = KMF_OK;
4796	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4797	X509	*xcert = NULL;
4798	EVP_PKEY *pkey = NULL;
4799	uchar_t *p;
4800	uchar_t *rsaout = NULL;
4801	uchar_t *pfx = NULL;
4802	const EVP_MD *md;
4803	int pfxlen = 0, len;
4804
4805	if (handle == NULL || indata == NULL ||
4806	    indata->Data == NULL || indata->Length == 0 ||
4807	    insig == NULL|| insig->Data == NULL || insig->Length == 0 ||
4808	    cert == NULL || cert->Data == NULL || cert->Length == 0)
4809		return (KMF_ERR_BAD_PARAMETER);
4810
4811	p = cert->Data;
4812	xcert = d2i_X509(NULL, (const uchar_t **)&p, cert->Length);
4813	if (xcert == NULL) {
4814		SET_ERROR(kmfh, ERR_get_error());
4815		ret = KMF_ERR_BAD_CERT_FORMAT;
4816		goto cleanup;
4817	}
4818
4819	pkey = X509_get_pubkey(xcert);
4820	if (!pkey) {
4821		SET_ERROR(kmfh, ERR_get_error());
4822		ret = KMF_ERR_BAD_CERT_FORMAT;
4823		goto cleanup;
4824	}
4825
4826	if (algid != KMF_ALGID_NONE) {
4827		switch (algid) {
4828			case KMF_ALGID_MD5WithRSA:
4829				md = EVP_md5();
4830				break;
4831			case KMF_ALGID_MD2WithRSA:
4832				md = EVP_md2();
4833				break;
4834			case KMF_ALGID_SHA1WithRSA:
4835				md = EVP_sha1();
4836				break;
4837			case KMF_ALGID_RSA:
4838				md = NULL;
4839				break;
4840			default:
4841				ret = KMF_ERR_BAD_PARAMETER;
4842				goto cleanup;
4843		}
4844	} else {
4845		/* Get the hash type from the cert signature */
4846		md = EVP_get_digestbyobj(xcert->sig_alg->algorithm);
4847		if (md == NULL) {
4848			SET_ERROR(kmfh, ERR_get_error());
4849			ret = KMF_ERR_BAD_PARAMETER;
4850			goto cleanup;
4851		}
4852	}
4853	if (md != NULL) {
4854		switch (EVP_MD_type(md)) {
4855		case NID_md2:
4856		case NID_md2WithRSAEncryption:
4857			pfxlen = ASN1_MD2_OID_PREFIX_LEN;
4858			pfx = MD2_DER_PREFIX;
4859			break;
4860		case NID_md5:
4861		case NID_md5WithRSAEncryption:
4862			pfxlen = ASN1_MD5_OID_PREFIX_LEN;
4863			pfx = MD5_DER_PREFIX;
4864			break;
4865		case NID_sha1:
4866		case NID_sha1WithRSAEncryption:
4867			pfxlen = ASN1_SHA1_OID_PREFIX_LEN;
4868			pfx = SHA1_DER_PREFIX;
4869			break;
4870		default: /* Unsupported */
4871			pfxlen = 0;
4872			pfx = NULL;
4873			break;
4874		}
4875	}
4876
4877	/* RSA with no hash is a special case */
4878	rsaout = malloc(RSA_size(pkey->pkey.rsa));
4879	if (rsaout == NULL)
4880		return (KMF_ERR_MEMORY);
4881
4882	/* Decrypt the input signature */
4883	len = RSA_public_decrypt(insig->Length,
4884		insig->Data, rsaout, pkey->pkey.rsa, RSA_PKCS1_PADDING);
4885	if (len < 1) {
4886		SET_ERROR(kmfh, ERR_get_error());
4887		ret = KMF_ERR_BAD_PARAMETER;
4888	} else {
4889		size_t hashlen = 0;
4890		uint32_t dlen;
4891		char *digest = NULL;
4892
4893		/*
4894		 * If the AlgId requires it, hash the input data before
4895		 * comparing it to the decrypted signature.
4896		 */
4897		if (md) {
4898			EVP_MD_CTX ctx;
4899
4900			hashlen = md->md_size;
4901
4902			digest = malloc(hashlen + pfxlen);
4903			if (digest == NULL)
4904				return (KMF_ERR_MEMORY);
4905			/* Add the prefix to the comparison buffer. */
4906			if (pfx && pfxlen > 0) {
4907				(void) memcpy(digest, pfx, pfxlen);
4908			}
4909			(void) EVP_DigestInit(&ctx, md);
4910			(void) EVP_DigestUpdate(&ctx, indata->Data,
4911				indata->Length);
4912
4913			/* Add the digest AFTER the ASN1 prefix */
4914			(void) EVP_DigestFinal(&ctx,
4915				(uchar_t *)digest + pfxlen, &dlen);
4916
4917			dlen += pfxlen;
4918		} else {
4919			digest = (char *)indata->Data;
4920			dlen = indata->Length;
4921		}
4922
4923		/*
4924		 * The result of the RSA decryption should be ASN1(OID | Hash).
4925		 * Compare the output hash to the input data for the final
4926		 * result.
4927		 */
4928		if (memcmp(rsaout, digest, dlen))
4929			ret = KMF_ERR_INTERNAL;
4930		else
4931			ret = KMF_OK;
4932
4933		/* If we had to allocate space for the digest, free it now */
4934		if (hashlen)
4935			free(digest);
4936	}
4937cleanup:
4938	if (pkey)
4939		EVP_PKEY_free(pkey);
4940
4941	if (xcert)
4942		X509_free(xcert);
4943
4944	if (rsaout)
4945		free(rsaout);
4946
4947	return (ret);
4948}
4949