xref: /onnv-gate/usr/src/lib/libkmsagent/common/k_setupssl.c (revision 12720:3db6e0082404)
1*12720SWyllys.Ingersoll@Sun.COM /*
2*12720SWyllys.Ingersoll@Sun.COM  * CDDL HEADER START
3*12720SWyllys.Ingersoll@Sun.COM  *
4*12720SWyllys.Ingersoll@Sun.COM  * The contents of this file are subject to the terms of the
5*12720SWyllys.Ingersoll@Sun.COM  * Common Development and Distribution License (the "License").
6*12720SWyllys.Ingersoll@Sun.COM  * You may not use this file except in compliance with the License.
7*12720SWyllys.Ingersoll@Sun.COM  *
8*12720SWyllys.Ingersoll@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12720SWyllys.Ingersoll@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*12720SWyllys.Ingersoll@Sun.COM  * See the License for the specific language governing permissions
11*12720SWyllys.Ingersoll@Sun.COM  * and limitations under the License.
12*12720SWyllys.Ingersoll@Sun.COM  *
13*12720SWyllys.Ingersoll@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*12720SWyllys.Ingersoll@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12720SWyllys.Ingersoll@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*12720SWyllys.Ingersoll@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*12720SWyllys.Ingersoll@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*12720SWyllys.Ingersoll@Sun.COM  *
19*12720SWyllys.Ingersoll@Sun.COM  * CDDL HEADER END
20*12720SWyllys.Ingersoll@Sun.COM  */
21*12720SWyllys.Ingersoll@Sun.COM 
22*12720SWyllys.Ingersoll@Sun.COM /*
23*12720SWyllys.Ingersoll@Sun.COM  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*12720SWyllys.Ingersoll@Sun.COM  */
25*12720SWyllys.Ingersoll@Sun.COM 
26*12720SWyllys.Ingersoll@Sun.COM /*---------------------------------------------------------------------------
27*12720SWyllys.Ingersoll@Sun.COM  * Module:            k_setupssl.c
28*12720SWyllys.Ingersoll@Sun.COM  * Operating System:  Linux, Win32
29*12720SWyllys.Ingersoll@Sun.COM  *
30*12720SWyllys.Ingersoll@Sun.COM  * Description:
31*12720SWyllys.Ingersoll@Sun.COM  * This is the C Implementation file for setting up OpenSSL muti-threading environment
32*12720SWyllys.Ingersoll@Sun.COM  *
33*12720SWyllys.Ingersoll@Sun.COM  *-------------------------------------------------------------------------*/
34*12720SWyllys.Ingersoll@Sun.COM 
35*12720SWyllys.Ingersoll@Sun.COM #ifndef WIN32
36*12720SWyllys.Ingersoll@Sun.COM #include <signal.h>
37*12720SWyllys.Ingersoll@Sun.COM #include <openssl/evp.h>	/* UNIX */
38*12720SWyllys.Ingersoll@Sun.COM #include <openssl/engine.h>
39*12720SWyllys.Ingersoll@Sun.COM #endif
40*12720SWyllys.Ingersoll@Sun.COM 
41*12720SWyllys.Ingersoll@Sun.COM #include "k_setupssl.h"
42*12720SWyllys.Ingersoll@Sun.COM #include "stdsoap2.h"
43*12720SWyllys.Ingersoll@Sun.COM #include <openssl/crypto.h>
44*12720SWyllys.Ingersoll@Sun.COM 
45*12720SWyllys.Ingersoll@Sun.COM #if defined(WIN32)
46*12720SWyllys.Ingersoll@Sun.COM 
47*12720SWyllys.Ingersoll@Sun.COM #include <windows.h>
48*12720SWyllys.Ingersoll@Sun.COM #define MUTEX_TYPE              HANDLE
49*12720SWyllys.Ingersoll@Sun.COM #define MUTEX_SETUP(x)          (x) = CreateMutex(NULL, FALSE, NULL)
50*12720SWyllys.Ingersoll@Sun.COM #define MUTEX_CLEANUP(x)        CloseHandle(x)
51*12720SWyllys.Ingersoll@Sun.COM #define MUTEX_LOCK(x)           WaitForSingleObject((x), INFINITE)
52*12720SWyllys.Ingersoll@Sun.COM #define MUTEX_UNLOCK(x)         ReleaseMutex(x)
53*12720SWyllys.Ingersoll@Sun.COM #define THREAD_ID               GetCurrentThreadId()
54*12720SWyllys.Ingersoll@Sun.COM 
55*12720SWyllys.Ingersoll@Sun.COM #else
56*12720SWyllys.Ingersoll@Sun.COM 
57*12720SWyllys.Ingersoll@Sun.COM #include <pthread.h>
58*12720SWyllys.Ingersoll@Sun.COM 
59*12720SWyllys.Ingersoll@Sun.COM # define MUTEX_TYPE             pthread_mutex_t
60*12720SWyllys.Ingersoll@Sun.COM # define MUTEX_SETUP(x)         pthread_mutex_init(&(x), NULL)
61*12720SWyllys.Ingersoll@Sun.COM # define MUTEX_CLEANUP(x)       pthread_mutex_destroy(&(x))
62*12720SWyllys.Ingersoll@Sun.COM # define MUTEX_LOCK(x)          pthread_mutex_lock(&(x))
63*12720SWyllys.Ingersoll@Sun.COM # define MUTEX_UNLOCK(x)        pthread_mutex_unlock(&(x))
64*12720SWyllys.Ingersoll@Sun.COM # define THREAD_ID              pthread_self()
65*12720SWyllys.Ingersoll@Sun.COM 
66*12720SWyllys.Ingersoll@Sun.COM #ifdef K_SOLARIS_PLATFORM
67*12720SWyllys.Ingersoll@Sun.COM MUTEX_TYPE	init_ssl_mutex = PTHREAD_MUTEX_INITIALIZER;
68*12720SWyllys.Ingersoll@Sun.COM static		int	ssl_initialized = 0;
69*12720SWyllys.Ingersoll@Sun.COM #endif
70*12720SWyllys.Ingersoll@Sun.COM #endif
71*12720SWyllys.Ingersoll@Sun.COM 
72*12720SWyllys.Ingersoll@Sun.COM struct CRYPTO_dynlock_value
73*12720SWyllys.Ingersoll@Sun.COM { MUTEX_TYPE mutex;
74*12720SWyllys.Ingersoll@Sun.COM };
75*12720SWyllys.Ingersoll@Sun.COM 
sigpipe_handle(int x)76*12720SWyllys.Ingersoll@Sun.COM void sigpipe_handle(int x)
77*12720SWyllys.Ingersoll@Sun.COM {
78*12720SWyllys.Ingersoll@Sun.COM }
79*12720SWyllys.Ingersoll@Sun.COM 
80*12720SWyllys.Ingersoll@Sun.COM static MUTEX_TYPE *mutex_buf;
81*12720SWyllys.Ingersoll@Sun.COM 
dyn_create_function(const char * file,int line)82*12720SWyllys.Ingersoll@Sun.COM static struct CRYPTO_dynlock_value *dyn_create_function(const char *file, int line)
83*12720SWyllys.Ingersoll@Sun.COM { struct CRYPTO_dynlock_value *value;
84*12720SWyllys.Ingersoll@Sun.COM   value = (struct CRYPTO_dynlock_value*)malloc(sizeof(struct CRYPTO_dynlock_value));
85*12720SWyllys.Ingersoll@Sun.COM   if (value)
86*12720SWyllys.Ingersoll@Sun.COM     MUTEX_SETUP(value->mutex);
87*12720SWyllys.Ingersoll@Sun.COM   return value;
88*12720SWyllys.Ingersoll@Sun.COM }
89*12720SWyllys.Ingersoll@Sun.COM 
dyn_lock_function(int mode,struct CRYPTO_dynlock_value * l,const char * file,int line)90*12720SWyllys.Ingersoll@Sun.COM static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)
91*12720SWyllys.Ingersoll@Sun.COM { if (mode & CRYPTO_LOCK)
92*12720SWyllys.Ingersoll@Sun.COM     MUTEX_LOCK(l->mutex);
93*12720SWyllys.Ingersoll@Sun.COM   else
94*12720SWyllys.Ingersoll@Sun.COM     MUTEX_UNLOCK(l->mutex);
95*12720SWyllys.Ingersoll@Sun.COM }
96*12720SWyllys.Ingersoll@Sun.COM 
dyn_destroy_function(struct CRYPTO_dynlock_value * l,const char * file,int line)97*12720SWyllys.Ingersoll@Sun.COM static void dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line)
98*12720SWyllys.Ingersoll@Sun.COM { MUTEX_CLEANUP(l->mutex);
99*12720SWyllys.Ingersoll@Sun.COM   free(l);
100*12720SWyllys.Ingersoll@Sun.COM }
101*12720SWyllys.Ingersoll@Sun.COM 
kms_locking_function(int mode,int n,const char * file,int line)102*12720SWyllys.Ingersoll@Sun.COM void kms_locking_function(int mode, int n, const char *file, int line)
103*12720SWyllys.Ingersoll@Sun.COM { if (mode & CRYPTO_LOCK)
104*12720SWyllys.Ingersoll@Sun.COM     MUTEX_LOCK(mutex_buf[n]);
105*12720SWyllys.Ingersoll@Sun.COM   else
106*12720SWyllys.Ingersoll@Sun.COM     MUTEX_UNLOCK(mutex_buf[n]);
107*12720SWyllys.Ingersoll@Sun.COM }
108*12720SWyllys.Ingersoll@Sun.COM 
109*12720SWyllys.Ingersoll@Sun.COM 
id_function(void)110*12720SWyllys.Ingersoll@Sun.COM unsigned long id_function(void )
111*12720SWyllys.Ingersoll@Sun.COM { return (unsigned long)THREAD_ID;
112*12720SWyllys.Ingersoll@Sun.COM }
113*12720SWyllys.Ingersoll@Sun.COM 
114*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32
115*12720SWyllys.Ingersoll@Sun.COM void OpenSSL_add_all_ciphers(void);	// UNIX
116*12720SWyllys.Ingersoll@Sun.COM void OpenSSL_add_all_digests(void);
117*12720SWyllys.Ingersoll@Sun.COM #endif
118*12720SWyllys.Ingersoll@Sun.COM 
119*12720SWyllys.Ingersoll@Sun.COM #ifdef K_HPUX_PLATFORM
120*12720SWyllys.Ingersoll@Sun.COM extern void allow_unaligned_data_access();
121*12720SWyllys.Ingersoll@Sun.COM #endif
122*12720SWyllys.Ingersoll@Sun.COM 
123*12720SWyllys.Ingersoll@Sun.COM // gSOAP 2.7e:
124*12720SWyllys.Ingersoll@Sun.COM //   The function ssl_init is defined in stdsoap2.cpp and is not exported by
125*12720SWyllys.Ingersoll@Sun.COM //   default by gSOAP.
126*12720SWyllys.Ingersoll@Sun.COM // gSOAP 2.7.12:
127*12720SWyllys.Ingersoll@Sun.COM //   The function soap_ssl_init is defined in stdsoap2.cpp.  It replaces
128*12720SWyllys.Ingersoll@Sun.COM //   ssl_init and is exported by gSOAP.  gSOAP 2.7.13 also supports a new
129*12720SWyllys.Ingersoll@Sun.COM //   SOAP_SSL_SKIP_HOST_CHECK flag.
130*12720SWyllys.Ingersoll@Sun.COM #ifndef SOAP_SSL_SKIP_HOST_CHECK
131*12720SWyllys.Ingersoll@Sun.COM extern int ssl_init();
132*12720SWyllys.Ingersoll@Sun.COM #endif
133*12720SWyllys.Ingersoll@Sun.COM 
K_SetupSSL()134*12720SWyllys.Ingersoll@Sun.COM int K_SetupSSL()
135*12720SWyllys.Ingersoll@Sun.COM { int i;
136*12720SWyllys.Ingersoll@Sun.COM #ifdef K_SOLARIS_PLATFORM
137*12720SWyllys.Ingersoll@Sun.COM 	if (ssl_initialized)
138*12720SWyllys.Ingersoll@Sun.COM 		return 1;
139*12720SWyllys.Ingersoll@Sun.COM 	MUTEX_LOCK(init_ssl_mutex);
140*12720SWyllys.Ingersoll@Sun.COM #endif
141*12720SWyllys.Ingersoll@Sun.COM   mutex_buf = (MUTEX_TYPE*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE));
142*12720SWyllys.Ingersoll@Sun.COM   if (!mutex_buf) {
143*12720SWyllys.Ingersoll@Sun.COM #ifdef K_SOLARIS_PLATFORM
144*12720SWyllys.Ingersoll@Sun.COM 	MUTEX_UNLOCK(init_ssl_mutex);
145*12720SWyllys.Ingersoll@Sun.COM #endif
146*12720SWyllys.Ingersoll@Sun.COM     return 0;
147*12720SWyllys.Ingersoll@Sun.COM   }
148*12720SWyllys.Ingersoll@Sun.COM   for (i = 0; i < CRYPTO_num_locks(); i++)
149*12720SWyllys.Ingersoll@Sun.COM     MUTEX_SETUP(mutex_buf[i]);
150*12720SWyllys.Ingersoll@Sun.COM   if (CRYPTO_get_id_callback() == NULL)
151*12720SWyllys.Ingersoll@Sun.COM 	CRYPTO_set_id_callback(id_function);
152*12720SWyllys.Ingersoll@Sun.COM   if (CRYPTO_get_locking_callback() == NULL)
153*12720SWyllys.Ingersoll@Sun.COM 	CRYPTO_set_locking_callback(kms_locking_function);
154*12720SWyllys.Ingersoll@Sun.COM 
155*12720SWyllys.Ingersoll@Sun.COM   CRYPTO_set_dynlock_create_callback(dyn_create_function);
156*12720SWyllys.Ingersoll@Sun.COM   CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
157*12720SWyllys.Ingersoll@Sun.COM   CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
158*12720SWyllys.Ingersoll@Sun.COM 
159*12720SWyllys.Ingersoll@Sun.COM #ifndef WIN32
160*12720SWyllys.Ingersoll@Sun.COM   /* Need SIGPIPE handler on Unix/Linux systems to catch broken pipes: */
161*12720SWyllys.Ingersoll@Sun.COM   signal(SIGPIPE, sigpipe_handle);
162*12720SWyllys.Ingersoll@Sun.COM #endif
163*12720SWyllys.Ingersoll@Sun.COM #ifdef K_HPUX_PLATFORM
164*12720SWyllys.Ingersoll@Sun.COM //  signal(SIGBUS, sigpipe_handle);
165*12720SWyllys.Ingersoll@Sun.COM     allow_unaligned_data_access();
166*12720SWyllys.Ingersoll@Sun.COM #endif
167*12720SWyllys.Ingersoll@Sun.COM   OpenSSL_add_all_ciphers();
168*12720SWyllys.Ingersoll@Sun.COM   OpenSSL_add_all_digests();
169*12720SWyllys.Ingersoll@Sun.COM 
170*12720SWyllys.Ingersoll@Sun.COM   // call gSOAP's OpenSSL initialization, which initializes SSL algorithms and seeds RAND
171*12720SWyllys.Ingersoll@Sun.COM 
172*12720SWyllys.Ingersoll@Sun.COM   // gSOAP 2.7e:
173*12720SWyllys.Ingersoll@Sun.COM   //   The function ssl_init is defined in stdsoap2.cpp and is not exported by
174*12720SWyllys.Ingersoll@Sun.COM   //   default by gSOAP.
175*12720SWyllys.Ingersoll@Sun.COM   // gSOAP 2.7.13:
176*12720SWyllys.Ingersoll@Sun.COM   //   The function soap_ssl_init is defined in stdsoap2.cpp.  It replaces
177*12720SWyllys.Ingersoll@Sun.COM   //   ssl_init and is exported by gSOAP.  gSOAP 2.7.13 also supports a new
178*12720SWyllys.Ingersoll@Sun.COM   //   SOAP_SSL_SKIP_HOST_CHECK flag.
179*12720SWyllys.Ingersoll@Sun.COM #ifdef SOAP_SSL_SKIP_HOST_CHECK
180*12720SWyllys.Ingersoll@Sun.COM   soap_ssl_init();
181*12720SWyllys.Ingersoll@Sun.COM #else
182*12720SWyllys.Ingersoll@Sun.COM   ssl_init();
183*12720SWyllys.Ingersoll@Sun.COM #endif
184*12720SWyllys.Ingersoll@Sun.COM 
185*12720SWyllys.Ingersoll@Sun.COM #ifdef K_SOLARIS_PLATFORM
186*12720SWyllys.Ingersoll@Sun.COM 	ssl_initialized = 1;
187*12720SWyllys.Ingersoll@Sun.COM 	MUTEX_UNLOCK(init_ssl_mutex);
188*12720SWyllys.Ingersoll@Sun.COM #endif
189*12720SWyllys.Ingersoll@Sun.COM 
190*12720SWyllys.Ingersoll@Sun.COM   return 1;
191*12720SWyllys.Ingersoll@Sun.COM }
192*12720SWyllys.Ingersoll@Sun.COM 
K_CleanupSSL()193*12720SWyllys.Ingersoll@Sun.COM void K_CleanupSSL()
194*12720SWyllys.Ingersoll@Sun.COM { int i;
195*12720SWyllys.Ingersoll@Sun.COM   if (!mutex_buf)
196*12720SWyllys.Ingersoll@Sun.COM     return;
197*12720SWyllys.Ingersoll@Sun.COM #ifdef K_SOLARIS_PLATFORM
198*12720SWyllys.Ingersoll@Sun.COM   {
199*12720SWyllys.Ingersoll@Sun.COM 	unsigned long (*id_func)();
200*12720SWyllys.Ingersoll@Sun.COM 
201*12720SWyllys.Ingersoll@Sun.COM 	if ((id_func = CRYPTO_get_id_callback()) == id_function) {
202*12720SWyllys.Ingersoll@Sun.COM   		ENGINE_cleanup();
203*12720SWyllys.Ingersoll@Sun.COM 		/* EVP_cleanup(); */
204*12720SWyllys.Ingersoll@Sun.COM 		ERR_free_strings();
205*12720SWyllys.Ingersoll@Sun.COM 		CRYPTO_set_id_callback(NULL);
206*12720SWyllys.Ingersoll@Sun.COM 		CRYPTO_set_locking_callback(NULL);
207*12720SWyllys.Ingersoll@Sun.COM 	}
208*12720SWyllys.Ingersoll@Sun.COM   }
209*12720SWyllys.Ingersoll@Sun.COM #endif
210*12720SWyllys.Ingersoll@Sun.COM   CRYPTO_set_dynlock_create_callback(NULL);
211*12720SWyllys.Ingersoll@Sun.COM   CRYPTO_set_dynlock_lock_callback(NULL);
212*12720SWyllys.Ingersoll@Sun.COM   CRYPTO_set_dynlock_destroy_callback(NULL);
213*12720SWyllys.Ingersoll@Sun.COM   for (i = 0; i < CRYPTO_num_locks(); i++)
214*12720SWyllys.Ingersoll@Sun.COM     MUTEX_CLEANUP(mutex_buf[i]);
215*12720SWyllys.Ingersoll@Sun.COM   OPENSSL_free(mutex_buf);
216*12720SWyllys.Ingersoll@Sun.COM   mutex_buf = NULL;
217*12720SWyllys.Ingersoll@Sun.COM }
218*12720SWyllys.Ingersoll@Sun.COM 
219*12720SWyllys.Ingersoll@Sun.COM // TODO: what should 'struct soap' really be?
K_SetupCallbacks(struct soap * i_pSoap)220*12720SWyllys.Ingersoll@Sun.COM int K_SetupCallbacks( struct soap *i_pSoap )
221*12720SWyllys.Ingersoll@Sun.COM {
222*12720SWyllys.Ingersoll@Sun.COM     return 1;
223*12720SWyllys.Ingersoll@Sun.COM }
224