1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright © 2010 Red Hat, Inc
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
26 #include <gnutls/gnutls.h>
32 #include "gtlsbackend-gnutls.h"
33 #include "gtlscertificate-gnutls.h"
34 #include "gtlsclientconnection-gnutls.h"
35 #include "gtlsserverconnection-gnutls.h"
37 static void gtls_gnutls_init (void);
38 static void g_tls_backend_gnutls_interface_init (GTlsBackendInterface *iface);
40 G_DEFINE_DYNAMIC_TYPE_EXTENDED (GTlsBackendGnutls, g_tls_backend_gnutls, G_TYPE_OBJECT, 0,
41 G_IMPLEMENT_INTERFACE_DYNAMIC (G_TYPE_TLS_BACKEND,
42 g_tls_backend_gnutls_interface_init);
45 #if defined(GCRY_THREAD_OPTION_PTHREAD_IMPL) && !defined(G_OS_WIN32)
46 GCRY_THREAD_OPTION_PTHREAD_IMPL;
52 gtls_gcry_win32_mutex_init (void **priv)
55 CRITICAL_SECTION *lock = (CRITICAL_SECTION*)malloc (sizeof (CRITICAL_SECTION));
60 InitializeCriticalSection (lock);
67 gtls_gcry_win32_mutex_destroy (void **lock)
69 DeleteCriticalSection ((CRITICAL_SECTION*)*lock);
75 gtls_gcry_win32_mutex_lock (void **lock)
77 EnterCriticalSection ((CRITICAL_SECTION*)*lock);
82 gtls_gcry_win32_mutex_unlock (void **lock)
84 LeaveCriticalSection ((CRITICAL_SECTION*)*lock);
89 static struct gcry_thread_cbs gtls_gcry_threads_win32 = { \
90 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)), \
91 NULL, gtls_gcry_win32_mutex_init, gtls_gcry_win32_mutex_destroy, \
92 gtls_gcry_win32_mutex_lock, gtls_gcry_win32_mutex_unlock, \
93 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
98 gtls_gnutls_init (void)
100 #if defined(GCRY_THREAD_OPTION_PTHREAD_IMPL) && !defined(G_OS_WIN32)
101 gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
102 #elif defined(G_OS_WIN32)
103 gcry_control (GCRYCTL_SET_THREAD_CBS, >ls_gcry_threads_win32);
105 gnutls_global_init ();
109 g_tls_backend_gnutls_init (GTlsBackendGnutls *backend)
114 g_tls_backend_gnutls_class_init (GTlsBackendGnutlsClass *backend_class)
119 g_tls_backend_gnutls_class_finalize (GTlsBackendGnutlsClass *backend_class)
124 g_tls_backend_gnutls_interface_init (GTlsBackendInterface *iface)
126 iface->get_certificate_type = g_tls_certificate_gnutls_get_type;
127 iface->get_client_connection_type = g_tls_client_connection_gnutls_get_type;
128 iface->get_server_connection_type = g_tls_server_connection_gnutls_get_type;
131 #ifdef GTLS_SYSTEM_CA_FILE
132 /* Parsing the system CA list takes a noticeable amount of time.
133 * So we only do it once, and only when we actually need to see it.
136 get_ca_lists (gnutls_x509_crt_t **cas,
139 static gnutls_x509_crt_t *ca_list_gnutls;
140 static int ca_list_length;
141 static GList *ca_list;
143 if (g_once_init_enter ((volatile gsize *)&ca_list_gnutls))
145 GError *error = NULL;
146 gnutls_x509_crt_t *x509_crts;
150 ca_list = g_tls_certificate_list_new_from_file (GTLS_SYSTEM_CA_FILE, &error);
153 g_warning ("Failed to read system CA file %s: %s.",
154 GTLS_SYSTEM_CA_FILE, error->message);
155 g_error_free (error);
156 /* Note that this is not a security problem, since if
157 * G_TLS_VALIDATE_CA is set, then this just means validation
158 * will always fail, and if it isn't set, then it doesn't
159 * matter that we couldn't read the CAs.
163 ca_list_length = g_list_length (ca_list);
164 x509_crts = g_new (gnutls_x509_crt_t, ca_list_length);
165 for (c = ca_list, i = 0; c; c = c->next, i++)
166 x509_crts[i] = g_tls_certificate_gnutls_get_cert (c->data);
168 g_once_init_leave ((volatile gsize *)&ca_list_gnutls, GPOINTER_TO_SIZE (x509_crts));
172 *cas = ca_list_gnutls;
174 *num_cas = ca_list_length;
181 g_tls_backend_gnutls_get_system_ca_list_gtls (void)
183 #ifdef GTLS_SYSTEM_CA_FILE
184 return get_ca_lists (NULL, NULL);
191 g_tls_backend_gnutls_get_system_ca_list_gnutls (gnutls_x509_crt_t **cas,
194 #ifdef GTLS_SYSTEM_CA_FILE
195 get_ca_lists (cas, num_cas);
203 g_tls_backend_gnutls_register (GIOModule *module)
205 g_tls_backend_gnutls_register_type (G_TYPE_MODULE (module));
206 g_io_extension_point_implement (G_TLS_BACKEND_EXTENSION_POINT_NAME,
207 g_tls_backend_gnutls_get_type(),