Merge branch 'experimental_ocsp'
[exim.git] / src / src / tls-gnu.c
CommitLineData
059ec3d9
PH
1/*************************************************
2* Exim - an Internet mail transport agent *
3*************************************************/
4
17c76198 5/* Copyright (c) University of Cambridge 1995 - 2012 */
059ec3d9
PH
6/* See the file NOTICE for conditions of use and distribution. */
7
17c76198 8/* Copyright (c) Phil Pennock 2012 */
059ec3d9 9
17c76198
PP
10/* This file provides TLS/SSL support for Exim using the GnuTLS library,
11one of the available supported implementations. This file is #included into
12tls.c when USE_GNUTLS has been set.
059ec3d9 13
17c76198
PP
14The code herein is a revamp of GnuTLS integration using the current APIs; the
15original tls-gnu.c was based on a patch which was contributed by Nikos
16Mavroyanopoulos. The revamp is partially a rewrite, partially cut&paste as
17appropriate.
059ec3d9 18
17c76198
PP
19APIs current as of GnuTLS 2.12.18; note that the GnuTLS manual is for GnuTLS 3,
20which is not widely deployed by OS vendors. Will note issues below, which may
21assist in updating the code in the future. Another sources of hints is
22mod_gnutls for Apache (SNI callback registration and handling).
059ec3d9 23
17c76198
PP
24Keeping client and server variables more split than before and is currently
25the norm, in anticipation of TLS in ACL callouts.
059ec3d9 26
17c76198
PP
27I wanted to switch to gnutls_certificate_set_verify_function() so that
28certificate rejection could happen during handshake where it belongs, rather
29than being dropped afterwards, but that was introduced in 2.10.0 and Debian
30(6.0.5) is still on 2.8.6. So for now we have to stick with sub-par behaviour.
059ec3d9 31
17c76198
PP
32(I wasn't looking for libraries quite that old, when updating to get rid of
33compiler warnings of deprecated APIs. If it turns out that a lot of the rest
34require current GnuTLS, then we'll drop support for the ancient libraries).
35*/
b5aea5e1 36
17c76198
PP
37#include <gnutls/gnutls.h>
38/* needed for cert checks in verification and DN extraction: */
39#include <gnutls/x509.h>
40/* man-page is incorrect, gnutls_rnd() is not in gnutls.h: */
41#include <gnutls/crypto.h>
059ec3d9 42
17c76198 43/* GnuTLS 2 vs 3
059ec3d9 44
17c76198
PP
45GnuTLS 3 only:
46 gnutls_global_set_audit_log_function()
059ec3d9 47
17c76198
PP
48Changes:
49 gnutls_certificate_verify_peers2(): is new, drop the 2 for old version
50*/
059ec3d9 51
17c76198 52/* Local static variables for GnuTLS */
059ec3d9 53
17c76198 54/* Values for verify_requirement */
059ec3d9 55
17c76198 56enum peer_verify_requirement { VERIFY_NONE, VERIFY_OPTIONAL, VERIFY_REQUIRED };
059ec3d9 57
17c76198
PP
58/* This holds most state for server or client; with this, we can set up an
59outbound TLS-enabled connection in an ACL callout, while not stomping all
60over the TLS variables available for expansion.
059ec3d9 61
17c76198
PP
62Some of these correspond to variables in globals.c; those variables will
63be set to point to content in one of these instances, as appropriate for
64the stage of the process lifetime.
059ec3d9 65
17c76198
PP
66Not handled here: globals tls_active, tls_bits, tls_cipher, tls_peerdn,
67tls_certificate_verified, tls_channelbinding_b64, tls_sni.
68*/
059ec3d9 69
17c76198
PP
70typedef struct exim_gnutls_state {
71 gnutls_session_t session;
72 gnutls_certificate_credentials_t x509_cred;
73 gnutls_priority_t priority_cache;
74 enum peer_verify_requirement verify_requirement;
75 int fd_in;
76 int fd_out;
77 BOOL peer_cert_verified;
78 BOOL trigger_sni_changes;
79 const struct host_item *host;
80 uschar *peerdn;
81 uschar *received_sni;
82
83 const uschar *tls_certificate;
84 const uschar *tls_privatekey;
85 const uschar *tls_sni; /* client send only, not received */
86 const uschar *tls_verify_certificates;
87 const uschar *tls_crl;
88 const uschar *tls_require_ciphers;
89 uschar *exp_tls_certificate;
90 uschar *exp_tls_privatekey;
91 uschar *exp_tls_sni;
92 uschar *exp_tls_verify_certificates;
93 uschar *exp_tls_crl;
94 uschar *exp_tls_require_ciphers;
95
96 uschar *xfer_buffer;
97 int xfer_buffer_lwm;
98 int xfer_buffer_hwm;
99 int xfer_eof;
100 int xfer_error;
101
102 uschar cipherbuf[256];
103} exim_gnutls_state_st;
104
105static const exim_gnutls_state_st exim_gnutls_state_init = {
106 NULL, NULL, NULL, VERIFY_NONE, -1, -1, FALSE, FALSE,
107 NULL, NULL, NULL,
108 NULL, NULL, NULL, NULL, NULL, NULL,
109 NULL, NULL, NULL, NULL, NULL, NULL,
110 NULL, 0, 0, 0, 0,
111 ""
112};
83da1223 113
17c76198
PP
114/* Not only do we have our own APIs which don't pass around state, assuming
115it's held in globals, GnuTLS doesn't appear to let us register callback data
116for callbacks, or as part of the session, so we have to keep a "this is the
117context we're currently dealing with" pointer and rely upon being
118single-threaded to keep from processing data on an inbound TLS connection while
119talking to another TLS connection for an outbound check. This does mean that
120there's no way for heart-beats to be responded to, for the duration of the
121second connection. */
059ec3d9 122
17c76198
PP
123static exim_gnutls_state_st state_server, state_client;
124static exim_gnutls_state_st *current_global_tls_state;
059ec3d9 125
17c76198
PP
126/* dh_params are initialised once within the lifetime of a process using TLS;
127if we used TLS in a long-lived daemon, we'd have to reconsider this. But we
128don't want to repeat this. */
83da1223 129
17c76198 130static gnutls_dh_params_t dh_server_params = NULL;
059ec3d9 131
17c76198 132/* No idea how this value was chosen; preserving it. Default is 3600. */
059ec3d9 133
17c76198 134static const int ssl_session_timeout = 200;
059ec3d9 135
17c76198 136static const char * const exim_default_gnutls_priority = "NORMAL";
83da1223 137
17c76198 138/* Guard library core initialisation */
83da1223 139
17c76198 140static BOOL exim_gnutls_base_init_done = FALSE;
059ec3d9 141
059ec3d9 142
17c76198
PP
143/* ------------------------------------------------------------------------ */
144/* Callback declarations */
059ec3d9 145
17c76198
PP
146static void exim_gnutls_logger_cb(int level, const char *message);
147static int exim_sni_handling_cb(gnutls_session_t session);
83da1223 148
17c76198
PP
149/* ------------------------------------------------------------------------ */
150/* macros */
83da1223 151
17c76198 152#define MAX_HOST_LEN 255
83da1223 153
17c76198
PP
154/* Set this to control gnutls_global_set_log_level(); values 0 to 9 will setup
155the library logging; a value less than 0 disables the calls to set up logging
156callbacks. */
157#define EXIM_GNUTLS_LIBRARY_LOG_LEVEL -1
83da1223 158
17c76198 159#define EXIM_CLIENT_DH_MIN_BITS 1024
83da1223 160
17c76198
PP
161#define exim_gnutls_err_check(Label) do { \
162 if (rc != GNUTLS_E_SUCCESS) { return tls_error((Label), gnutls_strerror(rc), host); } } while (0)
059ec3d9 163
17c76198
PP
164#define exim_gnutls_err_debugreturn0(Label) do { \
165 if (rc != GNUTLS_E_SUCCESS) { \
166 DEBUG(D_tls) debug_printf("TLS failure: %s: %s", (Label), gnutls_strerror(rc)); \
167 return 0; } } while (0)
059ec3d9 168
17c76198 169#define expand_check_tlsvar(Varname) expand_check(state->Varname, US #Varname, &state->exp_##Varname)
83da1223 170
17c76198
PP
171#if GNUTLS_VERSION_NUMBER >= 0x020c00
172#define HAVE_GNUTLS_SESSION_CHANNEL_BINDING
173#endif
83da1223 174
17c76198
PP
175/* ------------------------------------------------------------------------ */
176/* Static functions */
059ec3d9
PH
177
178/*************************************************
179* Handle TLS error *
180*************************************************/
181
182/* Called from lots of places when errors occur before actually starting to do
183the TLS handshake, that is, while the session is still in clear. Always returns
184DEFER for a server and FAIL for a client so that most calls can use "return
185tls_error(...)" to do this processing and then give an appropriate return. A
186single function is used for both server and client, because it is called from
187some shared functions.
188
189Argument:
190 prefix text to include in the logged error
7199e1ee
TF
191 msg additional error string (may be NULL)
192 usually obtained from gnutls_strerror()
17c76198
PP
193 host NULL if setting up a server;
194 the connected host if setting up a client
059ec3d9
PH
195
196Returns: OK/DEFER/FAIL
197*/
198
199static int
17c76198 200tls_error(const uschar *prefix, const char *msg, const host_item *host)
059ec3d9 201{
17c76198
PP
202if (host)
203 {
204 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s)%s%s",
205 host->name, host->address, prefix, msg ? ": " : "", msg ? msg : "");
206 return FAIL;
207 }
208else
059ec3d9 209 {
7199e1ee 210 uschar *conn_info = smtp_get_connection_info();
17c76198 211 if (Ustrncmp(conn_info, US"SMTP ", 5) == 0)
7199e1ee
TF
212 conn_info += 5;
213 log_write(0, LOG_MAIN, "TLS error on %s (%s)%s%s",
17c76198 214 conn_info, prefix, msg ? ": " : "", msg ? msg : "");
059ec3d9
PH
215 return DEFER;
216 }
059ec3d9
PH
217}
218
219
220
17c76198 221
059ec3d9 222/*************************************************
17c76198 223* Deal with logging errors during I/O *
059ec3d9
PH
224*************************************************/
225
17c76198 226/* We have to get the identity of the peer from saved data.
059ec3d9 227
17c76198
PP
228Argument:
229 state the current GnuTLS exim state container
230 rc the GnuTLS error code, or 0 if it's a local error
231 when text identifying read or write
232 text local error text when ec is 0
059ec3d9 233
17c76198 234Returns: nothing
059ec3d9
PH
235*/
236
17c76198
PP
237static void
238record_io_error(exim_gnutls_state_st *state, int rc, uschar *when, uschar *text)
059ec3d9 239{
17c76198 240const char *msg;
059ec3d9 241
17c76198
PP
242if (rc == GNUTLS_E_FATAL_ALERT_RECEIVED)
243 msg = CS string_sprintf("%s: %s", US gnutls_strerror(rc),
244 US gnutls_alert_get_name(gnutls_alert_get(state->session)));
245else
246 msg = gnutls_strerror(rc);
059ec3d9 247
17c76198
PP
248tls_error(when, msg, state->host);
249}
059ec3d9 250
059ec3d9 251
059ec3d9 252
059ec3d9 253
17c76198
PP
254/*************************************************
255* Set various Exim expansion vars *
256*************************************************/
059ec3d9 257
17c76198
PP
258/* We set various Exim global variables from the state, once a session has
259been established. With TLS callouts, may need to change this to stack
260variables, or just re-call it with the server state after client callout
261has finished.
059ec3d9 262
17c76198
PP
263Make sure anything set here is inset in tls_getc().
264
265Sets:
266 tls_active fd
267 tls_bits strength indicator
268 tls_certificate_verified bool indicator
269 tls_channelbinding_b64 for some SASL mechanisms
270 tls_cipher a string
271 tls_peerdn a string
272 tls_sni a (UTF-8) string
273Also:
274 current_global_tls_state for API limitations
275
276Argument:
277 state the relevant exim_gnutls_state_st *
278*/
279
280static void
281extract_exim_vars_from_tls_state(exim_gnutls_state_st *state)
282{
283gnutls_protocol_t protocol;
284gnutls_cipher_algorithm_t cipher;
285gnutls_kx_algorithm_t kx;
286gnutls_mac_algorithm_t mac;
287uschar *p;
288#ifdef HAVE_GNUTLS_SESSION_CHANNEL_BINDING
289int old_pool;
290int rc;
291gnutls_datum_t channel;
292#endif
293
294current_global_tls_state = state;
295
296tls_active = state->fd_out;
297
298cipher = gnutls_cipher_get(state->session);
299/* returns size in "bytes" */
300tls_bits = gnutls_cipher_get_key_size(cipher) * 8;
301
302if (!*state->cipherbuf)
059ec3d9 303 {
17c76198
PP
304 protocol = gnutls_protocol_get_version(state->session);
305 mac = gnutls_mac_get(state->session);
306 kx = gnutls_kx_get(state->session);
307
308 string_format(state->cipherbuf, sizeof(state->cipherbuf),
309 "%s:%s:%u",
310 gnutls_protocol_get_name(protocol),
311 gnutls_cipher_suite_get_name(kx, cipher, mac),
312 tls_bits);
313
314 /* I don't see a way that spaces could occur, in the current GnuTLS
315 code base, but it was a concern in the old code and perhaps older GnuTLS
316 releases did return "TLS 1.0"; play it safe, just in case. */
317 for (p = state->cipherbuf; *p != '\0'; ++p)
318 if (isspace(*p))
319 *p = '-';
059ec3d9 320 }
17c76198
PP
321tls_cipher = state->cipherbuf;
322
323DEBUG(D_tls) debug_printf("cipher: %s\n", tls_cipher);
324
325tls_certificate_verified = state->peer_cert_verified;
059ec3d9 326
17c76198
PP
327/* note that tls_channelbinding_b64 is not saved to the spool file, since it's
328only available for use for authenticators while this TLS session is running. */
329
330tls_channelbinding_b64 = NULL;
331#ifdef HAVE_GNUTLS_SESSION_CHANNEL_BINDING
332channel.data = NULL;
333channel.size = 0;
334rc = gnutls_session_channel_binding(state->session, GNUTLS_CB_TLS_UNIQUE, &channel);
335if (rc) {
336 DEBUG(D_tls) debug_printf("Channel binding error: %s\n", gnutls_strerror(rc));
337} else {
338 old_pool = store_pool;
339 store_pool = POOL_PERM;
340 tls_channelbinding_b64 = auth_b64encode(channel.data, (int)channel.size);
341 store_pool = old_pool;
342 DEBUG(D_tls) debug_printf("Have channel bindings cached for possible auth usage.\n");
343}
344#endif
345
346tls_peerdn = state->peerdn;
347
348tls_sni = state->received_sni;
059ec3d9
PH
349}
350
351
352
17c76198 353
059ec3d9 354/*************************************************
575643cd 355* Setup up DH parameters *
059ec3d9
PH
356*************************************************/
357
575643cd 358/* Generating the D-H parameters may take a long time. They only need to
059ec3d9
PH
359be re-generated every so often, depending on security policy. What we do is to
360keep these parameters in a file in the spool directory. If the file does not
361exist, we generate them. This means that it is easy to cause a regeneration.
362
363The new file is written as a temporary file and renamed, so that an incomplete
364file is never present. If two processes both compute some new parameters, you
365waste a bit of effort, but it doesn't seem worth messing around with locking to
366prevent this.
367
368Argument:
369 host NULL for server, server for client (for error handling)
370
371Returns: OK/DEFER/FAIL
372*/
373
374static int
17c76198 375init_server_dh(void)
059ec3d9 376{
17c76198
PP
377int fd, rc;
378unsigned int dh_bits;
b5aea5e1 379gnutls_datum m;
17c76198
PP
380uschar filename[PATH_MAX];
381size_t sz;
382host_item *host = NULL; /* dummy for macros */
383const char * const dh_param_fn_ext = "normal"; /* change as dh_bits changes */
059ec3d9 384
17c76198 385DEBUG(D_tls) debug_printf("Initialising GnuTLS server params.\n");
059ec3d9 386
17c76198
PP
387rc = gnutls_dh_params_init(&dh_server_params);
388exim_gnutls_err_check(US"gnutls_dh_params_init");
059ec3d9 389
17c76198
PP
390/* If you change this, also change dh_param_fn_ext so that we can use a
391different filename and ensure we have sufficient bits. */
392dh_bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_NORMAL);
393if (!dh_bits)
394 return tls_error(US"gnutls_sec_param_to_pk_bits() failed", NULL, NULL);
059ec3d9 395
17c76198
PP
396if (!string_format(filename, sizeof(filename),
397 "%s/gnutls-params-%s", spool_directory, dh_param_fn_ext))
398 return tls_error(US"overlong filename", NULL, NULL);
059ec3d9 399
b5aea5e1 400/* Open the cache file for reading and if successful, read it and set up the
575643cd 401parameters. */
059ec3d9
PH
402
403fd = Uopen(filename, O_RDONLY, 0);
b5aea5e1 404if (fd >= 0)
059ec3d9 405 {
b5aea5e1 406 struct stat statbuf;
17c76198
PP
407 FILE *fp;
408 int saved_errno;
409
410 if (fstat(fd, &statbuf) < 0) /* EIO */
411 {
412 saved_errno = errno;
413 (void)close(fd);
414 return tls_error(US"TLS cache stat failed", strerror(saved_errno), NULL);
415 }
416 if (!S_ISREG(statbuf.st_mode))
b5aea5e1
PH
417 {
418 (void)close(fd);
17c76198
PP
419 return tls_error(US"TLS cache not a file", NULL, NULL);
420 }
421 fp = fdopen(fd, "rb");
422 if (!fp)
423 {
424 saved_errno = errno;
425 (void)close(fd);
426 return tls_error(US"fdopen(TLS cache stat fd) failed",
427 strerror(saved_errno), NULL);
b5aea5e1 428 }
059ec3d9 429
b5aea5e1
PH
430 m.size = statbuf.st_size;
431 m.data = malloc(m.size);
432 if (m.data == NULL)
17c76198
PP
433 {
434 fclose(fp);
435 return tls_error(US"malloc failed", strerror(errno), NULL);
436 }
437 sz = fread(m.data, m.size, 1, fp);
438 if (!sz)
439 {
440 saved_errno = errno;
441 fclose(fp);
442 free(m.data);
443 return tls_error(US"fread failed", strerror(saved_errno), NULL);
444 }
445 fclose(fp);
b5aea5e1 446
17c76198 447 rc = gnutls_dh_params_import_pkcs3(dh_server_params, &m, GNUTLS_X509_FMT_PEM);
b5aea5e1 448 free(m.data);
17c76198
PP
449 exim_gnutls_err_check(US"gnutls_dh_params_import_pkcs3");
450 DEBUG(D_tls) debug_printf("read D-H parameters from file \"%s\"\n", filename);
b5aea5e1
PH
451 }
452
453/* If the file does not exist, fall through to compute new data and cache it.
454If there was any other opening error, it is serious. */
455
182ad5cf
PH
456else if (errno == ENOENT)
457 {
17c76198 458 rc = -1;
182ad5cf 459 DEBUG(D_tls)
17c76198 460 debug_printf("D-H parameter cache file \"%s\" does not exist\n", filename);
182ad5cf
PH
461 }
462else
17c76198
PP
463 return tls_error(string_open_failed(errno, "\"%s\" for reading", filename),
464 NULL, NULL);
b5aea5e1
PH
465
466/* If ret < 0, either the cache file does not exist, or the data it contains
467is not useful. One particular case of this is when upgrading from an older
468release of Exim in which the data was stored in a different format. We don't
469try to be clever and support both formats; we just regenerate new data in this
470case. */
471
17c76198 472if (rc < 0)
b5aea5e1 473 {
17c76198 474 uschar *temp_fn;
059ec3d9 475
17c76198
PP
476 if ((PATH_MAX - Ustrlen(filename)) < 10)
477 return tls_error(US"Filename too long to generate replacement",
478 CS filename, NULL);
059ec3d9 479
17c76198
PP
480 temp_fn = string_copy(US "%s.XXXXXXX");
481 fd = mkstemp(CS temp_fn); /* modifies temp_fn */
059ec3d9 482 if (fd < 0)
17c76198 483 return tls_error(US"Unable to open temp file", strerror(errno), NULL);
059ec3d9
PH
484 (void)fchown(fd, exim_uid, exim_gid); /* Probably not necessary */
485
17c76198
PP
486 DEBUG(D_tls) debug_printf("generating %d bits Diffie-Hellman key ...\n", dh_bits);
487 rc = gnutls_dh_params_generate2(dh_server_params, dh_bits);
488 exim_gnutls_err_check(US"gnutls_dh_params_generate2");
489
490 /* gnutls_dh_params_export_pkcs3() will tell us the exact size, every time,
491 and I confirmed that a NULL call to get the size first is how the GnuTLS
492 sample apps handle this. */
493
494 sz = 0;
495 m.data = NULL;
496 rc = gnutls_dh_params_export_pkcs3(dh_server_params, GNUTLS_X509_FMT_PEM,
497 m.data, &sz);
498 if (rc != GNUTLS_E_SHORT_MEMORY_BUFFER)
499 exim_gnutls_err_check(US"gnutls_dh_params_export_pkcs3(NULL) sizing");
500 m.size = sz;
b5aea5e1
PH
501 m.data = malloc(m.size);
502 if (m.data == NULL)
17c76198
PP
503 return tls_error(US"memory allocation failed", strerror(errno), NULL);
504 rc = gnutls_dh_params_export_pkcs3(dh_server_params, GNUTLS_X509_FMT_PEM,
505 m.data, &sz);
506 if (rc != GNUTLS_E_SUCCESS)
507 {
508 free(m.data);
509 exim_gnutls_err_check(US"gnutls_dh_params_export_pkcs3() real");
510 }
059ec3d9 511
17c76198
PP
512 sz = write_to_fd_buf(fd, m.data, (size_t) m.size);
513 if (sz != m.size)
514 {
515 free(m.data);
516 return tls_error(US"TLS cache write D-H params failed",
517 strerror(errno), NULL);
518 }
b5aea5e1 519 free(m.data);
17c76198
PP
520 sz = write_to_fd_buf(fd, US"\n", 1);
521 if (sz != 1)
522 return tls_error(US"TLS cache write D-H params final newline failed",
523 strerror(errno), NULL);
524
525 rc = close(fd);
526 if (rc)
527 return tls_error(US"TLS cache write close() failed",
528 strerror(errno), NULL);
059ec3d9 529
17c76198
PP
530 if (Urename(temp_fn, filename) < 0)
531 return tls_error(string_sprintf("failed to rename \"%s\" as \"%s\"",
532 temp_fn, filename), strerror(errno), NULL);
059ec3d9 533
17c76198 534 DEBUG(D_tls) debug_printf("wrote D-H parameters to file \"%s\"\n", filename);
059ec3d9
PH
535 }
536
17c76198 537DEBUG(D_tls) debug_printf("initialized server D-H parameters\n");
059ec3d9
PH
538return OK;
539}
540
541
542
543
544/*************************************************
17c76198 545* Variables re-expanded post-SNI *
059ec3d9
PH
546*************************************************/
547
17c76198
PP
548/* Called from both server and client code, via tls_init(), and also from
549the SNI callback after receiving an SNI, if tls_certificate includes "tls_sni".
550
551We can tell the two apart by state->received_sni being non-NULL in callback.
552
553The callback should not call us unless state->trigger_sni_changes is true,
554which we are responsible for setting on the first pass through.
059ec3d9
PH
555
556Arguments:
17c76198 557 state exim_gnutls_state_st *
059ec3d9
PH
558
559Returns: OK/DEFER/FAIL
560*/
561
562static int
17c76198 563tls_expand_session_files(exim_gnutls_state_st *state)
059ec3d9
PH
564{
565int rc;
17c76198
PP
566const host_item *host = state->host; /* macro should be reconsidered? */
567uschar *saved_tls_certificate = NULL;
568uschar *saved_tls_privatekey = NULL;
569uschar *saved_tls_verify_certificates = NULL;
570uschar *saved_tls_crl = NULL;
571int cert_count;
572
573/* We check for tls_sni *before* expansion. */
574if (!state->host)
575 {
576 if (!state->received_sni)
577 {
578 if (Ustrstr(state->tls_certificate, US"tls_sni"))
579 {
580 DEBUG(D_tls) debug_printf("We will re-expand TLS session files if we receive SNI.\n");
581 state->trigger_sni_changes = TRUE;
582 }
583 }
584 else
585 {
586 saved_tls_certificate = state->exp_tls_certificate;
587 saved_tls_privatekey = state->exp_tls_privatekey;
588 saved_tls_verify_certificates = state->exp_tls_verify_certificates;
589 saved_tls_crl = state->exp_tls_crl;
590 }
591 }
059ec3d9 592
17c76198
PP
593/* remember: expand_check_tlsvar() is expand_check() but fiddling with
594state members, assuming consistent naming; and expand_check() returns
595false if expansion failed, unless expansion was forced to fail. */
059ec3d9 596
17c76198
PP
597/* check if we at least have a certificate, before doing expensive
598D-H generation. */
059ec3d9 599
17c76198
PP
600if (!expand_check_tlsvar(tls_certificate))
601 return DEFER;
059ec3d9 602
17c76198 603/* certificate is mandatory in server, optional in client */
059ec3d9 604
17c76198
PP
605if ((state->exp_tls_certificate == NULL) ||
606 (*state->exp_tls_certificate == '\0'))
607 {
608 if (state->host == NULL)
609 return tls_error(US"no TLS server certificate is specified", NULL, NULL);
610 else
611 DEBUG(D_tls) debug_printf("TLS: no client certificate specified; okay\n");
612 }
059ec3d9 613
17c76198 614if (state->tls_privatekey && !expand_check_tlsvar(tls_privatekey))
059ec3d9
PH
615 return DEFER;
616
17c76198
PP
617/* tls_privatekey is optional, defaulting to same file as certificate */
618
619if (state->tls_privatekey == NULL || *state->tls_privatekey == '\0')
059ec3d9 620 {
17c76198
PP
621 state->tls_privatekey = state->tls_certificate;
622 state->exp_tls_privatekey = state->exp_tls_certificate;
059ec3d9 623 }
c91535f3 624
059ec3d9 625
17c76198 626if (state->exp_tls_certificate && *state->exp_tls_certificate)
059ec3d9 627 {
17c76198 628 BOOL setit = TRUE;
059ec3d9 629 DEBUG(D_tls) debug_printf("certificate file = %s\nkey file = %s\n",
17c76198
PP
630 state->exp_tls_certificate, state->exp_tls_privatekey);
631
632 if (state->received_sni)
de365ded 633 {
17c76198
PP
634 if ((Ustrcmp(state->exp_tls_certificate, saved_tls_certificate) == 0) &&
635 (Ustrcmp(state->exp_tls_privatekey, saved_tls_privatekey) == 0))
636 {
637 DEBUG(D_tls) debug_printf("cert and key unchanged with SNI.\n");
638 setit = FALSE;
639 }
640 else
641 {
642 DEBUG(D_tls) debug_printf("SNI changed cert/key pair.\n");
643 }
8e669ac1 644 }
059ec3d9 645
17c76198
PP
646 if (setit)
647 {
648 rc = gnutls_certificate_set_x509_key_file(state->x509_cred,
649 CS state->exp_tls_certificate, CS state->exp_tls_privatekey,
650 GNUTLS_X509_FMT_PEM);
651 exim_gnutls_err_check(
652 string_sprintf("cert/key setup: cert=%s key=%s",
653 state->exp_tls_certificate, state->exp_tls_privatekey));
654 }
059ec3d9
PH
655 }
656
657/* Set the trusted CAs file if one is provided, and then add the CRL if one is
658provided. Experiment shows that, if the certificate file is empty, an unhelpful
659error message is provided. However, if we just refrain from setting anything up
660in that case, certificate verification fails, which seems to be the correct
661behaviour. */
662
17c76198 663if (state->tls_verify_certificates && *state->tls_verify_certificates)
059ec3d9
PH
664 {
665 struct stat statbuf;
17c76198 666 BOOL setit_vc = TRUE, setit_crl = TRUE;
059ec3d9 667
17c76198 668 if (!expand_check_tlsvar(tls_verify_certificates))
059ec3d9 669 return DEFER;
17c76198
PP
670 if (state->tls_crl && *state->tls_crl)
671 if (!expand_check_tlsvar(tls_crl))
672 return DEFER;
059ec3d9 673
17c76198
PP
674 if (state->received_sni)
675 {
676 if (Ustrcmp(state->exp_tls_verify_certificates, saved_tls_verify_certificates) == 0)
677 setit_vc = FALSE;
678 if (Ustrcmp(state->exp_tls_crl, saved_tls_crl) == 0)
679 setit_crl = FALSE;
680 }
681
682 /* nb: early exit; change if add more expansions to this function */
683 if (!(setit_vc || setit_crl))
684 return OK;
685
686 if (Ustat(state->exp_tls_verify_certificates, &statbuf) < 0)
059ec3d9
PH
687 {
688 log_write(0, LOG_MAIN|LOG_PANIC, "could not stat %s "
17c76198
PP
689 "(tls_verify_certificates): %s", state->exp_tls_verify_certificates,
690 strerror(errno));
691 return DEFER;
692 }
693
694 if (!S_ISREG(statbuf.st_mode))
695 {
696 DEBUG(D_tls)
697 debug_printf("verify certificates path is not a file: \"%s\"\n%s\n",
698 state->exp_tls_verify_certificates,
699 S_ISDIR(statbuf.st_mode)
700 ? " it's a directory, that's OpenSSL, this is GnuTLS"
701 : " (not a directory either)");
702 log_write(0, LOG_MAIN|LOG_PANIC,
703 "tls_verify_certificates \"%s\" is not a file",
704 state->exp_tls_verify_certificates);
059ec3d9
PH
705 return DEFER;
706 }
707
b1c749bb 708 DEBUG(D_tls) debug_printf("verify certificates = %s size=" OFF_T_FMT "\n",
17c76198 709 state->exp_tls_verify_certificates, statbuf.st_size);
059ec3d9 710
17c76198
PP
711 /* If the CA cert file is empty, there's no point in loading the CRL file,
712 as we aren't verifying, so checking for revocation is pointless. */
059ec3d9
PH
713
714 if (statbuf.st_size > 0)
715 {
17c76198 716 if (setit_vc)
059ec3d9 717 {
17c76198
PP
718 cert_count = gnutls_certificate_set_x509_trust_file(state->x509_cred,
719 CS state->exp_tls_verify_certificates, GNUTLS_X509_FMT_PEM);
720 if (cert_count < 0)
721 {
722 rc = cert_count;
723 exim_gnutls_err_check(US"gnutls_certificate_set_x509_trust_file");
724 }
725 DEBUG(D_tls) debug_printf("Added %d certificate authorities.\n", cert_count);
059ec3d9 726 }
059ec3d9 727
17c76198
PP
728 if (setit_crl && state->tls_crl && *state->tls_crl)
729 {
730 if (state->exp_tls_crl && *state->exp_tls_crl)
731 {
732 DEBUG(D_tls) debug_printf("loading CRL file = %s\n", state->exp_tls_crl);
733 rc = gnutls_certificate_set_x509_crl_file(state->x509_cred,
734 CS state->exp_tls_crl, GNUTLS_X509_FMT_PEM);
735 exim_gnutls_err_check(US"gnutls_certificate_set_x509_crl_file");
736 }
737 }
738 } /* statbuf.st_size */
739 } /* tls_verify_certificates */
059ec3d9 740
059ec3d9 741return OK;
17c76198 742/* also above, during verify_certificates/crl, during SNI, if unchanged */
059ec3d9
PH
743}
744
745
746
747
748/*************************************************
17c76198 749* Initialize for GnuTLS *
059ec3d9
PH
750*************************************************/
751
17c76198
PP
752/* Called from both server and client code. In the case of a server, errors
753before actual TLS negotiation return DEFER.
059ec3d9
PH
754
755Arguments:
17c76198
PP
756 host connected host, if client; NULL if server
757 certificate certificate file
758 privatekey private key file
759 sni TLS SNI to send, sometimes when client; else NULL
760 cas CA certs file
761 crl CRL file
762 require_ciphers tls_require_ciphers setting
059ec3d9 763
17c76198 764Returns: OK/DEFER/FAIL
059ec3d9
PH
765*/
766
17c76198
PP
767static int
768tls_init(
769 const host_item *host,
770 const uschar *certificate,
771 const uschar *privatekey,
772 const uschar *sni,
773 const uschar *cas,
774 const uschar *crl,
775 const uschar *require_ciphers,
776 exim_gnutls_state_st **caller_state)
059ec3d9 777{
17c76198
PP
778exim_gnutls_state_st *state;
779int rc;
780size_t sz;
781const char *errpos;
782uschar *p;
783BOOL want_default_priorities;
784
785if (!exim_gnutls_base_init_done)
059ec3d9 786 {
17c76198
PP
787 DEBUG(D_tls) debug_printf("GnuTLS global init required.\n");
788
789 rc = gnutls_global_init();
790 exim_gnutls_err_check(US"gnutls_global_init");
791
792#if EXIM_GNUTLS_LIBRARY_LOG_LEVEL >= 0
793 DEBUG(D_tls)
059ec3d9 794 {
17c76198
PP
795 gnutls_global_set_log_function(exim_gnutls_logger_cb);
796 /* arbitrarily chosen level; bump upto 9 for more */
797 gnutls_global_set_log_level(EXIM_GNUTLS_LIBRARY_LOG_LEVEL);
059ec3d9 798 }
17c76198
PP
799#endif
800
801 exim_gnutls_base_init_done = TRUE;
059ec3d9 802 }
059ec3d9 803
17c76198
PP
804if (host)
805 {
806 state = &state_client;
807 memcpy(state, &exim_gnutls_state_init, sizeof(exim_gnutls_state_init));
808 DEBUG(D_tls) debug_printf("initialising GnuTLS client session\n");
809 rc = gnutls_init(&state->session, GNUTLS_CLIENT);
810 }
811else
812 {
813 state = &state_server;
814 memcpy(state, &exim_gnutls_state_init, sizeof(exim_gnutls_state_init));
815 DEBUG(D_tls) debug_printf("initialising GnuTLS server session\n");
816 rc = gnutls_init(&state->session, GNUTLS_SERVER);
817 }
818exim_gnutls_err_check(US"gnutls_init");
059ec3d9 819
17c76198 820state->host = host;
059ec3d9 821
17c76198
PP
822state->tls_certificate = certificate;
823state->tls_privatekey = privatekey;
824state->tls_sni = sni;
825state->tls_verify_certificates = cas;
826state->tls_crl = crl;
059ec3d9 827
17c76198
PP
828rc = gnutls_certificate_allocate_credentials(&state->x509_cred);
829exim_gnutls_err_check(US"gnutls_certificate_allocate_credentials");
059ec3d9 830
17c76198
PP
831/* This handles the variables that might get re-expanded after TLS SNI;
832that's tls_certificate, tls_privatekey, tls_verify_certificates, tls_crl */
059ec3d9 833
17c76198
PP
834DEBUG(D_tls)
835 debug_printf("Expanding various TLS configuration options for session credentials.\n");
836rc = tls_expand_session_files(state);
837if (rc != OK) return rc;
059ec3d9 838
17c76198
PP
839/* Create D-H parameters, or read them from the cache file. This function does
840its own SMTP error messaging. This only happens for the server, TLS D-H ignores
841client-side params. */
842
843if (!host)
059ec3d9 844 {
17c76198
PP
845 rc = init_server_dh();
846 if (rc != OK) return rc;
847 gnutls_certificate_set_dh_params(state->x509_cred, dh_server_params);
059ec3d9 848 }
83da1223 849
17c76198 850/* Link the credentials to the session. */
83da1223 851
17c76198
PP
852rc = gnutls_credentials_set(state->session, GNUTLS_CRD_CERTIFICATE, state->x509_cred);
853exim_gnutls_err_check(US"gnutls_credentials_set");
83da1223 854
17c76198
PP
855/* set SNI in client, only */
856if (host)
857 {
858 if (!expand_check_tlsvar(tls_sni))
859 return DEFER;
860 if (state->exp_tls_sni && *state->exp_tls_sni)
861 {
862 DEBUG(D_tls)
863 debug_printf("Setting TLS client SNI to \"%s\"\n", state->exp_tls_sni);
864 sz = Ustrlen(state->exp_tls_sni);
865 rc = gnutls_server_name_set(state->session,
866 GNUTLS_NAME_DNS, state->exp_tls_sni, sz);
867 exim_gnutls_err_check(US"gnutls_server_name_set");
868 }
869 }
870else if (state->tls_sni)
871 DEBUG(D_tls) debug_printf("*** PROBABLY A BUG *** " \
872 "have an SNI set for a client [%s]\n", state->tls_sni);
83da1223 873
17c76198
PP
874/* This is the priority string support,
875http://www.gnu.org/software/gnutls/manual/html_node/Priority-Strings.html
876and replaces gnutls_require_kx, gnutls_require_mac & gnutls_require_protocols.
877This was backwards incompatible, but means Exim no longer needs to track
878all algorithms and provide string forms for them. */
83da1223 879
17c76198 880want_default_priorities = TRUE;
83da1223 881
17c76198 882if (state->tls_require_ciphers && *state->tls_require_ciphers)
83da1223 883 {
17c76198
PP
884 if (!expand_check_tlsvar(tls_require_ciphers))
885 return DEFER;
886 if (state->exp_tls_require_ciphers && *state->exp_tls_require_ciphers)
83da1223 887 {
17c76198
PP
888 DEBUG(D_tls) debug_printf("GnuTLS session cipher/priority \"%s\"\n",
889 state->exp_tls_require_ciphers);
890
891 rc = gnutls_priority_init(&state->priority_cache,
892 CS state->exp_tls_require_ciphers, &errpos);
893 want_default_priorities = FALSE;
894 p = state->exp_tls_require_ciphers;
83da1223
PH
895 }
896 }
17c76198
PP
897if (want_default_priorities)
898 {
899 rc = gnutls_priority_init(&state->priority_cache,
900 exim_default_gnutls_priority, &errpos);
901 p = US exim_default_gnutls_priority;
902 }
83da1223 903
17c76198
PP
904exim_gnutls_err_check(string_sprintf(
905 "gnutls_priority_init(%s) failed at offset %ld, \"%.6s..\"",
906 p, errpos - CS p, errpos));
907
908rc = gnutls_priority_set(state->session, state->priority_cache);
909exim_gnutls_err_check(US"gnutls_priority_set");
910
911gnutls_db_set_cache_expiration(state->session, ssl_session_timeout);
912
913/* Reduce security in favour of increased compatibility, if the admin
914decides to make that trade-off. */
915if (gnutls_compat_mode)
83da1223 916 {
17c76198
PP
917#if LIBGNUTLS_VERSION_NUMBER >= 0x020104
918 DEBUG(D_tls) debug_printf("lowering GnuTLS security, compatibility mode\n");
919 gnutls_session_enable_compatibility_mode(state->session);
920#else
921 DEBUG(D_tls) debug_printf("Unable to set gnutls_compat_mode - GnuTLS version too old\n");
922#endif
83da1223
PH
923 }
924
17c76198
PP
925*caller_state = state;
926/* needs to happen before callbacks during handshake */
927current_global_tls_state = state;
928return OK;
83da1223
PH
929}
930
931
932
933
059ec3d9 934/*************************************************
17c76198 935* Extract peer information *
059ec3d9
PH
936*************************************************/
937
17c76198
PP
938/* Called from both server and client code.
939Only this is allowed to set state->peerdn and we use that to detect double-calls.
059ec3d9
PH
940
941Arguments:
17c76198 942 state exim_gnutls_state_st *
059ec3d9 943
17c76198 944Returns: OK/DEFER/FAIL
059ec3d9
PH
945*/
946
17c76198
PP
947static int
948peer_status(exim_gnutls_state_st *state)
059ec3d9 949{
17c76198
PP
950const gnutls_datum *cert_list;
951int rc;
952unsigned int cert_list_size = 0;
953gnutls_certificate_type_t ct;
954gnutls_x509_crt_t crt;
955uschar *dn_buf;
956size_t sz;
059ec3d9 957
17c76198
PP
958if (state->peerdn)
959 return OK;
059ec3d9 960
17c76198 961state->peerdn = US"unknown";
059ec3d9 962
17c76198 963cert_list = gnutls_certificate_get_peers(state->session, &cert_list_size);
83da1223 964
17c76198
PP
965if (cert_list == NULL || cert_list_size == 0)
966 {
967 state->peerdn = US"unknown (no certificate)";
968 DEBUG(D_tls) debug_printf("TLS: no certificate from peer (%p & %d)\n",
969 cert_list, cert_list_size);
970 if (state->verify_requirement == VERIFY_REQUIRED)
971 return tls_error(US"certificate verification failed",
972 "no certificate received from peer", state->host);
973 return OK;
974 }
059ec3d9 975
17c76198
PP
976ct = gnutls_certificate_type_get(state->session);
977if (ct != GNUTLS_CRT_X509)
059ec3d9 978 {
17c76198
PP
979 const char *ctn = gnutls_certificate_type_get_name(ct);
980 state->peerdn = string_sprintf("unknown (type %s)", ctn);
981 DEBUG(D_tls)
982 debug_printf("TLS: peer cert not X.509 but instead \"%s\"\n", ctn);
983 if (state->verify_requirement == VERIFY_REQUIRED)
984 return tls_error(US"certificate verification not possible, unhandled type",
985 ctn, state->host);
986 return OK;
83da1223 987 }
059ec3d9 988
17c76198
PP
989#define exim_gnutls_peer_err(Label) do { \
990 if (rc != GNUTLS_E_SUCCESS) { \
991 DEBUG(D_tls) debug_printf("TLS: peer cert problem: %s: %s\n", (Label), gnutls_strerror(rc)); \
992 if (state->verify_requirement == VERIFY_REQUIRED) { return tls_error((Label), gnutls_strerror(rc), state->host); } \
993 return OK; } } while (0)
994
995rc = gnutls_x509_crt_init(&crt);
996exim_gnutls_peer_err(US"gnutls_x509_crt_init (crt)");
997
998rc = gnutls_x509_crt_import(crt, &cert_list[0], GNUTLS_X509_FMT_DER);
999exim_gnutls_peer_err(US"failed to import certificate [gnutls_x509_crt_import(cert 0)]");
1000sz = 0;
1001rc = gnutls_x509_crt_get_dn(crt, NULL, &sz);
1002if (rc != GNUTLS_E_SHORT_MEMORY_BUFFER)
83da1223 1003 {
17c76198
PP
1004 exim_gnutls_peer_err(US"getting size for cert DN failed");
1005 return FAIL; /* should not happen */
059ec3d9 1006 }
17c76198
PP
1007dn_buf = store_get_perm(sz);
1008rc = gnutls_x509_crt_get_dn(crt, CS dn_buf, &sz);
1009exim_gnutls_peer_err(US"failed to extract certificate DN [gnutls_x509_crt_get_dn(cert 0)]");
1010state->peerdn = dn_buf;
1011
1012return OK;
1013#undef exim_gnutls_peer_err
1014}
059ec3d9 1015
059ec3d9 1016
059ec3d9 1017
059ec3d9 1018
17c76198
PP
1019/*************************************************
1020* Verify peer certificate *
1021*************************************************/
059ec3d9 1022
17c76198
PP
1023/* Called from both server and client code.
1024*Should* be using a callback registered with
1025gnutls_certificate_set_verify_function() to fail the handshake if we dislike
1026the peer information, but that's too new for some OSes.
059ec3d9 1027
17c76198
PP
1028Arguments:
1029 state exim_gnutls_state_st *
1030 error where to put an error message
059ec3d9 1031
17c76198
PP
1032Returns:
1033 FALSE if the session should be rejected
1034 TRUE if the cert is okay or we just don't care
1035*/
059ec3d9 1036
17c76198
PP
1037static BOOL
1038verify_certificate(exim_gnutls_state_st *state, const char **error)
1039{
1040int rc;
1041unsigned int verify;
1042
1043*error = NULL;
1044
1045rc = peer_status(state);
1046if (rc != OK)
e6060e2c 1047 {
17c76198
PP
1048 verify = GNUTLS_CERT_INVALID;
1049 *error = "not supplied";
1050 }
1051else
1052 {
1053 rc = gnutls_certificate_verify_peers2(state->session, &verify);
e6060e2c
NM
1054 }
1055
17c76198
PP
1056/* Handle the result of verification. INVALID seems to be set as well
1057as REVOKED, but leave the test for both. */
059ec3d9 1058
17c76198
PP
1059if ((rc < 0) || (verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED)) != 0)
1060 {
1061 state->peer_cert_verified = FALSE;
1062 if (*error == NULL)
1063 *error = ((verify & GNUTLS_CERT_REVOKED) != 0) ? "revoked" : "invalid";
059ec3d9 1064
17c76198
PP
1065 DEBUG(D_tls)
1066 debug_printf("TLS certificate verification failed (%s): peerdn=%s\n",
1067 *error, state->peerdn);
059ec3d9 1068
17c76198
PP
1069 if (state->verify_requirement == VERIFY_REQUIRED)
1070 {
1071 gnutls_alert_send(state->session, GNUTLS_AL_FATAL, GNUTLS_A_BAD_CERTIFICATE);
1072 return FALSE;
1073 }
1074 DEBUG(D_tls)
1075 debug_printf("TLS verify failure overriden (host in tls_try_verify_hosts)\n");
1076 }
1077else
1078 {
1079 state->peer_cert_verified = TRUE;
1080 DEBUG(D_tls) debug_printf("TLS certificate verified: peerdn=%s\n", state->peerdn);
1081 }
059ec3d9 1082
17c76198 1083tls_peerdn = state->peerdn;
059ec3d9 1084
17c76198
PP
1085return TRUE;
1086}
059ec3d9 1087
17c76198
PP
1088
1089
1090
1091/* ------------------------------------------------------------------------ */
1092/* Callbacks */
1093
1094/* Logging function which can be registered with
1095 * gnutls_global_set_log_function()
1096 * gnutls_global_set_log_level() 0..9
1097 */
059ec3d9 1098static void
17c76198 1099exim_gnutls_logger_cb(int level, const char *message)
059ec3d9 1100{
17c76198
PP
1101 DEBUG(D_tls) debug_printf("GnuTLS<%d>: %s\n", level, message);
1102}
059ec3d9 1103
059ec3d9 1104
17c76198
PP
1105/* Called after client hello, should handle SNI work.
1106This will always set tls_sni (state->received_sni) if available,
1107and may trigger presenting different certificates,
1108if state->trigger_sni_changes is TRUE.
059ec3d9 1109
17c76198
PP
1110Should be registered with
1111 gnutls_handshake_set_post_client_hello_function()
059ec3d9 1112
17c76198
PP
1113"This callback must return 0 on success or a gnutls error code to terminate the
1114handshake.".
059ec3d9 1115
17c76198
PP
1116For inability to get SNI information, we return 0.
1117We only return non-zero if re-setup failed.
1118*/
44bbabb5 1119
17c76198
PP
1120static int
1121exim_sni_handling_cb(gnutls_session_t session)
1122{
1123char sni_name[MAX_HOST_LEN];
1124size_t data_len = MAX_HOST_LEN;
1125exim_gnutls_state_st *state = current_global_tls_state;
1126unsigned int sni_type;
1127int rc, old_pool;
1128
1129rc = gnutls_server_name_get(session, sni_name, &data_len, &sni_type, 0);
1130exim_gnutls_err_debugreturn0("gnutls_server_name_get()");
1131if (sni_type != GNUTLS_NAME_DNS)
1132 {
1133 DEBUG(D_tls) debug_printf("TLS: ignoring SNI of unhandled type %u\n", sni_type);
1134 return 0;
1135 }
44bbabb5 1136
17c76198
PP
1137/* We now have a UTF-8 string in sni_name */
1138old_pool = store_pool;
1139store_pool = POOL_PERM;
1140state->received_sni = string_copyn(US sni_name, data_len);
1141store_pool = old_pool;
1142
1143/* We set this one now so that variable expansions below will work */
1144tls_sni = state->received_sni;
1145
1146DEBUG(D_tls) debug_printf("Received TLS SNI \"%s\"%s\n", sni_name,
1147 state->trigger_sni_changes ? "" : " (unused for certificate selection)");
1148
1149if (!state->trigger_sni_changes)
1150 return 0;
1151
1152rc = tls_expand_session_files(state);
1153if (rc != OK)
1154 {
1155 /* If the setup of certs/etc failed before handshake, TLS would not have
1156 been offered. The best we can do now is abort. */
1157 return GNUTLS_E_APPLICATION_ERROR_MIN;
1158 }
1159
1160rc = gnutls_credentials_set(state->session, GNUTLS_CRD_CERTIFICATE, state->x509_cred);
1161return (rc == GNUTLS_E_SUCCESS) ? 0 : rc;
059ec3d9
PH
1162}
1163
1164
1165
17c76198
PP
1166
1167/* ------------------------------------------------------------------------ */
1168/* Exported functions */
1169
1170
1171
1172
059ec3d9
PH
1173/*************************************************
1174* Start a TLS session in a server *
1175*************************************************/
1176
1177/* This is called when Exim is running as a server, after having received
1178the STARTTLS command. It must respond to that command, and then negotiate
1179a TLS session.
1180
1181Arguments:
83da1223 1182 require_ciphers list of allowed ciphers or NULL
059ec3d9
PH
1183
1184Returns: OK on success
1185 DEFER for errors before the start of the negotiation
1186 FAIL for errors during the negotation; the server can't
1187 continue running.
1188*/
1189
1190int
17c76198 1191tls_server_start(const uschar *require_ciphers)
059ec3d9
PH
1192{
1193int rc;
7199e1ee 1194const char *error;
17c76198 1195exim_gnutls_state_st *state = NULL;
059ec3d9
PH
1196
1197/* Check for previous activation */
17c76198 1198/* nb: this will not be TLS callout safe, needs reworking as part of that. */
059ec3d9
PH
1199
1200if (tls_active >= 0)
1201 {
17c76198 1202 tls_error(US"STARTTLS received after TLS started", "", NULL);
059ec3d9
PH
1203 smtp_printf("554 Already in TLS\r\n");
1204 return FAIL;
1205 }
1206
1207/* Initialize the library. If it fails, it will already have logged the error
1208and sent an SMTP response. */
1209
17c76198 1210DEBUG(D_tls) debug_printf("initialising GnuTLS as a server\n");
059ec3d9 1211
17c76198
PP
1212rc = tls_init(NULL, tls_certificate, tls_privatekey,
1213 NULL, tls_verify_certificates, tls_crl,
1214 require_ciphers, &state);
059ec3d9
PH
1215if (rc != OK) return rc;
1216
059ec3d9
PH
1217/* If this is a host for which certificate verification is mandatory or
1218optional, set up appropriately. */
1219
059ec3d9 1220if (verify_check_host(&tls_verify_hosts) == OK)
17c76198
PP
1221 {
1222 DEBUG(D_tls) debug_printf("TLS: a client certificate will be required.\n");
1223 state->verify_requirement = VERIFY_REQUIRED;
1224 gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_REQUIRE);
1225 }
059ec3d9 1226else if (verify_check_host(&tls_try_verify_hosts) == OK)
17c76198
PP
1227 {
1228 DEBUG(D_tls) debug_printf("TLS: a client certificate will be requested but not required.\n");
1229 state->verify_requirement = VERIFY_OPTIONAL;
1230 gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_REQUEST);
1231 }
1232else
1233 {
1234 DEBUG(D_tls) debug_printf("TLS: a client certificate will not be requested.\n");
1235 state->verify_requirement = VERIFY_NONE;
1236 gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_IGNORE);
1237 }
059ec3d9 1238
17c76198
PP
1239/* Register SNI handling; always, even if not in tls_certificate, so that the
1240expansion variable $tls_sni is always available. */
059ec3d9 1241
17c76198
PP
1242gnutls_handshake_set_post_client_hello_function(state->session,
1243 exim_sni_handling_cb);
059ec3d9
PH
1244
1245/* Set context and tell client to go ahead, except in the case of TLS startup
1246on connection, where outputting anything now upsets the clients and tends to
1247make them disconnect. We need to have an explicit fflush() here, to force out
1248the response. Other smtp_printf() calls do not need it, because in non-TLS
1249mode, the fflush() happens when smtp_getc() is called. */
1250
1251if (!tls_on_connect)
1252 {
1253 smtp_printf("220 TLS go ahead\r\n");
1254 fflush(smtp_out);
1255 }
1256
1257/* Now negotiate the TLS session. We put our own timer on it, since it seems
1258that the GnuTLS library doesn't. */
1259
17c76198
PP
1260gnutls_transport_set_ptr2(state->session,
1261 (gnutls_transport_ptr)fileno(smtp_in),
1262 (gnutls_transport_ptr)fileno(smtp_out));
1263state->fd_in = fileno(smtp_in);
1264state->fd_out = fileno(smtp_out);
059ec3d9
PH
1265
1266sigalrm_seen = FALSE;
1267if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
17c76198
PP
1268do
1269 {
1270 rc = gnutls_handshake(state->session);
1271 } while ((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED));
059ec3d9
PH
1272alarm(0);
1273
17c76198 1274if (rc != GNUTLS_E_SUCCESS)
059ec3d9 1275 {
17c76198
PP
1276 tls_error(US"gnutls_handshake",
1277 sigalrm_seen ? "timed out" : gnutls_strerror(rc), NULL);
059ec3d9
PH
1278 /* It seems that, except in the case of a timeout, we have to close the
1279 connection right here; otherwise if the other end is running OpenSSL it hangs
1280 until the server times out. */
1281
1282 if (!sigalrm_seen)
1283 {
f1e894f3
PH
1284 (void)fclose(smtp_out);
1285 (void)fclose(smtp_in);
059ec3d9
PH
1286 }
1287
1288 return FAIL;
1289 }
1290
1291DEBUG(D_tls) debug_printf("gnutls_handshake was successful\n");
1292
17c76198
PP
1293/* Verify after the fact */
1294
1295if (state->verify_requirement != VERIFY_NONE)
059ec3d9 1296 {
17c76198
PP
1297 if (!verify_certificate(state, &error))
1298 {
1299 if (state->verify_requirement == VERIFY_OPTIONAL)
1300 {
1301 DEBUG(D_tls)
1302 debug_printf("TLS: continuing on only because verification was optional, after: %s\n",
1303 error);
1304 }
1305 else
1306 {
1307 tls_error(US"certificate verification failed", error, NULL);
1308 return FAIL;
1309 }
1310 }
059ec3d9
PH
1311 }
1312
17c76198
PP
1313/* Figure out peer DN, and if authenticated, etc. */
1314
1315rc = peer_status(state);
1316if (rc != OK) return rc;
1317
1318/* Sets various Exim expansion variables; always safe within server */
1319
1320extract_exim_vars_from_tls_state(state);
059ec3d9
PH
1321
1322/* TLS has been set up. Adjust the input functions to read via TLS,
1323and initialize appropriately. */
1324
17c76198 1325state->xfer_buffer = store_malloc(ssl_xfer_buffer_size);
059ec3d9
PH
1326
1327receive_getc = tls_getc;
1328receive_ungetc = tls_ungetc;
1329receive_feof = tls_feof;
1330receive_ferror = tls_ferror;
58eb016e 1331receive_smtp_buffered = tls_smtp_buffered;
059ec3d9 1332
059ec3d9
PH
1333return OK;
1334}
1335
1336
1337
1338
1339/*************************************************
1340* Start a TLS session in a client *
1341*************************************************/
1342
1343/* Called from the smtp transport after STARTTLS has been accepted.
1344
1345Arguments:
1346 fd the fd of the connection
1347 host connected host (for messages)
83da1223 1348 addr the first address (not used)
17c76198 1349 dhparam DH parameter file (ignored, we're a client)
059ec3d9
PH
1350 certificate certificate file
1351 privatekey private key file
3f0945ff 1352 sni TLS SNI to send to remote host
059ec3d9
PH
1353 verify_certs file for certificate verify
1354 verify_crl CRL for verify
83da1223 1355 require_ciphers list of allowed ciphers or NULL
059ec3d9
PH
1356 timeout startup timeout
1357
1358Returns: OK/DEFER/FAIL (because using common functions),
1359 but for a client, DEFER and FAIL have the same meaning
1360*/
1361
1362int
17c76198
PP
1363tls_client_start(int fd, host_item *host,
1364 address_item *addr ARG_UNUSED, uschar *dhparam ARG_UNUSED,
1365 uschar *certificate, uschar *privatekey, uschar *sni,
1366 uschar *verify_certs, uschar *verify_crl,
1367 uschar *require_ciphers, int timeout)
059ec3d9 1368{
059ec3d9 1369int rc;
17c76198
PP
1370const char *error;
1371exim_gnutls_state_st *state = NULL;
059ec3d9 1372
17c76198 1373DEBUG(D_tls) debug_printf("initialising GnuTLS as a client on fd %d\n", fd);
059ec3d9 1374
17c76198
PP
1375rc = tls_init(host, certificate, privatekey,
1376 sni, verify_certs, verify_crl, require_ciphers, &state);
059ec3d9
PH
1377if (rc != OK) return rc;
1378
17c76198 1379gnutls_dh_set_prime_bits(state->session, EXIM_CLIENT_DH_MIN_BITS);
83da1223 1380
17c76198
PP
1381if (verify_certs == NULL)
1382 {
1383 DEBUG(D_tls) debug_printf("TLS: server certificate verification not required\n");
1384 state->verify_requirement = VERIFY_NONE;
1385 /* we still ask for it, to log it, etc */
1386 gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_REQUEST);
1387 }
1388else
1389 {
1390 DEBUG(D_tls) debug_printf("TLS: server certificate verification required\n");
1391 state->verify_requirement = VERIFY_REQUIRED;
1392 gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_REQUIRE);
1393 }
059ec3d9 1394
17c76198
PP
1395gnutls_transport_set_ptr(state->session, (gnutls_transport_ptr)fd);
1396state->fd_in = fd;
1397state->fd_out = fd;
059ec3d9
PH
1398
1399/* There doesn't seem to be a built-in timeout on connection. */
1400
1401sigalrm_seen = FALSE;
1402alarm(timeout);
17c76198
PP
1403do
1404 {
1405 rc = gnutls_handshake(state->session);
1406 } while ((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED));
059ec3d9
PH
1407alarm(0);
1408
17c76198 1409DEBUG(D_tls) debug_printf("gnutls_handshake was successful\n");
059ec3d9 1410
17c76198 1411/* Verify late */
059ec3d9 1412
17c76198
PP
1413if (state->verify_requirement != VERIFY_NONE &&
1414 !verify_certificate(state, &error))
1415 return tls_error(US"certificate verification failed", error, state->host);
059ec3d9 1416
17c76198 1417/* Figure out peer DN, and if authenticated, etc. */
059ec3d9 1418
17c76198
PP
1419rc = peer_status(state);
1420if (rc != OK) return rc;
059ec3d9 1421
17c76198 1422/* Sets various Exim expansion variables; always safe within server */
059ec3d9 1423
17c76198 1424extract_exim_vars_from_tls_state(state);
059ec3d9 1425
059ec3d9
PH
1426return OK;
1427}
1428
1429
1430
17c76198 1431
059ec3d9 1432/*************************************************
17c76198 1433* Close down a TLS session *
059ec3d9
PH
1434*************************************************/
1435
17c76198
PP
1436/* This is also called from within a delivery subprocess forked from the
1437daemon, to shut down the TLS library, without actually doing a shutdown (which
1438would tamper with the TLS session in the parent process).
059ec3d9 1439
17c76198
PP
1440Arguments: TRUE if gnutls_bye is to be called
1441Returns: nothing
059ec3d9
PH
1442*/
1443
17c76198
PP
1444void
1445tls_close(BOOL shutdown)
059ec3d9 1446{
17c76198 1447exim_gnutls_state_st *state = current_global_tls_state;
059ec3d9 1448
17c76198
PP
1449if (tls_active < 0) return; /* TLS was not active */
1450
1451if (shutdown)
1452 {
1453 DEBUG(D_tls) debug_printf("tls_close(): shutting down TLS\n");
1454 gnutls_bye(state->session, GNUTLS_SHUT_WR);
1455 }
1456
1457gnutls_deinit(state->session);
1458
1459memcpy(state, &exim_gnutls_state_init, sizeof(exim_gnutls_state_init));
1460
1461if ((state_server.session == NULL) && (state_client.session == NULL))
1462 {
1463 gnutls_global_deinit();
1464 exim_gnutls_base_init_done = FALSE;
1465 }
7199e1ee 1466
17c76198 1467tls_active = -1;
059ec3d9
PH
1468}
1469
1470
1471
17c76198 1472
059ec3d9
PH
1473/*************************************************
1474* TLS version of getc *
1475*************************************************/
1476
1477/* This gets the next byte from the TLS input buffer. If the buffer is empty,
1478it refills the buffer via the GnuTLS reading function.
1479
17c76198
PP
1480This feeds DKIM and should be used for all message-body reads.
1481
059ec3d9
PH
1482Arguments: none
1483Returns: the next character or EOF
1484*/
1485
1486int
1487tls_getc(void)
1488{
17c76198
PP
1489exim_gnutls_state_st *state = current_global_tls_state;
1490if (state->xfer_buffer_lwm >= state->xfer_buffer_hwm)
059ec3d9 1491 {
17c76198 1492 ssize_t inbytes;
059ec3d9 1493
17c76198
PP
1494 DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%p, %p, %u)\n",
1495 state->session, state->xfer_buffer, ssl_xfer_buffer_size);
059ec3d9
PH
1496
1497 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
17c76198 1498 inbytes = gnutls_record_recv(state->session, state->xfer_buffer,
059ec3d9
PH
1499 ssl_xfer_buffer_size);
1500 alarm(0);
1501
1502 /* A zero-byte return appears to mean that the TLS session has been
1503 closed down, not that the socket itself has been closed down. Revert to
1504 non-TLS handling. */
1505
1506 if (inbytes == 0)
1507 {
1508 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1509
1510 receive_getc = smtp_getc;
1511 receive_ungetc = smtp_ungetc;
1512 receive_feof = smtp_feof;
1513 receive_ferror = smtp_ferror;
58eb016e 1514 receive_smtp_buffered = smtp_buffered;
059ec3d9 1515
17c76198
PP
1516 gnutls_deinit(state->session);
1517 state->session = NULL;
059ec3d9 1518 tls_active = -1;
17c76198
PP
1519 tls_bits = 0;
1520 tls_certificate_verified = FALSE;
1521 tls_channelbinding_b64 = NULL;
059ec3d9
PH
1522 tls_cipher = NULL;
1523 tls_peerdn = NULL;
1524
1525 return smtp_getc();
1526 }
1527
1528 /* Handle genuine errors */
1529
1530 else if (inbytes < 0)
1531 {
17c76198
PP
1532 record_io_error(state, (int) inbytes, US"recv", NULL);
1533 state->xfer_error = 1;
059ec3d9
PH
1534 return EOF;
1535 }
80a47a2c 1536#ifndef DISABLE_DKIM
17c76198 1537 dkim_exim_verify_feed(state->xfer_buffer, inbytes);
80a47a2c 1538#endif
17c76198
PP
1539 state->xfer_buffer_hwm = (int) inbytes;
1540 state->xfer_buffer_lwm = 0;
059ec3d9
PH
1541 }
1542
059ec3d9
PH
1543/* Something in the buffer; return next uschar */
1544
17c76198 1545return state->xfer_buffer[state->xfer_buffer_lwm++];
059ec3d9
PH
1546}
1547
1548
1549
17c76198 1550
059ec3d9
PH
1551/*************************************************
1552* Read bytes from TLS channel *
1553*************************************************/
1554
17c76198
PP
1555/* This does not feed DKIM, so if the caller uses this for reading message body,
1556then the caller must feed DKIM.
059ec3d9
PH
1557Arguments:
1558 buff buffer of data
1559 len size of buffer
1560
1561Returns: the number of bytes read
1562 -1 after a failed read
1563*/
1564
1565int
1566tls_read(uschar *buff, size_t len)
1567{
17c76198
PP
1568exim_gnutls_state_st *state = current_global_tls_state;
1569ssize_t inbytes;
059ec3d9 1570
17c76198
PP
1571if (len > INT_MAX)
1572 len = INT_MAX;
059ec3d9 1573
17c76198
PP
1574if (state->xfer_buffer_lwm < state->xfer_buffer_hwm)
1575 DEBUG(D_tls)
1576 debug_printf("*** PROBABLY A BUG *** " \
1577 "tls_read() called with data in the tls_getc() buffer, %d ignored\n",
1578 state->xfer_buffer_hwm - state->xfer_buffer_lwm);
1579
1580DEBUG(D_tls)
1581 debug_printf("Calling gnutls_record_recv(%p, %p, " SIZE_T_FMT ")\n",
1582 state->session, buff, len);
1583
1584inbytes = gnutls_record_recv(state->session, buff, len);
059ec3d9
PH
1585if (inbytes > 0) return inbytes;
1586if (inbytes == 0)
1587 {
1588 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1589 }
17c76198 1590else record_io_error(state, (int)inbytes, US"recv", NULL);
059ec3d9
PH
1591
1592return -1;
1593}
1594
1595
1596
17c76198 1597
059ec3d9
PH
1598/*************************************************
1599* Write bytes down TLS channel *
1600*************************************************/
1601
1602/*
1603Arguments:
1604 buff buffer of data
1605 len number of bytes
1606
1607Returns: the number of bytes after a successful write,
1608 -1 after a failed write
1609*/
1610
1611int
1612tls_write(const uschar *buff, size_t len)
1613{
17c76198
PP
1614ssize_t outbytes;
1615size_t left = len;
1616exim_gnutls_state_st *state = current_global_tls_state;
059ec3d9 1617
17c76198 1618DEBUG(D_tls) debug_printf("tls_do_write(%p, " SIZE_T_FMT ")\n", buff, left);
059ec3d9
PH
1619while (left > 0)
1620 {
17c76198
PP
1621 DEBUG(D_tls) debug_printf("gnutls_record_send(SSL, %p, " SIZE_T_FMT ")\n",
1622 buff, left);
1623 outbytes = gnutls_record_send(state->session, buff, left);
059ec3d9 1624
17c76198 1625 DEBUG(D_tls) debug_printf("outbytes=" SSIZE_T_FMT "\n", outbytes);
059ec3d9
PH
1626 if (outbytes < 0)
1627 {
17c76198 1628 record_io_error(state, outbytes, US"send", NULL);
059ec3d9
PH
1629 return -1;
1630 }
1631 if (outbytes == 0)
1632 {
17c76198 1633 record_io_error(state, 0, US"send", US"TLS channel closed on write");
059ec3d9
PH
1634 return -1;
1635 }
1636
1637 left -= outbytes;
1638 buff += outbytes;
1639 }
1640
17c76198
PP
1641if (len > INT_MAX)
1642 {
1643 DEBUG(D_tls)
1644 debug_printf("Whoops! Wrote more bytes (" SIZE_T_FMT ") than INT_MAX\n",
1645 len);
1646 len = INT_MAX;
1647 }
1648
1649return (int) len;
059ec3d9
PH
1650}
1651
1652
1653
17c76198 1654
059ec3d9 1655/*************************************************
17c76198 1656* Random number generation *
059ec3d9
PH
1657*************************************************/
1658
17c76198
PP
1659/* Pseudo-random number generation. The result is not expected to be
1660cryptographically strong but not so weak that someone will shoot themselves
1661in the foot using it as a nonce in input in some email header scheme or
1662whatever weirdness they'll twist this into. The result should handle fork()
1663and avoid repeating sequences. OpenSSL handles that for us.
059ec3d9 1664
17c76198
PP
1665Arguments:
1666 max range maximum
1667Returns a random number in range [0, max-1]
059ec3d9
PH
1668*/
1669
17c76198
PP
1670int
1671vaguely_random_number(int max)
059ec3d9 1672{
17c76198
PP
1673unsigned int r;
1674int i, needed_len;
1675uschar *p;
1676uschar smallbuf[sizeof(r)];
1677
1678if (max <= 1)
1679 return 0;
1680
1681needed_len = sizeof(r);
1682/* Don't take 8 times more entropy than needed if int is 8 octets and we were
1683 * asked for a number less than 10. */
1684for (r = max, i = 0; r; ++i)
1685 r >>= 1;
1686i = (i + 7) / 8;
1687if (i < needed_len)
1688 needed_len = i;
1689
1690i = gnutls_rnd(GNUTLS_RND_NONCE, smallbuf, needed_len);
1691if (i < 0)
059ec3d9 1692 {
17c76198
PP
1693 DEBUG(D_all) debug_printf("gnutls_rnd() failed, using fallback.\n");
1694 return vaguely_random_number_fallback(max);
1695 }
1696r = 0;
1697for (p = smallbuf; needed_len; --needed_len, ++p)
1698 {
1699 r *= 256;
1700 r += *p;
059ec3d9
PH
1701 }
1702
17c76198
PP
1703/* We don't particularly care about weighted results; if someone wants
1704 * smooth distribution and cares enough then they should submit a patch then. */
1705return r % max;
059ec3d9
PH
1706}
1707
36f12725
NM
1708
1709
1710
1711/*************************************************
1712* Report the library versions. *
1713*************************************************/
1714
1715/* See a description in tls-openssl.c for an explanation of why this exists.
1716
1717Arguments: a FILE* to print the results to
1718Returns: nothing
1719*/
1720
1721void
1722tls_version_report(FILE *f)
1723{
754a0503
PP
1724fprintf(f, "Library version: GnuTLS: Compile: %s\n"
1725 " Runtime: %s\n",
1726 LIBGNUTLS_VERSION,
1727 gnutls_check_version(NULL));
36f12725
NM
1728}
1729
059ec3d9 1730/* End of tls-gnu.c */