Update all copyright messages to cover 1995 - 2009. Remove tab from exim_checkaccess.src
[exim.git] / src / src / tls-gnu.c
CommitLineData
0a49a7a4 1/* $Cambridge: exim/src/src/tls-gnu.c,v 1.24 2009/11/16 19:50:37 nm4 Exp $ */
059ec3d9
PH
2
3/*************************************************
4* Exim - an Internet mail transport agent *
5*************************************************/
6
0a49a7a4 7/* Copyright (c) University of Cambridge 1995 - 2009 */
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
e6060e2c
NM
795/* Reduce security in favour of increased compatibility, if the admin
796decides to make that trade-off. */
797if (gnutls_compat_mode)
798 {
799#if LIBGNUTLS_VERSION_NUMBER >= 0x020104
800 DEBUG(D_tls) debug_printf("lowering GnuTLS security, compatibility mode\n");
801 gnutls_session_enable_compatibility_mode(session);
802#else
803 DEBUG(D_tls) debug_printf("Unable to set gnutls_compat_mode - GnuTLS version too old\n");
804#endif
805 }
806
059ec3d9
PH
807DEBUG(D_tls) debug_printf("initialized GnuTLS session\n");
808return session;
809}
810
811
812
813/*************************************************
814* Get name of cipher in use *
815*************************************************/
816
817/* The answer is left in a static buffer, and tls_cipher is set to point
818to it.
819
820Argument: pointer to a GnuTLS session
821Returns: nothing
822*/
823
824static void
825construct_cipher_name(gnutls_session session)
826{
827static uschar cipherbuf[256];
828uschar *ver;
829int bits, c, kx, mac;
830
831ver = string_copy(
832 US gnutls_protocol_get_name(gnutls_protocol_get_version(session)));
833if (Ustrncmp(ver, "TLS ", 4) == 0) ver[3] = '-'; /* Don't want space */
834
835c = gnutls_cipher_get(session);
836bits = gnutls_cipher_get_key_size(c);
837
838mac = gnutls_mac_get(session);
839kx = gnutls_kx_get(session);
840
841string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
842 gnutls_cipher_suite_get_name(kx, c, mac), bits);
843tls_cipher = cipherbuf;
844
845DEBUG(D_tls) debug_printf("cipher: %s\n", cipherbuf);
846}
847
848
849
850/*************************************************
851* Start a TLS session in a server *
852*************************************************/
853
854/* This is called when Exim is running as a server, after having received
855the STARTTLS command. It must respond to that command, and then negotiate
856a TLS session.
857
858Arguments:
83da1223
PH
859 require_ciphers list of allowed ciphers or NULL
860 require_mac list of allowed MACs or NULL
861 require_kx list of allowed key_exchange methods or NULL
862 require_proto list of allowed protocols or NULL
059ec3d9
PH
863
864Returns: OK on success
865 DEFER for errors before the start of the negotiation
866 FAIL for errors during the negotation; the server can't
867 continue running.
868*/
869
870int
83da1223
PH
871tls_server_start(uschar *require_ciphers, uschar *require_mac,
872 uschar *require_kx, uschar *require_proto)
059ec3d9
PH
873{
874int rc;
7199e1ee 875const char *error;
059ec3d9 876uschar *expciphers = NULL;
83da1223
PH
877uschar *expmac = NULL;
878uschar *expkx = NULL;
879uschar *expproto = NULL;
059ec3d9
PH
880
881/* Check for previous activation */
882
883if (tls_active >= 0)
884 {
7199e1ee 885 tls_error("STARTTLS received after TLS started", NULL, "");
059ec3d9
PH
886 smtp_printf("554 Already in TLS\r\n");
887 return FAIL;
888 }
889
890/* Initialize the library. If it fails, it will already have logged the error
891and sent an SMTP response. */
892
893DEBUG(D_tls) debug_printf("initializing GnuTLS as a server\n");
894
895rc = tls_init(NULL, tls_certificate, tls_privatekey, tls_verify_certificates,
896 tls_crl);
897if (rc != OK) return rc;
898
83da1223
PH
899if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers) ||
900 !expand_check(require_mac, US"gnutls_require_mac", &expmac) ||
901 !expand_check(require_kx, US"gnutls_require_kx", &expkx) ||
902 !expand_check(require_proto, US"gnutls_require_proto", &expproto))
059ec3d9
PH
903 return FAIL;
904
905/* If this is a host for which certificate verification is mandatory or
906optional, set up appropriately. */
907
908tls_certificate_verified = FALSE;
909verify_requirement = VERIFY_NONE;
910
911if (verify_check_host(&tls_verify_hosts) == OK)
912 verify_requirement = VERIFY_REQUIRED;
913else if (verify_check_host(&tls_try_verify_hosts) == OK)
914 verify_requirement = VERIFY_OPTIONAL;
915
916/* Prepare for new connection */
917
83da1223
PH
918tls_session = tls_session_init(GNUTLS_SERVER, expciphers, expmac, expkx,
919 expproto);
059ec3d9 920if (tls_session == NULL)
7199e1ee
TF
921 return tls_error(US"tls_session_init", NULL,
922 gnutls_strerror(GNUTLS_E_MEMORY_ERROR));
059ec3d9
PH
923
924/* Set context and tell client to go ahead, except in the case of TLS startup
925on connection, where outputting anything now upsets the clients and tends to
926make them disconnect. We need to have an explicit fflush() here, to force out
927the response. Other smtp_printf() calls do not need it, because in non-TLS
928mode, the fflush() happens when smtp_getc() is called. */
929
930if (!tls_on_connect)
931 {
932 smtp_printf("220 TLS go ahead\r\n");
933 fflush(smtp_out);
934 }
935
936/* Now negotiate the TLS session. We put our own timer on it, since it seems
937that the GnuTLS library doesn't. */
938
56f5d9bd
PH
939gnutls_transport_set_ptr2(tls_session, (gnutls_transport_ptr)fileno(smtp_in),
940 (gnutls_transport_ptr)fileno(smtp_out));
059ec3d9
PH
941
942sigalrm_seen = FALSE;
943if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
944rc = gnutls_handshake(tls_session);
945alarm(0);
946
947if (rc < 0)
948 {
7199e1ee
TF
949 tls_error(US"gnutls_handshake", NULL,
950 sigalrm_seen ? "timed out" : gnutls_strerror(rc));
059ec3d9
PH
951
952 /* It seems that, except in the case of a timeout, we have to close the
953 connection right here; otherwise if the other end is running OpenSSL it hangs
954 until the server times out. */
955
956 if (!sigalrm_seen)
957 {
f1e894f3
PH
958 (void)fclose(smtp_out);
959 (void)fclose(smtp_in);
059ec3d9
PH
960 }
961
962 return FAIL;
963 }
964
965DEBUG(D_tls) debug_printf("gnutls_handshake was successful\n");
966
967if (verify_requirement != VERIFY_NONE &&
968 !verify_certificate(tls_session, &error))
969 {
7199e1ee 970 tls_error(US"certificate verification failed", NULL, error);
059ec3d9
PH
971 return FAIL;
972 }
973
974construct_cipher_name(tls_session);
975
976/* TLS has been set up. Adjust the input functions to read via TLS,
977and initialize appropriately. */
978
979ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
980ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
981ssl_xfer_eof = ssl_xfer_error = 0;
982
983receive_getc = tls_getc;
984receive_ungetc = tls_ungetc;
985receive_feof = tls_feof;
986receive_ferror = tls_ferror;
58eb016e 987receive_smtp_buffered = tls_smtp_buffered;
059ec3d9
PH
988
989tls_active = fileno(smtp_out);
990
991return OK;
992}
993
994
995
996
997/*************************************************
998* Start a TLS session in a client *
999*************************************************/
1000
1001/* Called from the smtp transport after STARTTLS has been accepted.
1002
1003Arguments:
1004 fd the fd of the connection
1005 host connected host (for messages)
83da1223 1006 addr the first address (not used)
059ec3d9
PH
1007 dhparam DH parameter file
1008 certificate certificate file
1009 privatekey private key file
1010 verify_certs file for certificate verify
1011 verify_crl CRL for verify
83da1223
PH
1012 require_ciphers list of allowed ciphers or NULL
1013 require_mac list of allowed MACs or NULL
1014 require_kx list of allowed key_exchange methods or NULL
1015 require_proto list of allowed protocols or NULL
059ec3d9
PH
1016 timeout startup timeout
1017
1018Returns: OK/DEFER/FAIL (because using common functions),
1019 but for a client, DEFER and FAIL have the same meaning
1020*/
1021
1022int
1023tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
1024 uschar *certificate, uschar *privatekey, uschar *verify_certs,
83da1223
PH
1025 uschar *verify_crl, uschar *require_ciphers, uschar *require_mac,
1026 uschar *require_kx, uschar *require_proto, int timeout)
059ec3d9
PH
1027{
1028const gnutls_datum *server_certs;
1029uschar *expciphers = NULL;
83da1223
PH
1030uschar *expmac = NULL;
1031uschar *expkx = NULL;
1032uschar *expproto = NULL;
7199e1ee 1033const char *error;
059ec3d9
PH
1034unsigned int server_certs_size;
1035int rc;
1036
1037DEBUG(D_tls) debug_printf("initializing GnuTLS as a client\n");
1038
059ec3d9
PH
1039verify_requirement = (verify_certs == NULL)? VERIFY_NONE : VERIFY_REQUIRED;
1040rc = tls_init(host, certificate, privatekey, verify_certs, verify_crl);
1041if (rc != OK) return rc;
1042
83da1223
PH
1043if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers) ||
1044 !expand_check(require_mac, US"gnutls_require_mac", &expmac) ||
1045 !expand_check(require_kx, US"gnutls_require_kx", &expkx) ||
1046 !expand_check(require_proto, US"gnutls_require_proto", &expproto))
059ec3d9
PH
1047 return FAIL;
1048
83da1223
PH
1049tls_session = tls_session_init(GNUTLS_CLIENT, expciphers, expmac, expkx,
1050 expproto);
1051
059ec3d9 1052if (tls_session == NULL)
7199e1ee
TF
1053 return tls_error(US "tls_session_init", host,
1054 gnutls_strerror(GNUTLS_E_MEMORY_ERROR));
059ec3d9
PH
1055
1056gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr)fd);
1057
1058/* There doesn't seem to be a built-in timeout on connection. */
1059
1060sigalrm_seen = FALSE;
1061alarm(timeout);
1062rc = gnutls_handshake(tls_session);
1063alarm(0);
1064
1065if (rc < 0)
7199e1ee
TF
1066 return tls_error(US "gnutls_handshake", host,
1067 sigalrm_seen ? "timed out" : gnutls_strerror(rc));
059ec3d9
PH
1068
1069server_certs = gnutls_certificate_get_peers(tls_session, &server_certs_size);
1070
1071if (server_certs != NULL)
1072 {
1073 uschar buff[1024];
1074 gnutls_x509_crt gcert;
1075
1076 gnutls_x509_crt_init(&gcert);
1077 tls_peerdn = US"unknown";
1078
1079 if (gnutls_x509_crt_import(gcert, server_certs, GNUTLS_X509_FMT_DER) == 0)
1080 {
1081 size_t bufsize = sizeof(buff);
1082 if (gnutls_x509_crt_get_dn(gcert, CS buff, &bufsize) >= 0)
1083 tls_peerdn = string_copy_malloc(buff);
1084 }
1085 }
1086
1087/* Should we also verify the hostname here? */
1088
1089if (verify_requirement != VERIFY_NONE &&
1090 !verify_certificate(tls_session, &error))
7199e1ee 1091 return tls_error(US"certificate verification failed", host, error);
059ec3d9
PH
1092
1093construct_cipher_name(tls_session); /* Sets tls_cipher */
1094tls_active = fd;
1095return OK;
1096}
1097
1098
1099
1100/*************************************************
1101* Deal with logging errors during I/O *
1102*************************************************/
1103
1104/* We have to get the identity of the peer from saved data.
1105
1106Argument:
1107 ec the GnuTLS error code, or 0 if it's a local error
1108 when text identifying read or write
1109 text local error text when ec is 0
1110
1111Returns: nothing
1112*/
1113
1114static void
1115record_io_error(int ec, uschar *when, uschar *text)
1116{
7199e1ee 1117const char *msg;
059ec3d9
PH
1118
1119if (ec == GNUTLS_E_FATAL_ALERT_RECEIVED)
7199e1ee 1120 msg = string_sprintf("%s: %s", gnutls_strerror(ec),
059ec3d9 1121 gnutls_alert_get_name(gnutls_alert_get(tls_session)));
059ec3d9 1122else
7199e1ee
TF
1123 msg = gnutls_strerror(ec);
1124
1125tls_error(when, client_host, msg);
059ec3d9
PH
1126}
1127
1128
1129
1130/*************************************************
1131* TLS version of getc *
1132*************************************************/
1133
1134/* This gets the next byte from the TLS input buffer. If the buffer is empty,
1135it refills the buffer via the GnuTLS reading function.
1136
1137Arguments: none
1138Returns: the next character or EOF
1139*/
1140
1141int
1142tls_getc(void)
1143{
1144if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
1145 {
1146 int inbytes;
1147
1148 DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1149 (long) tls_session, (long) ssl_xfer_buffer, ssl_xfer_buffer_size);
1150
1151 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
1152 inbytes = gnutls_record_recv(tls_session, CS ssl_xfer_buffer,
1153 ssl_xfer_buffer_size);
1154 alarm(0);
1155
1156 /* A zero-byte return appears to mean that the TLS session has been
1157 closed down, not that the socket itself has been closed down. Revert to
1158 non-TLS handling. */
1159
1160 if (inbytes == 0)
1161 {
1162 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1163
1164 receive_getc = smtp_getc;
1165 receive_ungetc = smtp_ungetc;
1166 receive_feof = smtp_feof;
1167 receive_ferror = smtp_ferror;
58eb016e 1168 receive_smtp_buffered = smtp_buffered;
059ec3d9
PH
1169
1170 gnutls_deinit(tls_session);
1171 tls_session = NULL;
1172 tls_active = -1;
1173 tls_cipher = NULL;
1174 tls_peerdn = NULL;
1175
1176 return smtp_getc();
1177 }
1178
1179 /* Handle genuine errors */
1180
1181 else if (inbytes < 0)
1182 {
1183 record_io_error(inbytes, US"recv", NULL);
1184 ssl_xfer_error = 1;
1185 return EOF;
1186 }
80a47a2c
TK
1187#ifndef DISABLE_DKIM
1188 dkim_exim_verify_feed(ssl_xfer_buffer, inbytes);
1189#endif
059ec3d9
PH
1190 ssl_xfer_buffer_hwm = inbytes;
1191 ssl_xfer_buffer_lwm = 0;
1192 }
1193
1194
1195/* Something in the buffer; return next uschar */
1196
1197return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
1198}
1199
1200
1201
1202/*************************************************
1203* Read bytes from TLS channel *
1204*************************************************/
1205
1206/*
1207Arguments:
1208 buff buffer of data
1209 len size of buffer
1210
1211Returns: the number of bytes read
1212 -1 after a failed read
1213*/
1214
1215int
1216tls_read(uschar *buff, size_t len)
1217{
1218int inbytes;
1219
1220DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1221 (long) tls_session, (long) buff, len);
1222
1223inbytes = gnutls_record_recv(tls_session, CS buff, len);
1224if (inbytes > 0) return inbytes;
1225if (inbytes == 0)
1226 {
1227 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1228 }
1229else record_io_error(inbytes, US"recv", NULL);
1230
1231return -1;
1232}
1233
1234
1235
1236/*************************************************
1237* Write bytes down TLS channel *
1238*************************************************/
1239
1240/*
1241Arguments:
1242 buff buffer of data
1243 len number of bytes
1244
1245Returns: the number of bytes after a successful write,
1246 -1 after a failed write
1247*/
1248
1249int
1250tls_write(const uschar *buff, size_t len)
1251{
1252int outbytes;
1253int left = len;
1254
1255DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long) buff, left);
1256while (left > 0)
1257 {
1258 DEBUG(D_tls) debug_printf("gnutls_record_send(SSL, %lx, %d)\n", (long)buff,
1259 left);
1260 outbytes = gnutls_record_send(tls_session, CS buff, left);
1261
1262 DEBUG(D_tls) debug_printf("outbytes=%d\n", outbytes);
1263 if (outbytes < 0)
1264 {
1265 record_io_error(outbytes, US"send", NULL);
1266 return -1;
1267 }
1268 if (outbytes == 0)
1269 {
1270 record_io_error(0, US"send", US"TLS channel closed on write");
1271 return -1;
1272 }
1273
1274 left -= outbytes;
1275 buff += outbytes;
1276 }
1277
1278return len;
1279}
1280
1281
1282
1283/*************************************************
1284* Close down a TLS session *
1285*************************************************/
1286
1287/* This is also called from within a delivery subprocess forked from the
1288daemon, to shut down the TLS library, without actually doing a shutdown (which
1289would tamper with the TLS session in the parent process).
1290
1291Arguments: TRUE if gnutls_bye is to be called
1292Returns: nothing
1293*/
1294
1295void
1296tls_close(BOOL shutdown)
1297{
1298if (tls_active < 0) return; /* TLS was not active */
1299
1300if (shutdown)
1301 {
1302 DEBUG(D_tls) debug_printf("tls_close(): shutting down TLS\n");
1303 gnutls_bye(tls_session, GNUTLS_SHUT_WR);
1304 }
1305
1306gnutls_deinit(tls_session);
1307tls_session = NULL;
1308gnutls_global_deinit();
1309
1310tls_active = -1;
1311}
1312
36f12725
NM
1313
1314
1315
1316/*************************************************
1317* Report the library versions. *
1318*************************************************/
1319
1320/* See a description in tls-openssl.c for an explanation of why this exists.
1321
1322Arguments: a FILE* to print the results to
1323Returns: nothing
1324*/
1325
1326void
1327tls_version_report(FILE *f)
1328{
1329fprintf(f, "GnuTLS compile-time version: %s\n", LIBGNUTLS_VERSION);
1330fprintf(f, "GnuTLS runtime version: %s\n", gnutls_check_version(NULL));
1331}
1332
059ec3d9 1333/* End of tls-gnu.c */