Check the length of off_t at build time and use %ld or %lld to print
[exim.git] / src / src / tls-gnu.c
1 /* $Cambridge: exim/src/src/tls-gnu.c,v 1.8 2005/06/16 14:10:13 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 fclose(smtp_out);
860 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 */