TLS version reporting. fixes: #745
[exim.git] / src / src / tls-gnu.c
CommitLineData
36f12725 1/* $Cambridge: exim/src/src/tls-gnu.c,v 1.22 2009/10/14 13:52:48 nm4 Exp $ */
059ec3d9
PH
2
3/*************************************************
4* Exim - an Internet mail transport agent *
5*************************************************/
6
184e8823 7/* Copyright (c) University of Cambridge 1995 - 2007 */
059ec3d9
PH
8/* See the file NOTICE for conditions of use and distribution. */
9
10/* This module provides TLS (aka SSL) support for Exim using the GnuTLS
11library. It is #included into tls.c when that library is used. The code herein
12is based on a patch that was contributed by Nikos Mavroyanopoulos.
13
14No cryptographic code is included in Exim. All this module does is to call
15functions from the GnuTLS library. */
16
17
18/* Heading stuff for GnuTLS */
19
20#include <gnutls/gnutls.h>
21#include <gnutls/x509.h>
22
23
24#define UNKNOWN_NAME "unknown"
87054a31 25#define DH_BITS 1024
b5aea5e1
PH
26#define PARAM_SIZE 2*1024
27
059ec3d9 28
7199e1ee 29/* Values for verify_requirment */
059ec3d9
PH
30
31enum { VERIFY_NONE, VERIFY_OPTIONAL, VERIFY_REQUIRED };
059ec3d9
PH
32
33/* Local static variables for GNUTLS */
34
059ec3d9
PH
35static host_item *client_host;
36
059ec3d9
PH
37static gnutls_dh_params dh_params = NULL;
38
39static gnutls_certificate_server_credentials x509_cred = NULL;
40static gnutls_session tls_session = NULL;
41
42static char ssl_errstring[256];
43
44static int ssl_session_timeout = 200;
45static int verify_requirement;
46
83da1223
PH
47/* Priorities for TLS algorithms to use. In each case there's a default table,
48and space into which it can be copied and altered. */
059ec3d9 49
83da1223
PH
50static const int default_proto_priority[16] = {
51 GNUTLS_TLS1,
52 GNUTLS_SSL3,
53 0 };
54
55static int proto_priority[16];
059ec3d9 56
83da1223 57static const int default_kx_priority[16] = {
059ec3d9
PH
58 GNUTLS_KX_RSA,
59 GNUTLS_KX_DHE_DSS,
60 GNUTLS_KX_DHE_RSA,
059ec3d9
PH
61 0 };
62
83da1223
PH
63static int kx_priority[16];
64
059ec3d9 65static int default_cipher_priority[16] = {
26dd5a95 66 GNUTLS_CIPHER_AES_256_CBC,
059ec3d9
PH
67 GNUTLS_CIPHER_AES_128_CBC,
68 GNUTLS_CIPHER_3DES_CBC,
26dd5a95 69 GNUTLS_CIPHER_ARCFOUR_128,
059ec3d9
PH
70 0 };
71
72static int cipher_priority[16];
73
83da1223 74static const int default_mac_priority[16] = {
059ec3d9
PH
75 GNUTLS_MAC_SHA,
76 GNUTLS_MAC_MD5,
77 0 };
78
83da1223
PH
79static int mac_priority[16];
80
81/* These two are currently not changeable. */
82
059ec3d9
PH
83static const int comp_priority[16] = { GNUTLS_COMP_NULL, 0 };
84static const int cert_type_priority[16] = { GNUTLS_CRT_X509, 0 };
85
83da1223 86/* Tables of priority names and equivalent numbers */
059ec3d9
PH
87
88typedef struct pri_item {
89 uschar *name;
90 int *values;
91} pri_item;
92
83da1223
PH
93
94static int tls1_codes[] = { GNUTLS_TLS1, 0 };
95static int ssl3_codes[] = { GNUTLS_SSL3, 0 };
96
97static pri_item proto_index[] = {
98 { US"TLS1", tls1_codes },
99 { US"SSL3", ssl3_codes }
100};
101
102
103static int kx_rsa_codes[] = { GNUTLS_KX_RSA,
104 GNUTLS_KX_DHE_RSA, 0 };
105static int kx_dhe_codes[] = { GNUTLS_KX_DHE_DSS,
106 GNUTLS_KX_DHE_RSA, 0 };
107static int kx_dhe_dss_codes[] = { GNUTLS_KX_DHE_DSS, 0 };
108static int kx_dhe_rsa_codes[] = { GNUTLS_KX_DHE_RSA, 0 };
109
110static pri_item kx_index[] = {
111 { US"DHE_DSS", kx_dhe_dss_codes },
112 { US"DHE_RSA", kx_dhe_rsa_codes },
113 { US"RSA", kx_rsa_codes },
114 { US"DHE", kx_dhe_codes }
115};
116
117
059ec3d9
PH
118static int arcfour_128_codes[] = { GNUTLS_CIPHER_ARCFOUR_128, 0 };
119static int arcfour_40_codes[] = { GNUTLS_CIPHER_ARCFOUR_40, 0 };
120static int arcfour_codes[] = { GNUTLS_CIPHER_ARCFOUR_128,
121 GNUTLS_CIPHER_ARCFOUR_40, 0 };
122static int aes_256_codes[] = { GNUTLS_CIPHER_AES_256_CBC, 0 };
123static int aes_128_codes[] = { GNUTLS_CIPHER_AES_128_CBC, 0 };
124static int aes_codes[] = { GNUTLS_CIPHER_AES_256_CBC,
125 GNUTLS_CIPHER_AES_128_CBC, 0 };
126static int des3_codes[] = { GNUTLS_CIPHER_3DES_CBC, 0 };
127
128static pri_item cipher_index[] = {
129 { US"ARCFOUR_128", arcfour_128_codes },
130 { US"ARCFOUR_40", arcfour_40_codes },
131 { US"ARCFOUR", arcfour_codes },
132 { US"AES_256", aes_256_codes },
133 { US"AES_128", aes_128_codes },
134 { US"AES", aes_codes },
135 { US"3DES", des3_codes }
136};
137
138
83da1223
PH
139static int mac_sha_codes[] = { GNUTLS_MAC_SHA, 0 };
140static int mac_md5_codes[] = { GNUTLS_MAC_MD5, 0 };
141
142static pri_item mac_index[] = {
143 { US"SHA", mac_sha_codes },
144 { US"SHA1", mac_sha_codes },
145 { US"MD5", mac_md5_codes }
146};
147
148
059ec3d9
PH
149
150/*************************************************
151* Handle TLS error *
152*************************************************/
153
154/* Called from lots of places when errors occur before actually starting to do
155the TLS handshake, that is, while the session is still in clear. Always returns
156DEFER for a server and FAIL for a client so that most calls can use "return
157tls_error(...)" to do this processing and then give an appropriate return. A
158single function is used for both server and client, because it is called from
159some shared functions.
160
161Argument:
162 prefix text to include in the logged error
163 host NULL if setting up a server;
164 the connected host if setting up a client
7199e1ee
TF
165 msg additional error string (may be NULL)
166 usually obtained from gnutls_strerror()
059ec3d9
PH
167
168Returns: OK/DEFER/FAIL
169*/
170
171static int
7199e1ee 172tls_error(uschar *prefix, host_item *host, const char *msg)
059ec3d9 173{
059ec3d9
PH
174if (host == NULL)
175 {
7199e1ee
TF
176 uschar *conn_info = smtp_get_connection_info();
177 if (strncmp(conn_info, "SMTP ", 5) == 0)
178 conn_info += 5;
179 log_write(0, LOG_MAIN, "TLS error on %s (%s)%s%s",
180 conn_info, prefix, msg ? ": " : "", msg ? msg : "");
059ec3d9
PH
181 return DEFER;
182 }
183else
184 {
7199e1ee
TF
185 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s)%s%s",
186 host->name, host->address, prefix, msg ? ": " : "", msg ? msg : "");
059ec3d9
PH
187 return FAIL;
188 }
189}
190
191
192
193/*************************************************
194* Verify certificate *
195*************************************************/
196
197/* Called after a successful handshake, when certificate verification is
198required or optional, for both server and client.
199
200Arguments:
201 session GNUTLS session
202 error where to put text giving a reason for failure
203
204Returns: TRUE/FALSE
205*/
206
207static BOOL
7199e1ee 208verify_certificate(gnutls_session session, const char **error)
059ec3d9
PH
209{
210int verify;
211uschar *dn_string = US"";
212const gnutls_datum *cert;
213unsigned int cert_size = 0;
214
215*error = NULL;
216
217/* Get the peer's certificate. If it sent one, extract it's DN, and then
218attempt to verify the certificate. If no certificate is supplied, verification
219is forced to fail. */
220
221cert = gnutls_certificate_get_peers(session, &cert_size);
222if (cert != NULL)
223 {
224 uschar buff[1024];
225 gnutls_x509_crt gcert;
226
227 gnutls_x509_crt_init(&gcert);
228 dn_string = US"unknown";
229
230 if (gnutls_x509_crt_import(gcert, cert, GNUTLS_X509_FMT_DER) == 0)
231 {
232 size_t bufsize = sizeof(buff);
233 if (gnutls_x509_crt_get_dn(gcert, CS buff, &bufsize) >= 0)
234 dn_string = string_copy_malloc(buff);
235 }
236
237 verify = gnutls_certificate_verify_peers(session);
238 }
239else
240 {
241 DEBUG(D_tls) debug_printf("no peer certificate supplied\n");
242 verify = GNUTLS_CERT_INVALID;
7199e1ee 243 *error = "not supplied";
059ec3d9
PH
244 }
245
246/* Handle the result of verification. INVALID seems to be set as well
247as REVOKED, but leave the test for both. */
248
249if ((verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED)) != 0)
250 {
251 tls_certificate_verified = FALSE;
252 if (*error == NULL) *error = ((verify & GNUTLS_CERT_REVOKED) != 0)?
7199e1ee 253 "revoked" : "invalid";
059ec3d9
PH
254 if (verify_requirement == VERIFY_REQUIRED)
255 {
256 DEBUG(D_tls) debug_printf("TLS certificate verification failed (%s): "
257 "peerdn=%s\n", *error, dn_string);
258 gnutls_alert_send(session, GNUTLS_AL_FATAL, GNUTLS_A_BAD_CERTIFICATE);
259 return FALSE; /* reject */
260 }
261 DEBUG(D_tls) debug_printf("TLS certificate verify failure (%s) overridden "
262 "(host in tls_try_verify_hosts): peerdn=%s\n", *error, dn_string);
263 }
264else
265 {
266 tls_certificate_verified = TRUE;
267 DEBUG(D_tls) debug_printf("TLS certificate verified: peerdn=%s\n",
268 dn_string);
269 }
270
271tls_peerdn = dn_string;
272return TRUE; /* accept */
273}
274
275
276
059ec3d9 277/*************************************************
575643cd 278* Setup up DH parameters *
059ec3d9
PH
279*************************************************/
280
575643cd 281/* Generating the D-H parameters may take a long time. They only need to
059ec3d9
PH
282be re-generated every so often, depending on security policy. What we do is to
283keep these parameters in a file in the spool directory. If the file does not
284exist, we generate them. This means that it is easy to cause a regeneration.
285
286The new file is written as a temporary file and renamed, so that an incomplete
287file is never present. If two processes both compute some new parameters, you
288waste a bit of effort, but it doesn't seem worth messing around with locking to
289prevent this.
290
291Argument:
292 host NULL for server, server for client (for error handling)
293
294Returns: OK/DEFER/FAIL
295*/
296
297static int
575643cd 298init_dh(host_item *host)
059ec3d9 299{
b5aea5e1 300int fd;
182ad5cf 301int ret;
b5aea5e1 302gnutls_datum m;
059ec3d9
PH
303uschar filename[200];
304
305/* Initialize the data structures for holding the parameters */
306
059ec3d9 307ret = gnutls_dh_params_init(&dh_params);
7199e1ee 308if (ret < 0) return tls_error(US"init dh_params", host, gnutls_strerror(ret));
059ec3d9
PH
309
310/* Set up the name of the cache file */
311
312if (!string_format(filename, sizeof(filename), "%s/gnutls-params",
313 spool_directory))
7199e1ee 314 return tls_error(US"overlong filename", host, NULL);
059ec3d9 315
b5aea5e1 316/* Open the cache file for reading and if successful, read it and set up the
575643cd 317parameters. */
059ec3d9
PH
318
319fd = Uopen(filename, O_RDONLY, 0);
b5aea5e1 320if (fd >= 0)
059ec3d9 321 {
b5aea5e1
PH
322 struct stat statbuf;
323 if (fstat(fd, &statbuf) < 0)
324 {
325 (void)close(fd);
7199e1ee 326 return tls_error(US"TLS cache stat failed", host, strerror(errno));
b5aea5e1 327 }
059ec3d9 328
b5aea5e1
PH
329 m.size = statbuf.st_size;
330 m.data = malloc(m.size);
331 if (m.data == NULL)
7199e1ee
TF
332 return tls_error(US"memory allocation failed", host, strerror(errno));
333 errno = 0;
b5aea5e1 334 if (read(fd, m.data, m.size) != m.size)
7199e1ee 335 return tls_error(US"TLS cache read failed", host, strerror(errno));
b5aea5e1
PH
336 (void)close(fd);
337
411ef850 338 ret = gnutls_dh_params_import_pkcs3(dh_params, &m, GNUTLS_X509_FMT_PEM);
7199e1ee
TF
339 if (ret < 0)
340 return tls_error(US"DH params import", host, gnutls_strerror(ret));
575643cd 341 DEBUG(D_tls) debug_printf("read D-H parameters from file\n");
b5aea5e1
PH
342
343 free(m.data);
344 }
345
346/* If the file does not exist, fall through to compute new data and cache it.
347If there was any other opening error, it is serious. */
348
182ad5cf
PH
349else if (errno == ENOENT)
350 {
351 ret = -1;
352 DEBUG(D_tls)
353 debug_printf("parameter cache file %s does not exist\n", filename);
354 }
355else
b5aea5e1 356 return tls_error(string_open_failed(errno, "%s for reading", filename),
7199e1ee 357 host, NULL);
b5aea5e1
PH
358
359/* If ret < 0, either the cache file does not exist, or the data it contains
360is not useful. One particular case of this is when upgrading from an older
361release of Exim in which the data was stored in a different format. We don't
362try to be clever and support both formats; we just regenerate new data in this
363case. */
364
365if (ret < 0)
366 {
367 uschar tempfilename[sizeof(filename) + 10];
059ec3d9 368
059ec3d9
PH
369 DEBUG(D_tls) debug_printf("generating %d bit Diffie-Hellman key...\n",
370 DH_BITS);
371 ret = gnutls_dh_params_generate2(dh_params, DH_BITS);
7199e1ee 372 if (ret < 0) return tls_error(US"D-H key generation", host, gnutls_strerror(ret));
059ec3d9
PH
373
374 /* Write the parameters to a file in the spool directory so that we
375 can use them from other Exim processes. */
376
377 sprintf(CS tempfilename, "%s-%d", filename, (int)getpid());
378 fd = Uopen(tempfilename, O_WRONLY|O_CREAT, 0400);
379 if (fd < 0)
380 return tls_error(string_open_failed(errno, "%s for writing", filename),
7199e1ee 381 host, NULL);
059ec3d9
PH
382 (void)fchown(fd, exim_uid, exim_gid); /* Probably not necessary */
383
b5aea5e1
PH
384 /* export the parameters in a format that can be generated using GNUTLS'
385 * certtool or other programs.
386 *
387 * The commands for certtool are:
411ef850 388 * $ certtool --generate-dh-params --bits 1024 > params
b5aea5e1
PH
389 */
390
391 m.size = PARAM_SIZE;
392 m.data = malloc(m.size);
393 if (m.data == NULL)
7199e1ee 394 return tls_error(US"memory allocation failed", host, strerror(errno));
b5aea5e1 395
b5aea5e1
PH
396 m.size = PARAM_SIZE;
397 ret = gnutls_dh_params_export_pkcs3(dh_params, GNUTLS_X509_FMT_PEM, m.data,
398 &m.size);
7199e1ee
TF
399 if (ret < 0)
400 return tls_error(US"DH params export", host, gnutls_strerror(ret));
059ec3d9 401
b5aea5e1 402 m.size = Ustrlen(m.data);
7199e1ee 403 errno = 0;
b5aea5e1 404 if (write(fd, m.data, m.size) != m.size || write(fd, "\n", 1) != 1)
7199e1ee 405 return tls_error(US"TLS cache write failed", host, strerror(errno));
059ec3d9 406
b5aea5e1 407 free(m.data);
059ec3d9
PH
408 (void)close(fd);
409
410 if (rename(CS tempfilename, CS filename) < 0)
7199e1ee
TF
411 return tls_error(string_sprintf("failed to rename %s as %s",
412 tempfilename, filename), host, strerror(errno));
059ec3d9 413
411ef850 414 DEBUG(D_tls) debug_printf("wrote D-H parameters to file %s\n", filename);
059ec3d9
PH
415 }
416
411ef850 417DEBUG(D_tls) debug_printf("initialized D-H parameters\n");
059ec3d9
PH
418return OK;
419}
420
421
422
423
424/*************************************************
425* Initialize for GnuTLS *
426*************************************************/
427
428/* Called from both server and client code. In the case of a server, errors
429before actual TLS negotiation return DEFER.
430
431Arguments:
432 host connected host, if client; NULL if server
433 certificate certificate file
434 privatekey private key file
435 cas CA certs file
436 crl CRL file
437
438Returns: OK/DEFER/FAIL
439*/
440
441static int
442tls_init(host_item *host, uschar *certificate, uschar *privatekey, uschar *cas,
443 uschar *crl)
444{
445int rc;
446uschar *cert_expanded, *key_expanded, *cas_expanded, *crl_expanded;
447
7199e1ee 448client_host = host;
059ec3d9
PH
449
450rc = gnutls_global_init();
7199e1ee 451if (rc < 0) return tls_error(US"tls-init", host, gnutls_strerror(rc));
059ec3d9 452
575643cd
PH
453/* Create D-H parameters, or read them from the cache file. This function does
454its own SMTP error messaging. */
059ec3d9 455
575643cd 456rc = init_dh(host);
059ec3d9
PH
457if (rc != OK) return rc;
458
459/* Create the credentials structure */
460
461rc = gnutls_certificate_allocate_credentials(&x509_cred);
7199e1ee
TF
462if (rc < 0)
463 return tls_error(US"certificate_allocate_credentials",
464 host, gnutls_strerror(rc));
059ec3d9
PH
465
466/* This stuff must be done for each session, because different certificates
467may be required for different sessions. */
468
469if (!expand_check(certificate, US"tls_certificate", &cert_expanded))
470 return DEFER;
471
c91535f3 472key_expanded = NULL;
059ec3d9
PH
473if (privatekey != NULL)
474 {
475 if (!expand_check(privatekey, US"tls_privatekey", &key_expanded))
476 return DEFER;
477 }
c91535f3
PH
478
479/* If expansion was forced to fail, key_expanded will be NULL. If the result of
480the expansion is an empty string, ignore it also, and assume that the private
481key is in the same file as the certificate. */
482
483if (key_expanded == NULL || *key_expanded == 0)
484 key_expanded = cert_expanded;
059ec3d9
PH
485
486/* Set the certificate and private keys */
487
488if (cert_expanded != NULL)
489 {
490 DEBUG(D_tls) debug_printf("certificate file = %s\nkey file = %s\n",
491 cert_expanded, key_expanded);
492 rc = gnutls_certificate_set_x509_key_file(x509_cred, CS cert_expanded,
493 CS key_expanded, GNUTLS_X509_FMT_PEM);
8e669ac1 494 if (rc < 0)
de365ded
PH
495 {
496 uschar *msg = string_sprintf("cert/key setup: cert=%s key=%s",
8e669ac1 497 cert_expanded, key_expanded);
7199e1ee 498 return tls_error(msg, host, gnutls_strerror(rc));
8e669ac1 499 }
059ec3d9
PH
500 }
501
502/* A certificate is mandatory in a server, but not in a client */
503
504else
505 {
506 if (host == NULL)
7199e1ee 507 return tls_error(US"no TLS server certificate is specified", NULL, NULL);
059ec3d9
PH
508 DEBUG(D_tls) debug_printf("no TLS client certificate is specified\n");
509 }
510
511/* Set the trusted CAs file if one is provided, and then add the CRL if one is
512provided. Experiment shows that, if the certificate file is empty, an unhelpful
513error message is provided. However, if we just refrain from setting anything up
514in that case, certificate verification fails, which seems to be the correct
515behaviour. */
516
517if (cas != NULL)
518 {
519 struct stat statbuf;
520
521 if (!expand_check(cas, US"tls_verify_certificates", &cas_expanded))
522 return DEFER;
523
524 if (stat(CS cas_expanded, &statbuf) < 0)
525 {
526 log_write(0, LOG_MAIN|LOG_PANIC, "could not stat %s "
527 "(tls_verify_certificates): %s", cas_expanded, strerror(errno));
528 return DEFER;
529 }
530
b1c749bb
PH
531 DEBUG(D_tls) debug_printf("verify certificates = %s size=" OFF_T_FMT "\n",
532 cas_expanded, statbuf.st_size);
059ec3d9
PH
533
534 /* If the cert file is empty, there's no point in loading the CRL file. */
535
536 if (statbuf.st_size > 0)
537 {
538 rc = gnutls_certificate_set_x509_trust_file(x509_cred, CS cas_expanded,
539 GNUTLS_X509_FMT_PEM);
7199e1ee 540 if (rc < 0) return tls_error(US"setup_certs", host, gnutls_strerror(rc));
059ec3d9
PH
541
542 if (crl != NULL && *crl != 0)
543 {
544 if (!expand_check(crl, US"tls_crl", &crl_expanded))
545 return DEFER;
546 DEBUG(D_tls) debug_printf("loading CRL file = %s\n", crl_expanded);
547 rc = gnutls_certificate_set_x509_crl_file(x509_cred, CS crl_expanded,
548 GNUTLS_X509_FMT_PEM);
7199e1ee 549 if (rc < 0) return tls_error(US"CRL setup", host, gnutls_strerror(rc));
059ec3d9
PH
550 }
551 }
552 }
553
554/* Associate the parameters with the x509 credentials structure. */
555
556gnutls_certificate_set_dh_params(x509_cred, dh_params);
059ec3d9
PH
557
558DEBUG(D_tls) debug_printf("initialized certificate stuff\n");
559return OK;
560}
561
562
563
564
565/*************************************************
83da1223 566* Remove from a priority list *
059ec3d9
PH
567*************************************************/
568
569/* Cautiously written so that it will remove duplicates if present.
570
571Arguments:
572 list a zero-terminated list
573 remove_list a zero-terminated list to be removed
574
575Returns: nothing
576*/
577
578static void
83da1223 579remove_priority(int *list, int *remove_list)
059ec3d9
PH
580{
581for (; *remove_list != 0; remove_list++)
582 {
583 int *p = list;
584 while (*p != 0)
585 {
586 if (*p == *remove_list)
587 {
588 int *pp = p;
589 do { pp[0] = pp[1]; pp++; } while (*pp != 0);
590 }
591 else p++;
592 }
593 }
594}
595
596
597
598/*************************************************
83da1223 599* Add to a priority list *
059ec3d9
PH
600*************************************************/
601
602/* Cautiously written to check the list size
603
604Arguments:
605 list a zero-terminated list
606 list_max maximum offset in the list
607 add_list a zero-terminated list to be added
608
609Returns: TRUE if OK; FALSE if list overflows
610*/
611
612static BOOL
83da1223 613add_priority(int *list, int list_max, int *add_list)
059ec3d9
PH
614{
615int next = 0;
616while (list[next] != 0) next++;
617while (*add_list != 0)
618 {
619 if (next >= list_max) return FALSE;
620 list[next++] = *add_list++;
621 }
622list[next] = 0;
623return TRUE;
624}
625
626
627
83da1223
PH
628/*************************************************
629* Adjust a priority list *
630*************************************************/
631
632/* This function is called to adjust the lists of cipher algorithms, MAC
633algorithms, key-exchange methods, and protocols.
634
635Arguments:
636 plist the appropriate priority list
637 psize the length of the list
638 s the configuation string
639 index the index of recognized strings
640 isize the length of the index
641
642
643 which text for an error message
644
645Returns: FALSE if the table overflows, else TRUE
646*/
647
648static BOOL
649set_priority(int *plist, int psize, uschar *s, pri_item *index, int isize,
650 uschar *which)
651{
652int sep = 0;
653BOOL first = TRUE;
654uschar *t;
655
656while ((t = string_nextinlist(&s, &sep, big_buffer, big_buffer_size)) != NULL)
657 {
658 int i;
659 BOOL exclude = t[0] == '!';
660 if (first && !exclude) plist[0] = 0;
661 first = FALSE;
662 for (i = 0; i < isize; i++)
663 {
664 uschar *ss = strstric(t, index[i].name, FALSE);
665 if (ss != NULL)
666 {
667 uschar *endss = ss + Ustrlen(index[i].name);
668 if ((ss == t || !isalnum(ss[-1])) && !isalnum(*endss))
669 {
670 if (exclude)
671 remove_priority(plist, index[i].values);
672 else
673 {
674 if (!add_priority(plist, psize, index[i].values))
675 {
676 log_write(0, LOG_MAIN|LOG_PANIC, "GnuTLS init failed: %s "
677 "priority table overflow", which);
678 return FALSE;
679 }
680 }
681 }
682 }
683 }
684 }
685
686DEBUG(D_tls)
687 {
688 int *ptr = plist;
689 debug_printf("adjusted %s priorities:", which);
690 while (*ptr != 0) debug_printf(" %d", *ptr++);
691 debug_printf("\n");
692 }
693
694return TRUE;
695}
696
697
698
699
059ec3d9
PH
700/*************************************************
701* Initialize a single GNUTLS session *
702*************************************************/
703
704/* Set the algorithm, the db backend, whether to request certificates etc.
705
706TLS in Exim was first implemented using OpenSSL. This has a function to which
707you pass a list of cipher suites that are permitted/not permitted. GnuTLS works
708differently. It operates using priority lists for the different components of
709cipher suites.
710
711For compatibility of configuration, we scan a list of cipher suites and set
712priorities therefrom. However, at the moment, we pay attention only to the bulk
713cipher.
714
715Arguments:
716 side one of GNUTLS_SERVER, GNUTLS_CLIENT
83da1223
PH
717 expciphers expanded ciphers list or NULL
718 expmac expanded MAC list or NULL
719 expkx expanded key-exchange list or NULL
720 expproto expanded protocol list or NULL
059ec3d9
PH
721
722Returns: a gnutls_session, or NULL if there is a problem
723*/
724
725static gnutls_session
83da1223
PH
726tls_session_init(int side, uschar *expciphers, uschar *expmac, uschar *expkx,
727 uschar *expproto)
059ec3d9
PH
728{
729gnutls_session session;
730
731gnutls_init(&session, side);
732
83da1223
PH
733/* Initialize the lists of permitted protocols, key-exchange methods, ciphers,
734and MACs. */
059ec3d9
PH
735
736memcpy(cipher_priority, default_cipher_priority, sizeof(cipher_priority));
83da1223
PH
737memcpy(mac_priority, default_mac_priority, sizeof(mac_priority));
738memcpy(kx_priority, default_kx_priority, sizeof(kx_priority));
739memcpy(proto_priority, default_proto_priority, sizeof(proto_priority));
740
741/* The names OpenSSL uses in tls_require_ciphers are of the form DES-CBC3-SHA,
742using hyphen separators. GnuTLS uses underscore separators. So that I can use
743either form for tls_require_ciphers in my tests, and also for general
744convenience, we turn hyphens into underscores before scanning the list. */
059ec3d9
PH
745
746if (expciphers != NULL)
747 {
059ec3d9
PH
748 uschar *s = expciphers;
749 while (*s != 0) { if (*s == '-') *s = '_'; s++; }
83da1223 750 }
059ec3d9 751
83da1223
PH
752if ((expciphers != NULL &&
753 !set_priority(cipher_priority, sizeof(cipher_priority)/sizeof(int),
754 expciphers, cipher_index, sizeof(cipher_index)/sizeof(pri_item),
755 US"cipher")) ||
756 (expmac != NULL &&
757 !set_priority(mac_priority, sizeof(mac_priority)/sizeof(int),
758 expmac, mac_index, sizeof(mac_index)/sizeof(pri_item),
759 US"MAC")) ||
760 (expkx != NULL &&
761 !set_priority(kx_priority, sizeof(kx_priority)/sizeof(int),
762 expkx, kx_index, sizeof(kx_index)/sizeof(pri_item),
763 US"key-exchange")) ||
764 (expproto != NULL &&
765 !set_priority(proto_priority, sizeof(proto_priority)/sizeof(int),
766 expproto, proto_index, sizeof(proto_index)/sizeof(pri_item),
767 US"protocol")))
768 {
769 gnutls_deinit(session);
770 return NULL;
059ec3d9
PH
771 }
772
773/* Define the various priorities */
774
775gnutls_cipher_set_priority(session, cipher_priority);
776gnutls_compression_set_priority(session, comp_priority);
777gnutls_kx_set_priority(session, kx_priority);
83da1223 778gnutls_protocol_set_priority(session, proto_priority);
059ec3d9
PH
779gnutls_mac_set_priority(session, mac_priority);
780
781gnutls_cred_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
782
783gnutls_dh_set_prime_bits(session, DH_BITS);
784
785/* Request or demand a certificate of the peer, as configured. This will
786happen only in a server. */
787
788if (verify_requirement != VERIFY_NONE)
789 gnutls_certificate_server_set_request(session,
790 (verify_requirement == VERIFY_OPTIONAL)?
791 GNUTLS_CERT_REQUEST : GNUTLS_CERT_REQUIRE);
792
793gnutls_db_set_cache_expiration(session, ssl_session_timeout);
794
795DEBUG(D_tls) debug_printf("initialized GnuTLS session\n");
796return session;
797}
798
799
800
801/*************************************************
802* Get name of cipher in use *
803*************************************************/
804
805/* The answer is left in a static buffer, and tls_cipher is set to point
806to it.
807
808Argument: pointer to a GnuTLS session
809Returns: nothing
810*/
811
812static void
813construct_cipher_name(gnutls_session session)
814{
815static uschar cipherbuf[256];
816uschar *ver;
817int bits, c, kx, mac;
818
819ver = string_copy(
820 US gnutls_protocol_get_name(gnutls_protocol_get_version(session)));
821if (Ustrncmp(ver, "TLS ", 4) == 0) ver[3] = '-'; /* Don't want space */
822
823c = gnutls_cipher_get(session);
824bits = gnutls_cipher_get_key_size(c);
825
826mac = gnutls_mac_get(session);
827kx = gnutls_kx_get(session);
828
829string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
830 gnutls_cipher_suite_get_name(kx, c, mac), bits);
831tls_cipher = cipherbuf;
832
833DEBUG(D_tls) debug_printf("cipher: %s\n", cipherbuf);
834}
835
836
837
838/*************************************************
839* Start a TLS session in a server *
840*************************************************/
841
842/* This is called when Exim is running as a server, after having received
843the STARTTLS command. It must respond to that command, and then negotiate
844a TLS session.
845
846Arguments:
83da1223
PH
847 require_ciphers list of allowed ciphers or NULL
848 require_mac list of allowed MACs or NULL
849 require_kx list of allowed key_exchange methods or NULL
850 require_proto list of allowed protocols or NULL
059ec3d9
PH
851
852Returns: OK on success
853 DEFER for errors before the start of the negotiation
854 FAIL for errors during the negotation; the server can't
855 continue running.
856*/
857
858int
83da1223
PH
859tls_server_start(uschar *require_ciphers, uschar *require_mac,
860 uschar *require_kx, uschar *require_proto)
059ec3d9
PH
861{
862int rc;
7199e1ee 863const char *error;
059ec3d9 864uschar *expciphers = NULL;
83da1223
PH
865uschar *expmac = NULL;
866uschar *expkx = NULL;
867uschar *expproto = NULL;
059ec3d9
PH
868
869/* Check for previous activation */
870
871if (tls_active >= 0)
872 {
7199e1ee 873 tls_error("STARTTLS received after TLS started", NULL, "");
059ec3d9
PH
874 smtp_printf("554 Already in TLS\r\n");
875 return FAIL;
876 }
877
878/* Initialize the library. If it fails, it will already have logged the error
879and sent an SMTP response. */
880
881DEBUG(D_tls) debug_printf("initializing GnuTLS as a server\n");
882
883rc = tls_init(NULL, tls_certificate, tls_privatekey, tls_verify_certificates,
884 tls_crl);
885if (rc != OK) return rc;
886
83da1223
PH
887if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers) ||
888 !expand_check(require_mac, US"gnutls_require_mac", &expmac) ||
889 !expand_check(require_kx, US"gnutls_require_kx", &expkx) ||
890 !expand_check(require_proto, US"gnutls_require_proto", &expproto))
059ec3d9
PH
891 return FAIL;
892
893/* If this is a host for which certificate verification is mandatory or
894optional, set up appropriately. */
895
896tls_certificate_verified = FALSE;
897verify_requirement = VERIFY_NONE;
898
899if (verify_check_host(&tls_verify_hosts) == OK)
900 verify_requirement = VERIFY_REQUIRED;
901else if (verify_check_host(&tls_try_verify_hosts) == OK)
902 verify_requirement = VERIFY_OPTIONAL;
903
904/* Prepare for new connection */
905
83da1223
PH
906tls_session = tls_session_init(GNUTLS_SERVER, expciphers, expmac, expkx,
907 expproto);
059ec3d9 908if (tls_session == NULL)
7199e1ee
TF
909 return tls_error(US"tls_session_init", NULL,
910 gnutls_strerror(GNUTLS_E_MEMORY_ERROR));
059ec3d9
PH
911
912/* Set context and tell client to go ahead, except in the case of TLS startup
913on connection, where outputting anything now upsets the clients and tends to
914make them disconnect. We need to have an explicit fflush() here, to force out
915the response. Other smtp_printf() calls do not need it, because in non-TLS
916mode, the fflush() happens when smtp_getc() is called. */
917
918if (!tls_on_connect)
919 {
920 smtp_printf("220 TLS go ahead\r\n");
921 fflush(smtp_out);
922 }
923
924/* Now negotiate the TLS session. We put our own timer on it, since it seems
925that the GnuTLS library doesn't. */
926
56f5d9bd
PH
927gnutls_transport_set_ptr2(tls_session, (gnutls_transport_ptr)fileno(smtp_in),
928 (gnutls_transport_ptr)fileno(smtp_out));
059ec3d9
PH
929
930sigalrm_seen = FALSE;
931if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
932rc = gnutls_handshake(tls_session);
933alarm(0);
934
935if (rc < 0)
936 {
7199e1ee
TF
937 tls_error(US"gnutls_handshake", NULL,
938 sigalrm_seen ? "timed out" : gnutls_strerror(rc));
059ec3d9
PH
939
940 /* It seems that, except in the case of a timeout, we have to close the
941 connection right here; otherwise if the other end is running OpenSSL it hangs
942 until the server times out. */
943
944 if (!sigalrm_seen)
945 {
f1e894f3
PH
946 (void)fclose(smtp_out);
947 (void)fclose(smtp_in);
059ec3d9
PH
948 }
949
950 return FAIL;
951 }
952
953DEBUG(D_tls) debug_printf("gnutls_handshake was successful\n");
954
955if (verify_requirement != VERIFY_NONE &&
956 !verify_certificate(tls_session, &error))
957 {
7199e1ee 958 tls_error(US"certificate verification failed", NULL, error);
059ec3d9
PH
959 return FAIL;
960 }
961
962construct_cipher_name(tls_session);
963
964/* TLS has been set up. Adjust the input functions to read via TLS,
965and initialize appropriately. */
966
967ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
968ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
969ssl_xfer_eof = ssl_xfer_error = 0;
970
971receive_getc = tls_getc;
972receive_ungetc = tls_ungetc;
973receive_feof = tls_feof;
974receive_ferror = tls_ferror;
58eb016e 975receive_smtp_buffered = tls_smtp_buffered;
059ec3d9
PH
976
977tls_active = fileno(smtp_out);
978
979return OK;
980}
981
982
983
984
985/*************************************************
986* Start a TLS session in a client *
987*************************************************/
988
989/* Called from the smtp transport after STARTTLS has been accepted.
990
991Arguments:
992 fd the fd of the connection
993 host connected host (for messages)
83da1223 994 addr the first address (not used)
059ec3d9
PH
995 dhparam DH parameter file
996 certificate certificate file
997 privatekey private key file
998 verify_certs file for certificate verify
999 verify_crl CRL for verify
83da1223
PH
1000 require_ciphers list of allowed ciphers or NULL
1001 require_mac list of allowed MACs or NULL
1002 require_kx list of allowed key_exchange methods or NULL
1003 require_proto list of allowed protocols or NULL
059ec3d9
PH
1004 timeout startup timeout
1005
1006Returns: OK/DEFER/FAIL (because using common functions),
1007 but for a client, DEFER and FAIL have the same meaning
1008*/
1009
1010int
1011tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
1012 uschar *certificate, uschar *privatekey, uschar *verify_certs,
83da1223
PH
1013 uschar *verify_crl, uschar *require_ciphers, uschar *require_mac,
1014 uschar *require_kx, uschar *require_proto, int timeout)
059ec3d9
PH
1015{
1016const gnutls_datum *server_certs;
1017uschar *expciphers = NULL;
83da1223
PH
1018uschar *expmac = NULL;
1019uschar *expkx = NULL;
1020uschar *expproto = NULL;
7199e1ee 1021const char *error;
059ec3d9
PH
1022unsigned int server_certs_size;
1023int rc;
1024
1025DEBUG(D_tls) debug_printf("initializing GnuTLS as a client\n");
1026
059ec3d9
PH
1027verify_requirement = (verify_certs == NULL)? VERIFY_NONE : VERIFY_REQUIRED;
1028rc = tls_init(host, certificate, privatekey, verify_certs, verify_crl);
1029if (rc != OK) return rc;
1030
83da1223
PH
1031if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers) ||
1032 !expand_check(require_mac, US"gnutls_require_mac", &expmac) ||
1033 !expand_check(require_kx, US"gnutls_require_kx", &expkx) ||
1034 !expand_check(require_proto, US"gnutls_require_proto", &expproto))
059ec3d9
PH
1035 return FAIL;
1036
83da1223
PH
1037tls_session = tls_session_init(GNUTLS_CLIENT, expciphers, expmac, expkx,
1038 expproto);
1039
059ec3d9 1040if (tls_session == NULL)
7199e1ee
TF
1041 return tls_error(US "tls_session_init", host,
1042 gnutls_strerror(GNUTLS_E_MEMORY_ERROR));
059ec3d9
PH
1043
1044gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr)fd);
1045
1046/* There doesn't seem to be a built-in timeout on connection. */
1047
1048sigalrm_seen = FALSE;
1049alarm(timeout);
1050rc = gnutls_handshake(tls_session);
1051alarm(0);
1052
1053if (rc < 0)
7199e1ee
TF
1054 return tls_error(US "gnutls_handshake", host,
1055 sigalrm_seen ? "timed out" : gnutls_strerror(rc));
059ec3d9
PH
1056
1057server_certs = gnutls_certificate_get_peers(tls_session, &server_certs_size);
1058
1059if (server_certs != NULL)
1060 {
1061 uschar buff[1024];
1062 gnutls_x509_crt gcert;
1063
1064 gnutls_x509_crt_init(&gcert);
1065 tls_peerdn = US"unknown";
1066
1067 if (gnutls_x509_crt_import(gcert, server_certs, GNUTLS_X509_FMT_DER) == 0)
1068 {
1069 size_t bufsize = sizeof(buff);
1070 if (gnutls_x509_crt_get_dn(gcert, CS buff, &bufsize) >= 0)
1071 tls_peerdn = string_copy_malloc(buff);
1072 }
1073 }
1074
1075/* Should we also verify the hostname here? */
1076
1077if (verify_requirement != VERIFY_NONE &&
1078 !verify_certificate(tls_session, &error))
7199e1ee 1079 return tls_error(US"certificate verification failed", host, error);
059ec3d9
PH
1080
1081construct_cipher_name(tls_session); /* Sets tls_cipher */
1082tls_active = fd;
1083return OK;
1084}
1085
1086
1087
1088/*************************************************
1089* Deal with logging errors during I/O *
1090*************************************************/
1091
1092/* We have to get the identity of the peer from saved data.
1093
1094Argument:
1095 ec the GnuTLS error code, or 0 if it's a local error
1096 when text identifying read or write
1097 text local error text when ec is 0
1098
1099Returns: nothing
1100*/
1101
1102static void
1103record_io_error(int ec, uschar *when, uschar *text)
1104{
7199e1ee 1105const char *msg;
059ec3d9
PH
1106
1107if (ec == GNUTLS_E_FATAL_ALERT_RECEIVED)
7199e1ee 1108 msg = string_sprintf("%s: %s", gnutls_strerror(ec),
059ec3d9 1109 gnutls_alert_get_name(gnutls_alert_get(tls_session)));
059ec3d9 1110else
7199e1ee
TF
1111 msg = gnutls_strerror(ec);
1112
1113tls_error(when, client_host, msg);
059ec3d9
PH
1114}
1115
1116
1117
1118/*************************************************
1119* TLS version of getc *
1120*************************************************/
1121
1122/* This gets the next byte from the TLS input buffer. If the buffer is empty,
1123it refills the buffer via the GnuTLS reading function.
1124
1125Arguments: none
1126Returns: the next character or EOF
1127*/
1128
1129int
1130tls_getc(void)
1131{
1132if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
1133 {
1134 int inbytes;
1135
1136 DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1137 (long) tls_session, (long) ssl_xfer_buffer, ssl_xfer_buffer_size);
1138
1139 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
1140 inbytes = gnutls_record_recv(tls_session, CS ssl_xfer_buffer,
1141 ssl_xfer_buffer_size);
1142 alarm(0);
1143
1144 /* A zero-byte return appears to mean that the TLS session has been
1145 closed down, not that the socket itself has been closed down. Revert to
1146 non-TLS handling. */
1147
1148 if (inbytes == 0)
1149 {
1150 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1151
1152 receive_getc = smtp_getc;
1153 receive_ungetc = smtp_ungetc;
1154 receive_feof = smtp_feof;
1155 receive_ferror = smtp_ferror;
58eb016e 1156 receive_smtp_buffered = smtp_buffered;
059ec3d9
PH
1157
1158 gnutls_deinit(tls_session);
1159 tls_session = NULL;
1160 tls_active = -1;
1161 tls_cipher = NULL;
1162 tls_peerdn = NULL;
1163
1164 return smtp_getc();
1165 }
1166
1167 /* Handle genuine errors */
1168
1169 else if (inbytes < 0)
1170 {
1171 record_io_error(inbytes, US"recv", NULL);
1172 ssl_xfer_error = 1;
1173 return EOF;
1174 }
80a47a2c
TK
1175#ifndef DISABLE_DKIM
1176 dkim_exim_verify_feed(ssl_xfer_buffer, inbytes);
1177#endif
059ec3d9
PH
1178 ssl_xfer_buffer_hwm = inbytes;
1179 ssl_xfer_buffer_lwm = 0;
1180 }
1181
1182
1183/* Something in the buffer; return next uschar */
1184
1185return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
1186}
1187
1188
1189
1190/*************************************************
1191* Read bytes from TLS channel *
1192*************************************************/
1193
1194/*
1195Arguments:
1196 buff buffer of data
1197 len size of buffer
1198
1199Returns: the number of bytes read
1200 -1 after a failed read
1201*/
1202
1203int
1204tls_read(uschar *buff, size_t len)
1205{
1206int inbytes;
1207
1208DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1209 (long) tls_session, (long) buff, len);
1210
1211inbytes = gnutls_record_recv(tls_session, CS buff, len);
1212if (inbytes > 0) return inbytes;
1213if (inbytes == 0)
1214 {
1215 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1216 }
1217else record_io_error(inbytes, US"recv", NULL);
1218
1219return -1;
1220}
1221
1222
1223
1224/*************************************************
1225* Write bytes down TLS channel *
1226*************************************************/
1227
1228/*
1229Arguments:
1230 buff buffer of data
1231 len number of bytes
1232
1233Returns: the number of bytes after a successful write,
1234 -1 after a failed write
1235*/
1236
1237int
1238tls_write(const uschar *buff, size_t len)
1239{
1240int outbytes;
1241int left = len;
1242
1243DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long) buff, left);
1244while (left > 0)
1245 {
1246 DEBUG(D_tls) debug_printf("gnutls_record_send(SSL, %lx, %d)\n", (long)buff,
1247 left);
1248 outbytes = gnutls_record_send(tls_session, CS buff, left);
1249
1250 DEBUG(D_tls) debug_printf("outbytes=%d\n", outbytes);
1251 if (outbytes < 0)
1252 {
1253 record_io_error(outbytes, US"send", NULL);
1254 return -1;
1255 }
1256 if (outbytes == 0)
1257 {
1258 record_io_error(0, US"send", US"TLS channel closed on write");
1259 return -1;
1260 }
1261
1262 left -= outbytes;
1263 buff += outbytes;
1264 }
1265
1266return len;
1267}
1268
1269
1270
1271/*************************************************
1272* Close down a TLS session *
1273*************************************************/
1274
1275/* This is also called from within a delivery subprocess forked from the
1276daemon, to shut down the TLS library, without actually doing a shutdown (which
1277would tamper with the TLS session in the parent process).
1278
1279Arguments: TRUE if gnutls_bye is to be called
1280Returns: nothing
1281*/
1282
1283void
1284tls_close(BOOL shutdown)
1285{
1286if (tls_active < 0) return; /* TLS was not active */
1287
1288if (shutdown)
1289 {
1290 DEBUG(D_tls) debug_printf("tls_close(): shutting down TLS\n");
1291 gnutls_bye(tls_session, GNUTLS_SHUT_WR);
1292 }
1293
1294gnutls_deinit(tls_session);
1295tls_session = NULL;
1296gnutls_global_deinit();
1297
1298tls_active = -1;
1299}
1300
36f12725
NM
1301
1302
1303
1304/*************************************************
1305* Report the library versions. *
1306*************************************************/
1307
1308/* See a description in tls-openssl.c for an explanation of why this exists.
1309
1310Arguments: a FILE* to print the results to
1311Returns: nothing
1312*/
1313
1314void
1315tls_version_report(FILE *f)
1316{
1317fprintf(f, "GnuTLS compile-time version: %s\n", LIBGNUTLS_VERSION);
1318fprintf(f, "GnuTLS runtime version: %s\n", gnutls_check_version(NULL));
1319}
1320
059ec3d9 1321/* End of tls-gnu.c */