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