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