xref: /illumos-gate/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c (revision 6ff4183c538023f1acb277f9d3b05296bb816e66)
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 exit:
1137 		(void) closedir(dirp);
1138 	} else {
1139 		KMF_DATA *certlist = NULL;
1140 		uint32_t loaded_certs = 0;
1141 
1142 		rv = load_certs(kmfh, issuer, subject, serial, validity,
1143 		    fullpath, &certlist, &loaded_certs);
1144 		if (rv != KMF_OK) {
1145 			free(fullpath);
1146 			return (rv);
1147 		}
1148 
1149 		n = 0;
1150 		if (kmf_cert != NULL && certlist != NULL) {
1151 			for (i = 0; i < loaded_certs && i < maxcerts; i++) {
1152 				kmf_cert[n].certificate.Data =
1153 				    certlist[i].Data;
1154 				kmf_cert[n].certificate.Length =
1155 				    certlist[i].Length;
1156 				kmf_cert[n].kmf_private.keystore_type =
1157 				    KMF_KEYSTORE_OPENSSL;
1158 				kmf_cert[n].kmf_private.flags =
1159 				    KMF_FLAG_CERT_VALID;
1160 				kmf_cert[n].kmf_private.label =
1161 				    strdup(fullpath);
1162 				n++;
1163 			}
1164 			/* If maxcerts < loaded_certs, clean up */
1165 			for (; i < loaded_certs; i++)
1166 				kmf_free_data(&certlist[i]);
1167 		} else if (certlist != NULL) {
1168 			for (i = 0; i < loaded_certs; i++)
1169 				kmf_free_data(&certlist[i]);
1170 			n = loaded_certs;
1171 		}
1172 		if (certlist != NULL)
1173 			free(certlist);
1174 		*num_certs = n;
1175 	}
1176 
1177 	free(fullpath);
1178 
1179 	return (rv);
1180 }
1181 
1182 void
OpenSSL_FreeKMFCert(KMF_HANDLE_T handle,KMF_X509_DER_CERT * kmf_cert)1183 OpenSSL_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert)
1184 {
1185 	if (kmf_cert != NULL) {
1186 		if (kmf_cert->certificate.Data != NULL) {
1187 			kmf_free_data(&kmf_cert->certificate);
1188 		}
1189 		if (kmf_cert->kmf_private.label)
1190 			free(kmf_cert->kmf_private.label);
1191 	}
1192 }
1193 
1194 KMF_RETURN
OpenSSL_StoreCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1195 OpenSSL_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1196 {
1197 	KMF_RETURN ret = KMF_OK;
1198 	KMF_DATA *cert = NULL;
1199 	char *outfilename = NULL;
1200 	char *dirpath = NULL;
1201 	char *fullpath = NULL;
1202 	KMF_ENCODE_FORMAT format;
1203 
1204 	/* Get the cert data */
1205 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
1206 	if (cert == NULL || cert->Data == NULL)
1207 		return (KMF_ERR_BAD_PARAMETER);
1208 
1209 	/* Check the output filename and directory attributes. */
1210 	outfilename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
1211 	    numattr);
1212 	if (outfilename == NULL)
1213 		return (KMF_ERR_BAD_PARAMETER);
1214 
1215 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1216 	fullpath = get_fullpath(dirpath, outfilename);
1217 	if (fullpath == NULL)
1218 		return (KMF_ERR_BAD_CERTFILE);
1219 
1220 	/* Check the optional format attribute */
1221 	ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
1222 	    &format, NULL);
1223 	if (ret != KMF_OK) {
1224 		/* If there is no format attribute, then default to PEM */
1225 		format = KMF_FORMAT_PEM;
1226 		ret = KMF_OK;
1227 	} else if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) {
1228 		ret = KMF_ERR_BAD_CERT_FORMAT;
1229 		goto out;
1230 	}
1231 
1232 	/* Store the certificate in the file with the specified format */
1233 	ret = kmf_create_cert_file(cert, format, fullpath);
1234 
1235 out:
1236 	if (fullpath != NULL)
1237 		free(fullpath);
1238 
1239 	return (ret);
1240 }
1241 
1242 
1243 KMF_RETURN
OpenSSL_DeleteCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1244 OpenSSL_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1245 {
1246 	KMF_RETURN rv;
1247 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1248 	KMF_DATA certdata = { 0, NULL };
1249 	char *dirpath = NULL;
1250 	char *filename = NULL;
1251 	char *fullpath = NULL;
1252 	char *issuer = NULL;
1253 	char *subject = NULL;
1254 	KMF_BIGINT *serial = NULL;
1255 	KMF_CERT_VALIDITY validity;
1256 
1257 	/*
1258 	 * Get the DIRPATH and CERT_FILENAME attributes.  They can not be
1259 	 * NULL at the same time.
1260 	 */
1261 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1262 	filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
1263 	    numattr);
1264 	fullpath = get_fullpath(dirpath, filename);
1265 	if (fullpath == NULL)
1266 		return (KMF_ERR_BAD_PARAMETER);
1267 
1268 	/* Get optional search criteria attributes */
1269 	issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
1270 	subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
1271 	serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
1272 	rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
1273 	    &validity, NULL);
1274 	if (rv != KMF_OK) {
1275 		validity = KMF_ALL_CERTS;
1276 		rv = KMF_OK;
1277 	}
1278 
1279 	if (isdir(fullpath)) {
1280 		DIR *dirp;
1281 		struct dirent *dp;
1282 
1283 		/* open all files in the directory and attempt to read them */
1284 		if ((dirp = opendir(fullpath)) == NULL) {
1285 			return (KMF_ERR_BAD_PARAMETER);
1286 		}
1287 
1288 		while ((dp = readdir(dirp)) != NULL) {
1289 			if (strcmp(dp->d_name, ".") != 0 &&
1290 			    strcmp(dp->d_name, "..") != 0) {
1291 				char *fname;
1292 
1293 				fname = get_fullpath(fullpath,
1294 				    (char *)&dp->d_name);
1295 
1296 				if (fname == NULL) {
1297 					rv = KMF_ERR_MEMORY;
1298 					break;
1299 				}
1300 
1301 				rv = kmf_load_cert(kmfh, issuer, subject,
1302 				    serial, validity, fname, &certdata);
1303 
1304 				if (rv == KMF_ERR_CERT_NOT_FOUND) {
1305 					free(fname);
1306 					kmf_free_data(&certdata);
1307 					rv = KMF_OK;
1308 					continue;
1309 				} else if (rv != KMF_OK) {
1310 					free(fname);
1311 					break;
1312 				}
1313 
1314 				if (unlink(fname) != 0) {
1315 					SET_SYS_ERROR(kmfh, errno);
1316 					rv = KMF_ERR_INTERNAL;
1317 					free(fname);
1318 					break;
1319 				}
1320 				free(fname);
1321 				kmf_free_data(&certdata);
1322 			}
1323 		}
1324 		(void) closedir(dirp);
1325 	} else {
1326 		/* Just try to load a single certificate */
1327 		rv = kmf_load_cert(kmfh, issuer, subject, serial, validity,
1328 		    fullpath, &certdata);
1329 		if (rv == KMF_OK) {
1330 			if (unlink(fullpath) != 0) {
1331 				SET_SYS_ERROR(kmfh, errno);
1332 				rv = KMF_ERR_INTERNAL;
1333 			}
1334 		}
1335 	}
1336 
1337 out:
1338 	if (fullpath != NULL)
1339 		free(fullpath);
1340 
1341 	kmf_free_data(&certdata);
1342 
1343 	return (rv);
1344 }
1345 
1346 KMF_RETURN
OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_DATA * keydata)1347 OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
1348     KMF_DATA *keydata)
1349 {
1350 	KMF_RETURN rv = KMF_OK;
1351 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1352 	int n;
1353 
1354 	if (key == NULL || keydata == NULL ||
1355 	    key->keyp == NULL)
1356 		return (KMF_ERR_BAD_PARAMETER);
1357 
1358 	if (key->keyalg == KMF_RSA) {
1359 		RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp);
1360 
1361 		if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) {
1362 			SET_ERROR(kmfh, ERR_get_error());
1363 			return (KMF_ERR_ENCODING);
1364 		}
1365 		RSA_free(pubkey);
1366 	} else if (key->keyalg == KMF_DSA) {
1367 		DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp);
1368 
1369 		if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) {
1370 			SET_ERROR(kmfh, ERR_get_error());
1371 			return (KMF_ERR_ENCODING);
1372 		}
1373 		DSA_free(pubkey);
1374 	} else {
1375 		return (KMF_ERR_BAD_PARAMETER);
1376 	}
1377 	keydata->Length = n;
1378 
1379 cleanup:
1380 	if (rv != KMF_OK) {
1381 		if (keydata->Data)
1382 			free(keydata->Data);
1383 		keydata->Data = NULL;
1384 		keydata->Length = 0;
1385 	}
1386 
1387 	return (rv);
1388 }
1389 
1390 static KMF_RETURN
ssl_write_key(KMF_HANDLE * kmfh,KMF_ENCODE_FORMAT format,BIO * out,KMF_CREDENTIAL * cred,EVP_PKEY * pkey,boolean_t private)1391 ssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out,
1392     KMF_CREDENTIAL *cred, EVP_PKEY *pkey, boolean_t private)
1393 {
1394 	int rv = 0;
1395 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
1396 	const RSA *rsa;
1397 	const DSA *dsa;
1398 #else
1399 	RSA *rsa;
1400 	DSA *dsa;
1401 #endif
1402 
1403 	if (pkey == NULL || out == NULL)
1404 		return (KMF_ERR_BAD_PARAMETER);
1405 
1406 	switch (format) {
1407 		case KMF_FORMAT_RAWKEY:
1408 			/* same as ASN.1 */
1409 		case KMF_FORMAT_ASN1:
1410 			if ((rsa = EVP_PKEY_get0_RSA(pkey)) != NULL) {
1411 				if (private)
1412 					rv = i2d_RSAPrivateKey_bio(out, rsa);
1413 				else
1414 					rv = i2d_RSAPublicKey_bio(out, rsa);
1415 			} else if ((dsa = EVP_PKEY_get0_DSA(pkey)) != NULL) {
1416 				rv = i2d_DSAPrivateKey_bio(out, dsa);
1417 			}
1418 			if (rv == 1) {
1419 				rv = KMF_OK;
1420 			} else {
1421 				SET_ERROR(kmfh, rv);
1422 			}
1423 			break;
1424 		case KMF_FORMAT_PEM:
1425 			if ((rsa = EVP_PKEY_get0_RSA(pkey)) != NULL) {
1426 				if (private)
1427 					rv = PEM_write_bio_RSAPrivateKey(out,
1428 					    rsa, NULL, NULL, 0, NULL,
1429 					    (cred != NULL ? cred->cred : NULL));
1430 				else
1431 					rv = PEM_write_bio_RSAPublicKey(out,
1432 					    rsa);
1433 			} else if ((dsa = EVP_PKEY_get0_DSA(pkey)) != NULL) {
1434 				rv = PEM_write_bio_DSAPrivateKey(out,
1435 				    dsa, NULL, NULL, 0, NULL,
1436 				    (cred != NULL ? cred->cred : NULL));
1437 			}
1438 
1439 			if (rv == 1) {
1440 				rv = KMF_OK;
1441 			} else {
1442 				SET_ERROR(kmfh, rv);
1443 			}
1444 			break;
1445 
1446 		default:
1447 			rv = KMF_ERR_BAD_PARAMETER;
1448 	}
1449 
1450 	return (rv);
1451 }
1452 
1453 KMF_RETURN
OpenSSL_CreateKeypair(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1454 OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1455 {
1456 	KMF_RETURN rv = KMF_OK;
1457 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1458 	uint32_t eValue = RSA_F4;
1459 	BIGNUM *eValue_bn = NULL;
1460 	RSA *sslPrivKey = NULL;
1461 	DSA *sslDSAKey = NULL;
1462 	EVP_PKEY *eprikey = NULL;
1463 	EVP_PKEY *epubkey = NULL;
1464 	BIO *out = NULL;
1465 	KMF_KEY_HANDLE *pubkey = NULL, *privkey = NULL;
1466 	uint32_t keylen = 1024;
1467 	uint32_t keylen_size = sizeof (uint32_t);
1468 	boolean_t storekey = TRUE;
1469 	KMF_KEY_ALG keytype = KMF_RSA;
1470 
1471 	eValue_bn = BN_new();
1472 	if (eValue_bn == NULL)
1473 		return (KMF_ERR_MEMORY);
1474 	if (BN_set_word(eValue_bn, eValue) == 0) {
1475 		rv = KMF_ERR_KEYGEN_FAILED;
1476 		goto cleanup;
1477 	}
1478 
1479 	rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr,
1480 	    &storekey, NULL);
1481 	if (rv != KMF_OK) {
1482 		/* "storekey" is optional. Default is TRUE */
1483 		rv = KMF_OK;
1484 	}
1485 
1486 	rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
1487 	    (void *)&keytype, NULL);
1488 	if (rv != KMF_OK)
1489 		/* keytype is optional.  KMF_RSA is default */
1490 		rv = KMF_OK;
1491 
1492 	pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
1493 	if (pubkey == NULL) {
1494 		rv = KMF_ERR_BAD_PARAMETER;
1495 		goto cleanup;
1496 	}
1497 
1498 	privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
1499 	if (privkey == NULL) {
1500 		rv = KMF_ERR_BAD_PARAMETER;
1501 		goto cleanup;
1502 	}
1503 
1504 	(void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
1505 	(void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
1506 
1507 	eprikey = EVP_PKEY_new();
1508 	if (eprikey == NULL) {
1509 		SET_ERROR(kmfh, ERR_get_error());
1510 		rv = KMF_ERR_KEYGEN_FAILED;
1511 		goto cleanup;
1512 	}
1513 	epubkey = EVP_PKEY_new();
1514 	if (epubkey == NULL) {
1515 		SET_ERROR(kmfh, ERR_get_error());
1516 		rv = KMF_ERR_KEYGEN_FAILED;
1517 		goto cleanup;
1518 	}
1519 	if (keytype == KMF_RSA) {
1520 		KMF_BIGINT *rsaexp = NULL;
1521 
1522 		rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attrlist, numattr);
1523 		if (rsaexp != NULL) {
1524 			if (rsaexp->len > 0 &&
1525 			    rsaexp->len <= sizeof (eValue) &&
1526 			    rsaexp->val != NULL) {
1527 				eValue = *(uint32_t *)rsaexp->val;
1528 				if (BN_set_word(eValue_bn, eValue) == 0) {
1529 					rv = KMF_ERR_BAD_PARAMETER;
1530 					goto cleanup;
1531 				}
1532 			} else {
1533 				rv = KMF_ERR_BAD_PARAMETER;
1534 				goto cleanup;
1535 			}
1536 		} else {
1537 			/* RSA Exponent is optional. Default is 0x10001 */
1538 			rv = KMF_OK;
1539 		}
1540 
1541 		rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
1542 		    &keylen, &keylen_size);
1543 		if (rv == KMF_ERR_ATTR_NOT_FOUND)
1544 			/* keylen is optional, default is 1024 */
1545 			rv = KMF_OK;
1546 		if (rv != KMF_OK) {
1547 			rv = KMF_ERR_BAD_PARAMETER;
1548 			goto cleanup;
1549 		}
1550 
1551 		sslPrivKey = RSA_new();
1552 		if (sslPrivKey == NULL ||
1553 		    RSA_generate_key_ex(sslPrivKey, keylen, eValue_bn, NULL)
1554 		    == 0) {
1555 			SET_ERROR(kmfh, ERR_get_error());
1556 			rv = KMF_ERR_KEYGEN_FAILED;
1557 		} else {
1558 			(void) EVP_PKEY_set1_RSA(eprikey, sslPrivKey);
1559 			privkey->kstype = KMF_KEYSTORE_OPENSSL;
1560 			privkey->keyalg = KMF_RSA;
1561 			privkey->keyclass = KMF_ASYM_PRI;
1562 			privkey->israw = FALSE;
1563 			privkey->keyp = (void *)eprikey;
1564 
1565 			/* OpenSSL derives the public key from the private */
1566 			(void) EVP_PKEY_set1_RSA(epubkey, sslPrivKey);
1567 			pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1568 			pubkey->keyalg = KMF_RSA;
1569 			pubkey->israw = FALSE;
1570 			pubkey->keyclass = KMF_ASYM_PUB;
1571 			pubkey->keyp = (void *)epubkey;
1572 		}
1573 	} else if (keytype == KMF_DSA) {
1574 		BIGNUM *p, *q, *g;
1575 
1576 		sslDSAKey = DSA_new();
1577 		if (sslDSAKey == NULL) {
1578 			SET_ERROR(kmfh, ERR_get_error());
1579 			return (KMF_ERR_MEMORY);
1580 		}
1581 
1582 		p = BN_bin2bn(P, sizeof (P), NULL);
1583 		q = BN_bin2bn(Q, sizeof (Q), NULL);
1584 		g = BN_bin2bn(G, sizeof (G), NULL);
1585 		if (p == NULL || q == NULL || g == NULL) {
1586 			BN_free(p);
1587 			BN_free(q);
1588 			BN_free(g);
1589 			SET_ERROR(kmfh, ERR_get_error());
1590 			rv = KMF_ERR_KEYGEN_FAILED;
1591 			goto cleanup;
1592 		}
1593 
1594 		if (DSA_set0_pqg(sslDSAKey, p, q, g) == 0) {
1595 			SET_ERROR(kmfh, ERR_get_error());
1596 			rv = KMF_ERR_KEYGEN_FAILED;
1597 			goto cleanup;
1598 		}
1599 
1600 		if (!DSA_generate_key(sslDSAKey)) {
1601 			SET_ERROR(kmfh, ERR_get_error());
1602 			rv = KMF_ERR_KEYGEN_FAILED;
1603 			goto cleanup;
1604 		}
1605 
1606 		privkey->kstype = KMF_KEYSTORE_OPENSSL;
1607 		privkey->keyalg = KMF_DSA;
1608 		privkey->keyclass = KMF_ASYM_PRI;
1609 		privkey->israw = FALSE;
1610 		if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) {
1611 			privkey->keyp = (void *)eprikey;
1612 		} else {
1613 			SET_ERROR(kmfh, ERR_get_error());
1614 			rv = KMF_ERR_KEYGEN_FAILED;
1615 			goto cleanup;
1616 		}
1617 
1618 		pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1619 		pubkey->keyalg = KMF_DSA;
1620 		pubkey->keyclass = KMF_ASYM_PUB;
1621 		pubkey->israw = FALSE;
1622 
1623 		if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) {
1624 			pubkey->keyp = (void *)epubkey;
1625 		} else {
1626 			SET_ERROR(kmfh, ERR_get_error());
1627 			rv = KMF_ERR_KEYGEN_FAILED;
1628 			goto cleanup;
1629 		}
1630 	}
1631 
1632 	if (rv != KMF_OK) {
1633 		goto cleanup;
1634 	}
1635 
1636 	if (storekey) {
1637 		KMF_ATTRIBUTE storeattrs[4]; /* max. 4 attributes needed */
1638 		int i = 0;
1639 		char *keyfile = NULL, *dirpath = NULL;
1640 		KMF_ENCODE_FORMAT format;
1641 		/*
1642 		 * Construct a new attribute arrray and call openssl_store_key
1643 		 */
1644 		kmf_set_attr_at_index(storeattrs, i, KMF_PRIVKEY_HANDLE_ATTR,
1645 		    privkey, sizeof (privkey));
1646 		i++;
1647 
1648 		dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1649 		if (dirpath != NULL) {
1650 			storeattrs[i].type = KMF_DIRPATH_ATTR;
1651 			storeattrs[i].pValue = dirpath;
1652 			storeattrs[i].valueLen = strlen(dirpath);
1653 			i++;
1654 		} else {
1655 			rv = KMF_OK; /* DIRPATH is optional */
1656 		}
1657 		keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR,
1658 		    attrlist, numattr);
1659 		if (keyfile != NULL) {
1660 			storeattrs[i].type = KMF_KEY_FILENAME_ATTR;
1661 			storeattrs[i].pValue = keyfile;
1662 			storeattrs[i].valueLen = strlen(keyfile);
1663 			i++;
1664 		} else {
1665 			goto cleanup; /* KEYFILE is required */
1666 		}
1667 		rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
1668 		    (void *)&format, NULL);
1669 		if (rv == KMF_OK) {
1670 			storeattrs[i].type = KMF_ENCODE_FORMAT_ATTR;
1671 			storeattrs[i].pValue = &format;
1672 			storeattrs[i].valueLen = sizeof (format);
1673 			i++;
1674 		}
1675 
1676 		rv = OpenSSL_StoreKey(handle, i, storeattrs);
1677 	}
1678 
1679 cleanup:
1680 	if (eValue_bn != NULL)
1681 		BN_free(eValue_bn);
1682 
1683 	if (rv != KMF_OK) {
1684 		if (eprikey != NULL)
1685 			EVP_PKEY_free(eprikey);
1686 
1687 		if (epubkey != NULL)
1688 			EVP_PKEY_free(epubkey);
1689 
1690 		if (pubkey->keylabel) {
1691 			free(pubkey->keylabel);
1692 			pubkey->keylabel = NULL;
1693 		}
1694 
1695 		if (privkey->keylabel) {
1696 			free(privkey->keylabel);
1697 			privkey->keylabel = NULL;
1698 		}
1699 
1700 		pubkey->keyp = NULL;
1701 		privkey->keyp = NULL;
1702 	}
1703 
1704 	if (sslPrivKey)
1705 		RSA_free(sslPrivKey);
1706 
1707 	if (sslDSAKey)
1708 		DSA_free(sslDSAKey);
1709 
1710 	if (out != NULL)
1711 		(void) BIO_free(out);
1712 
1713 	return (rv);
1714 }
1715 
1716 /*
1717  * Make sure the BN conversion is properly padded with 0x00
1718  * bytes.  If not, signature verification for DSA signatures
1719  * may fail in the case where the bignum value does not use
1720  * all of the bits.
1721  */
1722 static int
fixbnlen(const BIGNUM * bn,unsigned char * buf,int len)1723 fixbnlen(const BIGNUM *bn, unsigned char *buf, int len)
1724 {
1725 	int bytes = len - BN_num_bytes(bn);
1726 
1727 	/* prepend with leading 0x00 if necessary */
1728 	while (bytes-- > 0)
1729 		*buf++ = 0;
1730 
1731 	(void) BN_bn2bin(bn, buf);
1732 	/*
1733 	 * Return the desired length since we prepended it
1734 	 * with the necessary 0x00 padding.
1735 	 */
1736 	return (len);
1737 }
1738 
1739 KMF_RETURN
OpenSSL_SignData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * AlgOID,KMF_DATA * tobesigned,KMF_DATA * output)1740 OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
1741     KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output)
1742 {
1743 	KMF_RETURN ret = KMF_OK;
1744 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1745 	KMF_ALGORITHM_INDEX		AlgId;
1746 	EVP_MD_CTX *ctx;
1747 	const EVP_MD *md;
1748 
1749 	if (key == NULL || AlgOID == NULL ||
1750 	    tobesigned == NULL || output == NULL ||
1751 	    tobesigned->Data == NULL ||
1752 	    output->Data == NULL)
1753 		return (KMF_ERR_BAD_PARAMETER);
1754 
1755 	/* Map the OID to an OpenSSL algorithm */
1756 	AlgId = x509_algoid_to_algid(AlgOID);
1757 	if (AlgId == KMF_ALGID_NONE)
1758 		return (KMF_ERR_BAD_ALGORITHM);
1759 
1760 	if (key->keyalg == KMF_RSA) {
1761 		EVP_PKEY *pkey = (EVP_PKEY *)key->keyp;
1762 		uchar_t *p;
1763 		int len;
1764 		switch (AlgId) {
1765 #ifndef	OPENSSL_NO_MD5
1766 		case KMF_ALGID_MD5WithRSA:
1767 			md = EVP_md5();
1768 			break;
1769 #endif
1770 #ifndef	OPENSSL_NO_SHA
1771 		case KMF_ALGID_SHA1WithRSA:
1772 			md = EVP_sha1();
1773 			break;
1774 #endif
1775 #ifndef	OPENSSL_NO_SHA256
1776 		case KMF_ALGID_SHA256WithRSA:
1777 			md = EVP_sha256();
1778 			break;
1779 #endif
1780 #ifndef	OPENSSL_NO_SHA512
1781 		case KMF_ALGID_SHA384WithRSA:
1782 			md = EVP_sha384();
1783 			break;
1784 		case KMF_ALGID_SHA512WithRSA:
1785 			md = EVP_sha512();
1786 			break;
1787 #endif
1788 		case KMF_ALGID_RSA:
1789 			md = NULL;
1790 			break;
1791 		default:
1792 			return (KMF_ERR_BAD_ALGORITHM);
1793 		}
1794 
1795 		if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) {
1796 			RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey);
1797 
1798 			p = output->Data;
1799 			if ((len = RSA_private_encrypt(tobesigned->Length,
1800 			    tobesigned->Data, p, rsa,
1801 			    RSA_PKCS1_PADDING)) <= 0) {
1802 				SET_ERROR(kmfh, ERR_get_error());
1803 				ret = KMF_ERR_INTERNAL;
1804 			}
1805 			output->Length = len;
1806 		} else {
1807 			if ((ctx = EVP_MD_CTX_new()) == NULL)
1808 				return (KMF_ERR_MEMORY);
1809 			(void) EVP_SignInit_ex(ctx, md, NULL);
1810 			(void) EVP_SignUpdate(ctx, tobesigned->Data,
1811 			    (uint32_t)tobesigned->Length);
1812 			len = (uint32_t)output->Length;
1813 			p = output->Data;
1814 			if (!EVP_SignFinal(ctx, p, (uint32_t *)&len, pkey)) {
1815 				SET_ERROR(kmfh, ERR_get_error());
1816 				len = 0;
1817 				ret = KMF_ERR_INTERNAL;
1818 			}
1819 			output->Length = len;
1820 			EVP_MD_CTX_free(ctx);
1821 		}
1822 	} else if (key->keyalg == KMF_DSA) {
1823 		DSA *dsa = EVP_PKEY_get1_DSA(key->keyp);
1824 
1825 		uchar_t hash[EVP_MAX_MD_SIZE];
1826 		uint32_t hashlen;
1827 		DSA_SIG *dsasig;
1828 
1829 		if (AlgId == KMF_ALGID_DSA ||
1830 		    AlgId == KMF_ALGID_SHA1WithDSA)
1831 			md = EVP_sha1();
1832 		else if (AlgId == KMF_ALGID_SHA256WithDSA)
1833 			md = EVP_sha256();
1834 		else /* Bad algorithm */
1835 			return (KMF_ERR_BAD_ALGORITHM);
1836 
1837 		/*
1838 		 * OpenSSL EVP_Sign operation automatically converts to
1839 		 * ASN.1 output so we do the operations separately so we
1840 		 * are assured of NOT getting ASN.1 output returned.
1841 		 * KMF does not want ASN.1 encoded results because
1842 		 * not all mechanisms return ASN.1 encodings (PKCS#11
1843 		 * and NSS return raw signature data).
1844 		 */
1845 		if ((ctx = EVP_MD_CTX_new()) == NULL)
1846 			return (KMF_ERR_MEMORY);
1847 		(void) EVP_DigestInit_ex(ctx, md, NULL);
1848 		(void) EVP_DigestUpdate(ctx, tobesigned->Data,
1849 		    tobesigned->Length);
1850 		(void) EVP_DigestFinal_ex(ctx, hash, &hashlen);
1851 
1852 		/* Only sign first 20 bytes for SHA2 */
1853 		if (AlgId == KMF_ALGID_SHA256WithDSA)
1854 			hashlen = 20;
1855 		dsasig = DSA_do_sign(hash, hashlen, dsa);
1856 		if (dsasig != NULL) {
1857 			int i;
1858 			const BIGNUM *r, *s;
1859 
1860 			DSA_SIG_get0(dsasig, &r, &s);
1861 			output->Length = i = fixbnlen(r, output->Data,
1862 			    hashlen);
1863 
1864 			output->Length += fixbnlen(s, &output->Data[i],
1865 			    hashlen);
1866 
1867 			DSA_SIG_free(dsasig);
1868 		} else {
1869 			SET_ERROR(kmfh, ERR_get_error());
1870 		}
1871 		EVP_MD_CTX_free(ctx);
1872 	} else {
1873 		return (KMF_ERR_BAD_PARAMETER);
1874 	}
1875 cleanup:
1876 	return (ret);
1877 }
1878 
1879 KMF_RETURN
OpenSSL_DeleteKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1880 OpenSSL_DeleteKey(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1881 {
1882 	KMF_RETURN rv = KMF_OK;
1883 	KMF_KEY_HANDLE *key;
1884 	boolean_t destroy = B_TRUE;
1885 
1886 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
1887 	if (key == NULL || key->keyp == NULL)
1888 		return (KMF_ERR_BAD_PARAMETER);
1889 
1890 	rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
1891 	    (void *)&destroy, NULL);
1892 	if (rv != KMF_OK) {
1893 		/* "destroy" is optional. Default is TRUE */
1894 		rv = KMF_OK;
1895 	}
1896 
1897 	if (key->keyclass != KMF_ASYM_PUB &&
1898 	    key->keyclass != KMF_ASYM_PRI &&
1899 	    key->keyclass != KMF_SYMMETRIC)
1900 		return (KMF_ERR_BAD_KEY_CLASS);
1901 
1902 	if (key->keyclass == KMF_SYMMETRIC) {
1903 		kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp);
1904 		key->keyp = NULL;
1905 	} else {
1906 		if (key->keyp != NULL) {
1907 			EVP_PKEY_free(key->keyp);
1908 			key->keyp = NULL;
1909 		}
1910 	}
1911 
1912 	if (key->keylabel != NULL) {
1913 		EVP_PKEY *pkey = NULL;
1914 		/* If the file exists, make sure it is a proper key. */
1915 		pkey = openssl_load_key(handle, key->keylabel);
1916 		if (pkey == NULL) {
1917 			if (key->keylabel != NULL) {
1918 				free(key->keylabel);
1919 				key->keylabel = NULL;
1920 			}
1921 			return (KMF_ERR_KEY_NOT_FOUND);
1922 		}
1923 		EVP_PKEY_free(pkey);
1924 
1925 		if (destroy) {
1926 			if (unlink(key->keylabel) != 0) {
1927 				KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1928 				SET_SYS_ERROR(kmfh, errno);
1929 				rv = KMF_ERR_INTERNAL;
1930 			}
1931 		}
1932 		if (key->keylabel != NULL) {
1933 			free(key->keylabel);
1934 			key->keylabel = NULL;
1935 		}
1936 	}
1937 	return (rv);
1938 }
1939 
1940 KMF_RETURN
OpenSSL_GetErrorString(KMF_HANDLE_T handle,char ** msgstr)1941 OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
1942 {
1943 	KMF_RETURN ret = KMF_OK;
1944 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1945 	char str[256];	/* OpenSSL needs at least 120 byte buffer */
1946 
1947 	ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str));
1948 	if (strlen(str)) {
1949 		*msgstr = (char *)strdup(str);
1950 		if ((*msgstr) == NULL)
1951 			ret = KMF_ERR_MEMORY;
1952 	} else {
1953 		*msgstr = NULL;
1954 	}
1955 
1956 	return (ret);
1957 }
1958 
1959 static int
ext2NID(int kmfext)1960 ext2NID(int kmfext)
1961 {
1962 	switch (kmfext) {
1963 		case KMF_X509_EXT_KEY_USAGE:
1964 			return (NID_key_usage);
1965 		case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
1966 			return (NID_private_key_usage_period);
1967 		case KMF_X509_EXT_CERT_POLICIES:
1968 			return (NID_certificate_policies);
1969 		case KMF_X509_EXT_SUBJ_ALTNAME:
1970 			return (NID_subject_alt_name);
1971 		case KMF_X509_EXT_ISSUER_ALTNAME:
1972 			return (NID_issuer_alt_name);
1973 		case KMF_X509_EXT_BASIC_CONSTRAINTS:
1974 			return (NID_basic_constraints);
1975 		case KMF_X509_EXT_EXT_KEY_USAGE:
1976 			return (NID_ext_key_usage);
1977 		case KMF_X509_EXT_AUTH_KEY_ID:
1978 			return (NID_authority_key_identifier);
1979 		case KMF_X509_EXT_CRL_DIST_POINTS:
1980 			return (NID_crl_distribution_points);
1981 		case KMF_X509_EXT_SUBJ_KEY_ID:
1982 			return (NID_subject_key_identifier);
1983 		case KMF_X509_EXT_POLICY_MAPPINGS:
1984 			return (OBJ_sn2nid("policyMappings"));
1985 		case KMF_X509_EXT_NAME_CONSTRAINTS:
1986 			return (OBJ_sn2nid("nameConstraints"));
1987 		case KMF_X509_EXT_POLICY_CONSTRAINTS:
1988 			return (OBJ_sn2nid("policyConstraints"));
1989 		case KMF_X509_EXT_INHIBIT_ANY_POLICY:
1990 			return (OBJ_sn2nid("inhibitAnyPolicy"));
1991 		case KMF_X509_EXT_FRESHEST_CRL:
1992 			return (OBJ_sn2nid("freshestCRL"));
1993 		default:
1994 			return (NID_undef);
1995 	}
1996 }
1997 
1998 KMF_RETURN
OpenSSL_CertGetPrintable(KMF_HANDLE_T handle,const KMF_DATA * pcert,KMF_PRINTABLE_ITEM flag,char * resultStr)1999 OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert,
2000     KMF_PRINTABLE_ITEM flag, char *resultStr)
2001 {
2002 	KMF_RETURN ret = KMF_OK;
2003 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2004 	X509 *xcert = NULL;
2005 	unsigned char *outbuf = NULL;
2006 	unsigned char *outbuf_p;
2007 	int j;
2008 	int ext_index, nid, len;
2009 	BIO *mem = NULL;
2010 	STACK_OF(OPENSSL_STRING) *emlst = NULL;
2011 	X509_EXTENSION *ex;
2012 
2013 	if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) {
2014 		return (KMF_ERR_BAD_PARAMETER);
2015 	}
2016 
2017 	/* copy cert data to outbuf */
2018 	outbuf = malloc(pcert->Length);
2019 	if (outbuf == NULL) {
2020 		return (KMF_ERR_MEMORY);
2021 	}
2022 	(void) memcpy(outbuf, pcert->Data, pcert->Length);
2023 
2024 	outbuf_p = outbuf; /* use a temp pointer; required by openssl */
2025 	xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length);
2026 	if (xcert == NULL) {
2027 		SET_ERROR(kmfh, ERR_get_error());
2028 		ret = KMF_ERR_ENCODING;
2029 		goto out;
2030 	}
2031 
2032 	mem = BIO_new(BIO_s_mem());
2033 	if (mem == NULL) {
2034 		SET_ERROR(kmfh, ERR_get_error());
2035 		ret = KMF_ERR_MEMORY;
2036 		goto out;
2037 	}
2038 
2039 	switch (flag) {
2040 	case KMF_CERT_ISSUER:
2041 		(void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0,
2042 		    XN_FLAG_SEP_CPLUS_SPC);
2043 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2044 		break;
2045 
2046 	case KMF_CERT_SUBJECT:
2047 		(void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0,
2048 		    XN_FLAG_SEP_CPLUS_SPC);
2049 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2050 		break;
2051 
2052 	case KMF_CERT_VERSION:
2053 		(void) snprintf(resultStr, KMF_CERT_PRINTABLE_LEN,
2054 		    "%ld", X509_get_version(xcert));
2055 		len = strlen(resultStr);
2056 		break;
2057 
2058 	case KMF_CERT_SERIALNUM:
2059 		if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) {
2060 			(void) strcpy(resultStr, "0x");
2061 			len = BIO_gets(mem, &resultStr[2],
2062 			    KMF_CERT_PRINTABLE_LEN - 2);
2063 		}
2064 		break;
2065 
2066 	case KMF_CERT_NOTBEFORE:
2067 		(void) ASN1_TIME_print(mem, X509_getm_notBefore(xcert));
2068 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2069 		break;
2070 
2071 	case KMF_CERT_NOTAFTER:
2072 		(void) ASN1_TIME_print(mem, X509_getm_notAfter(xcert));
2073 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2074 		break;
2075 
2076 	case KMF_CERT_PUBKEY_DATA:
2077 		{
2078 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
2079 			const RSA *rsa;
2080 			const DSA *dsa;
2081 #else
2082 			RSA *rsa;
2083 			DSA *dsa;
2084 #endif
2085 
2086 			EVP_PKEY *pkey = X509_get_pubkey(xcert);
2087 			if (pkey == NULL) {
2088 				SET_ERROR(kmfh, ERR_get_error());
2089 				ret = KMF_ERR_ENCODING;
2090 				goto out;
2091 			}
2092 
2093 			if ((rsa = EVP_PKEY_get0_RSA(pkey)) != NULL) {
2094 				(void) BIO_printf(mem,
2095 				    "RSA Public Key: (%d bit)\n",
2096 				    RSA_bits(rsa));
2097 				(void) RSA_print(mem, rsa, 0);
2098 
2099 			} else if ((dsa = EVP_PKEY_get0_DSA(pkey)) != NULL) {
2100 				(void) BIO_printf(mem,
2101 				    "%12sDSA Public Key:\n", "");
2102 				(void) DSA_print(mem, dsa, 0);
2103 			} else {
2104 				(void) BIO_printf(mem,
2105 				    "%12sUnknown Public Key:\n", "");
2106 			}
2107 			(void) BIO_printf(mem, "\n");
2108 			EVP_PKEY_free(pkey);
2109 		}
2110 		len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2111 		break;
2112 	case KMF_CERT_SIGNATURE_ALG:
2113 	case KMF_CERT_PUBKEY_ALG:
2114 		{
2115 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2116 			ASN1_OBJECT *alg = NULL;
2117 #else
2118 			const ASN1_OBJECT *alg = NULL;
2119 #endif
2120 
2121 			if (flag == KMF_CERT_SIGNATURE_ALG) {
2122 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2123 				alg = xcert->sig_alg->algorithm;
2124 #else
2125 				const X509_ALGOR *sig_alg = NULL;
2126 
2127 				X509_get0_signature(NULL, &sig_alg, xcert);
2128 				if (sig_alg != NULL)
2129 					X509_ALGOR_get0(&alg, NULL, NULL,
2130 					    sig_alg);
2131 #endif
2132 			} else {
2133 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2134 				alg = xcert->cert_info->key->algor->algorithm;
2135 #else
2136 				X509_PUBKEY *key = X509_get_X509_PUBKEY(xcert);
2137 
2138 				if (key != NULL)
2139 					(void) X509_PUBKEY_get0_param(
2140 					    (ASN1_OBJECT **)&alg, NULL, 0,
2141 					    NULL, key);
2142 #endif
2143 			}
2144 
2145 			if (alg == NULL)
2146 				len = -1;
2147 			else if ((len = i2a_ASN1_OBJECT(mem, alg)) > 0)
2148 				len = BIO_read(mem, resultStr,
2149 				    KMF_CERT_PRINTABLE_LEN);
2150 		}
2151 		break;
2152 
2153 	case KMF_CERT_EMAIL:
2154 		emlst = X509_get1_email(xcert);
2155 		for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
2156 			(void) BIO_printf(mem, "%s\n",
2157 			    sk_OPENSSL_STRING_value(emlst, j));
2158 
2159 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2160 		X509_email_free(emlst);
2161 		break;
2162 	case KMF_X509_EXT_ISSUER_ALTNAME:
2163 	case KMF_X509_EXT_SUBJ_ALTNAME:
2164 	case KMF_X509_EXT_KEY_USAGE:
2165 	case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
2166 	case KMF_X509_EXT_CERT_POLICIES:
2167 	case KMF_X509_EXT_BASIC_CONSTRAINTS:
2168 	case KMF_X509_EXT_NAME_CONSTRAINTS:
2169 	case KMF_X509_EXT_POLICY_CONSTRAINTS:
2170 	case KMF_X509_EXT_EXT_KEY_USAGE:
2171 	case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2172 	case KMF_X509_EXT_AUTH_KEY_ID:
2173 	case KMF_X509_EXT_SUBJ_KEY_ID:
2174 	case KMF_X509_EXT_POLICY_MAPPINGS:
2175 	case KMF_X509_EXT_CRL_DIST_POINTS:
2176 	case KMF_X509_EXT_FRESHEST_CRL:
2177 		nid = ext2NID(flag);
2178 		if (nid == NID_undef) {
2179 			ret = KMF_ERR_EXTENSION_NOT_FOUND;
2180 			goto out;
2181 		}
2182 
2183 		ext_index = X509_get_ext_by_NID(xcert, nid, -1);
2184 		if (ext_index == -1) {
2185 			SET_ERROR(kmfh, ERR_get_error());
2186 
2187 			ret = KMF_ERR_EXTENSION_NOT_FOUND;
2188 			goto out;
2189 		}
2190 		ex = X509_get_ext(xcert, ext_index);
2191 
2192 		(void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex));
2193 
2194 		if (BIO_printf(mem, ": %s\n",
2195 		    X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) {
2196 			SET_ERROR(kmfh, ERR_get_error());
2197 			ret = KMF_ERR_ENCODING;
2198 			goto out;
2199 		}
2200 		if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) {
2201 			(void) BIO_printf(mem, "%*s", 4, "");
2202 			(void) ASN1_STRING_print(mem,
2203 			    X509_EXTENSION_get_data(ex));
2204 		}
2205 		if (BIO_write(mem, "\n", 1) <= 0) {
2206 			SET_ERROR(kmfh, ERR_get_error());
2207 			ret = KMF_ERR_ENCODING;
2208 			goto out;
2209 		}
2210 		len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2211 	}
2212 	if (len <= 0) {
2213 		SET_ERROR(kmfh, ERR_get_error());
2214 		ret = KMF_ERR_ENCODING;
2215 	}
2216 
2217 out:
2218 	if (outbuf != NULL) {
2219 		free(outbuf);
2220 	}
2221 
2222 	if (xcert != NULL) {
2223 		X509_free(xcert);
2224 	}
2225 
2226 	if (mem != NULL) {
2227 		(void) BIO_free(mem);
2228 	}
2229 
2230 	return (ret);
2231 }
2232 
2233 KMF_RETURN
OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2234 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
2235     KMF_ATTRIBUTE *attrlist)
2236 {
2237 	KMF_RETURN rv = KMF_OK;
2238 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
2239 	KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
2240 	KMF_KEY_HANDLE *key = NULL;
2241 	uint32_t numkeys = 1; /* 1 key only */
2242 	char *dirpath = NULL;
2243 	char *keyfile = NULL;
2244 	KMF_ATTRIBUTE new_attrlist[16];
2245 	int i = 0;
2246 
2247 	/*
2248 	 * This is really just a FindKey operation, reuse the
2249 	 * FindKey function.
2250 	 */
2251 	kmf_set_attr_at_index(new_attrlist, i,
2252 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2253 	i++;
2254 
2255 	kmf_set_attr_at_index(new_attrlist, i,
2256 	    KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t));
2257 	i++;
2258 
2259 	kmf_set_attr_at_index(new_attrlist, i,
2260 	    KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass));
2261 	i++;
2262 
2263 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2264 	if (key == NULL) {
2265 		return (KMF_ERR_BAD_PARAMETER);
2266 	} else {
2267 		kmf_set_attr_at_index(new_attrlist, i,
2268 		    KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
2269 		i++;
2270 	}
2271 
2272 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2273 	if (dirpath != NULL) {
2274 		kmf_set_attr_at_index(new_attrlist, i,
2275 		    KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
2276 		i++;
2277 	}
2278 
2279 	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
2280 	if (keyfile == NULL)
2281 		return (KMF_ERR_BAD_PARAMETER);
2282 	else {
2283 		kmf_set_attr_at_index(new_attrlist, i,
2284 		    KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
2285 		i++;
2286 	}
2287 
2288 	rv = OpenSSL_FindKey(handle, i, new_attrlist);
2289 	return (rv);
2290 }
2291 
2292 KMF_RETURN
OpenSSL_DecryptData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * AlgOID,KMF_DATA * ciphertext,KMF_DATA * output)2293 OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
2294     KMF_OID *AlgOID, KMF_DATA *ciphertext, KMF_DATA *output)
2295 {
2296 	KMF_RETURN		ret = KMF_OK;
2297 	RSA *rsa = NULL;
2298 	unsigned int in_len = 0, out_len = 0;
2299 	unsigned int total_decrypted = 0, modulus_len = 0;
2300 	uint8_t *in_data, *out_data;
2301 	int i, blocks;
2302 
2303 	if (key == NULL || AlgOID == NULL ||
2304 	    ciphertext == NULL || output == NULL ||
2305 	    ciphertext->Data == NULL ||
2306 	    output->Data == NULL)
2307 		return (KMF_ERR_BAD_PARAMETER);
2308 
2309 	if (key->keyalg == KMF_RSA) {
2310 		rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp);
2311 		modulus_len = RSA_size(rsa);
2312 	} else {
2313 		return (KMF_ERR_BAD_PARAMETER);
2314 	}
2315 
2316 	blocks = ciphertext->Length/modulus_len;
2317 	out_data = output->Data;
2318 	in_data = ciphertext->Data;
2319 	out_len = modulus_len - 11;
2320 	in_len = modulus_len;
2321 
2322 	for (i = 0; i < blocks; i++) {
2323 		out_len  = RSA_private_decrypt(in_len,
2324 		    in_data, out_data, rsa, RSA_PKCS1_PADDING);
2325 
2326 		if (out_len == 0) {
2327 			ret = KMF_ERR_INTERNAL;
2328 			goto cleanup;
2329 		}
2330 
2331 		out_data += out_len;
2332 		total_decrypted += out_len;
2333 		in_data += in_len;
2334 	}
2335 
2336 	output->Length = total_decrypted;
2337 
2338 cleanup:
2339 	RSA_free(rsa);
2340 	if (ret != KMF_OK)
2341 		output->Length = 0;
2342 
2343 	return (ret);
2344 
2345 }
2346 
2347 /*
2348  *  This function will create a certid from issuer_cert and user_cert.
2349  *  The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2350  *  certid memory after use.
2351  */
2352 static KMF_RETURN
create_certid(KMF_HANDLE_T handle,const KMF_DATA * issuer_cert,const KMF_DATA * user_cert,OCSP_CERTID ** certid)2353 create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert,
2354     const KMF_DATA *user_cert, OCSP_CERTID **certid)
2355 {
2356 	KMF_RETURN ret = KMF_OK;
2357 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2358 	X509   *issuer = NULL;
2359 	X509   *cert = NULL;
2360 	unsigned char *ptmp;
2361 
2362 	if (issuer_cert == NULL || user_cert == NULL) {
2363 		return (KMF_ERR_BAD_PARAMETER);
2364 	}
2365 
2366 	/* convert the DER-encoded issuer cert to an internal X509 */
2367 	ptmp = issuer_cert->Data;
2368 	issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2369 	    issuer_cert->Length);
2370 	if (issuer == NULL) {
2371 		SET_ERROR(kmfh, ERR_get_error());
2372 		ret = KMF_ERR_OCSP_BAD_ISSUER;
2373 		goto end;
2374 	}
2375 
2376 	/* convert the DER-encoded user cert to an internal X509 */
2377 	ptmp = user_cert->Data;
2378 	cert = d2i_X509(NULL, (const uchar_t **)&ptmp,
2379 	    user_cert->Length);
2380 	if (cert == NULL) {
2381 		SET_ERROR(kmfh, ERR_get_error());
2382 
2383 		ret = KMF_ERR_OCSP_BAD_CERT;
2384 		goto end;
2385 	}
2386 
2387 	/* create a CERTID */
2388 	*certid = OCSP_cert_to_id(NULL, cert, issuer);
2389 	if (*certid == NULL) {
2390 		SET_ERROR(kmfh, ERR_get_error());
2391 		ret = KMF_ERR_OCSP_CERTID;
2392 		goto end;
2393 	}
2394 
2395 end:
2396 	if (issuer != NULL) {
2397 		X509_free(issuer);
2398 	}
2399 
2400 	if (cert != NULL) {
2401 		X509_free(cert);
2402 	}
2403 
2404 	return (ret);
2405 }
2406 
2407 KMF_RETURN
OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2408 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle,
2409     int numattr, KMF_ATTRIBUTE *attrlist)
2410 {
2411 	KMF_RETURN ret = KMF_OK;
2412 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2413 	OCSP_CERTID *id = NULL;
2414 	OCSP_REQUEST *req = NULL;
2415 	BIO *derbio = NULL;
2416 	char *reqfile;
2417 	KMF_DATA *issuer_cert;
2418 	KMF_DATA *user_cert;
2419 
2420 	user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
2421 	    attrlist, numattr);
2422 	if (user_cert == NULL)
2423 		return (KMF_ERR_BAD_PARAMETER);
2424 
2425 	issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
2426 	    attrlist, numattr);
2427 	if (issuer_cert == NULL)
2428 		return (KMF_ERR_BAD_PARAMETER);
2429 
2430 	reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR,
2431 	    attrlist, numattr);
2432 	if (reqfile == NULL)
2433 		return (KMF_ERR_BAD_PARAMETER);
2434 
2435 	ret = create_certid(handle, issuer_cert, user_cert, &id);
2436 	if (ret != KMF_OK) {
2437 		return (ret);
2438 	}
2439 
2440 	/* Create an OCSP request */
2441 	req = OCSP_REQUEST_new();
2442 	if (req == NULL) {
2443 		SET_ERROR(kmfh, ERR_get_error());
2444 		ret = KMF_ERR_OCSP_CREATE_REQUEST;
2445 		goto end;
2446 	}
2447 
2448 	if (!OCSP_request_add0_id(req, id)) {
2449 		ret = KMF_ERR_OCSP_CREATE_REQUEST;
2450 		goto end;
2451 	}
2452 
2453 	/* Write the request to the output file with DER encoding */
2454 	derbio = BIO_new_file(reqfile, "wb");
2455 	if (!derbio) {
2456 		SET_ERROR(kmfh, ERR_get_error());
2457 		ret = KMF_ERR_OPEN_FILE;
2458 		goto end;
2459 	}
2460 	if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) {
2461 		ret = KMF_ERR_ENCODING;
2462 	}
2463 
2464 end:
2465 	/*
2466 	 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2467 	 * will also deallocate certid's space.
2468 	 */
2469 	if (req != NULL) {
2470 		OCSP_REQUEST_free(req);
2471 	}
2472 
2473 	if (derbio != NULL) {
2474 		(void) BIO_free(derbio);
2475 	}
2476 
2477 	return (ret);
2478 }
2479 
2480 /* ocsp_find_signer_sk() is copied from openssl source */
ocsp_find_signer_sk(STACK_OF (X509)* certs,OCSP_BASICRESP * bs)2481 static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_BASICRESP *bs)
2482 {
2483 	int i;
2484 	unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
2485 	const ASN1_OCTET_STRING *pid;
2486 
2487 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2488 	OCSP_RESPID *id = bs->tbsResponseData->responderId;
2489 
2490 	if (id->type == V_OCSP_RESPID_NAME)
2491 		return (X509_find_by_subject(certs, id->value.byName));
2492 
2493 	pid = id->value.byKey;
2494 #else
2495 	const X509_NAME *pname;
2496 
2497 	if (OCSP_resp_get0_id(bs, &pid, &pname) == 0)
2498 		return (NULL);
2499 
2500 	if (pname != NULL)
2501 		return (X509_find_by_subject(certs, (X509_NAME *)pname));
2502 #endif
2503 
2504 	/* Lookup by key hash */
2505 
2506 	/* If key hash isn't SHA1 length then forget it */
2507 	if (pid->length != SHA_DIGEST_LENGTH)
2508 		return (NULL);
2509 
2510 	keyhash = pid->data;
2511 	/* Calculate hash of each key and compare */
2512 	for (i = 0; i < sk_X509_num(certs); i++) {
2513 		X509 *x = sk_X509_value(certs, i);
2514 		/* Use pubkey_digest to get the key ID value */
2515 		(void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
2516 		if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
2517 			return (x);
2518 	}
2519 	return (NULL);
2520 }
2521 
2522 /* ocsp_find_signer() is copied from openssl source */
2523 static int
ocsp_find_signer(X509 ** psigner,OCSP_BASICRESP * bs,STACK_OF (X509)* certs,X509_STORE * st,unsigned long flags)2524 ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
2525     X509_STORE *st, unsigned long flags)
2526 {
2527 	X509 *signer;
2528 	if ((signer = ocsp_find_signer_sk(certs, bs)))	{
2529 		*psigner = signer;
2530 		return (2);
2531 	}
2532 
2533 	if (!(flags & OCSP_NOINTERN) &&
2534 	    (signer = ocsp_find_signer_sk(
2535 	    (STACK_OF(X509) *)OCSP_resp_get0_certs(bs), bs))) {
2536 		*psigner = signer;
2537 		return (1);
2538 	}
2539 	/* Maybe lookup from store if by subject name */
2540 
2541 	*psigner = NULL;
2542 	return (0);
2543 }
2544 
2545 /*
2546  * This function will verify the signature of a basic response, using
2547  * the public key from the OCSP responder certificate.
2548  */
2549 static KMF_RETURN
check_response_signature(KMF_HANDLE_T handle,OCSP_BASICRESP * bs,KMF_DATA * signer_cert,KMF_DATA * issuer_cert)2550 check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs,
2551     KMF_DATA *signer_cert, KMF_DATA *issuer_cert)
2552 {
2553 	KMF_RETURN ret = KMF_OK;
2554 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2555 	STACK_OF(X509) *cert_stack = NULL;
2556 	X509 *signer = NULL;
2557 	X509 *issuer = NULL;
2558 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2559 	EVP_PKEY *skey = NULL;
2560 #else
2561 	STACK_OF(X509) *cert_stack2 = NULL;
2562 #endif
2563 	unsigned char *ptmp;
2564 
2565 	if (bs == NULL || issuer_cert == NULL)
2566 		return (KMF_ERR_BAD_PARAMETER);
2567 
2568 	/*
2569 	 * Find the certificate that signed the basic response.
2570 	 *
2571 	 * If signer_cert is not NULL, we will use that as the signer cert.
2572 	 * Otherwise, we will check if the issuer cert is actually the signer.
2573 	 * If we still do not find a signer, we will look for it from the
2574 	 * certificate list came with the response file.
2575 	 */
2576 	if (signer_cert != NULL) {
2577 		ptmp = signer_cert->Data;
2578 		signer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2579 		    signer_cert->Length);
2580 		if (signer == NULL) {
2581 			SET_ERROR(kmfh, ERR_get_error());
2582 			ret = KMF_ERR_OCSP_BAD_SIGNER;
2583 			goto end;
2584 		}
2585 	} else {
2586 		/*
2587 		 * Convert the issuer cert into X509 and push it into a
2588 		 * stack to be used by ocsp_find_signer().
2589 		 */
2590 		ptmp = issuer_cert->Data;
2591 		issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2592 		    issuer_cert->Length);
2593 		if (issuer == NULL) {
2594 			SET_ERROR(kmfh, ERR_get_error());
2595 			ret = KMF_ERR_OCSP_BAD_ISSUER;
2596 			goto end;
2597 		}
2598 
2599 		if ((cert_stack = sk_X509_new_null()) == NULL) {
2600 			ret = KMF_ERR_INTERNAL;
2601 			goto end;
2602 		}
2603 
2604 		if (sk_X509_push(cert_stack, issuer) == 0) {
2605 			ret = KMF_ERR_INTERNAL;
2606 			goto end;
2607 		}
2608 
2609 		ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0);
2610 		if (!ret) {
2611 			/* can not find the signer */
2612 			ret = KMF_ERR_OCSP_BAD_SIGNER;
2613 			goto end;
2614 		}
2615 	}
2616 
2617 	/* Verify the signature of the response */
2618 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2619 	skey = X509_get_pubkey(signer);
2620 	if (skey == NULL) {
2621 		ret = KMF_ERR_OCSP_BAD_SIGNER;
2622 		goto end;
2623 	}
2624 
2625 	ret = OCSP_BASICRESP_verify(bs, skey, 0);
2626 #else
2627 	/*
2628 	 * Technique based on
2629 	 * https://mta.openssl.org/pipermail/openssl-users/
2630 	 *	2017-October/006814.html
2631 	 */
2632 	if ((cert_stack2 = sk_X509_new_null()) == NULL) {
2633 		ret = KMF_ERR_INTERNAL;
2634 		goto end;
2635 	}
2636 
2637 	if (sk_X509_push(cert_stack2, signer) == 0) {
2638 		ret = KMF_ERR_INTERNAL;
2639 		goto end;
2640 	}
2641 
2642 	ret = OCSP_basic_verify(bs, cert_stack2, NULL, OCSP_NOVERIFY);
2643 #endif
2644 
2645 	if (ret == 0) {
2646 		ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE;
2647 		goto end;
2648 	}
2649 
2650 end:
2651 	if (issuer != NULL) {
2652 		X509_free(issuer);
2653 	}
2654 
2655 	if (signer != NULL) {
2656 		X509_free(signer);
2657 	}
2658 
2659 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2660 	if (skey != NULL) {
2661 		EVP_PKEY_free(skey);
2662 	}
2663 #else
2664 	if (cert_stack2 != NULL) {
2665 		sk_X509_free(cert_stack2);
2666 	}
2667 #endif
2668 
2669 	if (cert_stack != NULL) {
2670 		sk_X509_free(cert_stack);
2671 	}
2672 
2673 	return (ret);
2674 }
2675 
2676 KMF_RETURN
OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2677 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, int numattr,
2678     KMF_ATTRIBUTE *attrlist)
2679 {
2680 	KMF_RETURN ret = KMF_OK;
2681 	BIO *derbio = NULL;
2682 	OCSP_RESPONSE *resp = NULL;
2683 	OCSP_BASICRESP *bs = NULL;
2684 	OCSP_CERTID *id = NULL;
2685 	OCSP_SINGLERESP *single = NULL;
2686 	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
2687 	int index, status, reason;
2688 	KMF_DATA *issuer_cert;
2689 	KMF_DATA *user_cert;
2690 	KMF_DATA *signer_cert;
2691 	KMF_DATA *response;
2692 	int *response_reason, *response_status, *cert_status;
2693 	boolean_t ignore_response_sign = B_FALSE;	/* default is FALSE */
2694 	uint32_t response_lifetime;
2695 
2696 	issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
2697 	    attrlist, numattr);
2698 	if (issuer_cert == NULL)
2699 		return (KMF_ERR_BAD_PARAMETER);
2700 
2701 	user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
2702 	    attrlist, numattr);
2703 	if (user_cert == NULL)
2704 		return (KMF_ERR_BAD_PARAMETER);
2705 
2706 	response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR,
2707 	    attrlist, numattr);
2708 	if (response == NULL)
2709 		return (KMF_ERR_BAD_PARAMETER);
2710 
2711 	response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR,
2712 	    attrlist, numattr);
2713 	if (response_status == NULL)
2714 		return (KMF_ERR_BAD_PARAMETER);
2715 
2716 	response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR,
2717 	    attrlist, numattr);
2718 	if (response_reason == NULL)
2719 		return (KMF_ERR_BAD_PARAMETER);
2720 
2721 	cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR,
2722 	    attrlist, numattr);
2723 	if (cert_status == NULL)
2724 		return (KMF_ERR_BAD_PARAMETER);
2725 
2726 	/* Read in the response */
2727 	derbio = BIO_new_mem_buf(response->Data, response->Length);
2728 	if (!derbio) {
2729 		ret = KMF_ERR_MEMORY;
2730 		return (ret);
2731 	}
2732 
2733 	resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
2734 	if (resp == NULL) {
2735 		ret = KMF_ERR_OCSP_MALFORMED_RESPONSE;
2736 		goto end;
2737 	}
2738 
2739 	/* Check the response status */
2740 	status = OCSP_response_status(resp);
2741 	*response_status = status;
2742 	if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
2743 		ret = KMF_ERR_OCSP_RESPONSE_STATUS;
2744 		goto end;
2745 	}
2746 
2747 #ifdef DEBUG
2748 	printf("Successfully checked the response file status.\n");
2749 #endif /* DEBUG */
2750 
2751 	/* Extract basic response */
2752 	bs = OCSP_response_get1_basic(resp);
2753 	if (bs == NULL) {
2754 		ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE;
2755 		goto end;
2756 	}
2757 
2758 #ifdef DEBUG
2759 	printf("Successfully retrieved the basic response.\n");
2760 #endif /* DEBUG */
2761 
2762 	/* Check the basic response signature if required */
2763 	ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr,
2764 	    (void *)&ignore_response_sign, NULL);
2765 	if (ret != KMF_OK)
2766 		ret = KMF_OK;
2767 
2768 	signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR,
2769 	    attrlist, numattr);
2770 
2771 	if (ignore_response_sign == B_FALSE) {
2772 		ret = check_response_signature(handle, bs,
2773 		    signer_cert, issuer_cert);
2774 		if (ret != KMF_OK)
2775 			goto end;
2776 	}
2777 
2778 #ifdef DEBUG
2779 	printf("Successfully verified the response signature.\n");
2780 #endif /* DEBUG */
2781 
2782 	/* Create a certid for the certificate in question */
2783 	ret = create_certid(handle, issuer_cert, user_cert, &id);
2784 	if (ret != KMF_OK) {
2785 		ret = KMF_ERR_OCSP_CERTID;
2786 		goto end;
2787 	}
2788 
2789 #ifdef DEBUG
2790 	printf("successfully created a certid for the cert.\n");
2791 #endif /* DEBUG */
2792 
2793 	/* Find the index of the single response for the certid */
2794 	index = OCSP_resp_find(bs, id, -1);
2795 	if (index < 0) {
2796 		/* cound not find this certificate in the response */
2797 		ret = KMF_ERR_OCSP_UNKNOWN_CERT;
2798 		goto end;
2799 	}
2800 
2801 #ifdef DEBUG
2802 	printf("Successfully found the single response index for the cert.\n");
2803 #endif /* DEBUG */
2804 
2805 	/* Retrieve the single response and get the cert status */
2806 	single = OCSP_resp_get0(bs, index);
2807 	status = OCSP_single_get0_status(single, &reason, &rev, &thisupd,
2808 	    &nextupd);
2809 	if (status == V_OCSP_CERTSTATUS_GOOD) {
2810 		*cert_status = OCSP_GOOD;
2811 	} else if (status == V_OCSP_CERTSTATUS_UNKNOWN) {
2812 		*cert_status = OCSP_UNKNOWN;
2813 	} else { /* revoked */
2814 		*cert_status = OCSP_REVOKED;
2815 		*response_reason = reason;
2816 	}
2817 	ret = KMF_OK;
2818 
2819 	/* resp. time is optional, so we don't care about the return code. */
2820 	(void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr,
2821 	    (void *)&response_lifetime, NULL);
2822 
2823 	if (!OCSP_check_validity(thisupd, nextupd, 300,
2824 	    response_lifetime)) {
2825 		ret = KMF_ERR_OCSP_STATUS_TIME_INVALID;
2826 		goto end;
2827 	}
2828 
2829 #ifdef DEBUG
2830 	printf("Successfully verify the time.\n");
2831 #endif /* DEBUG */
2832 
2833 end:
2834 	if (derbio != NULL)
2835 		(void) BIO_free(derbio);
2836 
2837 	if (resp != NULL)
2838 		OCSP_RESPONSE_free(resp);
2839 
2840 	if (bs != NULL)
2841 		OCSP_BASICRESP_free(bs);
2842 
2843 	if (id != NULL)
2844 		OCSP_CERTID_free(id);
2845 
2846 	return (ret);
2847 }
2848 
2849 static KMF_RETURN
fetch_key(KMF_HANDLE_T handle,char * path,KMF_KEY_CLASS keyclass,KMF_KEY_HANDLE * key)2850 fetch_key(KMF_HANDLE_T handle, char *path, KMF_KEY_CLASS keyclass,
2851     KMF_KEY_HANDLE *key)
2852 {
2853 	KMF_RETURN rv = KMF_OK;
2854 	EVP_PKEY *pkey = NULL;
2855 	KMF_RAW_SYM_KEY *rkey = NULL;
2856 
2857 	if (keyclass == KMF_ASYM_PRI ||
2858 	    keyclass == KMF_ASYM_PUB) {
2859 		pkey = openssl_load_key(handle, path);
2860 		if (pkey == NULL) {
2861 			return (KMF_ERR_KEY_NOT_FOUND);
2862 		}
2863 		if (key != NULL) {
2864 			if (EVP_PKEY_get0_RSA(pkey) != NULL)
2865 				key->keyalg = KMF_RSA;
2866 			else if (EVP_PKEY_get0_DSA(pkey) != NULL)
2867 				key->keyalg = KMF_DSA;
2868 
2869 			key->kstype = KMF_KEYSTORE_OPENSSL;
2870 			key->keyclass = keyclass;
2871 			key->keyp = (void *)pkey;
2872 			key->israw = FALSE;
2873 			if (path != NULL &&
2874 			    ((key->keylabel = strdup(path)) == NULL)) {
2875 				EVP_PKEY_free(pkey);
2876 				return (KMF_ERR_MEMORY);
2877 			}
2878 		} else {
2879 			EVP_PKEY_free(pkey);
2880 			pkey = NULL;
2881 		}
2882 	} else if (keyclass == KMF_SYMMETRIC) {
2883 		KMF_ENCODE_FORMAT fmt;
2884 		/*
2885 		 * If the file is a recognized format,
2886 		 * then it is NOT a symmetric key.
2887 		 */
2888 		rv = kmf_get_file_format(path, &fmt);
2889 		if (rv == KMF_OK || fmt != 0) {
2890 			return (KMF_ERR_KEY_NOT_FOUND);
2891 		} else if (rv == KMF_ERR_ENCODING) {
2892 			/*
2893 			 * If we don't know the encoding,
2894 			 * it is probably  a symmetric key.
2895 			 */
2896 			rv = KMF_OK;
2897 		} else if (rv == KMF_ERR_OPEN_FILE) {
2898 			return (KMF_ERR_KEY_NOT_FOUND);
2899 		}
2900 
2901 		if (key != NULL) {
2902 			KMF_DATA keyvalue;
2903 			rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
2904 			if (rkey == NULL) {
2905 				rv = KMF_ERR_MEMORY;
2906 				goto out;
2907 			}
2908 
2909 			(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
2910 			rv = kmf_read_input_file(handle, path, &keyvalue);
2911 			if (rv != KMF_OK)
2912 				goto out;
2913 
2914 			rkey->keydata.len = keyvalue.Length;
2915 			rkey->keydata.val = keyvalue.Data;
2916 
2917 			key->kstype = KMF_KEYSTORE_OPENSSL;
2918 			key->keyclass = keyclass;
2919 			key->israw = TRUE;
2920 			key->keyp = (void *)rkey;
2921 			if (path != NULL &&
2922 			    ((key->keylabel = strdup(path)) == NULL)) {
2923 				rv = KMF_ERR_MEMORY;
2924 			}
2925 		}
2926 	}
2927 out:
2928 	if (rv != KMF_OK) {
2929 		if (rkey != NULL) {
2930 			kmf_free_raw_sym_key(rkey);
2931 		}
2932 		if (pkey != NULL)
2933 			EVP_PKEY_free(pkey);
2934 
2935 		if (key != NULL) {
2936 			key->keyalg = KMF_KEYALG_NONE;
2937 			key->keyclass = KMF_KEYCLASS_NONE;
2938 			key->keyp = NULL;
2939 		}
2940 	}
2941 
2942 	return (rv);
2943 }
2944 
2945 KMF_RETURN
OpenSSL_FindKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2946 OpenSSL_FindKey(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
2947 {
2948 	KMF_RETURN rv = KMF_OK;
2949 	char *fullpath = NULL;
2950 	uint32_t maxkeys;
2951 	KMF_KEY_HANDLE *key;
2952 	uint32_t *numkeys;
2953 	KMF_KEY_CLASS keyclass;
2954 	KMF_RAW_KEY_DATA *rawkey;
2955 	char *dirpath;
2956 	char *keyfile;
2957 
2958 	if (handle == NULL)
2959 		return (KMF_ERR_BAD_PARAMETER);
2960 
2961 	numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
2962 	if (numkeys == NULL)
2963 		return (KMF_ERR_BAD_PARAMETER);
2964 
2965 	rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
2966 	    (void *)&keyclass, NULL);
2967 	if (rv != KMF_OK)
2968 		return (KMF_ERR_BAD_PARAMETER);
2969 
2970 	if (keyclass != KMF_ASYM_PUB &&
2971 	    keyclass != KMF_ASYM_PRI &&
2972 	    keyclass != KMF_SYMMETRIC)
2973 		return (KMF_ERR_BAD_KEY_CLASS);
2974 
2975 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2976 	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
2977 
2978 	fullpath = get_fullpath(dirpath, keyfile);
2979 
2980 	if (fullpath == NULL)
2981 		return (KMF_ERR_BAD_PARAMETER);
2982 
2983 	maxkeys = *numkeys;
2984 	if (maxkeys == 0)
2985 		maxkeys = 0xFFFFFFFF;
2986 	*numkeys = 0;
2987 
2988 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2989 	/* it is okay to have "keys" contains NULL */
2990 
2991 	/*
2992 	 * The caller may want a list of the raw key data as well.
2993 	 * Useful for importing keys from a file into other keystores.
2994 	 */
2995 	rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
2996 
2997 	if (isdir(fullpath)) {
2998 		DIR *dirp;
2999 		struct dirent *dp;
3000 		int n = 0;
3001 
3002 		/* open all files in the directory and attempt to read them */
3003 		if ((dirp = opendir(fullpath)) == NULL) {
3004 			return (KMF_ERR_BAD_PARAMETER);
3005 		}
3006 		rewinddir(dirp);
3007 		while ((dp = readdir(dirp)) != NULL && n < maxkeys) {
3008 			if (strcmp(dp->d_name, ".") &&
3009 			    strcmp(dp->d_name, "..")) {
3010 				char *fname;
3011 
3012 				fname = get_fullpath(fullpath,
3013 				    (char *)&dp->d_name);
3014 
3015 				rv = fetch_key(handle, fname,
3016 				    keyclass, key ? &key[n] : NULL);
3017 
3018 				if (rv == KMF_OK) {
3019 					if (key != NULL && rawkey != NULL)
3020 						rv = convertToRawKey(
3021 						    key[n].keyp, &rawkey[n]);
3022 					n++;
3023 				}
3024 
3025 				if (rv != KMF_OK || key == NULL)
3026 					free(fname);
3027 			}
3028 		}
3029 		(void) closedir(dirp);
3030 		free(fullpath);
3031 		(*numkeys) = n;
3032 	} else {
3033 		rv = fetch_key(handle, fullpath, keyclass, key);
3034 		if (rv == KMF_OK)
3035 			(*numkeys) = 1;
3036 
3037 		if (rv != KMF_OK || key == NULL)
3038 			free(fullpath);
3039 
3040 		if (rv == KMF_OK && key != NULL && rawkey != NULL) {
3041 			rv = convertToRawKey(key->keyp, rawkey);
3042 		}
3043 	}
3044 
3045 	if (rv == KMF_OK && (*numkeys) == 0)
3046 		rv = KMF_ERR_KEY_NOT_FOUND;
3047 	else if (rv == KMF_ERR_KEY_NOT_FOUND && (*numkeys) > 0)
3048 		rv = KMF_OK;
3049 
3050 	return (rv);
3051 }
3052 
3053 #define	HANDLE_PK12_ERROR { \
3054 	SET_ERROR(kmfh, ERR_get_error()); \
3055 	rv = KMF_ERR_ENCODING; \
3056 	goto out; \
3057 }
3058 
3059 static int
add_alias_to_bag(PKCS12_SAFEBAG * bag,X509 * xcert)3060 add_alias_to_bag(PKCS12_SAFEBAG *bag, X509 *xcert)
3061 {
3062 	unsigned char *alias;
3063 	int len;
3064 
3065 	if (xcert != NULL && (alias = X509_alias_get0(xcert, &len)) != NULL) {
3066 		if (PKCS12_add_friendlyname_asc(bag,
3067 		    (const char *)alias, len) == 0)
3068 			return (0);
3069 	}
3070 	return (1);
3071 }
3072 
3073 static PKCS7 *
add_cert_to_safe(X509 * sslcert,KMF_CREDENTIAL * cred,uchar_t * keyid,unsigned int keyidlen)3074 add_cert_to_safe(X509 *sslcert, KMF_CREDENTIAL *cred,
3075     uchar_t *keyid, unsigned int keyidlen)
3076 {
3077 	PKCS12_SAFEBAG *bag = NULL;
3078 	PKCS7 *cert_authsafe = NULL;
3079 	STACK_OF(PKCS12_SAFEBAG) *bag_stack;
3080 
3081 	bag_stack = sk_PKCS12_SAFEBAG_new_null();
3082 	if (bag_stack == NULL)
3083 		return (NULL);
3084 
3085 	/* Convert cert from X509 struct to PKCS#12 bag */
3086 	bag = PKCS12_SAFEBAG_create_cert(sslcert);
3087 	if (bag == NULL) {
3088 		goto out;
3089 	}
3090 
3091 	/* Add the key id to the certificate bag. */
3092 	if (keyidlen > 0 && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
3093 		goto out;
3094 	}
3095 
3096 	if (!add_alias_to_bag(bag, sslcert))
3097 		goto out;
3098 
3099 	/* Pile it on the bag_stack. */
3100 	if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
3101 		goto out;
3102 	}
3103 	/* Turn bag_stack of certs into encrypted authsafe. */
3104 	cert_authsafe = PKCS12_pack_p7encdata(
3105 	    NID_pbe_WithSHA1And40BitRC2_CBC,
3106 	    cred->cred, cred->credlen, NULL, 0,
3107 	    PKCS12_DEFAULT_ITER, bag_stack);
3108 
3109 out:
3110 	if (bag_stack != NULL)
3111 		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3112 
3113 	return (cert_authsafe);
3114 }
3115 
3116 static PKCS7 *
add_key_to_safe(EVP_PKEY * pkey,KMF_CREDENTIAL * cred,uchar_t * keyid,unsigned int keyidlen,char * label,int label_len)3117 add_key_to_safe(EVP_PKEY *pkey, KMF_CREDENTIAL *cred,
3118     uchar_t *keyid,  unsigned int keyidlen, char *label, int label_len)
3119 {
3120 	PKCS8_PRIV_KEY_INFO *p8 = NULL;
3121 	STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL;
3122 	PKCS12_SAFEBAG *bag = NULL;
3123 	PKCS7 *key_authsafe = NULL;
3124 
3125 	p8 = EVP_PKEY2PKCS8(pkey);
3126 	if (p8 == NULL) {
3127 		return (NULL);
3128 	}
3129 	/* Put the shrouded key into a PKCS#12 bag. */
3130 	bag = PKCS12_SAFEBAG_create_pkcs8_encrypt(
3131 	    NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
3132 	    cred->cred, cred->credlen,
3133 	    NULL, 0, PKCS12_DEFAULT_ITER, p8);
3134 
3135 	/* Clean up the PKCS#8 shrouded key, don't need it now. */
3136 	PKCS8_PRIV_KEY_INFO_free(p8);
3137 	p8 = NULL;
3138 
3139 	if (bag == NULL) {
3140 		return (NULL);
3141 	}
3142 	if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
3143 		goto out;
3144 	if (label != NULL && !PKCS12_add_friendlyname(bag, label, label_len))
3145 		goto out;
3146 
3147 	/* Start a PKCS#12 safebag container for the private key. */
3148 	bag_stack = sk_PKCS12_SAFEBAG_new_null();
3149 	if (bag_stack == NULL)
3150 		goto out;
3151 
3152 	/* Pile on the private key on the bag_stack. */
3153 	if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag))
3154 		goto out;
3155 
3156 	key_authsafe = PKCS12_pack_p7data(bag_stack);
3157 
3158 out:
3159 	if (bag_stack != NULL)
3160 		sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3161 	bag_stack = NULL;
3162 	return (key_authsafe);
3163 }
3164 
3165 static EVP_PKEY *
ImportRawRSAKey(KMF_RAW_RSA_KEY * key)3166 ImportRawRSAKey(KMF_RAW_RSA_KEY *key)
3167 {
3168 	RSA		*rsa = NULL;
3169 	EVP_PKEY	*newkey = NULL;
3170 	BIGNUM		*n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL;
3171 	BIGNUM		*dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
3172 
3173 	if ((rsa = RSA_new()) == NULL)
3174 		goto cleanup;
3175 
3176 	if ((n = BN_bin2bn(key->mod.val, key->mod.len, NULL)) == NULL)
3177 		goto cleanup;
3178 
3179 	if ((e = BN_bin2bn(key->pubexp.val, key->pubexp.len, NULL)) == NULL)
3180 		goto cleanup;
3181 
3182 	if (key->priexp.val != NULL &&
3183 	    (d = BN_bin2bn(key->priexp.val, key->priexp.len, NULL)) == NULL)
3184 		goto cleanup;
3185 
3186 	if (key->prime1.val != NULL &&
3187 	    (p = BN_bin2bn(key->prime1.val, key->prime1.len, NULL)) == NULL)
3188 		goto cleanup;
3189 
3190 	if (key->prime2.val != NULL &&
3191 	    (q = BN_bin2bn(key->prime2.val, key->prime2.len, NULL)) == NULL)
3192 		goto cleanup;
3193 
3194 	if (key->exp1.val != NULL &&
3195 	    (dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len, NULL)) == NULL)
3196 		goto cleanup;
3197 
3198 	if (key->exp2.val != NULL &&
3199 	    (dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len, NULL)) == NULL)
3200 		goto cleanup;
3201 
3202 	if (key->coef.val != NULL &&
3203 	    (iqmp = BN_bin2bn(key->coef.val, key->coef.len, NULL)) == NULL)
3204 		goto cleanup;
3205 
3206 	if (RSA_set0_key(rsa, n, e, d) == 0)
3207 		goto cleanup;
3208 	n = e = d = NULL;
3209 	if (RSA_set0_factors(rsa, p, q) == 0)
3210 		goto cleanup;
3211 	p = q = NULL;
3212 	if (RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) == 0)
3213 		goto cleanup;
3214 	dmp1 = dmq1 = iqmp = NULL;
3215 
3216 	if ((newkey = EVP_PKEY_new()) == NULL)
3217 		goto cleanup;
3218 
3219 	(void) EVP_PKEY_set1_RSA(newkey, rsa);
3220 
3221 cleanup:
3222 	/* The original key must be freed once here or it leaks memory */
3223 	if (rsa)
3224 		RSA_free(rsa);
3225 	BN_free(n);
3226 	BN_free(e);
3227 	BN_free(d);
3228 	BN_free(p);
3229 	BN_free(q);
3230 	BN_free(dmp1);
3231 	BN_free(dmq1);
3232 	BN_free(iqmp);
3233 
3234 	return (newkey);
3235 }
3236 
3237 static EVP_PKEY *
ImportRawDSAKey(KMF_RAW_DSA_KEY * key)3238 ImportRawDSAKey(KMF_RAW_DSA_KEY *key)
3239 {
3240 	DSA		*dsa = NULL;
3241 	EVP_PKEY	*newkey = NULL;
3242 	BIGNUM		*p = NULL, *q = NULL, *g = NULL;
3243 	BIGNUM		*priv_key = NULL, *pub_key = NULL;
3244 
3245 	if ((dsa = DSA_new()) == NULL)
3246 		goto cleanup;
3247 
3248 	if ((p = BN_bin2bn(key->prime.val, key->prime.len, NULL)) == NULL)
3249 		goto cleanup;
3250 
3251 	if ((q = BN_bin2bn(key->subprime.val, key->subprime.len, NULL)) == NULL)
3252 		goto cleanup;
3253 
3254 	if ((g = BN_bin2bn(key->base.val, key->base.len, NULL)) == NULL)
3255 		goto cleanup;
3256 
3257 	if ((priv_key = BN_bin2bn(key->value.val, key->value.len,
3258 	    NULL)) == NULL)
3259 		goto cleanup;
3260 
3261 	if (key->pubvalue.val != NULL && (pub_key =
3262 	    BN_bin2bn(key->pubvalue.val, key->pubvalue.len, NULL)) == NULL)
3263 		goto cleanup;
3264 
3265 	if (DSA_set0_pqg(dsa, p, q, g) == 0)
3266 		goto cleanup;
3267 	p = q = g = NULL;
3268 	if (DSA_set0_key(dsa, pub_key, priv_key) == 0)
3269 		goto cleanup;
3270 	pub_key = priv_key = 0;
3271 
3272 	if ((newkey = EVP_PKEY_new()) == NULL)
3273 		goto cleanup;
3274 
3275 	(void) EVP_PKEY_set1_DSA(newkey, dsa);
3276 
3277 cleanup:
3278 	/* The original key must be freed once here or it leaks memory */
3279 	if (dsa)
3280 		DSA_free(dsa);
3281 	BN_free(p);
3282 	BN_free(q);
3283 	BN_free(g);
3284 	BN_free(priv_key);
3285 	BN_free(pub_key);
3286 
3287 	return (newkey);
3288 }
3289 
3290 static EVP_PKEY *
raw_key_to_pkey(KMF_KEY_HANDLE * key)3291 raw_key_to_pkey(KMF_KEY_HANDLE *key)
3292 {
3293 	EVP_PKEY *pkey = NULL;
3294 	KMF_RAW_KEY_DATA *rawkey;
3295 	ASN1_TYPE *attr = NULL;
3296 	KMF_RETURN ret;
3297 
3298 	if (key == NULL || !key->israw)
3299 		return (NULL);
3300 
3301 	rawkey = (KMF_RAW_KEY_DATA *)key->keyp;
3302 	if (rawkey->keytype == KMF_RSA) {
3303 		pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
3304 	} else if (rawkey->keytype == KMF_DSA) {
3305 		pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
3306 	} else if (rawkey->keytype == KMF_ECDSA) {
3307 		/*
3308 		 * OpenSSL in Solaris does not support EC for
3309 		 * legal reasons
3310 		 */
3311 		return (NULL);
3312 	} else {
3313 		/* wrong kind of key */
3314 		return (NULL);
3315 	}
3316 
3317 	if (rawkey->label != NULL) {
3318 		if ((attr = ASN1_TYPE_new()) == NULL) {
3319 			EVP_PKEY_free(pkey);
3320 			return (NULL);
3321 		}
3322 		attr->value.bmpstring = ASN1_STRING_type_new(V_ASN1_BMPSTRING);
3323 		(void) ASN1_STRING_set(attr->value.bmpstring, rawkey->label,
3324 		    strlen(rawkey->label));
3325 		attr->type = V_ASN1_BMPSTRING;
3326 		attr->value.ptr = (char *)attr->value.bmpstring;
3327 		ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
3328 		if (ret != KMF_OK) {
3329 			EVP_PKEY_free(pkey);
3330 			ASN1_TYPE_free(attr);
3331 			return (NULL);
3332 		}
3333 	}
3334 	if (rawkey->id.Data != NULL) {
3335 		if ((attr = ASN1_TYPE_new()) == NULL) {
3336 			EVP_PKEY_free(pkey);
3337 			return (NULL);
3338 		}
3339 		attr->value.octet_string =
3340 		    ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
3341 		attr->type = V_ASN1_OCTET_STRING;
3342 		(void) ASN1_STRING_set(attr->value.octet_string,
3343 		    rawkey->id.Data, rawkey->id.Length);
3344 		attr->value.ptr = (char *)attr->value.octet_string;
3345 		ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
3346 		if (ret != KMF_OK) {
3347 			EVP_PKEY_free(pkey);
3348 			ASN1_TYPE_free(attr);
3349 			return (NULL);
3350 		}
3351 	}
3352 	return (pkey);
3353 }
3354 
3355 /*
3356  * Search a list of private keys to find one that goes with the certificate.
3357  */
3358 static EVP_PKEY *
find_matching_key(X509 * xcert,int numkeys,KMF_KEY_HANDLE * keylist)3359 find_matching_key(X509 *xcert, int numkeys, KMF_KEY_HANDLE *keylist)
3360 {
3361 	int i;
3362 	EVP_PKEY *pkey = NULL;
3363 
3364 	if (numkeys == 0 || keylist == NULL || xcert == NULL)
3365 		return (NULL);
3366 	for (i = 0; i < numkeys; i++) {
3367 		if (keylist[i].israw)
3368 			pkey = raw_key_to_pkey(&keylist[i]);
3369 		else
3370 			pkey = (EVP_PKEY *)keylist[i].keyp;
3371 		if (pkey != NULL) {
3372 			if (X509_check_private_key(xcert, pkey)) {
3373 				return (pkey);
3374 			} else {
3375 				EVP_PKEY_free(pkey);
3376 				pkey = NULL;
3377 			}
3378 		}
3379 	}
3380 	return (pkey);
3381 }
3382 
3383 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)3384 local_export_pk12(KMF_HANDLE_T handle, KMF_CREDENTIAL *cred, int numcerts,
3385     KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist,
3386     char *filename)
3387 {
3388 	KMF_RETURN rv = KMF_OK;
3389 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3390 	BIO *bio = NULL;
3391 	PKCS7 *cert_authsafe = NULL;
3392 	PKCS7 *key_authsafe = NULL;
3393 	STACK_OF(PKCS7) *authsafe_stack = NULL;
3394 	PKCS12 *p12_elem = NULL;
3395 	int i;
3396 
3397 	if (numcerts == 0 && numkeys == 0)
3398 		return (KMF_ERR_BAD_PARAMETER);
3399 
3400 	/*
3401 	 * Open the output file.
3402 	 */
3403 	if ((bio = BIO_new_file(filename, "wb")) == NULL) {
3404 		SET_ERROR(kmfh, ERR_get_error());
3405 		rv = KMF_ERR_OPEN_FILE;
3406 		goto cleanup;
3407 	}
3408 
3409 	/* Start a PKCS#7 stack. */
3410 	authsafe_stack = sk_PKCS7_new_null();
3411 	if (authsafe_stack == NULL) {
3412 		rv = KMF_ERR_MEMORY;
3413 		goto cleanup;
3414 	}
3415 	if (numcerts > 0) {
3416 		for (i = 0; rv == KMF_OK && i < numcerts; i++) {
3417 			const uchar_t *p = certlist[i].certificate.Data;
3418 			long len = certlist[i].certificate.Length;
3419 			X509 *xcert = NULL;
3420 			EVP_PKEY *pkey = NULL;
3421 			unsigned char keyid[EVP_MAX_MD_SIZE];
3422 			unsigned int keyidlen = 0;
3423 
3424 			xcert = d2i_X509(NULL, &p, len);
3425 			if (xcert == NULL) {
3426 				SET_ERROR(kmfh, ERR_get_error());
3427 				rv = KMF_ERR_ENCODING;
3428 			}
3429 			if (certlist[i].kmf_private.label != NULL) {
3430 				/* Set alias attribute */
3431 				(void) X509_alias_set1(xcert,
3432 				    (uchar_t *)certlist[i].kmf_private.label,
3433 				    strlen(certlist[i].kmf_private.label));
3434 			}
3435 			/* Check if there is a key corresponding to this cert */
3436 			pkey = find_matching_key(xcert, numkeys, keylist);
3437 
3438 			/*
3439 			 * If key is found, get fingerprint and create a
3440 			 * safebag.
3441 			 */
3442 			if (pkey != NULL) {
3443 				(void) X509_digest(xcert, EVP_sha1(),
3444 				    keyid, &keyidlen);
3445 				key_authsafe = add_key_to_safe(pkey, cred,
3446 				    keyid, keyidlen,
3447 				    certlist[i].kmf_private.label,
3448 				    (certlist[i].kmf_private.label ?
3449 				    strlen(certlist[i].kmf_private.label) : 0));
3450 
3451 				if (key_authsafe == NULL) {
3452 					X509_free(xcert);
3453 					EVP_PKEY_free(pkey);
3454 					goto cleanup;
3455 				}
3456 				/* Put the key safe into the Auth Safe */
3457 				if (!sk_PKCS7_push(authsafe_stack,
3458 				    key_authsafe)) {
3459 					X509_free(xcert);
3460 					EVP_PKEY_free(pkey);
3461 					goto cleanup;
3462 				}
3463 			}
3464 
3465 			/* create a certificate safebag */
3466 			cert_authsafe = add_cert_to_safe(xcert, cred, keyid,
3467 			    keyidlen);
3468 			if (cert_authsafe == NULL) {
3469 				X509_free(xcert);
3470 				EVP_PKEY_free(pkey);
3471 				goto cleanup;
3472 			}
3473 			if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) {
3474 				X509_free(xcert);
3475 				EVP_PKEY_free(pkey);
3476 				goto cleanup;
3477 			}
3478 
3479 			X509_free(xcert);
3480 			if (pkey)
3481 				EVP_PKEY_free(pkey);
3482 		}
3483 	} else if (numcerts == 0 && numkeys > 0) {
3484 		/*
3485 		 * If only adding keys to the file.
3486 		 */
3487 		for (i = 0; i < numkeys; i++) {
3488 			EVP_PKEY *pkey = NULL;
3489 
3490 			if (keylist[i].israw)
3491 				pkey = raw_key_to_pkey(&keylist[i]);
3492 			else
3493 				pkey = (EVP_PKEY *)keylist[i].keyp;
3494 
3495 			if (pkey == NULL)
3496 				continue;
3497 
3498 			key_authsafe = add_key_to_safe(pkey, cred,
3499 			    NULL, 0, NULL, 0);
3500 
3501 			if (key_authsafe == NULL) {
3502 				EVP_PKEY_free(pkey);
3503 				goto cleanup;
3504 			}
3505 			if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) {
3506 				EVP_PKEY_free(pkey);
3507 				goto cleanup;
3508 			}
3509 		}
3510 	}
3511 	p12_elem = PKCS12_init(NID_pkcs7_data);
3512 	if (p12_elem == NULL) {
3513 		goto cleanup;
3514 	}
3515 
3516 	/* Put the PKCS#7 stack into the PKCS#12 element. */
3517 	if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) {
3518 		goto cleanup;
3519 	}
3520 
3521 	/* Set the integrity MAC on the PKCS#12 element. */
3522 	if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen,
3523 	    NULL, 0, PKCS12_DEFAULT_ITER, NULL)) {
3524 		goto cleanup;
3525 	}
3526 
3527 	/* Write the PKCS#12 element to the export file. */
3528 	if (!i2d_PKCS12_bio(bio, p12_elem)) {
3529 		goto cleanup;
3530 	}
3531 	PKCS12_free(p12_elem);
3532 
3533 cleanup:
3534 	/* Clear away the PKCS#7 stack, we're done with it. */
3535 	if (authsafe_stack)
3536 		sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
3537 
3538 	if (bio != NULL)
3539 		(void) BIO_free_all(bio);
3540 
3541 	return (rv);
3542 }
3543 
3544 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)3545 openssl_build_pk12(KMF_HANDLE_T handle, int numcerts,
3546     KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist,
3547     KMF_CREDENTIAL *p12cred, char *filename)
3548 {
3549 	KMF_RETURN rv;
3550 
3551 	if (certlist == NULL && keylist == NULL)
3552 		return (KMF_ERR_BAD_PARAMETER);
3553 
3554 	rv = local_export_pk12(handle, p12cred, numcerts, certlist,
3555 	    numkeys, keylist, filename);
3556 
3557 	return (rv);
3558 }
3559 
3560 KMF_RETURN
OpenSSL_ExportPK12(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)3561 OpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
3562 {
3563 	KMF_RETURN rv;
3564 	KMF_HANDLE *kmfh = (KMF_HANDLE  *)handle;
3565 	char *fullpath = NULL;
3566 	char *dirpath = NULL;
3567 	char *certfile = NULL;
3568 	char *keyfile = NULL;
3569 	char *filename = NULL;
3570 	KMF_CREDENTIAL *p12cred = NULL;
3571 	KMF_X509_DER_CERT certdata;
3572 	KMF_KEY_HANDLE key;
3573 	int gotkey = 0;
3574 	int gotcert = 0;
3575 
3576 	if (handle == NULL)
3577 		return (KMF_ERR_BAD_PARAMETER);
3578 
3579 	/*
3580 	 *  First, find the certificate.
3581 	 */
3582 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
3583 	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
3584 	if (certfile != NULL) {
3585 		fullpath = get_fullpath(dirpath, certfile);
3586 		if (fullpath == NULL)
3587 			return (KMF_ERR_BAD_PARAMETER);
3588 
3589 		if (isdir(fullpath)) {
3590 			free(fullpath);
3591 			return (KMF_ERR_AMBIGUOUS_PATHNAME);
3592 		}
3593 
3594 		(void) memset(&certdata, 0, sizeof (certdata));
3595 		rv = kmf_load_cert(kmfh, NULL, NULL, NULL, 0,
3596 		    fullpath, &certdata.certificate);
3597 		if (rv != KMF_OK)
3598 			goto end;
3599 
3600 		gotcert++;
3601 		certdata.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
3602 		free(fullpath);
3603 	}
3604 
3605 	/*
3606 	 * Now find the private key.
3607 	 */
3608 	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
3609 	if (keyfile != NULL) {
3610 		fullpath = get_fullpath(dirpath, keyfile);
3611 		if (fullpath == NULL)
3612 			return (KMF_ERR_BAD_PARAMETER);
3613 
3614 		if (isdir(fullpath)) {
3615 			free(fullpath);
3616 			return (KMF_ERR_AMBIGUOUS_PATHNAME);
3617 		}
3618 
3619 		(void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
3620 		rv = fetch_key(handle, fullpath, KMF_ASYM_PRI, &key);
3621 		if (rv != KMF_OK)
3622 			goto end;
3623 		gotkey++;
3624 	}
3625 
3626 	/*
3627 	 * Open the output file.
3628 	 */
3629 	filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
3630 	    numattr);
3631 	if (filename == NULL) {
3632 		rv = KMF_ERR_BAD_PARAMETER;
3633 		goto end;
3634 	}
3635 
3636 	/* Stick the key and the cert into a PKCS#12 file */
3637 	p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
3638 	if (p12cred == NULL) {
3639 		rv = KMF_ERR_BAD_PARAMETER;
3640 		goto end;
3641 	}
3642 
3643 	rv = local_export_pk12(handle, p12cred, 1, &certdata,
3644 	    1, &key, filename);
3645 
3646 end:
3647 	if (fullpath)
3648 		free(fullpath);
3649 
3650 	if (gotcert)
3651 		kmf_free_kmf_cert(handle, &certdata);
3652 	if (gotkey)
3653 		kmf_free_kmf_key(handle, &key);
3654 	return (rv);
3655 }
3656 
3657 /*
3658  * Helper function to extract keys and certificates from
3659  * a single PEM file.  Typically the file should contain a
3660  * private key and an associated public key wrapped in an x509 cert.
3661  * However, the file may be just a list of X509 certs with no keys.
3662  */
3663 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)3664 extract_pem(KMF_HANDLE *kmfh, char *issuer, char *subject, KMF_BIGINT *serial,
3665     char *filename, CK_UTF8CHAR *pin, CK_ULONG pinlen, EVP_PKEY **priv_key,
3666     KMF_DATA **certs, int *numcerts)
3667 {
3668 	KMF_RETURN rv = KMF_OK;
3669 	FILE *fp;
3670 	STACK_OF(X509_INFO) *x509_info_stack = NULL;
3671 	int i, ncerts = 0, matchcerts = 0;
3672 	EVP_PKEY *pkey = NULL;
3673 	X509_INFO *info;
3674 	X509 *x;
3675 	X509_INFO **cert_infos = NULL;
3676 	KMF_DATA *certlist = NULL;
3677 
3678 	if (priv_key)
3679 		*priv_key = NULL;
3680 	if (certs)
3681 		*certs = NULL;
3682 	fp = fopen(filename, "r");
3683 	if (fp == NULL)
3684 		return (KMF_ERR_OPEN_FILE);
3685 
3686 	x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin);
3687 	if (x509_info_stack == NULL) {
3688 		(void) fclose(fp);
3689 		return (KMF_ERR_ENCODING);
3690 	}
3691 	cert_infos = (X509_INFO **)malloc(sk_X509_INFO_num(x509_info_stack) *
3692 	    sizeof (X509_INFO *));
3693 	if (cert_infos == NULL) {
3694 		(void) fclose(fp);
3695 		rv = KMF_ERR_MEMORY;
3696 		goto err;
3697 	}
3698 
3699 	for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
3700 		cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i);
3701 		ncerts++;
3702 	}
3703 
3704 	if (ncerts == 0) {
3705 		(void) fclose(fp);
3706 		rv = KMF_ERR_CERT_NOT_FOUND;
3707 		goto err;
3708 	}
3709 
3710 	if (priv_key != NULL) {
3711 		rewind(fp);
3712 		pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin);
3713 	}
3714 	(void) fclose(fp);
3715 
3716 	x = cert_infos[ncerts - 1]->x509;
3717 	/*
3718 	 * Make sure the private key matchs the last cert in the file.
3719 	 */
3720 	if (pkey != NULL && !X509_check_private_key(x, pkey)) {
3721 		EVP_PKEY_free(pkey);
3722 		rv = KMF_ERR_KEY_MISMATCH;
3723 		goto err;
3724 	}
3725 
3726 	certlist = (KMF_DATA *)calloc(ncerts, sizeof (KMF_DATA));
3727 	if (certlist == NULL) {
3728 		if (pkey != NULL)
3729 			EVP_PKEY_free(pkey);
3730 		rv = KMF_ERR_MEMORY;
3731 		goto err;
3732 	}
3733 
3734 	/*
3735 	 * Convert all of the certs to DER format.
3736 	 */
3737 	matchcerts = 0;
3738 	for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) {
3739 		boolean_t match = FALSE;
3740 		info =  cert_infos[ncerts - 1 - i];
3741 
3742 		rv = check_cert(info->x509, issuer, subject, serial, &match);
3743 		if (rv != KMF_OK || match != TRUE) {
3744 			rv = KMF_OK;
3745 			continue;
3746 		}
3747 
3748 		rv = ssl_cert2KMFDATA(kmfh, info->x509,
3749 		    &certlist[matchcerts++]);
3750 
3751 		if (rv != KMF_OK) {
3752 			int j;
3753 			for (j = 0; j < matchcerts; j++)
3754 				kmf_free_data(&certlist[j]);
3755 			free(certlist);
3756 			certlist = NULL;
3757 			ncerts = matchcerts = 0;
3758 		}
3759 	}
3760 
3761 	if (numcerts != NULL)
3762 		*numcerts = matchcerts;
3763 
3764 	if (certs != NULL)
3765 		*certs = certlist;
3766 	else if (certlist != NULL) {
3767 		for (i = 0; i < ncerts; i++)
3768 			kmf_free_data(&certlist[i]);
3769 		free(certlist);
3770 		certlist = NULL;
3771 	}
3772 
3773 	if (priv_key == NULL && pkey != NULL)
3774 		EVP_PKEY_free(pkey);
3775 	else if (priv_key != NULL && pkey != NULL)
3776 		*priv_key = pkey;
3777 
3778 err:
3779 	/* Cleanup the stack of X509 info records */
3780 	for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
3781 		info = (X509_INFO *)sk_X509_INFO_value(x509_info_stack, i);
3782 		X509_INFO_free(info);
3783 	}
3784 	if (x509_info_stack)
3785 		sk_X509_INFO_free(x509_info_stack);
3786 
3787 	if (cert_infos != NULL)
3788 		free(cert_infos);
3789 
3790 	return (rv);
3791 }
3792 
3793 static KMF_RETURN
openssl_parse_bags(const STACK_OF (PKCS12_SAFEBAG)* bags,char * pin,STACK_OF (EVP_PKEY)* keys,STACK_OF (X509)* certs)3794 openssl_parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, char *pin,
3795     STACK_OF(EVP_PKEY) *keys, STACK_OF(X509) *certs)
3796 {
3797 	KMF_RETURN ret;
3798 	int i;
3799 
3800 	for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
3801 		PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value(bags, i);
3802 		ret = openssl_parse_bag(bag, pin, (pin ? strlen(pin) : 0),
3803 		    keys, certs);
3804 
3805 		if (ret != KMF_OK)
3806 			return (ret);
3807 	}
3808 
3809 	return (ret);
3810 }
3811 
3812 static KMF_RETURN
set_pkey_attrib(EVP_PKEY * pkey,ASN1_TYPE * attrib,int nid)3813 set_pkey_attrib(EVP_PKEY *pkey, ASN1_TYPE *attrib, int nid)
3814 {
3815 	X509_ATTRIBUTE *attr = NULL;
3816 
3817 	if (pkey == NULL || attrib == NULL)
3818 		return (KMF_ERR_BAD_PARAMETER);
3819 
3820 	attr = X509_ATTRIBUTE_create(nid, attrib->type, attrib->value.ptr);
3821 	if (attr != NULL) {
3822 		int i;
3823 
3824 		if ((i = EVP_PKEY_get_attr_by_NID(pkey, nid, -1)) != -1)
3825 			(void) EVP_PKEY_delete_attr(pkey, i);
3826 		if (EVP_PKEY_add1_attr(pkey, attr) == 0) {
3827 			X509_ATTRIBUTE_free(attr);
3828 			return (KMF_ERR_MEMORY);
3829 		}
3830 	} else {
3831 		return (KMF_ERR_MEMORY);
3832 	}
3833 
3834 	return (KMF_OK);
3835 }
3836 
3837 static KMF_RETURN
openssl_parse_bag(PKCS12_SAFEBAG * bag,char * pass,int passlen,STACK_OF (EVP_PKEY)* keylist,STACK_OF (X509)* certlist)3838 openssl_parse_bag(PKCS12_SAFEBAG *bag, char *pass, int passlen,
3839     STACK_OF(EVP_PKEY) *keylist, STACK_OF(X509) *certlist)
3840 {
3841 	KMF_RETURN ret = KMF_OK;
3842 	PKCS8_PRIV_KEY_INFO *p8 = NULL;
3843 	EVP_PKEY *pkey = NULL;
3844 	X509 *xcert = NULL;
3845 	const ASN1_TYPE *keyid = NULL;
3846 	const ASN1_TYPE *fname = NULL;
3847 	uchar_t *data = NULL;
3848 
3849 	keyid = PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID);
3850 	fname = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName);
3851 
3852 	switch (PKCS12_SAFEBAG_get_nid(bag)) {
3853 		case NID_keyBag:
3854 			if (keylist == NULL)
3855 				goto end;
3856 			pkey = EVP_PKCS82PKEY(
3857 			    PKCS12_SAFEBAG_get0_p8inf(bag));
3858 			if (pkey == NULL)
3859 				ret = KMF_ERR_PKCS12_FORMAT;
3860 
3861 			break;
3862 		case NID_pkcs8ShroudedKeyBag:
3863 			if (keylist == NULL)
3864 				goto end;
3865 			p8 = PKCS12_decrypt_skey(bag, pass, passlen);
3866 			if (p8 == NULL)
3867 				return (KMF_ERR_AUTH_FAILED);
3868 			pkey = EVP_PKCS82PKEY(p8);
3869 			PKCS8_PRIV_KEY_INFO_free(p8);
3870 			if (pkey == NULL)
3871 				ret = KMF_ERR_PKCS12_FORMAT;
3872 			break;
3873 		case NID_certBag:
3874 			if (certlist == NULL)
3875 				goto end;
3876 			if (PKCS12_SAFEBAG_get_bag_nid(bag) !=
3877 			    NID_x509Certificate)
3878 				return (KMF_ERR_PKCS12_FORMAT);
3879 			xcert = PKCS12_SAFEBAG_get1_cert(bag);
3880 			if (xcert == NULL) {
3881 				ret = KMF_ERR_PKCS12_FORMAT;
3882 				goto end;
3883 			}
3884 			if (keyid != NULL) {
3885 				if (X509_keyid_set1(xcert,
3886 				    keyid->value.octet_string->data,
3887 				    keyid->value.octet_string->length) == 0) {
3888 					ret = KMF_ERR_PKCS12_FORMAT;
3889 					goto end;
3890 				}
3891 			}
3892 			if (fname != NULL) {
3893 				int len, r;
3894 				len = ASN1_STRING_to_UTF8(&data,
3895 				    fname->value.asn1_string);
3896 				if (len > 0 && data != NULL) {
3897 					r = X509_alias_set1(xcert, data, len);
3898 					if (r == 0) {
3899 						ret = KMF_ERR_PKCS12_FORMAT;
3900 						goto end;
3901 					}
3902 				} else {
3903 					ret = KMF_ERR_PKCS12_FORMAT;
3904 					goto end;
3905 				}
3906 			}
3907 			if (sk_X509_push(certlist, xcert) == 0)
3908 				ret = KMF_ERR_MEMORY;
3909 			else
3910 				xcert = NULL;
3911 			break;
3912 		case NID_safeContentsBag:
3913 			return (openssl_parse_bags(
3914 			    PKCS12_SAFEBAG_get0_safes(bag),
3915 			    pass, keylist, certlist));
3916 		default:
3917 			ret = KMF_ERR_PKCS12_FORMAT;
3918 			break;
3919 	}
3920 
3921 	/*
3922 	 * Set the ID and/or FriendlyName attributes on the key.
3923 	 * If converting to PKCS11 objects, these can translate to CKA_ID
3924 	 * and CKA_LABEL values.
3925 	 */
3926 	if (pkey != NULL && ret == KMF_OK) {
3927 		ASN1_TYPE *attr = NULL;
3928 		if (keyid != NULL && keyid->type == V_ASN1_OCTET_STRING) {
3929 			if ((attr = ASN1_TYPE_new()) == NULL)
3930 				return (KMF_ERR_MEMORY);
3931 			attr->value.octet_string =
3932 			    ASN1_STRING_dup(keyid->value.octet_string);
3933 			attr->type = V_ASN1_OCTET_STRING;
3934 			attr->value.ptr = (char *)attr->value.octet_string;
3935 			ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
3936 			OPENSSL_free(attr);
3937 		}
3938 
3939 		if (ret == KMF_OK && fname != NULL &&
3940 		    fname->type == V_ASN1_BMPSTRING) {
3941 			if ((attr = ASN1_TYPE_new()) == NULL)
3942 				return (KMF_ERR_MEMORY);
3943 			attr->value.bmpstring =
3944 			    ASN1_STRING_dup(fname->value.bmpstring);
3945 			attr->type = V_ASN1_BMPSTRING;
3946 			attr->value.ptr = (char *)attr->value.bmpstring;
3947 			ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
3948 			OPENSSL_free(attr);
3949 		}
3950 
3951 		if (ret == KMF_OK && keylist != NULL &&
3952 		    sk_EVP_PKEY_push(keylist, pkey) == 0)
3953 			ret = KMF_ERR_MEMORY;
3954 	}
3955 	if (ret == KMF_OK && keylist != NULL)
3956 		pkey = NULL;
3957 end:
3958 	if (pkey != NULL)
3959 		EVP_PKEY_free(pkey);
3960 	if (xcert != NULL)
3961 		X509_free(xcert);
3962 	if (data != NULL)
3963 		OPENSSL_free(data);
3964 
3965 	return (ret);
3966 }
3967 
3968 static KMF_RETURN
openssl_pkcs12_parse(PKCS12 * p12,char * pin,STACK_OF (EVP_PKEY)* keys,STACK_OF (X509)* certs,STACK_OF (X509)* ca)3969 openssl_pkcs12_parse(PKCS12 *p12, char *pin, STACK_OF(EVP_PKEY) *keys,
3970     STACK_OF(X509) *certs, STACK_OF(X509) *ca)
3971 {
3972 	KMF_RETURN ret = KMF_OK;
3973 	STACK_OF(PKCS7) *asafes = NULL;
3974 	STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
3975 	int i, bagnid;
3976 	PKCS7 *p7;
3977 
3978 	if (p12 == NULL || (keys == NULL && certs == NULL))
3979 		return (KMF_ERR_BAD_PARAMETER);
3980 
3981 	if (pin == NULL || *pin == '\0') {
3982 		if (PKCS12_verify_mac(p12, NULL, 0)) {
3983 			pin = NULL;
3984 		} else if (PKCS12_verify_mac(p12, "", 0)) {
3985 			pin = "";
3986 		} else {
3987 			return (KMF_ERR_AUTH_FAILED);
3988 		}
3989 	} else if (!PKCS12_verify_mac(p12, pin, -1)) {
3990 		return (KMF_ERR_AUTH_FAILED);
3991 	}
3992 
3993 	if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
3994 		return (KMF_ERR_PKCS12_FORMAT);
3995 
3996 	for (i = 0; ret == KMF_OK && i < sk_PKCS7_num(asafes); i++) {
3997 		bags = NULL;
3998 		p7 = sk_PKCS7_value(asafes, i);
3999 		bagnid = OBJ_obj2nid(p7->type);
4000 
4001 		if (bagnid == NID_pkcs7_data) {
4002 			bags = PKCS12_unpack_p7data(p7);
4003 		} else if (bagnid == NID_pkcs7_encrypted) {
4004 			bags = PKCS12_unpack_p7encdata(p7, pin,
4005 			    (pin ? strlen(pin) : 0));
4006 		} else {
4007 			continue;
4008 		}
4009 		if (bags == NULL) {
4010 			ret = KMF_ERR_PKCS12_FORMAT;
4011 			goto out;
4012 		}
4013 
4014 		if (openssl_parse_bags(bags, pin, keys, certs) != KMF_OK)
4015 			ret = KMF_ERR_PKCS12_FORMAT;
4016 
4017 		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
4018 	}
4019 out:
4020 	if (asafes != NULL)
4021 		sk_PKCS7_pop_free(asafes, PKCS7_free);
4022 
4023 	return (ret);
4024 }
4025 
4026 /*
4027  * Helper function to decrypt and parse PKCS#12 import file.
4028  */
4029 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)4030 extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
4031     STACK_OF(EVP_PKEY) **priv_key, STACK_OF(X509) **certs, STACK_OF(X509) **ca)
4032 {
4033 	PKCS12			*pk12, *pk12_tmp;
4034 	STACK_OF(EVP_PKEY)	*pkeylist = NULL;
4035 	STACK_OF(X509)		*xcertlist = NULL;
4036 	STACK_OF(X509)		*cacertlist = NULL;
4037 
4038 	if ((pk12 = PKCS12_new()) == NULL) {
4039 		return (KMF_ERR_MEMORY);
4040 	}
4041 
4042 	if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) {
4043 		/* This is ok; it seems to mean there is no more to read. */
4044 		if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 &&
4045 		    ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG)
4046 			goto end_extract_pkcs12;
4047 
4048 		PKCS12_free(pk12);
4049 		return (KMF_ERR_PKCS12_FORMAT);
4050 	}
4051 	pk12 = pk12_tmp;
4052 
4053 	xcertlist = sk_X509_new_null();
4054 	if (xcertlist == NULL) {
4055 		PKCS12_free(pk12);
4056 		return (KMF_ERR_MEMORY);
4057 	}
4058 	pkeylist = sk_EVP_PKEY_new_null();
4059 	if (pkeylist == NULL) {
4060 		sk_X509_pop_free(xcertlist, X509_free);
4061 		PKCS12_free(pk12);
4062 		return (KMF_ERR_MEMORY);
4063 	}
4064 
4065 	if (openssl_pkcs12_parse(pk12, (char *)pin, pkeylist, xcertlist,
4066 	    cacertlist) != KMF_OK) {
4067 		sk_X509_pop_free(xcertlist, X509_free);
4068 		sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
4069 		PKCS12_free(pk12);
4070 		return (KMF_ERR_PKCS12_FORMAT);
4071 	}
4072 
4073 	if (priv_key && pkeylist)
4074 		*priv_key = pkeylist;
4075 	else if (pkeylist)
4076 		sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
4077 	if (certs && xcertlist)
4078 		*certs = xcertlist;
4079 	else if (xcertlist)
4080 		sk_X509_pop_free(xcertlist, X509_free);
4081 	if (ca && cacertlist)
4082 		*ca = cacertlist;
4083 	else if (cacertlist)
4084 		sk_X509_pop_free(cacertlist, X509_free);
4085 
4086 end_extract_pkcs12:
4087 
4088 	PKCS12_free(pk12);
4089 	return (KMF_OK);
4090 }
4091 
4092 static KMF_RETURN
sslBN2KMFBN(BIGNUM * from,KMF_BIGINT * to)4093 sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to)
4094 {
4095 	KMF_RETURN rv = KMF_OK;
4096 	uint32_t sz;
4097 
4098 	sz = BN_num_bytes(from);
4099 	to->val = (uchar_t *)malloc(sz);
4100 	if (to->val == NULL)
4101 		return (KMF_ERR_MEMORY);
4102 
4103 	if ((to->len = BN_bn2bin(from, to->val)) != sz) {
4104 		free(to->val);
4105 		to->val = NULL;
4106 		to->len = 0;
4107 		rv = KMF_ERR_MEMORY;
4108 	}
4109 
4110 	return (rv);
4111 }
4112 
4113 static KMF_RETURN
exportRawRSAKey(RSA * rsa,KMF_RAW_KEY_DATA * key)4114 exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key)
4115 {
4116 	KMF_RETURN rv;
4117 	KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa;
4118 
4119 	const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmpq, *iqmp;
4120 
4121 	RSA_get0_key(rsa, &n, &e, &d);
4122 	RSA_get0_factors(rsa, &p, &q);
4123 	RSA_get0_crt_params(rsa, &dmp1, &dmpq, &iqmp);
4124 
4125 	(void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY));
4126 	if ((rv = sslBN2KMFBN((BIGNUM *)n, &kmfkey->mod)) != KMF_OK)
4127 		goto cleanup;
4128 
4129 	if ((rv = sslBN2KMFBN((BIGNUM *)e, &kmfkey->pubexp)) != KMF_OK)
4130 		goto cleanup;
4131 
4132 	if (d != NULL)
4133 		if ((rv = sslBN2KMFBN((BIGNUM *)d, &kmfkey->priexp)) != KMF_OK)
4134 			goto cleanup;
4135 
4136 	if (p != NULL)
4137 		if ((rv = sslBN2KMFBN((BIGNUM *)p, &kmfkey->prime1)) != KMF_OK)
4138 			goto cleanup;
4139 
4140 	if (q != NULL)
4141 		if ((rv = sslBN2KMFBN((BIGNUM *)q, &kmfkey->prime2)) != KMF_OK)
4142 			goto cleanup;
4143 
4144 	if (dmp1 != NULL)
4145 		if ((rv = sslBN2KMFBN((BIGNUM *)dmp1, &kmfkey->exp1)) != KMF_OK)
4146 			goto cleanup;
4147 
4148 	if (dmpq != NULL)
4149 		if ((rv = sslBN2KMFBN((BIGNUM *)dmpq, &kmfkey->exp2)) != KMF_OK)
4150 			goto cleanup;
4151 
4152 	if (iqmp != NULL)
4153 		if ((rv = sslBN2KMFBN((BIGNUM *)iqmp, &kmfkey->coef)) != KMF_OK)
4154 			goto cleanup;
4155 cleanup:
4156 	if (rv != KMF_OK)
4157 		kmf_free_raw_key(key);
4158 	else
4159 		key->keytype = KMF_RSA;
4160 
4161 	/*
4162 	 * Free the reference to this key, SSL will not actually free
4163 	 * the memory until the refcount == 0, so this is safe.
4164 	 */
4165 	RSA_free(rsa);
4166 
4167 	return (rv);
4168 }
4169 
4170 static KMF_RETURN
exportRawDSAKey(DSA * dsa,KMF_RAW_KEY_DATA * key)4171 exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key)
4172 {
4173 	KMF_RETURN rv;
4174 	KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa;
4175 	const BIGNUM *p, *q, *g, *priv_key;
4176 
4177 	DSA_get0_pqg(dsa, &p, &q, &g);
4178 	DSA_get0_key(dsa, NULL, &priv_key);
4179 
4180 	(void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY));
4181 	if ((rv = sslBN2KMFBN((BIGNUM *)p, &kmfkey->prime)) != KMF_OK)
4182 		goto cleanup;
4183 
4184 	if ((rv = sslBN2KMFBN((BIGNUM *)q, &kmfkey->subprime)) != KMF_OK)
4185 		goto cleanup;
4186 
4187 	if ((rv = sslBN2KMFBN((BIGNUM *)g, &kmfkey->base)) != KMF_OK)
4188 		goto cleanup;
4189 
4190 	if ((rv = sslBN2KMFBN((BIGNUM *)priv_key, &kmfkey->value)) != KMF_OK)
4191 		goto cleanup;
4192 
4193 cleanup:
4194 	if (rv != KMF_OK)
4195 		kmf_free_raw_key(key);
4196 	else
4197 		key->keytype = KMF_DSA;
4198 
4199 	/*
4200 	 * Free the reference to this key, SSL will not actually free
4201 	 * the memory until the refcount == 0, so this is safe.
4202 	 */
4203 	DSA_free(dsa);
4204 
4205 	return (rv);
4206 }
4207 
4208 static KMF_RETURN
add_cert_to_list(KMF_HANDLE * kmfh,X509 * sslcert,KMF_X509_DER_CERT ** certlist,int * ncerts)4209 add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert,
4210     KMF_X509_DER_CERT **certlist, int *ncerts)
4211 {
4212 	KMF_RETURN rv = KMF_OK;
4213 	KMF_X509_DER_CERT *list = (*certlist);
4214 	KMF_X509_DER_CERT cert;
4215 	int n = (*ncerts);
4216 
4217 	if (list == NULL) {
4218 		list = (KMF_X509_DER_CERT *)malloc(sizeof (KMF_X509_DER_CERT));
4219 	} else {
4220 		list = (KMF_X509_DER_CERT *)realloc(list,
4221 		    sizeof (KMF_X509_DER_CERT) * (n + 1));
4222 	}
4223 
4224 	if (list == NULL)
4225 		return (KMF_ERR_MEMORY);
4226 
4227 	(void) memset(&cert, 0, sizeof (cert));
4228 	rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert.certificate);
4229 	if (rv == KMF_OK) {
4230 		int len = 0;
4231 		/* Get the alias name for the cert if there is one */
4232 		char *a = (char *)X509_alias_get0(sslcert, &len);
4233 		if (a != NULL)
4234 			cert.kmf_private.label = strdup(a);
4235 		cert.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
4236 
4237 		list[n] = cert;
4238 		(*ncerts) = n + 1;
4239 
4240 		*certlist = list;
4241 	} else {
4242 		free(list);
4243 	}
4244 
4245 	return (rv);
4246 }
4247 
4248 static KMF_RETURN
add_key_to_list(KMF_RAW_KEY_DATA ** keylist,KMF_RAW_KEY_DATA * newkey,int * nkeys)4249 add_key_to_list(KMF_RAW_KEY_DATA **keylist,
4250     KMF_RAW_KEY_DATA *newkey, int *nkeys)
4251 {
4252 	KMF_RAW_KEY_DATA *list = (*keylist);
4253 	int n = (*nkeys);
4254 
4255 	if (list == NULL) {
4256 		list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA));
4257 	} else {
4258 		list = (KMF_RAW_KEY_DATA *)realloc(list,
4259 		    sizeof (KMF_RAW_KEY_DATA) * (n + 1));
4260 	}
4261 
4262 	if (list == NULL)
4263 		return (KMF_ERR_MEMORY);
4264 
4265 	list[n] = *newkey;
4266 	(*nkeys) = n + 1;
4267 
4268 	*keylist = list;
4269 
4270 	return (KMF_OK);
4271 }
4272 
4273 static KMF_RETURN
convertToRawKey(EVP_PKEY * pkey,KMF_RAW_KEY_DATA * key)4274 convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key)
4275 {
4276 	KMF_RETURN rv = KMF_OK;
4277 	X509_ATTRIBUTE *attr;
4278 	RSA *rsa;
4279 	DSA *dsa;
4280 	int loc;
4281 
4282 	if (pkey == NULL || key == NULL)
4283 		return (KMF_ERR_BAD_PARAMETER);
4284 	/* Convert SSL key to raw key */
4285 	if ((rsa = EVP_PKEY_get1_RSA(pkey)) != NULL) {
4286 		rv = exportRawRSAKey(rsa, key);
4287 		if (rv != KMF_OK)
4288 			return (rv);
4289 	} else if ((dsa = EVP_PKEY_get1_DSA(pkey)) != NULL) {
4290 		rv = exportRawDSAKey(dsa, key);
4291 		if (rv != KMF_OK)
4292 			return (rv);
4293 	} else
4294 		return (KMF_ERR_BAD_PARAMETER);
4295 
4296 	/*
4297 	 * If friendlyName, add it to record.
4298 	 */
4299 
4300 	if ((loc = EVP_PKEY_get_attr_by_NID(pkey,
4301 	    NID_friendlyName, -1)) != -1 &&
4302 	    (attr = EVP_PKEY_get_attr(pkey, loc))) {
4303 		ASN1_TYPE *ty = NULL;
4304 		int numattr = X509_ATTRIBUTE_count(attr);
4305 		if (numattr > 0) {
4306 			ty = X509_ATTRIBUTE_get0_type(attr, 0);
4307 		}
4308 		if (ty != NULL) {
4309 			key->label = OPENSSL_uni2asc(ty->value.bmpstring->data,
4310 			    ty->value.bmpstring->length);
4311 		}
4312 	} else {
4313 		key->label = NULL;
4314 	}
4315 
4316 	/*
4317 	 * If KeyID, add it to record as a KMF_DATA object.
4318 	 */
4319 	if ((loc = EVP_PKEY_get_attr_by_NID(pkey,
4320 	    NID_localKeyID, -1)) != -1 &&
4321 	    (attr = EVP_PKEY_get_attr(pkey, loc)) != NULL) {
4322 		ASN1_TYPE *ty = NULL;
4323 		int numattr = X509_ATTRIBUTE_count(attr);
4324 		if (numattr > 0)
4325 			ty = X509_ATTRIBUTE_get0_type(attr, 0);
4326 		key->id.Data = (uchar_t *)malloc(
4327 		    ty->value.octet_string->length);
4328 		if (key->id.Data == NULL)
4329 			return (KMF_ERR_MEMORY);
4330 		(void) memcpy(key->id.Data, ty->value.octet_string->data,
4331 		    ty->value.octet_string->length);
4332 		key->id.Length = ty->value.octet_string->length;
4333 	} else {
4334 		(void) memset(&key->id, 0, sizeof (KMF_DATA));
4335 	}
4336 
4337 	return (rv);
4338 }
4339 
4340 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)4341 convertPK12Objects(
4342 	KMF_HANDLE *kmfh,
4343 	STACK_OF(EVP_PKEY) *sslkeys,
4344 	STACK_OF(X509) *sslcert,
4345 	STACK_OF(X509) *sslcacerts,
4346 	KMF_RAW_KEY_DATA **keylist, int *nkeys,
4347 	KMF_X509_DER_CERT **certlist, int *ncerts)
4348 {
4349 	KMF_RETURN rv = KMF_OK;
4350 	KMF_RAW_KEY_DATA key;
4351 	int i;
4352 
4353 	for (i = 0; sslkeys != NULL && i < sk_EVP_PKEY_num(sslkeys); i++) {
4354 		EVP_PKEY *pkey = sk_EVP_PKEY_value(sslkeys, i);
4355 		rv = convertToRawKey(pkey, &key);
4356 		if (rv == KMF_OK)
4357 			rv = add_key_to_list(keylist, &key, nkeys);
4358 
4359 		if (rv != KMF_OK)
4360 			return (rv);
4361 	}
4362 
4363 	/* Now add the certificate to the certlist */
4364 	for (i = 0; sslcert != NULL && i < sk_X509_num(sslcert); i++) {
4365 		X509 *cert = sk_X509_value(sslcert, i);
4366 		rv = add_cert_to_list(kmfh, cert, certlist, ncerts);
4367 		if (rv != KMF_OK)
4368 			return (rv);
4369 	}
4370 
4371 	/* Also add any included CA certs to the list */
4372 	for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) {
4373 		X509 *c;
4374 		/*
4375 		 * sk_X509_value() is macro that embeds a cast to (X509 *).
4376 		 * Here it translates into ((X509 *)sk_value((ca), (i))).
4377 		 * Lint is complaining about the embedded casting, and
4378 		 * to fix it, you need to fix openssl header files.
4379 		 */
4380 		c = sk_X509_value(sslcacerts, i);
4381 
4382 		/* Now add the ca cert to the certlist */
4383 		rv = add_cert_to_list(kmfh, c, certlist, ncerts);
4384 		if (rv != KMF_OK)
4385 			return (rv);
4386 	}
4387 	return (rv);
4388 }
4389 
4390 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)4391 openssl_import_objects(KMF_HANDLE *kmfh, char *filename, KMF_CREDENTIAL *cred,
4392     KMF_X509_DER_CERT **certlist, int *ncerts,
4393     KMF_RAW_KEY_DATA **keylist, int *nkeys)
4394 {
4395 	KMF_RETURN	rv = KMF_OK;
4396 	KMF_ENCODE_FORMAT format;
4397 	BIO		*bio = NULL;
4398 	STACK_OF(EVP_PKEY)	*privkeys = NULL;
4399 	STACK_OF(X509)		*certs = NULL;
4400 	STACK_OF(X509)		*cacerts = NULL;
4401 
4402 	/*
4403 	 * auto-detect the file format, regardless of what
4404 	 * the 'format' parameters in the params say.
4405 	 */
4406 	rv = kmf_get_file_format(filename, &format);
4407 	if (rv != KMF_OK) {
4408 		return (rv);
4409 	}
4410 
4411 	/* This function only works for PEM or PKCS#12 files */
4412 	if (format != KMF_FORMAT_PEM &&
4413 	    format != KMF_FORMAT_PEM_KEYPAIR &&
4414 	    format != KMF_FORMAT_PKCS12)
4415 		return (KMF_ERR_ENCODING);
4416 
4417 	*certlist = NULL;
4418 	*keylist = NULL;
4419 	*ncerts = 0;
4420 	*nkeys = 0;
4421 
4422 	if (format == KMF_FORMAT_PKCS12) {
4423 		bio = BIO_new_file(filename, "rb");
4424 		if (bio == NULL) {
4425 			SET_ERROR(kmfh, ERR_get_error());
4426 			rv = KMF_ERR_OPEN_FILE;
4427 			goto end;
4428 		}
4429 
4430 		rv = extract_pkcs12(bio, (uchar_t *)cred->cred,
4431 		    (uint32_t)cred->credlen, &privkeys, &certs, &cacerts);
4432 
4433 		if (rv  == KMF_OK)
4434 			/* Convert keys and certs to exportable format */
4435 			rv = convertPK12Objects(kmfh, privkeys, certs, cacerts,
4436 			    keylist, nkeys, certlist, ncerts);
4437 	} else {
4438 		EVP_PKEY *pkey;
4439 		KMF_DATA *certdata = NULL;
4440 		KMF_X509_DER_CERT *kmfcerts = NULL;
4441 		int i;
4442 		rv = extract_pem(kmfh, NULL, NULL, NULL, filename,
4443 		    (uchar_t *)cred->cred, (uint32_t)cred->credlen,
4444 		    &pkey, &certdata, ncerts);
4445 
4446 		/* Reached end of import file? */
4447 		if (rv == KMF_OK && pkey != NULL) {
4448 			privkeys = sk_EVP_PKEY_new_null();
4449 			if (privkeys == NULL) {
4450 				rv = KMF_ERR_MEMORY;
4451 				goto end;
4452 			}
4453 			(void) sk_EVP_PKEY_push(privkeys, pkey);
4454 			/* convert the certificate list here */
4455 			if (*ncerts > 0 && certlist != NULL) {
4456 				kmfcerts = (KMF_X509_DER_CERT *)calloc(*ncerts,
4457 				    sizeof (KMF_X509_DER_CERT));
4458 				if (kmfcerts == NULL) {
4459 					rv = KMF_ERR_MEMORY;
4460 					goto end;
4461 				}
4462 				for (i = 0; i < *ncerts; i++) {
4463 					kmfcerts[i].certificate = certdata[i];
4464 					kmfcerts[i].kmf_private.keystore_type =
4465 					    KMF_KEYSTORE_OPENSSL;
4466 				}
4467 				*certlist = kmfcerts;
4468 			}
4469 			/*
4470 			 * Convert keys to exportable format, the certs
4471 			 * are already OK.
4472 			 */
4473 			rv = convertPK12Objects(kmfh, privkeys, NULL, NULL,
4474 			    keylist, nkeys, NULL, NULL);
4475 		}
4476 	}
4477 end:
4478 	if (bio != NULL)
4479 		(void) BIO_free(bio);
4480 
4481 	if (privkeys)
4482 		sk_EVP_PKEY_pop_free(privkeys, EVP_PKEY_free);
4483 	if (certs)
4484 		sk_X509_pop_free(certs, X509_free);
4485 	if (cacerts)
4486 		sk_X509_pop_free(cacerts, X509_free);
4487 
4488 	return (rv);
4489 }
4490 
4491 static KMF_RETURN
create_deskey(DES_cblock ** deskey)4492 create_deskey(DES_cblock **deskey)
4493 {
4494 	DES_cblock *key;
4495 
4496 	key = (DES_cblock *) malloc(sizeof (DES_cblock));
4497 	if (key == NULL) {
4498 		return (KMF_ERR_MEMORY);
4499 	}
4500 
4501 	if (DES_random_key(key) == 0) {
4502 		free(key);
4503 		return (KMF_ERR_KEYGEN_FAILED);
4504 	}
4505 
4506 	*deskey = key;
4507 	return (KMF_OK);
4508 }
4509 
4510 #define	KEYGEN_RETRY 3
4511 #define	DES3_KEY_SIZE 24
4512 
4513 static KMF_RETURN
create_des3key(unsigned char ** des3key)4514 create_des3key(unsigned char **des3key)
4515 {
4516 	KMF_RETURN ret = KMF_OK;
4517 	DES_cblock *deskey1 = NULL;
4518 	DES_cblock *deskey2 = NULL;
4519 	DES_cblock *deskey3 = NULL;
4520 	unsigned char *newkey = NULL;
4521 	int retry;
4522 
4523 	if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) {
4524 		return (KMF_ERR_MEMORY);
4525 	}
4526 
4527 	/* create the 1st DES key */
4528 	if ((ret = create_deskey(&deskey1)) != KMF_OK) {
4529 		goto out;
4530 	}
4531 
4532 	/*
4533 	 * Create the 2nd DES key and make sure its value is different
4534 	 * from the 1st DES key.
4535 	 */
4536 	retry = 0;
4537 	do {
4538 		if (deskey2 != NULL) {
4539 			free(deskey2);
4540 			deskey2 = NULL;
4541 		}
4542 
4543 		if ((ret = create_deskey(&deskey2)) != KMF_OK) {
4544 			goto out;
4545 		}
4546 
4547 		if (memcmp((const void *) deskey1, (const void *) deskey2, 8)
4548 		    == 0) {
4549 			ret = KMF_ERR_KEYGEN_FAILED;
4550 			retry++;
4551 		}
4552 	} while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4553 
4554 	if (ret != KMF_OK) {
4555 		goto out;
4556 	}
4557 
4558 	/*
4559 	 * Create the 3rd DES key and make sure its value is different
4560 	 * from the 2nd DES key.
4561 	 */
4562 	retry = 0;
4563 	do {
4564 		if (deskey3 != NULL) {
4565 			free(deskey3);
4566 			deskey3 = NULL;
4567 		}
4568 
4569 		if ((ret = create_deskey(&deskey3)) != KMF_OK) {
4570 			goto out;
4571 		}
4572 
4573 		if (memcmp((const void *)deskey2, (const void *)deskey3, 8)
4574 		    == 0) {
4575 			ret = KMF_ERR_KEYGEN_FAILED;
4576 			retry++;
4577 		}
4578 	} while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4579 
4580 	if (ret != KMF_OK) {
4581 		goto out;
4582 	}
4583 
4584 	/* Concatenate 3 DES keys into a DES3 key */
4585 	(void) memcpy((void *)newkey, (const void *)deskey1, 8);
4586 	(void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8);
4587 	(void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8);
4588 	*des3key = newkey;
4589 
4590 out:
4591 	if (deskey1 != NULL)
4592 		free(deskey1);
4593 
4594 	if (deskey2 != NULL)
4595 		free(deskey2);
4596 
4597 	if (deskey3 != NULL)
4598 		free(deskey3);
4599 
4600 	if (ret != KMF_OK && newkey != NULL)
4601 		free(newkey);
4602 
4603 	return (ret);
4604 }
4605 
4606 KMF_RETURN
OpenSSL_CreateSymKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)4607 OpenSSL_CreateSymKey(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
4608 {
4609 	KMF_RETURN ret = KMF_OK;
4610 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4611 	char *fullpath = NULL;
4612 	KMF_RAW_SYM_KEY *rkey = NULL;
4613 	DES_cblock *deskey = NULL;
4614 	unsigned char *des3key = NULL;
4615 	unsigned char *random = NULL;
4616 	int fd = -1;
4617 	KMF_KEY_HANDLE *symkey;
4618 	KMF_KEY_ALG keytype;
4619 	uint32_t keylen;
4620 	uint32_t keylen_size = sizeof (keylen);
4621 	char *dirpath;
4622 	char *keyfile;
4623 
4624 	if (kmfh == NULL)
4625 		return (KMF_ERR_UNINITIALIZED);
4626 
4627 	symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
4628 	if (symkey == NULL)
4629 		return (KMF_ERR_BAD_PARAMETER);
4630 
4631 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
4632 
4633 	keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
4634 	if (keyfile == NULL)
4635 		return (KMF_ERR_BAD_PARAMETER);
4636 
4637 	ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
4638 	    (void *)&keytype, NULL);
4639 	if (ret != KMF_OK)
4640 		return (KMF_ERR_BAD_PARAMETER);
4641 
4642 	ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
4643 	    &keylen, &keylen_size);
4644 	if (ret == KMF_ERR_ATTR_NOT_FOUND &&
4645 	    (keytype == KMF_DES || keytype == KMF_DES3))
4646 		/* keylength is not required for DES and 3DES */
4647 		ret = KMF_OK;
4648 	if (ret != KMF_OK)
4649 		return (KMF_ERR_BAD_PARAMETER);
4650 
4651 	fullpath = get_fullpath(dirpath, keyfile);
4652 	if (fullpath == NULL)
4653 		return (KMF_ERR_BAD_PARAMETER);
4654 
4655 	/* If the requested file exists, return an error */
4656 	if (test_for_file(fullpath, 0400) == 1) {
4657 		free(fullpath);
4658 		return (KMF_ERR_DUPLICATE_KEYFILE);
4659 	}
4660 
4661 	fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400);
4662 	if (fd == -1) {
4663 		ret = KMF_ERR_OPEN_FILE;
4664 		goto out;
4665 	}
4666 
4667 	rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
4668 	if (rkey == NULL) {
4669 		ret = KMF_ERR_MEMORY;
4670 		goto out;
4671 	}
4672 	(void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
4673 
4674 	if (keytype == KMF_DES) {
4675 		if ((ret = create_deskey(&deskey)) != KMF_OK) {
4676 			goto out;
4677 		}
4678 		rkey->keydata.val = (uchar_t *)deskey;
4679 		rkey->keydata.len = 8;
4680 
4681 		symkey->keyalg = KMF_DES;
4682 
4683 	} else if (keytype == KMF_DES3) {
4684 		if ((ret = create_des3key(&des3key)) != KMF_OK) {
4685 			goto out;
4686 		}
4687 		rkey->keydata.val = (uchar_t *)des3key;
4688 		rkey->keydata.len = DES3_KEY_SIZE;
4689 		symkey->keyalg = KMF_DES3;
4690 
4691 	} else if (keytype == KMF_AES || keytype == KMF_RC4 ||
4692 	    keytype == KMF_GENERIC_SECRET) {
4693 		int bytes;
4694 
4695 		if (keylen % 8 != 0) {
4696 			ret = KMF_ERR_BAD_KEY_SIZE;
4697 			goto out;
4698 		}
4699 
4700 		if (keytype == KMF_AES) {
4701 			if (keylen != 128 &&
4702 			    keylen != 192 &&
4703 			    keylen != 256) {
4704 				ret = KMF_ERR_BAD_KEY_SIZE;
4705 				goto out;
4706 			}
4707 		}
4708 
4709 		bytes = keylen/8;
4710 		random = malloc(bytes);
4711 		if (random == NULL) {
4712 			ret = KMF_ERR_MEMORY;
4713 			goto out;
4714 		}
4715 		if (RAND_bytes(random, bytes) != 1) {
4716 			ret = KMF_ERR_KEYGEN_FAILED;
4717 			goto out;
4718 		}
4719 
4720 		rkey->keydata.val = (uchar_t *)random;
4721 		rkey->keydata.len = bytes;
4722 		symkey->keyalg = keytype;
4723 
4724 	} else {
4725 		ret = KMF_ERR_BAD_KEY_TYPE;
4726 		goto out;
4727 	}
4728 
4729 	(void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len);
4730 
4731 	symkey->kstype = KMF_KEYSTORE_OPENSSL;
4732 	symkey->keyclass = KMF_SYMMETRIC;
4733 	symkey->keylabel = (char *)fullpath;
4734 	symkey->israw = TRUE;
4735 	symkey->keyp = rkey;
4736 
4737 out:
4738 	if (fd != -1)
4739 		(void) close(fd);
4740 
4741 	if (ret != KMF_OK && fullpath != NULL) {
4742 		free(fullpath);
4743 	}
4744 	if (ret != KMF_OK) {
4745 		kmf_free_raw_sym_key(rkey);
4746 		symkey->keyp = NULL;
4747 		symkey->keyalg = KMF_KEYALG_NONE;
4748 	}
4749 
4750 	return (ret);
4751 }
4752 
4753 /*
4754  * Check a file to see if it is a CRL file with PEM or DER format.
4755  * If success, return its format in the "pformat" argument.
4756  */
4757 KMF_RETURN
OpenSSL_IsCRLFile(KMF_HANDLE_T handle,char * filename,int * pformat)4758 OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat)
4759 {
4760 	KMF_RETURN	ret = KMF_OK;
4761 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4762 	BIO		*bio = NULL;
4763 	X509_CRL	*xcrl = NULL;
4764 
4765 	if (filename == NULL) {
4766 		return (KMF_ERR_BAD_PARAMETER);
4767 	}
4768 
4769 	bio = BIO_new_file(filename, "rb");
4770 	if (bio == NULL)	{
4771 		SET_ERROR(kmfh, ERR_get_error());
4772 		ret = KMF_ERR_OPEN_FILE;
4773 		goto out;
4774 	}
4775 
4776 	if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) {
4777 		*pformat = KMF_FORMAT_PEM;
4778 		goto out;
4779 	}
4780 	(void) BIO_free(bio);
4781 
4782 	/*
4783 	 * Now try to read it as raw DER data.
4784 	 */
4785 	bio = BIO_new_file(filename, "rb");
4786 	if (bio == NULL)	{
4787 		SET_ERROR(kmfh, ERR_get_error());
4788 		ret = KMF_ERR_OPEN_FILE;
4789 		goto out;
4790 	}
4791 
4792 	if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) {
4793 		*pformat = KMF_FORMAT_ASN1;
4794 	} else {
4795 		ret = KMF_ERR_BAD_CRLFILE;
4796 	}
4797 
4798 out:
4799 	if (bio != NULL)
4800 		(void) BIO_free(bio);
4801 
4802 	if (xcrl != NULL)
4803 		X509_CRL_free(xcrl);
4804 
4805 	return (ret);
4806 }
4807 
4808 KMF_RETURN
OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle,KMF_KEY_HANDLE * symkey,KMF_RAW_SYM_KEY * rkey)4809 OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
4810     KMF_RAW_SYM_KEY *rkey)
4811 {
4812 	KMF_RETURN	rv = KMF_OK;
4813 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4814 	KMF_DATA	keyvalue;
4815 
4816 	if (kmfh == NULL)
4817 		return (KMF_ERR_UNINITIALIZED);
4818 
4819 	if (symkey == NULL || rkey == NULL)
4820 		return (KMF_ERR_BAD_PARAMETER);
4821 	else if (symkey->keyclass != KMF_SYMMETRIC)
4822 		return (KMF_ERR_BAD_KEY_CLASS);
4823 
4824 	if (symkey->israw) {
4825 		KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp;
4826 
4827 		if (rawkey == NULL ||
4828 		    rawkey->keydata.val == NULL ||
4829 		    rawkey->keydata.len == 0)
4830 			return (KMF_ERR_BAD_KEYHANDLE);
4831 
4832 		rkey->keydata.len = rawkey->keydata.len;
4833 		if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
4834 			return (KMF_ERR_MEMORY);
4835 		(void) memcpy(rkey->keydata.val, rawkey->keydata.val,
4836 		    rkey->keydata.len);
4837 	} else {
4838 		rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue);
4839 		if (rv != KMF_OK)
4840 			return (rv);
4841 		rkey->keydata.len = keyvalue.Length;
4842 		rkey->keydata.val = keyvalue.Data;
4843 	}
4844 
4845 	return (rv);
4846 }
4847 
4848 /*
4849  * substitute for the unsafe access(2) function.
4850  * If the file in question already exists, return 1.
4851  * else 0.  If an error occurs during testing (other
4852  * than EEXIST), return -1.
4853  */
4854 static int
test_for_file(char * filename,mode_t mode)4855 test_for_file(char *filename, mode_t mode)
4856 {
4857 	int fd;
4858 
4859 	/*
4860 	 * Try to create the file with the EXCL flag.
4861 	 * The call should fail if the file exists.
4862 	 */
4863 	fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode);
4864 	if (fd == -1 && errno == EEXIST)
4865 		return (1);
4866 	else if (fd == -1) /* some other error */
4867 		return (-1);
4868 
4869 	/* The file did NOT exist.  Delete the testcase. */
4870 	(void) close(fd);
4871 	(void) unlink(filename);
4872 	return (0);
4873 }
4874 
4875 KMF_RETURN
OpenSSL_StoreKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)4876 OpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
4877 {
4878 	KMF_RETURN rv = KMF_OK;
4879 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
4880 	KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL;
4881 	KMF_RAW_KEY_DATA *rawkey;
4882 	EVP_PKEY *pkey = NULL;
4883 	KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM;
4884 	KMF_CREDENTIAL cred = { NULL, 0 };
4885 	BIO *out = NULL;
4886 	int keys = 0;
4887 	char *fullpath = NULL;
4888 	char *keyfile = NULL;
4889 	char *dirpath = NULL;
4890 
4891 	pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
4892 	if (pubkey != NULL)
4893 		keys++;
4894 
4895 	prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
4896 	if (prikey != NULL)
4897 		keys++;
4898 
4899 	rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
4900 	if (rawkey != NULL)
4901 		keys++;
4902 
4903 	/*
4904 	 * Exactly 1 type of key must be passed to this function.
4905 	 */
4906 	if (keys != 1)
4907 		return (KMF_ERR_BAD_PARAMETER);
4908 
4909 	keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist,
4910 	    numattr);
4911 	if (keyfile == NULL)
4912 		return (KMF_ERR_BAD_PARAMETER);
4913 
4914 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
4915 
4916 	fullpath = get_fullpath(dirpath, keyfile);
4917 
4918 	/* Once we have the full path, we don't need the pieces */
4919 	if (fullpath == NULL)
4920 		return (KMF_ERR_BAD_PARAMETER);
4921 
4922 	/* If the requested file exists, return an error */
4923 	if (test_for_file(fullpath, 0400) == 1) {
4924 		free(fullpath);
4925 		return (KMF_ERR_DUPLICATE_KEYFILE);
4926 	}
4927 
4928 	rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
4929 	    &format, NULL);
4930 	if (rv != KMF_OK)
4931 		/* format is optional. */
4932 		rv = KMF_OK;
4933 
4934 	/* CRED is not required for OpenSSL files */
4935 	(void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
4936 	    &cred, NULL);
4937 
4938 	/* Store the private key to the keyfile */
4939 	out = BIO_new_file(fullpath, "wb");
4940 	if (out == NULL) {
4941 		SET_ERROR(kmfh, ERR_get_error());
4942 		rv = KMF_ERR_OPEN_FILE;
4943 		goto end;
4944 	}
4945 
4946 	if (prikey != NULL && prikey->keyp != NULL) {
4947 		if (prikey->keyalg == KMF_RSA ||
4948 		    prikey->keyalg == KMF_DSA) {
4949 			pkey = (EVP_PKEY *)prikey->keyp;
4950 
4951 			rv = ssl_write_key(kmfh, format,
4952 			    out, &cred, pkey, TRUE);
4953 
4954 			if (rv == KMF_OK && prikey->keylabel == NULL) {
4955 				prikey->keylabel = strdup(fullpath);
4956 				if (prikey->keylabel == NULL)
4957 					rv = KMF_ERR_MEMORY;
4958 			}
4959 		}
4960 	} else if (pubkey != NULL && pubkey->keyp != NULL) {
4961 		if (pubkey->keyalg == KMF_RSA ||
4962 		    pubkey->keyalg == KMF_DSA) {
4963 			pkey = (EVP_PKEY *)pubkey->keyp;
4964 
4965 			rv = ssl_write_key(kmfh, format,
4966 			    out, &cred, pkey, FALSE);
4967 
4968 			if (rv == KMF_OK && pubkey->keylabel == NULL) {
4969 				pubkey->keylabel = strdup(fullpath);
4970 				if (pubkey->keylabel == NULL)
4971 					rv = KMF_ERR_MEMORY;
4972 			}
4973 		}
4974 	} else if (rawkey != NULL) {
4975 		if (rawkey->keytype == KMF_RSA) {
4976 			pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
4977 		} else if (rawkey->keytype == KMF_DSA) {
4978 			pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
4979 		} else {
4980 			rv = KMF_ERR_BAD_PARAMETER;
4981 		}
4982 		if (pkey != NULL) {
4983 			KMF_KEY_CLASS kclass = KMF_ASYM_PRI;
4984 
4985 			rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
4986 			    (void *)&kclass, NULL);
4987 			if (rv != KMF_OK)
4988 				rv = KMF_OK;
4989 			rv = ssl_write_key(kmfh, format, out,
4990 			    &cred, pkey, (kclass == KMF_ASYM_PRI));
4991 			EVP_PKEY_free(pkey);
4992 		}
4993 	}
4994 
4995 end:
4996 
4997 	if (out)
4998 		(void) BIO_free(out);
4999 
5000 
5001 	if (rv == KMF_OK)
5002 		(void) chmod(fullpath, 0400);
5003 
5004 	free(fullpath);
5005 	return (rv);
5006 }
5007 
5008 KMF_RETURN
OpenSSL_ImportCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)5009 OpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5010 {
5011 	KMF_RETURN ret = KMF_OK;
5012 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5013 	X509_CRL *xcrl = NULL;
5014 	X509 *xcert = NULL;
5015 	EVP_PKEY *pkey;
5016 	KMF_ENCODE_FORMAT format;
5017 	BIO *in = NULL, *out = NULL;
5018 	int openssl_ret = 0;
5019 	KMF_ENCODE_FORMAT outformat;
5020 	boolean_t crlcheck = FALSE;
5021 	char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile;
5022 
5023 	if (numattr == 0 || attrlist == NULL) {
5024 		return (KMF_ERR_BAD_PARAMETER);
5025 	}
5026 
5027 	/* CRL check is optional */
5028 	(void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr,
5029 	    &crlcheck, NULL);
5030 
5031 	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
5032 	if (crlcheck == B_TRUE && certfile == NULL) {
5033 		return (KMF_ERR_BAD_CERTFILE);
5034 	}
5035 
5036 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5037 	incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr);
5038 	outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr);
5039 
5040 	crlfile = get_fullpath(dirpath, incrl);
5041 
5042 	if (crlfile == NULL)
5043 		return (KMF_ERR_BAD_CRLFILE);
5044 
5045 	outcrlfile = get_fullpath(dirpath, outcrl);
5046 	if (outcrlfile == NULL)
5047 		return (KMF_ERR_BAD_CRLFILE);
5048 
5049 	if (isdir(outcrlfile)) {
5050 		free(outcrlfile);
5051 		return (KMF_ERR_BAD_CRLFILE);
5052 	}
5053 
5054 	ret = kmf_is_crl_file(handle, crlfile, &format);
5055 	if (ret != KMF_OK) {
5056 		free(outcrlfile);
5057 		return (ret);
5058 	}
5059 
5060 	in = BIO_new_file(crlfile, "rb");
5061 	if (in == NULL)	{
5062 		SET_ERROR(kmfh, ERR_get_error());
5063 		ret = KMF_ERR_OPEN_FILE;
5064 		goto end;
5065 	}
5066 
5067 	if (format == KMF_FORMAT_ASN1) {
5068 		xcrl = d2i_X509_CRL_bio(in, NULL);
5069 	} else if (format == KMF_FORMAT_PEM) {
5070 		xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5071 	}
5072 
5073 	if (xcrl == NULL) {
5074 		SET_ERROR(kmfh, ERR_get_error());
5075 		ret = KMF_ERR_BAD_CRLFILE;
5076 		goto end;
5077 	}
5078 
5079 	/* If bypasscheck is specified, no need to verify. */
5080 	if (crlcheck == B_FALSE)
5081 		goto output;
5082 
5083 	ret = kmf_is_cert_file(handle, certfile, &format);
5084 	if (ret != KMF_OK)
5085 		goto end;
5086 
5087 	/* Read in the CA cert file and convert to X509 */
5088 	if (BIO_read_filename(in, certfile) <= 0) {
5089 		SET_ERROR(kmfh, ERR_get_error());
5090 		ret = KMF_ERR_OPEN_FILE;
5091 		goto end;
5092 	}
5093 
5094 	if (format == KMF_FORMAT_ASN1) {
5095 		xcert = d2i_X509_bio(in, NULL);
5096 	} else if (format == KMF_FORMAT_PEM) {
5097 		xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
5098 	} else {
5099 		ret = KMF_ERR_BAD_CERT_FORMAT;
5100 		goto end;
5101 	}
5102 
5103 	if (xcert == NULL) {
5104 		SET_ERROR(kmfh, ERR_get_error());
5105 		ret = KMF_ERR_BAD_CERT_FORMAT;
5106 		goto end;
5107 	}
5108 	/* Now get the public key from the CA cert */
5109 	pkey = X509_get_pubkey(xcert);
5110 	if (pkey == NULL) {
5111 		SET_ERROR(kmfh, ERR_get_error());
5112 		ret = KMF_ERR_BAD_CERTFILE;
5113 		goto end;
5114 	}
5115 
5116 	/* Verify the CRL with the CA's public key */
5117 	openssl_ret = X509_CRL_verify(xcrl, pkey);
5118 	EVP_PKEY_free(pkey);
5119 	if (openssl_ret > 0) {
5120 		ret = KMF_OK;  /* verify succeed */
5121 	} else {
5122 		SET_ERROR(kmfh, openssl_ret);
5123 		ret = KMF_ERR_BAD_CRLFILE;
5124 	}
5125 
5126 output:
5127 	ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
5128 	    &outformat, NULL);
5129 	if (ret != KMF_OK) {
5130 		ret = KMF_OK;
5131 		outformat = KMF_FORMAT_PEM;
5132 	}
5133 
5134 	out = BIO_new_file(outcrlfile, "wb");
5135 	if (out == NULL) {
5136 		SET_ERROR(kmfh, ERR_get_error());
5137 		ret = KMF_ERR_OPEN_FILE;
5138 		goto end;
5139 	}
5140 
5141 	if (outformat == KMF_FORMAT_ASN1) {
5142 		openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl);
5143 	} else if (outformat == KMF_FORMAT_PEM) {
5144 		openssl_ret = PEM_write_bio_X509_CRL(out, xcrl);
5145 	} else {
5146 		ret = KMF_ERR_BAD_PARAMETER;
5147 		goto end;
5148 	}
5149 
5150 	if (openssl_ret <= 0) {
5151 		SET_ERROR(kmfh, ERR_get_error());
5152 		ret = KMF_ERR_WRITE_FILE;
5153 	} else {
5154 		ret = KMF_OK;
5155 	}
5156 
5157 end:
5158 	if (xcrl != NULL)
5159 		X509_CRL_free(xcrl);
5160 
5161 	if (xcert != NULL)
5162 		X509_free(xcert);
5163 
5164 	if (in != NULL)
5165 		(void) BIO_free(in);
5166 
5167 	if (out != NULL)
5168 		(void) BIO_free(out);
5169 
5170 	if (outcrlfile != NULL)
5171 		free(outcrlfile);
5172 
5173 	return (ret);
5174 }
5175 
5176 KMF_RETURN
OpenSSL_ListCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)5177 OpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5178 {
5179 	KMF_RETURN ret = KMF_OK;
5180 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5181 	X509_CRL   *x = NULL;
5182 	KMF_ENCODE_FORMAT format;
5183 	char *crlfile = NULL;
5184 	BIO *in = NULL;
5185 	BIO *mem = NULL;
5186 	long len;
5187 	char *memptr;
5188 	char *data = NULL;
5189 	char **crldata;
5190 	char *crlfilename, *dirpath;
5191 
5192 	if (numattr == 0 || attrlist == NULL) {
5193 		return (KMF_ERR_BAD_PARAMETER);
5194 	}
5195 	crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5196 	    attrlist, numattr);
5197 	if (crlfilename == NULL)
5198 		return (KMF_ERR_BAD_CRLFILE);
5199 
5200 	crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR,
5201 	    attrlist, numattr);
5202 
5203 	if (crldata == NULL)
5204 		return (KMF_ERR_BAD_PARAMETER);
5205 
5206 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5207 
5208 	crlfile = get_fullpath(dirpath, crlfilename);
5209 
5210 	if (crlfile == NULL)
5211 		return (KMF_ERR_BAD_CRLFILE);
5212 
5213 	if (isdir(crlfile)) {
5214 		free(crlfile);
5215 		return (KMF_ERR_BAD_CRLFILE);
5216 	}
5217 
5218 	ret = kmf_is_crl_file(handle, crlfile, &format);
5219 	if (ret != KMF_OK) {
5220 		free(crlfile);
5221 		return (ret);
5222 	}
5223 
5224 	if (bio_err == NULL)
5225 		bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
5226 
5227 	in = BIO_new_file(crlfile, "rb");
5228 	if (in == NULL)	{
5229 		SET_ERROR(kmfh, ERR_get_error());
5230 		ret = KMF_ERR_OPEN_FILE;
5231 		goto end;
5232 	}
5233 
5234 	if (format == KMF_FORMAT_ASN1) {
5235 		x = d2i_X509_CRL_bio(in, NULL);
5236 	} else if (format == KMF_FORMAT_PEM) {
5237 		x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5238 	}
5239 
5240 	if (x == NULL) { /* should not happen */
5241 		SET_ERROR(kmfh, ERR_get_error());
5242 		ret = KMF_ERR_OPEN_FILE;
5243 		goto end;
5244 	}
5245 
5246 	mem = BIO_new(BIO_s_mem());
5247 	if (mem == NULL) {
5248 		SET_ERROR(kmfh, ERR_get_error());
5249 		ret = KMF_ERR_MEMORY;
5250 		goto end;
5251 	}
5252 
5253 	(void) X509_CRL_print(mem, x);
5254 	len = BIO_get_mem_data(mem, &memptr);
5255 	if (len <= 0) {
5256 		SET_ERROR(kmfh, ERR_get_error());
5257 		ret = KMF_ERR_MEMORY;
5258 		goto end;
5259 	}
5260 
5261 	data = malloc(len + 1);
5262 	if (data == NULL) {
5263 		ret = KMF_ERR_MEMORY;
5264 		goto end;
5265 	}
5266 
5267 	(void) memcpy(data, memptr, len);
5268 	data[len] = '\0';
5269 	*crldata = data;
5270 
5271 end:
5272 	if (x != NULL)
5273 		X509_CRL_free(x);
5274 
5275 	if (crlfile != NULL)
5276 		free(crlfile);
5277 
5278 	if (in != NULL)
5279 		(void) BIO_free(in);
5280 
5281 	if (mem != NULL)
5282 		(void) BIO_free(mem);
5283 
5284 	return (ret);
5285 }
5286 
5287 KMF_RETURN
OpenSSL_DeleteCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)5288 OpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5289 {
5290 	KMF_RETURN ret = KMF_OK;
5291 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5292 	KMF_ENCODE_FORMAT format;
5293 	char *crlfile = NULL;
5294 	BIO *in = NULL;
5295 	char *crlfilename, *dirpath;
5296 
5297 	if (numattr == 0 || attrlist == NULL) {
5298 		return (KMF_ERR_BAD_PARAMETER);
5299 	}
5300 
5301 	crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5302 	    attrlist, numattr);
5303 
5304 	if (crlfilename == NULL)
5305 		return (KMF_ERR_BAD_CRLFILE);
5306 
5307 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5308 
5309 	crlfile = get_fullpath(dirpath, crlfilename);
5310 
5311 	if (crlfile == NULL)
5312 		return (KMF_ERR_BAD_CRLFILE);
5313 
5314 	if (isdir(crlfile)) {
5315 		ret = KMF_ERR_BAD_CRLFILE;
5316 		goto end;
5317 	}
5318 
5319 	ret = kmf_is_crl_file(handle, crlfile, &format);
5320 	if (ret != KMF_OK)
5321 		goto end;
5322 
5323 	if (unlink(crlfile) != 0) {
5324 		SET_SYS_ERROR(kmfh, errno);
5325 		ret = KMF_ERR_INTERNAL;
5326 		goto end;
5327 	}
5328 
5329 end:
5330 	if (in != NULL)
5331 		(void) BIO_free(in);
5332 	if (crlfile != NULL)
5333 		free(crlfile);
5334 
5335 	return (ret);
5336 }
5337 
5338 KMF_RETURN
OpenSSL_FindCertInCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)5339 OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5340 {
5341 	KMF_RETURN ret = KMF_OK;
5342 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5343 	KMF_ENCODE_FORMAT format;
5344 	BIO *in = NULL;
5345 	X509   *xcert = NULL;
5346 	X509_CRL   *xcrl = NULL;
5347 	STACK_OF(X509_REVOKED) *revoke_stack = NULL;
5348 	X509_REVOKED *revoke;
5349 	int i;
5350 	char *crlfilename, *crlfile, *dirpath, *certfile;
5351 
5352 	if (numattr == 0 || attrlist == NULL) {
5353 		return (KMF_ERR_BAD_PARAMETER);
5354 	}
5355 
5356 	crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5357 	    attrlist, numattr);
5358 
5359 	if (crlfilename == NULL)
5360 		return (KMF_ERR_BAD_CRLFILE);
5361 
5362 	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
5363 	if (certfile == NULL)
5364 		return (KMF_ERR_BAD_CRLFILE);
5365 
5366 	dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5367 
5368 	crlfile = get_fullpath(dirpath, crlfilename);
5369 
5370 	if (crlfile == NULL)
5371 		return (KMF_ERR_BAD_CRLFILE);
5372 
5373 	if (isdir(crlfile)) {
5374 		ret = KMF_ERR_BAD_CRLFILE;
5375 		goto end;
5376 	}
5377 
5378 	ret = kmf_is_crl_file(handle, crlfile, &format);
5379 	if (ret != KMF_OK)
5380 		goto end;
5381 
5382 	/* Read the CRL file and load it into a X509_CRL structure */
5383 	in = BIO_new_file(crlfilename, "rb");
5384 	if (in == NULL)	{
5385 		SET_ERROR(kmfh, ERR_get_error());
5386 		ret = KMF_ERR_OPEN_FILE;
5387 		goto end;
5388 	}
5389 
5390 	if (format == KMF_FORMAT_ASN1) {
5391 		xcrl = d2i_X509_CRL_bio(in, NULL);
5392 	} else if (format == KMF_FORMAT_PEM) {
5393 		xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5394 	}
5395 
5396 	if (xcrl == NULL) {
5397 		SET_ERROR(kmfh, ERR_get_error());
5398 		ret = KMF_ERR_BAD_CRLFILE;
5399 		goto end;
5400 	}
5401 	(void) BIO_free(in);
5402 
5403 	/* Read the Certificate file and load it into a X509 structure */
5404 	ret = kmf_is_cert_file(handle, certfile, &format);
5405 	if (ret != KMF_OK)
5406 		goto end;
5407 
5408 	in = BIO_new_file(certfile, "rb");
5409 	if (in == NULL)	{
5410 		SET_ERROR(kmfh, ERR_get_error());
5411 		ret = KMF_ERR_OPEN_FILE;
5412 		goto end;
5413 	}
5414 
5415 	if (format == KMF_FORMAT_ASN1) {
5416 		xcert = d2i_X509_bio(in, NULL);
5417 	} else if (format == KMF_FORMAT_PEM) {
5418 		xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
5419 	}
5420 
5421 	if (xcert == NULL) {
5422 		SET_ERROR(kmfh, ERR_get_error());
5423 		ret = KMF_ERR_BAD_CERTFILE;
5424 		goto end;
5425 	}
5426 
5427 	/* Check if the certificate and the CRL have same issuer */
5428 	if (X509_NAME_cmp(X509_get_issuer_name(xcert),
5429 	    X509_CRL_get_issuer(xcrl)) != 0) {
5430 		ret = KMF_ERR_ISSUER;
5431 		goto end;
5432 	}
5433 
5434 	/* Check to see if the certificate serial number is revoked */
5435 	revoke_stack = X509_CRL_get_REVOKED(xcrl);
5436 	if (sk_X509_REVOKED_num(revoke_stack) <= 0) {
5437 		/* No revoked certificates in the CRL file */
5438 		SET_ERROR(kmfh, ERR_get_error());
5439 		ret = KMF_ERR_EMPTY_CRL;
5440 		goto end;
5441 	}
5442 
5443 	for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) {
5444 		revoke = sk_X509_REVOKED_value(revoke_stack, i);
5445 		if (ASN1_INTEGER_cmp(X509_get_serialNumber(xcert),
5446 		    X509_REVOKED_get0_serialNumber(revoke)) == 0) {
5447 			break;
5448 		}
5449 	}
5450 
5451 	if (i < sk_X509_REVOKED_num(revoke_stack)) {
5452 		ret = KMF_OK;
5453 	} else {
5454 		ret = KMF_ERR_NOT_REVOKED;
5455 	}
5456 
5457 end:
5458 	if (in != NULL)
5459 		(void) BIO_free(in);
5460 	if (xcrl != NULL)
5461 		X509_CRL_free(xcrl);
5462 	if (xcert != NULL)
5463 		X509_free(xcert);
5464 
5465 	return (ret);
5466 }
5467 
5468 KMF_RETURN
OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle,char * crlname,KMF_DATA * tacert)5469 OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert)
5470 {
5471 	KMF_RETURN	ret = KMF_OK;
5472 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
5473 	BIO		*bcrl = NULL;
5474 	X509_CRL	*xcrl = NULL;
5475 	X509		*xcert = NULL;
5476 	EVP_PKEY	*pkey;
5477 	int		sslret;
5478 	KMF_ENCODE_FORMAT crl_format;
5479 	unsigned char	*p;
5480 	long		len;
5481 
5482 	if (handle == NULL || crlname == NULL || tacert == NULL) {
5483 		return (KMF_ERR_BAD_PARAMETER);
5484 	}
5485 
5486 	ret = kmf_get_file_format(crlname, &crl_format);
5487 	if (ret != KMF_OK)
5488 		return (ret);
5489 
5490 	bcrl = BIO_new_file(crlname, "rb");
5491 	if (bcrl == NULL)	{
5492 		SET_ERROR(kmfh, ERR_get_error());
5493 		ret = KMF_ERR_OPEN_FILE;
5494 		goto cleanup;
5495 	}
5496 
5497 	if (crl_format == KMF_FORMAT_ASN1) {
5498 		xcrl = d2i_X509_CRL_bio(bcrl, NULL);
5499 	} else if (crl_format == KMF_FORMAT_PEM) {
5500 		xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
5501 	} else {
5502 		ret = KMF_ERR_BAD_PARAMETER;
5503 		goto cleanup;
5504 	}
5505 
5506 	if (xcrl == NULL) {
5507 		SET_ERROR(kmfh, ERR_get_error());
5508 		ret = KMF_ERR_BAD_CRLFILE;
5509 		goto cleanup;
5510 	}
5511 
5512 	p = tacert->Data;
5513 	len = tacert->Length;
5514 	xcert = d2i_X509(NULL, (const uchar_t **)&p, len);
5515 
5516 	if (xcert == NULL) {
5517 		SET_ERROR(kmfh, ERR_get_error());
5518 		ret = KMF_ERR_BAD_CERTFILE;
5519 		goto cleanup;
5520 	}
5521 
5522 	/* Get issuer certificate public key */
5523 	pkey = X509_get_pubkey(xcert);
5524 	if (pkey == NULL) {
5525 		SET_ERROR(kmfh, ERR_get_error());
5526 		ret = KMF_ERR_BAD_CERT_FORMAT;
5527 		goto cleanup;
5528 	}
5529 
5530 	/* Verify CRL signature */
5531 	sslret = X509_CRL_verify(xcrl, pkey);
5532 	EVP_PKEY_free(pkey);
5533 	if (sslret > 0) {
5534 		ret = KMF_OK;
5535 	} else {
5536 		SET_ERROR(kmfh, sslret);
5537 		ret = KMF_ERR_BAD_CRLFILE;
5538 	}
5539 
5540 cleanup:
5541 	if (bcrl != NULL)
5542 		(void) BIO_free(bcrl);
5543 
5544 	if (xcrl != NULL)
5545 		X509_CRL_free(xcrl);
5546 
5547 	if (xcert != NULL)
5548 		X509_free(xcert);
5549 
5550 	return (ret);
5551 
5552 }
5553 
5554 KMF_RETURN
OpenSSL_CheckCRLDate(KMF_HANDLE_T handle,char * crlname)5555 OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname)
5556 {
5557 	KMF_RETURN	ret = KMF_OK;
5558 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
5559 	KMF_ENCODE_FORMAT crl_format;
5560 	BIO		*bcrl = NULL;
5561 	X509_CRL	*xcrl = NULL;
5562 	int		i;
5563 
5564 	if (handle == NULL || crlname == NULL) {
5565 		return (KMF_ERR_BAD_PARAMETER);
5566 	}
5567 
5568 	ret = kmf_is_crl_file(handle, crlname, &crl_format);
5569 	if (ret != KMF_OK)
5570 		return (ret);
5571 
5572 	bcrl = BIO_new_file(crlname, "rb");
5573 	if (bcrl == NULL) {
5574 		SET_ERROR(kmfh, ERR_get_error());
5575 		ret = KMF_ERR_OPEN_FILE;
5576 		goto cleanup;
5577 	}
5578 
5579 	if (crl_format == KMF_FORMAT_ASN1)
5580 		xcrl = d2i_X509_CRL_bio(bcrl, NULL);
5581 	else if (crl_format == KMF_FORMAT_PEM)
5582 		xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
5583 
5584 	if (xcrl == NULL) {
5585 		SET_ERROR(kmfh, ERR_get_error());
5586 		ret = KMF_ERR_BAD_CRLFILE;
5587 		goto cleanup;
5588 	}
5589 	i = X509_cmp_time(X509_CRL_get0_lastUpdate(xcrl), NULL);
5590 	if (i >= 0) {
5591 		ret = KMF_ERR_VALIDITY_PERIOD;
5592 		goto cleanup;
5593 	}
5594 	if (X509_CRL_get0_nextUpdate(xcrl)) {
5595 		i = X509_cmp_time(X509_CRL_get0_nextUpdate(xcrl), NULL);
5596 
5597 		if (i <= 0) {
5598 			ret = KMF_ERR_VALIDITY_PERIOD;
5599 			goto cleanup;
5600 		}
5601 	}
5602 
5603 	ret = KMF_OK;
5604 
5605 cleanup:
5606 	if (bcrl != NULL)
5607 		(void) BIO_free(bcrl);
5608 
5609 	if (xcrl != NULL)
5610 		X509_CRL_free(xcrl);
5611 
5612 	return (ret);
5613 }
5614