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