1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  *
21  * OpenSSL keystore wrapper
22  *
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <kmfapiP.h>
30 #include <ber_der.h>
31 #include <oidsalg.h>
32 #include <fcntl.h>
33 #include <sys/stat.h>
34 #include <dirent.h>
35 #include <cryptoutil.h>
36 #include <synch.h>
37 #include <thread.h>
38 
39 /* OPENSSL related headers */
40 #include <openssl/bio.h>
41 #include <openssl/bn.h>
42 #include <openssl/asn1.h>
43 #include <openssl/err.h>
44 #include <openssl/bn.h>
45 #include <openssl/x509.h>
46 #include <openssl/rsa.h>
47 #include <openssl/dsa.h>
48 #include <openssl/x509v3.h>
49 #include <openssl/objects.h>
50 #include <openssl/pem.h>
51 #include <openssl/pkcs12.h>
52 #include <openssl/ocsp.h>
53 #include <openssl/des.h>
54 #include <openssl/rand.h>
55 
56 #define	PRINT_ANY_EXTENSION (\
57 	KMF_X509_EXT_KEY_USAGE |\
58 	KMF_X509_EXT_CERT_POLICIES |\
59 	KMF_X509_EXT_SUBJALTNAME |\
60 	KMF_X509_EXT_BASIC_CONSTRAINTS |\
61 	KMF_X509_EXT_NAME_CONSTRAINTS |\
62 	KMF_X509_EXT_POLICY_CONSTRAINTS |\
63 	KMF_X509_EXT_EXT_KEY_USAGE |\
64 	KMF_X509_EXT_INHIBIT_ANY_POLICY |\
65 	KMF_X509_EXT_AUTH_KEY_ID |\
66 	KMF_X509_EXT_SUBJ_KEY_ID |\
67 	KMF_X509_EXT_POLICY_MAPPING)
68 
69 static BIO *bio_err = NULL;
70 static uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
71 	0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69,
72 	0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c,
73 	0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82,
74 	0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e,
75 	0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a,
76 	0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
77 	0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02,
78 	0x91 };
79 
80 static uchar_t Q[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
81 	0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4,
82 	0x8e, 0xda, 0xce, 0x91, 0x5f };
83 
84 static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
85 	0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5,
86 	0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef,
87 	0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c,
88 	0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba,
89 	0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c,
90 	0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
91 	0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
92 	0x02 };
93 
94 #define	SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \
95 	h->lasterr.errcode = c;
96 
97 #define	SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c;
98 
99 mutex_t init_lock = DEFAULTMUTEX;
100 static int ssl_initialized = 0;
101 
102 KMF_RETURN
103 OpenSSL_FindCert(KMF_HANDLE_T,
104 	KMF_FINDCERT_PARAMS *,
105 	KMF_X509_DER_CERT *,
106 	uint32_t *);
107 
108 void
109 OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *);
110 
111 KMF_RETURN
112 OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *, KMF_DATA *);
113 
114 KMF_RETURN
115 OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *);
116 
117 KMF_RETURN
118 OpenSSL_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *,
119 	KMF_KEY_HANDLE *, KMF_KEY_HANDLE *);
120 
121 KMF_RETURN
122 OpenSSL_EncodePubKeyData(KMF_HANDLE_T,  KMF_KEY_HANDLE *, KMF_DATA *);
123 
124 KMF_RETURN
125 OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
126 	KMF_DATA *, KMF_DATA *);
127 
128 KMF_RETURN
129 OpenSSL_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *,
130 	KMF_KEY_HANDLE *, boolean_t);
131 
132 KMF_RETURN
133 OpenSSL_ImportCRL(KMF_HANDLE_T, KMF_IMPORTCRL_PARAMS *);
134 
135 KMF_RETURN
136 OpenSSL_DeleteCRL(KMF_HANDLE_T, KMF_DELETECRL_PARAMS *);
137 
138 KMF_RETURN
139 OpenSSL_ListCRL(KMF_HANDLE_T, KMF_LISTCRL_PARAMS *, char **);
140 
141 KMF_RETURN
142 OpenSSL_FindCertInCRL(KMF_HANDLE_T, KMF_FINDCERTINCRL_PARAMS *);
143 
144 KMF_RETURN
145 OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *,
146 	KMF_PRINTABLE_ITEM, char *);
147 
148 KMF_RETURN
149 OpenSSL_GetErrorString(KMF_HANDLE_T, char **);
150 
151 KMF_RETURN
152 OpenSSL_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *,
153 	KMF_KEY_HANDLE *, KMF_KEY_ALG);
154 
155 KMF_RETURN
156 OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
157 	KMF_DATA *, KMF_DATA *);
158 
159 KMF_RETURN
160 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, KMF_OCSPREQUEST_PARAMS *,
161 	char *reqfile);
162 
163 KMF_RETURN
164 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, KMF_OCSPRESPONSE_PARAMS_INPUT *,
165     KMF_OCSPRESPONSE_PARAMS_OUTPUT *);
166 
167 KMF_RETURN
168 OpenSSL_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *,
169 	KMF_KEY_HANDLE *, uint32_t *);
170 
171 KMF_RETURN
172 OpenSSL_ExportP12(KMF_HANDLE_T,
173 	KMF_EXPORTP12_PARAMS *,
174 	int, KMF_X509_DER_CERT *,
175 	int, KMF_KEY_HANDLE *,
176 	char *);
177 
178 KMF_RETURN
179 OpenSSL_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *,
180 	KMF_RAW_KEY_DATA *);
181 
182 KMF_RETURN
183 OpenSSL_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *,
184 	KMF_KEY_HANDLE *);
185 
186 KMF_RETURN
187 OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
188 
189 KMF_RETURN
190 OpenSSL_VerifyCRLFile(KMF_HANDLE_T, KMF_VERIFYCRL_PARAMS *);
191 
192 KMF_RETURN
193 OpenSSL_CheckCRLDate(KMF_HANDLE_T, KMF_CHECKCRLDATE_PARAMS *);
194 
195 static
196 KMF_PLUGIN_FUNCLIST openssl_plugin_table =
197 {
198 	1,				/* Version */
199 	NULL, /* ConfigureKeystore */
200 	OpenSSL_FindCert,
201 	OpenSSL_FreeKMFCert,
202 	OpenSSL_StoreCert,
203 	NULL, /* ImportCert */
204 	OpenSSL_ImportCRL,
205 	OpenSSL_DeleteCert,
206 	OpenSSL_DeleteCRL,
207 	OpenSSL_CreateKeypair,
208 	OpenSSL_FindKey,
209 	OpenSSL_EncodePubKeyData,
210 	OpenSSL_SignData,
211 	OpenSSL_DeleteKey,
212 	OpenSSL_ListCRL,
213 	NULL,	/* FindCRL */
214 	OpenSSL_FindCertInCRL,
215 	OpenSSL_GetErrorString,
216 	OpenSSL_GetPrikeyByCert,
217 	OpenSSL_DecryptData,
218 	OpenSSL_ExportP12,
219 	OpenSSL_StorePrivateKey,
220 	OpenSSL_CreateSymKey,
221 	OpenSSL_GetSymKeyValue,
222 	NULL,	/* SetTokenPin */
223 	NULL	/* Finalize */
224 };
225 
226 static mutex_t *lock_cs;
227 static long *lock_count;
228 
229 static void
230 /*ARGSUSED*/
231 locking_cb(int mode, int type, char *file, int line)
232 {
233 	if (mode & CRYPTO_LOCK) {
234 		(void) mutex_lock(&(lock_cs[type]));
235 		lock_count[type]++;
236 	} else {
237 		(void) mutex_unlock(&(lock_cs[type]));
238 	}
239 }
240 
241 static unsigned long
242 thread_id()
243 {
244 	return ((unsigned long)thr_self());
245 }
246 
247 KMF_PLUGIN_FUNCLIST *
248 KMF_Plugin_Initialize()
249 {
250 	int i;
251 
252 	(void) mutex_lock(&init_lock);
253 	if (!ssl_initialized) {
254 		OpenSSL_add_all_algorithms();
255 
256 		/* Enable error strings for reporting */
257 		ERR_load_crypto_strings();
258 
259 		/*
260 		 * Add support for extension OIDs that are not yet in the
261 		 * openssl default set.
262 		 */
263 		(void) OBJ_create("2.5.29.30", "nameConstraints",
264 				"X509v3 Name Constraints");
265 		(void) OBJ_create("2.5.29.33", "policyMappings",
266 				"X509v3 Policy Mappings");
267 		(void) OBJ_create("2.5.29.36", "policyConstraints",
268 			"X509v3 Policy Constraints");
269 		(void) OBJ_create("2.5.29.46", "freshestCRL",
270 			"X509v3 Freshest CRL");
271 		(void) OBJ_create("2.5.29.54", "inhibitAnyPolicy",
272 			"X509v3 Inhibit Any-Policy");
273 		/*
274 		 * Set up for thread-safe operation.
275 		 */
276 		lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t));
277 		if (lock_cs == NULL) {
278 			(void) mutex_unlock(&init_lock);
279 			return (NULL);
280 		}
281 
282 		lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long));
283 		if (lock_count == NULL) {
284 			OPENSSL_free(lock_cs);
285 			(void) mutex_unlock(&init_lock);
286 			return (NULL);
287 		}
288 
289 		for (i = 0; i < CRYPTO_num_locks(); i++) {
290 			lock_count[i] = 0;
291 			(void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL);
292 		}
293 
294 		CRYPTO_set_id_callback((unsigned long (*)())thread_id);
295 		CRYPTO_set_locking_callback((void (*)())locking_cb);
296 		ssl_initialized = 1;
297 	}
298 	(void) mutex_unlock(&init_lock);
299 
300 	return (&openssl_plugin_table);
301 }
302 /*
303  * Convert an SSL DN to a KMF DN.
304  */
305 static KMF_RETURN
306 get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN)
307 {
308 	KMF_DATA derdata;
309 	KMF_RETURN rv = KMF_OK;
310 	uchar_t *tmp;
311 
312 	/* Convert to raw DER format */
313 	derdata.Length = i2d_X509_NAME(sslDN, NULL);
314 	if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length))
315 		== NULL) {
316 		return (KMF_ERR_MEMORY);
317 	}
318 	(void) i2d_X509_NAME(sslDN, &tmp);
319 
320 	/* Decode to KMF format */
321 	rv = DerDecodeName(&derdata, kmfDN);
322 	if (rv != KMF_OK) {
323 		rv = KMF_ERR_BAD_CERT_FORMAT;
324 	}
325 	OPENSSL_free(derdata.Data);
326 
327 	return (rv);
328 }
329 
330 static int
331 isdir(char *path)
332 {
333 	struct stat s;
334 
335 	if (stat(path, &s) == -1)
336 		return (0);
337 
338 	return (s.st_mode & S_IFDIR);
339 }
340 
341 static KMF_RETURN
342 ssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert)
343 {
344 	KMF_RETURN rv = KMF_OK;
345 	unsigned char *buf = NULL, *p;
346 	int len;
347 
348 	/*
349 	 * Convert the X509 internal struct to DER encoded data
350 	 */
351 	if ((len = i2d_X509(x509cert, NULL)) < 0) {
352 		SET_ERROR(kmfh, ERR_get_error());
353 		rv = KMF_ERR_BAD_CERT_FORMAT;
354 		goto cleanup;
355 	}
356 	if ((buf = malloc(len)) == NULL) {
357 		SET_SYS_ERROR(kmfh, errno);
358 		rv = KMF_ERR_MEMORY;
359 		goto cleanup;
360 	}
361 
362 	/*
363 	 * i2d_X509 will increment the buf pointer so that we need to
364 	 * save it.
365 	 */
366 	p = buf;
367 	if ((len = i2d_X509(x509cert, &p)) < 0) {
368 		SET_ERROR(kmfh, ERR_get_error());
369 		free(buf);
370 		rv = KMF_ERR_BAD_CERT_FORMAT;
371 		goto cleanup;
372 	}
373 
374 	/* caller's responsibility to free it */
375 	cert->Data = buf;
376 	cert->Length = len;
377 
378 cleanup:
379 	if (rv != KMF_OK) {
380 		if (buf)
381 			free(buf);
382 		cert->Data = NULL;
383 		cert->Length = 0;
384 	}
385 
386 	return (rv);
387 }
388 
389 static KMF_RETURN
390 check_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match)
391 {
392 	KMF_RETURN rv = KMF_OK;
393 	boolean_t findIssuer = FALSE;
394 	boolean_t findSubject = FALSE;
395 	boolean_t findSerial = FALSE;
396 	KMF_X509_NAME issuerDN, subjectDN;
397 	KMF_X509_NAME certIssuerDN, certSubjectDN;
398 
399 	*match = FALSE;
400 	if (xcert == NULL) {
401 		return (KMF_ERR_BAD_PARAMETER);
402 	}
403 
404 	(void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME));
405 	(void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME));
406 	(void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME));
407 	(void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME));
408 
409 	if (params->issuer != NULL && strlen(params->issuer)) {
410 		rv = KMF_DNParser(params->issuer, &issuerDN);
411 		if (rv != KMF_OK)
412 			return (KMF_ERR_BAD_PARAMETER);
413 
414 		rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN);
415 		if (rv != KMF_OK) {
416 			KMF_FreeDN(&issuerDN);
417 			return (KMF_ERR_BAD_PARAMETER);
418 		}
419 
420 		findIssuer = TRUE;
421 	}
422 	if (params->subject != NULL && strlen(params->subject)) {
423 		rv = KMF_DNParser(params->subject, &subjectDN);
424 		if (rv != KMF_OK) {
425 			rv = KMF_ERR_BAD_PARAMETER;
426 			goto cleanup;
427 		}
428 
429 		rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN);
430 		if (rv != KMF_OK) {
431 			rv = KMF_ERR_BAD_PARAMETER;
432 			goto cleanup;
433 		}
434 		findSubject = TRUE;
435 	}
436 	if (params->serial != NULL && params->serial->val != NULL)
437 		findSerial = TRUE;
438 
439 	if (findSerial) {
440 		BIGNUM *bn;
441 
442 		/* Comparing BIGNUMs is a pain! */
443 		bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL);
444 		if (bn != NULL) {
445 			int bnlen = BN_num_bytes(bn);
446 
447 			if (bnlen == params->serial->len) {
448 				uchar_t *a = malloc(bnlen);
449 				if (a == NULL) {
450 					rv = KMF_ERR_MEMORY;
451 					BN_free(bn);
452 					goto cleanup;
453 				}
454 				bnlen = BN_bn2bin(bn, a);
455 				*match = !memcmp(a,
456 					params->serial->val,
457 					params->serial->len);
458 				rv = KMF_OK;
459 				free(a);
460 			}
461 			BN_free(bn);
462 			if (!(*match))
463 				goto cleanup;
464 		} else {
465 			rv = KMF_OK;
466 			goto cleanup;
467 		}
468 	}
469 	if (findIssuer) {
470 		*match = !KMF_CompareRDNs(&issuerDN, &certIssuerDN);
471 		if (!(*match)) {
472 			rv = KMF_OK;
473 			goto cleanup;
474 		}
475 	}
476 	if (findSubject) {
477 		*match = !KMF_CompareRDNs(&subjectDN, &certSubjectDN);
478 		if (!(*match)) {
479 			rv = KMF_OK;
480 			goto cleanup;
481 		}
482 	}
483 
484 	*match = TRUE;
485 cleanup:
486 	if (findIssuer) {
487 		KMF_FreeDN(&issuerDN);
488 		KMF_FreeDN(&certIssuerDN);
489 	}
490 	if (findSubject) {
491 		KMF_FreeDN(&subjectDN);
492 		KMF_FreeDN(&certSubjectDN);
493 	}
494 
495 	return (rv);
496 }
497 
498 static KMF_RETURN
499 load_X509cert(KMF_HANDLE *kmfh,
500 	KMF_FINDCERT_PARAMS *params,
501 	char *pathname,
502 	X509 **outcert)
503 {
504 	KMF_RETURN rv = KMF_OK;
505 	X509 *xcert = NULL;
506 	BIO *bcert = NULL;
507 	boolean_t  match = FALSE;
508 	KMF_ENCODE_FORMAT format;
509 
510 	/*
511 	 * auto-detect the file format, regardless of what
512 	 * the 'format' parameters in the params say.
513 	 */
514 	rv = KMF_GetFileFormat(pathname, &format);
515 	if (rv != KMF_OK) {
516 		if (rv == KMF_ERR_OPEN_FILE)
517 			rv = KMF_ERR_CERT_NOT_FOUND;
518 		return (rv);
519 	}
520 
521 	/* Not ASN1(DER) format */
522 	if ((bcert = BIO_new_file(pathname, "rb")) == NULL) {
523 		SET_ERROR(kmfh, ERR_get_error());
524 		rv = KMF_ERR_OPEN_FILE;
525 		goto cleanup;
526 	}
527 
528 	if (format == KMF_FORMAT_PEM)
529 		xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL);
530 	else if (format == KMF_FORMAT_ASN1)
531 		xcert = d2i_X509_bio(bcert, NULL);
532 	else if (format == KMF_FORMAT_PKCS12) {
533 		PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL);
534 		if (p12 != NULL) {
535 			(void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL);
536 			PKCS12_free(p12);
537 			p12 = NULL;
538 		} else {
539 			SET_ERROR(kmfh, ERR_get_error());
540 			rv = KMF_ERR_BAD_CERT_FORMAT;
541 		}
542 	} else {
543 		rv = KMF_ERR_BAD_PARAMETER;
544 		goto cleanup;
545 	}
546 
547 	if (xcert == NULL) {
548 		SET_ERROR(kmfh, ERR_get_error());
549 		rv = KMF_ERR_BAD_CERT_FORMAT;
550 		goto cleanup;
551 	}
552 
553 	if (check_cert(xcert, params, &match) != KMF_OK || match == FALSE) {
554 		rv = KMF_ERR_CERT_NOT_FOUND;
555 		goto cleanup;
556 	}
557 
558 	if (outcert != NULL) {
559 		*outcert = xcert;
560 	}
561 
562 cleanup:
563 	if (bcert != NULL) (void) BIO_free(bcert);
564 	if (rv != KMF_OK && xcert != NULL)
565 		X509_free(xcert);
566 
567 	return (rv);
568 }
569 
570 static KMF_RETURN
571 kmf_load_cert(KMF_HANDLE *kmfh,
572 	KMF_FINDCERT_PARAMS *params,
573 	char *pathname,
574 	KMF_DATA *cert)
575 {
576 	KMF_RETURN rv = KMF_OK;
577 	X509 *x509cert = NULL;
578 
579 	rv = load_X509cert(kmfh, params, pathname, &x509cert);
580 	if (rv == KMF_OK && x509cert != NULL && cert != NULL) {
581 		rv = ssl_cert2KMFDATA(kmfh, x509cert, cert);
582 		if (rv != KMF_OK) {
583 			goto cleanup;
584 		}
585 		if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) {
586 			rv = KMF_CheckCertDate(kmfh, cert);
587 		} else if (params->find_cert_validity == KMF_EXPIRED_CERTS) {
588 			rv = KMF_CheckCertDate(kmfh, cert);
589 			if (rv == KMF_OK)  {
590 				/*
591 				 * This is a valid cert so skip it.
592 				 */
593 				rv = KMF_ERR_CERT_NOT_FOUND;
594 			}
595 			if (rv == KMF_ERR_VALIDITY_PERIOD) {
596 				/*
597 				 * We want to return success when we
598 				 * find an invalid cert.
599 				 */
600 				rv = KMF_OK;
601 				goto cleanup;
602 			}
603 		}
604 	}
605 cleanup:
606 	if (x509cert != NULL)
607 		X509_free(x509cert);
608 
609 	return (rv);
610 }
611 
612 static EVP_PKEY *
613 openssl_load_key(KMF_HANDLE_T handle, const char *file)
614 {
615 	BIO *keyfile = NULL;
616 	EVP_PKEY *pkey = NULL;
617 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
618 	KMF_ENCODE_FORMAT format;
619 
620 	if (file == NULL) {
621 		return (NULL);
622 	}
623 
624 	if (KMF_GetFileFormat((char *)file, &format) != KMF_OK)
625 		return (NULL);
626 
627 	keyfile = BIO_new_file(file, "rb");
628 	if (keyfile == NULL) {
629 		goto end;
630 	}
631 
632 	if (format == KMF_FORMAT_ASN1)
633 		pkey = d2i_PrivateKey_bio(keyfile, NULL);
634 	else if (format == KMF_FORMAT_PEM)
635 		pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL);
636 
637 end:
638 	if (pkey == NULL)
639 		SET_ERROR(kmfh, ERR_get_error());
640 
641 	if (keyfile != NULL)
642 		(void) BIO_free(keyfile);
643 
644 	return (pkey);
645 }
646 
647 KMF_RETURN
648 OpenSSL_FindCert(KMF_HANDLE_T handle,
649 	KMF_FINDCERT_PARAMS *params,
650 	KMF_X509_DER_CERT *kmf_cert,
651 	uint32_t *num_certs)
652 {
653 	KMF_RETURN rv = KMF_OK;
654 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
655 	KMF_DATA certdata = {NULL, 0};
656 	char *fullpath;
657 
658 	if (num_certs == NULL || params == NULL)
659 		return (KMF_ERR_BAD_PARAMETER);
660 
661 	*num_certs = 0;
662 
663 	fullpath = get_fullpath(params->sslparms.dirpath,
664 		params->sslparms.certfile);
665 
666 	if (fullpath == NULL)
667 		return (KMF_ERR_BAD_PARAMETER);
668 
669 	if (isdir(fullpath)) {
670 		DIR *dirp;
671 		struct dirent *dp;
672 		int n = 0;
673 
674 		/* open all files in the directory and attempt to read them */
675 		if ((dirp = opendir(fullpath)) == NULL) {
676 			return (KMF_ERR_BAD_PARAMETER);
677 		}
678 		while ((dp = readdir(dirp)) != NULL) {
679 			char *fname;
680 			if (strcmp(dp->d_name, ".") == 0 ||
681 			    strcmp(dp->d_name, "..") == 0)
682 				continue;
683 
684 			fname = get_fullpath(fullpath,
685 				(char *)&dp->d_name);
686 
687 			rv = kmf_load_cert(kmfh, params, fname,
688 				&certdata);
689 
690 			if (rv != KMF_OK) {
691 				free(fname);
692 				KMF_FreeData(&certdata);
693 				continue;
694 			}
695 
696 			/* If load succeeds, add certdata to the list */
697 			if (kmf_cert != NULL) {
698 				kmf_cert[n].certificate.Data = certdata.Data;
699 				kmf_cert[n].certificate.Length =
700 					certdata.Length;
701 
702 				kmf_cert[n].kmf_private.keystore_type =
703 					KMF_KEYSTORE_OPENSSL;
704 				kmf_cert[n].kmf_private.flags =
705 					KMF_FLAG_CERT_VALID;
706 				kmf_cert[n].kmf_private.label = fname;
707 			} else {
708 				free(fname);
709 				KMF_FreeData(&certdata);
710 			}
711 			n++;
712 		}
713 		(*num_certs) = n;
714 		if (*num_certs == 0)
715 			rv = KMF_ERR_CERT_NOT_FOUND;
716 		if (*num_certs > 0)
717 			rv = KMF_OK;
718 exit:
719 		(void) closedir(dirp);
720 	} else {
721 		/* Just try to load a single certificate */
722 		rv = kmf_load_cert(kmfh, params, fullpath, &certdata);
723 		if (rv != KMF_OK) {
724 			free(fullpath);
725 			KMF_FreeData(&certdata);
726 			return (rv);
727 		}
728 
729 		if (kmf_cert != NULL) {
730 			kmf_cert->certificate.Data = certdata.Data;
731 			kmf_cert->certificate.Length = certdata.Length;
732 			kmf_cert->kmf_private.keystore_type =
733 				KMF_KEYSTORE_OPENSSL;
734 			kmf_cert->kmf_private.flags = KMF_FLAG_CERT_VALID;
735 			kmf_cert->kmf_private.label = fullpath;
736 		} else {
737 			KMF_FreeData(&certdata);
738 		}
739 
740 		*num_certs = 1;
741 	}
742 
743 	if (kmf_cert == NULL || rv != KMF_OK)
744 		free(fullpath);
745 
746 	return (rv);
747 
748 }
749 
750 void
751 /*ARGSUSED*/
752 OpenSSL_FreeKMFCert(KMF_HANDLE_T handle,
753 	KMF_X509_DER_CERT *kmf_cert)
754 {
755 	if (kmf_cert != NULL) {
756 		if (kmf_cert->certificate.Data != NULL) {
757 			free(kmf_cert->certificate.Data);
758 			kmf_cert->certificate.Data = NULL;
759 			kmf_cert->certificate.Length = 0;
760 		}
761 		if (kmf_cert->kmf_private.label)
762 			free(kmf_cert->kmf_private.label);
763 	}
764 }
765 
766 KMF_RETURN
767 OpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params,
768     KMF_DATA * pcert)
769 {
770 	KMF_RETURN ret = KMF_OK;
771 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
772 	X509 *xcert = NULL;
773 	FILE *fp;
774 	unsigned char *outbuf;
775 	unsigned char *outbuf_p;
776 	char *fullpath;
777 	int outbuflen;
778 	int len;
779 	KMF_ENCODE_FORMAT format;
780 
781 	if (params == NULL || params->ks_opt_u.openssl_opts.certfile == NULL) {
782 		return (KMF_ERR_BAD_PARAMETER);
783 	}
784 
785 	/*
786 	 * check if the cert output format is supported by OPENSSL.
787 	 * however, since the keystore for OPENSSL is just a file, we have
788 	 * no way to store the format along with the file.
789 	 */
790 	format = params->sslparms.format;
791 	if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM)
792 		return (KMF_ERR_BAD_CERT_FORMAT);
793 
794 
795 	fullpath = get_fullpath(params->sslparms.dirpath,
796 		params->sslparms.certfile);
797 	if (fullpath == NULL)
798 		return (KMF_ERR_BAD_PARAMETER);
799 
800 	/*
801 	 * When storing a certificate, you must specify a filename.
802 	 */
803 	if (isdir(fullpath)) {
804 		free(fullpath);
805 		return (KMF_ERR_BAD_PARAMETER);
806 	}
807 
808 	/* copy cert data to outbuf */
809 	outbuflen = pcert->Length;
810 	outbuf = malloc(outbuflen);
811 	if (outbuf == NULL) {
812 		free(fullpath);
813 		return (KMF_ERR_MEMORY);
814 	}
815 	(void) memcpy(outbuf, pcert->Data, pcert->Length);
816 
817 	if ((fp = fopen(fullpath, "w")) ==
818 		NULL) {
819 		SET_SYS_ERROR(kmfh, errno);
820 		ret = KMF_ERR_INTERNAL;
821 		goto out;
822 	}
823 
824 	if (format == KMF_FORMAT_ASN1) {
825 		len = fwrite(outbuf, 1, outbuflen, fp);
826 		if (len != outbuflen) {
827 			SET_SYS_ERROR(kmfh, errno);
828 			ret = KMF_ERR_WRITE_FILE;
829 		} else {
830 			ret = KMF_OK;
831 		}
832 		goto out;
833 	}
834 
835 	/*
836 	 * The output format is not KMF_FORMAT_ASN1, so we will
837 	 * Convert the cert data to OpenSSL internal X509 first.
838 	 */
839 	outbuf_p = outbuf; /* use a temp pointer; required by openssl */
840 	xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, outbuflen);
841 	if (xcert == NULL) {
842 		SET_ERROR(kmfh, ERR_get_error());
843 		ret = KMF_ERR_ENCODING;
844 		goto out;
845 	}
846 
847 	if (format == KMF_FORMAT_PEM) {
848 		/* Convert to the PEM format and write it out */
849 		if (!PEM_write_X509(fp, xcert)) {
850 			SET_ERROR(kmfh, ERR_get_error());
851 			ret = KMF_ERR_ENCODING;
852 		} else {
853 			ret = KMF_OK;
854 		}
855 		goto out;
856 	}
857 
858 out:
859 	if (fullpath != NULL)
860 		free(fullpath);
861 
862 	if (outbuf != NULL) {
863 		free(outbuf);
864 	}
865 	if (fp != NULL) {
866 		(void) fclose(fp);
867 	}
868 
869 	if (xcert != NULL) {
870 		X509_free(xcert);
871 	}
872 
873 	return (ret);
874 }
875 
876 KMF_RETURN
877 OpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params)
878 {
879 	KMF_RETURN rv;
880 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
881 	char *fullpath = NULL;
882 	KMF_DATA certdata = {NULL, 0};
883 
884 	if (params == NULL) {
885 		return (KMF_ERR_BAD_PARAMETER);
886 	}
887 
888 	fullpath = get_fullpath(params->sslparms.dirpath,
889 		params->sslparms.certfile);
890 
891 	if (fullpath == NULL)
892 		return (KMF_ERR_BAD_PARAMETER);
893 
894 	if (isdir(fullpath)) {
895 		DIR *dirp;
896 		struct dirent *dp;
897 
898 		/* open all files in the directory and attempt to read them */
899 		if ((dirp = opendir(fullpath)) == NULL) {
900 			return (KMF_ERR_BAD_PARAMETER);
901 		}
902 
903 		while ((dp = readdir(dirp)) != NULL) {
904 			if (strcmp(dp->d_name, ".") != 0 &&
905 			    strcmp(dp->d_name, "..") != 0) {
906 				char *fname;
907 
908 				fname = get_fullpath(fullpath,
909 					(char *)&dp->d_name);
910 
911 				if (fname == NULL) {
912 					rv = KMF_ERR_MEMORY;
913 					break;
914 				}
915 
916 				rv = kmf_load_cert(kmfh, params, fname,
917 				    &certdata);
918 
919 				if (rv == KMF_ERR_CERT_NOT_FOUND) {
920 					free(fname);
921 					if (certdata.Data)
922 						free(certdata.Data);
923 					rv = KMF_OK;
924 					continue;
925 				} else if (rv != KMF_OK) {
926 					free(fname);
927 					break;
928 				}
929 
930 				if (unlink(fname) != 0) {
931 					SET_SYS_ERROR(kmfh, errno);
932 					rv = KMF_ERR_INTERNAL;
933 					free(fname);
934 					break;
935 				}
936 				free(fname);
937 				if (certdata.Data)
938 					free(certdata.Data);
939 			}
940 		}
941 		(void) closedir(dirp);
942 	} else {
943 		/* Just try to load a single certificate */
944 		rv = kmf_load_cert(kmfh, params, fullpath, &certdata);
945 		if (rv == KMF_OK) {
946 			if (unlink(fullpath) != 0) {
947 				SET_SYS_ERROR(kmfh, errno);
948 				rv = KMF_ERR_INTERNAL;
949 			}
950 		}
951 	}
952 
953 out:
954 	if (fullpath != NULL)
955 		free(fullpath);
956 
957 	if (certdata.Data)
958 		free(certdata.Data);
959 
960 	return (rv);
961 }
962 
963 KMF_RETURN
964 OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
965 	KMF_DATA *keydata)
966 {
967 	KMF_RETURN rv = KMF_OK;
968 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
969 	int n;
970 
971 	if (key == NULL || keydata == NULL ||
972 	    key->keyp == NULL)
973 		return (KMF_ERR_BAD_PARAMETER);
974 
975 	if (key->keyalg == KMF_RSA) {
976 		RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp);
977 
978 		if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) {
979 			SET_ERROR(kmfh, ERR_get_error());
980 			return (KMF_ERR_ENCODING);
981 		}
982 		RSA_free(pubkey);
983 	} else if (key->keyalg == KMF_DSA) {
984 		DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp);
985 
986 		if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) {
987 			SET_ERROR(kmfh, ERR_get_error());
988 			return (KMF_ERR_ENCODING);
989 		}
990 		DSA_free(pubkey);
991 	} else {
992 	    return (KMF_ERR_BAD_PARAMETER);
993 	}
994 	keydata->Length = n;
995 
996 cleanup:
997 	if (rv != KMF_OK) {
998 		if (keydata->Data)
999 			free(keydata->Data);
1000 		keydata->Data = NULL;
1001 		keydata->Length = 0;
1002 	}
1003 
1004 	return (rv);
1005 }
1006 
1007 static KMF_RETURN
1008 ssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out,
1009 	KMF_CREDENTIAL *cred, EVP_PKEY *pkey)
1010 {
1011 	int rv = 0;
1012 	RSA *rsa;
1013 	DSA *dsa;
1014 
1015 	switch (format) {
1016 		case KMF_FORMAT_ASN1:
1017 			if (pkey->type == EVP_PKEY_RSA) {
1018 				rsa = EVP_PKEY_get1_RSA(pkey);
1019 				rv = i2d_RSAPrivateKey_bio(out, rsa);
1020 				RSA_free(rsa);
1021 			} else if (pkey->type == EVP_PKEY_DSA) {
1022 				dsa = EVP_PKEY_get1_DSA(pkey);
1023 				rv = i2d_DSAPrivateKey_bio(out, dsa);
1024 				DSA_free(dsa);
1025 			}
1026 			if (rv == 1) {
1027 				rv = KMF_OK;
1028 			} else {
1029 				SET_ERROR(kmfh, rv);
1030 			}
1031 			break;
1032 		case KMF_FORMAT_PEM:
1033 			if (pkey->type == EVP_PKEY_RSA) {
1034 				rsa = EVP_PKEY_get1_RSA(pkey);
1035 				rv = PEM_write_bio_RSAPrivateKey(out,
1036 					rsa,
1037 					NULL /* encryption type */,
1038 					NULL, 0, NULL,
1039 					cred->cred);
1040 				RSA_free(rsa);
1041 			} else if (pkey->type == EVP_PKEY_DSA) {
1042 				dsa = EVP_PKEY_get1_DSA(pkey);
1043 				rv = PEM_write_bio_DSAPrivateKey(out,
1044 					dsa,
1045 					NULL /* encryption type */,
1046 					NULL, 0, NULL,
1047 					cred->cred);
1048 				DSA_free(dsa);
1049 			}
1050 
1051 			if (rv == 1) {
1052 				rv = KMF_OK;
1053 			} else {
1054 				SET_ERROR(kmfh, rv);
1055 			}
1056 			break;
1057 
1058 		default:
1059 			rv = KMF_ERR_BAD_PARAMETER;
1060 	}
1061 
1062 	return (rv);
1063 }
1064 
1065 KMF_RETURN
1066 OpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params,
1067 	KMF_KEY_HANDLE *privkey, KMF_KEY_HANDLE *pubkey)
1068 {
1069 	KMF_RETURN rv = KMF_OK;
1070 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1071 	int format;
1072 	uint32_t eValue = 0x010001;
1073 	RSA *sslPrivKey = NULL;
1074 	DSA *sslDSAKey = NULL;
1075 	EVP_PKEY *eprikey = NULL;
1076 	EVP_PKEY *epubkey = NULL;
1077 	BIO *out = NULL;
1078 	char *fullpath = NULL;
1079 
1080 	if (params == NULL || params->sslparms.keyfile == NULL) {
1081 		return (KMF_ERR_BAD_PARAMETER);
1082 	}
1083 
1084 	fullpath = get_fullpath(params->sslparms.dirpath,
1085 			params->sslparms.keyfile);
1086 
1087 	if (fullpath == NULL)
1088 		return (KMF_ERR_BAD_PARAMETER);
1089 
1090 	/* If the requested file exists, return an error */
1091 	if (access(fullpath, F_OK) == 0) {
1092 		free(fullpath);
1093 		return (KMF_ERR_DUPLICATE_KEYFILE);
1094 	}
1095 
1096 	eprikey = EVP_PKEY_new();
1097 	if (eprikey == NULL) {
1098 		SET_ERROR(kmfh, ERR_get_error());
1099 		rv = KMF_ERR_KEYGEN_FAILED;
1100 		goto cleanup;
1101 	}
1102 	epubkey = EVP_PKEY_new();
1103 	if (epubkey == NULL) {
1104 		SET_ERROR(kmfh, ERR_get_error());
1105 		rv = KMF_ERR_KEYGEN_FAILED;
1106 		goto cleanup;
1107 	}
1108 	if (params->keytype == KMF_RSA) {
1109 		if (params->rsa_exponent.len > 0 &&
1110 		    params->rsa_exponent.len <= sizeof (eValue) &&
1111 		    params->rsa_exponent.val != NULL)
1112 			/*LINTED*/
1113 			eValue = *(uint32_t *)params->rsa_exponent.val;
1114 
1115 		sslPrivKey = RSA_generate_key(params->keylength, eValue,
1116 			NULL, NULL);
1117 		if (sslPrivKey == NULL) {
1118 			SET_ERROR(kmfh, ERR_get_error());
1119 			rv = KMF_ERR_KEYGEN_FAILED;
1120 		} else {
1121 			if (privkey != NULL &&
1122 				EVP_PKEY_set1_RSA(eprikey, sslPrivKey)) {
1123 				privkey->kstype = KMF_KEYSTORE_OPENSSL;
1124 				privkey->keyalg = KMF_RSA;
1125 				privkey->keyclass = KMF_ASYM_PRI;
1126 				privkey->israw = FALSE;
1127 				privkey->keylabel = (char *)strdup(fullpath);
1128 				privkey->keyp = (void *)eprikey;
1129 			}
1130 			/* OpenSSL derives the public key from the private */
1131 			if (pubkey != NULL &&
1132 				EVP_PKEY_set1_RSA(epubkey, sslPrivKey)) {
1133 				pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1134 				pubkey->keyalg = KMF_RSA;
1135 				pubkey->israw = FALSE;
1136 				pubkey->keyclass = KMF_ASYM_PUB;
1137 				pubkey->keylabel = (char *)strdup(fullpath);
1138 				pubkey->keyp = (void *)epubkey;
1139 			}
1140 		}
1141 	} else if (params->keytype == KMF_DSA) {
1142 		sslDSAKey = DSA_new();
1143 		if (sslDSAKey == NULL) {
1144 			SET_ERROR(kmfh, ERR_get_error());
1145 			return (KMF_ERR_MEMORY);
1146 		}
1147 
1148 		if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) ==
1149 			NULL) {
1150 			SET_ERROR(kmfh, ERR_get_error());
1151 			rv = KMF_ERR_KEYGEN_FAILED;
1152 			goto cleanup;
1153 		}
1154 		if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) ==
1155 			NULL) {
1156 			SET_ERROR(kmfh, ERR_get_error());
1157 			rv = KMF_ERR_KEYGEN_FAILED;
1158 			goto cleanup;
1159 		}
1160 		if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) ==
1161 			NULL) {
1162 			SET_ERROR(kmfh, ERR_get_error());
1163 			rv = KMF_ERR_KEYGEN_FAILED;
1164 			goto cleanup;
1165 		}
1166 
1167 		if (!DSA_generate_key(sslDSAKey)) {
1168 			SET_ERROR(kmfh, ERR_get_error());
1169 			rv = KMF_ERR_KEYGEN_FAILED;
1170 			goto cleanup;
1171 		}
1172 
1173 		if (privkey != NULL) {
1174 			privkey->kstype = KMF_KEYSTORE_OPENSSL;
1175 			privkey->keyalg = KMF_DSA;
1176 			privkey->keyclass = KMF_ASYM_PRI;
1177 			privkey->israw = FALSE;
1178 			privkey->keylabel = (char *)strdup(fullpath);
1179 			if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) {
1180 				privkey->keyp = (void *)eprikey;
1181 			} else {
1182 				SET_ERROR(kmfh, ERR_get_error());
1183 				rv = KMF_ERR_KEYGEN_FAILED;
1184 				goto cleanup;
1185 			}
1186 		}
1187 		if (pubkey != NULL) {
1188 			DSA *dp = DSA_new();
1189 			/* Make a copy for the public key */
1190 			if (dp != NULL) {
1191 				if ((dp->p = BN_new()) == NULL) {
1192 					SET_ERROR(kmfh, ERR_get_error());
1193 					rv = KMF_ERR_MEMORY;
1194 					DSA_free(dp);
1195 					goto cleanup;
1196 				}
1197 				if ((dp->q = BN_new()) == NULL) {
1198 					SET_ERROR(kmfh, ERR_get_error());
1199 					rv = KMF_ERR_MEMORY;
1200 					BN_free(dp->p);
1201 					DSA_free(dp);
1202 					goto cleanup;
1203 				}
1204 				if ((dp->g = BN_new()) == NULL) {
1205 					SET_ERROR(kmfh, ERR_get_error());
1206 					rv = KMF_ERR_MEMORY;
1207 					BN_free(dp->q);
1208 					BN_free(dp->p);
1209 					DSA_free(dp);
1210 					goto cleanup;
1211 				}
1212 				if ((dp->pub_key = BN_new()) == NULL) {
1213 					SET_ERROR(kmfh, ERR_get_error());
1214 					rv = KMF_ERR_MEMORY;
1215 					BN_free(dp->q);
1216 					BN_free(dp->p);
1217 					BN_free(dp->g);
1218 					DSA_free(dp);
1219 					goto cleanup;
1220 				}
1221 				(void) BN_copy(dp->p, sslDSAKey->p);
1222 				(void) BN_copy(dp->q, sslDSAKey->q);
1223 				(void) BN_copy(dp->g, sslDSAKey->g);
1224 				(void) BN_copy(dp->pub_key, sslDSAKey->pub_key);
1225 
1226 				pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1227 				pubkey->keyalg = KMF_DSA;
1228 				pubkey->keyclass = KMF_ASYM_PUB;
1229 				pubkey->israw = FALSE;
1230 				pubkey->keylabel = (char *)strdup(fullpath);
1231 
1232 				if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) {
1233 					pubkey->keyp = (void *)epubkey;
1234 				} else {
1235 					SET_ERROR(kmfh, ERR_get_error());
1236 					rv = KMF_ERR_KEYGEN_FAILED;
1237 					goto cleanup;
1238 				}
1239 			}
1240 		}
1241 	}
1242 
1243 	if (rv != KMF_OK) {
1244 		goto cleanup;
1245 	}
1246 
1247 	/* Store the private key to the keyfile */
1248 	format = params->sslparms.format;
1249 	out = BIO_new_file(fullpath, "wb");
1250 	if (out == NULL) {
1251 		SET_ERROR(kmfh, ERR_get_error());
1252 		rv = KMF_ERR_OPEN_FILE;
1253 		goto cleanup;
1254 	}
1255 	rv = ssl_write_private_key(kmfh, format, out, &params->cred, eprikey);
1256 
1257 cleanup:
1258 	if (rv != KMF_OK) {
1259 		if (eprikey != NULL)
1260 			EVP_PKEY_free(eprikey);
1261 
1262 		if (epubkey != NULL)
1263 			EVP_PKEY_free(epubkey);
1264 
1265 		if (pubkey->keylabel) {
1266 			free(pubkey->keylabel);
1267 			pubkey->keylabel = NULL;
1268 		}
1269 
1270 		if (privkey->keylabel) {
1271 			free(privkey->keylabel);
1272 			privkey->keylabel = NULL;
1273 		}
1274 
1275 		pubkey->keyp = NULL;
1276 		privkey->keyp = NULL;
1277 	}
1278 
1279 	if (sslPrivKey)
1280 		RSA_free(sslPrivKey);
1281 
1282 	if (sslDSAKey)
1283 		DSA_free(sslDSAKey);
1284 
1285 
1286 	if (out != NULL)
1287 		(void) BIO_free(out);
1288 
1289 	if (fullpath)
1290 		free(fullpath);
1291 
1292 	/* Protect the file by making it read-only */
1293 	if (rv == KMF_OK) {
1294 		(void) chmod(fullpath, 0400);
1295 	}
1296 	return (rv);
1297 }
1298 
1299 KMF_RETURN
1300 OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
1301 	KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output)
1302 {
1303 	KMF_RETURN ret = KMF_OK;
1304 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1305 	KMF_ALGORITHM_INDEX		AlgId;
1306 	EVP_MD_CTX ctx;
1307 	const EVP_MD *md;
1308 	if (key == NULL || AlgOID == NULL ||
1309 		tobesigned == NULL || output == NULL ||
1310 		tobesigned->Data == NULL ||
1311 		output->Data == NULL)
1312 		return (KMF_ERR_BAD_PARAMETER);
1313 
1314 	/* Map the OID to an OpenSSL algorithm */
1315 	AlgId = X509_AlgorithmOidToAlgId(AlgOID);
1316 	if (AlgId == KMF_ALGID_NONE)
1317 		return (KMF_ERR_BAD_PARAMETER);
1318 
1319 	if (key->keyalg == KMF_RSA) {
1320 		EVP_PKEY *pkey = (EVP_PKEY *)key->keyp;
1321 		uchar_t *p;
1322 		uint32_t len;
1323 		if (AlgId == KMF_ALGID_MD5WithRSA)
1324 			md = EVP_md5();
1325 		else if (AlgId == KMF_ALGID_MD2WithRSA)
1326 			md = EVP_md2();
1327 		else if (AlgId == KMF_ALGID_SHA1WithRSA)
1328 			md = EVP_sha1();
1329 		else
1330 			return (KMF_ERR_BAD_PARAMETER);
1331 
1332 		if (md == NULL) {
1333 			SET_ERROR(kmfh, ERR_get_error());
1334 			return (KMF_ERR_MEMORY);
1335 		}
1336 
1337 		(void) EVP_MD_CTX_init(&ctx);
1338 		(void) EVP_SignInit_ex(&ctx, md, NULL);
1339 		(void) EVP_SignUpdate(&ctx, tobesigned->Data,
1340 			(uint32_t)tobesigned->Length);
1341 		len = (uint32_t)output->Length;
1342 		p = output->Data;
1343 		if (!EVP_SignFinal(&ctx, p, &len, pkey)) {
1344 			SET_ERROR(kmfh, ERR_get_error());
1345 			output->Length = 0;
1346 		}
1347 		output->Length = len;
1348 		(void) EVP_MD_CTX_cleanup(&ctx);
1349 	} else if (key->keyalg == KMF_DSA) {
1350 		DSA *dsa = EVP_PKEY_get1_DSA(key->keyp);
1351 
1352 		uchar_t hash[EVP_MAX_MD_SIZE];
1353 		uint32_t hashlen;
1354 		DSA_SIG *dsasig;
1355 
1356 		/*
1357 		 * OpenSSL EVP_Sign operation automatically converts to
1358 		 * ASN.1 output so we do the operations separately so we
1359 		 * are assured of NOT getting ASN.1 output returned.
1360 		 * KMF does not want ASN.1 encoded results because
1361 		 * not all mechanisms return ASN.1 encodings (PKCS#11
1362 		 * and NSS return raw signature data).
1363 		 */
1364 		md = EVP_sha1();
1365 		EVP_MD_CTX_init(&ctx);
1366 		(void) EVP_DigestInit_ex(&ctx, md, NULL);
1367 		(void) EVP_DigestUpdate(&ctx, tobesigned->Data,
1368 			tobesigned->Length);
1369 		(void) EVP_DigestFinal_ex(&ctx, hash, &hashlen);
1370 		(void) EVP_MD_CTX_cleanup(&ctx);
1371 
1372 		dsasig = DSA_do_sign(hash, hashlen, dsa);
1373 		if (dsasig != NULL) {
1374 			int i;
1375 			output->Length = i = BN_bn2bin(dsasig->r, output->Data);
1376 			output->Length += BN_bn2bin(dsasig->s,
1377 				&output->Data[i]);
1378 			DSA_SIG_free(dsasig);
1379 		} else {
1380 			SET_ERROR(kmfh, ERR_get_error());
1381 		}
1382 	} else {
1383 		return (KMF_ERR_BAD_PARAMETER);
1384 	}
1385 cleanup:
1386 	return (ret);
1387 }
1388 
1389 KMF_RETURN
1390 /*ARGSUSED*/
1391 OpenSSL_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params,
1392 	KMF_KEY_HANDLE *key, boolean_t destroy)
1393 {
1394 	KMF_RETURN rv = KMF_OK;
1395 	if (key == NULL || key->keyp == NULL)
1396 		return (KMF_ERR_BAD_PARAMETER);
1397 
1398 	if (key->keyclass != KMF_ASYM_PUB &&
1399 		key->keyclass != KMF_ASYM_PRI &&
1400 		key->keyclass != KMF_SYMMETRIC)
1401 		return (KMF_ERR_BAD_KEY_CLASS);
1402 
1403 	if (key->keyclass == KMF_SYMMETRIC) {
1404 		KMF_FreeRawSymKey((KMF_RAW_SYM_KEY *)key->keyp);
1405 		key->keyp = NULL;
1406 	} else {
1407 		if (key->keyp != NULL) {
1408 			EVP_PKEY_free(key->keyp);
1409 			key->keyp = NULL;
1410 		}
1411 	}
1412 
1413 	if (key->keylabel != NULL) {
1414 		EVP_PKEY *pkey = NULL;
1415 		/* If the file exists, make sure it is a proper key. */
1416 		pkey = openssl_load_key(handle, key->keylabel);
1417 		if (pkey == NULL) {
1418 			free(key->keylabel);
1419 			key->keylabel = NULL;
1420 			return (KMF_ERR_KEY_NOT_FOUND);
1421 		}
1422 		EVP_PKEY_free(pkey);
1423 
1424 		if (destroy) {
1425 			if (unlink(key->keylabel) != 0) {
1426 				KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1427 				SET_SYS_ERROR(kmfh, errno);
1428 				rv = KMF_ERR_INTERNAL;
1429 			}
1430 		}
1431 		if (key->keylabel != NULL) {
1432 			free(key->keylabel);
1433 			key->keylabel = NULL;
1434 		}
1435 	}
1436 	return (rv);
1437 }
1438 
1439 KMF_RETURN
1440 OpenSSL_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params)
1441 {
1442 	KMF_RETURN 	ret = KMF_OK;
1443 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1444 	X509_CRL   	*xcrl = NULL;
1445 	X509		*xcert = NULL;
1446 	EVP_PKEY	*pkey;
1447 	KMF_ENCODE_FORMAT format;
1448 	BIO *in = NULL, *out = NULL;
1449 	int openssl_ret = 0;
1450 	char *outcrlfile = NULL;
1451 	KMF_ENCODE_FORMAT outformat;
1452 
1453 	if (params == NULL || params->sslparms.crlfile == NULL) {
1454 		return (KMF_ERR_BAD_PARAMETER);
1455 	}
1456 
1457 	if (params->sslparms.crl_check == B_TRUE &&
1458 	    params->sslparms.certfile == NULL) {
1459 		return (KMF_ERR_BAD_PARAMETER);
1460 	}
1461 
1462 	outcrlfile = get_fullpath(params->sslparms.dirpath,
1463 		params->sslparms.outcrlfile);
1464 
1465 	if (outcrlfile == NULL)
1466 		return (KMF_ERR_BAD_PARAMETER);
1467 
1468 	if (isdir(outcrlfile)) {
1469 		free(outcrlfile);
1470 		return (KMF_ERR_BAD_PARAMETER);
1471 	}
1472 
1473 	ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format);
1474 	if (ret != KMF_OK) {
1475 		free(outcrlfile);
1476 		return (ret);
1477 	}
1478 
1479 	in = BIO_new_file(params->sslparms.crlfile, "rb");
1480 	if (in == NULL)	{
1481 		SET_ERROR(kmfh, ERR_get_error());
1482 		ret = KMF_ERR_OPEN_FILE;
1483 		goto end;
1484 	}
1485 
1486 	if (format == KMF_FORMAT_ASN1) {
1487 		xcrl = d2i_X509_CRL_bio(in, NULL);
1488 	} else if (format == KMF_FORMAT_PEM) {
1489 		xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
1490 	}
1491 
1492 	if (xcrl == NULL) {
1493 		SET_ERROR(kmfh, ERR_get_error());
1494 		ret = KMF_ERR_BAD_CRLFILE;
1495 		goto end;
1496 	}
1497 
1498 	/* If bypasscheck is specified, no need to verify. */
1499 	if (params->sslparms.crl_check == B_FALSE) {
1500 		goto output;
1501 	}
1502 
1503 	ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format);
1504 	if (ret != KMF_OK)
1505 		goto end;
1506 
1507 	/* Read in the CA cert file and convert to X509 */
1508 	if (BIO_read_filename(in, params->sslparms.certfile) <= 0) {
1509 		SET_ERROR(kmfh, ERR_get_error());
1510 		ret = KMF_ERR_OPEN_FILE;
1511 		goto end;
1512 	}
1513 
1514 	if (format == KMF_FORMAT_ASN1) {
1515 		xcert = d2i_X509_bio(in, NULL);
1516 	} else if (format == KMF_FORMAT_PEM) {
1517 		xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
1518 	} else {
1519 		ret = KMF_ERR_BAD_CERT_FORMAT;
1520 		goto end;
1521 	}
1522 
1523 	if (xcert == NULL) {
1524 		SET_ERROR(kmfh, ERR_get_error());
1525 		ret = KMF_ERR_BAD_CERT_FORMAT;
1526 		goto end;
1527 	}
1528 	/* Now get the public key from the CA cert */
1529 	pkey = X509_get_pubkey(xcert);
1530 	if (!pkey) {
1531 		SET_ERROR(kmfh, ERR_get_error());
1532 		ret = KMF_ERR_BAD_CERTFILE;
1533 		goto end;
1534 	}
1535 
1536 	/* Verify the CRL with the CA's public key */
1537 	openssl_ret = X509_CRL_verify(xcrl, pkey);
1538 	EVP_PKEY_free(pkey);
1539 	if (openssl_ret > 0) {
1540 		ret = KMF_OK;  /* verify succeed */
1541 	} else {
1542 		SET_ERROR(kmfh, openssl_ret);
1543 		ret = KMF_ERR_BAD_CRLFILE;
1544 	}
1545 
1546 output:
1547 	outformat = params->sslparms.format;
1548 
1549 	out = BIO_new_file(outcrlfile, "wb");
1550 	if (out == NULL) {
1551 		SET_ERROR(kmfh, ERR_get_error());
1552 		ret = KMF_ERR_OPEN_FILE;
1553 		goto end;
1554 	}
1555 
1556 	if (outformat == KMF_FORMAT_ASN1) {
1557 		openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl);
1558 	} else if (outformat == KMF_FORMAT_PEM) {
1559 		openssl_ret = PEM_write_bio_X509_CRL(out, xcrl);
1560 	} else {
1561 		ret = KMF_ERR_BAD_PARAMETER;
1562 		goto end;
1563 	}
1564 
1565 	if (openssl_ret <= 0) {
1566 		SET_ERROR(kmfh, ERR_get_error());
1567 		ret = KMF_ERR_WRITE_FILE;
1568 	} else {
1569 		ret = KMF_OK;
1570 	}
1571 
1572 end:
1573 	if (xcrl != NULL)
1574 		X509_CRL_free(xcrl);
1575 
1576 	if (xcert != NULL)
1577 		X509_free(xcert);
1578 
1579 	if (in != NULL)
1580 		(void) BIO_free(in);
1581 
1582 	if (out != NULL)
1583 		(void) BIO_free(out);
1584 
1585 	if (outcrlfile != NULL)
1586 		free(outcrlfile);
1587 
1588 	return (ret);
1589 }
1590 
1591 KMF_RETURN
1592 OpenSSL_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params,
1593     char **crldata)
1594 {
1595 	KMF_RETURN ret = KMF_OK;
1596 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1597 	X509_CRL   *x = NULL;
1598 	KMF_ENCODE_FORMAT format;
1599 	char *crlfile = NULL;
1600 	BIO *in = NULL;
1601 	BIO *mem = NULL;
1602 	long len;
1603 	char *memptr;
1604 	char *data = NULL;
1605 
1606 	if (params == NULL || params->sslparms.crlfile == NULL) {
1607 		return (KMF_ERR_BAD_PARAMETER);
1608 	}
1609 
1610 	crlfile = get_fullpath(params->sslparms.dirpath,
1611 		params->sslparms.crlfile);
1612 
1613 	if (crlfile == NULL)
1614 		return (KMF_ERR_BAD_PARAMETER);
1615 
1616 	if (isdir(crlfile)) {
1617 		free(crlfile);
1618 		return (KMF_ERR_BAD_PARAMETER);
1619 	}
1620 
1621 	ret = KMF_IsCRLFile(handle, crlfile, &format);
1622 	if (ret != KMF_OK) {
1623 		free(crlfile);
1624 		return (ret);
1625 	}
1626 
1627 	if (bio_err == NULL)
1628 		bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
1629 
1630 	in = BIO_new_file(crlfile, "rb");
1631 	if (in == NULL)	{
1632 		SET_ERROR(kmfh, ERR_get_error());
1633 		ret = KMF_ERR_OPEN_FILE;
1634 		goto end;
1635 	}
1636 
1637 	if (format == KMF_FORMAT_ASN1) {
1638 		x = d2i_X509_CRL_bio(in, NULL);
1639 	} else if (format == KMF_FORMAT_PEM) {
1640 		x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
1641 	}
1642 
1643 	if (x == NULL) { /* should not happen */
1644 		SET_ERROR(kmfh, ERR_get_error());
1645 		ret = KMF_ERR_OPEN_FILE;
1646 		goto end;
1647 	}
1648 
1649 	mem = BIO_new(BIO_s_mem());
1650 	if (mem == NULL) {
1651 		SET_ERROR(kmfh, ERR_get_error());
1652 		ret = KMF_ERR_MEMORY;
1653 		goto end;
1654 	}
1655 
1656 	(void) X509_CRL_print(mem, x);
1657 	len = BIO_get_mem_data(mem, &memptr);
1658 	if (len <= 0) {
1659 		SET_ERROR(kmfh, ERR_get_error());
1660 		ret = KMF_ERR_MEMORY;
1661 		goto end;
1662 	}
1663 
1664 	data = malloc(len + 1);
1665 	if (data == NULL) {
1666 		ret = KMF_ERR_MEMORY;
1667 		goto end;
1668 	}
1669 
1670 	(void) memcpy(data, memptr, len);
1671 	data[len] = '\0';
1672 	*crldata = data;
1673 
1674 end:
1675 	if (x != NULL)
1676 		X509_CRL_free(x);
1677 
1678 	if (crlfile != NULL)
1679 		free(crlfile);
1680 
1681 	if (in != NULL)
1682 		(void) BIO_free(in);
1683 
1684 	if (mem != NULL)
1685 		(void) BIO_free(mem);
1686 
1687 	return (ret);
1688 }
1689 
1690 KMF_RETURN
1691 OpenSSL_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params)
1692 {
1693 	KMF_RETURN ret = KMF_OK;
1694 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1695 	KMF_ENCODE_FORMAT format;
1696 	char *crlfile = NULL;
1697 	BIO *in = NULL;
1698 
1699 	if (params == NULL || params->sslparms.crlfile == NULL) {
1700 		return (KMF_ERR_BAD_PARAMETER);
1701 	}
1702 
1703 	crlfile = get_fullpath(params->sslparms.dirpath,
1704 		params->sslparms.crlfile);
1705 
1706 	if (crlfile == NULL)
1707 		return (KMF_ERR_BAD_PARAMETER);
1708 
1709 	if (isdir(crlfile)) {
1710 		ret = KMF_ERR_BAD_PARAMETER;
1711 		goto end;
1712 	}
1713 
1714 	ret = KMF_IsCRLFile(handle, crlfile, &format);
1715 	if (ret != KMF_OK)
1716 		goto end;
1717 
1718 	if (unlink(crlfile) != 0) {
1719 		SET_SYS_ERROR(kmfh, errno);
1720 		ret = KMF_ERR_INTERNAL;
1721 		goto end;
1722 	}
1723 
1724 end:
1725 	if (in != NULL)
1726 		(void) BIO_free(in);
1727 	if (crlfile != NULL)
1728 		free(crlfile);
1729 
1730 	return (ret);
1731 }
1732 
1733 
1734 KMF_RETURN
1735 OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params)
1736 {
1737 	KMF_RETURN ret = KMF_OK;
1738 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1739 	KMF_ENCODE_FORMAT format;
1740 	BIO *in = NULL;
1741 	X509   *xcert = NULL;
1742 	X509_CRL   *xcrl = NULL;
1743 	STACK_OF(X509_REVOKED) *revoke_stack = NULL;
1744 	X509_REVOKED *revoke;
1745 	int i;
1746 
1747 	if (params == NULL || params->sslparms.crlfile == NULL ||
1748 	    params->sslparms.certfile == NULL) {
1749 		return (KMF_ERR_BAD_PARAMETER);
1750 	}
1751 
1752 	ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format);
1753 	if (ret != KMF_OK)
1754 		return (ret);
1755 
1756 	/* Read the CRL file and load it into a X509_CRL structure */
1757 	in = BIO_new_file(params->sslparms.crlfile, "rb");
1758 	if (in == NULL)	{
1759 		SET_ERROR(kmfh, ERR_get_error());
1760 		ret = KMF_ERR_OPEN_FILE;
1761 		goto end;
1762 	}
1763 
1764 	if (format == KMF_FORMAT_ASN1) {
1765 		xcrl = d2i_X509_CRL_bio(in, NULL);
1766 	} else if (format == KMF_FORMAT_PEM) {
1767 		xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
1768 	}
1769 
1770 	if (xcrl == NULL) {
1771 		SET_ERROR(kmfh, ERR_get_error());
1772 		ret = KMF_ERR_BAD_CRLFILE;
1773 		goto end;
1774 	}
1775 	(void) BIO_free(in);
1776 
1777 	/* Read the Certificate file and load it into a X509 structure */
1778 	ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format);
1779 	if (ret != KMF_OK)
1780 		goto end;
1781 
1782 	in = BIO_new_file(params->sslparms.certfile, "rb");
1783 	if (in == NULL)	{
1784 		SET_ERROR(kmfh, ERR_get_error());
1785 		ret = KMF_ERR_OPEN_FILE;
1786 		goto end;
1787 	}
1788 
1789 	if (format == KMF_FORMAT_ASN1) {
1790 		xcert = d2i_X509_bio(in, NULL);
1791 	} else if (format == KMF_FORMAT_PEM) {
1792 		xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
1793 	}
1794 
1795 	if (xcert == NULL) {
1796 		SET_ERROR(kmfh, ERR_get_error());
1797 		ret = KMF_ERR_BAD_CERTFILE;
1798 		goto end;
1799 	}
1800 
1801 	/* Check if the certificate and the CRL have same issuer */
1802 	if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) {
1803 		ret = KMF_ERR_ISSUER;
1804 		goto end;
1805 	}
1806 
1807 	/* Check to see if the certificate serial number is revoked */
1808 	revoke_stack = X509_CRL_get_REVOKED(xcrl);
1809 	if (sk_X509_REVOKED_num(revoke_stack) <= 0) {
1810 		/* No revoked certificates in the CRL file */
1811 		SET_ERROR(kmfh, ERR_get_error());
1812 		ret = KMF_ERR_EMPTY_CRL;
1813 		goto end;
1814 	}
1815 
1816 	for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) {
1817 		/*LINTED*/
1818 		revoke = sk_X509_REVOKED_value(revoke_stack, i);
1819 		if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber,
1820 		    revoke->serialNumber) == 0) {
1821 			break;
1822 		}
1823 	}
1824 
1825 	if (i < sk_X509_REVOKED_num(revoke_stack)) {
1826 		ret = KMF_OK;
1827 	} else {
1828 		ret = KMF_ERR_NOT_REVOKED;
1829 	}
1830 
1831 end:
1832 	if (in != NULL)
1833 		(void) BIO_free(in);
1834 	if (xcrl != NULL)
1835 		X509_CRL_free(xcrl);
1836 	if (xcert != NULL)
1837 		X509_free(xcert);
1838 
1839 	return (ret);
1840 }
1841 
1842 KMF_RETURN
1843 OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
1844 {
1845 	KMF_RETURN ret = KMF_OK;
1846 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1847 	char str[256];	/* OpenSSL needs at least 120 byte buffer */
1848 
1849 	ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str));
1850 	if (strlen(str)) {
1851 		*msgstr = (char *)strdup(str);
1852 		if ((*msgstr) == NULL)
1853 			ret = KMF_ERR_MEMORY;
1854 	} else {
1855 		*msgstr = NULL;
1856 	}
1857 
1858 	return (ret);
1859 }
1860 
1861 static int
1862 ext2NID(int kmfext)
1863 {
1864 	switch (kmfext) {
1865 		case KMF_X509_EXT_KEY_USAGE:
1866 			return (NID_key_usage);
1867 		case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
1868 			return (NID_private_key_usage_period);
1869 		case KMF_X509_EXT_CERT_POLICIES:
1870 			return (NID_certificate_policies);
1871 		case KMF_X509_EXT_SUBJ_ALTNAME:
1872 			return (NID_subject_alt_name);
1873 		case KMF_X509_EXT_ISSUER_ALTNAME:
1874 			return (NID_issuer_alt_name);
1875 		case KMF_X509_EXT_BASIC_CONSTRAINTS:
1876 			return (NID_basic_constraints);
1877 		case KMF_X509_EXT_EXT_KEY_USAGE:
1878 			return (NID_ext_key_usage);
1879 		case KMF_X509_EXT_AUTH_KEY_ID:
1880 			return (NID_authority_key_identifier);
1881 		case KMF_X509_EXT_CRL_DIST_POINTS:
1882 			return (NID_crl_distribution_points);
1883 		case KMF_X509_EXT_SUBJ_KEY_ID:
1884 			return (NID_subject_key_identifier);
1885 		case KMF_X509_EXT_POLICY_MAPPINGS:
1886 			return (OBJ_sn2nid("policyMappings"));
1887 		case KMF_X509_EXT_NAME_CONSTRAINTS:
1888 			return (OBJ_sn2nid("nameConstraints"));
1889 		case KMF_X509_EXT_POLICY_CONSTRAINTS:
1890 			return (OBJ_sn2nid("policyConstraints"));
1891 		case KMF_X509_EXT_INHIBIT_ANY_POLICY:
1892 			return (OBJ_sn2nid("inhibitAnyPolicy"));
1893 		case KMF_X509_EXT_FRESHEST_CRL:
1894 			return (OBJ_sn2nid("freshestCRL"));
1895 		default:
1896 			return (NID_undef);
1897 	}
1898 }
1899 
1900 KMF_RETURN
1901 OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert,
1902 	KMF_PRINTABLE_ITEM flag, char *resultStr)
1903 {
1904 	KMF_RETURN ret = KMF_OK;
1905 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1906 	X509 *xcert = NULL;
1907 	unsigned char *outbuf = NULL;
1908 	unsigned char *outbuf_p;
1909 	char *tmpstr = NULL;
1910 	int j;
1911 	int ext_index, nid, len;
1912 	BIO *mem = NULL;
1913 	STACK *emlst = NULL;
1914 	X509_EXTENSION *ex;
1915 	X509_CINF *ci;
1916 
1917 	if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) {
1918 		return (KMF_ERR_BAD_PARAMETER);
1919 	}
1920 
1921 	/* copy cert data to outbuf */
1922 	outbuf = malloc(pcert->Length);
1923 	if (outbuf == NULL) {
1924 		return (KMF_ERR_MEMORY);
1925 	}
1926 	(void) memcpy(outbuf, pcert->Data, pcert->Length);
1927 
1928 	outbuf_p = outbuf; /* use a temp pointer; required by openssl */
1929 	xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length);
1930 	if (xcert == NULL) {
1931 		SET_ERROR(kmfh, ERR_get_error());
1932 		ret = KMF_ERR_ENCODING;
1933 		goto out;
1934 	}
1935 
1936 	mem = BIO_new(BIO_s_mem());
1937 	if (mem == NULL) {
1938 		SET_ERROR(kmfh, ERR_get_error());
1939 		ret = KMF_ERR_MEMORY;
1940 		goto out;
1941 	}
1942 
1943 	switch (flag) {
1944 	case KMF_CERT_ISSUER:
1945 		(void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0,
1946 		    XN_FLAG_SEP_CPLUS_SPC);
1947 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
1948 		break;
1949 
1950 	case KMF_CERT_SUBJECT:
1951 		(void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0,
1952 		    XN_FLAG_SEP_CPLUS_SPC);
1953 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
1954 		break;
1955 
1956 	case KMF_CERT_VERSION:
1957 		tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version);
1958 		(void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN);
1959 		OPENSSL_free(tmpstr);
1960 		len = strlen(resultStr);
1961 		break;
1962 
1963 	case KMF_CERT_SERIALNUM:
1964 		if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) {
1965 			(void) strcpy(resultStr, "0x");
1966 			len = BIO_gets(mem, &resultStr[2],
1967 				KMF_CERT_PRINTABLE_LEN - 2);
1968 		}
1969 		break;
1970 
1971 	case KMF_CERT_NOTBEFORE:
1972 		(void) ASN1_TIME_print(mem, X509_get_notBefore(xcert));
1973 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
1974 		break;
1975 
1976 	case KMF_CERT_NOTAFTER:
1977 		(void) ASN1_TIME_print(mem, X509_get_notAfter(xcert));
1978 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
1979 		break;
1980 
1981 	case KMF_CERT_PUBKEY_DATA:
1982 		{
1983 			EVP_PKEY *pkey = X509_get_pubkey(xcert);
1984 			if (pkey == NULL) {
1985 				SET_ERROR(kmfh, ERR_get_error());
1986 				ret = KMF_ERR_ENCODING;
1987 				goto out;
1988 			}
1989 
1990 			if (pkey->type == EVP_PKEY_RSA) {
1991 				(void) BIO_printf(mem,
1992 					"RSA Public Key: (%d bit)\n",
1993 					BN_num_bits(pkey->pkey.rsa->n));
1994 				(void) RSA_print(mem, pkey->pkey.rsa, 0);
1995 			} else if (pkey->type == EVP_PKEY_DSA) {
1996 				(void) BIO_printf(mem,
1997 					"%12sDSA Public Key:\n", "");
1998 				(void) DSA_print(mem, pkey->pkey.dsa, 0);
1999 			} else {
2000 				(void) BIO_printf(mem,
2001 					"%12sUnknown Public Key:\n", "");
2002 			}
2003 			(void) BIO_printf(mem, "\n");
2004 			EVP_PKEY_free(pkey);
2005 		}
2006 		len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2007 		break;
2008 	case KMF_CERT_SIGNATURE_ALG:
2009 	case KMF_CERT_PUBKEY_ALG:
2010 		if (flag == KMF_CERT_SIGNATURE_ALG) {
2011 			len = i2a_ASN1_OBJECT(mem,
2012 				xcert->sig_alg->algorithm);
2013 		} else {
2014 			len = i2a_ASN1_OBJECT(mem,
2015 				xcert->cert_info->key->algor->algorithm);
2016 		}
2017 
2018 		if (len > 0) {
2019 			len = BIO_read(mem, resultStr,
2020 				KMF_CERT_PRINTABLE_LEN);
2021 		}
2022 		break;
2023 
2024 	case KMF_CERT_EMAIL:
2025 		emlst = X509_get1_email(xcert);
2026 		for (j = 0; j < sk_num(emlst); j++)
2027 			(void) BIO_printf(mem, "%s\n", sk_value(emlst, j));
2028 
2029 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2030 		X509_email_free(emlst);
2031 		break;
2032 	case KMF_X509_EXT_ISSUER_ALTNAME:
2033 	case KMF_X509_EXT_SUBJ_ALTNAME:
2034 	case KMF_X509_EXT_KEY_USAGE:
2035 	case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
2036 	case KMF_X509_EXT_CERT_POLICIES:
2037 	case KMF_X509_EXT_BASIC_CONSTRAINTS:
2038 	case KMF_X509_EXT_NAME_CONSTRAINTS:
2039 	case KMF_X509_EXT_POLICY_CONSTRAINTS:
2040 	case KMF_X509_EXT_EXT_KEY_USAGE:
2041 	case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2042 	case KMF_X509_EXT_AUTH_KEY_ID:
2043 	case KMF_X509_EXT_SUBJ_KEY_ID:
2044 	case KMF_X509_EXT_POLICY_MAPPINGS:
2045 	case KMF_X509_EXT_CRL_DIST_POINTS:
2046 	case KMF_X509_EXT_FRESHEST_CRL:
2047 		nid = ext2NID(flag);
2048 		if (nid == NID_undef) {
2049 			ret = KMF_ERR_EXTENSION_NOT_FOUND;
2050 			goto out;
2051 		}
2052 		ci = xcert->cert_info;
2053 
2054 		ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1);
2055 		if (ext_index == -1) {
2056 			SET_ERROR(kmfh, ERR_get_error());
2057 
2058 			ret = KMF_ERR_EXTENSION_NOT_FOUND;
2059 			goto out;
2060 		}
2061 		ex = X509v3_get_ext(ci->extensions, ext_index);
2062 
2063 		(void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex));
2064 
2065 		if (BIO_printf(mem, ": %s\n",
2066 			X509_EXTENSION_get_critical(ex) ? "critical" : "") <=
2067 			0) {
2068 			SET_ERROR(kmfh, ERR_get_error());
2069 			ret = KMF_ERR_ENCODING;
2070 			goto out;
2071 		}
2072 		if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) {
2073 			(void) BIO_printf(mem, "%*s", 4, "");
2074 			(void) M_ASN1_OCTET_STRING_print(mem, ex->value);
2075 		}
2076 		if (BIO_write(mem, "\n", 1) <= 0) {
2077 			SET_ERROR(kmfh, ERR_get_error());
2078 			ret = KMF_ERR_ENCODING;
2079 			goto out;
2080 		}
2081 		len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2082 	}
2083 	if (len <= 0) {
2084 		SET_ERROR(kmfh, ERR_get_error());
2085 		ret = KMF_ERR_ENCODING;
2086 	}
2087 
2088 out:
2089 	if (outbuf != NULL) {
2090 		free(outbuf);
2091 	}
2092 
2093 	if (xcert != NULL) {
2094 		X509_free(xcert);
2095 	}
2096 
2097 	if (mem != NULL) {
2098 		(void) BIO_free(mem);
2099 	}
2100 
2101 	return (ret);
2102 }
2103 KMF_RETURN
2104 /*ARGSUSED*/
2105 OpenSSL_GetPrikeyByCert(KMF_HANDLE_T handle,
2106 	KMF_CRYPTOWITHCERT_PARAMS *params,
2107 	KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key,
2108 	KMF_KEY_ALG keytype)
2109 {
2110 	KMF_RETURN rv = KMF_OK;
2111 	KMF_FINDKEY_PARAMS fkparms;
2112 	uint32_t numkeys = 0;
2113 
2114 	if (params == NULL && params->sslparms.keyfile == NULL)
2115 		return (KMF_ERR_BAD_PARAMETER);
2116 
2117 	/*
2118 	 * This is really just a FindKey operation, reuse the
2119 	 * FindKey function.
2120 	 */
2121 	(void *)memset(&fkparms, 0, sizeof (fkparms));
2122 	fkparms.kstype = KMF_KEYSTORE_OPENSSL;
2123 	fkparms.keyclass = KMF_ASYM_PRI;
2124 	fkparms.keytype = keytype;
2125 	fkparms.format = params->format;
2126 	fkparms.sslparms = params->sslparms;
2127 
2128 	rv = OpenSSL_FindKey(handle, &fkparms, key, &numkeys);
2129 
2130 	return (rv);
2131 }
2132 
2133 KMF_RETURN
2134 /*ARGSUSED*/
2135 OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
2136 	KMF_OID *AlgOID, KMF_DATA *ciphertext,
2137 	KMF_DATA *output)
2138 {
2139 	KMF_RETURN		ret = KMF_OK;
2140 	RSA *rsa = NULL;
2141 	unsigned int in_len = 0, out_len = 0;
2142 	unsigned int total_decrypted = 0, modulus_len = 0;
2143 	uint8_t *in_data, *out_data;
2144 	int i, blocks;
2145 
2146 	if (key == NULL || AlgOID == NULL ||
2147 	    ciphertext == NULL || output == NULL ||
2148 	    ciphertext->Data == NULL ||
2149 	    output->Data == NULL)
2150 		return (KMF_ERR_BAD_PARAMETER);
2151 
2152 	if (key->keyalg == KMF_RSA) {
2153 		rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp);
2154 		modulus_len = RSA_size(rsa);
2155 	} else {
2156 		return (KMF_ERR_BAD_PARAMETER);
2157 	}
2158 
2159 	blocks = ciphertext->Length/modulus_len;
2160 	out_data = output->Data;
2161 	in_data = ciphertext->Data;
2162 	out_len = modulus_len - 11;
2163 	in_len = modulus_len;
2164 
2165 	for (i = 0; i < blocks; i++) {
2166 		out_len  = RSA_private_decrypt(in_len,
2167 			in_data, out_data, rsa, RSA_PKCS1_PADDING);
2168 
2169 		if (out_len == 0) {
2170 			ret = KMF_ERR_INTERNAL;
2171 			goto cleanup;
2172 		}
2173 
2174 		out_data += out_len;
2175 		total_decrypted += out_len;
2176 		in_data += in_len;
2177 	}
2178 
2179 	output->Length = total_decrypted;
2180 
2181 cleanup:
2182 	RSA_free(rsa);
2183 	if (ret != KMF_OK)
2184 		output->Length = 0;
2185 
2186 	return (ret);
2187 
2188 }
2189 
2190 /*
2191  *  This function will create a certid from issuer_cert and user_cert.
2192  *  The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2193  *  certid memory after use.
2194  */
2195 static KMF_RETURN
2196 create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert,
2197     const KMF_DATA *user_cert, OCSP_CERTID **certid)
2198 {
2199 	KMF_RETURN ret = KMF_OK;
2200 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2201 	X509   *issuer = NULL;
2202 	X509   *cert = NULL;
2203 	unsigned char *ptmp;
2204 
2205 	if (issuer_cert == NULL || user_cert == NULL) {
2206 		return (KMF_ERR_BAD_PARAMETER);
2207 	}
2208 
2209 	/* convert the DER-encoded issuer cert to an internal X509 */
2210 	ptmp = issuer_cert->Data;
2211 	issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2212 		issuer_cert->Length);
2213 	if (issuer == NULL) {
2214 		SET_ERROR(kmfh, ERR_get_error());
2215 		ret = KMF_ERR_OCSP_BAD_ISSUER;
2216 		goto end;
2217 	}
2218 
2219 	/* convert the DER-encoded user cert to an internal X509 */
2220 	ptmp = user_cert->Data;
2221 	cert = d2i_X509(NULL, (const uchar_t **)&ptmp,
2222 		user_cert->Length);
2223 	if (cert == NULL) {
2224 		SET_ERROR(kmfh, ERR_get_error());
2225 
2226 		ret = KMF_ERR_OCSP_BAD_CERT;
2227 		goto end;
2228 	}
2229 
2230 	/* create a CERTID */
2231 	*certid = OCSP_cert_to_id(NULL, cert, issuer);
2232 	if (*certid == NULL) {
2233 		SET_ERROR(kmfh, ERR_get_error());
2234 		ret = KMF_ERR_OCSP_CERTID;
2235 		goto end;
2236 	}
2237 
2238 end:
2239 	if (issuer != NULL) {
2240 		X509_free(issuer);
2241 	}
2242 
2243 	if (cert != NULL) {
2244 		X509_free(cert);
2245 	}
2246 
2247 	return (ret);
2248 }
2249 
2250 KMF_RETURN
2251 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params,
2252     char *reqfile)
2253 {
2254 	KMF_RETURN ret = KMF_OK;
2255 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2256 	OCSP_CERTID *id = NULL;
2257 	OCSP_REQUEST *req = NULL;
2258 	BIO *derbio = NULL;
2259 
2260 	if (params->user_cert == NULL || params->issuer_cert == NULL ||
2261 	    reqfile == NULL) {
2262 		return (KMF_ERR_BAD_PARAMETER);
2263 	}
2264 
2265 	ret = create_certid(handle, params->issuer_cert, params->user_cert,
2266 	    &id);
2267 	if (ret != KMF_OK) {
2268 		return (ret);
2269 	}
2270 
2271 	/* Create an OCSP request */
2272 	req = OCSP_REQUEST_new();
2273 	if (req == NULL) {
2274 		SET_ERROR(kmfh, ERR_get_error());
2275 		ret = KMF_ERR_OCSP_CREATE_REQUEST;
2276 		goto end;
2277 	}
2278 
2279 	if (!OCSP_request_add0_id(req, id)) {
2280 		ret = KMF_ERR_OCSP_CREATE_REQUEST;
2281 		goto end;
2282 	}
2283 
2284 	/* Write the request to the output file with DER encoding */
2285 	derbio = BIO_new_file(reqfile, "wb");
2286 	if (!derbio) {
2287 		SET_ERROR(kmfh, ERR_get_error());
2288 		ret = KMF_ERR_OPEN_FILE;
2289 		goto end;
2290 	}
2291 	if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) {
2292 		ret = KMF_ERR_ENCODING;
2293 	}
2294 
2295 end:
2296 	/*
2297 	 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2298 	 * will deallocate certid's space also.
2299 	 */
2300 	if (req != NULL) {
2301 		OCSP_REQUEST_free(req);
2302 	}
2303 
2304 	if (derbio != NULL) {
2305 		(void) BIO_free(derbio);
2306 	}
2307 
2308 	return (ret);
2309 }
2310 
2311 /* ocsp_find_signer_sk() is copied from openssl source */
2312 static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
2313 {
2314 	int i;
2315 	unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
2316 
2317 	/* Easy if lookup by name */
2318 	if (id->type == V_OCSP_RESPID_NAME)
2319 		return (X509_find_by_subject(certs, id->value.byName));
2320 
2321 	/* Lookup by key hash */
2322 
2323 	/* If key hash isn't SHA1 length then forget it */
2324 	if (id->value.byKey->length != SHA_DIGEST_LENGTH)
2325 		return (NULL);
2326 
2327 	keyhash = id->value.byKey->data;
2328 	/* Calculate hash of each key and compare */
2329 	for (i = 0; i < sk_X509_num(certs); i++) {
2330 		/*LINTED*/
2331 		X509 *x = sk_X509_value(certs, i);
2332 		(void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
2333 		if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
2334 			return (x);
2335 	}
2336 	return (NULL);
2337 }
2338 
2339 /* ocsp_find_signer() is copied from openssl source */
2340 /*ARGSUSED*/
2341 static int
2342 ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
2343     X509_STORE *st, unsigned long flags)
2344 {
2345 	X509 *signer;
2346 	OCSP_RESPID *rid = bs->tbsResponseData->responderId;
2347 	if ((signer = ocsp_find_signer_sk(certs, rid)))	{
2348 		*psigner = signer;
2349 		return (2);
2350 	}
2351 	if (!(flags & OCSP_NOINTERN) &&
2352 	    (signer = ocsp_find_signer_sk(bs->certs, rid))) {
2353 		*psigner = signer;
2354 		return (1);
2355 	}
2356 	/* Maybe lookup from store if by subject name */
2357 
2358 	*psigner = NULL;
2359 	return (0);
2360 }
2361 
2362 /*
2363  * This function will verify the signature of a basic response, using
2364  * the public key from the OCSP responder certificate.
2365  */
2366 static KMF_RETURN
2367 check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs,
2368     KMF_DATA *signer_cert, KMF_DATA *issuer_cert)
2369 {
2370 	KMF_RETURN ret = KMF_OK;
2371 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2372 	STACK_OF(X509) *cert_stack = NULL;
2373 	X509 *signer = NULL;
2374 	X509 *issuer = NULL;
2375 	EVP_PKEY *skey = NULL;
2376 	unsigned char *ptmp;
2377 
2378 
2379 	if (bs == NULL || issuer_cert == NULL)
2380 		return (KMF_ERR_BAD_PARAMETER);
2381 
2382 	/*
2383 	 * Find the certificate that signed the basic response.
2384 	 *
2385 	 * If signer_cert is not NULL, we will use that as the signer cert.
2386 	 * Otherwise, we will check if the issuer cert is actually the signer.
2387 	 * If we still do not find a signer, we will look for it from the
2388 	 * certificate list came with the response file.
2389 	 */
2390 	if (signer_cert != NULL) {
2391 		ptmp = signer_cert->Data;
2392 		signer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2393 		    signer_cert->Length);
2394 		if (signer == NULL) {
2395 			SET_ERROR(kmfh, ERR_get_error());
2396 			ret = KMF_ERR_OCSP_BAD_SIGNER;
2397 			goto end;
2398 		}
2399 	} else {
2400 		/*
2401 		 * Convert the issuer cert into X509 and push it into a
2402 		 * stack to be used by ocsp_find_signer().
2403 		 */
2404 		ptmp = issuer_cert->Data;
2405 		issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2406 			issuer_cert->Length);
2407 		if (issuer == NULL) {
2408 			SET_ERROR(kmfh, ERR_get_error());
2409 			ret = KMF_ERR_OCSP_BAD_ISSUER;
2410 			goto end;
2411 		}
2412 
2413 		if ((cert_stack = sk_X509_new_null()) == NULL) {
2414 			ret = KMF_ERR_INTERNAL;
2415 			goto end;
2416 		}
2417 
2418 		if (sk_X509_push(cert_stack, issuer) == NULL) {
2419 			ret = KMF_ERR_INTERNAL;
2420 			goto end;
2421 		}
2422 
2423 		ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0);
2424 		if (!ret) {
2425 			/* can not find the signer */
2426 			ret = KMF_ERR_OCSP_BAD_SIGNER;
2427 			goto end;
2428 		}
2429 	}
2430 
2431 	/* Verify the signature of the response */
2432 	skey = X509_get_pubkey(signer);
2433 	if (skey == NULL) {
2434 		ret = KMF_ERR_OCSP_BAD_SIGNER;
2435 		goto end;
2436 	}
2437 
2438 	ret = OCSP_BASICRESP_verify(bs, skey, 0);
2439 	if (ret == 0) {
2440 		ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE;
2441 		goto end;
2442 	}
2443 
2444 end:
2445 	if (issuer != NULL) {
2446 		X509_free(issuer);
2447 	}
2448 
2449 	if (signer != NULL) {
2450 		X509_free(signer);
2451 	}
2452 
2453 	if (skey != NULL) {
2454 		EVP_PKEY_free(skey);
2455 	}
2456 
2457 	if (cert_stack != NULL) {
2458 		sk_X509_free(cert_stack);
2459 	}
2460 
2461 	return (ret);
2462 }
2463 
2464 
2465 
2466 KMF_RETURN
2467 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,
2468     KMF_OCSPRESPONSE_PARAMS_INPUT *params_in,
2469     KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out)
2470 {
2471 	KMF_RETURN ret = KMF_OK;
2472 	BIO *derbio = NULL;
2473 	OCSP_RESPONSE *resp = NULL;
2474 	OCSP_BASICRESP *bs = NULL;
2475 	OCSP_CERTID *id = NULL;
2476 	OCSP_SINGLERESP *single = NULL;
2477 	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
2478 	int index, status, reason;
2479 
2480 	if (params_in == NULL || params_in->issuer_cert == NULL ||
2481 	    params_in->user_cert == NULL || params_in->response == NULL) {
2482 		return (KMF_ERR_BAD_PARAMETER);
2483 	}
2484 
2485 	if (params_out == NULL) {
2486 		return (KMF_ERR_BAD_PARAMETER);
2487 	}
2488 
2489 	/* Read in the response */
2490 	derbio = BIO_new_mem_buf(params_in->response->Data,
2491 	    params_in->response->Length);
2492 	if (!derbio) {
2493 		ret = KMF_ERR_MEMORY;
2494 		return (ret);
2495 	}
2496 
2497 	resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
2498 	if (resp == NULL) {
2499 		ret = KMF_ERR_OCSP_MALFORMED_RESPONSE;
2500 		goto end;
2501 	}
2502 
2503 	/* Check the response status */
2504 	status = OCSP_response_status(resp);
2505 	params_out->response_status = status;
2506 	if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
2507 		ret = KMF_ERR_OCSP_RESPONSE_STATUS;
2508 		goto end;
2509 	}
2510 
2511 #ifdef DEBUG
2512 	printf("Successfully checked the response file status.\n");
2513 #endif /* DEBUG */
2514 
2515 	/* Extract basic response */
2516 	bs = OCSP_response_get1_basic(resp);
2517 	if (bs == NULL) {
2518 		ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE;
2519 		goto end;
2520 	}
2521 
2522 #ifdef DEBUG
2523 	printf("Successfully retrieved the basic response.\n");
2524 #endif /* DEBUG */
2525 
2526 	/* Check the basic response signature if required */
2527 	if (params_in->ignore_response_sign == B_FALSE) {
2528 		ret = check_response_signature(handle, bs,
2529 		    params_in->signer_cert, params_in->issuer_cert);
2530 		if (ret != KMF_OK)
2531 			goto end;
2532 	}
2533 
2534 #ifdef DEBUG
2535 	printf("Successfully verified the response signature.\n");
2536 #endif /* DEBUG */
2537 
2538 	/* Create a certid for the certificate in question */
2539 	ret = create_certid(handle, params_in->issuer_cert,
2540 	    params_in->user_cert, &id);
2541 	if (ret != KMF_OK) {
2542 		ret = KMF_ERR_OCSP_CERTID;
2543 		goto end;
2544 	}
2545 
2546 #ifdef DEBUG
2547 	printf("successfully created a certid for the cert.\n");
2548 #endif /* DEBUG */
2549 
2550 	/* Find the index of the single response for the certid */
2551 	index = OCSP_resp_find(bs, id, -1);
2552 	if (index < 0) {
2553 		/* cound not find this certificate in the response */
2554 		ret = KMF_ERR_OCSP_UNKNOWN_CERT;
2555 		goto end;
2556 	}
2557 
2558 #ifdef DEBUG
2559 	printf("Successfully found the single response index for the cert.\n");
2560 #endif /* DEBUG */
2561 
2562 	/* Retrieve the single response and get the cert status */
2563 	single = OCSP_resp_get0(bs, index);
2564 	status = OCSP_single_get0_status(single, &reason, &rev, &thisupd,
2565 	    &nextupd);
2566 	if (status == V_OCSP_CERTSTATUS_GOOD) {
2567 		params_out->cert_status = OCSP_GOOD;
2568 	} else if (status == V_OCSP_CERTSTATUS_UNKNOWN) {
2569 		params_out->cert_status = OCSP_UNKNOWN;
2570 	} else { /* revoked */
2571 		params_out->cert_status = OCSP_REVOKED;
2572 		params_out->reason = reason;
2573 	}
2574 	ret = KMF_OK;
2575 
2576 	/* Verify the time */
2577 	if (!OCSP_check_validity(thisupd, nextupd, 300,
2578 	    params_in->response_lifetime)) {
2579 		ret = KMF_ERR_OCSP_STATUS_TIME_INVALID;
2580 		goto end;
2581 	}
2582 
2583 #ifdef DEBUG
2584 	printf("Successfully verify the time.\n");
2585 #endif /* DEBUG */
2586 
2587 end:
2588 	if (derbio != NULL)
2589 		(void) BIO_free(derbio);
2590 
2591 	if (resp != NULL)
2592 		OCSP_RESPONSE_free(resp);
2593 
2594 	if (bs != NULL)
2595 		OCSP_BASICRESP_free(bs);
2596 
2597 	if (id != NULL)
2598 		OCSP_CERTID_free(id);
2599 
2600 	return (ret);
2601 }
2602 
2603 static KMF_RETURN
2604 fetch_key(KMF_HANDLE_T handle, char *path,
2605 	KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key)
2606 {
2607 	KMF_RETURN rv = KMF_OK;
2608 	EVP_PKEY *pkey;
2609 	KMF_RAW_SYM_KEY *rkey = NULL;
2610 
2611 	/* Make sure the requested file actually exists. */
2612 	if (access(path, F_OK) != 0) {
2613 		return (KMF_ERR_KEY_NOT_FOUND);
2614 	}
2615 
2616 	if (keyclass == KMF_ASYM_PRI ||
2617 	    keyclass == KMF_ASYM_PUB) {
2618 		pkey = openssl_load_key(handle, path);
2619 		if (pkey == NULL) {
2620 			return (KMF_ERR_KEY_NOT_FOUND);
2621 		}
2622 		if (key != NULL) {
2623 			if (pkey->type == EVP_PKEY_RSA)
2624 				key->keyalg = KMF_RSA;
2625 			else if (pkey->type == EVP_PKEY_DSA)
2626 				key->keyalg = KMF_DSA;
2627 
2628 			key->kstype = KMF_KEYSTORE_OPENSSL;
2629 			key->keyclass = keyclass;
2630 			key->keyp = (void *)pkey;
2631 			key->israw = FALSE;
2632 			key->keylabel = path;
2633 		} else {
2634 			EVP_PKEY_free(pkey);
2635 			pkey = NULL;
2636 		}
2637 	} else if (keyclass == KMF_SYMMETRIC) {
2638 		KMF_ENCODE_FORMAT fmt;
2639 		/*
2640 		 * If the file is a recognized format,
2641 		 * then it is NOT a symmetric key.
2642 		 */
2643 		rv = KMF_GetFileFormat(path, &fmt);
2644 		if (rv == KMF_OK || fmt != 0) {
2645 			return (KMF_ERR_KEY_NOT_FOUND);
2646 		} else if (rv == KMF_ERR_ENCODING) {
2647 			/*
2648 			 * If we don't know the encoding,
2649 			 * it is probably  a symmetric key.
2650 			 */
2651 			rv = KMF_OK;
2652 		}
2653 
2654 		if (key != NULL) {
2655 			KMF_DATA keyvalue;
2656 			rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
2657 			if (rkey == NULL) {
2658 				rv = KMF_ERR_MEMORY;
2659 				goto out;
2660 			}
2661 
2662 			(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
2663 			rv = KMF_ReadInputFile(handle, path, &keyvalue);
2664 			if (rv != KMF_OK)
2665 				goto out;
2666 
2667 			rkey->keydata.len = keyvalue.Length;
2668 			rkey->keydata.val = keyvalue.Data;
2669 
2670 			key->kstype = KMF_KEYSTORE_OPENSSL;
2671 			key->keyclass = keyclass;
2672 			key->israw = TRUE;
2673 			key->keylabel = path;
2674 			key->keyp = (void *)rkey;
2675 		}
2676 	}
2677 out:
2678 	if (rv != KMF_OK) {
2679 		if (rkey != NULL) {
2680 			KMF_FreeRawSymKey(rkey);
2681 		}
2682 		if (pkey != NULL)
2683 			EVP_PKEY_free(pkey);
2684 
2685 		if (key != NULL) {
2686 			key->keyalg = KMF_KEYALG_NONE;
2687 			key->keyclass = KMF_KEYCLASS_NONE;
2688 			key->keyp = NULL;
2689 		}
2690 	}
2691 
2692 	return (rv);
2693 }
2694 
2695 KMF_RETURN
2696 OpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params,
2697 	KMF_KEY_HANDLE *key, uint32_t *numkeys)
2698 {
2699 	KMF_RETURN rv = KMF_OK;
2700 	char *fullpath = NULL;
2701 
2702 	if (handle == NULL || params == NULL || numkeys == NULL)
2703 		return (KMF_ERR_BAD_PARAMETER);
2704 
2705 	if (params->keyclass != KMF_ASYM_PUB &&
2706 		params->keyclass != KMF_ASYM_PRI &&
2707 		params->keyclass != KMF_SYMMETRIC)
2708 		return (KMF_ERR_BAD_KEY_CLASS);
2709 
2710 	fullpath = get_fullpath(params->sslparms.dirpath,
2711 		params->sslparms.keyfile);
2712 
2713 	if (fullpath == NULL)
2714 		return (KMF_ERR_BAD_PARAMETER);
2715 
2716 	*numkeys = 0;
2717 
2718 	if (isdir(fullpath)) {
2719 		DIR *dirp;
2720 		struct dirent *dp;
2721 		int n = 0;
2722 
2723 		/* open all files in the directory and attempt to read them */
2724 		if ((dirp = opendir(fullpath)) == NULL) {
2725 			return (KMF_ERR_BAD_PARAMETER);
2726 		}
2727 		rewinddir(dirp);
2728 		while ((dp = readdir(dirp)) != NULL) {
2729 			if (strcmp(dp->d_name, ".") &&
2730 			    strcmp(dp->d_name, "..")) {
2731 				char *fname;
2732 
2733 				fname = get_fullpath(fullpath,
2734 					(char *)&dp->d_name);
2735 
2736 				rv = fetch_key(handle, fname,
2737 					params->keyclass,
2738 					key ? &key[n] : NULL);
2739 
2740 				if (rv == KMF_OK)
2741 					n++;
2742 
2743 				if (rv != KMF_OK || key == NULL)
2744 					free(fname);
2745 			}
2746 		}
2747 		(void) closedir(dirp);
2748 		free(fullpath);
2749 		(*numkeys) = n;
2750 	} else {
2751 		rv = fetch_key(handle, fullpath, params->keyclass, key);
2752 		if (rv == KMF_OK)
2753 			(*numkeys) = 1;
2754 
2755 		if (rv != KMF_OK || key == NULL)
2756 			free(fullpath);
2757 	}
2758 
2759 	if ((*numkeys) == 0)
2760 		rv = KMF_ERR_KEY_NOT_FOUND;
2761 
2762 	return (rv);
2763 }
2764 
2765 #define	HANDLE_PK12_ERROR { \
2766 	SET_ERROR(kmfh, ERR_get_error()); \
2767 	rv = KMF_ERR_ENCODING; \
2768 	goto out; \
2769 }
2770 
2771 static KMF_RETURN
2772 write_pkcs12(KMF_HANDLE *kmfh,
2773 	BIO *bio,
2774 	KMF_CREDENTIAL *cred,
2775 	EVP_PKEY *pkey,
2776 	X509 *sslcert)
2777 {
2778 	KMF_RETURN rv = KMF_OK;
2779 	STACK_OF(PKCS12_SAFEBAG)	*bag_stack = NULL;
2780 	PKCS12_SAFEBAG			*bag = NULL;
2781 	PKCS7				*cert_authsafe = NULL;
2782 	PKCS8_PRIV_KEY_INFO		*p8 = NULL;
2783 	PKCS7				*key_authsafe = NULL;
2784 	STACK_OF(PKCS7)			*authsafe_stack = NULL;
2785 	PKCS12				*p12_elem = NULL;
2786 	char				*lab = NULL;
2787 	int				lab_len = 0;
2788 	unsigned char keyid[EVP_MAX_MD_SIZE];
2789 	unsigned int keyidlen = 0;
2790 
2791 	/* Must have at least a cert OR a key */
2792 	if (sslcert == NULL && pkey == NULL)
2793 		return (KMF_ERR_BAD_PARAMETER);
2794 
2795 	(void) memset(keyid, 0, sizeof (keyid));
2796 	/*
2797 	 * Section 1:
2798 	 *
2799 	 * The first PKCS#12 container (safebag) will hold the certificates
2800 	 * associated with this key.  The result of this section is a
2801 	 * PIN-encrypted PKCS#7 container (authsafe).  If there are no
2802 	 * certificates, there is no point in creating the "safebag" or the
2803 	 * "authsafe" so we go to the next section.
2804 	 */
2805 	if (sslcert != NULL && pkey != NULL) {
2806 		if (X509_check_private_key(sslcert, pkey)) {
2807 			(void) X509_digest(sslcert, EVP_sha1(), keyid,
2808 				&keyidlen);
2809 		} else {
2810 			/* The key doesn't match the cert */
2811 			HANDLE_PK12_ERROR
2812 		}
2813 	}
2814 
2815 	bag_stack = sk_PKCS12_SAFEBAG_new_null();
2816 	if (bag_stack == NULL)
2817 		return (KMF_ERR_MEMORY);
2818 
2819 	if (sslcert != NULL) {
2820 		/* Convert cert from X509 struct to PKCS#12 bag */
2821 		bag = PKCS12_x5092certbag(sslcert);
2822 		if (bag == NULL) {
2823 			HANDLE_PK12_ERROR
2824 		}
2825 
2826 		/* Add the key id to the certificate bag. */
2827 		if (keyidlen > 0 &&
2828 			!PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
2829 			HANDLE_PK12_ERROR
2830 		}
2831 
2832 		/* Pile it on the bag_stack. */
2833 		if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
2834 			HANDLE_PK12_ERROR
2835 		}
2836 #if 0
2837 		/* No support for CA certs yet */
2838 		if (cacerts != NULL && ncacerts > 0) {
2839 			int i;
2840 			for (i = 0; i < ncacerts; i++) {
2841 				KMF_X509_DER_CERT *c = &cacerts[i];
2842 				X509 *ca = NULL;
2843 
2844 				uchar_t *p = (uchar_t *)c->certificate.Data;
2845 				ca = d2i_X509(NULL, &p,
2846 					c->certificate.Length);
2847 				if (ca == NULL) {
2848 					HANDLE_PK12_ERROR
2849 				}
2850 				/* Convert CA cert to PKCS#12 bag. */
2851 				bag = PKCS12_x5092certbag(ca);
2852 				if (bag == NULL) {
2853 					sk_PKCS12_SAFEBAG_pop_free(bag_stack,
2854 					    PKCS12_SAFEBAG_free);
2855 					HANDLE_PK12_ERROR
2856 				}
2857 				/* Pile it onto the bag_stack. */
2858 				if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
2859 					HANDLE_PK12_ERROR
2860 				}
2861 			}
2862 		}
2863 #endif
2864 		/* Turn bag_stack of certs into encrypted authsafe. */
2865 		cert_authsafe = PKCS12_pack_p7encdata(
2866 			NID_pbe_WithSHA1And40BitRC2_CBC,
2867 			cred->cred,
2868 			cred->credlen, NULL, 0,
2869 			PKCS12_DEFAULT_ITER,
2870 			bag_stack);
2871 
2872 		/* Clear away this bag_stack, we're done with it. */
2873 		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
2874 		bag_stack = NULL;
2875 
2876 		if (cert_authsafe == NULL) {
2877 			HANDLE_PK12_ERROR
2878 		}
2879 	}
2880 	/*
2881 	 * Section 2:
2882 	 *
2883 	 * The second PKCS#12 container (safebag) will hold the private key
2884 	 * that goes with the certificates above.  The results of this section
2885 	 * is an unencrypted PKCS#7 container (authsafe).  If there is no
2886 	 * private key, there is no point in creating the "safebag" or the
2887 	 * "authsafe" so we go to the next section.
2888 	 */
2889 	if (pkey != NULL) {
2890 		p8 = EVP_PKEY2PKCS8(pkey);
2891 		if (p8 == NULL) {
2892 			HANDLE_PK12_ERROR
2893 		}
2894 		/* Put the shrouded key into a PKCS#12 bag. */
2895 		bag = PKCS12_MAKE_SHKEYBAG(
2896 			NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
2897 			cred->cred, cred->credlen,
2898 			NULL, 0, PKCS12_DEFAULT_ITER, p8);
2899 
2900 		/* Clean up the PKCS#8 shrouded key, don't need it now. */
2901 		PKCS8_PRIV_KEY_INFO_free(p8);
2902 		p8 = NULL;
2903 
2904 		if (bag == NULL) {
2905 			HANDLE_PK12_ERROR
2906 		}
2907 		if (keyidlen &&
2908 			!PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
2909 			HANDLE_PK12_ERROR
2910 		}
2911 		if (lab != NULL) {
2912 			if (!PKCS12_add_friendlyname(bag,
2913 				(char *)lab, lab_len)) {
2914 				HANDLE_PK12_ERROR
2915 			}
2916 		}
2917 		/* Start a PKCS#12 safebag container for the private key. */
2918 		bag_stack = sk_PKCS12_SAFEBAG_new_null();
2919 		if (bag_stack == NULL) {
2920 			HANDLE_PK12_ERROR
2921 		}
2922 
2923 		/* Pile on the private key on the bag_stack. */
2924 		if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
2925 			HANDLE_PK12_ERROR
2926 		}
2927 		key_authsafe = PKCS12_pack_p7data(bag_stack);
2928 
2929 		/* Clear away this bag_stack, we're done with it. */
2930 		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
2931 		bag_stack = NULL;
2932 
2933 		if (key_authsafe == NULL) {
2934 			HANDLE_PK12_ERROR
2935 		}
2936 	}
2937 	/*
2938 	 * Section 3:
2939 	 *
2940 	 * This is where the two PKCS#7 containers, one for the certificates
2941 	 * and one for the private key, are put together into a PKCS#12
2942 	 * element.  This final PKCS#12 element is written to the export file.
2943 	 */
2944 
2945 	/* Start a PKCS#7 stack. */
2946 	authsafe_stack = sk_PKCS7_new_null();
2947 	if (authsafe_stack == NULL) {
2948 		HANDLE_PK12_ERROR
2949 	}
2950 	if (key_authsafe != NULL) {
2951 		if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) {
2952 			HANDLE_PK12_ERROR
2953 		}
2954 	}
2955 	if (cert_authsafe != NULL) {
2956 		if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) {
2957 			HANDLE_PK12_ERROR
2958 		}
2959 	}
2960 	p12_elem = PKCS12_init(NID_pkcs7_data);
2961 	if (p12_elem == NULL) {
2962 		sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
2963 		HANDLE_PK12_ERROR
2964 	}
2965 
2966 	/* Put the PKCS#7 stack into the PKCS#12 element. */
2967 	if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) {
2968 		HANDLE_PK12_ERROR
2969 	}
2970 	/* Clear away the PKCS#7 stack, we're done with it. */
2971 	sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
2972 	authsafe_stack = NULL;
2973 
2974 	/* Set the integrity MAC on the PKCS#12 element. */
2975 	if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen,
2976 		NULL, 0, PKCS12_DEFAULT_ITER, NULL)) {
2977 		HANDLE_PK12_ERROR
2978 	}
2979 
2980 	/* Write the PKCS#12 element to the export file. */
2981 	if (!i2d_PKCS12_bio(bio, p12_elem)) {
2982 		HANDLE_PK12_ERROR
2983 	}
2984 
2985 	PKCS12_free(p12_elem);
2986 out:
2987 	if (rv != KMF_OK) {
2988 		/* Clear away this bag_stack, we're done with it. */
2989 		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
2990 		sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
2991 	}
2992 	return (rv);
2993 }
2994 
2995 static EVP_PKEY *
2996 ImportRawRSAKey(KMF_RAW_RSA_KEY *key)
2997 {
2998 	RSA		*rsa = NULL;
2999 	EVP_PKEY 	*newkey = NULL;
3000 
3001 	if ((rsa = RSA_new()) == NULL)
3002 		return (NULL);
3003 
3004 	if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL)
3005 		return (NULL);
3006 
3007 	if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) ==
3008 		NULL)
3009 		return (NULL);
3010 
3011 	if (key->priexp.val != NULL)
3012 		if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len,
3013 			rsa->d)) == NULL)
3014 			return (NULL);
3015 
3016 	if (key->prime1.val != NULL)
3017 		if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len,
3018 			rsa->p)) == NULL)
3019 			return (NULL);
3020 
3021 	if (key->prime2.val != NULL)
3022 		if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len,
3023 			rsa->q)) == NULL)
3024 			return (NULL);
3025 
3026 	if (key->exp1.val != NULL)
3027 		if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len,
3028 			rsa->dmp1)) == NULL)
3029 			return (NULL);
3030 
3031 	if (key->exp2.val != NULL)
3032 		if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len,
3033 			rsa->dmq1)) == NULL)
3034 			return (NULL);
3035 
3036 	if (key->coef.val != NULL)
3037 		if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len,
3038 			rsa->iqmp)) == NULL)
3039 			return (NULL);
3040 
3041 	if ((newkey = EVP_PKEY_new()) == NULL)
3042 		return (NULL);
3043 
3044 	(void) EVP_PKEY_set1_RSA(newkey, rsa);
3045 
3046 	/* The original key must be freed once here or it leaks memory */
3047 	RSA_free(rsa);
3048 
3049 	return (newkey);
3050 }
3051 
3052 static EVP_PKEY *
3053 ImportRawDSAKey(KMF_RAW_DSA_KEY *key)
3054 {
3055 	DSA		*dsa = NULL;
3056 	EVP_PKEY 	*newkey = NULL;
3057 
3058 	if ((dsa = DSA_new()) == NULL)
3059 		return (NULL);
3060 
3061 	if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len,
3062 		dsa->p)) == NULL)
3063 		return (NULL);
3064 
3065 	if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len,
3066 		dsa->q)) == NULL)
3067 		return (NULL);
3068 
3069 	if ((dsa->g = BN_bin2bn(key->base.val, key->base.len,
3070 		dsa->g)) == NULL)
3071 		return (NULL);
3072 
3073 	if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len,
3074 		dsa->priv_key)) == NULL)
3075 		return (NULL);
3076 
3077 	if ((newkey = EVP_PKEY_new()) == NULL)
3078 		return (NULL);
3079 
3080 	(void) EVP_PKEY_set1_DSA(newkey, dsa);
3081 
3082 	/* The original key must be freed once here or it leaks memory */
3083 	DSA_free(dsa);
3084 	return (newkey);
3085 }
3086 
3087 static KMF_RETURN
3088 ExportPK12FromRawData(KMF_HANDLE_T handle,
3089 	KMF_CREDENTIAL *cred,
3090 	int numcerts, KMF_X509_DER_CERT *certlist,
3091 	int numkeys, KMF_KEY_HANDLE *keylist,
3092 	char *filename)
3093 {
3094 	KMF_RETURN rv = KMF_OK;
3095 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3096 	BIO *bio = NULL;
3097 	X509 *xcert = NULL;
3098 	EVP_PKEY *pkey = NULL;
3099 	int i;
3100 
3101 	/*
3102 	 * Open the output file.
3103 	 */
3104 	if ((bio = BIO_new_file(filename, "wb")) == NULL) {
3105 		SET_ERROR(kmfh, ERR_get_error());
3106 		rv = KMF_ERR_OPEN_FILE;
3107 		goto cleanup;
3108 	}
3109 
3110 	if (numcerts > 0 && numkeys > 0) {
3111 		for (i = 0; rv == KMF_OK && i < numcerts; i++) {
3112 			KMF_RAW_KEY_DATA *key = NULL;
3113 			const uchar_t *p = certlist[i].certificate.Data;
3114 			long len = certlist[i].certificate.Length;
3115 
3116 			if (i < numkeys) {
3117 				key = (KMF_RAW_KEY_DATA *)keylist[i].keyp;
3118 
3119 				if (key->keytype == KMF_RSA) {
3120 					pkey = ImportRawRSAKey(
3121 						&key->rawdata.rsa);
3122 				} else if (key->keytype == KMF_DSA) {
3123 					pkey = ImportRawDSAKey(
3124 						&key->rawdata.dsa);
3125 				} else {
3126 					rv = KMF_ERR_BAD_PARAMETER;
3127 				}
3128 			}
3129 
3130 			xcert = d2i_X509(NULL, &p, len);
3131 			if (xcert == NULL) {
3132 				SET_ERROR(kmfh, ERR_get_error());
3133 				rv = KMF_ERR_ENCODING;
3134 			}
3135 			/* Stick the key and the cert into a PKCS#12 file */
3136 			rv = write_pkcs12(kmfh, bio, cred, pkey, xcert);
3137 			if (xcert)
3138 				X509_free(xcert);
3139 			if (pkey)
3140 				EVP_PKEY_free(pkey);
3141 		}
3142 	}
3143 
3144 cleanup:
3145 
3146 	if (bio != NULL)
3147 		(void) BIO_free_all(bio);
3148 
3149 	return (rv);
3150 }
3151 
3152 KMF_RETURN
3153 OpenSSL_ExportP12(KMF_HANDLE_T handle,
3154 	KMF_EXPORTP12_PARAMS *params,
3155 	int numcerts, KMF_X509_DER_CERT *certlist,
3156 	int numkeys, KMF_KEY_HANDLE *keylist,
3157 	char *filename)
3158 {
3159 	KMF_RETURN rv;
3160 	KMF_HANDLE *kmfh = (KMF_HANDLE  *)handle;
3161 	KMF_FINDCERT_PARAMS fcargs;
3162 	BIO *bio = NULL;
3163 	X509 *xcert = NULL;
3164 	char *fullpath = NULL;
3165 	EVP_PKEY *pkey = NULL;
3166 
3167 	/*
3168 	 *  First, find the certificate.
3169 	 */
3170 	if (params == NULL)
3171 		return (KMF_ERR_BAD_PARAMETER);
3172 
3173 	/*
3174 	 * If the caller already sent the raw keys and certs,
3175 	 * shortcut the search and just export that
3176 	 * data.
3177 	 *
3178 	 * One *may* export a key OR a cert by itself.
3179 	 */
3180 	if (certlist != NULL || keylist != NULL) {
3181 		rv = ExportPK12FromRawData(handle,
3182 			&params->p12cred,
3183 			numcerts, certlist,
3184 			numkeys, keylist,
3185 			filename);
3186 		return (rv);
3187 	}
3188 
3189 	if (params->sslparms.certfile != NULL) {
3190 		fullpath = get_fullpath(params->sslparms.dirpath,
3191 			params->sslparms.certfile);
3192 
3193 		if (fullpath == NULL)
3194 			return (KMF_ERR_BAD_PARAMETER);
3195 
3196 		if (isdir(fullpath)) {
3197 			free(fullpath);
3198 			return (KMF_ERR_AMBIGUOUS_PATHNAME);
3199 		}
3200 
3201 		(void *)memset(&fcargs, 0, sizeof (fcargs));
3202 		fcargs.kstype = params->kstype;
3203 		fcargs.certLabel = params->certLabel;
3204 		fcargs.issuer = params->issuer;
3205 		fcargs.subject = params->subject;
3206 		fcargs.serial = params->serial;
3207 		fcargs.idstr = params->idstr;
3208 		fcargs.sslparms.dirpath = NULL;
3209 		fcargs.sslparms.certfile = fullpath;
3210 		fcargs.sslparms.format = params->sslparms.format;
3211 
3212 		rv = load_X509cert(kmfh, &fcargs, fullpath, &xcert);
3213 		if (rv != KMF_OK)
3214 			goto end;
3215 	}
3216 
3217 	/*
3218 	 * Now find the private key.
3219 	 */
3220 	if (params->sslparms.keyfile != NULL) {
3221 		fullpath = get_fullpath(params->sslparms.dirpath,
3222 			params->sslparms.keyfile);
3223 
3224 		if (fullpath == NULL)
3225 			return (KMF_ERR_BAD_PARAMETER);
3226 
3227 		if (isdir(fullpath)) {
3228 			free(fullpath);
3229 			return (KMF_ERR_AMBIGUOUS_PATHNAME);
3230 		}
3231 
3232 		pkey = openssl_load_key(handle, fullpath);
3233 		if (pkey == NULL) {
3234 			rv = KMF_ERR_KEY_NOT_FOUND;
3235 			goto end;
3236 		}
3237 	}
3238 
3239 	/*
3240 	 * Open the output file.
3241 	 */
3242 	if ((bio = BIO_new_file(filename, "wb")) == NULL) {
3243 		SET_ERROR(kmfh, ERR_get_error());
3244 		rv = KMF_ERR_OPEN_FILE;
3245 		goto end;
3246 	}
3247 
3248 	/* Stick the key and the cert into a PKCS#12 file */
3249 	rv = write_pkcs12(kmfh, bio, &params->p12cred,
3250 		pkey, xcert);
3251 
3252 end:
3253 	if (fullpath)
3254 		free(fullpath);
3255 	if (xcert)
3256 		X509_free(xcert);
3257 	if (pkey)
3258 		EVP_PKEY_free(pkey);
3259 	if (bio)
3260 		(void) BIO_free(bio);
3261 
3262 	return (rv);
3263 }
3264 
3265 /*
3266  * Helper function to decrypt and parse PKCS#12 import file.
3267  */
3268 static KMF_RETURN
3269 extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
3270 	EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca)
3271 /* ARGSUSED */
3272 {
3273 	PKCS12		*pk12, *pk12_tmp;
3274 	EVP_PKEY	*temp_pkey = NULL;
3275 	X509		*temp_cert = NULL;
3276 	STACK_OF(X509)	*temp_ca = NULL;
3277 
3278 	if ((pk12 = PKCS12_new()) == NULL) {
3279 		return (KMF_ERR_MEMORY);
3280 	}
3281 
3282 	if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) {
3283 		/* This is ok; it seems to mean there is no more to read. */
3284 		if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 &&
3285 		    ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG)
3286 			goto end_extract_pkcs12;
3287 
3288 		PKCS12_free(pk12);
3289 		return (KMF_ERR_PKCS12_FORMAT);
3290 	}
3291 	pk12 = pk12_tmp;
3292 
3293 	if (PKCS12_parse(pk12, (char *)pin, &temp_pkey, &temp_cert,
3294 	    &temp_ca) <= 0) {
3295 		PKCS12_free(pk12);
3296 		return (KMF_ERR_PKCS12_FORMAT);
3297 	}
3298 
3299 end_extract_pkcs12:
3300 
3301 	*priv_key = temp_pkey;
3302 	*cert = temp_cert;
3303 	*ca = temp_ca;
3304 
3305 	PKCS12_free(pk12);
3306 	return (KMF_OK);
3307 }
3308 
3309 static KMF_RETURN
3310 sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to)
3311 {
3312 	KMF_RETURN rv = KMF_OK;
3313 	uint32_t sz;
3314 
3315 	sz = BN_num_bytes(from);
3316 	to->val = (uchar_t *)malloc(sz);
3317 	if (to->val == NULL)
3318 		return (KMF_ERR_MEMORY);
3319 
3320 	if ((to->len = BN_bn2bin(from, to->val)) != sz) {
3321 		free(to->val);
3322 		to->val = NULL;
3323 		to->len = 0;
3324 		rv = KMF_ERR_MEMORY;
3325 	}
3326 
3327 	return (rv);
3328 }
3329 
3330 static KMF_RETURN
3331 exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key)
3332 {
3333 	KMF_RETURN rv;
3334 	KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa;
3335 
3336 	(void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY));
3337 	if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK)
3338 		goto cleanup;
3339 
3340 	if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK)
3341 		goto cleanup;
3342 
3343 	if (rsa->d != NULL)
3344 		if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK)
3345 			goto cleanup;
3346 
3347 	if (rsa->p != NULL)
3348 		if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK)
3349 			goto cleanup;
3350 
3351 	if (rsa->q != NULL)
3352 		if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK)
3353 			goto cleanup;
3354 
3355 	if (rsa->dmp1 != NULL)
3356 		if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK)
3357 			goto cleanup;
3358 
3359 	if (rsa->dmq1 != NULL)
3360 		if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK)
3361 			goto cleanup;
3362 
3363 	if (rsa->iqmp != NULL)
3364 		if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK)
3365 			goto cleanup;
3366 cleanup:
3367 	if (rv != KMF_OK)
3368 		KMF_FreeRawKey(key);
3369 	else
3370 		key->keytype = KMF_RSA;
3371 
3372 	/*
3373 	 * Free the reference to this key, SSL will not actually free
3374 	 * the memory until the refcount == 0, so this is safe.
3375 	 */
3376 	RSA_free(rsa);
3377 
3378 	return (rv);
3379 }
3380 
3381 static KMF_RETURN
3382 exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key)
3383 {
3384 	KMF_RETURN rv;
3385 	KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa;
3386 
3387 	(void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY));
3388 	if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK)
3389 		goto cleanup;
3390 
3391 	if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK)
3392 		goto cleanup;
3393 
3394 	if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK)
3395 		goto cleanup;
3396 
3397 	if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK)
3398 		goto cleanup;
3399 
3400 cleanup:
3401 	if (rv != KMF_OK)
3402 		KMF_FreeRawKey(key);
3403 	else
3404 		key->keytype = KMF_DSA;
3405 
3406 	/*
3407 	 * Free the reference to this key, SSL will not actually free
3408 	 * the memory until the refcount == 0, so this is safe.
3409 	 */
3410 	DSA_free(dsa);
3411 
3412 	return (rv);
3413 }
3414 
3415 static KMF_RETURN
3416 add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert,
3417 	KMF_DATA **certlist, int *ncerts)
3418 {
3419 	KMF_RETURN rv = KMF_OK;
3420 	KMF_DATA *list = (*certlist);
3421 	KMF_DATA cert;
3422 	int n = (*ncerts);
3423 
3424 	if (list == NULL) {
3425 		list = (KMF_DATA *)malloc(sizeof (KMF_DATA));
3426 	} else {
3427 		list = (KMF_DATA *)realloc(list, sizeof (KMF_DATA) * (n + 1));
3428 	}
3429 
3430 	if (list == NULL)
3431 		return (KMF_ERR_MEMORY);
3432 
3433 	rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert);
3434 	if (rv == KMF_OK) {
3435 		list[n] = cert;
3436 		(*ncerts) = n + 1;
3437 
3438 		*certlist = list;
3439 	} else {
3440 		free(list);
3441 	}
3442 
3443 	return (rv);
3444 }
3445 
3446 static KMF_RETURN
3447 add_key_to_list(KMF_RAW_KEY_DATA **keylist,
3448 	KMF_RAW_KEY_DATA *newkey, int *nkeys)
3449 {
3450 	KMF_RAW_KEY_DATA *list = (*keylist);
3451 	int n = (*nkeys);
3452 
3453 	if (list == NULL) {
3454 		list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA));
3455 	} else {
3456 		list = (KMF_RAW_KEY_DATA *)realloc(list,
3457 			sizeof (KMF_RAW_KEY_DATA) * (n + 1));
3458 	}
3459 
3460 	if (list == NULL)
3461 		return (KMF_ERR_MEMORY);
3462 
3463 	list[n] = *newkey;
3464 	(*nkeys) = n + 1;
3465 
3466 	*keylist = list;
3467 
3468 	return (KMF_OK);
3469 }
3470 
3471 
3472 static KMF_RETURN
3473 convertPK12Objects(
3474 	KMF_HANDLE *kmfh,
3475 	EVP_PKEY *sslkey, X509 *sslcert, STACK_OF(X509) *sslcacerts,
3476 	KMF_RAW_KEY_DATA **keylist, int *nkeys,
3477 	KMF_DATA **certlist, int *ncerts)
3478 {
3479 	KMF_RETURN rv = KMF_OK;
3480 	KMF_RAW_KEY_DATA key;
3481 	int i;
3482 
3483 	if (sslkey != NULL) {
3484 		/* Convert SSL key to raw key */
3485 		switch (sslkey->type) {
3486 			case EVP_PKEY_RSA:
3487 				rv = exportRawRSAKey(EVP_PKEY_get1_RSA(sslkey),
3488 					&key);
3489 				if (rv != KMF_OK)
3490 					return (rv);
3491 
3492 				break;
3493 			case EVP_PKEY_DSA:
3494 				rv = exportRawDSAKey(EVP_PKEY_get1_DSA(sslkey),
3495 					&key);
3496 				if (rv != KMF_OK)
3497 					return (rv);
3498 
3499 				break;
3500 			default:
3501 				return (KMF_ERR_BAD_PARAMETER);
3502 		}
3503 
3504 		rv = add_key_to_list(keylist, &key, nkeys);
3505 		if (rv != KMF_OK)
3506 			return (rv);
3507 	}
3508 
3509 	/* Now add the certificate to the certlist */
3510 	if (sslcert != NULL) {
3511 		rv = add_cert_to_list(kmfh, sslcert, certlist, ncerts);
3512 		if (rv != KMF_OK)
3513 			return (rv);
3514 	}
3515 
3516 	/* Also add any included CA certs to the list */
3517 	for (i = 0; i != sk_X509_num(sslcacerts); i++) {
3518 		X509 *c;
3519 		/*
3520 		 * sk_X509_value() is macro that embeds a cast to (X509 *).
3521 		 * Here it translates into ((X509 *)sk_value((ca), (i))).
3522 		 * Lint is complaining about the embedded casting, and
3523 		 * to fix it, you need to fix openssl header files.
3524 		 */
3525 		/* LINTED E_BAD_PTR_CAST_ALIGN */
3526 		c = sk_X509_value(sslcacerts, i);
3527 
3528 		/* Now add the ca cert to the certlist */
3529 		rv = add_cert_to_list(kmfh, c, certlist, ncerts);
3530 		if (rv != KMF_OK)
3531 			return (rv);
3532 	}
3533 	return (rv);
3534 }
3535 
3536 KMF_RETURN
3537 openssl_read_pkcs12(KMF_HANDLE *kmfh,
3538 	char *filename, KMF_CREDENTIAL *cred,
3539 	KMF_DATA **certlist, int *ncerts,
3540 	KMF_RAW_KEY_DATA **keylist, int *nkeys)
3541 {
3542 	KMF_RETURN	rv = KMF_OK;
3543 	BIO		*bio = NULL;
3544 	EVP_PKEY	*privkey = NULL;
3545 	X509		*cert = NULL;
3546 	STACK_OF(X509)	*cacerts = NULL;
3547 
3548 	bio = BIO_new_file(filename, "rb");
3549 	if (bio == NULL) {
3550 		SET_ERROR(kmfh, ERR_get_error());
3551 		rv = KMF_ERR_OPEN_FILE;
3552 		goto end;
3553 	}
3554 
3555 	*certlist = NULL;
3556 	*keylist = NULL;
3557 	*ncerts = 0;
3558 	*nkeys = 0;
3559 	while (rv == KMF_OK) {
3560 		rv = extract_pkcs12(bio,
3561 			(uchar_t *)cred->cred,
3562 			(uint32_t)cred->credlen,
3563 			&privkey, &cert, &cacerts);
3564 
3565 		/* Reached end of import file? */
3566 		if (rv == KMF_OK && privkey == NULL &&
3567 			cert == NULL && cacerts == NULL)
3568 			break;
3569 
3570 		if (rv == KMF_OK)
3571 			/* Convert keys and certs to exportable format */
3572 			rv = convertPK12Objects(kmfh, privkey, cert, cacerts,
3573 				keylist, nkeys, certlist, ncerts);
3574 
3575 		if (privkey)
3576 			EVP_PKEY_free(privkey);
3577 
3578 		if (cert)
3579 			X509_free(cert);
3580 
3581 		if (cacerts)
3582 			sk_X509_free(cacerts);
3583 	}
3584 end:
3585 	if (bio != NULL)
3586 		(void) BIO_free(bio);
3587 
3588 	if (privkey)
3589 		EVP_PKEY_free(privkey);
3590 
3591 	if (cert)
3592 		X509_free(cert);
3593 
3594 	if (cacerts)
3595 		sk_X509_free(cacerts);
3596 
3597 	return (rv);
3598 }
3599 
3600 KMF_RETURN
3601 OpenSSL_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params,
3602 	KMF_RAW_KEY_DATA *key)
3603 {
3604 	KMF_RETURN	rv = KMF_OK;
3605 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
3606 	char		*fullpath;
3607 	EVP_PKEY	*pkey = NULL;
3608 	BIO		*bio = NULL;
3609 
3610 	if (key != NULL) {
3611 		if (key->keytype == KMF_RSA) {
3612 			pkey = ImportRawRSAKey(&key->rawdata.rsa);
3613 		} else if (key->keytype == KMF_DSA) {
3614 			pkey = ImportRawDSAKey(&key->rawdata.dsa);
3615 		} else {
3616 			rv = KMF_ERR_BAD_PARAMETER;
3617 		}
3618 	} else {
3619 		rv = KMF_ERR_BAD_PARAMETER;
3620 	}
3621 	if (rv != KMF_OK || pkey == NULL)
3622 		return (rv);
3623 
3624 	fullpath = get_fullpath(params->sslparms.dirpath,
3625 			params->sslparms.keyfile);
3626 
3627 	if (fullpath == NULL)
3628 		return (KMF_ERR_BAD_PARAMETER);
3629 
3630 	/* If the requested file exists, return an error */
3631 	if (access(fullpath, F_OK) == 0) {
3632 		free(fullpath);
3633 		return (KMF_ERR_DUPLICATE_KEYFILE);
3634 	}
3635 
3636 	bio = BIO_new_file(fullpath, "wb");
3637 	if (bio == NULL) {
3638 		SET_ERROR(kmfh, ERR_get_error());
3639 		rv = KMF_ERR_OPEN_FILE;
3640 		goto cleanup;
3641 	}
3642 
3643 	rv = ssl_write_private_key(kmfh,
3644 		params->sslparms.format,
3645 		bio, &params->cred, pkey);
3646 
3647 cleanup:
3648 	if (fullpath)
3649 		free(fullpath);
3650 
3651 	if (pkey)
3652 		EVP_PKEY_free(pkey);
3653 
3654 	if (bio)
3655 		(void) BIO_free(bio);
3656 
3657 	/* Protect the file by making it read-only */
3658 	if (rv == KMF_OK) {
3659 		(void) chmod(fullpath, 0400);
3660 	}
3661 	return (rv);
3662 }
3663 
3664 static KMF_RETURN
3665 create_deskey(DES_cblock **deskey)
3666 {
3667 	DES_cblock *key;
3668 
3669 	key = (DES_cblock *) malloc(sizeof (DES_cblock));
3670 	if (key == NULL) {
3671 		return (KMF_ERR_MEMORY);
3672 	}
3673 
3674 	if (DES_random_key(key) == 0) {
3675 		free(key);
3676 		return (KMF_ERR_KEYGEN_FAILED);
3677 	}
3678 
3679 	*deskey = key;
3680 	return (KMF_OK);
3681 }
3682 
3683 #define	KEYGEN_RETRY 3
3684 #define	DES3_KEY_SIZE 24
3685 
3686 static KMF_RETURN
3687 create_des3key(unsigned char **des3key)
3688 {
3689 	KMF_RETURN ret = KMF_OK;
3690 	DES_cblock *deskey1 = NULL;
3691 	DES_cblock *deskey2 = NULL;
3692 	DES_cblock *deskey3 = NULL;
3693 	unsigned char *newkey = NULL;
3694 	int retry;
3695 
3696 	if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) {
3697 		return (KMF_ERR_MEMORY);
3698 	}
3699 
3700 	/* create the 1st DES key */
3701 	if ((ret = create_deskey(&deskey1)) != KMF_OK) {
3702 		goto out;
3703 	}
3704 
3705 	/*
3706 	 * Create the 2nd DES key and make sure its value is different
3707 	 * from the 1st DES key.
3708 	 */
3709 	retry = 0;
3710 	do {
3711 		if (deskey2 != NULL) {
3712 			free(deskey2);
3713 			deskey2 = NULL;
3714 		}
3715 
3716 		if ((ret = create_deskey(&deskey2)) != KMF_OK) {
3717 			goto out;
3718 		}
3719 
3720 		if (memcmp((const void *) deskey1, (const void *) deskey2, 8)
3721 		    == 0) {
3722 			ret = KMF_ERR_KEYGEN_FAILED;
3723 			retry++;
3724 		}
3725 	} while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
3726 
3727 	if (ret != KMF_OK) {
3728 		goto out;
3729 	}
3730 
3731 	/*
3732 	 * Create the 3rd DES key and make sure its value is different
3733 	 * from the 2nd DES key.
3734 	 */
3735 	retry = 0;
3736 	do {
3737 		if (deskey3 != NULL) {
3738 			free(deskey3);
3739 			deskey3 = NULL;
3740 		}
3741 
3742 		if ((ret = create_deskey(&deskey3)) != KMF_OK) {
3743 			goto out;
3744 		}
3745 
3746 		if (memcmp((const void *)deskey2, (const void *)deskey3, 8)
3747 		    == 0) {
3748 			ret = KMF_ERR_KEYGEN_FAILED;
3749 			retry++;
3750 		}
3751 	} while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
3752 
3753 	if (ret != KMF_OK) {
3754 		goto out;
3755 	}
3756 
3757 	/* Concatenate 3 DES keys into a DES3 key */
3758 	(void) memcpy((void *)newkey, (const void *)deskey1, 8);
3759 	(void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8);
3760 	(void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8);
3761 	*des3key = newkey;
3762 
3763 out:
3764 	if (deskey1 != NULL)
3765 		free(deskey1);
3766 
3767 	if (deskey2 != NULL)
3768 		free(deskey2);
3769 
3770 	if (deskey3 != NULL)
3771 		free(deskey3);
3772 
3773 	if (ret != KMF_OK && newkey != NULL)
3774 		free(newkey);
3775 
3776 	return (ret);
3777 }
3778 
3779 KMF_RETURN
3780 OpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params,
3781 	KMF_KEY_HANDLE *symkey)
3782 {
3783 	KMF_RETURN ret = KMF_OK;
3784 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3785 	char *fullpath = NULL;
3786 	KMF_RAW_SYM_KEY *rkey = NULL;
3787 	DES_cblock *deskey = NULL;
3788 	unsigned char *des3key = NULL;
3789 	unsigned char *random = NULL;
3790 	int fd = -1;
3791 
3792 	if (kmfh == NULL)
3793 		return (KMF_ERR_UNINITIALIZED);
3794 
3795 	if (params == NULL || params->sslparms.keyfile == NULL) {
3796 		return (KMF_ERR_BAD_PARAMETER);
3797 	}
3798 
3799 	fullpath = get_fullpath(params->sslparms.dirpath,
3800 		params->sslparms.keyfile);
3801 	if (fullpath == NULL)
3802 		return (KMF_ERR_BAD_PARAMETER);
3803 
3804 	/* If the requested file exists, return an error */
3805 	if (access(fullpath, F_OK) == 0) {
3806 		free(fullpath);
3807 		return (KMF_ERR_DUPLICATE_KEYFILE);
3808 	}
3809 
3810 	fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400);
3811 	if (fd == -1) {
3812 		ret = KMF_ERR_OPEN_FILE;
3813 		goto out;
3814 	}
3815 
3816 	rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
3817 	if (rkey == NULL) {
3818 		ret = KMF_ERR_MEMORY;
3819 		goto out;
3820 	}
3821 	(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
3822 
3823 	if (params->keytype == KMF_DES) {
3824 		if ((ret = create_deskey(&deskey)) != KMF_OK) {
3825 			goto out;
3826 		}
3827 		rkey->keydata.val = (uchar_t *)deskey;
3828 		rkey->keydata.len = 8;
3829 
3830 		symkey->keyalg = KMF_DES;
3831 
3832 	} else if (params->keytype == KMF_DES3) {
3833 		if ((ret = create_des3key(&des3key)) != KMF_OK) {
3834 			goto out;
3835 		}
3836 		rkey->keydata.val = (uchar_t *)des3key;
3837 		rkey->keydata.len = DES3_KEY_SIZE;
3838 		symkey->keyalg = KMF_DES3;
3839 
3840 	} else if (params->keytype == KMF_AES || params->keytype == KMF_RC4) {
3841 		int bytes;
3842 
3843 		if (params->keylength % 8 != 0) {
3844 			ret = KMF_ERR_BAD_KEY_SIZE;
3845 			goto out;
3846 		}
3847 
3848 		if (params->keytype == KMF_AES) {
3849 			if (params->keylength != 128 &&
3850 			    params->keylength != 192 &&
3851 			    params->keylength != 256) {
3852 				ret = KMF_ERR_BAD_KEY_SIZE;
3853 				goto out;
3854 			}
3855 		}
3856 
3857 		bytes = params->keylength/8;
3858 		random = malloc(bytes);
3859 		if (random == NULL) {
3860 			ret = KMF_ERR_MEMORY;
3861 			goto out;
3862 		}
3863 		if (RAND_bytes(random, bytes) != 1) {
3864 			ret = KMF_ERR_KEYGEN_FAILED;
3865 			goto out;
3866 		}
3867 
3868 		rkey->keydata.val = (uchar_t *)random;
3869 		rkey->keydata.len = bytes;
3870 		symkey->keyalg = params->keytype;
3871 
3872 	} else {
3873 		ret = KMF_ERR_BAD_KEY_TYPE;
3874 		goto out;
3875 	}
3876 
3877 	(void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len);
3878 
3879 	symkey->kstype = KMF_KEYSTORE_OPENSSL;
3880 	symkey->keyclass = KMF_SYMMETRIC;
3881 	symkey->keylabel = (char *)fullpath;
3882 	symkey->israw = TRUE;
3883 	symkey->keyp = rkey;
3884 
3885 out:
3886 	if (fd != -1)
3887 		(void) close(fd);
3888 
3889 	if (ret != KMF_OK && fullpath != NULL) {
3890 		free(fullpath);
3891 	}
3892 	if (ret != KMF_OK) {
3893 		KMF_FreeRawSymKey(rkey);
3894 		symkey->keyp = NULL;
3895 		symkey->keyalg = KMF_KEYALG_NONE;
3896 	}
3897 
3898 	return (ret);
3899 }
3900 
3901 
3902 KMF_RETURN
3903 OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, KMF_VERIFYCRL_PARAMS *params)
3904 {
3905 	KMF_RETURN	ret = KMF_OK;
3906 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
3907 	BIO		*bcrl = NULL;
3908 	X509_CRL   	*xcrl = NULL;
3909 	X509		*xcert = NULL;
3910 	EVP_PKEY	*pkey;
3911 	int		sslret;
3912 	KMF_ENCODE_FORMAT crl_format;
3913 	unsigned char	*p;
3914 	long		len;
3915 
3916 	if (params->crl_name == NULL || params->tacert == NULL) {
3917 		return (KMF_ERR_BAD_PARAMETER);
3918 	}
3919 
3920 	ret = KMF_GetFileFormat(params->crl_name, &crl_format);
3921 	if (ret != KMF_OK)
3922 		return (ret);
3923 
3924 	bcrl = BIO_new_file(params->crl_name, "rb");
3925 	if (bcrl == NULL)	{
3926 		SET_ERROR(kmfh, ERR_get_error());
3927 		ret = KMF_ERR_OPEN_FILE;
3928 		goto cleanup;
3929 	}
3930 
3931 	if (crl_format == KMF_FORMAT_ASN1) {
3932 		xcrl = d2i_X509_CRL_bio(bcrl, NULL);
3933 	} else if (crl_format == KMF_FORMAT_PEM) {
3934 		xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
3935 	} else {
3936 		ret = KMF_ERR_BAD_PARAMETER;
3937 		goto cleanup;
3938 	}
3939 
3940 	if (xcrl == NULL) {
3941 		SET_ERROR(kmfh, ERR_get_error());
3942 		ret = KMF_ERR_BAD_CRLFILE;
3943 		goto cleanup;
3944 	}
3945 
3946 	p = params->tacert->Data;
3947 	len = params->tacert->Length;
3948 	xcert = d2i_X509(NULL, (const uchar_t **)&p, len);
3949 
3950 	if (xcert == NULL) {
3951 		SET_ERROR(kmfh, ERR_get_error());
3952 		ret = KMF_ERR_BAD_CERTFILE;
3953 		goto cleanup;
3954 	}
3955 
3956 	/* Get issuer certificate public key */
3957 	pkey = X509_get_pubkey(xcert);
3958 	if (!pkey) {
3959 		SET_ERROR(kmfh, ERR_get_error());
3960 		ret = KMF_ERR_BAD_CERT_FORMAT;
3961 		goto cleanup;
3962 	}
3963 
3964 	/* Verify CRL signature */
3965 	sslret = X509_CRL_verify(xcrl, pkey);
3966 	EVP_PKEY_free(pkey);
3967 	if (sslret > 0) {
3968 		ret = KMF_OK;
3969 	} else {
3970 		SET_ERROR(kmfh, sslret);
3971 		ret = KMF_ERR_BAD_CRLFILE;
3972 	}
3973 
3974 cleanup:
3975 	if (bcrl != NULL)
3976 		(void) BIO_free(bcrl);
3977 
3978 	if (xcrl != NULL)
3979 		X509_CRL_free(xcrl);
3980 
3981 	if (xcert != NULL)
3982 		X509_free(xcert);
3983 
3984 	return (ret);
3985 
3986 }
3987 
3988 KMF_RETURN
3989 OpenSSL_CheckCRLDate(KMF_HANDLE_T handle,
3990 	KMF_CHECKCRLDATE_PARAMS *params)
3991 {
3992 
3993 	KMF_RETURN	ret = KMF_OK;
3994 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
3995 	KMF_ENCODE_FORMAT crl_format;
3996 	BIO		*bcrl = NULL;
3997 	X509_CRL   	*xcrl = NULL;
3998 	int		i;
3999 
4000 	if (params == NULL || params->crl_name == NULL) {
4001 		return (KMF_ERR_BAD_PARAMETER);
4002 	}
4003 
4004 	ret = KMF_IsCRLFile(handle, params->crl_name, &crl_format);
4005 	if (ret != KMF_OK)
4006 		return (ret);
4007 
4008 	bcrl = BIO_new_file(params->crl_name, "rb");
4009 	if (bcrl == NULL)	{
4010 		SET_ERROR(kmfh, ERR_get_error());
4011 		ret = KMF_ERR_OPEN_FILE;
4012 		goto cleanup;
4013 	}
4014 
4015 	if (crl_format == KMF_FORMAT_ASN1) {
4016 		xcrl = d2i_X509_CRL_bio(bcrl, NULL);
4017 	} else if (crl_format == KMF_FORMAT_PEM) {
4018 		xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
4019 	}
4020 
4021 	if (xcrl == NULL) {
4022 		SET_ERROR(kmfh, ERR_get_error());
4023 		ret = KMF_ERR_BAD_CRLFILE;
4024 		goto cleanup;
4025 	}
4026 
4027 	i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL);
4028 	if (i >= 0) {
4029 		ret = KMF_ERR_VALIDITY_PERIOD;
4030 		goto cleanup;
4031 	}
4032 
4033 	if (X509_CRL_get_nextUpdate(xcrl)) {
4034 		i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL);
4035 
4036 		if (i <= 0) {
4037 			ret = KMF_ERR_VALIDITY_PERIOD;
4038 			goto cleanup;
4039 		}
4040 	}
4041 
4042 	ret = KMF_OK;
4043 
4044 cleanup:
4045 	if (bcrl != NULL)
4046 		(void) BIO_free(bcrl);
4047 
4048 	if (xcrl != NULL)
4049 		X509_CRL_free(xcrl);
4050 
4051 	return (ret);
4052 }
4053 
4054 /*
4055  * Check a file to see if it is a CRL file with PEM or DER format.
4056  * If success, return its format in the "pformat" argument.
4057  */
4058 KMF_RETURN
4059 OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat)
4060 {
4061 	KMF_RETURN	ret = KMF_OK;
4062 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4063 	BIO		*bio = NULL;
4064 	X509_CRL   	*xcrl = NULL;
4065 
4066 	if (filename == NULL) {
4067 		return (KMF_ERR_BAD_PARAMETER);
4068 	}
4069 
4070 	bio = BIO_new_file(filename, "rb");
4071 	if (bio == NULL)	{
4072 		SET_ERROR(kmfh, ERR_get_error());
4073 		ret = KMF_ERR_OPEN_FILE;
4074 		goto out;
4075 	}
4076 
4077 	if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) {
4078 		*pformat = KMF_FORMAT_PEM;
4079 		goto out;
4080 	}
4081 	(void) BIO_free(bio);
4082 
4083 	/*
4084 	 * Now try to read it as raw DER data.
4085 	 */
4086 	bio = BIO_new_file(filename, "rb");
4087 	if (bio == NULL)	{
4088 		SET_ERROR(kmfh, ERR_get_error());
4089 		ret = KMF_ERR_OPEN_FILE;
4090 		goto out;
4091 	}
4092 
4093 	if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) {
4094 		*pformat = KMF_FORMAT_ASN1;
4095 	} else {
4096 		ret = KMF_ERR_BAD_CRLFILE;
4097 	}
4098 
4099 out:
4100 	if (bio != NULL)
4101 		(void) BIO_free(bio);
4102 
4103 	if (xcrl != NULL)
4104 		X509_CRL_free(xcrl);
4105 
4106 	return (ret);
4107 }
4108 
4109 /*
4110  * Check a file to see if it is a certficate file with PEM or DER format.
4111  * If success, return its format in the pformat argument.
4112  */
4113 KMF_RETURN
4114 OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename,
4115 	KMF_ENCODE_FORMAT *pformat)
4116 {
4117 	KMF_RETURN	ret = KMF_OK;
4118 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4119 	BIO		*bio = NULL;
4120 	X509		*xcert = NULL;
4121 
4122 	if (filename == NULL) {
4123 		return (KMF_ERR_BAD_PARAMETER);
4124 	}
4125 
4126 	ret = KMF_GetFileFormat(filename, pformat);
4127 	if (ret != KMF_OK)
4128 		return (ret);
4129 
4130 	bio = BIO_new_file(filename, "rb");
4131 	if (bio == NULL)	{
4132 		SET_ERROR(kmfh, ERR_get_error());
4133 		ret = KMF_ERR_OPEN_FILE;
4134 		goto out;
4135 	}
4136 
4137 	if ((*pformat) == KMF_FORMAT_PEM) {
4138 		if ((xcert = PEM_read_bio_X509(bio, NULL,
4139 			NULL, NULL)) == NULL) {
4140 			ret = KMF_ERR_BAD_CERTFILE;
4141 		}
4142 	} else if ((*pformat) == KMF_FORMAT_ASN1) {
4143 		if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) {
4144 			ret = KMF_ERR_BAD_CERTFILE;
4145 		}
4146 	} else {
4147 		ret = KMF_ERR_BAD_CERTFILE;
4148 	}
4149 
4150 out:
4151 	if (bio != NULL)
4152 		(void) BIO_free(bio);
4153 
4154 	if (xcert != NULL)
4155 		X509_free(xcert);
4156 
4157 	return (ret);
4158 }
4159 
4160 KMF_RETURN
4161 OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
4162     KMF_RAW_SYM_KEY *rkey)
4163 {
4164 	KMF_RETURN	rv = KMF_OK;
4165 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4166 	KMF_DATA	keyvalue;
4167 
4168 	if (kmfh == NULL)
4169 		return (KMF_ERR_UNINITIALIZED);
4170 
4171 	if (symkey == NULL || rkey == NULL)
4172 		return (KMF_ERR_BAD_PARAMETER);
4173 	else if (symkey->keyclass != KMF_SYMMETRIC)
4174 		return (KMF_ERR_BAD_KEY_CLASS);
4175 
4176 	if (symkey->israw) {
4177 		KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp;
4178 
4179 		if (rawkey == NULL ||
4180 		    rawkey->keydata.val == NULL ||
4181 		    rawkey->keydata.len == 0)
4182 			return (KMF_ERR_BAD_KEYHANDLE);
4183 
4184 		rkey->keydata.len = rawkey->keydata.len;
4185 		if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
4186 			return (KMF_ERR_MEMORY);
4187 		(void) memcpy(rkey->keydata.val, rawkey->keydata.val,
4188 		    rkey->keydata.len);
4189 	} else {
4190 		rv = KMF_ReadInputFile(handle, symkey->keylabel, &keyvalue);
4191 		if (rv != KMF_OK)
4192 			return (rv);
4193 		rkey->keydata.len = keyvalue.Length;
4194 		rkey->keydata.val = keyvalue.Data;
4195 	}
4196 
4197 	return (rv);
4198 }
4199