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