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