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