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