1 /* riemann/client/tls-gnutls2.c -- Riemann C client library
2  * Copyright (C) 2013-2017  Gergely Nagy <algernon@madhouse-project.org>
3  *
4  * This library is free software: you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation, either version 3 of
7  * the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT
19 #define GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT -1
20 #endif
21 
22 static int
_verify_certificate_callback(gnutls_session_t session)23 _verify_certificate_callback (gnutls_session_t session)
24 {
25   unsigned int status;
26   const gnutls_datum_t *cert_list;
27   unsigned int cert_list_size;
28   int ret;
29   gnutls_x509_crt_t cert;
30 
31   ret = gnutls_certificate_verify_peers2 (session, &status);
32   if (ret < 0)
33     return GNUTLS_E_CERTIFICATE_ERROR;
34 
35   if (status & GNUTLS_CERT_INVALID ||
36       status & GNUTLS_CERT_SIGNER_NOT_FOUND ||
37       status & GNUTLS_CERT_REVOKED ||
38       status & GNUTLS_CERT_EXPIRED ||
39       status & GNUTLS_CERT_NOT_ACTIVATED)
40     return GNUTLS_E_CERTIFICATE_ERROR;
41 
42   if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
43     return GNUTLS_E_CERTIFICATE_ERROR;
44 
45   if (gnutls_x509_crt_init (&cert) < 0)
46     return GNUTLS_E_CERTIFICATE_ERROR;
47 
48   cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
49   if (cert_list == NULL)
50     return GNUTLS_E_CERTIFICATE_ERROR;
51 
52   if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0)
53     return GNUTLS_E_CERTIFICATE_ERROR;
54 
55   gnutls_x509_crt_deinit (cert);
56 
57   return 0;
58 }
59 
60 static void
_tls_handshake_setup(riemann_client_t * client,riemann_client_tls_options_t * tls_options)61 _tls_handshake_setup (riemann_client_t *client,
62                       riemann_client_tls_options_t __attribute__((unused)) *tls_options)
63 {
64 #if __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 4
65 #pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
66 #endif
67   gnutls_transport_set_ptr (client->tls.session,
68                             (gnutls_transport_ptr_t) client->sock);
69 
70   if (tls_options->handshake_timeout != (unsigned int)GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT)
71     {
72       struct timeval timeout;
73 
74       timeout.tv_sec = tls_options->handshake_timeout / 1000;
75       timeout.tv_usec = (tls_options->handshake_timeout % 1000) * 1000;
76 
77       riemann_client_set_timeout (client, &timeout);
78     }
79 
80 #if __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 4
81 #pragma GCC diagnostic warning "-Wint-to-pointer-cast"
82 #endif
83 }
84 
85 __attribute__((constructor))
86 static void
riemann_tls_init()87 riemann_tls_init ()
88 {
89   gnutls_global_init ();
90 }
91 
92 __attribute__((destructor))
93 static void
riemann_tls_deinit()94 riemann_tls_deinit ()
95 {
96   gnutls_global_deinit ();
97 }
98