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