openssl_spi.c revision 5536:865d075cefb7
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_ASN1:
1420			if (pkey->type == EVP_PKEY_RSA) {
1421				rsa = EVP_PKEY_get1_RSA(pkey);
1422				if (private)
1423					rv = i2d_RSAPrivateKey_bio(out, rsa);
1424				else
1425					rv = i2d_RSAPublicKey_bio(out, rsa);
1426				RSA_free(rsa);
1427			} else if (pkey->type == EVP_PKEY_DSA) {
1428				dsa = EVP_PKEY_get1_DSA(pkey);
1429				rv = i2d_DSAPrivateKey_bio(out, dsa);
1430				DSA_free(dsa);
1431			}
1432			if (rv == 1) {
1433				rv = KMF_OK;
1434			} else {
1435				SET_ERROR(kmfh, rv);
1436			}
1437			break;
1438		case KMF_FORMAT_PEM:
1439			if (pkey->type == EVP_PKEY_RSA) {
1440				rsa = EVP_PKEY_get1_RSA(pkey);
1441				if (private)
1442					rv = PEM_write_bio_RSAPrivateKey(out,
1443					    rsa, NULL, NULL, 0, NULL,
1444					    (cred != NULL ? cred->cred : NULL));
1445				else
1446					rv = PEM_write_bio_RSAPublicKey(out,
1447					    rsa);
1448				RSA_free(rsa);
1449			} else if (pkey->type == EVP_PKEY_DSA) {
1450				dsa = EVP_PKEY_get1_DSA(pkey);
1451				rv = PEM_write_bio_DSAPrivateKey(out,
1452				    dsa, NULL, NULL, 0, NULL,
1453				    (cred != NULL ? cred->cred : NULL));
1454				DSA_free(dsa);
1455			}
1456
1457			if (rv == 1) {
1458				rv = KMF_OK;
1459			} else {
1460				SET_ERROR(kmfh, rv);
1461			}
1462			break;
1463
1464		default:
1465			rv = KMF_ERR_BAD_PARAMETER;
1466	}
1467
1468	return (rv);
1469}
1470
1471KMF_RETURN
1472OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr,
1473	KMF_ATTRIBUTE *attrlist)
1474{
1475	KMF_RETURN rv = KMF_OK;
1476	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1477	uint32_t eValue = 0x010001;
1478	RSA *sslPrivKey = NULL;
1479	DSA *sslDSAKey = NULL;
1480	EVP_PKEY *eprikey = NULL;
1481	EVP_PKEY *epubkey = NULL;
1482	BIO *out = NULL;
1483	KMF_KEY_HANDLE *pubkey = NULL, *privkey = NULL;
1484	uint32_t keylen = 1024;
1485	uint32_t keylen_size = sizeof (uint32_t);
1486	boolean_t storekey = TRUE;
1487	KMF_KEY_ALG keytype = KMF_RSA;
1488
1489	rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr,
1490	    &storekey, NULL);
1491	if (rv != KMF_OK) {
1492		/* "storekey" is optional. Default is TRUE */
1493		rv = KMF_OK;
1494	}
1495
1496	rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
1497	    (void *)&keytype, NULL);
1498	if (rv != KMF_OK)
1499		/* keytype is optional.  KMF_RSA is default */
1500		rv = KMF_OK;
1501
1502	pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
1503	if (pubkey == NULL)
1504		return (KMF_ERR_BAD_PARAMETER);
1505
1506	privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
1507	if (privkey == NULL)
1508		return (KMF_ERR_BAD_PARAMETER);
1509
1510	(void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
1511	(void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
1512
1513	eprikey = EVP_PKEY_new();
1514	if (eprikey == NULL) {
1515		SET_ERROR(kmfh, ERR_get_error());
1516		rv = KMF_ERR_KEYGEN_FAILED;
1517		goto cleanup;
1518	}
1519	epubkey = EVP_PKEY_new();
1520	if (epubkey == NULL) {
1521		SET_ERROR(kmfh, ERR_get_error());
1522		rv = KMF_ERR_KEYGEN_FAILED;
1523		goto cleanup;
1524	}
1525	if (keytype == KMF_RSA) {
1526		KMF_BIGINT *rsaexp = NULL;
1527
1528		rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attrlist, numattr);
1529		if (rsaexp != NULL) {
1530			if (rsaexp->len > 0 &&
1531			    rsaexp->len <= sizeof (eValue) &&
1532			    rsaexp->val != NULL) {
1533				/*LINTED*/
1534				eValue = *(uint32_t *)rsaexp->val;
1535			} else {
1536				rv = KMF_ERR_BAD_PARAMETER;
1537				goto cleanup;
1538			}
1539		} else {
1540			/* RSA Exponent is optional. Default is 0x10001 */
1541			rv = KMF_OK;
1542		}
1543
1544		rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
1545		    &keylen, &keylen_size);
1546		if (rv == KMF_ERR_ATTR_NOT_FOUND)
1547			/* keylen is optional, default is 1024 */
1548			rv = KMF_OK;
1549		if (rv != KMF_OK) {
1550			rv = KMF_ERR_BAD_PARAMETER;
1551			goto cleanup;
1552		}
1553
1554		sslPrivKey = RSA_generate_key(keylen, eValue, NULL, NULL);
1555		if (sslPrivKey == NULL) {
1556			SET_ERROR(kmfh, ERR_get_error());
1557			rv = KMF_ERR_KEYGEN_FAILED;
1558		} else {
1559			(void) EVP_PKEY_set1_RSA(eprikey, sslPrivKey);
1560			privkey->kstype = KMF_KEYSTORE_OPENSSL;
1561			privkey->keyalg = KMF_RSA;
1562			privkey->keyclass = KMF_ASYM_PRI;
1563			privkey->israw = FALSE;
1564			privkey->keyp = (void *)eprikey;
1565
1566			/* OpenSSL derives the public key from the private */
1567			(void) EVP_PKEY_set1_RSA(epubkey, sslPrivKey);
1568			pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1569			pubkey->keyalg = KMF_RSA;
1570			pubkey->israw = FALSE;
1571			pubkey->keyclass = KMF_ASYM_PUB;
1572			pubkey->keyp = (void *)epubkey;
1573		}
1574	} else if (keytype == KMF_DSA) {
1575		DSA *dp;
1576		sslDSAKey = DSA_new();
1577		if (sslDSAKey == NULL) {
1578			SET_ERROR(kmfh, ERR_get_error());
1579			return (KMF_ERR_MEMORY);
1580		}
1581
1582		if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) ==
1583		    NULL) {
1584			SET_ERROR(kmfh, ERR_get_error());
1585			rv = KMF_ERR_KEYGEN_FAILED;
1586			goto cleanup;
1587		}
1588		if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) ==
1589		    NULL) {
1590			SET_ERROR(kmfh, ERR_get_error());
1591			rv = KMF_ERR_KEYGEN_FAILED;
1592			goto cleanup;
1593		}
1594		if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) ==
1595		    NULL) {
1596			SET_ERROR(kmfh, ERR_get_error());
1597			rv = KMF_ERR_KEYGEN_FAILED;
1598			goto cleanup;
1599		}
1600
1601		if (!DSA_generate_key(sslDSAKey)) {
1602			SET_ERROR(kmfh, ERR_get_error());
1603			rv = KMF_ERR_KEYGEN_FAILED;
1604			goto cleanup;
1605		}
1606
1607		privkey->kstype = KMF_KEYSTORE_OPENSSL;
1608		privkey->keyalg = KMF_DSA;
1609		privkey->keyclass = KMF_ASYM_PRI;
1610		privkey->israw = FALSE;
1611		if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) {
1612			privkey->keyp = (void *)eprikey;
1613		} else {
1614			SET_ERROR(kmfh, ERR_get_error());
1615			rv = KMF_ERR_KEYGEN_FAILED;
1616			goto cleanup;
1617		}
1618		dp = DSA_new();
1619		/* Make a copy for the public key */
1620		if (dp != NULL) {
1621			if ((dp->p = BN_new()) == NULL) {
1622				SET_ERROR(kmfh, ERR_get_error());
1623				rv = KMF_ERR_MEMORY;
1624				DSA_free(dp);
1625				goto cleanup;
1626			}
1627			if ((dp->q = BN_new()) == NULL) {
1628				SET_ERROR(kmfh, ERR_get_error());
1629				rv = KMF_ERR_MEMORY;
1630				BN_free(dp->p);
1631				DSA_free(dp);
1632				goto cleanup;
1633			}
1634			if ((dp->g = BN_new()) == NULL) {
1635				SET_ERROR(kmfh, ERR_get_error());
1636				rv = KMF_ERR_MEMORY;
1637				BN_free(dp->q);
1638				BN_free(dp->p);
1639				DSA_free(dp);
1640				goto cleanup;
1641			}
1642			if ((dp->pub_key = BN_new()) == NULL) {
1643				SET_ERROR(kmfh, ERR_get_error());
1644				rv = KMF_ERR_MEMORY;
1645				BN_free(dp->q);
1646				BN_free(dp->p);
1647				BN_free(dp->g);
1648				DSA_free(dp);
1649				goto cleanup;
1650			}
1651			(void) BN_copy(dp->p, sslDSAKey->p);
1652			(void) BN_copy(dp->q, sslDSAKey->q);
1653			(void) BN_copy(dp->g, sslDSAKey->g);
1654			(void) BN_copy(dp->pub_key, sslDSAKey->pub_key);
1655
1656			pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1657			pubkey->keyalg = KMF_DSA;
1658			pubkey->keyclass = KMF_ASYM_PUB;
1659			pubkey->israw = FALSE;
1660
1661			if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) {
1662				pubkey->keyp = (void *)epubkey;
1663			} else {
1664				SET_ERROR(kmfh, ERR_get_error());
1665				rv = KMF_ERR_KEYGEN_FAILED;
1666				goto cleanup;
1667			}
1668		}
1669	}
1670
1671	if (rv != KMF_OK) {
1672		goto cleanup;
1673	}
1674
1675	if (storekey) {
1676		KMF_ATTRIBUTE storeattrs[4]; /* max. 4 attributes needed */
1677		int i = 0;
1678		char *keyfile = NULL, *dirpath = NULL;
1679		KMF_ENCODE_FORMAT format;
1680		/*
1681		 * Construct a new attribute arrray and call openssl_store_key
1682		 */
1683		kmf_set_attr_at_index(storeattrs, i, KMF_PRIVKEY_HANDLE_ATTR,
1684		    privkey, sizeof (privkey));
1685		i++;
1686
1687		dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1688		if (dirpath != NULL) {
1689			storeattrs[i].type = KMF_DIRPATH_ATTR;
1690			storeattrs[i].pValue = dirpath;
1691			storeattrs[i].valueLen = strlen(dirpath);
1692			i++;
1693		} else {
1694			rv = KMF_OK; /* DIRPATH is optional */
1695		}
1696		keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR,
1697		    attrlist, numattr);
1698		if (keyfile != NULL) {
1699			storeattrs[i].type = KMF_KEY_FILENAME_ATTR;
1700			storeattrs[i].pValue = keyfile;
1701			storeattrs[i].valueLen = strlen(keyfile);
1702			i++;
1703		} else {
1704			goto cleanup; /* KEYFILE is required */
1705		}
1706		rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
1707		    (void *)&format, NULL);
1708		if (rv == KMF_OK) {
1709			storeattrs[i].type = KMF_ENCODE_FORMAT_ATTR;
1710			storeattrs[i].pValue = &format;
1711			storeattrs[i].valueLen = sizeof (format);
1712			i++;
1713		}
1714
1715		rv = OpenSSL_StoreKey(handle, i, storeattrs);
1716	}
1717
1718cleanup:
1719	if (rv != KMF_OK) {
1720		if (eprikey != NULL)
1721			EVP_PKEY_free(eprikey);
1722
1723		if (epubkey != NULL)
1724			EVP_PKEY_free(epubkey);
1725
1726		if (pubkey->keylabel) {
1727			free(pubkey->keylabel);
1728			pubkey->keylabel = NULL;
1729		}
1730
1731		if (privkey->keylabel) {
1732			free(privkey->keylabel);
1733			privkey->keylabel = NULL;
1734		}
1735
1736		pubkey->keyp = NULL;
1737		privkey->keyp = NULL;
1738	}
1739
1740	if (sslPrivKey)
1741		RSA_free(sslPrivKey);
1742
1743	if (sslDSAKey)
1744		DSA_free(sslDSAKey);
1745
1746	if (out != NULL)
1747		(void) BIO_free(out);
1748
1749	return (rv);
1750}
1751
1752KMF_RETURN
1753OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
1754	KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output)
1755{
1756	KMF_RETURN ret = KMF_OK;
1757	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1758	KMF_ALGORITHM_INDEX		AlgId;
1759	EVP_MD_CTX ctx;
1760	const EVP_MD *md;
1761
1762	if (key == NULL || AlgOID == NULL ||
1763	    tobesigned == NULL || output == NULL ||
1764	    tobesigned->Data == NULL ||
1765	    output->Data == NULL)
1766		return (KMF_ERR_BAD_PARAMETER);
1767
1768	/* Map the OID to an OpenSSL algorithm */
1769	AlgId = x509_algoid_to_algid(AlgOID);
1770	if (AlgId == KMF_ALGID_NONE)
1771		return (KMF_ERR_BAD_PARAMETER);
1772
1773	if (key->keyalg == KMF_RSA) {
1774		EVP_PKEY *pkey = (EVP_PKEY *)key->keyp;
1775		uchar_t *p;
1776		int len;
1777		if (AlgId == KMF_ALGID_MD5WithRSA)
1778			md = EVP_md5();
1779		else if (AlgId == KMF_ALGID_MD2WithRSA)
1780			md = EVP_md2();
1781		else if (AlgId == KMF_ALGID_SHA1WithRSA)
1782			md = EVP_sha1();
1783		else if (AlgId == KMF_ALGID_RSA)
1784			md = NULL;
1785		else
1786			return (KMF_ERR_BAD_PARAMETER);
1787
1788		if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) {
1789			RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey);
1790
1791			p = output->Data;
1792			if ((len = RSA_private_encrypt(tobesigned->Length,
1793			    tobesigned->Data, p, rsa,
1794			    RSA_PKCS1_PADDING)) <= 0) {
1795				SET_ERROR(kmfh, ERR_get_error());
1796				ret = KMF_ERR_INTERNAL;
1797			}
1798			output->Length = len;
1799		} else {
1800			(void) EVP_MD_CTX_init(&ctx);
1801			(void) EVP_SignInit_ex(&ctx, md, NULL);
1802			(void) EVP_SignUpdate(&ctx, tobesigned->Data,
1803			    (uint32_t)tobesigned->Length);
1804			len = (uint32_t)output->Length;
1805			p = output->Data;
1806			if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) {
1807				SET_ERROR(kmfh, ERR_get_error());
1808				len = 0;
1809				ret = KMF_ERR_INTERNAL;
1810			}
1811			output->Length = len;
1812			(void) EVP_MD_CTX_cleanup(&ctx);
1813		}
1814	} else if (key->keyalg == KMF_DSA) {
1815		DSA *dsa = EVP_PKEY_get1_DSA(key->keyp);
1816
1817		uchar_t hash[EVP_MAX_MD_SIZE];
1818		uint32_t hashlen;
1819		DSA_SIG *dsasig;
1820
1821		/*
1822		 * OpenSSL EVP_Sign operation automatically converts to
1823		 * ASN.1 output so we do the operations separately so we
1824		 * are assured of NOT getting ASN.1 output returned.
1825		 * KMF does not want ASN.1 encoded results because
1826		 * not all mechanisms return ASN.1 encodings (PKCS#11
1827		 * and NSS return raw signature data).
1828		 */
1829		md = EVP_sha1();
1830		EVP_MD_CTX_init(&ctx);
1831		(void) EVP_DigestInit_ex(&ctx, md, NULL);
1832		(void) EVP_DigestUpdate(&ctx, tobesigned->Data,
1833		    tobesigned->Length);
1834		(void) EVP_DigestFinal_ex(&ctx, hash, &hashlen);
1835		(void) EVP_MD_CTX_cleanup(&ctx);
1836
1837		dsasig = DSA_do_sign(hash, hashlen, dsa);
1838		if (dsasig != NULL) {
1839			int i;
1840			output->Length = i = BN_bn2bin(dsasig->r, output->Data);
1841			output->Length += BN_bn2bin(dsasig->s,
1842			    &output->Data[i]);
1843			DSA_SIG_free(dsasig);
1844		} else {
1845			SET_ERROR(kmfh, ERR_get_error());
1846		}
1847	} else {
1848		return (KMF_ERR_BAD_PARAMETER);
1849	}
1850cleanup:
1851	return (ret);
1852}
1853
1854KMF_RETURN
1855/*ARGSUSED*/
1856OpenSSL_DeleteKey(KMF_HANDLE_T handle,
1857	int numattr, KMF_ATTRIBUTE *attrlist)
1858{
1859	KMF_RETURN rv = KMF_OK;
1860	KMF_KEY_HANDLE *key;
1861	boolean_t destroy = B_TRUE;
1862
1863	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
1864	if (key == NULL || key->keyp == NULL)
1865		return (KMF_ERR_BAD_PARAMETER);
1866
1867	rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
1868	    (void *)&destroy, NULL);
1869	if (rv != KMF_OK) {
1870		/* "destroy" is optional. Default is TRUE */
1871		rv = KMF_OK;
1872	}
1873
1874	if (key->keyclass != KMF_ASYM_PUB &&
1875	    key->keyclass != KMF_ASYM_PRI &&
1876	    key->keyclass != KMF_SYMMETRIC)
1877		return (KMF_ERR_BAD_KEY_CLASS);
1878
1879	if (key->keyclass == KMF_SYMMETRIC) {
1880		kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp);
1881		key->keyp = NULL;
1882	} else {
1883		if (key->keyp != NULL) {
1884			EVP_PKEY_free(key->keyp);
1885			key->keyp = NULL;
1886		}
1887	}
1888
1889	if (key->keylabel != NULL) {
1890		EVP_PKEY *pkey = NULL;
1891		/* If the file exists, make sure it is a proper key. */
1892		pkey = openssl_load_key(handle, key->keylabel);
1893		if (pkey == NULL) {
1894			if (key->keylabel != NULL) {
1895				free(key->keylabel);
1896				key->keylabel = NULL;
1897			}
1898			return (KMF_ERR_KEY_NOT_FOUND);
1899		}
1900		EVP_PKEY_free(pkey);
1901
1902		if (destroy) {
1903			if (unlink(key->keylabel) != 0) {
1904				KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1905				SET_SYS_ERROR(kmfh, errno);
1906				rv = KMF_ERR_INTERNAL;
1907			}
1908		}
1909		if (key->keylabel != NULL) {
1910			free(key->keylabel);
1911			key->keylabel = NULL;
1912		}
1913	}
1914	return (rv);
1915}
1916
1917KMF_RETURN
1918OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
1919{
1920	KMF_RETURN ret = KMF_OK;
1921	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1922	char str[256];	/* OpenSSL needs at least 120 byte buffer */
1923
1924	ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str));
1925	if (strlen(str)) {
1926		*msgstr = (char *)strdup(str);
1927		if ((*msgstr) == NULL)
1928			ret = KMF_ERR_MEMORY;
1929	} else {
1930		*msgstr = NULL;
1931	}
1932
1933	return (ret);
1934}
1935
1936static int
1937ext2NID(int kmfext)
1938{
1939	switch (kmfext) {
1940		case KMF_X509_EXT_KEY_USAGE:
1941			return (NID_key_usage);
1942		case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
1943			return (NID_private_key_usage_period);
1944		case KMF_X509_EXT_CERT_POLICIES:
1945			return (NID_certificate_policies);
1946		case KMF_X509_EXT_SUBJ_ALTNAME:
1947			return (NID_subject_alt_name);
1948		case KMF_X509_EXT_ISSUER_ALTNAME:
1949			return (NID_issuer_alt_name);
1950		case KMF_X509_EXT_BASIC_CONSTRAINTS:
1951			return (NID_basic_constraints);
1952		case KMF_X509_EXT_EXT_KEY_USAGE:
1953			return (NID_ext_key_usage);
1954		case KMF_X509_EXT_AUTH_KEY_ID:
1955			return (NID_authority_key_identifier);
1956		case KMF_X509_EXT_CRL_DIST_POINTS:
1957			return (NID_crl_distribution_points);
1958		case KMF_X509_EXT_SUBJ_KEY_ID:
1959			return (NID_subject_key_identifier);
1960		case KMF_X509_EXT_POLICY_MAPPINGS:
1961			return (OBJ_sn2nid("policyMappings"));
1962		case KMF_X509_EXT_NAME_CONSTRAINTS:
1963			return (OBJ_sn2nid("nameConstraints"));
1964		case KMF_X509_EXT_POLICY_CONSTRAINTS:
1965			return (OBJ_sn2nid("policyConstraints"));
1966		case KMF_X509_EXT_INHIBIT_ANY_POLICY:
1967			return (OBJ_sn2nid("inhibitAnyPolicy"));
1968		case KMF_X509_EXT_FRESHEST_CRL:
1969			return (OBJ_sn2nid("freshestCRL"));
1970		default:
1971			return (NID_undef);
1972	}
1973}
1974
1975KMF_RETURN
1976OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert,
1977	KMF_PRINTABLE_ITEM flag, char *resultStr)
1978{
1979	KMF_RETURN ret = KMF_OK;
1980	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1981	X509 *xcert = NULL;
1982	unsigned char *outbuf = NULL;
1983	unsigned char *outbuf_p;
1984	char *tmpstr = NULL;
1985	int j;
1986	int ext_index, nid, len;
1987	BIO *mem = NULL;
1988	STACK *emlst = NULL;
1989	X509_EXTENSION *ex;
1990	X509_CINF *ci;
1991
1992	if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) {
1993		return (KMF_ERR_BAD_PARAMETER);
1994	}
1995
1996	/* copy cert data to outbuf */
1997	outbuf = malloc(pcert->Length);
1998	if (outbuf == NULL) {
1999		return (KMF_ERR_MEMORY);
2000	}
2001	(void) memcpy(outbuf, pcert->Data, pcert->Length);
2002
2003	outbuf_p = outbuf; /* use a temp pointer; required by openssl */
2004	xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length);
2005	if (xcert == NULL) {
2006		SET_ERROR(kmfh, ERR_get_error());
2007		ret = KMF_ERR_ENCODING;
2008		goto out;
2009	}
2010
2011	mem = BIO_new(BIO_s_mem());
2012	if (mem == NULL) {
2013		SET_ERROR(kmfh, ERR_get_error());
2014		ret = KMF_ERR_MEMORY;
2015		goto out;
2016	}
2017
2018	switch (flag) {
2019	case KMF_CERT_ISSUER:
2020		(void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0,
2021		    XN_FLAG_SEP_CPLUS_SPC);
2022		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2023		break;
2024
2025	case KMF_CERT_SUBJECT:
2026		(void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0,
2027		    XN_FLAG_SEP_CPLUS_SPC);
2028		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2029		break;
2030
2031	case KMF_CERT_VERSION:
2032		tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version);
2033		(void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN);
2034		OPENSSL_free(tmpstr);
2035		len = strlen(resultStr);
2036		break;
2037
2038	case KMF_CERT_SERIALNUM:
2039		if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) {
2040			(void) strcpy(resultStr, "0x");
2041			len = BIO_gets(mem, &resultStr[2],
2042			    KMF_CERT_PRINTABLE_LEN - 2);
2043		}
2044		break;
2045
2046	case KMF_CERT_NOTBEFORE:
2047		(void) ASN1_TIME_print(mem, X509_get_notBefore(xcert));
2048		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2049		break;
2050
2051	case KMF_CERT_NOTAFTER:
2052		(void) ASN1_TIME_print(mem, X509_get_notAfter(xcert));
2053		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2054		break;
2055
2056	case KMF_CERT_PUBKEY_DATA:
2057		{
2058			EVP_PKEY *pkey = X509_get_pubkey(xcert);
2059			if (pkey == NULL) {
2060				SET_ERROR(kmfh, ERR_get_error());
2061				ret = KMF_ERR_ENCODING;
2062				goto out;
2063			}
2064
2065			if (pkey->type == EVP_PKEY_RSA) {
2066				(void) BIO_printf(mem,
2067				    "RSA Public Key: (%d bit)\n",
2068				    BN_num_bits(pkey->pkey.rsa->n));
2069				(void) RSA_print(mem, pkey->pkey.rsa, 0);
2070			} else if (pkey->type == EVP_PKEY_DSA) {
2071				(void) BIO_printf(mem,
2072				    "%12sDSA Public Key:\n", "");
2073				(void) DSA_print(mem, pkey->pkey.dsa, 0);
2074			} else {
2075				(void) BIO_printf(mem,
2076				    "%12sUnknown Public Key:\n", "");
2077			}
2078			(void) BIO_printf(mem, "\n");
2079			EVP_PKEY_free(pkey);
2080		}
2081		len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2082		break;
2083	case KMF_CERT_SIGNATURE_ALG:
2084	case KMF_CERT_PUBKEY_ALG:
2085		if (flag == KMF_CERT_SIGNATURE_ALG) {
2086			len = i2a_ASN1_OBJECT(mem,
2087			    xcert->sig_alg->algorithm);
2088		} else {
2089			len = i2a_ASN1_OBJECT(mem,
2090			    xcert->cert_info->key->algor->algorithm);
2091		}
2092
2093		if (len > 0) {
2094			len = BIO_read(mem, resultStr,
2095			    KMF_CERT_PRINTABLE_LEN);
2096		}
2097		break;
2098
2099	case KMF_CERT_EMAIL:
2100		emlst = X509_get1_email(xcert);
2101		for (j = 0; j < sk_num(emlst); j++)
2102			(void) BIO_printf(mem, "%s\n", sk_value(emlst, j));
2103
2104		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2105		X509_email_free(emlst);
2106		break;
2107	case KMF_X509_EXT_ISSUER_ALTNAME:
2108	case KMF_X509_EXT_SUBJ_ALTNAME:
2109	case KMF_X509_EXT_KEY_USAGE:
2110	case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
2111	case KMF_X509_EXT_CERT_POLICIES:
2112	case KMF_X509_EXT_BASIC_CONSTRAINTS:
2113	case KMF_X509_EXT_NAME_CONSTRAINTS:
2114	case KMF_X509_EXT_POLICY_CONSTRAINTS:
2115	case KMF_X509_EXT_EXT_KEY_USAGE:
2116	case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2117	case KMF_X509_EXT_AUTH_KEY_ID:
2118	case KMF_X509_EXT_SUBJ_KEY_ID:
2119	case KMF_X509_EXT_POLICY_MAPPINGS:
2120	case KMF_X509_EXT_CRL_DIST_POINTS:
2121	case KMF_X509_EXT_FRESHEST_CRL:
2122		nid = ext2NID(flag);
2123		if (nid == NID_undef) {
2124			ret = KMF_ERR_EXTENSION_NOT_FOUND;
2125			goto out;
2126		}
2127		ci = xcert->cert_info;
2128
2129		ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1);
2130		if (ext_index == -1) {
2131			SET_ERROR(kmfh, ERR_get_error());
2132
2133			ret = KMF_ERR_EXTENSION_NOT_FOUND;
2134			goto out;
2135		}
2136		ex = X509v3_get_ext(ci->extensions, ext_index);
2137
2138		(void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex));
2139
2140		if (BIO_printf(mem, ": %s\n",
2141		    X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) {
2142			SET_ERROR(kmfh, ERR_get_error());
2143			ret = KMF_ERR_ENCODING;
2144			goto out;
2145		}
2146		if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) {
2147			(void) BIO_printf(mem, "%*s", 4, "");
2148			(void) M_ASN1_OCTET_STRING_print(mem, ex->value);
2149		}
2150		if (BIO_write(mem, "\n", 1) <= 0) {
2151			SET_ERROR(kmfh, ERR_get_error());
2152			ret = KMF_ERR_ENCODING;
2153			goto out;
2154		}
2155		len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2156	}
2157	if (len <= 0) {
2158		SET_ERROR(kmfh, ERR_get_error());
2159		ret = KMF_ERR_ENCODING;
2160	}
2161
2162out:
2163	if (outbuf != NULL) {
2164		free(outbuf);
2165	}
2166
2167	if (xcert != NULL) {
2168		X509_free(xcert);
2169	}
2170
2171	if (mem != NULL) {
2172		(void) BIO_free(mem);
2173	}
2174
2175	return (ret);
2176}
2177
2178KMF_RETURN
2179/*ARGSUSED*/
2180OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
2181    KMF_ATTRIBUTE *attrlist)
2182{
2183	KMF_RETURN rv = KMF_OK;
2184	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
2185	KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
2186	KMF_KEY_HANDLE *key = NULL;
2187	uint32_t numkeys = 1; /* 1 key only */
2188	char *dirpath = NULL;
2189	char *keyfile = NULL;
2190	KMF_ATTRIBUTE new_attrlist[16];
2191	int i = 0;
2192
2193	/*
2194	 * This is really just a FindKey operation, reuse the
2195	 * FindKey function.
2196	 */
2197	kmf_set_attr_at_index(new_attrlist, i,
2198	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2199	i++;
2200
2201	kmf_set_attr_at_index(new_attrlist, i,
2202	    KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t));
2203	i++;
2204
2205	kmf_set_attr_at_index(new_attrlist, i,
2206	    KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass));
2207	i++;
2208
2209	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2210	if (key == NULL) {
2211		return (KMF_ERR_BAD_PARAMETER);
2212	} else {
2213		kmf_set_attr_at_index(new_attrlist, i,
2214		    KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
2215		i++;
2216	}
2217
2218	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2219	if (dirpath != NULL) {
2220		kmf_set_attr_at_index(new_attrlist, i,
2221		    KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
2222		i++;
2223	}
2224
2225	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
2226	if (keyfile == NULL)
2227		return (KMF_ERR_BAD_PARAMETER);
2228	else {
2229		kmf_set_attr_at_index(new_attrlist, i,
2230		    KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
2231		i++;
2232	}
2233
2234	rv = OpenSSL_FindKey(handle, i, new_attrlist);
2235	return (rv);
2236}
2237
2238KMF_RETURN
2239/*ARGSUSED*/
2240OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
2241	KMF_OID *AlgOID, KMF_DATA *ciphertext,
2242	KMF_DATA *output)
2243{
2244	KMF_RETURN		ret = KMF_OK;
2245	RSA *rsa = NULL;
2246	unsigned int in_len = 0, out_len = 0;
2247	unsigned int total_decrypted = 0, modulus_len = 0;
2248	uint8_t *in_data, *out_data;
2249	int i, blocks;
2250
2251	if (key == NULL || AlgOID == NULL ||
2252	    ciphertext == NULL || output == NULL ||
2253	    ciphertext->Data == NULL ||
2254	    output->Data == NULL)
2255		return (KMF_ERR_BAD_PARAMETER);
2256
2257	if (key->keyalg == KMF_RSA) {
2258		rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp);
2259		modulus_len = RSA_size(rsa);
2260	} else {
2261		return (KMF_ERR_BAD_PARAMETER);
2262	}
2263
2264	blocks = ciphertext->Length/modulus_len;
2265	out_data = output->Data;
2266	in_data = ciphertext->Data;
2267	out_len = modulus_len - 11;
2268	in_len = modulus_len;
2269
2270	for (i = 0; i < blocks; i++) {
2271		out_len  = RSA_private_decrypt(in_len,
2272		    in_data, out_data, rsa, RSA_PKCS1_PADDING);
2273
2274		if (out_len == 0) {
2275			ret = KMF_ERR_INTERNAL;
2276			goto cleanup;
2277		}
2278
2279		out_data += out_len;
2280		total_decrypted += out_len;
2281		in_data += in_len;
2282	}
2283
2284	output->Length = total_decrypted;
2285
2286cleanup:
2287	RSA_free(rsa);
2288	if (ret != KMF_OK)
2289		output->Length = 0;
2290
2291	return (ret);
2292
2293}
2294
2295/*
2296 *  This function will create a certid from issuer_cert and user_cert.
2297 *  The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2298 *  certid memory after use.
2299 */
2300static KMF_RETURN
2301create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert,
2302    const KMF_DATA *user_cert, OCSP_CERTID **certid)
2303{
2304	KMF_RETURN ret = KMF_OK;
2305	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2306	X509   *issuer = NULL;
2307	X509   *cert = NULL;
2308	unsigned char *ptmp;
2309
2310	if (issuer_cert == NULL || user_cert == NULL) {
2311		return (KMF_ERR_BAD_PARAMETER);
2312	}
2313
2314	/* convert the DER-encoded issuer cert to an internal X509 */
2315	ptmp = issuer_cert->Data;
2316	issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2317	    issuer_cert->Length);
2318	if (issuer == NULL) {
2319		SET_ERROR(kmfh, ERR_get_error());
2320		ret = KMF_ERR_OCSP_BAD_ISSUER;
2321		goto end;
2322	}
2323
2324	/* convert the DER-encoded user cert to an internal X509 */
2325	ptmp = user_cert->Data;
2326	cert = d2i_X509(NULL, (const uchar_t **)&ptmp,
2327	    user_cert->Length);
2328	if (cert == NULL) {
2329		SET_ERROR(kmfh, ERR_get_error());
2330
2331		ret = KMF_ERR_OCSP_BAD_CERT;
2332		goto end;
2333	}
2334
2335	/* create a CERTID */
2336	*certid = OCSP_cert_to_id(NULL, cert, issuer);
2337	if (*certid == NULL) {
2338		SET_ERROR(kmfh, ERR_get_error());
2339		ret = KMF_ERR_OCSP_CERTID;
2340		goto end;
2341	}
2342
2343end:
2344	if (issuer != NULL) {
2345		X509_free(issuer);
2346	}
2347
2348	if (cert != NULL) {
2349		X509_free(cert);
2350	}
2351
2352	return (ret);
2353}
2354
2355KMF_RETURN
2356OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle,
2357	int numattr, KMF_ATTRIBUTE *attrlist)
2358{
2359	KMF_RETURN ret = KMF_OK;
2360	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2361	OCSP_CERTID *id = NULL;
2362	OCSP_REQUEST *req = NULL;
2363	BIO *derbio = NULL;
2364	char *reqfile;
2365	KMF_DATA *issuer_cert;
2366	KMF_DATA *user_cert;
2367
2368	user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
2369	    attrlist, numattr);
2370	if (user_cert == NULL)
2371		return (KMF_ERR_BAD_PARAMETER);
2372
2373	issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
2374	    attrlist, numattr);
2375	if (issuer_cert == NULL)
2376		return (KMF_ERR_BAD_PARAMETER);
2377
2378	reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR,
2379	    attrlist, numattr);
2380	if (reqfile == NULL)
2381		return (KMF_ERR_BAD_PARAMETER);
2382
2383	ret = create_certid(handle, issuer_cert, user_cert, &id);
2384	if (ret != KMF_OK) {
2385		return (ret);
2386	}
2387
2388	/* Create an OCSP request */
2389	req = OCSP_REQUEST_new();
2390	if (req == NULL) {
2391		SET_ERROR(kmfh, ERR_get_error());
2392		ret = KMF_ERR_OCSP_CREATE_REQUEST;
2393		goto end;
2394	}
2395
2396	if (!OCSP_request_add0_id(req, id)) {
2397		ret = KMF_ERR_OCSP_CREATE_REQUEST;
2398		goto end;
2399	}
2400
2401	/* Write the request to the output file with DER encoding */
2402	derbio = BIO_new_file(reqfile, "wb");
2403	if (!derbio) {
2404		SET_ERROR(kmfh, ERR_get_error());
2405		ret = KMF_ERR_OPEN_FILE;
2406		goto end;
2407	}
2408	if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) {
2409		ret = KMF_ERR_ENCODING;
2410	}
2411
2412end:
2413	/*
2414	 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2415	 * will deallocate certid's space also.
2416	 */
2417	if (req != NULL) {
2418		OCSP_REQUEST_free(req);
2419	}
2420
2421	if (derbio != NULL) {
2422		(void) BIO_free(derbio);
2423	}
2424
2425	return (ret);
2426}
2427
2428/* ocsp_find_signer_sk() is copied from openssl source */
2429static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
2430{
2431	int i;
2432	unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
2433
2434	/* Easy if lookup by name */
2435	if (id->type == V_OCSP_RESPID_NAME)
2436		return (X509_find_by_subject(certs, id->value.byName));
2437
2438	/* Lookup by key hash */
2439
2440	/* If key hash isn't SHA1 length then forget it */
2441	if (id->value.byKey->length != SHA_DIGEST_LENGTH)
2442		return (NULL);
2443
2444	keyhash = id->value.byKey->data;
2445	/* Calculate hash of each key and compare */
2446	for (i = 0; i < sk_X509_num(certs); i++) {
2447		/*LINTED*/
2448		X509 *x = sk_X509_value(certs, i);
2449		/* Use pubkey_digest to get the key ID value */
2450		(void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
2451		if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
2452			return (x);
2453	}
2454	return (NULL);
2455}
2456
2457/* ocsp_find_signer() is copied from openssl source */
2458/*ARGSUSED*/
2459static int
2460ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
2461    X509_STORE *st, unsigned long flags)
2462{
2463	X509 *signer;
2464	OCSP_RESPID *rid = bs->tbsResponseData->responderId;
2465	if ((signer = ocsp_find_signer_sk(certs, rid)))	{
2466		*psigner = signer;
2467		return (2);
2468	}
2469	if (!(flags & OCSP_NOINTERN) &&
2470	    (signer = ocsp_find_signer_sk(bs->certs, rid))) {
2471		*psigner = signer;
2472		return (1);
2473	}
2474	/* Maybe lookup from store if by subject name */
2475
2476	*psigner = NULL;
2477	return (0);
2478}
2479
2480/*
2481 * This function will verify the signature of a basic response, using
2482 * the public key from the OCSP responder certificate.
2483 */
2484static KMF_RETURN
2485check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs,
2486    KMF_DATA *signer_cert, KMF_DATA *issuer_cert)
2487{
2488	KMF_RETURN ret = KMF_OK;
2489	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2490	STACK_OF(X509) *cert_stack = NULL;
2491	X509 *signer = NULL;
2492	X509 *issuer = NULL;
2493	EVP_PKEY *skey = NULL;
2494	unsigned char *ptmp;
2495
2496
2497	if (bs == NULL || issuer_cert == NULL)
2498		return (KMF_ERR_BAD_PARAMETER);
2499
2500	/*
2501	 * Find the certificate that signed the basic response.
2502	 *
2503	 * If signer_cert is not NULL, we will use that as the signer cert.
2504	 * Otherwise, we will check if the issuer cert is actually the signer.
2505	 * If we still do not find a signer, we will look for it from the
2506	 * certificate list came with the response file.
2507	 */
2508	if (signer_cert != NULL) {
2509		ptmp = signer_cert->Data;
2510		signer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2511		    signer_cert->Length);
2512		if (signer == NULL) {
2513			SET_ERROR(kmfh, ERR_get_error());
2514			ret = KMF_ERR_OCSP_BAD_SIGNER;
2515			goto end;
2516		}
2517	} else {
2518		/*
2519		 * Convert the issuer cert into X509 and push it into a
2520		 * stack to be used by ocsp_find_signer().
2521		 */
2522		ptmp = issuer_cert->Data;
2523		issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2524		    issuer_cert->Length);
2525		if (issuer == NULL) {
2526			SET_ERROR(kmfh, ERR_get_error());
2527			ret = KMF_ERR_OCSP_BAD_ISSUER;
2528			goto end;
2529		}
2530
2531		if ((cert_stack = sk_X509_new_null()) == NULL) {
2532			ret = KMF_ERR_INTERNAL;
2533			goto end;
2534		}
2535
2536		if (sk_X509_push(cert_stack, issuer) == NULL) {
2537			ret = KMF_ERR_INTERNAL;
2538			goto end;
2539		}
2540
2541		ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0);
2542		if (!ret) {
2543			/* can not find the signer */
2544			ret = KMF_ERR_OCSP_BAD_SIGNER;
2545			goto end;
2546		}
2547	}
2548
2549	/* Verify the signature of the response */
2550	skey = X509_get_pubkey(signer);
2551	if (skey == NULL) {
2552		ret = KMF_ERR_OCSP_BAD_SIGNER;
2553		goto end;
2554	}
2555
2556	ret = OCSP_BASICRESP_verify(bs, skey, 0);
2557	if (ret == 0) {
2558		ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE;
2559		goto end;
2560	}
2561
2562end:
2563	if (issuer != NULL) {
2564		X509_free(issuer);
2565	}
2566
2567	if (signer != NULL) {
2568		X509_free(signer);
2569	}
2570
2571	if (skey != NULL) {
2572		EVP_PKEY_free(skey);
2573	}
2574
2575	if (cert_stack != NULL) {
2576		sk_X509_free(cert_stack);
2577	}
2578
2579	return (ret);
2580}
2581
2582
2583
2584KMF_RETURN
2585OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,
2586	int numattr, KMF_ATTRIBUTE *attrlist)
2587{
2588	KMF_RETURN ret = KMF_OK;
2589	BIO *derbio = NULL;
2590	OCSP_RESPONSE *resp = NULL;
2591	OCSP_BASICRESP *bs = NULL;
2592	OCSP_CERTID *id = NULL;
2593	OCSP_SINGLERESP *single = NULL;
2594	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
2595	int index, status, reason;
2596	KMF_DATA *issuer_cert;
2597	KMF_DATA *user_cert;
2598	KMF_DATA *signer_cert;
2599	KMF_DATA *response;
2600	int *response_reason, *response_status, *cert_status;
2601	boolean_t ignore_response_sign = B_FALSE;	/* default is FALSE */
2602	uint32_t response_lifetime;
2603
2604	issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
2605	    attrlist, numattr);
2606	if (issuer_cert == NULL)
2607		return (KMF_ERR_BAD_PARAMETER);
2608
2609	user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
2610	    attrlist, numattr);
2611	if (user_cert == NULL)
2612		return (KMF_ERR_BAD_PARAMETER);
2613
2614	response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR,
2615	    attrlist, numattr);
2616	if (response == NULL)
2617		return (KMF_ERR_BAD_PARAMETER);
2618
2619	response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR,
2620	    attrlist, numattr);
2621	if (response_status == NULL)
2622		return (KMF_ERR_BAD_PARAMETER);
2623
2624	response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR,
2625	    attrlist, numattr);
2626	if (response_reason == NULL)
2627		return (KMF_ERR_BAD_PARAMETER);
2628
2629	cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR,
2630	    attrlist, numattr);
2631	if (cert_status == NULL)
2632		return (KMF_ERR_BAD_PARAMETER);
2633
2634	/* Read in the response */
2635	derbio = BIO_new_mem_buf(response->Data, response->Length);
2636	if (!derbio) {
2637		ret = KMF_ERR_MEMORY;
2638		return (ret);
2639	}
2640
2641	resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
2642	if (resp == NULL) {
2643		ret = KMF_ERR_OCSP_MALFORMED_RESPONSE;
2644		goto end;
2645	}
2646
2647	/* Check the response status */
2648	status = OCSP_response_status(resp);
2649	*response_status = status;
2650	if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
2651		ret = KMF_ERR_OCSP_RESPONSE_STATUS;
2652		goto end;
2653	}
2654
2655#ifdef DEBUG
2656	printf("Successfully checked the response file status.\n");
2657#endif /* DEBUG */
2658
2659	/* Extract basic response */
2660	bs = OCSP_response_get1_basic(resp);
2661	if (bs == NULL) {
2662		ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE;
2663		goto end;
2664	}
2665
2666#ifdef DEBUG
2667	printf("Successfully retrieved the basic response.\n");
2668#endif /* DEBUG */
2669
2670	/* Check the basic response signature if required */
2671	ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr,
2672	    (void *)&ignore_response_sign, NULL);
2673	if (ret != KMF_OK)
2674		ret = KMF_OK;
2675
2676	signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR,
2677	    attrlist, numattr);
2678
2679	if (ignore_response_sign == B_FALSE) {
2680		ret = check_response_signature(handle, bs,
2681		    signer_cert, issuer_cert);
2682		if (ret != KMF_OK)
2683			goto end;
2684	}
2685
2686#ifdef DEBUG
2687	printf("Successfully verified the response signature.\n");
2688#endif /* DEBUG */
2689
2690	/* Create a certid for the certificate in question */
2691	ret = create_certid(handle, issuer_cert, user_cert, &id);
2692	if (ret != KMF_OK) {
2693		ret = KMF_ERR_OCSP_CERTID;
2694		goto end;
2695	}
2696
2697#ifdef DEBUG
2698	printf("successfully created a certid for the cert.\n");
2699#endif /* DEBUG */
2700
2701	/* Find the index of the single response for the certid */
2702	index = OCSP_resp_find(bs, id, -1);
2703	if (index < 0) {
2704		/* cound not find this certificate in the response */
2705		ret = KMF_ERR_OCSP_UNKNOWN_CERT;
2706		goto end;
2707	}
2708
2709#ifdef DEBUG
2710	printf("Successfully found the single response index for the cert.\n");
2711#endif /* DEBUG */
2712
2713	/* Retrieve the single response and get the cert status */
2714	single = OCSP_resp_get0(bs, index);
2715	status = OCSP_single_get0_status(single, &reason, &rev, &thisupd,
2716	    &nextupd);
2717	if (status == V_OCSP_CERTSTATUS_GOOD) {
2718		*cert_status = OCSP_GOOD;
2719	} else if (status == V_OCSP_CERTSTATUS_UNKNOWN) {
2720		*cert_status = OCSP_UNKNOWN;
2721	} else { /* revoked */
2722		*cert_status = OCSP_REVOKED;
2723		*response_reason = reason;
2724	}
2725	ret = KMF_OK;
2726
2727	/* resp. time is optional, so we don't care about the return code. */
2728	(void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr,
2729	    (void *)&response_lifetime, NULL);
2730
2731	if (!OCSP_check_validity(thisupd, nextupd, 300,
2732	    response_lifetime)) {
2733		ret = KMF_ERR_OCSP_STATUS_TIME_INVALID;
2734		goto end;
2735	}
2736
2737#ifdef DEBUG
2738	printf("Successfully verify the time.\n");
2739#endif /* DEBUG */
2740
2741end:
2742	if (derbio != NULL)
2743		(void) BIO_free(derbio);
2744
2745	if (resp != NULL)
2746		OCSP_RESPONSE_free(resp);
2747
2748	if (bs != NULL)
2749		OCSP_BASICRESP_free(bs);
2750
2751	if (id != NULL)
2752		OCSP_CERTID_free(id);
2753
2754	return (ret);
2755}
2756
2757static KMF_RETURN
2758fetch_key(KMF_HANDLE_T handle, char *path,
2759	KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key)
2760{
2761	KMF_RETURN rv = KMF_OK;
2762	EVP_PKEY *pkey = NULL;
2763	KMF_RAW_SYM_KEY *rkey = NULL;
2764
2765	if (keyclass == KMF_ASYM_PRI ||
2766	    keyclass == KMF_ASYM_PUB) {
2767		pkey = openssl_load_key(handle, path);
2768		if (pkey == NULL) {
2769			return (KMF_ERR_KEY_NOT_FOUND);
2770		}
2771		if (key != NULL) {
2772			if (pkey->type == EVP_PKEY_RSA)
2773				key->keyalg = KMF_RSA;
2774			else if (pkey->type == EVP_PKEY_DSA)
2775				key->keyalg = KMF_DSA;
2776
2777			key->kstype = KMF_KEYSTORE_OPENSSL;
2778			key->keyclass = keyclass;
2779			key->keyp = (void *)pkey;
2780			key->israw = FALSE;
2781			if (path != NULL &&
2782			    ((key->keylabel = strdup(path)) == NULL)) {
2783				EVP_PKEY_free(pkey);
2784				return (KMF_ERR_MEMORY);
2785			}
2786		} else {
2787			EVP_PKEY_free(pkey);
2788			pkey = NULL;
2789		}
2790	} else if (keyclass == KMF_SYMMETRIC) {
2791		KMF_ENCODE_FORMAT fmt;
2792		/*
2793		 * If the file is a recognized format,
2794		 * then it is NOT a symmetric key.
2795		 */
2796		rv = kmf_get_file_format(path, &fmt);
2797		if (rv == KMF_OK || fmt != 0) {
2798			return (KMF_ERR_KEY_NOT_FOUND);
2799		} else if (rv == KMF_ERR_ENCODING) {
2800			/*
2801			 * If we don't know the encoding,
2802			 * it is probably  a symmetric key.
2803			 */
2804			rv = KMF_OK;
2805		} else if (rv == KMF_ERR_OPEN_FILE) {
2806			return (KMF_ERR_KEY_NOT_FOUND);
2807		}
2808
2809		if (key != NULL) {
2810			KMF_DATA keyvalue;
2811			rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
2812			if (rkey == NULL) {
2813				rv = KMF_ERR_MEMORY;
2814				goto out;
2815			}
2816
2817			(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
2818			rv = kmf_read_input_file(handle, path, &keyvalue);
2819			if (rv != KMF_OK)
2820				goto out;
2821
2822			rkey->keydata.len = keyvalue.Length;
2823			rkey->keydata.val = keyvalue.Data;
2824
2825			key->kstype = KMF_KEYSTORE_OPENSSL;
2826			key->keyclass = keyclass;
2827			key->israw = TRUE;
2828			key->keyp = (void *)rkey;
2829			if (path != NULL &&
2830			    ((key->keylabel = strdup(path)) == NULL)) {
2831				rv = KMF_ERR_MEMORY;
2832			}
2833		}
2834	}
2835out:
2836	if (rv != KMF_OK) {
2837		if (rkey != NULL) {
2838			kmf_free_raw_sym_key(rkey);
2839		}
2840		if (pkey != NULL)
2841			EVP_PKEY_free(pkey);
2842
2843		if (key != NULL) {
2844			key->keyalg = KMF_KEYALG_NONE;
2845			key->keyclass = KMF_KEYCLASS_NONE;
2846			key->keyp = NULL;
2847		}
2848	}
2849
2850	return (rv);
2851}
2852
2853KMF_RETURN
2854OpenSSL_FindKey(KMF_HANDLE_T handle,
2855	int numattr, KMF_ATTRIBUTE *attrlist)
2856{
2857	KMF_RETURN rv = KMF_OK;
2858	char *fullpath = NULL;
2859	uint32_t maxkeys;
2860	KMF_KEY_HANDLE *key;
2861	uint32_t *numkeys;
2862	KMF_KEY_CLASS keyclass;
2863	KMF_RAW_KEY_DATA *rawkey;
2864	char *dirpath;
2865	char *keyfile;
2866
2867	if (handle == NULL)
2868		return (KMF_ERR_BAD_PARAMETER);
2869
2870	numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
2871	if (numkeys == NULL)
2872		return (KMF_ERR_BAD_PARAMETER);
2873
2874	rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
2875	    (void *)&keyclass, NULL);
2876	if (rv != KMF_OK)
2877		return (KMF_ERR_BAD_PARAMETER);
2878
2879	if (keyclass != KMF_ASYM_PUB &&
2880	    keyclass != KMF_ASYM_PRI &&
2881	    keyclass != KMF_SYMMETRIC)
2882		return (KMF_ERR_BAD_KEY_CLASS);
2883
2884	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2885	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
2886
2887	fullpath = get_fullpath(dirpath, keyfile);
2888
2889	if (fullpath == NULL)
2890		return (KMF_ERR_BAD_PARAMETER);
2891
2892	maxkeys = *numkeys;
2893	if (maxkeys == 0)
2894		maxkeys = 0xFFFFFFFF;
2895	*numkeys = 0;
2896
2897	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2898	/* it is okay to have "keys" contains NULL */
2899
2900	/*
2901	 * The caller may want a list of the raw key data as well.
2902	 * Useful for importing keys from a file into other keystores.
2903	 */
2904	rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
2905
2906	if (isdir(fullpath)) {
2907		DIR *dirp;
2908		struct dirent *dp;
2909		int n = 0;
2910
2911		/* open all files in the directory and attempt to read them */
2912		if ((dirp = opendir(fullpath)) == NULL) {
2913			return (KMF_ERR_BAD_PARAMETER);
2914		}
2915		rewinddir(dirp);
2916		while ((dp = readdir(dirp)) != NULL && n < maxkeys) {
2917			if (strcmp(dp->d_name, ".") &&
2918			    strcmp(dp->d_name, "..")) {
2919				char *fname;
2920
2921				fname = get_fullpath(fullpath,
2922				    (char *)&dp->d_name);
2923
2924				rv = fetch_key(handle, fname,
2925				    keyclass, key ? &key[n] : NULL);
2926
2927				if (rv == KMF_OK) {
2928					if (key != NULL && rawkey != NULL)
2929						rv = convertToRawKey(
2930						    key[n].keyp, &rawkey[n]);
2931					n++;
2932				}
2933
2934				if (rv != KMF_OK || key == NULL)
2935					free(fname);
2936			}
2937		}
2938		(void) closedir(dirp);
2939		free(fullpath);
2940		(*numkeys) = n;
2941	} else {
2942		rv = fetch_key(handle, fullpath, keyclass, key);
2943		if (rv == KMF_OK)
2944			(*numkeys) = 1;
2945
2946		if (rv != KMF_OK || key == NULL)
2947			free(fullpath);
2948
2949		if (rv == KMF_OK && key != NULL && rawkey != NULL) {
2950			rv = convertToRawKey(key->keyp, rawkey);
2951		}
2952	}
2953
2954	if (rv == KMF_OK && (*numkeys) == 0)
2955		rv = KMF_ERR_KEY_NOT_FOUND;
2956
2957	return (rv);
2958}
2959
2960#define	HANDLE_PK12_ERROR { \
2961	SET_ERROR(kmfh, ERR_get_error()); \
2962	rv = KMF_ERR_ENCODING; \
2963	goto out; \
2964}
2965
2966static int
2967add_alias_to_bag(PKCS12_SAFEBAG *bag, X509 *xcert)
2968{
2969	if (xcert != NULL && xcert->aux != NULL &&
2970	    xcert->aux->alias != NULL) {
2971		if (PKCS12_add_friendlyname_asc(bag,
2972		    (const char *)xcert->aux->alias->data,
2973		    xcert->aux->alias->length) == 0)
2974			return (0);
2975	}
2976	return (1);
2977}
2978
2979static PKCS7 *
2980add_cert_to_safe(X509 *sslcert, KMF_CREDENTIAL *cred,
2981	uchar_t *keyid, unsigned int keyidlen)
2982{
2983	PKCS12_SAFEBAG *bag = NULL;
2984	PKCS7 *cert_authsafe = NULL;
2985	STACK_OF(PKCS12_SAFEBAG) *bag_stack;
2986
2987	bag_stack = sk_PKCS12_SAFEBAG_new_null();
2988	if (bag_stack == NULL)
2989		return (NULL);
2990
2991	/* Convert cert from X509 struct to PKCS#12 bag */
2992	bag = PKCS12_x5092certbag(sslcert);
2993	if (bag == NULL) {
2994		goto out;
2995	}
2996
2997	/* Add the key id to the certificate bag. */
2998	if (keyidlen > 0 && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
2999		goto out;
3000	}
3001
3002	if (!add_alias_to_bag(bag, sslcert))
3003		goto out;
3004
3005	/* Pile it on the bag_stack. */
3006	if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
3007		goto out;
3008	}
3009	/* Turn bag_stack of certs into encrypted authsafe. */
3010	cert_authsafe = PKCS12_pack_p7encdata(
3011	    NID_pbe_WithSHA1And40BitRC2_CBC,
3012	    cred->cred, cred->credlen, NULL, 0,
3013	    PKCS12_DEFAULT_ITER, bag_stack);
3014
3015out:
3016	if (bag_stack != NULL)
3017		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3018
3019	return (cert_authsafe);
3020}
3021
3022static PKCS7 *
3023add_key_to_safe(EVP_PKEY *pkey, KMF_CREDENTIAL *cred,
3024	uchar_t *keyid,  unsigned int keyidlen,
3025	char *label, int label_len)
3026{
3027	PKCS8_PRIV_KEY_INFO *p8 = NULL;
3028	STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL;
3029	PKCS12_SAFEBAG *bag = NULL;
3030	PKCS7 *key_authsafe = NULL;
3031
3032	p8 = EVP_PKEY2PKCS8(pkey);
3033	if (p8 == NULL) {
3034		return (NULL);
3035	}
3036	/* Put the shrouded key into a PKCS#12 bag. */
3037	bag = PKCS12_MAKE_SHKEYBAG(
3038	    NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
3039	    cred->cred, cred->credlen,
3040	    NULL, 0, PKCS12_DEFAULT_ITER, p8);
3041
3042	/* Clean up the PKCS#8 shrouded key, don't need it now. */
3043	PKCS8_PRIV_KEY_INFO_free(p8);
3044	p8 = NULL;
3045
3046	if (bag == NULL) {
3047		return (NULL);
3048	}
3049	if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
3050		goto out;
3051	if (label != NULL && !PKCS12_add_friendlyname(bag, label, label_len))
3052		goto out;
3053
3054	/* Start a PKCS#12 safebag container for the private key. */
3055	bag_stack = sk_PKCS12_SAFEBAG_new_null();
3056	if (bag_stack == NULL)
3057		goto out;
3058
3059	/* Pile on the private key on the bag_stack. */
3060	if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag))
3061		goto out;
3062
3063	key_authsafe = PKCS12_pack_p7data(bag_stack);
3064
3065out:
3066	if (bag_stack != NULL)
3067		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3068	bag_stack = NULL;
3069	return (key_authsafe);
3070}
3071
3072static EVP_PKEY *
3073ImportRawRSAKey(KMF_RAW_RSA_KEY *key)
3074{
3075	RSA		*rsa = NULL;
3076	EVP_PKEY 	*newkey = NULL;
3077
3078	if ((rsa = RSA_new()) == NULL)
3079		return (NULL);
3080
3081	if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL)
3082		return (NULL);
3083
3084	if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) ==
3085	    NULL)
3086		return (NULL);
3087
3088	if (key->priexp.val != NULL)
3089		if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len,
3090		    rsa->d)) == NULL)
3091			return (NULL);
3092
3093	if (key->prime1.val != NULL)
3094		if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len,
3095		    rsa->p)) == NULL)
3096			return (NULL);
3097
3098	if (key->prime2.val != NULL)
3099		if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len,
3100		    rsa->q)) == NULL)
3101			return (NULL);
3102
3103	if (key->exp1.val != NULL)
3104		if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len,
3105		    rsa->dmp1)) == NULL)
3106			return (NULL);
3107
3108	if (key->exp2.val != NULL)
3109		if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len,
3110		    rsa->dmq1)) == NULL)
3111			return (NULL);
3112
3113	if (key->coef.val != NULL)
3114		if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len,
3115		    rsa->iqmp)) == NULL)
3116			return (NULL);
3117
3118	if ((newkey = EVP_PKEY_new()) == NULL)
3119		return (NULL);
3120
3121	(void) EVP_PKEY_set1_RSA(newkey, rsa);
3122
3123	/* The original key must be freed once here or it leaks memory */
3124	RSA_free(rsa);
3125
3126	return (newkey);
3127}
3128
3129static EVP_PKEY *
3130ImportRawDSAKey(KMF_RAW_DSA_KEY *key)
3131{
3132	DSA		*dsa = NULL;
3133	EVP_PKEY 	*newkey = NULL;
3134
3135	if ((dsa = DSA_new()) == NULL)
3136		return (NULL);
3137
3138	if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len,
3139	    dsa->p)) == NULL)
3140		return (NULL);
3141
3142	if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len,
3143	    dsa->q)) == NULL)
3144		return (NULL);
3145
3146	if ((dsa->g = BN_bin2bn(key->base.val, key->base.len,
3147	    dsa->g)) == NULL)
3148		return (NULL);
3149
3150	if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len,
3151	    dsa->priv_key)) == NULL)
3152		return (NULL);
3153
3154	if (key->pubvalue.val != NULL) {
3155		if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val,
3156		    key->pubvalue.len, dsa->pub_key)) == NULL)
3157			return (NULL);
3158	}
3159
3160	if ((newkey = EVP_PKEY_new()) == NULL)
3161		return (NULL);
3162
3163	(void) EVP_PKEY_set1_DSA(newkey, dsa);
3164
3165	/* The original key must be freed once here or it leaks memory */
3166	DSA_free(dsa);
3167	return (newkey);
3168}
3169
3170static EVP_PKEY *
3171raw_key_to_pkey(KMF_KEY_HANDLE *key)
3172{
3173	EVP_PKEY *pkey = NULL;
3174	KMF_RAW_KEY_DATA *rawkey;
3175	ASN1_TYPE *attr = NULL;
3176	KMF_RETURN ret;
3177
3178	if (key == NULL || !key->israw)
3179		return (NULL);
3180
3181	rawkey = (KMF_RAW_KEY_DATA *)key->keyp;
3182	if (rawkey->keytype == KMF_RSA) {
3183		pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
3184	} else if (rawkey->keytype == KMF_DSA) {
3185		pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
3186	} else {
3187		/* wrong kind of key */
3188		return (NULL);
3189	}
3190
3191	if (rawkey->label != NULL) {
3192		if ((attr = ASN1_TYPE_new()) == NULL) {
3193			EVP_PKEY_free(pkey);
3194			return (NULL);
3195		}
3196		attr->value.bmpstring = ASN1_STRING_type_new(V_ASN1_BMPSTRING);
3197		(void) ASN1_STRING_set(attr->value.bmpstring, rawkey->label,
3198		    strlen(rawkey->label));
3199		attr->type = V_ASN1_BMPSTRING;
3200		attr->value.ptr = (char *)attr->value.bmpstring;
3201		ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
3202		if (ret != KMF_OK) {
3203			EVP_PKEY_free(pkey);
3204			ASN1_TYPE_free(attr);
3205			return (NULL);
3206		}
3207	}
3208	if (rawkey->id.Data != NULL) {
3209		if ((attr = ASN1_TYPE_new()) == NULL) {
3210			EVP_PKEY_free(pkey);
3211			return (NULL);
3212		}
3213		attr->value.octet_string =
3214		    ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
3215		attr->type = V_ASN1_OCTET_STRING;
3216		(void) ASN1_STRING_set(attr->value.octet_string,
3217		    rawkey->id.Data, rawkey->id.Length);
3218		attr->value.ptr = (char *)attr->value.octet_string;
3219		ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
3220		if (ret != KMF_OK) {
3221			EVP_PKEY_free(pkey);
3222			ASN1_TYPE_free(attr);
3223			return (NULL);
3224		}
3225	}
3226	return (pkey);
3227}
3228
3229/*
3230 * Search a list of private keys to find one that goes with the certificate.
3231 */
3232static EVP_PKEY *
3233find_matching_key(X509 *xcert, int numkeys, KMF_KEY_HANDLE *keylist)
3234{
3235	int i;
3236	EVP_PKEY *pkey = NULL;
3237
3238	if (numkeys == 0 || keylist == NULL || xcert == NULL)
3239		return (NULL);
3240	for (i = 0; i < numkeys; i++) {
3241		if (keylist[i].israw)
3242			pkey = raw_key_to_pkey(&keylist[i]);
3243		else
3244			pkey = (EVP_PKEY *)keylist[i].keyp;
3245		if (pkey != NULL) {
3246			if (X509_check_private_key(xcert, pkey)) {
3247				return (pkey);
3248			} else {
3249				EVP_PKEY_free(pkey);
3250				pkey = NULL;
3251			}
3252		}
3253	}
3254	return (pkey);
3255}
3256
3257static KMF_RETURN
3258local_export_pk12(KMF_HANDLE_T handle,
3259	KMF_CREDENTIAL *cred,
3260	int numcerts, KMF_X509_DER_CERT *certlist,
3261	int numkeys, KMF_KEY_HANDLE *keylist,
3262	char *filename)
3263{
3264	KMF_RETURN rv = KMF_OK;
3265	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3266	BIO *bio = NULL;
3267	PKCS7 *cert_authsafe = NULL;
3268	PKCS7 *key_authsafe = NULL;
3269	STACK_OF(PKCS7) *authsafe_stack = NULL;
3270	PKCS12 *p12_elem = NULL;
3271	int i;
3272
3273	if (numcerts == 0 && numkeys == 0)
3274		return (KMF_ERR_BAD_PARAMETER);
3275
3276	/*
3277	 * Open the output file.
3278	 */
3279	if ((bio = BIO_new_file(filename, "wb")) == NULL) {
3280		SET_ERROR(kmfh, ERR_get_error());
3281		rv = KMF_ERR_OPEN_FILE;
3282		goto cleanup;
3283	}
3284
3285	/* Start a PKCS#7 stack. */
3286	authsafe_stack = sk_PKCS7_new_null();
3287	if (authsafe_stack == NULL) {
3288		rv = KMF_ERR_MEMORY;
3289		goto cleanup;
3290	}
3291	if (numcerts > 0) {
3292		for (i = 0; rv == KMF_OK && i < numcerts; i++) {
3293			const uchar_t *p = certlist[i].certificate.Data;
3294			long len = certlist[i].certificate.Length;
3295			X509 *xcert = NULL;
3296			EVP_PKEY *pkey = NULL;
3297			unsigned char keyid[EVP_MAX_MD_SIZE];
3298			unsigned int keyidlen = 0;
3299
3300			xcert = d2i_X509(NULL, &p, len);
3301			if (xcert == NULL) {
3302				SET_ERROR(kmfh, ERR_get_error());
3303				rv = KMF_ERR_ENCODING;
3304			}
3305			if (certlist[i].kmf_private.label != NULL) {
3306				/* Set alias attribute */
3307				(void) X509_alias_set1(xcert,
3308				    (uchar_t *)certlist[i].kmf_private.label,
3309				    strlen(certlist[i].kmf_private.label));
3310			}
3311			/* Check if there is a key corresponding to this cert */
3312			pkey = find_matching_key(xcert, numkeys, keylist);
3313
3314			/*
3315			 * If key is found, get fingerprint and create a
3316			 * safebag.
3317			 */
3318			if (pkey != NULL) {
3319				(void) X509_digest(xcert, EVP_sha1(),
3320				    keyid, &keyidlen);
3321				key_authsafe = add_key_to_safe(pkey, cred,
3322				    keyid, keyidlen,
3323				    certlist[i].kmf_private.label,
3324				    (certlist[i].kmf_private.label ?
3325				    strlen(certlist[i].kmf_private.label) : 0));
3326
3327				if (key_authsafe == NULL) {
3328					X509_free(xcert);
3329					EVP_PKEY_free(pkey);
3330					goto cleanup;
3331				}
3332				/* Put the key safe into the Auth Safe */
3333				if (!sk_PKCS7_push(authsafe_stack,
3334				    key_authsafe)) {
3335					X509_free(xcert);
3336					EVP_PKEY_free(pkey);
3337					goto cleanup;
3338				}
3339			}
3340
3341			/* create a certificate safebag */
3342			cert_authsafe = add_cert_to_safe(xcert, cred, keyid,
3343			    keyidlen);
3344			if (cert_authsafe == NULL) {
3345				X509_free(xcert);
3346				EVP_PKEY_free(pkey);
3347				goto cleanup;
3348			}
3349			if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) {
3350				X509_free(xcert);
3351				EVP_PKEY_free(pkey);
3352				goto cleanup;
3353			}
3354
3355			X509_free(xcert);
3356			if (pkey)
3357				EVP_PKEY_free(pkey);
3358		}
3359	} else if (numcerts == 0 && numkeys > 0) {
3360		/*
3361		 * If only adding keys to the file.
3362		 */
3363		for (i = 0; i < numkeys; i++) {
3364			EVP_PKEY *pkey = NULL;
3365
3366			if (keylist[i].israw)
3367				pkey = raw_key_to_pkey(&keylist[i]);
3368			else
3369				pkey = (EVP_PKEY *)keylist[i].keyp;
3370
3371			if (pkey == NULL)
3372				continue;
3373
3374			key_authsafe = add_key_to_safe(pkey, cred,
3375			    NULL, 0, NULL, 0);
3376
3377			if (key_authsafe == NULL) {
3378				EVP_PKEY_free(pkey);
3379				goto cleanup;
3380			}
3381			if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) {
3382				EVP_PKEY_free(pkey);
3383				goto cleanup;
3384			}
3385		}
3386	}
3387	p12_elem = PKCS12_init(NID_pkcs7_data);
3388	if (p12_elem == NULL) {
3389		goto cleanup;
3390	}
3391
3392	/* Put the PKCS#7 stack into the PKCS#12 element. */
3393	if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) {
3394		goto cleanup;
3395	}
3396
3397	/* Set the integrity MAC on the PKCS#12 element. */
3398	if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen,
3399	    NULL, 0, PKCS12_DEFAULT_ITER, NULL)) {
3400		goto cleanup;
3401	}
3402
3403	/* Write the PKCS#12 element to the export file. */
3404	if (!i2d_PKCS12_bio(bio, p12_elem)) {
3405		goto cleanup;
3406	}
3407	PKCS12_free(p12_elem);
3408
3409cleanup:
3410	/* Clear away the PKCS#7 stack, we're done with it. */
3411	if (authsafe_stack)
3412		sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
3413
3414	if (bio != NULL)
3415		(void) BIO_free_all(bio);
3416
3417	return (rv);
3418}
3419
3420KMF_RETURN
3421openssl_build_pk12(KMF_HANDLE_T handle, int numcerts,
3422    KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist,
3423    KMF_CREDENTIAL *p12cred, char *filename)
3424{
3425	KMF_RETURN rv;
3426
3427	if (certlist == NULL && keylist == NULL)
3428		return (KMF_ERR_BAD_PARAMETER);
3429
3430	rv = local_export_pk12(handle, p12cred, numcerts, certlist,
3431	    numkeys, keylist, filename);
3432
3433	return (rv);
3434}
3435
3436KMF_RETURN
3437OpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
3438{
3439	KMF_RETURN rv;
3440	KMF_HANDLE *kmfh = (KMF_HANDLE  *)handle;
3441	char *fullpath = NULL;
3442	char *dirpath = NULL;
3443	char *certfile = NULL;
3444	char *keyfile = NULL;
3445	char *filename = NULL;
3446	KMF_CREDENTIAL *p12cred = NULL;
3447	KMF_X509_DER_CERT certdata;
3448	KMF_KEY_HANDLE key;
3449	int gotkey = 0;
3450	int gotcert = 0;
3451
3452	if (handle == NULL)
3453		return (KMF_ERR_BAD_PARAMETER);
3454
3455	/*
3456	 *  First, find the certificate.
3457	 */
3458	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
3459	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
3460	if (certfile != NULL) {
3461		fullpath = get_fullpath(dirpath, certfile);
3462		if (fullpath == NULL)
3463			return (KMF_ERR_BAD_PARAMETER);
3464
3465		if (isdir(fullpath)) {
3466			free(fullpath);
3467			return (KMF_ERR_AMBIGUOUS_PATHNAME);
3468		}
3469
3470		(void) memset(&certdata, 0, sizeof (certdata));
3471		rv = kmf_load_cert(kmfh, NULL, NULL, NULL, NULL,
3472		    fullpath, &certdata.certificate);
3473		if (rv != KMF_OK)
3474			goto end;
3475
3476		gotcert++;
3477		certdata.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
3478		free(fullpath);
3479	}
3480
3481	/*
3482	 * Now find the private key.
3483	 */
3484	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
3485	if (keyfile != NULL) {
3486		fullpath = get_fullpath(dirpath, keyfile);
3487		if (fullpath == NULL)
3488			return (KMF_ERR_BAD_PARAMETER);
3489
3490		if (isdir(fullpath)) {
3491			free(fullpath);
3492			return (KMF_ERR_AMBIGUOUS_PATHNAME);
3493		}
3494
3495		(void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
3496		rv = fetch_key(handle, fullpath, KMF_ASYM_PRI, &key);
3497		if (rv != KMF_OK)
3498			goto end;
3499		gotkey++;
3500	}
3501
3502	/*
3503	 * Open the output file.
3504	 */
3505	filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
3506	    numattr);
3507	if (filename == NULL) {
3508		rv = KMF_ERR_BAD_PARAMETER;
3509		goto end;
3510	}
3511
3512	/* Stick the key and the cert into a PKCS#12 file */
3513	p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
3514	if (p12cred == NULL) {
3515		rv = KMF_ERR_BAD_PARAMETER;
3516		goto end;
3517	}
3518
3519	rv = local_export_pk12(handle, p12cred, 1, &certdata,
3520	    1, &key, filename);
3521
3522end:
3523	if (fullpath)
3524		free(fullpath);
3525
3526	if (gotcert)
3527		kmf_free_kmf_cert(handle, &certdata);
3528	if (gotkey)
3529		kmf_free_kmf_key(handle, &key);
3530	return (rv);
3531}
3532
3533/*
3534 * Helper function to extract keys and certificates from
3535 * a single PEM file.  Typically the file should contain a
3536 * private key and an associated public key wrapped in an x509 cert.
3537 * However, the file may be just a list of X509 certs with no keys.
3538 */
3539static KMF_RETURN
3540extract_pem(KMF_HANDLE *kmfh,
3541	char *issuer, char *subject, KMF_BIGINT *serial,
3542	char *filename, CK_UTF8CHAR *pin,
3543	CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs,
3544	int *numcerts)
3545/* ARGSUSED */
3546{
3547	KMF_RETURN rv = KMF_OK;
3548	FILE *fp;
3549	STACK_OF(X509_INFO) *x509_info_stack = NULL;
3550	int i, ncerts = 0, matchcerts = 0;
3551	EVP_PKEY *pkey = NULL;
3552	X509_INFO *info;
3553	X509 *x;
3554	X509_INFO **cert_infos = NULL;
3555	KMF_DATA *certlist = NULL;
3556
3557	if (priv_key)
3558		*priv_key = NULL;
3559	if (certs)
3560		*certs = NULL;
3561	fp = fopen(filename, "r");
3562	if (fp == NULL)
3563		return (KMF_ERR_OPEN_FILE);
3564
3565	x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin);
3566	if (x509_info_stack == NULL) {
3567		(void) fclose(fp);
3568		return (KMF_ERR_ENCODING);
3569	}
3570	cert_infos = (X509_INFO **)malloc(sk_X509_INFO_num(x509_info_stack) *
3571	    sizeof (X509_INFO *));
3572	if (cert_infos == NULL) {
3573		(void) fclose(fp);
3574		rv = KMF_ERR_MEMORY;
3575		goto err;
3576	}
3577
3578	for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
3579		/* LINTED */
3580		cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i);
3581		ncerts++;
3582	}
3583
3584	if (ncerts == 0) {
3585		(void) fclose(fp);
3586		rv = KMF_ERR_CERT_NOT_FOUND;
3587		goto err;
3588	}
3589
3590	if (priv_key != NULL) {
3591		rewind(fp);
3592		pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin);
3593	}
3594	(void) fclose(fp);
3595
3596	x = cert_infos[ncerts - 1]->x509;
3597	/*
3598	 * Make sure the private key matchs the last cert in the file.
3599	 */
3600	if (pkey != NULL && !X509_check_private_key(x, pkey)) {
3601		EVP_PKEY_free(pkey);
3602		rv = KMF_ERR_KEY_MISMATCH;
3603		goto err;
3604	}
3605
3606	certlist = (KMF_DATA *)malloc(ncerts * sizeof (KMF_DATA));
3607	if (certlist == NULL) {
3608		if (pkey != NULL)
3609			EVP_PKEY_free(pkey);
3610		rv = KMF_ERR_MEMORY;
3611		goto err;
3612	}
3613
3614	/*
3615	 * Convert all of the certs to DER format.
3616	 */
3617	matchcerts = 0;
3618	for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) {
3619		boolean_t match = FALSE;
3620		info =  cert_infos[ncerts - 1 - i];
3621
3622		rv = check_cert(info->x509, issuer, subject, serial, &match);
3623		if (rv != KMF_OK || match != TRUE) {
3624			rv = KMF_OK;
3625			continue;
3626		}
3627
3628		rv = ssl_cert2KMFDATA(kmfh, info->x509,
3629			&certlist[matchcerts++]);
3630
3631		if (rv != KMF_OK) {
3632			free(certlist);
3633			certlist = NULL;
3634			ncerts = matchcerts = 0;
3635		}
3636	}
3637
3638	if (numcerts != NULL)
3639		*numcerts = matchcerts;
3640	if (certs != NULL)
3641		*certs = certlist;
3642
3643	if (priv_key == NULL && pkey != NULL)
3644		EVP_PKEY_free(pkey);
3645	else if (priv_key != NULL && pkey != NULL)
3646		*priv_key = pkey;
3647
3648err:
3649	/* Cleanup the stack of X509 info records */
3650	for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
3651		/*LINTED*/
3652		info = (X509_INFO *)sk_X509_INFO_value(x509_info_stack, i);
3653		X509_INFO_free(info);
3654	}
3655	if (x509_info_stack)
3656		sk_X509_INFO_free(x509_info_stack);
3657
3658	if (cert_infos != NULL)
3659		free(cert_infos);
3660
3661	return (rv);
3662}
3663
3664static KMF_RETURN
3665openssl_parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *pin,
3666	STACK_OF(EVP_PKEY) *keys, STACK_OF(X509) *certs)
3667{
3668	KMF_RETURN ret;
3669	int i;
3670
3671	for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
3672		/*LINTED*/
3673		PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value(bags, i);
3674		ret = openssl_parse_bag(bag, pin, (pin ? strlen(pin) : 0),
3675		    keys, certs);
3676
3677		if (ret != KMF_OK)
3678			return (ret);
3679	}
3680
3681	return (ret);
3682}
3683
3684static KMF_RETURN
3685set_pkey_attrib(EVP_PKEY *pkey, ASN1_TYPE *attrib, int nid)
3686{
3687	X509_ATTRIBUTE *attr = NULL;
3688
3689	if (pkey == NULL || attrib == NULL)
3690		return (KMF_ERR_BAD_PARAMETER);
3691
3692	if (pkey->attributes == NULL) {
3693		pkey->attributes = sk_X509_ATTRIBUTE_new_null();
3694		if (pkey->attributes == NULL)
3695			return (KMF_ERR_MEMORY);
3696	}
3697	attr = X509_ATTRIBUTE_create(nid, attrib->type, attrib->value.ptr);
3698	if (attr != NULL) {
3699		int i;
3700		X509_ATTRIBUTE *a;
3701		for (i = 0;
3702		    i < sk_X509_ATTRIBUTE_num(pkey->attributes); i++) {
3703			/*LINTED*/
3704			a = sk_X509_ATTRIBUTE_value(pkey->attributes, i);
3705			if (OBJ_obj2nid(a->object) == nid) {
3706				X509_ATTRIBUTE_free(a);
3707				/*LINTED*/
3708				sk_X509_ATTRIBUTE_set(pkey->attributes,
3709				    i, attr);
3710				return (KMF_OK);
3711			}
3712		}
3713		if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == NULL) {
3714			X509_ATTRIBUTE_free(attr);
3715			return (KMF_ERR_MEMORY);
3716		}
3717	} else {
3718		return (KMF_ERR_MEMORY);
3719	}
3720
3721	return (KMF_OK);
3722}
3723
3724static KMF_RETURN
3725openssl_parse_bag(PKCS12_SAFEBAG *bag, char *pass, int passlen,
3726	STACK_OF(EVP_PKEY) *keylist, STACK_OF(X509) *certlist)
3727{
3728	KMF_RETURN ret = KMF_OK;
3729	PKCS8_PRIV_KEY_INFO *p8 = NULL;
3730	EVP_PKEY *pkey = NULL;
3731	X509 *xcert = NULL;
3732	ASN1_TYPE *keyid = NULL;
3733	ASN1_TYPE *fname = NULL;
3734	uchar_t *data = NULL;
3735
3736	keyid = PKCS12_get_attr(bag, NID_localKeyID);
3737	fname = PKCS12_get_attr(bag, NID_friendlyName);
3738
3739	switch (M_PKCS12_bag_type(bag)) {
3740		case NID_keyBag:
3741			if (keylist == NULL)
3742				goto end;
3743			pkey = EVP_PKCS82PKEY(bag->value.keybag);
3744			if (pkey == NULL)
3745				ret = KMF_ERR_PKCS12_FORMAT;
3746
3747			break;
3748		case NID_pkcs8ShroudedKeyBag:
3749			if (keylist == NULL)
3750				goto end;
3751			p8 = M_PKCS12_decrypt_skey(bag, pass, passlen);
3752			if (p8 == NULL)
3753				return (KMF_ERR_AUTH_FAILED);
3754			pkey = EVP_PKCS82PKEY(p8);
3755			PKCS8_PRIV_KEY_INFO_free(p8);
3756			if (pkey == NULL)
3757				ret = KMF_ERR_PKCS12_FORMAT;
3758			break;
3759		case NID_certBag:
3760			if (certlist == NULL)
3761				goto end;
3762			if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
3763				return (KMF_ERR_PKCS12_FORMAT);
3764			xcert = M_PKCS12_certbag2x509(bag);
3765			if (xcert == NULL) {
3766				ret = KMF_ERR_PKCS12_FORMAT;
3767				goto end;
3768			}
3769			if (keyid != NULL) {
3770				if (X509_keyid_set1(xcert,
3771				    keyid->value.octet_string->data,
3772				    keyid->value.octet_string->length) == 0) {
3773					ret = KMF_ERR_PKCS12_FORMAT;
3774					goto end;
3775				}
3776			}
3777			if (fname != NULL) {
3778				int len, r;
3779				len = ASN1_STRING_to_UTF8(&data,
3780				    fname->value.asn1_string);
3781				if (len > 0 && data != NULL) {
3782					r = X509_alias_set1(xcert, data, len);
3783					if (r == NULL) {
3784						ret = KMF_ERR_PKCS12_FORMAT;
3785						goto end;
3786					}
3787				} else {
3788					ret = KMF_ERR_PKCS12_FORMAT;
3789					goto end;
3790				}
3791			}
3792			if (sk_X509_push(certlist, xcert) == 0)
3793				ret = KMF_ERR_MEMORY;
3794			else
3795				xcert = NULL;
3796			break;
3797		case NID_safeContentsBag:
3798			return (openssl_parse_bags(bag->value.safes, pass,
3799			    keylist, certlist));
3800		default:
3801			ret = KMF_ERR_PKCS12_FORMAT;
3802			break;
3803	}
3804
3805	/*
3806	 * Set the ID and/or FriendlyName attributes on the key.
3807	 * If converting to PKCS11 objects, these can translate to CKA_ID
3808	 * and CKA_LABEL values.
3809	 */
3810	if (pkey != NULL && ret == KMF_OK) {
3811		ASN1_TYPE *attr = NULL;
3812		if (keyid != NULL && keyid->type == V_ASN1_OCTET_STRING) {
3813			if ((attr = ASN1_TYPE_new()) == NULL)
3814				return (KMF_ERR_MEMORY);
3815			attr->value.octet_string =
3816			    ASN1_STRING_dup(keyid->value.octet_string);
3817			attr->type = V_ASN1_OCTET_STRING;
3818			attr->value.ptr = (char *)attr->value.octet_string;
3819			ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
3820			OPENSSL_free(attr);
3821		}
3822
3823		if (ret == KMF_OK && fname != NULL &&
3824		    fname->type == V_ASN1_BMPSTRING) {
3825			if ((attr = ASN1_TYPE_new()) == NULL)
3826				return (KMF_ERR_MEMORY);
3827			attr->value.bmpstring =
3828			    ASN1_STRING_dup(fname->value.bmpstring);
3829			attr->type = V_ASN1_BMPSTRING;
3830			attr->value.ptr = (char *)attr->value.bmpstring;
3831			ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
3832			OPENSSL_free(attr);
3833		}
3834
3835		if (ret == KMF_OK && keylist != NULL &&
3836		    sk_EVP_PKEY_push(keylist, pkey) == 0)
3837			ret = KMF_ERR_MEMORY;
3838	}
3839	if (ret == KMF_OK && keylist != NULL)
3840		pkey = NULL;
3841end:
3842	if (pkey != NULL)
3843		EVP_PKEY_free(pkey);
3844	if (xcert != NULL)
3845		X509_free(xcert);
3846	if (data != NULL)
3847		OPENSSL_free(data);
3848
3849	return (ret);
3850}
3851
3852static KMF_RETURN
3853openssl_pkcs12_parse(PKCS12 *p12, char *pin,
3854	STACK_OF(EVP_PKEY) *keys,
3855	STACK_OF(X509) *certs,
3856	STACK_OF(X509) *ca)
3857/*ARGSUSED*/
3858{
3859	KMF_RETURN ret = KMF_OK;
3860	STACK_OF(PKCS7) *asafes = NULL;
3861	STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
3862	int i, bagnid;
3863	PKCS7 *p7;
3864
3865	if (p12 == NULL || (keys == NULL && certs == NULL))
3866		return (KMF_ERR_BAD_PARAMETER);
3867
3868	if (pin == NULL || *pin == NULL) {
3869		if (PKCS12_verify_mac(p12, NULL, 0)) {
3870			pin = NULL;
3871		} else if (PKCS12_verify_mac(p12, "", 0)) {
3872			pin = "";
3873		} else {
3874			return (KMF_ERR_AUTH_FAILED);
3875		}
3876	} else if (!PKCS12_verify_mac(p12, pin, -1)) {
3877		return (KMF_ERR_AUTH_FAILED);
3878	}
3879
3880	if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
3881		return (KMF_ERR_PKCS12_FORMAT);
3882
3883	for (i = 0; ret == KMF_OK && i < sk_PKCS7_num(asafes); i++) {
3884		bags = NULL;
3885		/*LINTED*/
3886		p7 = sk_PKCS7_value(asafes, i);
3887		bagnid = OBJ_obj2nid(p7->type);
3888
3889		if (bagnid == NID_pkcs7_data) {
3890			bags = PKCS12_unpack_p7data(p7);
3891		} else if (bagnid == NID_pkcs7_encrypted) {
3892			bags = PKCS12_unpack_p7encdata(p7, pin,
3893			    (pin ? strlen(pin) : 0));
3894		} else {
3895			continue;
3896		}
3897		if (bags == NULL) {
3898			ret = KMF_ERR_PKCS12_FORMAT;
3899			goto out;
3900		}
3901
3902		if (openssl_parse_bags(bags, pin, keys, certs) != KMF_OK)
3903			ret = KMF_ERR_PKCS12_FORMAT;
3904
3905		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
3906	}
3907out:
3908	if (asafes != NULL)
3909		sk_PKCS7_pop_free(asafes, PKCS7_free);
3910
3911	return (ret);
3912}
3913
3914/*
3915 * Helper function to decrypt and parse PKCS#12 import file.
3916 */
3917static KMF_RETURN
3918extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
3919	STACK_OF(EVP_PKEY) **priv_key, STACK_OF(X509) **certs,
3920	STACK_OF(X509) **ca)
3921/* ARGSUSED */
3922{
3923	PKCS12			*pk12, *pk12_tmp;
3924	STACK_OF(EVP_PKEY)	*pkeylist = NULL;
3925	STACK_OF(X509)		*xcertlist = NULL;
3926	STACK_OF(X509)		*cacertlist = NULL;
3927
3928	if ((pk12 = PKCS12_new()) == NULL) {
3929		return (KMF_ERR_MEMORY);
3930	}
3931
3932	if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) {
3933		/* This is ok; it seems to mean there is no more to read. */
3934		if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 &&
3935		    ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG)
3936			goto end_extract_pkcs12;
3937
3938		PKCS12_free(pk12);
3939		return (KMF_ERR_PKCS12_FORMAT);
3940	}
3941	pk12 = pk12_tmp;
3942
3943	xcertlist = sk_X509_new_null();
3944	if (xcertlist == NULL) {
3945		PKCS12_free(pk12);
3946		return (KMF_ERR_MEMORY);
3947	}
3948	pkeylist = sk_EVP_PKEY_new_null();
3949	if (pkeylist == NULL) {
3950		sk_X509_pop_free(xcertlist, X509_free);
3951		PKCS12_free(pk12);
3952		return (KMF_ERR_MEMORY);
3953	}
3954
3955	if (openssl_pkcs12_parse(pk12, (char *)pin, pkeylist, xcertlist,
3956	    cacertlist) != KMF_OK) {
3957		sk_X509_pop_free(xcertlist, X509_free);
3958		sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
3959		PKCS12_free(pk12);
3960		return (KMF_ERR_PKCS12_FORMAT);
3961	}
3962
3963	if (priv_key && pkeylist)
3964		*priv_key = pkeylist;
3965	else if (pkeylist)
3966		sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
3967	if (certs && xcertlist)
3968		*certs = xcertlist;
3969	else if (xcertlist)
3970		sk_X509_pop_free(xcertlist, X509_free);
3971	if (ca && cacertlist)
3972		*ca = cacertlist;
3973	else if (cacertlist)
3974		sk_X509_pop_free(cacertlist, X509_free);
3975
3976end_extract_pkcs12:
3977
3978	PKCS12_free(pk12);
3979	return (KMF_OK);
3980}
3981
3982static KMF_RETURN
3983sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to)
3984{
3985	KMF_RETURN rv = KMF_OK;
3986	uint32_t sz;
3987
3988	sz = BN_num_bytes(from);
3989	to->val = (uchar_t *)malloc(sz);
3990	if (to->val == NULL)
3991		return (KMF_ERR_MEMORY);
3992
3993	if ((to->len = BN_bn2bin(from, to->val)) != sz) {
3994		free(to->val);
3995		to->val = NULL;
3996		to->len = 0;
3997		rv = KMF_ERR_MEMORY;
3998	}
3999
4000	return (rv);
4001}
4002
4003static KMF_RETURN
4004exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key)
4005{
4006	KMF_RETURN rv;
4007	KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa;
4008
4009	(void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY));
4010	if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK)
4011		goto cleanup;
4012
4013	if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK)
4014		goto cleanup;
4015
4016	if (rsa->d != NULL)
4017		if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK)
4018			goto cleanup;
4019
4020	if (rsa->p != NULL)
4021		if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK)
4022			goto cleanup;
4023
4024	if (rsa->q != NULL)
4025		if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK)
4026			goto cleanup;
4027
4028	if (rsa->dmp1 != NULL)
4029		if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK)
4030			goto cleanup;
4031
4032	if (rsa->dmq1 != NULL)
4033		if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK)
4034			goto cleanup;
4035
4036	if (rsa->iqmp != NULL)
4037		if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK)
4038			goto cleanup;
4039cleanup:
4040	if (rv != KMF_OK)
4041		kmf_free_raw_key(key);
4042	else
4043		key->keytype = KMF_RSA;
4044
4045	/*
4046	 * Free the reference to this key, SSL will not actually free
4047	 * the memory until the refcount == 0, so this is safe.
4048	 */
4049	RSA_free(rsa);
4050
4051	return (rv);
4052}
4053
4054static KMF_RETURN
4055exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key)
4056{
4057	KMF_RETURN rv;
4058	KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa;
4059
4060	(void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY));
4061	if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK)
4062		goto cleanup;
4063
4064	if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK)
4065		goto cleanup;
4066
4067	if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK)
4068		goto cleanup;
4069
4070	if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK)
4071		goto cleanup;
4072
4073cleanup:
4074	if (rv != KMF_OK)
4075		kmf_free_raw_key(key);
4076	else
4077		key->keytype = KMF_DSA;
4078
4079	/*
4080	 * Free the reference to this key, SSL will not actually free
4081	 * the memory until the refcount == 0, so this is safe.
4082	 */
4083	DSA_free(dsa);
4084
4085	return (rv);
4086}
4087
4088static KMF_RETURN
4089add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert,
4090	KMF_X509_DER_CERT **certlist, int *ncerts)
4091{
4092	KMF_RETURN rv = KMF_OK;
4093	KMF_X509_DER_CERT *list = (*certlist);
4094	KMF_X509_DER_CERT cert;
4095	int n = (*ncerts);
4096
4097	if (list == NULL) {
4098		list = (KMF_X509_DER_CERT *)malloc(sizeof (KMF_X509_DER_CERT));
4099	} else {
4100		list = (KMF_X509_DER_CERT *)realloc(list,
4101		    sizeof (KMF_X509_DER_CERT) * (n + 1));
4102	}
4103
4104	if (list == NULL)
4105		return (KMF_ERR_MEMORY);
4106
4107	(void) memset(&cert, 0, sizeof (cert));
4108	rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert.certificate);
4109	if (rv == KMF_OK) {
4110		int len = 0;
4111		/* Get the alias name for the cert if there is one */
4112		char *a = (char *)X509_alias_get0(sslcert, &len);
4113		if (a != NULL)
4114			cert.kmf_private.label = strdup(a);
4115		cert.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
4116
4117		list[n] = cert;
4118		(*ncerts) = n + 1;
4119
4120		*certlist = list;
4121	} else {
4122		free(list);
4123	}
4124
4125	return (rv);
4126}
4127
4128static KMF_RETURN
4129add_key_to_list(KMF_RAW_KEY_DATA **keylist,
4130	KMF_RAW_KEY_DATA *newkey, int *nkeys)
4131{
4132	KMF_RAW_KEY_DATA *list = (*keylist);
4133	int n = (*nkeys);
4134
4135	if (list == NULL) {
4136		list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA));
4137	} else {
4138		list = (KMF_RAW_KEY_DATA *)realloc(list,
4139		    sizeof (KMF_RAW_KEY_DATA) * (n + 1));
4140	}
4141
4142	if (list == NULL)
4143		return (KMF_ERR_MEMORY);
4144
4145	list[n] = *newkey;
4146	(*nkeys) = n + 1;
4147
4148	*keylist = list;
4149
4150	return (KMF_OK);
4151}
4152
4153static X509_ATTRIBUTE *
4154find_attr(STACK_OF(X509_ATTRIBUTE) *attrs, int nid)
4155{
4156	X509_ATTRIBUTE *a;
4157	int i;
4158
4159	if (attrs == NULL)
4160		return (NULL);
4161
4162	for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) {
4163		/*LINTED*/
4164		a = sk_X509_ATTRIBUTE_value(attrs, i);
4165		if (OBJ_obj2nid(a->object) == nid)
4166			return (a);
4167	}
4168	return (NULL);
4169}
4170
4171static KMF_RETURN
4172convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key)
4173{
4174	KMF_RETURN rv = KMF_OK;
4175	X509_ATTRIBUTE *attr;
4176
4177	if (pkey == NULL || key == NULL)
4178		return (KMF_ERR_BAD_PARAMETER);
4179	/* Convert SSL key to raw key */
4180	switch (pkey->type) {
4181		case EVP_PKEY_RSA:
4182			rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey),
4183			    key);
4184			if (rv != KMF_OK)
4185				return (rv);
4186			break;
4187		case EVP_PKEY_DSA:
4188			rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey),
4189			    key);
4190			if (rv != KMF_OK)
4191				return (rv);
4192			break;
4193		default:
4194			return (KMF_ERR_BAD_PARAMETER);
4195	}
4196	/*
4197	 * If friendlyName, add it to record.
4198	 */
4199	attr = find_attr(pkey->attributes, NID_friendlyName);
4200	if (attr != NULL) {
4201		ASN1_TYPE *ty = NULL;
4202		int numattr = sk_ASN1_TYPE_num(attr->value.set);
4203		if (attr->single == 0 && numattr > 0) {
4204			/*LINTED*/
4205			ty = sk_ASN1_TYPE_value(attr->value.set, 0);
4206		}
4207		if (ty != NULL) {
4208			key->label = uni2asc(ty->value.bmpstring->data,
4209			    ty->value.bmpstring->length);
4210		}
4211	} else {
4212		key->label = NULL;
4213	}
4214
4215	/*
4216	 * If KeyID, add it to record as a KMF_DATA object.
4217	 */
4218	attr = find_attr(pkey->attributes, NID_localKeyID);
4219	if (attr != NULL) {
4220		ASN1_TYPE *ty = NULL;
4221		int numattr = sk_ASN1_TYPE_num(attr->value.set);
4222		if (attr->single == 0 && numattr > 0) {
4223			/*LINTED*/
4224			ty = sk_ASN1_TYPE_value(attr->value.set, 0);
4225		}
4226		key->id.Data = (uchar_t *)malloc(
4227		    ty->value.octet_string->length);
4228		if (key->id.Data == NULL)
4229			return (KMF_ERR_MEMORY);
4230		(void) memcpy(key->id.Data, ty->value.octet_string->data,
4231		    ty->value.octet_string->length);
4232		key->id.Length = ty->value.octet_string->length;
4233	} else {
4234		(void) memset(&key->id, 0, sizeof (KMF_DATA));
4235	}
4236
4237	return (rv);
4238}
4239
4240static KMF_RETURN
4241convertPK12Objects(
4242	KMF_HANDLE *kmfh,
4243	STACK_OF(EVP_PKEY) *sslkeys,
4244	STACK_OF(X509) *sslcert,
4245	STACK_OF(X509) *sslcacerts,
4246	KMF_RAW_KEY_DATA **keylist, int *nkeys,
4247	KMF_X509_DER_CERT **certlist, int *ncerts)
4248{
4249	KMF_RETURN rv = KMF_OK;
4250	KMF_RAW_KEY_DATA key;
4251	int i;
4252
4253	for (i = 0; sslkeys != NULL && i < sk_EVP_PKEY_num(sslkeys); i++) {
4254		/*LINTED*/
4255		EVP_PKEY *pkey = sk_EVP_PKEY_value(sslkeys, i);
4256		rv = convertToRawKey(pkey, &key);
4257		if (rv == KMF_OK)
4258			rv = add_key_to_list(keylist, &key, nkeys);
4259
4260		if (rv != KMF_OK)
4261			return (rv);
4262	}
4263
4264	/* Now add the certificate to the certlist */
4265	for (i = 0; sslcert != NULL && i < sk_X509_num(sslcert); i++) {
4266		/*LINTED*/
4267		X509 *cert = sk_X509_value(sslcert, i);
4268		rv = add_cert_to_list(kmfh, cert, certlist, ncerts);
4269		if (rv != KMF_OK)
4270			return (rv);
4271	}
4272
4273	/* Also add any included CA certs to the list */
4274	for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) {
4275		X509 *c;
4276		/*
4277		 * sk_X509_value() is macro that embeds a cast to (X509 *).
4278		 * Here it translates into ((X509 *)sk_value((ca), (i))).
4279		 * Lint is complaining about the embedded casting, and
4280		 * to fix it, you need to fix openssl header files.
4281		 */
4282		/* LINTED E_BAD_PTR_CAST_ALIGN */
4283		c = sk_X509_value(sslcacerts, i);
4284
4285		/* Now add the ca cert to the certlist */
4286		rv = add_cert_to_list(kmfh, c, certlist, ncerts);
4287		if (rv != KMF_OK)
4288			return (rv);
4289	}
4290	return (rv);
4291}
4292
4293KMF_RETURN
4294openssl_import_objects(KMF_HANDLE *kmfh,
4295	char *filename, KMF_CREDENTIAL *cred,
4296	KMF_X509_DER_CERT **certlist, int *ncerts,
4297	KMF_RAW_KEY_DATA **keylist, int *nkeys)
4298{
4299	KMF_RETURN	rv = KMF_OK;
4300	KMF_ENCODE_FORMAT format;
4301	BIO		*bio = NULL;
4302	STACK_OF(EVP_PKEY)	*privkeys = NULL;
4303	STACK_OF(X509)		*certs = NULL;
4304	STACK_OF(X509)		*cacerts = NULL;
4305
4306	/*
4307	 * auto-detect the file format, regardless of what
4308	 * the 'format' parameters in the params say.
4309	 */
4310	rv = kmf_get_file_format(filename, &format);
4311	if (rv != KMF_OK) {
4312		return (rv);
4313	}
4314
4315	/* This function only works for PEM or PKCS#12 files */
4316	if (format != KMF_FORMAT_PEM &&
4317	    format != KMF_FORMAT_PEM_KEYPAIR &&
4318	    format != KMF_FORMAT_PKCS12)
4319		return (KMF_ERR_ENCODING);
4320
4321	*certlist = NULL;
4322	*keylist = NULL;
4323	*ncerts = 0;
4324	*nkeys = 0;
4325
4326	if (format == KMF_FORMAT_PKCS12) {
4327		bio = BIO_new_file(filename, "rb");
4328		if (bio == NULL) {
4329			SET_ERROR(kmfh, ERR_get_error());
4330			rv = KMF_ERR_OPEN_FILE;
4331			goto end;
4332		}
4333
4334		rv = extract_pkcs12(bio, (uchar_t *)cred->cred,
4335		    (uint32_t)cred->credlen, &privkeys, &certs, &cacerts);
4336
4337		if (rv  == KMF_OK)
4338			/* Convert keys and certs to exportable format */
4339			rv = convertPK12Objects(kmfh, privkeys, certs, cacerts,
4340			    keylist, nkeys, certlist, ncerts);
4341	} else {
4342		EVP_PKEY *pkey;
4343		KMF_DATA *certdata = NULL;
4344		KMF_X509_DER_CERT *kmfcerts = NULL;
4345		int i;
4346		rv = extract_pem(kmfh, NULL, NULL, NULL, filename,
4347		    (uchar_t *)cred->cred, (uint32_t)cred->credlen,
4348		    &pkey, &certdata, ncerts);
4349
4350		/* Reached end of import file? */
4351		if (rv == KMF_OK && pkey != NULL) {
4352			privkeys = sk_EVP_PKEY_new_null();
4353			if (privkeys == NULL) {
4354				rv = KMF_ERR_MEMORY;
4355				goto end;
4356			}
4357			(void) sk_EVP_PKEY_push(privkeys, pkey);
4358			/* convert the certificate list here */
4359			if (*ncerts > 0 && certlist != NULL) {
4360				kmfcerts = (KMF_X509_DER_CERT *)malloc(*ncerts *
4361				    sizeof (KMF_X509_DER_CERT));
4362				if (kmfcerts == NULL) {
4363					rv = KMF_ERR_MEMORY;
4364					goto end;
4365				}
4366				(void) memset(kmfcerts, 0, *ncerts *
4367				    sizeof (KMF_X509_DER_CERT));
4368				for (i = 0; i < *ncerts; i++) {
4369					kmfcerts[i].certificate = certdata[i];
4370					kmfcerts[i].kmf_private.keystore_type =
4371					    KMF_KEYSTORE_OPENSSL;
4372				}
4373				*certlist = kmfcerts;
4374			}
4375			/*
4376			 * Convert keys to exportable format, the certs
4377			 * are already OK.
4378			 */
4379			rv = convertPK12Objects(kmfh, privkeys, NULL, NULL,
4380			    keylist, nkeys, NULL, NULL);
4381		}
4382	}
4383end:
4384	if (bio != NULL)
4385		(void) BIO_free(bio);
4386
4387	if (privkeys)
4388		sk_EVP_PKEY_pop_free(privkeys, EVP_PKEY_free);
4389	if (certs)
4390		sk_X509_pop_free(certs, X509_free);
4391	if (cacerts)
4392		sk_X509_pop_free(cacerts, X509_free);
4393
4394	return (rv);
4395}
4396
4397static KMF_RETURN
4398create_deskey(DES_cblock **deskey)
4399{
4400	DES_cblock *key;
4401
4402	key = (DES_cblock *) malloc(sizeof (DES_cblock));
4403	if (key == NULL) {
4404		return (KMF_ERR_MEMORY);
4405	}
4406
4407	if (DES_random_key(key) == 0) {
4408		free(key);
4409		return (KMF_ERR_KEYGEN_FAILED);
4410	}
4411
4412	*deskey = key;
4413	return (KMF_OK);
4414}
4415
4416#define	KEYGEN_RETRY 3
4417#define	DES3_KEY_SIZE 24
4418
4419static KMF_RETURN
4420create_des3key(unsigned char **des3key)
4421{
4422	KMF_RETURN ret = KMF_OK;
4423	DES_cblock *deskey1 = NULL;
4424	DES_cblock *deskey2 = NULL;
4425	DES_cblock *deskey3 = NULL;
4426	unsigned char *newkey = NULL;
4427	int retry;
4428
4429	if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) {
4430		return (KMF_ERR_MEMORY);
4431	}
4432
4433	/* create the 1st DES key */
4434	if ((ret = create_deskey(&deskey1)) != KMF_OK) {
4435		goto out;
4436	}
4437
4438	/*
4439	 * Create the 2nd DES key and make sure its value is different
4440	 * from the 1st DES key.
4441	 */
4442	retry = 0;
4443	do {
4444		if (deskey2 != NULL) {
4445			free(deskey2);
4446			deskey2 = NULL;
4447		}
4448
4449		if ((ret = create_deskey(&deskey2)) != KMF_OK) {
4450			goto out;
4451		}
4452
4453		if (memcmp((const void *) deskey1, (const void *) deskey2, 8)
4454		    == 0) {
4455			ret = KMF_ERR_KEYGEN_FAILED;
4456			retry++;
4457		}
4458	} while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4459
4460	if (ret != KMF_OK) {
4461		goto out;
4462	}
4463
4464	/*
4465	 * Create the 3rd DES key and make sure its value is different
4466	 * from the 2nd DES key.
4467	 */
4468	retry = 0;
4469	do {
4470		if (deskey3 != NULL) {
4471			free(deskey3);
4472			deskey3 = NULL;
4473		}
4474
4475		if ((ret = create_deskey(&deskey3)) != KMF_OK) {
4476			goto out;
4477		}
4478
4479		if (memcmp((const void *)deskey2, (const void *)deskey3, 8)
4480		    == 0) {
4481			ret = KMF_ERR_KEYGEN_FAILED;
4482			retry++;
4483		}
4484	} while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4485
4486	if (ret != KMF_OK) {
4487		goto out;
4488	}
4489
4490	/* Concatenate 3 DES keys into a DES3 key */
4491	(void) memcpy((void *)newkey, (const void *)deskey1, 8);
4492	(void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8);
4493	(void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8);
4494	*des3key = newkey;
4495
4496out:
4497	if (deskey1 != NULL)
4498		free(deskey1);
4499
4500	if (deskey2 != NULL)
4501		free(deskey2);
4502
4503	if (deskey3 != NULL)
4504		free(deskey3);
4505
4506	if (ret != KMF_OK && newkey != NULL)
4507		free(newkey);
4508
4509	return (ret);
4510}
4511
4512KMF_RETURN
4513OpenSSL_CreateSymKey(KMF_HANDLE_T handle,
4514	int numattr, KMF_ATTRIBUTE *attrlist)
4515{
4516	KMF_RETURN ret = KMF_OK;
4517	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4518	char *fullpath = NULL;
4519	KMF_RAW_SYM_KEY *rkey = NULL;
4520	DES_cblock *deskey = NULL;
4521	unsigned char *des3key = NULL;
4522	unsigned char *random = NULL;
4523	int fd = -1;
4524	KMF_KEY_HANDLE *symkey;
4525	KMF_KEY_ALG keytype;
4526	uint32_t keylen;
4527	uint32_t keylen_size = sizeof (keylen);
4528	char *dirpath;
4529	char *keyfile;
4530
4531	if (kmfh == NULL)
4532		return (KMF_ERR_UNINITIALIZED);
4533
4534	symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
4535	if (symkey == NULL)
4536		return (KMF_ERR_BAD_PARAMETER);
4537
4538	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
4539
4540	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
4541	if (keyfile == NULL)
4542		return (KMF_ERR_BAD_PARAMETER);
4543
4544	ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
4545	    (void *)&keytype, NULL);
4546	if (ret != KMF_OK)
4547		return (KMF_ERR_BAD_PARAMETER);
4548
4549	ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
4550	    &keylen, &keylen_size);
4551	if (ret == KMF_ERR_ATTR_NOT_FOUND &&
4552	    (keytype == KMF_DES || keytype == KMF_DES3))
4553		/* keylength is not required for DES and 3DES */
4554		ret = KMF_OK;
4555	if (ret != KMF_OK)
4556		return (KMF_ERR_BAD_PARAMETER);
4557
4558	fullpath = get_fullpath(dirpath, keyfile);
4559	if (fullpath == NULL)
4560		return (KMF_ERR_BAD_PARAMETER);
4561
4562	/* If the requested file exists, return an error */
4563	if (test_for_file(fullpath, 0400) == 1) {
4564		free(fullpath);
4565		return (KMF_ERR_DUPLICATE_KEYFILE);
4566	}
4567
4568	fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400);
4569	if (fd == -1) {
4570		ret = KMF_ERR_OPEN_FILE;
4571		goto out;
4572	}
4573
4574	rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
4575	if (rkey == NULL) {
4576		ret = KMF_ERR_MEMORY;
4577		goto out;
4578	}
4579	(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
4580
4581	if (keytype == KMF_DES) {
4582		if ((ret = create_deskey(&deskey)) != KMF_OK) {
4583			goto out;
4584		}
4585		rkey->keydata.val = (uchar_t *)deskey;
4586		rkey->keydata.len = 8;
4587
4588		symkey->keyalg = KMF_DES;
4589
4590	} else if (keytype == KMF_DES3) {
4591		if ((ret = create_des3key(&des3key)) != KMF_OK) {
4592			goto out;
4593		}
4594		rkey->keydata.val = (uchar_t *)des3key;
4595		rkey->keydata.len = DES3_KEY_SIZE;
4596		symkey->keyalg = KMF_DES3;
4597
4598	} else if (keytype == KMF_AES || keytype == KMF_RC4 ||
4599	    keytype == KMF_GENERIC_SECRET) {
4600		int bytes;
4601
4602		if (keylen % 8 != 0) {
4603			ret = KMF_ERR_BAD_KEY_SIZE;
4604			goto out;
4605		}
4606
4607		if (keytype == KMF_AES) {
4608			if (keylen != 128 &&
4609			    keylen != 192 &&
4610			    keylen != 256) {
4611				ret = KMF_ERR_BAD_KEY_SIZE;
4612				goto out;
4613			}
4614		}
4615
4616		bytes = keylen/8;
4617		random = malloc(bytes);
4618		if (random == NULL) {
4619			ret = KMF_ERR_MEMORY;
4620			goto out;
4621		}
4622		if (RAND_bytes(random, bytes) != 1) {
4623			ret = KMF_ERR_KEYGEN_FAILED;
4624			goto out;
4625		}
4626
4627		rkey->keydata.val = (uchar_t *)random;
4628		rkey->keydata.len = bytes;
4629		symkey->keyalg = keytype;
4630
4631	} else {
4632		ret = KMF_ERR_BAD_KEY_TYPE;
4633		goto out;
4634	}
4635
4636	(void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len);
4637
4638	symkey->kstype = KMF_KEYSTORE_OPENSSL;
4639	symkey->keyclass = KMF_SYMMETRIC;
4640	symkey->keylabel = (char *)fullpath;
4641	symkey->israw = TRUE;
4642	symkey->keyp = rkey;
4643
4644out:
4645	if (fd != -1)
4646		(void) close(fd);
4647
4648	if (ret != KMF_OK && fullpath != NULL) {
4649		free(fullpath);
4650	}
4651	if (ret != KMF_OK) {
4652		kmf_free_raw_sym_key(rkey);
4653		symkey->keyp = NULL;
4654		symkey->keyalg = KMF_KEYALG_NONE;
4655	}
4656
4657	return (ret);
4658}
4659
4660/*
4661 * Check a file to see if it is a CRL file with PEM or DER format.
4662 * If success, return its format in the "pformat" argument.
4663 */
4664KMF_RETURN
4665OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat)
4666{
4667	KMF_RETURN	ret = KMF_OK;
4668	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4669	BIO		*bio = NULL;
4670	X509_CRL   	*xcrl = NULL;
4671
4672	if (filename == NULL) {
4673		return (KMF_ERR_BAD_PARAMETER);
4674	}
4675
4676	bio = BIO_new_file(filename, "rb");
4677	if (bio == NULL)	{
4678		SET_ERROR(kmfh, ERR_get_error());
4679		ret = KMF_ERR_OPEN_FILE;
4680		goto out;
4681	}
4682
4683	if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) {
4684		*pformat = KMF_FORMAT_PEM;
4685		goto out;
4686	}
4687	(void) BIO_free(bio);
4688
4689	/*
4690	 * Now try to read it as raw DER data.
4691	 */
4692	bio = BIO_new_file(filename, "rb");
4693	if (bio == NULL)	{
4694		SET_ERROR(kmfh, ERR_get_error());
4695		ret = KMF_ERR_OPEN_FILE;
4696		goto out;
4697	}
4698
4699	if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) {
4700		*pformat = KMF_FORMAT_ASN1;
4701	} else {
4702		ret = KMF_ERR_BAD_CRLFILE;
4703	}
4704
4705out:
4706	if (bio != NULL)
4707		(void) BIO_free(bio);
4708
4709	if (xcrl != NULL)
4710		X509_CRL_free(xcrl);
4711
4712	return (ret);
4713}
4714
4715/*
4716 * Check a file to see if it is a certficate file with PEM or DER format.
4717 * If success, return its format in the pformat argument.
4718 */
4719KMF_RETURN
4720OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename,
4721	KMF_ENCODE_FORMAT *pformat)
4722{
4723	KMF_RETURN	ret = KMF_OK;
4724	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4725	BIO		*bio = NULL;
4726	X509		*xcert = NULL;
4727
4728	if (filename == NULL) {
4729		return (KMF_ERR_BAD_PARAMETER);
4730	}
4731
4732	ret = kmf_get_file_format(filename, pformat);
4733	if (ret != KMF_OK)
4734		return (ret);
4735
4736	bio = BIO_new_file(filename, "rb");
4737	if (bio == NULL)	{
4738		SET_ERROR(kmfh, ERR_get_error());
4739		ret = KMF_ERR_OPEN_FILE;
4740		goto out;
4741	}
4742
4743	if ((*pformat) == KMF_FORMAT_PEM) {
4744		if ((xcert = PEM_read_bio_X509(bio, NULL,
4745		    NULL, NULL)) == NULL) {
4746			ret = KMF_ERR_BAD_CERTFILE;
4747		}
4748	} else if ((*pformat) == KMF_FORMAT_ASN1) {
4749		if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) {
4750			ret = KMF_ERR_BAD_CERTFILE;
4751		}
4752	} else {
4753		ret = KMF_ERR_BAD_CERTFILE;
4754	}
4755
4756out:
4757	if (bio != NULL)
4758		(void) BIO_free(bio);
4759
4760	if (xcert != NULL)
4761		X509_free(xcert);
4762
4763	return (ret);
4764}
4765
4766KMF_RETURN
4767OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
4768    KMF_RAW_SYM_KEY *rkey)
4769{
4770	KMF_RETURN	rv = KMF_OK;
4771	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4772	KMF_DATA	keyvalue;
4773
4774	if (kmfh == NULL)
4775		return (KMF_ERR_UNINITIALIZED);
4776
4777	if (symkey == NULL || rkey == NULL)
4778		return (KMF_ERR_BAD_PARAMETER);
4779	else if (symkey->keyclass != KMF_SYMMETRIC)
4780		return (KMF_ERR_BAD_KEY_CLASS);
4781
4782	if (symkey->israw) {
4783		KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp;
4784
4785		if (rawkey == NULL ||
4786		    rawkey->keydata.val == NULL ||
4787		    rawkey->keydata.len == 0)
4788			return (KMF_ERR_BAD_KEYHANDLE);
4789
4790		rkey->keydata.len = rawkey->keydata.len;
4791		if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
4792			return (KMF_ERR_MEMORY);
4793		(void) memcpy(rkey->keydata.val, rawkey->keydata.val,
4794		    rkey->keydata.len);
4795	} else {
4796		rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue);
4797		if (rv != KMF_OK)
4798			return (rv);
4799		rkey->keydata.len = keyvalue.Length;
4800		rkey->keydata.val = keyvalue.Data;
4801	}
4802
4803	return (rv);
4804}
4805
4806/*
4807 * id-sha1    OBJECT IDENTIFIER ::= {
4808 *     iso(1) identified-organization(3) oiw(14) secsig(3)
4809 *     algorithms(2) 26
4810 * }
4811 */
4812#define	ASN1_SHA1_OID_PREFIX_LEN 15
4813static uchar_t SHA1_DER_PREFIX[ASN1_SHA1_OID_PREFIX_LEN] = {
4814	0x30, 0x21, 0x30, 0x09,
4815	0x06, 0x05, 0x2b, 0x0e,
4816	0x03, 0x02, 0x1a, 0x05,
4817	0x00, 0x04, 0x14
4818};
4819
4820/*
4821 * id-md2 OBJECT IDENTIFIER ::= {
4822 *     iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2
4823 * }
4824 */
4825#define	ASN1_MD2_OID_PREFIX_LEN 18
4826static uchar_t MD2_DER_PREFIX[ASN1_MD2_OID_PREFIX_LEN] = {
4827	0x30, 0x20, 0x30, 0x0c,
4828	0x06, 0x08, 0x2a, 0x86,
4829	0x48, 0x86, 0xf7, 0x0d,
4830	0x02, 0x02, 0x05, 0x00,
4831	0x04, 0x10
4832};
4833
4834/*
4835 * id-md5 OBJECT IDENTIFIER ::= {
4836 *     iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5
4837 * }
4838 */
4839#define	ASN1_MD5_OID_PREFIX_LEN 18
4840static uchar_t MD5_DER_PREFIX[ASN1_MD5_OID_PREFIX_LEN] = {
4841	0x30, 0x20, 0x30, 0x0c,
4842	0x06, 0x08, 0x2a, 0x86,
4843	0x48, 0x86, 0xf7, 0x0d,
4844	0x02, 0x05, 0x05, 0x00,
4845	0x04, 0x10
4846};
4847
4848KMF_RETURN
4849OpenSSL_VerifyDataWithCert(KMF_HANDLE_T handle,
4850	KMF_ALGORITHM_INDEX algid, KMF_DATA *indata,
4851	KMF_DATA *insig, KMF_DATA *cert)
4852{
4853	KMF_RETURN ret = KMF_OK;
4854	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4855	X509	*xcert = NULL;
4856	EVP_PKEY *pkey = NULL;
4857	uchar_t *p;
4858	uchar_t *rsaout = NULL;
4859	uchar_t *pfx = NULL;
4860	const EVP_MD *md;
4861	int pfxlen = 0, len;
4862
4863	if (handle == NULL || indata == NULL ||
4864	    indata->Data == NULL || indata->Length == 0 ||
4865	    insig == NULL|| insig->Data == NULL || insig->Length == 0 ||
4866	    cert == NULL || cert->Data == NULL || cert->Length == 0)
4867		return (KMF_ERR_BAD_PARAMETER);
4868
4869	p = cert->Data;
4870	xcert = d2i_X509(NULL, (const uchar_t **)&p, cert->Length);
4871	if (xcert == NULL) {
4872		SET_ERROR(kmfh, ERR_get_error());
4873		ret = KMF_ERR_BAD_CERT_FORMAT;
4874		goto cleanup;
4875	}
4876
4877	pkey = X509_get_pubkey(xcert);
4878	if (pkey == NULL) {
4879		SET_ERROR(kmfh, ERR_get_error());
4880		ret = KMF_ERR_BAD_CERT_FORMAT;
4881		goto cleanup;
4882	}
4883
4884	if (algid != KMF_ALGID_NONE) {
4885		switch (algid) {
4886			case KMF_ALGID_MD5WithRSA:
4887				md = EVP_md5();
4888				break;
4889			case KMF_ALGID_MD2WithRSA:
4890				md = EVP_md2();
4891				break;
4892			case KMF_ALGID_SHA1WithRSA:
4893				md = EVP_sha1();
4894				break;
4895			case KMF_ALGID_RSA:
4896				md = NULL;
4897				break;
4898			default:
4899				ret = KMF_ERR_BAD_PARAMETER;
4900				goto cleanup;
4901		}
4902	} else {
4903		/* Get the hash type from the cert signature */
4904		md = EVP_get_digestbyobj(xcert->sig_alg->algorithm);
4905		if (md == NULL) {
4906			SET_ERROR(kmfh, ERR_get_error());
4907			ret = KMF_ERR_BAD_PARAMETER;
4908			goto cleanup;
4909		}
4910	}
4911	if (md != NULL) {
4912		switch (EVP_MD_type(md)) {
4913		case NID_md2:
4914		case NID_md2WithRSAEncryption:
4915			pfxlen = ASN1_MD2_OID_PREFIX_LEN;
4916			pfx = MD2_DER_PREFIX;
4917			break;
4918		case NID_md5:
4919		case NID_md5WithRSAEncryption:
4920			pfxlen = ASN1_MD5_OID_PREFIX_LEN;
4921			pfx = MD5_DER_PREFIX;
4922			break;
4923		case NID_sha1:
4924		case NID_sha1WithRSAEncryption:
4925			pfxlen = ASN1_SHA1_OID_PREFIX_LEN;
4926			pfx = SHA1_DER_PREFIX;
4927			break;
4928		default: /* Unsupported */
4929			pfxlen = 0;
4930			pfx = NULL;
4931			break;
4932		}
4933	}
4934
4935	/* RSA with no hash is a special case */
4936	rsaout = malloc(RSA_size(pkey->pkey.rsa));
4937	if (rsaout == NULL)
4938		return (KMF_ERR_MEMORY);
4939
4940	/* Decrypt the input signature */
4941	len = RSA_public_decrypt(insig->Length,
4942	    insig->Data, rsaout, pkey->pkey.rsa, RSA_PKCS1_PADDING);
4943	if (len < 1) {
4944		SET_ERROR(kmfh, ERR_get_error());
4945		ret = KMF_ERR_BAD_PARAMETER;
4946	} else {
4947		size_t hashlen = 0;
4948		uint32_t dlen;
4949		char *digest = NULL;
4950
4951		/*
4952		 * If the AlgId requires it, hash the input data before
4953		 * comparing it to the decrypted signature.
4954		 */
4955		if (md) {
4956			EVP_MD_CTX ctx;
4957
4958			hashlen = md->md_size;
4959
4960			digest = malloc(hashlen + pfxlen);
4961			if (digest == NULL)
4962				return (KMF_ERR_MEMORY);
4963			/* Add the prefix to the comparison buffer. */
4964			if (pfx && pfxlen > 0) {
4965				(void) memcpy(digest, pfx, pfxlen);
4966			}
4967			(void) EVP_DigestInit(&ctx, md);
4968			(void) EVP_DigestUpdate(&ctx, indata->Data,
4969			    indata->Length);
4970
4971			/* Add the digest AFTER the ASN1 prefix */
4972			(void) EVP_DigestFinal(&ctx,
4973			    (uchar_t *)digest + pfxlen, &dlen);
4974
4975			dlen += pfxlen;
4976		} else {
4977			digest = (char *)indata->Data;
4978			dlen = indata->Length;
4979		}
4980
4981		/*
4982		 * The result of the RSA decryption should be ASN1(OID | Hash).
4983		 * Compare the output hash to the input data for the final
4984		 * result.
4985		 */
4986		if (memcmp(rsaout, digest, dlen))
4987			ret = KMF_ERR_INTERNAL;
4988		else
4989			ret = KMF_OK;
4990
4991		/* If we had to allocate space for the digest, free it now */
4992		if (hashlen)
4993			free(digest);
4994	}
4995cleanup:
4996	if (pkey)
4997		EVP_PKEY_free(pkey);
4998
4999	if (xcert)
5000		X509_free(xcert);
5001
5002	if (rsaout)
5003		free(rsaout);
5004
5005	return (ret);
5006}
5007
5008/*
5009 * substitute for the unsafe access(2) function.
5010 * If the file in question already exists, return 1.
5011 * else 0.  If an error occurs during testing (other
5012 * than EEXIST), return -1.
5013 */
5014static int
5015test_for_file(char *filename, mode_t mode)
5016{
5017	int fd;
5018
5019	/*
5020	 * Try to create the file with the EXCL flag.
5021	 * The call should fail if the file exists.
5022	 */
5023	fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode);
5024	if (fd == -1 && errno == EEXIST)
5025		return (1);
5026	else if (fd == -1) /* some other error */
5027		return (-1);
5028
5029	/* The file did NOT exist.  Delete the testcase. */
5030	(void) close(fd);
5031	(void) unlink(filename);
5032	return (0);
5033}
5034
5035KMF_RETURN
5036OpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr,
5037	KMF_ATTRIBUTE *attrlist)
5038{
5039	KMF_RETURN rv = KMF_OK;
5040	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
5041	KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL;
5042	KMF_RAW_KEY_DATA *rawkey;
5043	EVP_PKEY *pkey = NULL;
5044	KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM;
5045	KMF_CREDENTIAL cred = {NULL, 0};
5046	BIO *out = NULL;
5047	int keys = 0;
5048	char *fullpath = NULL;
5049	char *keyfile = NULL;
5050	char *dirpath = NULL;
5051
5052	pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
5053	if (pubkey != NULL)
5054		keys++;
5055
5056	prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
5057	if (prikey != NULL)
5058		keys++;
5059
5060	rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
5061	if (rawkey != NULL)
5062		keys++;
5063
5064	/*
5065	 * Exactly 1 type of key must be passed to this function.
5066	 */
5067	if (keys != 1)
5068		return (KMF_ERR_BAD_PARAMETER);
5069
5070	keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist,
5071	    numattr);
5072	if (keyfile == NULL)
5073		return (KMF_ERR_BAD_PARAMETER);
5074
5075	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5076
5077	fullpath = get_fullpath(dirpath, keyfile);
5078
5079	/* Once we have the full path, we don't need the pieces */
5080	if (fullpath == NULL)
5081		return (KMF_ERR_BAD_PARAMETER);
5082
5083	/* If the requested file exists, return an error */
5084	if (test_for_file(fullpath, 0400) == 1) {
5085		free(fullpath);
5086		return (KMF_ERR_DUPLICATE_KEYFILE);
5087	}
5088
5089	rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
5090	    &format, NULL);
5091	if (rv != KMF_OK)
5092		/* format is optional. */
5093		rv = KMF_OK;
5094
5095	/* CRED is not required for OpenSSL files */
5096	(void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
5097	    &cred, NULL);
5098
5099	/* Store the private key to the keyfile */
5100	out = BIO_new_file(fullpath, "wb");
5101	if (out == NULL) {
5102		SET_ERROR(kmfh, ERR_get_error());
5103		rv = KMF_ERR_OPEN_FILE;
5104		goto end;
5105	}
5106
5107	if (prikey != NULL && prikey->keyp != NULL) {
5108		if (prikey->keyalg == KMF_RSA ||
5109		    prikey->keyalg == KMF_DSA) {
5110			pkey = (EVP_PKEY *)prikey->keyp;
5111
5112			rv = ssl_write_key(kmfh, format,
5113			    out, &cred, pkey, TRUE);
5114
5115			if (rv == KMF_OK && prikey->keylabel == NULL) {
5116				prikey->keylabel = strdup(fullpath);
5117				if (prikey->keylabel == NULL)
5118					rv = KMF_ERR_MEMORY;
5119			}
5120		}
5121	} else if (pubkey != NULL && pubkey->keyp != NULL) {
5122		if (pubkey->keyalg == KMF_RSA ||
5123		    pubkey->keyalg == KMF_DSA) {
5124			pkey = (EVP_PKEY *)pubkey->keyp;
5125
5126			rv = ssl_write_key(kmfh, format,
5127			    out, &cred, pkey, FALSE);
5128
5129			if (rv == KMF_OK && pubkey->keylabel == NULL) {
5130				pubkey->keylabel = strdup(fullpath);
5131				if (pubkey->keylabel == NULL)
5132					rv = KMF_ERR_MEMORY;
5133			}
5134		}
5135	} else if (rawkey != NULL) {
5136		/* RAW keys are always private */
5137		if (rawkey->keytype == KMF_RSA) {
5138			pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
5139		} else if (rawkey->keytype == KMF_DSA) {
5140			pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
5141		} else {
5142			rv = KMF_ERR_BAD_PARAMETER;
5143		}
5144		if (pkey != NULL) {
5145			rv = ssl_write_key(kmfh, format, out,
5146			    &cred, pkey, TRUE);
5147			EVP_PKEY_free(pkey);
5148		}
5149	}
5150
5151end:
5152
5153	if (out)
5154		(void) BIO_free(out);
5155
5156
5157	if (rv == KMF_OK)
5158		(void) chmod(fullpath, 0400);
5159
5160	free(fullpath);
5161	return (rv);
5162}
5163
5164KMF_RETURN
5165OpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5166{
5167	KMF_RETURN ret = KMF_OK;
5168	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5169	X509_CRL *xcrl = NULL;
5170	X509 *xcert = NULL;
5171	EVP_PKEY *pkey;
5172	KMF_ENCODE_FORMAT format;
5173	BIO *in = NULL, *out = NULL;
5174	int openssl_ret = 0;
5175	KMF_ENCODE_FORMAT outformat;
5176	boolean_t crlcheck = FALSE;
5177	char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile;
5178
5179	if (numattr == 0 || attrlist == NULL) {
5180		return (KMF_ERR_BAD_PARAMETER);
5181	}
5182
5183	/* CRL check is optional */
5184	(void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr,
5185	    &crlcheck, NULL);
5186
5187	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
5188	if (crlcheck == B_TRUE && certfile == NULL) {
5189		return (KMF_ERR_BAD_CERTFILE);
5190	}
5191
5192	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5193	incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr);
5194	outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr);
5195
5196	crlfile = get_fullpath(dirpath, incrl);
5197
5198	if (crlfile == NULL)
5199		return (KMF_ERR_BAD_CRLFILE);
5200
5201	outcrlfile = get_fullpath(dirpath, outcrl);
5202	if (outcrlfile == NULL)
5203		return (KMF_ERR_BAD_CRLFILE);
5204
5205	if (isdir(outcrlfile)) {
5206		free(outcrlfile);
5207		return (KMF_ERR_BAD_CRLFILE);
5208	}
5209
5210	ret = kmf_is_crl_file(handle, crlfile, &format);
5211	if (ret != KMF_OK) {
5212		free(outcrlfile);
5213		return (ret);
5214	}
5215
5216	in = BIO_new_file(crlfile, "rb");
5217	if (in == NULL)	{
5218		SET_ERROR(kmfh, ERR_get_error());
5219		ret = KMF_ERR_OPEN_FILE;
5220		goto end;
5221	}
5222
5223	if (format == KMF_FORMAT_ASN1) {
5224		xcrl = d2i_X509_CRL_bio(in, NULL);
5225	} else if (format == KMF_FORMAT_PEM) {
5226		xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5227	}
5228
5229	if (xcrl == NULL) {
5230		SET_ERROR(kmfh, ERR_get_error());
5231		ret = KMF_ERR_BAD_CRLFILE;
5232		goto end;
5233	}
5234
5235	/* If bypasscheck is specified, no need to verify. */
5236	if (crlcheck == B_FALSE)
5237		goto output;
5238
5239	ret = kmf_is_cert_file(handle, certfile, &format);
5240	if (ret != KMF_OK)
5241		goto end;
5242
5243	/* Read in the CA cert file and convert to X509 */
5244	if (BIO_read_filename(in, certfile) <= 0) {
5245		SET_ERROR(kmfh, ERR_get_error());
5246		ret = KMF_ERR_OPEN_FILE;
5247		goto end;
5248	}
5249
5250	if (format == KMF_FORMAT_ASN1) {
5251		xcert = d2i_X509_bio(in, NULL);
5252	} else if (format == KMF_FORMAT_PEM) {
5253		xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
5254	} else {
5255		ret = KMF_ERR_BAD_CERT_FORMAT;
5256		goto end;
5257	}
5258
5259	if (xcert == NULL) {
5260		SET_ERROR(kmfh, ERR_get_error());
5261		ret = KMF_ERR_BAD_CERT_FORMAT;
5262		goto end;
5263	}
5264	/* Now get the public key from the CA cert */
5265	pkey = X509_get_pubkey(xcert);
5266	if (pkey == NULL) {
5267		SET_ERROR(kmfh, ERR_get_error());
5268		ret = KMF_ERR_BAD_CERTFILE;
5269		goto end;
5270	}
5271
5272	/* Verify the CRL with the CA's public key */
5273	openssl_ret = X509_CRL_verify(xcrl, pkey);
5274	EVP_PKEY_free(pkey);
5275	if (openssl_ret > 0) {
5276		ret = KMF_OK;  /* verify succeed */
5277	} else {
5278		SET_ERROR(kmfh, openssl_ret);
5279		ret = KMF_ERR_BAD_CRLFILE;
5280	}
5281
5282output:
5283	ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
5284	    &outformat, NULL);
5285	if (ret != KMF_OK) {
5286		ret = KMF_OK;
5287		outformat = KMF_FORMAT_PEM;
5288	}
5289
5290	out = BIO_new_file(outcrlfile, "wb");
5291	if (out == NULL) {
5292		SET_ERROR(kmfh, ERR_get_error());
5293		ret = KMF_ERR_OPEN_FILE;
5294		goto end;
5295	}
5296
5297	if (outformat == KMF_FORMAT_ASN1) {
5298		openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl);
5299	} else if (outformat == KMF_FORMAT_PEM) {
5300		openssl_ret = PEM_write_bio_X509_CRL(out, xcrl);
5301	} else {
5302		ret = KMF_ERR_BAD_PARAMETER;
5303		goto end;
5304	}
5305
5306	if (openssl_ret <= 0) {
5307		SET_ERROR(kmfh, ERR_get_error());
5308		ret = KMF_ERR_WRITE_FILE;
5309	} else {
5310		ret = KMF_OK;
5311	}
5312
5313end:
5314	if (xcrl != NULL)
5315		X509_CRL_free(xcrl);
5316
5317	if (xcert != NULL)
5318		X509_free(xcert);
5319
5320	if (in != NULL)
5321		(void) BIO_free(in);
5322
5323	if (out != NULL)
5324		(void) BIO_free(out);
5325
5326	if (outcrlfile != NULL)
5327		free(outcrlfile);
5328
5329	return (ret);
5330}
5331
5332KMF_RETURN
5333OpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5334{
5335	KMF_RETURN ret = KMF_OK;
5336	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5337	X509_CRL   *x = NULL;
5338	KMF_ENCODE_FORMAT format;
5339	char *crlfile = NULL;
5340	BIO *in = NULL;
5341	BIO *mem = NULL;
5342	long len;
5343	char *memptr;
5344	char *data = NULL;
5345	char **crldata;
5346	char *crlfilename, *dirpath;
5347
5348	if (numattr == 0 || attrlist == NULL) {
5349		return (KMF_ERR_BAD_PARAMETER);
5350	}
5351	crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5352	    attrlist, numattr);
5353	if (crlfilename == NULL)
5354		return (KMF_ERR_BAD_CRLFILE);
5355
5356	crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR,
5357	    attrlist, numattr);
5358
5359	if (crldata == NULL)
5360		return (KMF_ERR_BAD_PARAMETER);
5361
5362	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5363
5364	crlfile = get_fullpath(dirpath, crlfilename);
5365
5366	if (crlfile == NULL)
5367		return (KMF_ERR_BAD_CRLFILE);
5368
5369	if (isdir(crlfile)) {
5370		free(crlfile);
5371		return (KMF_ERR_BAD_CRLFILE);
5372	}
5373
5374	ret = kmf_is_crl_file(handle, crlfile, &format);
5375	if (ret != KMF_OK) {
5376		free(crlfile);
5377		return (ret);
5378	}
5379
5380	if (bio_err == NULL)
5381		bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
5382
5383	in = BIO_new_file(crlfile, "rb");
5384	if (in == NULL)	{
5385		SET_ERROR(kmfh, ERR_get_error());
5386		ret = KMF_ERR_OPEN_FILE;
5387		goto end;
5388	}
5389
5390	if (format == KMF_FORMAT_ASN1) {
5391		x = d2i_X509_CRL_bio(in, NULL);
5392	} else if (format == KMF_FORMAT_PEM) {
5393		x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5394	}
5395
5396	if (x == NULL) { /* should not happen */
5397		SET_ERROR(kmfh, ERR_get_error());
5398		ret = KMF_ERR_OPEN_FILE;
5399		goto end;
5400	}
5401
5402	mem = BIO_new(BIO_s_mem());
5403	if (mem == NULL) {
5404		SET_ERROR(kmfh, ERR_get_error());
5405		ret = KMF_ERR_MEMORY;
5406		goto end;
5407	}
5408
5409	(void) X509_CRL_print(mem, x);
5410	len = BIO_get_mem_data(mem, &memptr);
5411	if (len <= 0) {
5412		SET_ERROR(kmfh, ERR_get_error());
5413		ret = KMF_ERR_MEMORY;
5414		goto end;
5415	}
5416
5417	data = malloc(len + 1);
5418	if (data == NULL) {
5419		ret = KMF_ERR_MEMORY;
5420		goto end;
5421	}
5422
5423	(void) memcpy(data, memptr, len);
5424	data[len] = '\0';
5425	*crldata = data;
5426
5427end:
5428	if (x != NULL)
5429		X509_CRL_free(x);
5430
5431	if (crlfile != NULL)
5432		free(crlfile);
5433
5434	if (in != NULL)
5435		(void) BIO_free(in);
5436
5437	if (mem != NULL)
5438		(void) BIO_free(mem);
5439
5440	return (ret);
5441}
5442
5443KMF_RETURN
5444OpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5445{
5446	KMF_RETURN ret = KMF_OK;
5447	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5448	KMF_ENCODE_FORMAT format;
5449	char *crlfile = NULL;
5450	BIO *in = NULL;
5451	char *crlfilename, *dirpath;
5452
5453	if (numattr == 0 || attrlist == NULL) {
5454		return (KMF_ERR_BAD_PARAMETER);
5455	}
5456
5457	crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5458	    attrlist, numattr);
5459
5460	if (crlfilename == NULL)
5461		return (KMF_ERR_BAD_CRLFILE);
5462
5463	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5464
5465	crlfile = get_fullpath(dirpath, crlfilename);
5466
5467	if (crlfile == NULL)
5468		return (KMF_ERR_BAD_CRLFILE);
5469
5470	if (isdir(crlfile)) {
5471		ret = KMF_ERR_BAD_CRLFILE;
5472		goto end;
5473	}
5474
5475	ret = kmf_is_crl_file(handle, crlfile, &format);
5476	if (ret != KMF_OK)
5477		goto end;
5478
5479	if (unlink(crlfile) != 0) {
5480		SET_SYS_ERROR(kmfh, errno);
5481		ret = KMF_ERR_INTERNAL;
5482		goto end;
5483	}
5484
5485end:
5486	if (in != NULL)
5487		(void) BIO_free(in);
5488	if (crlfile != NULL)
5489		free(crlfile);
5490
5491	return (ret);
5492}
5493
5494KMF_RETURN
5495OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5496{
5497	KMF_RETURN ret = KMF_OK;
5498	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5499	KMF_ENCODE_FORMAT format;
5500	BIO *in = NULL;
5501	X509   *xcert = NULL;
5502	X509_CRL   *xcrl = NULL;
5503	STACK_OF(X509_REVOKED) *revoke_stack = NULL;
5504	X509_REVOKED *revoke;
5505	int i;
5506	char *crlfilename, *crlfile, *dirpath, *certfile;
5507
5508	if (numattr == 0 || attrlist == NULL) {
5509		return (KMF_ERR_BAD_PARAMETER);
5510	}
5511
5512	crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5513	    attrlist, numattr);
5514
5515	if (crlfilename == NULL)
5516		return (KMF_ERR_BAD_CRLFILE);
5517
5518	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
5519	if (certfile == NULL)
5520		return (KMF_ERR_BAD_CRLFILE);
5521
5522	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5523
5524	crlfile = get_fullpath(dirpath, crlfilename);
5525
5526	if (crlfile == NULL)
5527		return (KMF_ERR_BAD_CRLFILE);
5528
5529	if (isdir(crlfile)) {
5530		ret = KMF_ERR_BAD_CRLFILE;
5531		goto end;
5532	}
5533
5534	ret = kmf_is_crl_file(handle, crlfile, &format);
5535	if (ret != KMF_OK)
5536		goto end;
5537
5538	/* Read the CRL file and load it into a X509_CRL structure */
5539	in = BIO_new_file(crlfilename, "rb");
5540	if (in == NULL)	{
5541		SET_ERROR(kmfh, ERR_get_error());
5542		ret = KMF_ERR_OPEN_FILE;
5543		goto end;
5544	}
5545
5546	if (format == KMF_FORMAT_ASN1) {
5547		xcrl = d2i_X509_CRL_bio(in, NULL);
5548	} else if (format == KMF_FORMAT_PEM) {
5549		xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5550	}
5551
5552	if (xcrl == NULL) {
5553		SET_ERROR(kmfh, ERR_get_error());
5554		ret = KMF_ERR_BAD_CRLFILE;
5555		goto end;
5556	}
5557	(void) BIO_free(in);
5558
5559	/* Read the Certificate file and load it into a X509 structure */
5560	ret = kmf_is_cert_file(handle, certfile, &format);
5561	if (ret != KMF_OK)
5562		goto end;
5563
5564	in = BIO_new_file(certfile, "rb");
5565	if (in == NULL)	{
5566		SET_ERROR(kmfh, ERR_get_error());
5567		ret = KMF_ERR_OPEN_FILE;
5568		goto end;
5569	}
5570
5571	if (format == KMF_FORMAT_ASN1) {
5572		xcert = d2i_X509_bio(in, NULL);
5573	} else if (format == KMF_FORMAT_PEM) {
5574		xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
5575	}
5576
5577	if (xcert == NULL) {
5578		SET_ERROR(kmfh, ERR_get_error());
5579		ret = KMF_ERR_BAD_CERTFILE;
5580		goto end;
5581	}
5582
5583	/* Check if the certificate and the CRL have same issuer */
5584	if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) {
5585		ret = KMF_ERR_ISSUER;
5586		goto end;
5587	}
5588
5589	/* Check to see if the certificate serial number is revoked */
5590	revoke_stack = X509_CRL_get_REVOKED(xcrl);
5591	if (sk_X509_REVOKED_num(revoke_stack) <= 0) {
5592		/* No revoked certificates in the CRL file */
5593		SET_ERROR(kmfh, ERR_get_error());
5594		ret = KMF_ERR_EMPTY_CRL;
5595		goto end;
5596	}
5597
5598	for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) {
5599		/*LINTED*/
5600		revoke = sk_X509_REVOKED_value(revoke_stack, i);
5601		if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber,
5602		    revoke->serialNumber) == 0) {
5603			break;
5604		}
5605	}
5606
5607	if (i < sk_X509_REVOKED_num(revoke_stack)) {
5608		ret = KMF_OK;
5609	} else {
5610		ret = KMF_ERR_NOT_REVOKED;
5611	}
5612
5613end:
5614	if (in != NULL)
5615		(void) BIO_free(in);
5616	if (xcrl != NULL)
5617		X509_CRL_free(xcrl);
5618	if (xcert != NULL)
5619		X509_free(xcert);
5620
5621	return (ret);
5622}
5623
5624KMF_RETURN
5625OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert)
5626{
5627	KMF_RETURN	ret = KMF_OK;
5628	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
5629	BIO		*bcrl = NULL;
5630	X509_CRL   	*xcrl = NULL;
5631	X509		*xcert = NULL;
5632	EVP_PKEY	*pkey;
5633	int		sslret;
5634	KMF_ENCODE_FORMAT crl_format;
5635	unsigned char	*p;
5636	long		len;
5637
5638	if (handle == NULL || crlname == NULL || tacert == NULL) {
5639		return (KMF_ERR_BAD_PARAMETER);
5640	}
5641
5642	ret = kmf_get_file_format(crlname, &crl_format);
5643	if (ret != KMF_OK)
5644		return (ret);
5645
5646	bcrl = BIO_new_file(crlname, "rb");
5647	if (bcrl == NULL)	{
5648		SET_ERROR(kmfh, ERR_get_error());
5649		ret = KMF_ERR_OPEN_FILE;
5650		goto cleanup;
5651	}
5652
5653	if (crl_format == KMF_FORMAT_ASN1) {
5654		xcrl = d2i_X509_CRL_bio(bcrl, NULL);
5655	} else if (crl_format == KMF_FORMAT_PEM) {
5656		xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
5657	} else {
5658		ret = KMF_ERR_BAD_PARAMETER;
5659		goto cleanup;
5660	}
5661
5662	if (xcrl == NULL) {
5663		SET_ERROR(kmfh, ERR_get_error());
5664		ret = KMF_ERR_BAD_CRLFILE;
5665		goto cleanup;
5666	}
5667
5668	p = tacert->Data;
5669	len = tacert->Length;
5670	xcert = d2i_X509(NULL, (const uchar_t **)&p, len);
5671
5672	if (xcert == NULL) {
5673		SET_ERROR(kmfh, ERR_get_error());
5674		ret = KMF_ERR_BAD_CERTFILE;
5675		goto cleanup;
5676	}
5677
5678	/* Get issuer certificate public key */
5679	pkey = X509_get_pubkey(xcert);
5680	if (pkey == NULL) {
5681		SET_ERROR(kmfh, ERR_get_error());
5682		ret = KMF_ERR_BAD_CERT_FORMAT;
5683		goto cleanup;
5684	}
5685
5686	/* Verify CRL signature */
5687	sslret = X509_CRL_verify(xcrl, pkey);
5688	EVP_PKEY_free(pkey);
5689	if (sslret > 0) {
5690		ret = KMF_OK;
5691	} else {
5692		SET_ERROR(kmfh, sslret);
5693		ret = KMF_ERR_BAD_CRLFILE;
5694	}
5695
5696cleanup:
5697	if (bcrl != NULL)
5698		(void) BIO_free(bcrl);
5699
5700	if (xcrl != NULL)
5701		X509_CRL_free(xcrl);
5702
5703	if (xcert != NULL)
5704		X509_free(xcert);
5705
5706	return (ret);
5707
5708}
5709
5710KMF_RETURN
5711OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname)
5712{
5713	KMF_RETURN	ret = KMF_OK;
5714	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
5715	KMF_ENCODE_FORMAT crl_format;
5716	BIO		*bcrl = NULL;
5717	X509_CRL   	*xcrl = NULL;
5718	int		i;
5719
5720	if (handle == NULL || crlname == NULL) {
5721		return (KMF_ERR_BAD_PARAMETER);
5722	}
5723
5724	ret = kmf_is_crl_file(handle, crlname, &crl_format);
5725	if (ret != KMF_OK)
5726		return (ret);
5727
5728	bcrl = BIO_new_file(crlname, "rb");
5729	if (bcrl == NULL) {
5730		SET_ERROR(kmfh, ERR_get_error());
5731		ret = KMF_ERR_OPEN_FILE;
5732		goto cleanup;
5733	}
5734
5735	if (crl_format == KMF_FORMAT_ASN1)
5736		xcrl = d2i_X509_CRL_bio(bcrl, NULL);
5737	else if (crl_format == KMF_FORMAT_PEM)
5738		xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
5739
5740	if (xcrl == NULL) {
5741		SET_ERROR(kmfh, ERR_get_error());
5742		ret = KMF_ERR_BAD_CRLFILE;
5743		goto cleanup;
5744	}
5745	i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL);
5746	if (i >= 0) {
5747		ret = KMF_ERR_VALIDITY_PERIOD;
5748		goto cleanup;
5749	}
5750	if (X509_CRL_get_nextUpdate(xcrl)) {
5751		i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL);
5752
5753		if (i <= 0) {
5754			ret = KMF_ERR_VALIDITY_PERIOD;
5755			goto cleanup;
5756		}
5757	}
5758
5759	ret = KMF_OK;
5760
5761cleanup:
5762	if (bcrl != NULL)
5763		(void) BIO_free(bcrl);
5764
5765	if (xcrl != NULL)
5766		X509_CRL_free(xcrl);
5767
5768	return (ret);
5769}
5770