2 * gtlsbackend-openssl.c
4 * Copyright (C) 2015 NICE s.r.l.
6 * This file is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This file is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * In addition, when the library is used with OpenSSL, a special
20 * exception applies. Refer to the LICENSE_EXCEPTION file for details.
22 * Authors: Ignacio Casal Quinteiro
31 #include "openssl-include.h"
33 #include "gtlsbackend-openssl.h"
34 #include "gtlscertificate-openssl.h"
35 #include "gtlsserverconnection-openssl.h"
36 #include "gtlsclientconnection-openssl.h"
37 #include "gtlsfiledatabase-openssl.h"
39 typedef struct _GTlsBackendOpensslPrivate
42 GTlsDatabase *default_database;
43 } GTlsBackendOpensslPrivate;
45 static void g_tls_backend_openssl_interface_init (GTlsBackendInterface *iface);
47 G_DEFINE_DYNAMIC_TYPE_EXTENDED (GTlsBackendOpenssl, g_tls_backend_openssl, G_TYPE_OBJECT, 0,
48 G_ADD_PRIVATE_DYNAMIC (GTlsBackendOpenssl)
49 G_IMPLEMENT_INTERFACE_DYNAMIC (G_TYPE_TLS_BACKEND,
50 g_tls_backend_openssl_interface_init))
52 static GMutex *mutex_array = NULL;
54 struct CRYPTO_dynlock_value {
59 #pragma GCC diagnostic push
60 #pragma GCC diagnostic ignored "-Wunused-function"
66 return (unsigned long) g_thread_self ();
75 if (mode & CRYPTO_LOCK)
76 g_mutex_lock (&mutex_array[n]);
78 g_mutex_unlock (&mutex_array[n]);
81 static struct CRYPTO_dynlock_value *
82 dyn_create_cb (const char *file,
85 struct CRYPTO_dynlock_value *value = g_try_new (struct CRYPTO_dynlock_value, 1);
88 g_mutex_init (&value->mutex);
94 dyn_lock_cb (int mode,
95 struct CRYPTO_dynlock_value *l,
99 if (mode & CRYPTO_LOCK)
100 g_mutex_lock (&l->mutex);
102 g_mutex_unlock (&l->mutex);
106 dyn_destroy_cb (struct CRYPTO_dynlock_value *l,
110 g_mutex_clear (&l->mutex);
114 #if defined(__GNUC__)
115 #pragma GCC diagnostic pop
119 gtls_openssl_init (gpointer data)
124 /* Initialize openssl threading */
125 mutex_array = g_malloc_n (CRYPTO_num_locks(), sizeof (GMutex));
126 for (i = 0; i < CRYPTO_num_locks (); ++i)
127 g_mutex_init(&mutex_array[i]);
129 CRYPTO_set_id_callback (id_cb);
130 CRYPTO_set_locking_callback (locking_cb);
131 CRYPTO_set_dynlock_create_callback (dyn_create_cb);
132 CRYPTO_set_dynlock_lock_callback (dyn_lock_cb);
133 CRYPTO_set_dynlock_destroy_callback (dyn_destroy_cb);
136 SSL_load_error_strings ();
137 OpenSSL_add_all_algorithms ();
139 /* Leak the module to keep it from being unloaded. */
140 plugin = g_type_get_plugin (G_TYPE_TLS_BACKEND_OPENSSL);
142 g_type_plugin_use (plugin);
146 static GOnce openssl_inited = G_ONCE_INIT;
149 g_tls_backend_openssl_init (GTlsBackendOpenssl *backend)
151 GTlsBackendOpensslPrivate *priv;
153 priv = g_tls_backend_openssl_get_instance_private (backend);
155 /* Once we call gtls_openssl_init(), we can't allow the module to be
156 * unloaded (since if openssl gets unloaded but gcrypt doesn't, then
157 * gcrypt will have dangling pointers to openssl's mutex functions).
158 * So we initialize it from here rather than at class init time so
159 * that it doesn't happen unless the app is actually using TLS (as
160 * opposed to just calling g_io_modules_scan_all_in_directory()).
162 g_once (&openssl_inited, gtls_openssl_init, NULL);
164 g_mutex_init (&priv->mutex);
168 g_tls_backend_openssl_finalize (GObject *object)
172 GTlsBackendOpenssl *backend = G_TLS_BACKEND_OPENSSL (object);
173 GTlsBackendOpensslPrivate *priv;
175 priv = g_tls_backend_openssl_get_instance_private (backend);
177 g_clear_object (&priv->default_database);
178 g_mutex_clear (&priv->mutex);
180 CRYPTO_set_id_callback (NULL);
181 CRYPTO_set_locking_callback (NULL);
182 CRYPTO_set_dynlock_create_callback (NULL);
183 CRYPTO_set_dynlock_lock_callback (NULL);
184 CRYPTO_set_dynlock_destroy_callback (NULL);
185 for (i = 0; i < CRYPTO_num_locks(); ++i)
186 g_mutex_clear (&mutex_array[i]);
187 g_free (mutex_array);
189 G_OBJECT_CLASS (g_tls_backend_openssl_parent_class)->finalize (object);
192 static GTlsDatabase *
193 g_tls_backend_openssl_real_create_database (GTlsBackendOpenssl *self,
196 gchar *anchor_file = NULL;
197 GTlsDatabase *database;
200 if (g_getenv ("G_TLS_OPENSSL_HANDLE_CERT_RELOCATABLE") != NULL)
204 module_dir = g_win32_get_package_installation_directory_of_module (NULL);
205 anchor_file = g_build_filename (module_dir, "bin", "cert.pem", NULL);
210 if (anchor_file == NULL)
212 const gchar *openssl_cert_file;
214 openssl_cert_file = g_getenv (X509_get_default_cert_file_env ());
215 if (openssl_cert_file == NULL)
216 openssl_cert_file = X509_get_default_cert_file ();
218 anchor_file = g_strdup (openssl_cert_file);
221 database = g_tls_file_database_new (anchor_file, error);
222 g_free (anchor_file);
228 g_tls_backend_openssl_class_init (GTlsBackendOpensslClass *klass)
230 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
232 gobject_class->finalize = g_tls_backend_openssl_finalize;
234 klass->create_database = g_tls_backend_openssl_real_create_database;
238 g_tls_backend_openssl_class_finalize (GTlsBackendOpensslClass *backend_class)
243 g_tls_backend_openssl_get_default_database (GTlsBackend *backend)
245 GTlsBackendOpenssl *openssl_backend = G_TLS_BACKEND_OPENSSL (backend);
246 GTlsBackendOpensslPrivate *priv;
247 GTlsDatabase *result;
248 GError *error = NULL;
250 priv = g_tls_backend_openssl_get_instance_private (openssl_backend);
252 g_mutex_lock (&priv->mutex);
254 if (priv->default_database)
256 result = g_object_ref (priv->default_database);
260 g_assert (G_TLS_BACKEND_OPENSSL_GET_CLASS (openssl_backend)->create_database);
261 result = G_TLS_BACKEND_OPENSSL_GET_CLASS (openssl_backend)->create_database (openssl_backend, &error);
264 g_warning ("Couldn't load TLS file database: %s",
266 g_clear_error (&error);
271 priv->default_database = g_object_ref (result);
275 g_mutex_unlock (&priv->mutex);
281 g_tls_backend_openssl_interface_init (GTlsBackendInterface *iface)
283 iface->get_certificate_type = g_tls_certificate_openssl_get_type;
284 iface->get_client_connection_type = g_tls_client_connection_openssl_get_type;
285 iface->get_server_connection_type = g_tls_server_connection_openssl_get_type;
286 iface->get_file_database_type = g_tls_file_database_openssl_get_type;
287 iface->get_default_database = g_tls_backend_openssl_get_default_database;
291 g_tls_backend_openssl_register (GIOModule *module)
293 g_tls_backend_openssl_register_type (G_TYPE_MODULE (module));
295 g_io_extension_point_register (G_TLS_BACKEND_EXTENSION_POINT_NAME);
296 g_io_extension_point_implement (G_TLS_BACKEND_EXTENSION_POINT_NAME,
297 g_tls_backend_openssl_get_type(),