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