ipsec_libssl_setup.c revision 6619:42f1b8b29716
1/*
2 * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to.  The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 *    must display the following acknowledgement:
33 *    "This product includes cryptographic software written by
34 *     Eric Young (eay@cryptsoft.com)"
35 *    The word 'cryptographic' can be left out if the rouines from the library
36 *    being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 *    the apps directory (application code) you must include an acknowledgement:
39 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59/*
60 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
61 * Use is subject to license terms.
62 */
63
64/*
65 * Thread setup portions of this code derived from
66 * OpenSSL 0.9.4 file mt/mttest.c examples
67 */
68
69#pragma ident	"%Z%%M%	%I%	%E% SMI"
70
71#include <stdio.h>
72#include <stdlib.h>
73#include <string.h>
74#include <errno.h>
75#include <libintl.h>
76#include <synch.h>
77#include <thread.h>
78#include <dlfcn.h>
79#include <openssl/lhash.h>
80#include <openssl/crypto.h>
81#include <openssl/ssl.h>
82#include <openssl/err.h>
83#include "ipsec_util.h"
84
85/* OpenSSL function pointers */
86static X509_NAME *(*d2i_X509_NAME_fn)() = NULL;
87static int (*X509_NAME_print_ex_fp_fn)() = NULL;
88static char *(*ERR_get_error_fn)() = NULL;
89static char *(*ERR_error_string_fn)() = NULL;
90static void (*SSL_load_error_strings_fn)() = NULL;
91static void (*ERR_free_strings_fn)() = NULL;
92static void (*CRYPTO_set_locking_callback_fn)() = NULL;
93static void (*CRYPTO_set_id_callback_fn)() = NULL;
94static void (*OPENSSL_free_fn)() = NULL;
95
96static void solaris_locking_callback(int, int, char *, int);
97static unsigned long solaris_thread_id(void);
98static void thread_setup(void);
99/* LINTED E_STATIC_UNUSED */
100static void thread_cleanup(void);
101
102mutex_t init_lock = DEFAULTMUTEX;
103static mutex_t lock_cs[CRYPTO_NUM_LOCKS];
104static long lock_count[CRYPTO_NUM_LOCKS];
105
106void
107libssl_load()
108{
109	void *dldesc;
110
111	(void) mutex_lock(&init_lock);
112	if (libssl_loaded) {
113		(void) mutex_unlock(&init_lock);
114		return;
115	}
116
117	dldesc = dlopen(LIBSSL, RTLD_LAZY);
118	if (dldesc != NULL) {
119		d2i_X509_NAME_fn = (X509_NAME*(*)())dlsym(dldesc,
120		    "d2i_X509_NAME");
121		if (d2i_X509_NAME_fn == NULL)
122			goto libssl_err;
123
124		X509_NAME_print_ex_fp_fn = (int(*)())dlsym(dldesc,
125		    "X509_NAME_print_ex_fp");
126		if (X509_NAME_print_ex_fp_fn == NULL)
127			goto libssl_err;
128
129		ERR_get_error_fn = (char *(*)())dlsym(dldesc,
130		    "ERR_get_error");
131		if (ERR_get_error_fn == NULL)
132			goto libssl_err;
133
134		ERR_error_string_fn = (char *(*)())dlsym(dldesc,
135		    "ERR_error_string");
136		if (ERR_error_string_fn == NULL)
137			goto libssl_err;
138
139		SSL_load_error_strings_fn = (void(*)())dlsym(dldesc,
140		    "SSL_load_error_strings");
141		if (SSL_load_error_strings_fn == NULL)
142			goto libssl_err;
143
144		ERR_free_strings_fn = (void(*)())dlsym(dldesc,
145		    "ERR_free_strings");
146		if (ERR_free_strings_fn == NULL)
147			goto libssl_err;
148
149		CRYPTO_set_locking_callback_fn = (void(*)())dlsym(dldesc,
150		    "CRYPTO_set_locking_callback");
151		if (CRYPTO_set_locking_callback_fn == NULL)
152			goto libssl_err;
153
154		CRYPTO_set_id_callback_fn = (void(*)())dlsym(dldesc,
155		    "CRYPTO_set_id_callback");
156		if (CRYPTO_set_id_callback_fn == NULL)
157			goto libssl_err;
158
159		OPENSSL_free_fn = (void(*)())dlsym(dldesc,
160		    "OPENSSL_free");
161		if (OPENSSL_free_fn == NULL)
162			goto libssl_err;
163
164		thread_setup();
165
166		libssl_loaded = B_TRUE;
167	}
168	(void) mutex_unlock(&init_lock);
169	return;
170libssl_err:
171	(void) dlclose(dldesc);
172	(void) mutex_unlock(&init_lock);
173}
174
175static void
176thread_setup(void)
177{
178	int i;
179
180	for (i = 0; i < CRYPTO_NUM_LOCKS; i++) {
181		lock_count[i] = 0;
182		(void) mutex_init(&(lock_cs[i]), USYNC_THREAD, NULL);
183	}
184
185	CRYPTO_set_id_callback_fn((unsigned long (*)())solaris_thread_id);
186	CRYPTO_set_locking_callback_fn((void (*)())solaris_locking_callback);
187}
188
189static void
190thread_cleanup(void)
191{
192	int i;
193
194	(void) mutex_lock(&init_lock);
195	CRYPTO_set_locking_callback_fn(NULL);
196	CRYPTO_set_id_callback_fn(NULL);
197	for (i = 0; i < CRYPTO_NUM_LOCKS; i++)
198		(void) mutex_destroy(&(lock_cs[i]));
199	(void) mutex_unlock(&init_lock);
200}
201
202/* ARGSUSED */
203static void
204solaris_locking_callback(int mode, int type, char *file, int line)
205{
206	if (mode & CRYPTO_LOCK) {
207		(void) mutex_lock(&(lock_cs[type]));
208		lock_count[type]++;
209	} else {
210		(void) mutex_unlock(&(lock_cs[type]));
211	}
212}
213
214static unsigned long
215solaris_thread_id(void)
216{
217	unsigned long ret;
218
219	ret = (unsigned long)thr_self();
220	return (ret);
221}
222
223void
224print_asn1_name(FILE *file, const unsigned char *buf, long buflen)
225{
226	libssl_load();
227
228	if (libssl_loaded) {
229		X509_NAME *x509 = NULL;
230		const unsigned char *p;
231
232		/* Make an effort to decode the ASN1 encoded name */
233		SSL_load_error_strings_fn();
234
235		/* temporary variable is mandatory per openssl docs */
236		p = buf;
237
238		x509 = d2i_X509_NAME_fn(NULL, &p, buflen);
239		if (x509 != NULL) {
240			(void) X509_NAME_print_ex_fp_fn(file, x509, 0,
241			    (ASN1_STRFLGS_RFC2253 | ASN1_STRFLGS_ESC_QUOTE |
242			    XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN));
243			OPENSSL_free_fn(p);
244			(void) fprintf(file, "\n");
245		} else {
246			char errbuf[80];
247
248			(void) fprintf(file, "\n# %s\n",
249			    ERR_error_string_fn(ERR_get_error_fn(), errbuf));
250			(void) fprintf(file, dgettext(TEXT_DOMAIN,
251			    "<cannot interpret>\n"));
252		}
253		ERR_free_strings_fn();
254	} else {
255		(void) fprintf(file, dgettext(TEXT_DOMAIN, "<cannot print>\n"));
256	}
257}
258