1 /* $Cambridge: exim/src/src/tls-gnu.c,v 1.13 2006/10/16 10:58:40 ph10 Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* Copyright (c) University of Cambridge 1995 - 2006 */
8 /* See the file NOTICE for conditions of use and distribution. */
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.
14 No cryptographic code is included in Exim. All this module does is to call
15 functions from the GnuTLS library. */
18 /* Heading stuff for GnuTLS */
20 #include <gnutls/gnutls.h>
21 #include <gnutls/x509.h>
24 #define UNKNOWN_NAME "unknown"
26 #define PARAM_SIZE 2*1024
29 /* Values for verify_requirment and initialized */
31 enum { VERIFY_NONE, VERIFY_OPTIONAL, VERIFY_REQUIRED };
32 enum { INITIALIZED_NOT, INITIALIZED_SERVER, INITIALIZED_CLIENT };
34 /* Local static variables for GNUTLS */
36 static BOOL initialized = INITIALIZED_NOT;
37 static host_item *client_host;
39 static gnutls_dh_params dh_params = NULL;
41 static gnutls_certificate_server_credentials x509_cred = NULL;
42 static gnutls_session tls_session = NULL;
44 static char ssl_errstring[256];
46 static int ssl_session_timeout = 200;
47 static int verify_requirement;
49 /* Priorities for TLS algorithms to use. At present, only the cipher priority
50 vector can be altered. */
52 static const int protocol_priority[16] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
54 static const int kx_priority[16] = {
60 static int default_cipher_priority[16] = {
61 GNUTLS_CIPHER_AES_256_CBC,
62 GNUTLS_CIPHER_AES_128_CBC,
63 GNUTLS_CIPHER_3DES_CBC,
64 GNUTLS_CIPHER_ARCFOUR_128,
67 static int cipher_priority[16];
69 static const int mac_priority[16] = {
74 static const int comp_priority[16] = { GNUTLS_COMP_NULL, 0 };
75 static const int cert_type_priority[16] = { GNUTLS_CRT_X509, 0 };
77 /* Tables of cipher names and equivalent numbers */
79 typedef struct pri_item {
84 static int arcfour_128_codes[] = { GNUTLS_CIPHER_ARCFOUR_128, 0 };
85 static int arcfour_40_codes[] = { GNUTLS_CIPHER_ARCFOUR_40, 0 };
86 static int arcfour_codes[] = { GNUTLS_CIPHER_ARCFOUR_128,
87 GNUTLS_CIPHER_ARCFOUR_40, 0 };
88 static int aes_256_codes[] = { GNUTLS_CIPHER_AES_256_CBC, 0 };
89 static int aes_128_codes[] = { GNUTLS_CIPHER_AES_128_CBC, 0 };
90 static int aes_codes[] = { GNUTLS_CIPHER_AES_256_CBC,
91 GNUTLS_CIPHER_AES_128_CBC, 0 };
92 static int des3_codes[] = { GNUTLS_CIPHER_3DES_CBC, 0 };
94 static pri_item cipher_index[] = {
95 { US"ARCFOUR_128", arcfour_128_codes },
96 { US"ARCFOUR_40", arcfour_40_codes },
97 { US"ARCFOUR", arcfour_codes },
98 { US"AES_256", aes_256_codes },
99 { US"AES_128", aes_128_codes },
100 { US"AES", aes_codes },
101 { US"3DES", des3_codes }
106 /*************************************************
108 *************************************************/
110 /* Called from lots of places when errors occur before actually starting to do
111 the TLS handshake, that is, while the session is still in clear. Always returns
112 DEFER for a server and FAIL for a client so that most calls can use "return
113 tls_error(...)" to do this processing and then give an appropriate return. A
114 single function is used for both server and client, because it is called from
115 some shared functions.
118 prefix text to include in the logged error
119 host NULL if setting up a server;
120 the connected host if setting up a client
121 err a GnuTLS error number, or 0 if local error
123 Returns: OK/DEFER/FAIL
127 tls_error(uschar *prefix, host_item *host, int err)
129 uschar *errtext = US"";
130 if (err != 0) errtext = string_sprintf(": %s", gnutls_strerror(err));
133 log_write(0, LOG_MAIN, "TLS error on connection from %s (%s)%s",
134 (sender_fullhost != NULL)? sender_fullhost : US "local process",
140 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s)%s",
141 host->name, host->address, prefix, errtext);
148 /*************************************************
149 * Verify certificate *
150 *************************************************/
152 /* Called after a successful handshake, when certificate verification is
153 required or optional, for both server and client.
156 session GNUTLS session
157 error where to put text giving a reason for failure
163 verify_certificate(gnutls_session session, uschar **error)
166 uschar *dn_string = US"";
167 const gnutls_datum *cert;
168 unsigned int cert_size = 0;
172 /* Get the peer's certificate. If it sent one, extract it's DN, and then
173 attempt to verify the certificate. If no certificate is supplied, verification
174 is forced to fail. */
176 cert = gnutls_certificate_get_peers(session, &cert_size);
180 gnutls_x509_crt gcert;
182 gnutls_x509_crt_init(&gcert);
183 dn_string = US"unknown";
185 if (gnutls_x509_crt_import(gcert, cert, GNUTLS_X509_FMT_DER) == 0)
187 size_t bufsize = sizeof(buff);
188 if (gnutls_x509_crt_get_dn(gcert, CS buff, &bufsize) >= 0)
189 dn_string = string_copy_malloc(buff);
192 verify = gnutls_certificate_verify_peers(session);
196 DEBUG(D_tls) debug_printf("no peer certificate supplied\n");
197 verify = GNUTLS_CERT_INVALID;
198 *error = US"not supplied";
201 /* Handle the result of verification. INVALID seems to be set as well
202 as REVOKED, but leave the test for both. */
204 if ((verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED)) != 0)
206 tls_certificate_verified = FALSE;
207 if (*error == NULL) *error = ((verify & GNUTLS_CERT_REVOKED) != 0)?
208 US"revoked" : US"invalid";
209 if (verify_requirement == VERIFY_REQUIRED)
211 DEBUG(D_tls) debug_printf("TLS certificate verification failed (%s): "
212 "peerdn=%s\n", *error, dn_string);
213 gnutls_alert_send(session, GNUTLS_AL_FATAL, GNUTLS_A_BAD_CERTIFICATE);
214 return FALSE; /* reject */
216 DEBUG(D_tls) debug_printf("TLS certificate verify failure (%s) overridden "
217 "(host in tls_try_verify_hosts): peerdn=%s\n", *error, dn_string);
221 tls_certificate_verified = TRUE;
222 DEBUG(D_tls) debug_printf("TLS certificate verified: peerdn=%s\n",
226 tls_peerdn = dn_string;
227 return TRUE; /* accept */
232 /*************************************************
233 * Setup up RSA and DH parameters *
234 *************************************************/
236 /* Generating the RSA and D-H parameters takes a long time. They only need to
237 be re-generated every so often, depending on security policy. What we do is to
238 keep these parameters in a file in the spool directory. If the file does not
239 exist, we generate them. This means that it is easy to cause a regeneration.
241 The new file is written as a temporary file and renamed, so that an incomplete
242 file is never present. If two processes both compute some new parameters, you
243 waste a bit of effort, but it doesn't seem worth messing around with locking to
247 host NULL for server, server for client (for error handling)
249 Returns: OK/DEFER/FAIL
253 init_rsa_dh(host_item *host)
258 uschar filename[200];
260 /* Initialize the data structures for holding the parameters */
262 ret = gnutls_dh_params_init(&dh_params);
263 if (ret < 0) return tls_error(US"init dh_params", host, ret);
265 /* Set up the name of the cache file */
267 if (!string_format(filename, sizeof(filename), "%s/gnutls-params",
269 return tls_error(US"overlong filename", host, 0);
271 /* Open the cache file for reading and if successful, read it and set up the
272 parameters. If we can't set up the RSA parameters, assume that we are dealing
273 with an old-style cache file that is in another format, and fall through to
274 compute new values. However, if we correctly get RSA parameters, a failure to
275 set up D-H parameters is treated as an error. */
277 fd = Uopen(filename, O_RDONLY, 0);
281 if (fstat(fd, &statbuf) < 0)
284 return tls_error(US"TLS cache stat failed", host, 0);
287 m.size = statbuf.st_size;
288 m.data = malloc(m.size);
290 return tls_error(US"memory allocation failed", host, 0);
291 if (read(fd, m.data, m.size) != m.size)
292 return tls_error(US"TLS cache read failed", host, 0);
295 ret = gnutls_dh_params_import_pkcs3(dh_params, &m, GNUTLS_X509_FMT_PEM);
296 if (ret < 0) return tls_error(US"DH params import", host, ret);
297 DEBUG(D_tls) debug_printf("read RSA and D-H parameters from file\n");
302 /* If the file does not exist, fall through to compute new data and cache it.
303 If there was any other opening error, it is serious. */
305 else if (errno == ENOENT)
309 debug_printf("parameter cache file %s does not exist\n", filename);
312 return tls_error(string_open_failed(errno, "%s for reading", filename),
315 /* If ret < 0, either the cache file does not exist, or the data it contains
316 is not useful. One particular case of this is when upgrading from an older
317 release of Exim in which the data was stored in a different format. We don't
318 try to be clever and support both formats; we just regenerate new data in this
323 uschar tempfilename[sizeof(filename) + 10];
325 DEBUG(D_tls) debug_printf("generating %d bit Diffie-Hellman key...\n",
327 ret = gnutls_dh_params_generate2(dh_params, DH_BITS);
328 if (ret < 0) return tls_error(US"D-H key generation", host, ret);
330 /* Write the parameters to a file in the spool directory so that we
331 can use them from other Exim processes. */
333 sprintf(CS tempfilename, "%s-%d", filename, (int)getpid());
334 fd = Uopen(tempfilename, O_WRONLY|O_CREAT, 0400);
336 return tls_error(string_open_failed(errno, "%s for writing", filename),
338 (void)fchown(fd, exim_uid, exim_gid); /* Probably not necessary */
340 /* export the parameters in a format that can be generated using GNUTLS'
341 * certtool or other programs.
343 * The commands for certtool are:
344 * $ certtool --generate-dh-params --bits 1024 > params
348 m.data = malloc(m.size);
350 return tls_error(US"memory allocation failed", host, 0);
353 ret = gnutls_dh_params_export_pkcs3(dh_params, GNUTLS_X509_FMT_PEM, m.data,
355 if (ret < 0) return tls_error(US"DH params export", host, ret);
357 m.size = Ustrlen(m.data);
358 if (write(fd, m.data, m.size) != m.size || write(fd, "\n", 1) != 1)
359 return tls_error(US"TLS cache write failed", host, 0);
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);
368 DEBUG(D_tls) debug_printf("wrote D-H parameters to file %s\n", filename);
371 DEBUG(D_tls) debug_printf("initialized D-H parameters\n");
378 /*************************************************
379 * Initialize for GnuTLS *
380 *************************************************/
382 /* Called from both server and client code. In the case of a server, errors
383 before actual TLS negotiation return DEFER.
386 host connected host, if client; NULL if server
387 certificate certificate file
388 privatekey private key file
392 Returns: OK/DEFER/FAIL
396 tls_init(host_item *host, uschar *certificate, uschar *privatekey, uschar *cas,
400 uschar *cert_expanded, *key_expanded, *cas_expanded, *crl_expanded;
402 initialized = (host == NULL)? INITIALIZED_SERVER : INITIALIZED_CLIENT;
404 rc = gnutls_global_init();
405 if (rc < 0) return tls_error(US"tls-init", host, rc);
407 /* Create RSA and D-H parameters, or read them from the cache file. This
408 function does its own SMTP error messaging. */
410 rc = init_rsa_dh(host);
411 if (rc != OK) return rc;
413 /* Create the credentials structure */
415 rc = gnutls_certificate_allocate_credentials(&x509_cred);
416 if (rc < 0) return tls_error(US"certificate_allocate_credentials", host, rc);
418 /* This stuff must be done for each session, because different certificates
419 may be required for different sessions. */
421 if (!expand_check(certificate, US"tls_certificate", &cert_expanded))
425 if (privatekey != NULL)
427 if (!expand_check(privatekey, US"tls_privatekey", &key_expanded))
431 /* If expansion was forced to fail, key_expanded will be NULL. If the result of
432 the expansion is an empty string, ignore it also, and assume that the private
433 key is in the same file as the certificate. */
435 if (key_expanded == NULL || *key_expanded == 0)
436 key_expanded = cert_expanded;
438 /* Set the certificate and private keys */
440 if (cert_expanded != NULL)
442 DEBUG(D_tls) debug_printf("certificate file = %s\nkey file = %s\n",
443 cert_expanded, key_expanded);
444 rc = gnutls_certificate_set_x509_key_file(x509_cred, CS cert_expanded,
445 CS key_expanded, GNUTLS_X509_FMT_PEM);
448 uschar *msg = string_sprintf("cert/key setup: cert=%s key=%s",
449 cert_expanded, key_expanded);
450 return tls_error(msg, host, rc);
454 /* A certificate is mandatory in a server, but not in a client */
459 return tls_error(US"no TLS server certificate is specified", host, 0);
460 DEBUG(D_tls) debug_printf("no TLS client certificate is specified\n");
463 /* Set the trusted CAs file if one is provided, and then add the CRL if one is
464 provided. Experiment shows that, if the certificate file is empty, an unhelpful
465 error message is provided. However, if we just refrain from setting anything up
466 in that case, certificate verification fails, which seems to be the correct
473 if (!expand_check(cas, US"tls_verify_certificates", &cas_expanded))
476 if (stat(CS cas_expanded, &statbuf) < 0)
478 log_write(0, LOG_MAIN|LOG_PANIC, "could not stat %s "
479 "(tls_verify_certificates): %s", cas_expanded, strerror(errno));
483 DEBUG(D_tls) debug_printf("verify certificates = %s size=" OFF_T_FMT "\n",
484 cas_expanded, statbuf.st_size);
486 /* If the cert file is empty, there's no point in loading the CRL file. */
488 if (statbuf.st_size > 0)
490 rc = gnutls_certificate_set_x509_trust_file(x509_cred, CS cas_expanded,
491 GNUTLS_X509_FMT_PEM);
492 if (rc < 0) return tls_error(US"setup_certs", host, rc);
494 if (crl != NULL && *crl != 0)
496 if (!expand_check(crl, US"tls_crl", &crl_expanded))
498 DEBUG(D_tls) debug_printf("loading CRL file = %s\n", crl_expanded);
499 rc = gnutls_certificate_set_x509_crl_file(x509_cred, CS crl_expanded,
500 GNUTLS_X509_FMT_PEM);
501 if (rc < 0) return tls_error(US"CRL setup", host, rc);
506 /* Associate the parameters with the x509 credentials structure. */
508 gnutls_certificate_set_dh_params(x509_cred, dh_params);
510 DEBUG(D_tls) debug_printf("initialized certificate stuff\n");
517 /*************************************************
518 * Remove ciphers from priority list *
519 *************************************************/
521 /* Cautiously written so that it will remove duplicates if present.
524 list a zero-terminated list
525 remove_list a zero-terminated list to be removed
531 remove_ciphers(int *list, int *remove_list)
533 for (; *remove_list != 0; remove_list++)
538 if (*p == *remove_list)
541 do { pp[0] = pp[1]; pp++; } while (*pp != 0);
550 /*************************************************
551 * Add ciphers to priority list *
552 *************************************************/
554 /* Cautiously written to check the list size
557 list a zero-terminated list
558 list_max maximum offset in the list
559 add_list a zero-terminated list to be added
561 Returns: TRUE if OK; FALSE if list overflows
565 add_ciphers(int *list, int list_max, int *add_list)
568 while (list[next] != 0) next++;
569 while (*add_list != 0)
571 if (next >= list_max) return FALSE;
572 list[next++] = *add_list++;
580 /*************************************************
581 * Initialize a single GNUTLS session *
582 *************************************************/
584 /* Set the algorithm, the db backend, whether to request certificates etc.
586 TLS in Exim was first implemented using OpenSSL. This has a function to which
587 you pass a list of cipher suites that are permitted/not permitted. GnuTLS works
588 differently. It operates using priority lists for the different components of
591 For compatibility of configuration, we scan a list of cipher suites and set
592 priorities therefrom. However, at the moment, we pay attention only to the bulk
596 side one of GNUTLS_SERVER, GNUTLS_CLIENT
597 expciphers expanded ciphers list
599 Returns: a gnutls_session, or NULL if there is a problem
602 static gnutls_session
603 tls_session_init(int side, uschar *expciphers)
605 gnutls_session session;
607 gnutls_init(&session, side);
609 /* Handle the list of permitted ciphers */
611 memcpy(cipher_priority, default_cipher_priority, sizeof(cipher_priority));
613 if (expciphers != NULL)
619 /* The names OpenSSL uses are of the form DES-CBC3-SHA, using hyphen
620 separators. GnuTLS uses underscore separators. So that I can use either form
621 in my tests, and also for general convenience, we turn hyphens into
622 underscores before scanning the list. */
624 uschar *s = expciphers;
625 while (*s != 0) { if (*s == '-') *s = '_'; s++; }
627 while ((cipher = string_nextinlist(&expciphers, &sep, big_buffer,
628 big_buffer_size)) != NULL)
631 BOOL exclude = cipher[0] == '!';
632 if (first && !exclude) cipher_priority[0] = 0;
635 for (i = 0; i < sizeof(cipher_index)/sizeof(pri_item); i++)
637 uschar *ss = strstric(cipher, cipher_index[i].name, FALSE);
640 uschar *endss = ss + Ustrlen(cipher_index[i].name);
641 if ((ss == cipher || !isalnum(ss[-1])) && !isalnum(*endss))
644 remove_ciphers(cipher_priority, cipher_index[i].values);
647 if (!add_ciphers(cipher_priority,
648 sizeof(cipher_priority)/sizeof(pri_item),
649 cipher_index[i].values))
651 log_write(0, LOG_MAIN|LOG_PANIC, "GnuTLS init failed: cipher "
652 "priority table overflow");
653 gnutls_deinit(session);
664 int *ptr = cipher_priority;
665 debug_printf("adjusted cipher priorities:");
666 while (*ptr != 0) debug_printf(" %d", *ptr++);
671 /* Define the various priorities */
673 gnutls_cipher_set_priority(session, cipher_priority);
674 gnutls_compression_set_priority(session, comp_priority);
675 gnutls_kx_set_priority(session, kx_priority);
676 gnutls_protocol_set_priority(session, protocol_priority);
677 gnutls_mac_set_priority(session, mac_priority);
679 gnutls_cred_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
681 gnutls_dh_set_prime_bits(session, DH_BITS);
683 /* Request or demand a certificate of the peer, as configured. This will
684 happen only in a server. */
686 if (verify_requirement != VERIFY_NONE)
687 gnutls_certificate_server_set_request(session,
688 (verify_requirement == VERIFY_OPTIONAL)?
689 GNUTLS_CERT_REQUEST : GNUTLS_CERT_REQUIRE);
691 gnutls_db_set_cache_expiration(session, ssl_session_timeout);
693 DEBUG(D_tls) debug_printf("initialized GnuTLS session\n");
699 /*************************************************
700 * Get name of cipher in use *
701 *************************************************/
703 /* The answer is left in a static buffer, and tls_cipher is set to point
706 Argument: pointer to a GnuTLS session
711 construct_cipher_name(gnutls_session session)
713 static uschar cipherbuf[256];
715 int bits, c, kx, mac;
718 US gnutls_protocol_get_name(gnutls_protocol_get_version(session)));
719 if (Ustrncmp(ver, "TLS ", 4) == 0) ver[3] = '-'; /* Don't want space */
721 c = gnutls_cipher_get(session);
722 bits = gnutls_cipher_get_key_size(c);
724 mac = gnutls_mac_get(session);
725 kx = gnutls_kx_get(session);
727 string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
728 gnutls_cipher_suite_get_name(kx, c, mac), bits);
729 tls_cipher = cipherbuf;
731 DEBUG(D_tls) debug_printf("cipher: %s\n", cipherbuf);
736 /*************************************************
737 * Start a TLS session in a server *
738 *************************************************/
740 /* This is called when Exim is running as a server, after having received
741 the STARTTLS command. It must respond to that command, and then negotiate
745 require_ciphers list of allowed ciphers
747 Returns: OK on success
748 DEFER for errors before the start of the negotiation
749 FAIL for errors during the negotation; the server can't
754 tls_server_start(uschar *require_ciphers)
758 uschar *expciphers = NULL;
760 /* Check for previous activation */
764 log_write(0, LOG_MAIN, "STARTTLS received in already encrypted "
765 "connection from %s",
766 (sender_fullhost != NULL)? sender_fullhost : US"local process");
767 smtp_printf("554 Already in TLS\r\n");
771 /* Initialize the library. If it fails, it will already have logged the error
772 and sent an SMTP response. */
774 DEBUG(D_tls) debug_printf("initializing GnuTLS as a server\n");
776 rc = tls_init(NULL, tls_certificate, tls_privatekey, tls_verify_certificates,
778 if (rc != OK) return rc;
780 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
783 /* If this is a host for which certificate verification is mandatory or
784 optional, set up appropriately. */
786 tls_certificate_verified = FALSE;
787 verify_requirement = VERIFY_NONE;
789 if (verify_check_host(&tls_verify_hosts) == OK)
790 verify_requirement = VERIFY_REQUIRED;
791 else if (verify_check_host(&tls_try_verify_hosts) == OK)
792 verify_requirement = VERIFY_OPTIONAL;
794 /* Prepare for new connection */
796 tls_session = tls_session_init(GNUTLS_SERVER, expciphers);
797 if (tls_session == NULL)
798 return tls_error(US"tls_session_init", NULL, GNUTLS_E_MEMORY_ERROR);
800 /* Set context and tell client to go ahead, except in the case of TLS startup
801 on connection, where outputting anything now upsets the clients and tends to
802 make them disconnect. We need to have an explicit fflush() here, to force out
803 the response. Other smtp_printf() calls do not need it, because in non-TLS
804 mode, the fflush() happens when smtp_getc() is called. */
808 smtp_printf("220 TLS go ahead\r\n");
812 /* Now negotiate the TLS session. We put our own timer on it, since it seems
813 that the GnuTLS library doesn't. */
815 gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr)fileno(smtp_out));
817 sigalrm_seen = FALSE;
818 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
819 rc = gnutls_handshake(tls_session);
825 Ustrcpy(ssl_errstring, "timed out");
827 Ustrcpy(ssl_errstring, gnutls_strerror(rc));
828 log_write(0, LOG_MAIN,
829 "TLS error on connection from %s (gnutls_handshake): %s",
830 (sender_fullhost != NULL)? sender_fullhost : US"local process",
833 /* It seems that, except in the case of a timeout, we have to close the
834 connection right here; otherwise if the other end is running OpenSSL it hangs
835 until the server times out. */
839 (void)fclose(smtp_out);
840 (void)fclose(smtp_in);
846 DEBUG(D_tls) debug_printf("gnutls_handshake was successful\n");
848 if (verify_requirement != VERIFY_NONE &&
849 !verify_certificate(tls_session, &error))
851 log_write(0, LOG_MAIN,
852 "TLS error on connection from %s: certificate verification failed (%s)",
853 (sender_fullhost != NULL)? sender_fullhost : US"local process", error);
857 construct_cipher_name(tls_session);
859 /* TLS has been set up. Adjust the input functions to read via TLS,
860 and initialize appropriately. */
862 ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
863 ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
864 ssl_xfer_eof = ssl_xfer_error = 0;
866 receive_getc = tls_getc;
867 receive_ungetc = tls_ungetc;
868 receive_feof = tls_feof;
869 receive_ferror = tls_ferror;
871 tls_active = fileno(smtp_out);
879 /*************************************************
880 * Start a TLS session in a client *
881 *************************************************/
883 /* Called from the smtp transport after STARTTLS has been accepted.
886 fd the fd of the connection
887 host connected host (for messages)
889 dhparam DH parameter file
890 certificate certificate file
891 privatekey private key file
892 verify_certs file for certificate verify
893 verify_crl CRL for verify
894 require_ciphers list of allowed ciphers
895 timeout startup timeout
897 Returns: OK/DEFER/FAIL (because using common functions),
898 but for a client, DEFER and FAIL have the same meaning
902 tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
903 uschar *certificate, uschar *privatekey, uschar *verify_certs,
904 uschar *verify_crl, uschar *require_ciphers, int timeout)
906 const gnutls_datum *server_certs;
907 uschar *expciphers = NULL;
909 unsigned int server_certs_size;
912 DEBUG(D_tls) debug_printf("initializing GnuTLS as a client\n");
915 verify_requirement = (verify_certs == NULL)? VERIFY_NONE : VERIFY_REQUIRED;
916 rc = tls_init(host, certificate, privatekey, verify_certs, verify_crl);
917 if (rc != OK) return rc;
919 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
922 tls_session = tls_session_init(GNUTLS_CLIENT, expciphers);
923 if (tls_session == NULL)
924 return tls_error(US "tls_session_init", host, GNUTLS_E_MEMORY_ERROR);
926 gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr)fd);
928 /* There doesn't seem to be a built-in timeout on connection. */
930 sigalrm_seen = FALSE;
932 rc = gnutls_handshake(tls_session);
939 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s]: "
940 "gnutls_handshake timed out", host->name, host->address);
943 else return tls_error(US "gnutls_handshake", host, rc);
946 server_certs = gnutls_certificate_get_peers(tls_session, &server_certs_size);
948 if (server_certs != NULL)
951 gnutls_x509_crt gcert;
953 gnutls_x509_crt_init(&gcert);
954 tls_peerdn = US"unknown";
956 if (gnutls_x509_crt_import(gcert, server_certs, GNUTLS_X509_FMT_DER) == 0)
958 size_t bufsize = sizeof(buff);
959 if (gnutls_x509_crt_get_dn(gcert, CS buff, &bufsize) >= 0)
960 tls_peerdn = string_copy_malloc(buff);
964 /* Should we also verify the hostname here? */
966 if (verify_requirement != VERIFY_NONE &&
967 !verify_certificate(tls_session, &error))
969 log_write(0, LOG_MAIN,
970 "TLS error on connection to %s [%s]: certificate verification failed (%s)",
971 host->name, host->address, error);
975 construct_cipher_name(tls_session); /* Sets tls_cipher */
982 /*************************************************
983 * Deal with logging errors during I/O *
984 *************************************************/
986 /* We have to get the identity of the peer from saved data.
989 ec the GnuTLS error code, or 0 if it's a local error
990 when text identifying read or write
991 text local error text when ec is 0
997 record_io_error(int ec, uschar *when, uschar *text)
999 uschar *additional = US"";
1001 if (ec == GNUTLS_E_FATAL_ALERT_RECEIVED)
1002 additional = string_sprintf(": %s",
1003 gnutls_alert_get_name(gnutls_alert_get(tls_session)));
1005 if (initialized == INITIALIZED_SERVER)
1006 log_write(0, LOG_MAIN, "TLS %s error on connection from %s: %s%s", when,
1007 (sender_fullhost != NULL)? sender_fullhost : US "local process",
1008 (ec == 0)? text : US gnutls_strerror(ec), additional);
1011 log_write(0, LOG_MAIN, "TLS %s error on connection to %s [%s]: %s%s", when,
1012 client_host->name, client_host->address,
1013 (ec == 0)? text : US gnutls_strerror(ec), additional);
1018 /*************************************************
1019 * TLS version of getc *
1020 *************************************************/
1022 /* This gets the next byte from the TLS input buffer. If the buffer is empty,
1023 it refills the buffer via the GnuTLS reading function.
1026 Returns: the next character or EOF
1032 if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
1036 DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1037 (long) tls_session, (long) ssl_xfer_buffer, ssl_xfer_buffer_size);
1039 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
1040 inbytes = gnutls_record_recv(tls_session, CS ssl_xfer_buffer,
1041 ssl_xfer_buffer_size);
1044 /* A zero-byte return appears to mean that the TLS session has been
1045 closed down, not that the socket itself has been closed down. Revert to
1046 non-TLS handling. */
1050 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1052 receive_getc = smtp_getc;
1053 receive_ungetc = smtp_ungetc;
1054 receive_feof = smtp_feof;
1055 receive_ferror = smtp_ferror;
1057 gnutls_deinit(tls_session);
1066 /* Handle genuine errors */
1068 else if (inbytes < 0)
1070 record_io_error(inbytes, US"recv", NULL);
1075 ssl_xfer_buffer_hwm = inbytes;
1076 ssl_xfer_buffer_lwm = 0;
1080 /* Something in the buffer; return next uschar */
1082 return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
1087 /*************************************************
1088 * Read bytes from TLS channel *
1089 *************************************************/
1096 Returns: the number of bytes read
1097 -1 after a failed read
1101 tls_read(uschar *buff, size_t len)
1105 DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1106 (long) tls_session, (long) buff, len);
1108 inbytes = gnutls_record_recv(tls_session, CS buff, len);
1109 if (inbytes > 0) return inbytes;
1112 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1114 else record_io_error(inbytes, US"recv", NULL);
1121 /*************************************************
1122 * Write bytes down TLS channel *
1123 *************************************************/
1130 Returns: the number of bytes after a successful write,
1131 -1 after a failed write
1135 tls_write(const uschar *buff, size_t len)
1140 DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long) buff, left);
1143 DEBUG(D_tls) debug_printf("gnutls_record_send(SSL, %lx, %d)\n", (long)buff,
1145 outbytes = gnutls_record_send(tls_session, CS buff, left);
1147 DEBUG(D_tls) debug_printf("outbytes=%d\n", outbytes);
1150 record_io_error(outbytes, US"send", NULL);
1155 record_io_error(0, US"send", US"TLS channel closed on write");
1168 /*************************************************
1169 * Close down a TLS session *
1170 *************************************************/
1172 /* This is also called from within a delivery subprocess forked from the
1173 daemon, to shut down the TLS library, without actually doing a shutdown (which
1174 would tamper with the TLS session in the parent process).
1176 Arguments: TRUE if gnutls_bye is to be called
1181 tls_close(BOOL shutdown)
1183 if (tls_active < 0) return; /* TLS was not active */
1187 DEBUG(D_tls) debug_printf("tls_close(): shutting down TLS\n");
1188 gnutls_bye(tls_session, GNUTLS_SHUT_WR);
1191 gnutls_deinit(tls_session);
1193 gnutls_global_deinit();
1198 /* End of tls-gnu.c */