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