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