1 /* $Cambridge: exim/src/src/tls-gnu.c,v 1.12 2006/02/14 14:12:07 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"
27 #define PARAM_SIZE 2*1024
30 /* Values for verify_requirment and initialized */
32 enum { VERIFY_NONE, VERIFY_OPTIONAL, VERIFY_REQUIRED };
33 enum { INITIALIZED_NOT, INITIALIZED_SERVER, INITIALIZED_CLIENT };
35 /* Local static variables for GNUTLS */
37 static BOOL initialized = INITIALIZED_NOT;
38 static host_item *client_host;
40 static gnutls_rsa_params rsa_params = NULL;
41 static gnutls_dh_params dh_params = NULL;
43 static gnutls_certificate_server_credentials x509_cred = NULL;
44 static gnutls_session tls_session = NULL;
46 static char ssl_errstring[256];
48 static int ssl_session_timeout = 200;
49 static int verify_requirement;
51 /* Priorities for TLS algorithms to use. At present, only the cipher priority
52 vector can be altered. */
54 static const int protocol_priority[16] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
56 static const int kx_priority[16] = {
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,
70 static int cipher_priority[16];
72 static const int mac_priority[16] = {
77 static const int comp_priority[16] = { GNUTLS_COMP_NULL, 0 };
78 static const int cert_type_priority[16] = { GNUTLS_CRT_X509, 0 };
80 /* Tables of cipher names and equivalent numbers */
82 typedef struct pri_item {
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 };
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 }
109 /*************************************************
111 *************************************************/
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.
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
126 Returns: OK/DEFER/FAIL
130 tls_error(uschar *prefix, host_item *host, int err)
132 uschar *errtext = US"";
133 if (err != 0) errtext = string_sprintf(": %s", gnutls_strerror(err));
136 log_write(0, LOG_MAIN, "TLS error on connection from %s (%s)%s",
137 (sender_fullhost != NULL)? sender_fullhost : US "local process",
143 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s)%s",
144 host->name, host->address, prefix, errtext);
151 /*************************************************
152 * Verify certificate *
153 *************************************************/
155 /* Called after a successful handshake, when certificate verification is
156 required or optional, for both server and client.
159 session GNUTLS session
160 error where to put text giving a reason for failure
166 verify_certificate(gnutls_session session, uschar **error)
169 uschar *dn_string = US"";
170 const gnutls_datum *cert;
171 unsigned int cert_size = 0;
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. */
179 cert = gnutls_certificate_get_peers(session, &cert_size);
183 gnutls_x509_crt gcert;
185 gnutls_x509_crt_init(&gcert);
186 dn_string = US"unknown";
188 if (gnutls_x509_crt_import(gcert, cert, GNUTLS_X509_FMT_DER) == 0)
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);
195 verify = gnutls_certificate_verify_peers(session);
199 DEBUG(D_tls) debug_printf("no peer certificate supplied\n");
200 verify = GNUTLS_CERT_INVALID;
201 *error = US"not supplied";
204 /* Handle the result of verification. INVALID seems to be set as well
205 as REVOKED, but leave the test for both. */
207 if ((verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED)) != 0)
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)
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 */
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);
224 tls_certificate_verified = TRUE;
225 DEBUG(D_tls) debug_printf("TLS certificate verified: peerdn=%s\n",
229 tls_peerdn = dn_string;
230 return TRUE; /* accept */
235 /*************************************************
236 * Setup up RSA and DH parameters *
237 *************************************************/
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.
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
250 host NULL for server, server for client (for error handling)
252 Returns: OK/DEFER/FAIL
256 init_rsa_dh(host_item *host)
261 uschar filename[200];
263 /* Initialize the data structures for holding the parameters */
265 ret = gnutls_rsa_params_init(&rsa_params);
266 if (ret < 0) return tls_error(US"init rsa_params", host, ret);
268 ret = gnutls_dh_params_init(&dh_params);
269 if (ret < 0) return tls_error(US"init dh_params", host, ret);
271 /* Set up the name of the cache file */
273 if (!string_format(filename, sizeof(filename), "%s/gnutls-params",
275 return tls_error(US"overlong filename", host, 0);
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. */
283 fd = Uopen(filename, O_RDONLY, 0);
287 if (fstat(fd, &statbuf) < 0)
290 return tls_error(US"TLS cache stat failed", host, 0);
293 m.size = statbuf.st_size;
294 m.data = malloc(m.size);
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);
301 ret = gnutls_rsa_params_import_pkcs1(rsa_params, &m, GNUTLS_X509_FMT_PEM);
306 debug_printf("RSA params import failed: assume old-style cache file\n");
310 ret = gnutls_dh_params_import_pkcs3(dh_params, &m, GNUTLS_X509_FMT_PEM);
312 return tls_error(US"DH params import", host, ret);
313 DEBUG(D_tls) debug_printf("read RSA and D-H parameters from file\n");
319 /* If the file does not exist, fall through to compute new data and cache it.
320 If there was any other opening error, it is serious. */
322 else if (errno == ENOENT)
326 debug_printf("parameter cache file %s does not exist\n", filename);
329 return tls_error(string_open_failed(errno, "%s for reading", filename),
332 /* If ret < 0, either the cache file does not exist, or the data it contains
333 is not useful. One particular case of this is when upgrading from an older
334 release of Exim in which the data was stored in a different format. We don't
335 try to be clever and support both formats; we just regenerate new data in this
340 uschar tempfilename[sizeof(filename) + 10];
342 DEBUG(D_tls) debug_printf("generating %d bit RSA key...\n", RSA_BITS);
343 ret = gnutls_rsa_params_generate2(rsa_params, RSA_BITS);
344 if (ret < 0) return tls_error(US"RSA key generation", host, ret);
346 DEBUG(D_tls) debug_printf("generating %d bit Diffie-Hellman key...\n",
348 ret = gnutls_dh_params_generate2(dh_params, DH_BITS);
349 if (ret < 0) return tls_error(US"D-H key generation", host, ret);
351 /* Write the parameters to a file in the spool directory so that we
352 can use them from other Exim processes. */
354 sprintf(CS tempfilename, "%s-%d", filename, (int)getpid());
355 fd = Uopen(tempfilename, O_WRONLY|O_CREAT, 0400);
357 return tls_error(string_open_failed(errno, "%s for writing", filename),
359 (void)fchown(fd, exim_uid, exim_gid); /* Probably not necessary */
361 /* export the parameters in a format that can be generated using GNUTLS'
362 * certtool or other programs.
364 * The commands for certtool are:
365 * $ certtool --generate-privkey --bits 512 >params
367 * $ certtool --generate-dh-params --bits 1024 >> params
371 m.data = malloc(m.size);
373 return tls_error(US"memory allocation failed", host, 0);
375 ret = gnutls_rsa_params_export_pkcs1(rsa_params, GNUTLS_X509_FMT_PEM,
377 if (ret < 0) return tls_error(US"RSA params export", host, ret);
379 /* Do not write the null termination byte. */
381 m.size = Ustrlen(m.data);
382 if (write(fd, m.data, m.size) != m.size || write(fd, "\n", 1) != 1)
383 return tls_error(US"TLS cache write failed", host, 0);
386 ret = gnutls_dh_params_export_pkcs3(dh_params, GNUTLS_X509_FMT_PEM, m.data,
388 if (ret < 0) return tls_error(US"DH params export", host, ret);
390 m.size = Ustrlen(m.data);
391 if (write(fd, m.data, m.size) != m.size || write(fd, "\n", 1) != 1)
392 return tls_error(US"TLS cache write failed", host, 0);
397 if (rename(CS tempfilename, CS filename) < 0)
398 return tls_error(string_sprintf("failed to rename %s as %s: %s",
399 tempfilename, filename, strerror(errno)), host, 0);
401 DEBUG(D_tls) debug_printf("wrote RSA and D-H parameters to file %s\n",
405 DEBUG(D_tls) debug_printf("initialized RSA and D-H parameters\n");
412 /*************************************************
413 * Initialize for GnuTLS *
414 *************************************************/
416 /* Called from both server and client code. In the case of a server, errors
417 before actual TLS negotiation return DEFER.
420 host connected host, if client; NULL if server
421 certificate certificate file
422 privatekey private key file
426 Returns: OK/DEFER/FAIL
430 tls_init(host_item *host, uschar *certificate, uschar *privatekey, uschar *cas,
434 uschar *cert_expanded, *key_expanded, *cas_expanded, *crl_expanded;
436 initialized = (host == NULL)? INITIALIZED_SERVER : INITIALIZED_CLIENT;
438 rc = gnutls_global_init();
439 if (rc < 0) return tls_error(US"tls-init", host, rc);
441 /* Create RSA and D-H parameters, or read them from the cache file. This
442 function does its own SMTP error messaging. */
444 rc = init_rsa_dh(host);
445 if (rc != OK) return rc;
447 /* Create the credentials structure */
449 rc = gnutls_certificate_allocate_credentials(&x509_cred);
450 if (rc < 0) return tls_error(US"certificate_allocate_credentials", host, rc);
452 /* This stuff must be done for each session, because different certificates
453 may be required for different sessions. */
455 if (!expand_check(certificate, US"tls_certificate", &cert_expanded))
459 if (privatekey != NULL)
461 if (!expand_check(privatekey, US"tls_privatekey", &key_expanded))
465 /* If expansion was forced to fail, key_expanded will be NULL. If the result of
466 the expansion is an empty string, ignore it also, and assume that the private
467 key is in the same file as the certificate. */
469 if (key_expanded == NULL || *key_expanded == 0)
470 key_expanded = cert_expanded;
472 /* Set the certificate and private keys */
474 if (cert_expanded != NULL)
476 DEBUG(D_tls) debug_printf("certificate file = %s\nkey file = %s\n",
477 cert_expanded, key_expanded);
478 rc = gnutls_certificate_set_x509_key_file(x509_cred, CS cert_expanded,
479 CS key_expanded, GNUTLS_X509_FMT_PEM);
482 uschar *msg = string_sprintf("cert/key setup: cert=%s key=%s",
483 cert_expanded, key_expanded);
484 return tls_error(msg, host, rc);
488 /* A certificate is mandatory in a server, but not in a client */
493 return tls_error(US"no TLS server certificate is specified", host, 0);
494 DEBUG(D_tls) debug_printf("no TLS client certificate is specified\n");
497 /* Set the trusted CAs file if one is provided, and then add the CRL if one is
498 provided. Experiment shows that, if the certificate file is empty, an unhelpful
499 error message is provided. However, if we just refrain from setting anything up
500 in that case, certificate verification fails, which seems to be the correct
507 if (!expand_check(cas, US"tls_verify_certificates", &cas_expanded))
510 if (stat(CS cas_expanded, &statbuf) < 0)
512 log_write(0, LOG_MAIN|LOG_PANIC, "could not stat %s "
513 "(tls_verify_certificates): %s", cas_expanded, strerror(errno));
517 DEBUG(D_tls) debug_printf("verify certificates = %s size=" OFF_T_FMT "\n",
518 cas_expanded, statbuf.st_size);
520 /* If the cert file is empty, there's no point in loading the CRL file. */
522 if (statbuf.st_size > 0)
524 rc = gnutls_certificate_set_x509_trust_file(x509_cred, CS cas_expanded,
525 GNUTLS_X509_FMT_PEM);
526 if (rc < 0) return tls_error(US"setup_certs", host, rc);
528 if (crl != NULL && *crl != 0)
530 if (!expand_check(crl, US"tls_crl", &crl_expanded))
532 DEBUG(D_tls) debug_printf("loading CRL file = %s\n", crl_expanded);
533 rc = gnutls_certificate_set_x509_crl_file(x509_cred, CS crl_expanded,
534 GNUTLS_X509_FMT_PEM);
535 if (rc < 0) return tls_error(US"CRL setup", host, rc);
540 /* Associate the parameters with the x509 credentials structure. */
542 gnutls_certificate_set_dh_params(x509_cred, dh_params);
543 gnutls_certificate_set_rsa_export_params(x509_cred, rsa_params);
545 DEBUG(D_tls) debug_printf("initialized certificate stuff\n");
552 /*************************************************
553 * Remove ciphers from priority list *
554 *************************************************/
556 /* Cautiously written so that it will remove duplicates if present.
559 list a zero-terminated list
560 remove_list a zero-terminated list to be removed
566 remove_ciphers(int *list, int *remove_list)
568 for (; *remove_list != 0; remove_list++)
573 if (*p == *remove_list)
576 do { pp[0] = pp[1]; pp++; } while (*pp != 0);
585 /*************************************************
586 * Add ciphers to priority list *
587 *************************************************/
589 /* Cautiously written to check the list size
592 list a zero-terminated list
593 list_max maximum offset in the list
594 add_list a zero-terminated list to be added
596 Returns: TRUE if OK; FALSE if list overflows
600 add_ciphers(int *list, int list_max, int *add_list)
603 while (list[next] != 0) next++;
604 while (*add_list != 0)
606 if (next >= list_max) return FALSE;
607 list[next++] = *add_list++;
615 /*************************************************
616 * Initialize a single GNUTLS session *
617 *************************************************/
619 /* Set the algorithm, the db backend, whether to request certificates etc.
621 TLS in Exim was first implemented using OpenSSL. This has a function to which
622 you pass a list of cipher suites that are permitted/not permitted. GnuTLS works
623 differently. It operates using priority lists for the different components of
626 For compatibility of configuration, we scan a list of cipher suites and set
627 priorities therefrom. However, at the moment, we pay attention only to the bulk
631 side one of GNUTLS_SERVER, GNUTLS_CLIENT
632 expciphers expanded ciphers list
634 Returns: a gnutls_session, or NULL if there is a problem
637 static gnutls_session
638 tls_session_init(int side, uschar *expciphers)
640 gnutls_session session;
642 gnutls_init(&session, side);
644 /* Handle the list of permitted ciphers */
646 memcpy(cipher_priority, default_cipher_priority, sizeof(cipher_priority));
648 if (expciphers != NULL)
654 /* The names OpenSSL uses are of the form DES-CBC3-SHA, using hyphen
655 separators. GnuTLS uses underscore separators. So that I can use either form
656 in my tests, and also for general convenience, we turn hyphens into
657 underscores before scanning the list. */
659 uschar *s = expciphers;
660 while (*s != 0) { if (*s == '-') *s = '_'; s++; }
662 while ((cipher = string_nextinlist(&expciphers, &sep, big_buffer,
663 big_buffer_size)) != NULL)
666 BOOL exclude = cipher[0] == '!';
667 if (first && !exclude) cipher_priority[0] = 0;
670 for (i = 0; i < sizeof(cipher_index)/sizeof(pri_item); i++)
672 uschar *ss = strstric(cipher, cipher_index[i].name, FALSE);
675 uschar *endss = ss + Ustrlen(cipher_index[i].name);
676 if ((ss == cipher || !isalnum(ss[-1])) && !isalnum(*endss))
679 remove_ciphers(cipher_priority, cipher_index[i].values);
682 if (!add_ciphers(cipher_priority,
683 sizeof(cipher_priority)/sizeof(pri_item),
684 cipher_index[i].values))
686 log_write(0, LOG_MAIN|LOG_PANIC, "GnuTLS init failed: cipher "
687 "priority table overflow");
688 gnutls_deinit(session);
699 int *ptr = cipher_priority;
700 debug_printf("adjusted cipher priorities:");
701 while (*ptr != 0) debug_printf(" %d", *ptr++);
706 /* Define the various priorities */
708 gnutls_cipher_set_priority(session, cipher_priority);
709 gnutls_compression_set_priority(session, comp_priority);
710 gnutls_kx_set_priority(session, kx_priority);
711 gnutls_protocol_set_priority(session, protocol_priority);
712 gnutls_mac_set_priority(session, mac_priority);
714 gnutls_cred_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
716 gnutls_dh_set_prime_bits(session, DH_BITS);
718 /* Request or demand a certificate of the peer, as configured. This will
719 happen only in a server. */
721 if (verify_requirement != VERIFY_NONE)
722 gnutls_certificate_server_set_request(session,
723 (verify_requirement == VERIFY_OPTIONAL)?
724 GNUTLS_CERT_REQUEST : GNUTLS_CERT_REQUIRE);
726 gnutls_db_set_cache_expiration(session, ssl_session_timeout);
728 DEBUG(D_tls) debug_printf("initialized GnuTLS session\n");
734 /*************************************************
735 * Get name of cipher in use *
736 *************************************************/
738 /* The answer is left in a static buffer, and tls_cipher is set to point
741 Argument: pointer to a GnuTLS session
746 construct_cipher_name(gnutls_session session)
748 static uschar cipherbuf[256];
750 int bits, c, kx, mac;
753 US gnutls_protocol_get_name(gnutls_protocol_get_version(session)));
754 if (Ustrncmp(ver, "TLS ", 4) == 0) ver[3] = '-'; /* Don't want space */
756 c = gnutls_cipher_get(session);
757 bits = gnutls_cipher_get_key_size(c);
759 mac = gnutls_mac_get(session);
760 kx = gnutls_kx_get(session);
762 string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
763 gnutls_cipher_suite_get_name(kx, c, mac), bits);
764 tls_cipher = cipherbuf;
766 DEBUG(D_tls) debug_printf("cipher: %s\n", cipherbuf);
771 /*************************************************
772 * Start a TLS session in a server *
773 *************************************************/
775 /* This is called when Exim is running as a server, after having received
776 the STARTTLS command. It must respond to that command, and then negotiate
780 require_ciphers list of allowed ciphers
782 Returns: OK on success
783 DEFER for errors before the start of the negotiation
784 FAIL for errors during the negotation; the server can't
789 tls_server_start(uschar *require_ciphers)
793 uschar *expciphers = NULL;
795 /* Check for previous activation */
799 log_write(0, LOG_MAIN, "STARTTLS received in already encrypted "
800 "connection from %s",
801 (sender_fullhost != NULL)? sender_fullhost : US"local process");
802 smtp_printf("554 Already in TLS\r\n");
806 /* Initialize the library. If it fails, it will already have logged the error
807 and sent an SMTP response. */
809 DEBUG(D_tls) debug_printf("initializing GnuTLS as a server\n");
811 rc = tls_init(NULL, tls_certificate, tls_privatekey, tls_verify_certificates,
813 if (rc != OK) return rc;
815 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
818 /* If this is a host for which certificate verification is mandatory or
819 optional, set up appropriately. */
821 tls_certificate_verified = FALSE;
822 verify_requirement = VERIFY_NONE;
824 if (verify_check_host(&tls_verify_hosts) == OK)
825 verify_requirement = VERIFY_REQUIRED;
826 else if (verify_check_host(&tls_try_verify_hosts) == OK)
827 verify_requirement = VERIFY_OPTIONAL;
829 /* Prepare for new connection */
831 tls_session = tls_session_init(GNUTLS_SERVER, expciphers);
832 if (tls_session == NULL)
833 return tls_error(US"tls_session_init", NULL, GNUTLS_E_MEMORY_ERROR);
835 /* Set context and tell client to go ahead, except in the case of TLS startup
836 on connection, where outputting anything now upsets the clients and tends to
837 make them disconnect. We need to have an explicit fflush() here, to force out
838 the response. Other smtp_printf() calls do not need it, because in non-TLS
839 mode, the fflush() happens when smtp_getc() is called. */
843 smtp_printf("220 TLS go ahead\r\n");
847 /* Now negotiate the TLS session. We put our own timer on it, since it seems
848 that the GnuTLS library doesn't. */
850 gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr)fileno(smtp_out));
852 sigalrm_seen = FALSE;
853 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
854 rc = gnutls_handshake(tls_session);
860 Ustrcpy(ssl_errstring, "timed out");
862 Ustrcpy(ssl_errstring, gnutls_strerror(rc));
863 log_write(0, LOG_MAIN,
864 "TLS error on connection from %s (gnutls_handshake): %s",
865 (sender_fullhost != NULL)? sender_fullhost : US"local process",
868 /* It seems that, except in the case of a timeout, we have to close the
869 connection right here; otherwise if the other end is running OpenSSL it hangs
870 until the server times out. */
874 (void)fclose(smtp_out);
875 (void)fclose(smtp_in);
881 DEBUG(D_tls) debug_printf("gnutls_handshake was successful\n");
883 if (verify_requirement != VERIFY_NONE &&
884 !verify_certificate(tls_session, &error))
886 log_write(0, LOG_MAIN,
887 "TLS error on connection from %s: certificate verification failed (%s)",
888 (sender_fullhost != NULL)? sender_fullhost : US"local process", error);
892 construct_cipher_name(tls_session);
894 /* TLS has been set up. Adjust the input functions to read via TLS,
895 and initialize appropriately. */
897 ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
898 ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
899 ssl_xfer_eof = ssl_xfer_error = 0;
901 receive_getc = tls_getc;
902 receive_ungetc = tls_ungetc;
903 receive_feof = tls_feof;
904 receive_ferror = tls_ferror;
906 tls_active = fileno(smtp_out);
914 /*************************************************
915 * Start a TLS session in a client *
916 *************************************************/
918 /* Called from the smtp transport after STARTTLS has been accepted.
921 fd the fd of the connection
922 host connected host (for messages)
924 dhparam DH parameter file
925 certificate certificate file
926 privatekey private key file
927 verify_certs file for certificate verify
928 verify_crl CRL for verify
929 require_ciphers list of allowed ciphers
930 timeout startup timeout
932 Returns: OK/DEFER/FAIL (because using common functions),
933 but for a client, DEFER and FAIL have the same meaning
937 tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
938 uschar *certificate, uschar *privatekey, uschar *verify_certs,
939 uschar *verify_crl, uschar *require_ciphers, int timeout)
941 const gnutls_datum *server_certs;
942 uschar *expciphers = NULL;
944 unsigned int server_certs_size;
947 DEBUG(D_tls) debug_printf("initializing GnuTLS as a client\n");
950 verify_requirement = (verify_certs == NULL)? VERIFY_NONE : VERIFY_REQUIRED;
951 rc = tls_init(host, certificate, privatekey, verify_certs, verify_crl);
952 if (rc != OK) return rc;
954 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
957 tls_session = tls_session_init(GNUTLS_CLIENT, expciphers);
958 if (tls_session == NULL)
959 return tls_error(US "tls_session_init", host, GNUTLS_E_MEMORY_ERROR);
961 gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr)fd);
963 /* There doesn't seem to be a built-in timeout on connection. */
965 sigalrm_seen = FALSE;
967 rc = gnutls_handshake(tls_session);
974 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s]: "
975 "gnutls_handshake timed out", host->name, host->address);
978 else return tls_error(US "gnutls_handshake", host, rc);
981 server_certs = gnutls_certificate_get_peers(tls_session, &server_certs_size);
983 if (server_certs != NULL)
986 gnutls_x509_crt gcert;
988 gnutls_x509_crt_init(&gcert);
989 tls_peerdn = US"unknown";
991 if (gnutls_x509_crt_import(gcert, server_certs, GNUTLS_X509_FMT_DER) == 0)
993 size_t bufsize = sizeof(buff);
994 if (gnutls_x509_crt_get_dn(gcert, CS buff, &bufsize) >= 0)
995 tls_peerdn = string_copy_malloc(buff);
999 /* Should we also verify the hostname here? */
1001 if (verify_requirement != VERIFY_NONE &&
1002 !verify_certificate(tls_session, &error))
1004 log_write(0, LOG_MAIN,
1005 "TLS error on connection to %s [%s]: certificate verification failed (%s)",
1006 host->name, host->address, error);
1010 construct_cipher_name(tls_session); /* Sets tls_cipher */
1017 /*************************************************
1018 * Deal with logging errors during I/O *
1019 *************************************************/
1021 /* We have to get the identity of the peer from saved data.
1024 ec the GnuTLS error code, or 0 if it's a local error
1025 when text identifying read or write
1026 text local error text when ec is 0
1032 record_io_error(int ec, uschar *when, uschar *text)
1034 uschar *additional = US"";
1036 if (ec == GNUTLS_E_FATAL_ALERT_RECEIVED)
1037 additional = string_sprintf(": %s",
1038 gnutls_alert_get_name(gnutls_alert_get(tls_session)));
1040 if (initialized == INITIALIZED_SERVER)
1041 log_write(0, LOG_MAIN, "TLS %s error on connection from %s: %s%s", when,
1042 (sender_fullhost != NULL)? sender_fullhost : US "local process",
1043 (ec == 0)? text : US gnutls_strerror(ec), additional);
1046 log_write(0, LOG_MAIN, "TLS %s error on connection to %s [%s]: %s%s", when,
1047 client_host->name, client_host->address,
1048 (ec == 0)? text : US gnutls_strerror(ec), additional);
1053 /*************************************************
1054 * TLS version of getc *
1055 *************************************************/
1057 /* This gets the next byte from the TLS input buffer. If the buffer is empty,
1058 it refills the buffer via the GnuTLS reading function.
1061 Returns: the next character or EOF
1067 if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
1071 DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1072 (long) tls_session, (long) ssl_xfer_buffer, ssl_xfer_buffer_size);
1074 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
1075 inbytes = gnutls_record_recv(tls_session, CS ssl_xfer_buffer,
1076 ssl_xfer_buffer_size);
1079 /* A zero-byte return appears to mean that the TLS session has been
1080 closed down, not that the socket itself has been closed down. Revert to
1081 non-TLS handling. */
1085 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1087 receive_getc = smtp_getc;
1088 receive_ungetc = smtp_ungetc;
1089 receive_feof = smtp_feof;
1090 receive_ferror = smtp_ferror;
1092 gnutls_deinit(tls_session);
1101 /* Handle genuine errors */
1103 else if (inbytes < 0)
1105 record_io_error(inbytes, US"recv", NULL);
1110 ssl_xfer_buffer_hwm = inbytes;
1111 ssl_xfer_buffer_lwm = 0;
1115 /* Something in the buffer; return next uschar */
1117 return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
1122 /*************************************************
1123 * Read bytes from TLS channel *
1124 *************************************************/
1131 Returns: the number of bytes read
1132 -1 after a failed read
1136 tls_read(uschar *buff, size_t len)
1140 DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1141 (long) tls_session, (long) buff, len);
1143 inbytes = gnutls_record_recv(tls_session, CS buff, len);
1144 if (inbytes > 0) return inbytes;
1147 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1149 else record_io_error(inbytes, US"recv", NULL);
1156 /*************************************************
1157 * Write bytes down TLS channel *
1158 *************************************************/
1165 Returns: the number of bytes after a successful write,
1166 -1 after a failed write
1170 tls_write(const uschar *buff, size_t len)
1175 DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long) buff, left);
1178 DEBUG(D_tls) debug_printf("gnutls_record_send(SSL, %lx, %d)\n", (long)buff,
1180 outbytes = gnutls_record_send(tls_session, CS buff, left);
1182 DEBUG(D_tls) debug_printf("outbytes=%d\n", outbytes);
1185 record_io_error(outbytes, US"send", NULL);
1190 record_io_error(0, US"send", US"TLS channel closed on write");
1203 /*************************************************
1204 * Close down a TLS session *
1205 *************************************************/
1207 /* This is also called from within a delivery subprocess forked from the
1208 daemon, to shut down the TLS library, without actually doing a shutdown (which
1209 would tamper with the TLS session in the parent process).
1211 Arguments: TRUE if gnutls_bye is to be called
1216 tls_close(BOOL shutdown)
1218 if (tls_active < 0) return; /* TLS was not active */
1222 DEBUG(D_tls) debug_printf("tls_close(): shutting down TLS\n");
1223 gnutls_bye(tls_session, GNUTLS_SHUT_WR);
1226 gnutls_deinit(tls_session);
1228 gnutls_global_deinit();
1233 /* End of tls-gnu.c */