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