2 * gtlsserverconnection-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
27 #include "gtlsserverconnection-openssl.h"
28 #include "gtlscertificate-openssl.h"
30 #include "openssl-include.h"
31 #include <glib/gi18n-lib.h>
33 #define DEFAULT_CIPHER_LIST "HIGH:!DSS:!aNULL@STRENGTH"
35 typedef struct _GTlsServerConnectionOpensslPrivate
37 GTlsAuthenticationMode authentication_mode;
41 } GTlsServerConnectionOpensslPrivate;
46 PROP_AUTHENTICATION_MODE
49 static void g_tls_server_connection_openssl_initable_interface_init (GInitableIface *iface);
51 static void g_tls_server_connection_openssl_server_connection_interface_init (GTlsServerConnectionInterface *iface);
53 static GInitableIface *g_tls_server_connection_openssl_parent_initable_iface;
55 G_DEFINE_TYPE_WITH_CODE (GTlsServerConnectionOpenssl, g_tls_server_connection_openssl, G_TYPE_TLS_CONNECTION_OPENSSL,
56 G_ADD_PRIVATE (GTlsServerConnectionOpenssl)
57 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
58 g_tls_server_connection_openssl_initable_interface_init)
59 G_IMPLEMENT_INTERFACE (G_TYPE_TLS_SERVER_CONNECTION,
60 g_tls_server_connection_openssl_server_connection_interface_init))
63 g_tls_server_connection_openssl_finalize (GObject *object)
65 GTlsServerConnectionOpenssl *openssl = G_TLS_SERVER_CONNECTION_OPENSSL (object);
66 GTlsServerConnectionOpensslPrivate *priv;
68 priv = g_tls_server_connection_openssl_get_instance_private (openssl);
71 SSL_CTX_free (priv->ssl_ctx);
72 SSL_SESSION_free (priv->session);
74 G_OBJECT_CLASS (g_tls_server_connection_openssl_parent_class)->finalize (object);
78 ssl_set_certificate (SSL *ssl,
79 GTlsCertificate *cert,
84 GTlsCertificate *issuer;
86 key = g_tls_certificate_openssl_get_key (G_TLS_CERTIFICATE_OPENSSL (cert));
90 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
91 _("Certificate has no private key"));
95 /* Note, order is important. If a certificate has been set previously,
96 * OpenSSL requires that the new certificate is set _before_ the new
97 * private key is set. */
98 x = g_tls_certificate_openssl_get_cert (G_TLS_CERTIFICATE_OPENSSL (cert));
99 if (SSL_use_certificate (ssl, x) <= 0)
101 g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
102 _("There is a problem with the certificate: %s"),
103 ERR_error_string (ERR_get_error (), NULL));
107 if (SSL_use_PrivateKey (ssl, key) <= 0)
109 g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
110 _("There is a problem with the certificate private key: %s"),
111 ERR_error_string (ERR_get_error (), NULL));
115 if (SSL_clear_chain_certs (ssl) == 0)
116 g_warning ("There was a problem clearing the chain certificates: %s",
117 ERR_error_string (ERR_get_error (), NULL));
119 /* Add all the issuers to create the full certificate chain */
120 for (issuer = g_tls_certificate_get_issuer (G_TLS_CERTIFICATE (cert));
122 issuer = g_tls_certificate_get_issuer (issuer))
126 /* Be careful here and duplicate the certificate since the context
127 * will take the ownership
129 issuer_x = X509_dup (g_tls_certificate_openssl_get_cert (G_TLS_CERTIFICATE_OPENSSL (issuer)));
130 if (SSL_add0_chain_cert (ssl, issuer_x) == 0)
131 g_warning ("There was a problem adding the chain certificate: %s",
132 ERR_error_string (ERR_get_error (), NULL));
139 g_tls_server_connection_openssl_get_property (GObject *object,
144 GTlsServerConnectionOpenssl *openssl = G_TLS_SERVER_CONNECTION_OPENSSL (object);
145 GTlsServerConnectionOpensslPrivate *priv;
147 priv = g_tls_server_connection_openssl_get_instance_private (openssl);
151 case PROP_AUTHENTICATION_MODE:
152 g_value_set_enum (value, priv->authentication_mode);
156 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
161 g_tls_server_connection_openssl_set_property (GObject *object,
166 GTlsServerConnectionOpenssl *openssl = G_TLS_SERVER_CONNECTION_OPENSSL (object);
167 GTlsServerConnectionOpensslPrivate *priv;
169 priv = g_tls_server_connection_openssl_get_instance_private (openssl);
173 case PROP_AUTHENTICATION_MODE:
174 priv->authentication_mode = g_value_get_enum (value);
178 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
183 verify_callback (int preverify_ok,
189 static GTlsConnectionBaseStatus
190 g_tls_server_connection_openssl_handshake (GTlsConnectionBase *tls,
191 GCancellable *cancellable,
194 GTlsServerConnectionOpenssl *openssl = G_TLS_SERVER_CONNECTION_OPENSSL (tls);
195 GTlsServerConnectionOpensslPrivate *priv;
198 priv = g_tls_server_connection_openssl_get_instance_private (openssl);
200 switch (priv->authentication_mode)
202 case G_TLS_AUTHENTICATION_REQUIRED:
203 req_mode = SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
204 case G_TLS_AUTHENTICATION_REQUESTED:
205 req_mode |= SSL_VERIFY_PEER;
207 case G_TLS_AUTHENTICATION_NONE:
209 req_mode = SSL_VERIFY_NONE;
213 SSL_set_verify (priv->ssl, req_mode, verify_callback);
214 /* FIXME: is this ok? */
215 SSL_set_verify_depth (priv->ssl, 0);
217 return G_TLS_CONNECTION_BASE_CLASS (g_tls_server_connection_openssl_parent_class)->
218 handshake (tls, cancellable, error);
222 g_tls_server_connection_openssl_get_ssl (GTlsConnectionOpenssl *connection)
224 GTlsServerConnectionOpenssl *server = G_TLS_SERVER_CONNECTION_OPENSSL (connection);
225 GTlsServerConnectionOpensslPrivate *priv;
227 priv = g_tls_server_connection_openssl_get_instance_private (server);
233 on_certificate_changed (GObject *object,
238 GTlsCertificate *cert;
240 ssl = g_tls_server_connection_openssl_get_ssl (G_TLS_CONNECTION_OPENSSL (object));
241 cert = g_tls_connection_get_certificate (G_TLS_CONNECTION (object));
244 ssl_set_certificate (ssl, cert, NULL);
248 g_tls_server_connection_openssl_class_init (GTlsServerConnectionOpensslClass *klass)
250 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
251 GTlsConnectionBaseClass *base_class = G_TLS_CONNECTION_BASE_CLASS (klass);
252 GTlsConnectionOpensslClass *connection_class = G_TLS_CONNECTION_OPENSSL_CLASS (klass);
254 gobject_class->finalize = g_tls_server_connection_openssl_finalize;
255 gobject_class->get_property = g_tls_server_connection_openssl_get_property;
256 gobject_class->set_property = g_tls_server_connection_openssl_set_property;
258 base_class->handshake = g_tls_server_connection_openssl_handshake;
260 connection_class->get_ssl = g_tls_server_connection_openssl_get_ssl;
262 g_object_class_override_property (gobject_class, PROP_AUTHENTICATION_MODE, "authentication-mode");
266 g_tls_server_connection_openssl_init (GTlsServerConnectionOpenssl *openssl)
271 g_tls_server_connection_openssl_server_connection_interface_init (GTlsServerConnectionInterface *iface)
275 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined (LIBRESSL_VERSION_NUMBER)
277 ssl_info_callback (const SSL *ssl,
281 if ((type & SSL_CB_HANDSHAKE_DONE) != 0)
283 /* Disable renegotiation (CVE-2009-3555) */
284 ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;
290 set_cipher_list (GTlsServerConnectionOpenssl *server,
293 GTlsServerConnectionOpensslPrivate *priv;
294 const gchar *cipher_list;
296 priv = g_tls_server_connection_openssl_get_instance_private (server);
298 cipher_list = g_getenv ("G_TLS_OPENSSL_CIPHER_LIST");
299 if (cipher_list == NULL)
300 cipher_list = DEFAULT_CIPHER_LIST;
302 if (!SSL_CTX_set_cipher_list (priv->ssl_ctx, cipher_list))
304 g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
305 _("Could not create TLS context: %s"),
306 ERR_error_string (ERR_get_error (), NULL));
313 #ifdef SSL_CTX_set1_sigalgs_list
315 set_signature_algorithm_list (GTlsServerConnectionOpenssl *server)
317 GTlsServerConnectionOpensslPrivate *priv;
318 const gchar *signature_algorithm_list;
320 priv = g_tls_server_connection_openssl_get_instance_private (server);
322 signature_algorithm_list = g_getenv ("G_TLS_OPENSSL_SIGNATURE_ALGORITHM_LIST");
323 if (signature_algorithm_list == NULL)
326 SSL_CTX_set1_sigalgs_list (priv->ssl_ctx, signature_algorithm_list);
330 #ifdef SSL_CTX_set1_curves_list
332 set_curve_list (GTlsServerConnectionOpenssl *server)
334 GTlsServerConnectionOpensslPrivate *priv;
335 const gchar *curve_list;
337 priv = g_tls_server_connection_openssl_get_instance_private (server);
339 curve_list = g_getenv ("G_TLS_OPENSSL_CURVE_LIST");
340 if (curve_list == NULL)
343 SSL_CTX_set1_curves_list (priv->ssl_ctx, curve_list);
348 g_tls_server_connection_openssl_initable_init (GInitable *initable,
349 GCancellable *cancellable,
352 GTlsServerConnectionOpenssl *server = G_TLS_SERVER_CONNECTION_OPENSSL (initable);
353 GTlsServerConnectionOpensslPrivate *priv;
354 GTlsCertificate *cert;
357 priv = g_tls_server_connection_openssl_get_instance_private (server);
359 priv->session = SSL_SESSION_new ();
361 priv->ssl_ctx = SSL_CTX_new (SSLv23_server_method ());
362 if (priv->ssl_ctx == NULL)
364 g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
365 _("Could not create TLS context: %s"),
366 ERR_error_string (ERR_get_error (), NULL));
370 if (!set_cipher_list (server, error))
373 /* Only TLS 1.2 or higher */
374 options = SSL_OP_NO_TICKET |
375 SSL_OP_NO_COMPRESSION |
376 SSL_OP_CIPHER_SERVER_PREFERENCE |
377 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
378 SSL_OP_SINGLE_ECDH_USE |
379 #ifdef SSL_OP_NO_TLSv1_1
386 #ifdef SSL_OP_NO_RENEGOTIATION
387 options |= SSL_OP_NO_RENEGOTIATION;
390 SSL_CTX_set_options (priv->ssl_ctx, options);
392 SSL_CTX_add_session (priv->ssl_ctx, priv->session);
394 #ifdef SSL_CTX_set1_sigalgs_list
395 set_signature_algorithm_list (server);
398 #ifdef SSL_CTX_set1_curves_list
399 set_curve_list (server);
402 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined (LIBRESSL_VERSION_NUMBER)
403 # ifdef SSL_CTX_set_ecdh_auto
404 SSL_CTX_set_ecdh_auto (priv->ssl_ctx, 1);
409 ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
412 SSL_CTX_set_tmp_ecdh (priv->ssl_ctx, ecdh);
418 SSL_CTX_set_info_callback (priv->ssl_ctx, ssl_info_callback);
421 priv->ssl = SSL_new (priv->ssl_ctx);
422 if (priv->ssl == NULL)
424 g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
425 _("Could not create TLS connection: %s"),
426 ERR_error_string (ERR_get_error (), NULL));
430 cert = g_tls_connection_get_certificate (G_TLS_CONNECTION (initable));
431 if (cert != NULL && !ssl_set_certificate (priv->ssl, cert, error))
434 SSL_set_accept_state (priv->ssl);
436 if (!g_tls_server_connection_openssl_parent_initable_iface->
437 init (initable, cancellable, error))
440 g_signal_connect (server, "notify::certificate", G_CALLBACK (on_certificate_changed), NULL);
446 g_tls_server_connection_openssl_initable_interface_init (GInitableIface *iface)
448 g_tls_server_connection_openssl_parent_initable_iface = g_type_interface_peek_parent (iface);
450 iface->init = g_tls_server_connection_openssl_initable_init;