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