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