1 /* $Cambridge: exim/src/src/tls-gnu.c,v 1.19 2007/04/13 15:13:47 ph10 Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* Copyright (c) University of Cambridge 1995 - 2007 */
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. In each case there's a default table,
50 and space into which it can be copied and altered. */
52 static const int default_proto_priority[16] = {
57 static int proto_priority[16];
59 static const int default_kx_priority[16] = {
65 static int kx_priority[16];
67 static int default_cipher_priority[16] = {
68 GNUTLS_CIPHER_AES_256_CBC,
69 GNUTLS_CIPHER_AES_128_CBC,
70 GNUTLS_CIPHER_3DES_CBC,
71 GNUTLS_CIPHER_ARCFOUR_128,
74 static int cipher_priority[16];
76 static const int default_mac_priority[16] = {
81 static int mac_priority[16];
83 /* These two are currently not changeable. */
85 static const int comp_priority[16] = { GNUTLS_COMP_NULL, 0 };
86 static const int cert_type_priority[16] = { GNUTLS_CRT_X509, 0 };
88 /* Tables of priority names and equivalent numbers */
90 typedef struct pri_item {
96 static int tls1_codes[] = { GNUTLS_TLS1, 0 };
97 static int ssl3_codes[] = { GNUTLS_SSL3, 0 };
99 static pri_item proto_index[] = {
100 { US"TLS1", tls1_codes },
101 { US"SSL3", ssl3_codes }
105 static int kx_rsa_codes[] = { GNUTLS_KX_RSA,
106 GNUTLS_KX_DHE_RSA, 0 };
107 static int kx_dhe_codes[] = { GNUTLS_KX_DHE_DSS,
108 GNUTLS_KX_DHE_RSA, 0 };
109 static int kx_dhe_dss_codes[] = { GNUTLS_KX_DHE_DSS, 0 };
110 static int kx_dhe_rsa_codes[] = { GNUTLS_KX_DHE_RSA, 0 };
112 static pri_item kx_index[] = {
113 { US"DHE_DSS", kx_dhe_dss_codes },
114 { US"DHE_RSA", kx_dhe_rsa_codes },
115 { US"RSA", kx_rsa_codes },
116 { US"DHE", kx_dhe_codes }
120 static int arcfour_128_codes[] = { GNUTLS_CIPHER_ARCFOUR_128, 0 };
121 static int arcfour_40_codes[] = { GNUTLS_CIPHER_ARCFOUR_40, 0 };
122 static int arcfour_codes[] = { GNUTLS_CIPHER_ARCFOUR_128,
123 GNUTLS_CIPHER_ARCFOUR_40, 0 };
124 static int aes_256_codes[] = { GNUTLS_CIPHER_AES_256_CBC, 0 };
125 static int aes_128_codes[] = { GNUTLS_CIPHER_AES_128_CBC, 0 };
126 static int aes_codes[] = { GNUTLS_CIPHER_AES_256_CBC,
127 GNUTLS_CIPHER_AES_128_CBC, 0 };
128 static int des3_codes[] = { GNUTLS_CIPHER_3DES_CBC, 0 };
130 static pri_item cipher_index[] = {
131 { US"ARCFOUR_128", arcfour_128_codes },
132 { US"ARCFOUR_40", arcfour_40_codes },
133 { US"ARCFOUR", arcfour_codes },
134 { US"AES_256", aes_256_codes },
135 { US"AES_128", aes_128_codes },
136 { US"AES", aes_codes },
137 { US"3DES", des3_codes }
141 static int mac_sha_codes[] = { GNUTLS_MAC_SHA, 0 };
142 static int mac_md5_codes[] = { GNUTLS_MAC_MD5, 0 };
144 static pri_item mac_index[] = {
145 { US"SHA", mac_sha_codes },
146 { US"SHA1", mac_sha_codes },
147 { US"MD5", mac_md5_codes }
152 /*************************************************
154 *************************************************/
156 /* Called from lots of places when errors occur before actually starting to do
157 the TLS handshake, that is, while the session is still in clear. Always returns
158 DEFER for a server and FAIL for a client so that most calls can use "return
159 tls_error(...)" to do this processing and then give an appropriate return. A
160 single function is used for both server and client, because it is called from
161 some shared functions.
164 prefix text to include in the logged error
165 host NULL if setting up a server;
166 the connected host if setting up a client
167 err a GnuTLS error number, or 0 if local error
169 Returns: OK/DEFER/FAIL
173 tls_error(uschar *prefix, host_item *host, int err)
175 uschar *errtext = US"";
176 if (err != 0) errtext = string_sprintf(": %s", gnutls_strerror(err));
179 log_write(0, LOG_MAIN, "TLS error on connection from %s (%s)%s",
180 (sender_fullhost != NULL)? sender_fullhost : US "local process",
186 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s)%s",
187 host->name, host->address, prefix, errtext);
194 /*************************************************
195 * Verify certificate *
196 *************************************************/
198 /* Called after a successful handshake, when certificate verification is
199 required or optional, for both server and client.
202 session GNUTLS session
203 error where to put text giving a reason for failure
209 verify_certificate(gnutls_session session, uschar **error)
212 uschar *dn_string = US"";
213 const gnutls_datum *cert;
214 unsigned int cert_size = 0;
218 /* Get the peer's certificate. If it sent one, extract it's DN, and then
219 attempt to verify the certificate. If no certificate is supplied, verification
220 is forced to fail. */
222 cert = gnutls_certificate_get_peers(session, &cert_size);
226 gnutls_x509_crt gcert;
228 gnutls_x509_crt_init(&gcert);
229 dn_string = US"unknown";
231 if (gnutls_x509_crt_import(gcert, cert, GNUTLS_X509_FMT_DER) == 0)
233 size_t bufsize = sizeof(buff);
234 if (gnutls_x509_crt_get_dn(gcert, CS buff, &bufsize) >= 0)
235 dn_string = string_copy_malloc(buff);
238 verify = gnutls_certificate_verify_peers(session);
242 DEBUG(D_tls) debug_printf("no peer certificate supplied\n");
243 verify = GNUTLS_CERT_INVALID;
244 *error = US"not supplied";
247 /* Handle the result of verification. INVALID seems to be set as well
248 as REVOKED, but leave the test for both. */
250 if ((verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED)) != 0)
252 tls_certificate_verified = FALSE;
253 if (*error == NULL) *error = ((verify & GNUTLS_CERT_REVOKED) != 0)?
254 US"revoked" : US"invalid";
255 if (verify_requirement == VERIFY_REQUIRED)
257 DEBUG(D_tls) debug_printf("TLS certificate verification failed (%s): "
258 "peerdn=%s\n", *error, dn_string);
259 gnutls_alert_send(session, GNUTLS_AL_FATAL, GNUTLS_A_BAD_CERTIFICATE);
260 return FALSE; /* reject */
262 DEBUG(D_tls) debug_printf("TLS certificate verify failure (%s) overridden "
263 "(host in tls_try_verify_hosts): peerdn=%s\n", *error, dn_string);
267 tls_certificate_verified = TRUE;
268 DEBUG(D_tls) debug_printf("TLS certificate verified: peerdn=%s\n",
272 tls_peerdn = dn_string;
273 return TRUE; /* accept */
278 /*************************************************
279 * Setup up DH parameters *
280 *************************************************/
282 /* Generating the D-H parameters may take a long time. They only need to
283 be re-generated every so often, depending on security policy. What we do is to
284 keep these parameters in a file in the spool directory. If the file does not
285 exist, we generate them. This means that it is easy to cause a regeneration.
287 The new file is written as a temporary file and renamed, so that an incomplete
288 file is never present. If two processes both compute some new parameters, you
289 waste a bit of effort, but it doesn't seem worth messing around with locking to
293 host NULL for server, server for client (for error handling)
295 Returns: OK/DEFER/FAIL
299 init_dh(host_item *host)
304 uschar filename[200];
306 /* Initialize the data structures for holding the parameters */
308 ret = gnutls_dh_params_init(&dh_params);
309 if (ret < 0) return tls_error(US"init dh_params", host, ret);
311 /* Set up the name of the cache file */
313 if (!string_format(filename, sizeof(filename), "%s/gnutls-params",
315 return tls_error(US"overlong filename", host, 0);
317 /* Open the cache file for reading and if successful, read it and set up the
320 fd = Uopen(filename, O_RDONLY, 0);
324 if (fstat(fd, &statbuf) < 0)
327 return tls_error(US"TLS cache stat failed", host, 0);
330 m.size = statbuf.st_size;
331 m.data = malloc(m.size);
333 return tls_error(US"memory allocation failed", host, 0);
334 if (read(fd, m.data, m.size) != m.size)
335 return tls_error(US"TLS cache read failed", host, 0);
338 ret = gnutls_dh_params_import_pkcs3(dh_params, &m, GNUTLS_X509_FMT_PEM);
339 if (ret < 0) return tls_error(US"DH params import", host, ret);
340 DEBUG(D_tls) debug_printf("read D-H parameters from file\n");
345 /* If the file does not exist, fall through to compute new data and cache it.
346 If there was any other opening error, it is serious. */
348 else if (errno == ENOENT)
352 debug_printf("parameter cache file %s does not exist\n", filename);
355 return tls_error(string_open_failed(errno, "%s for reading", filename),
358 /* If ret < 0, either the cache file does not exist, or the data it contains
359 is not useful. One particular case of this is when upgrading from an older
360 release of Exim in which the data was stored in a different format. We don't
361 try to be clever and support both formats; we just regenerate new data in this
366 uschar tempfilename[sizeof(filename) + 10];
368 DEBUG(D_tls) debug_printf("generating %d bit Diffie-Hellman key...\n",
370 ret = gnutls_dh_params_generate2(dh_params, DH_BITS);
371 if (ret < 0) return tls_error(US"D-H key generation", host, ret);
373 /* Write the parameters to a file in the spool directory so that we
374 can use them from other Exim processes. */
376 sprintf(CS tempfilename, "%s-%d", filename, (int)getpid());
377 fd = Uopen(tempfilename, O_WRONLY|O_CREAT, 0400);
379 return tls_error(string_open_failed(errno, "%s for writing", filename),
381 (void)fchown(fd, exim_uid, exim_gid); /* Probably not necessary */
383 /* export the parameters in a format that can be generated using GNUTLS'
384 * certtool or other programs.
386 * The commands for certtool are:
387 * $ certtool --generate-dh-params --bits 1024 > params
391 m.data = malloc(m.size);
393 return tls_error(US"memory allocation failed", host, 0);
396 ret = gnutls_dh_params_export_pkcs3(dh_params, GNUTLS_X509_FMT_PEM, m.data,
398 if (ret < 0) return tls_error(US"DH params export", host, ret);
400 m.size = Ustrlen(m.data);
401 if (write(fd, m.data, m.size) != m.size || write(fd, "\n", 1) != 1)
402 return tls_error(US"TLS cache write failed", host, 0);
407 if (rename(CS tempfilename, CS filename) < 0)
408 return tls_error(string_sprintf("failed to rename %s as %s: %s",
409 tempfilename, filename, strerror(errno)), host, 0);
411 DEBUG(D_tls) debug_printf("wrote D-H parameters to file %s\n", filename);
414 DEBUG(D_tls) debug_printf("initialized D-H parameters\n");
421 /*************************************************
422 * Initialize for GnuTLS *
423 *************************************************/
425 /* Called from both server and client code. In the case of a server, errors
426 before actual TLS negotiation return DEFER.
429 host connected host, if client; NULL if server
430 certificate certificate file
431 privatekey private key file
435 Returns: OK/DEFER/FAIL
439 tls_init(host_item *host, uschar *certificate, uschar *privatekey, uschar *cas,
443 uschar *cert_expanded, *key_expanded, *cas_expanded, *crl_expanded;
445 initialized = (host == NULL)? INITIALIZED_SERVER : INITIALIZED_CLIENT;
447 rc = gnutls_global_init();
448 if (rc < 0) return tls_error(US"tls-init", host, rc);
450 /* Create D-H parameters, or read them from the cache file. This function does
451 its own SMTP error messaging. */
454 if (rc != OK) return rc;
456 /* Create the credentials structure */
458 rc = gnutls_certificate_allocate_credentials(&x509_cred);
459 if (rc < 0) return tls_error(US"certificate_allocate_credentials", host, rc);
461 /* This stuff must be done for each session, because different certificates
462 may be required for different sessions. */
464 if (!expand_check(certificate, US"tls_certificate", &cert_expanded))
468 if (privatekey != NULL)
470 if (!expand_check(privatekey, US"tls_privatekey", &key_expanded))
474 /* If expansion was forced to fail, key_expanded will be NULL. If the result of
475 the expansion is an empty string, ignore it also, and assume that the private
476 key is in the same file as the certificate. */
478 if (key_expanded == NULL || *key_expanded == 0)
479 key_expanded = cert_expanded;
481 /* Set the certificate and private keys */
483 if (cert_expanded != NULL)
485 DEBUG(D_tls) debug_printf("certificate file = %s\nkey file = %s\n",
486 cert_expanded, key_expanded);
487 rc = gnutls_certificate_set_x509_key_file(x509_cred, CS cert_expanded,
488 CS key_expanded, GNUTLS_X509_FMT_PEM);
491 uschar *msg = string_sprintf("cert/key setup: cert=%s key=%s",
492 cert_expanded, key_expanded);
493 return tls_error(msg, host, rc);
497 /* A certificate is mandatory in a server, but not in a client */
502 return tls_error(US"no TLS server certificate is specified", host, 0);
503 DEBUG(D_tls) debug_printf("no TLS client certificate is specified\n");
506 /* Set the trusted CAs file if one is provided, and then add the CRL if one is
507 provided. Experiment shows that, if the certificate file is empty, an unhelpful
508 error message is provided. However, if we just refrain from setting anything up
509 in that case, certificate verification fails, which seems to be the correct
516 if (!expand_check(cas, US"tls_verify_certificates", &cas_expanded))
519 if (stat(CS cas_expanded, &statbuf) < 0)
521 log_write(0, LOG_MAIN|LOG_PANIC, "could not stat %s "
522 "(tls_verify_certificates): %s", cas_expanded, strerror(errno));
526 DEBUG(D_tls) debug_printf("verify certificates = %s size=" OFF_T_FMT "\n",
527 cas_expanded, statbuf.st_size);
529 /* If the cert file is empty, there's no point in loading the CRL file. */
531 if (statbuf.st_size > 0)
533 rc = gnutls_certificate_set_x509_trust_file(x509_cred, CS cas_expanded,
534 GNUTLS_X509_FMT_PEM);
535 if (rc < 0) return tls_error(US"setup_certs", host, rc);
537 if (crl != NULL && *crl != 0)
539 if (!expand_check(crl, US"tls_crl", &crl_expanded))
541 DEBUG(D_tls) debug_printf("loading CRL file = %s\n", crl_expanded);
542 rc = gnutls_certificate_set_x509_crl_file(x509_cred, CS crl_expanded,
543 GNUTLS_X509_FMT_PEM);
544 if (rc < 0) return tls_error(US"CRL setup", host, rc);
549 /* Associate the parameters with the x509 credentials structure. */
551 gnutls_certificate_set_dh_params(x509_cred, dh_params);
553 DEBUG(D_tls) debug_printf("initialized certificate stuff\n");
560 /*************************************************
561 * Remove from a priority list *
562 *************************************************/
564 /* Cautiously written so that it will remove duplicates if present.
567 list a zero-terminated list
568 remove_list a zero-terminated list to be removed
574 remove_priority(int *list, int *remove_list)
576 for (; *remove_list != 0; remove_list++)
581 if (*p == *remove_list)
584 do { pp[0] = pp[1]; pp++; } while (*pp != 0);
593 /*************************************************
594 * Add to a priority list *
595 *************************************************/
597 /* Cautiously written to check the list size
600 list a zero-terminated list
601 list_max maximum offset in the list
602 add_list a zero-terminated list to be added
604 Returns: TRUE if OK; FALSE if list overflows
608 add_priority(int *list, int list_max, int *add_list)
611 while (list[next] != 0) next++;
612 while (*add_list != 0)
614 if (next >= list_max) return FALSE;
615 list[next++] = *add_list++;
623 /*************************************************
624 * Adjust a priority list *
625 *************************************************/
627 /* This function is called to adjust the lists of cipher algorithms, MAC
628 algorithms, key-exchange methods, and protocols.
631 plist the appropriate priority list
632 psize the length of the list
633 s the configuation string
634 index the index of recognized strings
635 isize the length of the index
638 which text for an error message
640 Returns: FALSE if the table overflows, else TRUE
644 set_priority(int *plist, int psize, uschar *s, pri_item *index, int isize,
651 while ((t = string_nextinlist(&s, &sep, big_buffer, big_buffer_size)) != NULL)
654 BOOL exclude = t[0] == '!';
655 if (first && !exclude) plist[0] = 0;
657 for (i = 0; i < isize; i++)
659 uschar *ss = strstric(t, index[i].name, FALSE);
662 uschar *endss = ss + Ustrlen(index[i].name);
663 if ((ss == t || !isalnum(ss[-1])) && !isalnum(*endss))
666 remove_priority(plist, index[i].values);
669 if (!add_priority(plist, psize, index[i].values))
671 log_write(0, LOG_MAIN|LOG_PANIC, "GnuTLS init failed: %s "
672 "priority table overflow", which);
684 debug_printf("adjusted %s priorities:", which);
685 while (*ptr != 0) debug_printf(" %d", *ptr++);
695 /*************************************************
696 * Initialize a single GNUTLS session *
697 *************************************************/
699 /* Set the algorithm, the db backend, whether to request certificates etc.
701 TLS in Exim was first implemented using OpenSSL. This has a function to which
702 you pass a list of cipher suites that are permitted/not permitted. GnuTLS works
703 differently. It operates using priority lists for the different components of
706 For compatibility of configuration, we scan a list of cipher suites and set
707 priorities therefrom. However, at the moment, we pay attention only to the bulk
711 side one of GNUTLS_SERVER, GNUTLS_CLIENT
712 expciphers expanded ciphers list or NULL
713 expmac expanded MAC list or NULL
714 expkx expanded key-exchange list or NULL
715 expproto expanded protocol list or NULL
717 Returns: a gnutls_session, or NULL if there is a problem
720 static gnutls_session
721 tls_session_init(int side, uschar *expciphers, uschar *expmac, uschar *expkx,
724 gnutls_session session;
726 gnutls_init(&session, side);
728 /* Initialize the lists of permitted protocols, key-exchange methods, ciphers,
731 memcpy(cipher_priority, default_cipher_priority, sizeof(cipher_priority));
732 memcpy(mac_priority, default_mac_priority, sizeof(mac_priority));
733 memcpy(kx_priority, default_kx_priority, sizeof(kx_priority));
734 memcpy(proto_priority, default_proto_priority, sizeof(proto_priority));
736 /* The names OpenSSL uses in tls_require_ciphers are of the form DES-CBC3-SHA,
737 using hyphen separators. GnuTLS uses underscore separators. So that I can use
738 either form for tls_require_ciphers in my tests, and also for general
739 convenience, we turn hyphens into underscores before scanning the list. */
741 if (expciphers != NULL)
743 uschar *s = expciphers;
744 while (*s != 0) { if (*s == '-') *s = '_'; s++; }
747 if ((expciphers != NULL &&
748 !set_priority(cipher_priority, sizeof(cipher_priority)/sizeof(int),
749 expciphers, cipher_index, sizeof(cipher_index)/sizeof(pri_item),
752 !set_priority(mac_priority, sizeof(mac_priority)/sizeof(int),
753 expmac, mac_index, sizeof(mac_index)/sizeof(pri_item),
756 !set_priority(kx_priority, sizeof(kx_priority)/sizeof(int),
757 expkx, kx_index, sizeof(kx_index)/sizeof(pri_item),
758 US"key-exchange")) ||
760 !set_priority(proto_priority, sizeof(proto_priority)/sizeof(int),
761 expproto, proto_index, sizeof(proto_index)/sizeof(pri_item),
764 gnutls_deinit(session);
768 /* Define the various priorities */
770 gnutls_cipher_set_priority(session, cipher_priority);
771 gnutls_compression_set_priority(session, comp_priority);
772 gnutls_kx_set_priority(session, kx_priority);
773 gnutls_protocol_set_priority(session, proto_priority);
774 gnutls_mac_set_priority(session, mac_priority);
776 gnutls_cred_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
778 gnutls_dh_set_prime_bits(session, DH_BITS);
780 /* Request or demand a certificate of the peer, as configured. This will
781 happen only in a server. */
783 if (verify_requirement != VERIFY_NONE)
784 gnutls_certificate_server_set_request(session,
785 (verify_requirement == VERIFY_OPTIONAL)?
786 GNUTLS_CERT_REQUEST : GNUTLS_CERT_REQUIRE);
788 gnutls_db_set_cache_expiration(session, ssl_session_timeout);
790 DEBUG(D_tls) debug_printf("initialized GnuTLS session\n");
796 /*************************************************
797 * Get name of cipher in use *
798 *************************************************/
800 /* The answer is left in a static buffer, and tls_cipher is set to point
803 Argument: pointer to a GnuTLS session
808 construct_cipher_name(gnutls_session session)
810 static uschar cipherbuf[256];
812 int bits, c, kx, mac;
815 US gnutls_protocol_get_name(gnutls_protocol_get_version(session)));
816 if (Ustrncmp(ver, "TLS ", 4) == 0) ver[3] = '-'; /* Don't want space */
818 c = gnutls_cipher_get(session);
819 bits = gnutls_cipher_get_key_size(c);
821 mac = gnutls_mac_get(session);
822 kx = gnutls_kx_get(session);
824 string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
825 gnutls_cipher_suite_get_name(kx, c, mac), bits);
826 tls_cipher = cipherbuf;
828 DEBUG(D_tls) debug_printf("cipher: %s\n", cipherbuf);
833 /*************************************************
834 * Start a TLS session in a server *
835 *************************************************/
837 /* This is called when Exim is running as a server, after having received
838 the STARTTLS command. It must respond to that command, and then negotiate
842 require_ciphers list of allowed ciphers or NULL
843 require_mac list of allowed MACs or NULL
844 require_kx list of allowed key_exchange methods or NULL
845 require_proto list of allowed protocols or NULL
847 Returns: OK on success
848 DEFER for errors before the start of the negotiation
849 FAIL for errors during the negotation; the server can't
854 tls_server_start(uschar *require_ciphers, uschar *require_mac,
855 uschar *require_kx, uschar *require_proto)
859 uschar *expciphers = NULL;
860 uschar *expmac = NULL;
861 uschar *expkx = NULL;
862 uschar *expproto = NULL;
864 /* Check for previous activation */
868 log_write(0, LOG_MAIN, "STARTTLS received in already encrypted "
869 "connection from %s",
870 (sender_fullhost != NULL)? sender_fullhost : US"local process");
871 smtp_printf("554 Already in TLS\r\n");
875 /* Initialize the library. If it fails, it will already have logged the error
876 and sent an SMTP response. */
878 DEBUG(D_tls) debug_printf("initializing GnuTLS as a server\n");
880 rc = tls_init(NULL, tls_certificate, tls_privatekey, tls_verify_certificates,
882 if (rc != OK) return rc;
884 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers) ||
885 !expand_check(require_mac, US"gnutls_require_mac", &expmac) ||
886 !expand_check(require_kx, US"gnutls_require_kx", &expkx) ||
887 !expand_check(require_proto, US"gnutls_require_proto", &expproto))
890 /* If this is a host for which certificate verification is mandatory or
891 optional, set up appropriately. */
893 tls_certificate_verified = FALSE;
894 verify_requirement = VERIFY_NONE;
896 if (verify_check_host(&tls_verify_hosts) == OK)
897 verify_requirement = VERIFY_REQUIRED;
898 else if (verify_check_host(&tls_try_verify_hosts) == OK)
899 verify_requirement = VERIFY_OPTIONAL;
901 /* Prepare for new connection */
903 tls_session = tls_session_init(GNUTLS_SERVER, expciphers, expmac, expkx,
905 if (tls_session == NULL)
906 return tls_error(US"tls_session_init", NULL, GNUTLS_E_MEMORY_ERROR);
908 /* Set context and tell client to go ahead, except in the case of TLS startup
909 on connection, where outputting anything now upsets the clients and tends to
910 make them disconnect. We need to have an explicit fflush() here, to force out
911 the response. Other smtp_printf() calls do not need it, because in non-TLS
912 mode, the fflush() happens when smtp_getc() is called. */
916 smtp_printf("220 TLS go ahead\r\n");
920 /* Now negotiate the TLS session. We put our own timer on it, since it seems
921 that the GnuTLS library doesn't. */
923 gnutls_transport_set_ptr2(tls_session, (gnutls_transport_ptr)fileno(smtp_in),
924 (gnutls_transport_ptr)fileno(smtp_out));
926 sigalrm_seen = FALSE;
927 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
928 rc = gnutls_handshake(tls_session);
934 Ustrcpy(ssl_errstring, "timed out");
936 Ustrcpy(ssl_errstring, gnutls_strerror(rc));
937 log_write(0, LOG_MAIN,
938 "TLS error on connection from %s (gnutls_handshake): %s",
939 (sender_fullhost != NULL)? sender_fullhost : US"local process",
942 /* It seems that, except in the case of a timeout, we have to close the
943 connection right here; otherwise if the other end is running OpenSSL it hangs
944 until the server times out. */
948 (void)fclose(smtp_out);
949 (void)fclose(smtp_in);
955 DEBUG(D_tls) debug_printf("gnutls_handshake was successful\n");
957 if (verify_requirement != VERIFY_NONE &&
958 !verify_certificate(tls_session, &error))
960 log_write(0, LOG_MAIN,
961 "TLS error on connection from %s: certificate verification failed (%s)",
962 (sender_fullhost != NULL)? sender_fullhost : US"local process", error);
966 construct_cipher_name(tls_session);
968 /* TLS has been set up. Adjust the input functions to read via TLS,
969 and initialize appropriately. */
971 ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
972 ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
973 ssl_xfer_eof = ssl_xfer_error = 0;
975 receive_getc = tls_getc;
976 receive_ungetc = tls_ungetc;
977 receive_feof = tls_feof;
978 receive_ferror = tls_ferror;
979 receive_smtp_buffered = tls_smtp_buffered;
981 tls_active = fileno(smtp_out);
989 /*************************************************
990 * Start a TLS session in a client *
991 *************************************************/
993 /* Called from the smtp transport after STARTTLS has been accepted.
996 fd the fd of the connection
997 host connected host (for messages)
998 addr the first address (not used)
999 dhparam DH parameter file
1000 certificate certificate file
1001 privatekey private key file
1002 verify_certs file for certificate verify
1003 verify_crl CRL for verify
1004 require_ciphers list of allowed ciphers or NULL
1005 require_mac list of allowed MACs or NULL
1006 require_kx list of allowed key_exchange methods or NULL
1007 require_proto list of allowed protocols or NULL
1008 timeout startup timeout
1010 Returns: OK/DEFER/FAIL (because using common functions),
1011 but for a client, DEFER and FAIL have the same meaning
1015 tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
1016 uschar *certificate, uschar *privatekey, uschar *verify_certs,
1017 uschar *verify_crl, uschar *require_ciphers, uschar *require_mac,
1018 uschar *require_kx, uschar *require_proto, int timeout)
1020 const gnutls_datum *server_certs;
1021 uschar *expciphers = NULL;
1022 uschar *expmac = NULL;
1023 uschar *expkx = NULL;
1024 uschar *expproto = NULL;
1026 unsigned int server_certs_size;
1029 DEBUG(D_tls) debug_printf("initializing GnuTLS as a client\n");
1032 verify_requirement = (verify_certs == NULL)? VERIFY_NONE : VERIFY_REQUIRED;
1033 rc = tls_init(host, certificate, privatekey, verify_certs, verify_crl);
1034 if (rc != OK) return rc;
1036 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers) ||
1037 !expand_check(require_mac, US"gnutls_require_mac", &expmac) ||
1038 !expand_check(require_kx, US"gnutls_require_kx", &expkx) ||
1039 !expand_check(require_proto, US"gnutls_require_proto", &expproto))
1042 tls_session = tls_session_init(GNUTLS_CLIENT, expciphers, expmac, expkx,
1045 if (tls_session == NULL)
1046 return tls_error(US "tls_session_init", host, GNUTLS_E_MEMORY_ERROR);
1048 gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr)fd);
1050 /* There doesn't seem to be a built-in timeout on connection. */
1052 sigalrm_seen = FALSE;
1054 rc = gnutls_handshake(tls_session);
1061 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s]: "
1062 "gnutls_handshake timed out", host->name, host->address);
1065 else return tls_error(US "gnutls_handshake", host, rc);
1068 server_certs = gnutls_certificate_get_peers(tls_session, &server_certs_size);
1070 if (server_certs != NULL)
1073 gnutls_x509_crt gcert;
1075 gnutls_x509_crt_init(&gcert);
1076 tls_peerdn = US"unknown";
1078 if (gnutls_x509_crt_import(gcert, server_certs, GNUTLS_X509_FMT_DER) == 0)
1080 size_t bufsize = sizeof(buff);
1081 if (gnutls_x509_crt_get_dn(gcert, CS buff, &bufsize) >= 0)
1082 tls_peerdn = string_copy_malloc(buff);
1086 /* Should we also verify the hostname here? */
1088 if (verify_requirement != VERIFY_NONE &&
1089 !verify_certificate(tls_session, &error))
1091 log_write(0, LOG_MAIN,
1092 "TLS error on connection to %s [%s]: certificate verification failed (%s)",
1093 host->name, host->address, error);
1097 construct_cipher_name(tls_session); /* Sets tls_cipher */
1104 /*************************************************
1105 * Deal with logging errors during I/O *
1106 *************************************************/
1108 /* We have to get the identity of the peer from saved data.
1111 ec the GnuTLS error code, or 0 if it's a local error
1112 when text identifying read or write
1113 text local error text when ec is 0
1119 record_io_error(int ec, uschar *when, uschar *text)
1121 uschar *additional = US"";
1123 if (ec == GNUTLS_E_FATAL_ALERT_RECEIVED)
1124 additional = string_sprintf(": %s",
1125 gnutls_alert_get_name(gnutls_alert_get(tls_session)));
1127 if (initialized == INITIALIZED_SERVER)
1128 log_write(0, LOG_MAIN, "TLS %s error on connection from %s: %s%s", when,
1129 (sender_fullhost != NULL)? sender_fullhost : US "local process",
1130 (ec == 0)? text : US gnutls_strerror(ec), additional);
1133 log_write(0, LOG_MAIN, "TLS %s error on connection to %s [%s]: %s%s", when,
1134 client_host->name, client_host->address,
1135 (ec == 0)? text : US gnutls_strerror(ec), additional);
1140 /*************************************************
1141 * TLS version of getc *
1142 *************************************************/
1144 /* This gets the next byte from the TLS input buffer. If the buffer is empty,
1145 it refills the buffer via the GnuTLS reading function.
1148 Returns: the next character or EOF
1154 if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
1158 DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1159 (long) tls_session, (long) ssl_xfer_buffer, ssl_xfer_buffer_size);
1161 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
1162 inbytes = gnutls_record_recv(tls_session, CS ssl_xfer_buffer,
1163 ssl_xfer_buffer_size);
1166 /* A zero-byte return appears to mean that the TLS session has been
1167 closed down, not that the socket itself has been closed down. Revert to
1168 non-TLS handling. */
1172 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1174 receive_getc = smtp_getc;
1175 receive_ungetc = smtp_ungetc;
1176 receive_feof = smtp_feof;
1177 receive_ferror = smtp_ferror;
1178 receive_smtp_buffered = smtp_buffered;
1180 gnutls_deinit(tls_session);
1189 /* Handle genuine errors */
1191 else if (inbytes < 0)
1193 record_io_error(inbytes, US"recv", NULL);
1198 ssl_xfer_buffer_hwm = inbytes;
1199 ssl_xfer_buffer_lwm = 0;
1203 /* Something in the buffer; return next uschar */
1205 return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
1210 /*************************************************
1211 * Read bytes from TLS channel *
1212 *************************************************/
1219 Returns: the number of bytes read
1220 -1 after a failed read
1224 tls_read(uschar *buff, size_t len)
1228 DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1229 (long) tls_session, (long) buff, len);
1231 inbytes = gnutls_record_recv(tls_session, CS buff, len);
1232 if (inbytes > 0) return inbytes;
1235 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1237 else record_io_error(inbytes, US"recv", NULL);
1244 /*************************************************
1245 * Write bytes down TLS channel *
1246 *************************************************/
1253 Returns: the number of bytes after a successful write,
1254 -1 after a failed write
1258 tls_write(const uschar *buff, size_t len)
1263 DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long) buff, left);
1266 DEBUG(D_tls) debug_printf("gnutls_record_send(SSL, %lx, %d)\n", (long)buff,
1268 outbytes = gnutls_record_send(tls_session, CS buff, left);
1270 DEBUG(D_tls) debug_printf("outbytes=%d\n", outbytes);
1273 record_io_error(outbytes, US"send", NULL);
1278 record_io_error(0, US"send", US"TLS channel closed on write");
1291 /*************************************************
1292 * Close down a TLS session *
1293 *************************************************/
1295 /* This is also called from within a delivery subprocess forked from the
1296 daemon, to shut down the TLS library, without actually doing a shutdown (which
1297 would tamper with the TLS session in the parent process).
1299 Arguments: TRUE if gnutls_bye is to be called
1304 tls_close(BOOL shutdown)
1306 if (tls_active < 0) return; /* TLS was not active */
1310 DEBUG(D_tls) debug_printf("tls_close(): shutting down TLS\n");
1311 gnutls_bye(tls_session, GNUTLS_SHUT_WR);
1314 gnutls_deinit(tls_session);
1316 gnutls_global_deinit();
1321 /* End of tls-gnu.c */