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