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