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