Prereq: "3.5.3"
diff -ur --new-file /var/tmp/postfix-3.5.3/src/global/mail_version.h ./src/global/mail_version.h
--- /var/tmp/postfix-3.5.3/src/global/mail_version.h	2020-06-14 16:52:23.000000000 -0400
+++ ./src/global/mail_version.h	2020-06-27 17:30:07.000000000 -0400
@@ -20,8 +20,8 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE	"20200614"
-#define MAIL_VERSION_NUMBER	"3.5.3"
+#define MAIL_RELEASE_DATE	"20200627"
+#define MAIL_VERSION_NUMBER	"3.5.4"
 
 #ifdef SNAPSHOT
 #define MAIL_VERSION_DATE	"-" MAIL_RELEASE_DATE
diff -ur --new-file /var/tmp/postfix-3.5.3/HISTORY ./HISTORY
--- /var/tmp/postfix-3.5.3/HISTORY	2020-06-10 17:08:14.000000000 -0400
+++ ./HISTORY	2020-06-27 17:18:55.000000000 -0400
@@ -24753,3 +24753,41 @@
 	client. Reported by J��n M��t��, fixed by Viktor Dukhovni.
 	File: tls/tls_misc.c.
 
+20200617
+
+	Bugfix (introduced: Postfix 3.4): the connection_reuse
+	attribute in smtp_tls_policy_maps resulted in an "invalid
+	attribute name" error. Fix by Thorsten Habich. File:
+	smtp/smtp_tls_policy.c.
+
+20200619
+
+	Bugfix (introduced: Postfix 3.4): SMTP over TLS connection
+	reuse was broken for configurations that use explicit trust
+	anchors. Reported by Thorsten Habich. Cause: the tlsproxy
+	client was sending a zero certificate length. File:
+	tls/tls_proxy_client_print.c.
+
+20200620
+
+	Bugfix (introduced: Postfix 3.4): SMTP over TLS connection
+	reuse was broken for configurations that use explicit trust
+	anchors. Reported by Thorsten Habich. Fixed by calling DANE
+	initialization unconditionally (WTF). File: tlsproxy/tlsproxy.c.
+
+20200626
+
+	Bugfix (introduced: Postfix 2.11): The Postfix smtp(8)
+	client did not send the right SNI name when the TLSA base
+	domain was a secure CNAME expansion of the MX hostname (or
+	non-MX nexthop domain). Domains with CNAME expanded MX hosts
+	are not conformant with RFC5321, and so are rare. Even more
+	rare are MX hosts with TLSA records for their CNAME expansion.
+	For this to matter, the remote SMTP server would also have
+	to select its certificate based on the SNI name in such a
+	way that the original MX host would yield a different
+	certificate. Among the ~2 million hosts in the DANE survey,
+	none meet the conditions for returning a different certificate
+	for the expanded CNAME. Therefore, sending the correct SNI
+	name should not break existing mail flows. Fixed by Viktor
+	Dukhovni. File: src/tls/tls_client.c.
diff -ur --new-file /var/tmp/postfix-3.5.3/src/smtp/smtp_tls_policy.c ./src/smtp/smtp_tls_policy.c
--- /var/tmp/postfix-3.5.3/src/smtp/smtp_tls_policy.c	2018-12-26 14:21:49.000000000 -0500
+++ ./src/smtp/smtp_tls_policy.c	2020-06-17 11:19:54.000000000 -0400
@@ -389,6 +389,7 @@
 			 WHERE, name, val);
 		INVALID_RETURN(tls->why, site_level);
 	    }
+	    continue;
 	}
 	msg_warn("%s: invalid attribute name: \"%s\"", WHERE, name);
 	INVALID_RETURN(tls->why, site_level);
diff -ur --new-file /var/tmp/postfix-3.5.3/src/tls/tls_client.c ./src/tls/tls_client.c
--- /var/tmp/postfix-3.5.3/src/tls/tls_client.c	2020-03-08 10:59:02.000000000 -0400
+++ ./src/tls/tls_client.c	2020-06-27 17:13:06.000000000 -0400
@@ -1018,10 +1018,13 @@
 	 * avoid SNI, and there are no plans to support SNI in the Postfix
 	 * SMTP server).
 	 * 
+	 * Per RFC7672, the required SNI name is the TLSA "base domain" (the one
+	 * used to construct the "_25._tcp.<fqdn>" TLSA record DNS query).
+	 * 
 	 * Since the hostname is DNSSEC-validated, it must be a DNS FQDN and
 	 * thererefore valid for use with SNI.
 	 */
-	sni = props->host;
+	sni = props->dane->base_domain;
     } else if (props->sni && *props->sni) {
 	if (strcmp(props->sni, "hostname") == 0)
 	    sni = props->host;
diff -ur --new-file /var/tmp/postfix-3.5.3/src/tls/tls_proxy_client_print.c ./src/tls/tls_proxy_client_print.c
--- /var/tmp/postfix-3.5.3/src/tls/tls_proxy_client_print.c	2019-02-11 08:11:43.000000000 -0500
+++ ./src/tls/tls_proxy_client_print.c	2020-06-19 13:39:34.000000000 -0400
@@ -213,6 +213,7 @@
 	    i2d_X509(tp->cert, &bp);
 	    if ((char *) bp - STR(buf) != len)
 		msg_panic("i2d_X509 failed to encode certificate");
+	    vstring_set_payload_size(buf, len);
 	    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
 			   SEND_ATTR_DATA(TLS_ATTR_CERT, LEN(buf), STR(buf)),
 			   ATTR_TYPE_END);
@@ -258,6 +259,7 @@
 	    i2d_PUBKEY(tp->pkey, &bp);
 	    if ((char *) bp - STR(buf) != len)
 		msg_panic("i2d_PUBKEY failed to encode public key");
+	    vstring_set_payload_size(buf, len);
 	    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
 			   SEND_ATTR_DATA(TLS_ATTR_PKEY, LEN(buf), STR(buf)),
 			   ATTR_TYPE_END);
diff -ur --new-file /var/tmp/postfix-3.5.3/src/tlsproxy/tlsproxy.c ./src/tlsproxy/tlsproxy.c
--- /var/tmp/postfix-3.5.3/src/tlsproxy/tlsproxy.c	2020-05-15 09:29:14.000000000 -0400
+++ ./src/tlsproxy/tlsproxy.c	2020-06-20 14:55:59.000000000 -0400
@@ -997,12 +997,12 @@
     state->client_start_props->ctx = state->appl_state;
     state->client_start_props->fd = state->ciphertext_fd;
     /* These predicates and warning belong inside tls_client_start(). */
-    if (!TLS_DANE_BASED(state->client_start_props->tls_level)
-	|| tls_dane_avail())
-	state->tls_context = tls_client_start(state->client_start_props);
-    else
+    if (!tls_dane_avail()			/* mandatory side effects!! */
+	&&TLS_DANE_BASED(state->client_start_props->tls_level))
 	msg_warn("%s: DANE requested, but not available",
 		 state->client_start_props->namaddr);
+    else
+	state->tls_context = tls_client_start(state->client_start_props);
     if (state->tls_context != 0)
 	return (TLSP_STAT_OK);