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