Enforce TLS under DANE when host has TLSA records
authorJeremy Harris <jgh146exb@wizmail.org>
Thu, 4 Sep 2014 21:40:09 +0000 (22:40 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Thu, 4 Sep 2014 22:14:55 +0000 (23:14 +0100)
doc/doc-txt/experimental-spec.txt
src/src/functions.h
src/src/tls-gnu.c
src/src/tls-openssl.c
src/src/transports/smtp.c
src/src/verify.c

index 2f44fce26fb7ff7be6788c832265f4842e70c34a..e7a0d06682e95e507edf0d8c376bb1b6788e9a65 100644 (file)
@@ -1178,6 +1178,10 @@ admins of the target server.   The attack surface presented
 by (a) is thought to be smaller than that of the set
 of root CAs.
 
 by (a) is thought to be smaller than that of the set
 of root CAs.
 
+It also allows the server to declare (implicitly) that
+connections to it should use TLS.  An MITM could simply
+fail to pass on a server's STARTTLS.
+
 DANE scales better than having to maintain (and
 side-channel communicate) copies of server certificates
 for every possible target server.  It also scales
 DANE scales better than having to maintain (and
 side-channel communicate) copies of server certificates
 for every possible target server.  It also scales
@@ -1202,12 +1206,12 @@ There are no changes to Exim specific to server-side
 operation of DANE.
 
 The TLSA record for the server may have "certificate
 operation of DANE.
 
 The TLSA record for the server may have "certificate
-usage" of DANE_TA(2) or DANE_EE(3).  The latter specifies
+usage" of DANE-TA(2) or DANE-EE(3).  The latter specifies
 the End Entity directly, i.e. the certificate involved
 is that of the server (and should be the sole one transmitted
 during the TLS handshake); this is appropriate for a
 single system, using a self-signed certificate.
 the End Entity directly, i.e. the certificate involved
 is that of the server (and should be the sole one transmitted
 during the TLS handshake); this is appropriate for a
 single system, using a self-signed certificate.
-  DANE_TA usage is effectively declaring a specific CA
+  DANE-TA usage is effectively declaring a specific CA
 to be used; this might be a private CA or a public,
 well-known one.  A private CA at simplest is just
 a self-signed certificate which is used to sign
 to be used; this might be a private CA or a public,
 well-known one.  A private CA at simplest is just
 a self-signed certificate which is used to sign
@@ -1219,7 +1223,7 @@ the entire certificate chain from CA to server-certificate.
 If a public CA is used then all clients must be primed with it
 (losing one advantage of DANE) - but the attack surface is
 reduced from all public CAs to that single CA.
 If a public CA is used then all clients must be primed with it
 (losing one advantage of DANE) - but the attack surface is
 reduced from all public CAs to that single CA.
-DANE_TA is commonly used for several services and/or
+DANE-TA is commonly used for several services and/or
 servers, each having a TLSA query-domain CNAME record,
 all of which point to a single TLSA record.
 
 servers, each having a TLSA query-domain CNAME record,
 all of which point to a single TLSA record.
 
@@ -1236,13 +1240,13 @@ is useful for quickly generating TLSA records; and commands like
 
 are workable for 4th-field hashes.
 
 
 are workable for 4th-field hashes.
 
-For use with the DANE_TA model, server certificates
+For use with the DANE-TA model, server certificates
 must have a correct name (SubjectName or SubjectAltName).
 
 The use of OCSP-stapling should be considered, allowing
 for fast revocation of certificates (which would otherwise
 be limited by the DNS TTL on the TLSA records).  However,
 must have a correct name (SubjectName or SubjectAltName).
 
 The use of OCSP-stapling should be considered, allowing
 for fast revocation of certificates (which would otherwise
 be limited by the DNS TTL on the TLSA records).  However,
-this is likely to only be usable with DANE_TA.  NOTE: the
+this is likely to only be usable with DANE-TA.  NOTE: the
 default of requesting OCSP for all hosts is modified iff
 DANE is in use, to:
 
 default of requesting OCSP for all hosts is modified iff
 DANE is in use, to:
 
@@ -1253,10 +1257,10 @@ DANE is in use, to:
 The (new) variable $tls_out_tlsa_usage is a bitfield with
 numbered bits set for TLSA record usage codes.
 The zero above means DANE was not in use,
 The (new) variable $tls_out_tlsa_usage is a bitfield with
 numbered bits set for TLSA record usage codes.
 The zero above means DANE was not in use,
-the four means that only DANE_TA usage TLSA records were
-found. If the definition of hosts_require_ocsp or
-hosts_request_ocsp includes the string "tls_out_tlsa_usage",
-they are re-expanded in time to control the OCSP request.
+the four means that only DANE-TA usage TLSA records were
+found. If the definition of hosts_request_ocsp includes the
+string "tls_out_tlsa_usage", they are re-expanded in time to
+control the OCSP request.
 
 This modification of hosts_request_ocsp is only done if
 it has the default value of "*".  Admins who change it, and
 
 This modification of hosts_request_ocsp is only done if
 it has the default value of "*".  Admins who change it, and
@@ -1271,9 +1275,15 @@ hosts_try_dane and hosts_require_dane.  They do the obvious thing.
 DANE will only be usable if the target host has DNSSEC-secured
 MX, A and TLSA records.
 
 DANE will only be usable if the target host has DNSSEC-secured
 MX, A and TLSA records.
 
+A TLSA lookup will be done if either of the above options match
+and the host-lookup succeded using dnssec.
+If the TLSA lookup succeeds, a TLS connection will be required
+for the host.
+
 (TODO: specify when fallback happens vs. when the host is not used)
 
 If dane is in use the following transport options are ignored:
 (TODO: specify when fallback happens vs. when the host is not used)
 
 If dane is in use the following transport options are ignored:
+  hosts_require_tls
   tls_verify_hosts
   tls_try_verify_hosts
   tls_verify_certificates
   tls_verify_hosts
   tls_try_verify_hosts
   tls_verify_certificates
index fee4429a5454036d7458cce6d3cf5ab45ded86c3..d10a68a31de56882616aa1f4ada025ac894eae17 100644 (file)
@@ -44,7 +44,11 @@ extern uschar * tls_cert_fprt_sha1(void *);
 extern uschar * tls_cert_fprt_sha256(void *);
 
 extern int     tls_client_start(int, host_item *, address_item *,
 extern uschar * tls_cert_fprt_sha256(void *);
 
 extern int     tls_client_start(int, host_item *, address_item *,
-                transport_instance *);
+                transport_instance *
+#ifdef EXPERIMENTAL_DANE
+               , dns_answer *
+#endif
+                               );
 extern void    tls_close(BOOL, BOOL);
 extern int     tls_export_cert(uschar *, size_t, void *);
 extern int     tls_feof(void);
 extern void    tls_close(BOOL, BOOL);
 extern int     tls_export_cert(uschar *, size_t, void *);
 extern int     tls_feof(void);
@@ -66,6 +70,11 @@ extern uschar * tls_field_from_dn(uschar *, uschar *);
 # ifdef EXPERIMENTAL_CERTNAMES
 extern BOOL    tls_is_name_for_cert(uschar *, void *);
 # endif
 # ifdef EXPERIMENTAL_CERTNAMES
 extern BOOL    tls_is_name_for_cert(uschar *, void *);
 # endif
+
+# ifdef EXPERIMENTAL_DANE
+extern int     tlsa_lookup(host_item *, dns_answer *, BOOL, BOOL *);
+# endif
+
 #endif /*SUPPORT_TLS*/
 
 
 #endif /*SUPPORT_TLS*/
 
 
index b7eae17938710a88e925c97c9e351adc9b6ff041..3043e3abc925ff07f2ee9b6ed8a069d118c853a9 100644 (file)
@@ -1761,7 +1761,11 @@ Returns:            OK/DEFER/FAIL (because using common functions),
 int
 tls_client_start(int fd, host_item *host,
     address_item *addr ARG_UNUSED,
 int
 tls_client_start(int fd, host_item *host,
     address_item *addr ARG_UNUSED,
-    transport_instance *tb)
+    transport_instance *tb
+#ifdef EXPERIMENTAL_DANE
+    , dne_answer * unused_tlsa_dnsa
+#endif
+    )
 {
 smtp_transport_options_block *ob =
   (smtp_transport_options_block *)tb->options_block;
 {
 smtp_transport_options_block *ob =
   (smtp_transport_options_block *)tb->options_block;
index 2e95a467af3f7959a4adbbc2944cc449351babda..5056e618876ef19186fe34bb567ebbd85f31be21 100644 (file)
@@ -1677,44 +1677,6 @@ return OK;
 
 
 #ifdef EXPERIMENTAL_DANE
 
 
 #ifdef EXPERIMENTAL_DANE
-static int
-tlsa_lookup(host_item * host, dns_answer * dnsa,
-  BOOL dane_required, BOOL * dane)
-{
-/* move this out to host.c given the similarity to dns_lookup() ? */
-uschar buffer[300];
-uschar * fullname = buffer;
-
-/* TLSA lookup string */
-(void)sprintf(CS buffer, "_%d._tcp.%.256s", host->port, host->name);
-
-switch (dns_lookup(dnsa, buffer, T_TLSA, &fullname))
-  {
-  case DNS_AGAIN:
-    return DEFER; /* just defer this TLS'd conn */
-
-  default:
-  case DNS_FAIL:
-    if (dane_required)
-      {
-      log_write(0, LOG_MAIN, "DANE error: TLSA lookup failed");
-      return FAIL;
-      }
-    break;
-
-  case DNS_SUCCEED:
-    if (!dns_is_secure(dnsa))
-      {
-      log_write(0, LOG_MAIN, "DANE error: TLSA lookup not DNSSEC");
-      return DEFER;
-      }
-    *dane = TRUE;
-    break;
-  }
-return OK;
-}
-
-
 static int
 dane_tlsa_load(SSL * ssl, host_item * host, dns_answer * dnsa)
 {
 static int
 dane_tlsa_load(SSL * ssl, host_item * host, dns_answer * dnsa)
 {
@@ -1783,6 +1745,7 @@ Argument:
   host             connected host (for messages)
   addr             the first address
   tb               transport (always smtp)
   host             connected host (for messages)
   addr             the first address
   tb               transport (always smtp)
+  tlsa_dnsa        tlsa lookup, if DANE, else null
 
 Returns:           OK on success
                    FAIL otherwise - note that tls_error() will not give DEFER
 
 Returns:           OK on success
                    FAIL otherwise - note that tls_error() will not give DEFER
@@ -1791,7 +1754,11 @@ Returns:           OK on success
 
 int
 tls_client_start(int fd, host_item *host, address_item *addr,
 
 int
 tls_client_start(int fd, host_item *host, address_item *addr,
-  transport_instance *tb)
+  transport_instance *tb
+#ifdef EXPERIMENTAL_DANE
+  , dns_answer * tlsa_dnsa
+#endif
+  )
 {
 smtp_transport_options_block * ob =
   (smtp_transport_options_block *)tb->options_block;
 {
 smtp_transport_options_block * ob =
   (smtp_transport_options_block *)tb->options_block;
@@ -1805,34 +1772,9 @@ static uschar cipherbuf[256];
 BOOL request_ocsp = FALSE;
 BOOL require_ocsp = FALSE;
 #endif
 BOOL request_ocsp = FALSE;
 BOOL require_ocsp = FALSE;
 #endif
-#ifdef EXPERIMENTAL_DANE
-dns_answer tlsa_dnsa;
-BOOL dane = FALSE;
-BOOL dane_required;
-#endif
 
 #ifdef EXPERIMENTAL_DANE
 
 #ifdef EXPERIMENTAL_DANE
-tls_out.dane_verified = FALSE;
 tls_out.tlsa_usage = 0;
 tls_out.tlsa_usage = 0;
-dane_required = verify_check_this_host(&ob->hosts_require_dane, NULL,
-                         host->name, host->address, NULL) == OK;
-
-if (host->dnssec == DS_YES)
-  {
-  if(  dane_required
-    || verify_check_this_host(&ob->hosts_try_dane, NULL,
-                         host->name, host->address, NULL) == OK
-    )
-    if ((rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK)
-      return rc;
-  }
-else if (dane_required)
-  {
-  /*XXX a shame we only find this after making tcp & smtp connection */
-  /* move the test earlier? */
-  log_write(0, LOG_MAIN, "DANE error: previous lookup not DNSSEC");
-  return FAIL;
-  }
 #endif
 
 #ifndef DISABLE_OCSP
 #endif
 
 #ifndef DISABLE_OCSP
@@ -1843,7 +1785,7 @@ else if (dane_required)
   else
     {
 # ifdef EXPERIMENTAL_DANE
   else
     {
 # ifdef EXPERIMENTAL_DANE
-    if (  dane
+    if (  tlsa_dnsa
        && ob->hosts_request_ocsp[0] == '*'
        && ob->hosts_request_ocsp[1] == '\0'
        )
        && ob->hosts_request_ocsp[0] == '*'
        && ob->hosts_request_ocsp[1] == '\0'
        )
@@ -1891,7 +1833,7 @@ if (expciphers != NULL)
   }
 
 #ifdef EXPERIMENTAL_DANE
   }
 
 #ifdef EXPERIMENTAL_DANE
-if (dane)
+if (tlsa_dnsa)
   {
   SSL_CTX_set_verify(client_ctx, SSL_VERIFY_PEER, verify_callback_client_dane);
 
   {
   SSL_CTX_set_verify(client_ctx, SSL_VERIFY_PEER, verify_callback_client_dane);
 
@@ -1941,8 +1883,8 @@ if (ob->tls_sni)
   }
 
 #ifdef EXPERIMENTAL_DANE
   }
 
 #ifdef EXPERIMENTAL_DANE
-if (dane)
-  if ((rc = dane_tlsa_load(client_ssl, host, &tlsa_dnsa)) != OK)
+if (tlsa_dnsa)
+  if ((rc = dane_tlsa_load(client_ssl, host, tlsa_dnsa)) != OK)
     return rc;
 #endif
 
     return rc;
 #endif
 
@@ -1980,10 +1922,6 @@ if (request_ocsp)
 client_static_cbinfo->event_action = tb->tpda_event_action;
 #endif
 
 client_static_cbinfo->event_action = tb->tpda_event_action;
 #endif
 
-#ifdef EXPERIMENTAL_TPDA
-client_static_cbinfo->event_action = tb->tpda_event_action;
-#endif
-
 /* There doesn't seem to be a built-in timeout on connection. */
 
 DEBUG(D_tls) debug_printf("Calling SSL_connect\n");
 /* There doesn't seem to be a built-in timeout on connection. */
 
 DEBUG(D_tls) debug_printf("Calling SSL_connect\n");
@@ -1993,7 +1931,7 @@ rc = SSL_connect(client_ssl);
 alarm(0);
 
 #ifdef EXPERIMENTAL_DANE
 alarm(0);
 
 #ifdef EXPERIMENTAL_DANE
-if (dane)
+if (tlsa_dnsa)
   DANESSL_cleanup(client_ssl);
 #endif
 
   DANESSL_cleanup(client_ssl);
 #endif
 
index 7b2a7d5594fcd4244d2f422cf2f6f650a2282f78..9986e80f4b9603cd1d06ba1489596b2dfd244157 100644 (file)
@@ -212,7 +212,7 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   NULL,                /* hosts_try_prdr */
 #endif
 #ifndef DISABLE_OCSP
   NULL,                /* hosts_try_prdr */
 #endif
 #ifndef DISABLE_OCSP
-  US"*",               /* hosts_request_ocsp (except under DANE) */
+  US"*",               /* hosts_request_ocsp (except under DANE; tls_client_start()) */
   NULL,                /* hosts_require_ocsp */
 #endif
   NULL,                /* hosts_require_tls */
   NULL,                /* hosts_require_ocsp */
 #endif
   NULL,                /* hosts_require_tls */
@@ -1148,6 +1148,46 @@ return FALSE;
 
 
 
 
 
 
+#ifdef EXPERIMENTAL_DANE
+int
+tlsa_lookup(host_item * host, dns_answer * dnsa,
+  BOOL dane_required, BOOL * dane)
+{
+/* move this out to host.c given the similarity to dns_lookup() ? */
+uschar buffer[300];
+uschar * fullname = buffer;
+
+/* TLSA lookup string */
+(void)sprintf(CS buffer, "_%d._tcp.%.256s", host->port, host->name);
+
+switch (dns_lookup(dnsa, buffer, T_TLSA, &fullname))
+  {
+  case DNS_AGAIN:
+    return DEFER; /* just defer this TLS'd conn */
+
+  default:
+  case DNS_FAIL:
+    if (dane_required)
+      {
+      log_write(0, LOG_MAIN, "DANE error: TLSA lookup failed");
+      return FAIL;
+      }
+    break;
+
+  case DNS_SUCCEED:
+    if (!dns_is_secure(dnsa))
+      {
+      log_write(0, LOG_MAIN, "DANE error: TLSA lookup not DNSSEC");
+      return DEFER;
+      }
+    *dane = TRUE;
+    break;
+  }
+return OK;
+}
+#endif
+
+
 /*************************************************
 *       Deliver address list to given host       *
 *************************************************/
 /*************************************************
 *       Deliver address list to given host       *
 *************************************************/
@@ -1226,6 +1266,10 @@ BOOL prdr_active;
 #ifdef EXPERIMENTAL_DSN
 BOOL dsn_all_lasthop = TRUE;
 #endif
 #ifdef EXPERIMENTAL_DSN
 BOOL dsn_all_lasthop = TRUE;
 #endif
+#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
+BOOL dane = FALSE;
+dns_answer tlsa_dnsa;
+#endif
 smtp_inblock inblock;
 smtp_outblock outblock;
 int max_rcpt = tblock->max_addresses;
 smtp_inblock inblock;
 smtp_outblock outblock;
 int max_rcpt = tblock->max_addresses;
@@ -1307,6 +1351,36 @@ if (continue_hostname == NULL)
     return DEFER;
     }
 
     return DEFER;
     }
 
+#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
+    {
+    BOOL dane_required;
+
+    tls_out.dane_verified = FALSE;
+    tls_out.tlsa_usage = 0;
+
+    dane_required = verify_check_this_host(&ob->hosts_require_dane, NULL,
+                             host->name, host->address, NULL) == OK;
+
+    if (host->dnssec == DS_YES)
+      {
+      if(  dane_required
+       || verify_check_this_host(&ob->hosts_try_dane, NULL,
+                             host->name, host->address, NULL) == OK
+       )
+       if ((rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK)
+         return rc;
+      }
+    else if (dane_required)
+      {
+      log_write(0, LOG_MAIN, "DANE error: %s lookup not DNSSEC", host->name);
+      return FAIL;
+      }
+
+    if (dane)
+      ob->tls_tempfail_tryclear = FALSE;
+    }
+#endif /*DANE*/
+
   /* Expand the greeting message while waiting for the initial response. (Makes
   sense if helo_data contains ${lookup dnsdb ...} stuff). The expansion is
   delayed till here so that $sending_interface and $sending_port are set. */
   /* Expand the greeting message while waiting for the initial response. (Makes
   sense if helo_data contains ${lookup dnsdb ...} stuff). The expansion is
   delayed till here so that $sending_interface and $sending_port are set. */
@@ -1505,7 +1579,11 @@ if (tls_offered && !suppress_tls &&
   else
   TLS_NEGOTIATE:
     {
   else
   TLS_NEGOTIATE:
     {
-    int rc = tls_client_start(inblock.sock, host, addrlist, tblock);
+    int rc = tls_client_start(inblock.sock, host, addrlist, tblock
+# ifdef EXPERIMENTAL_DANE
+                            , dane ? &tlsa_dnsa : NULL
+# endif
+                            );
 
     /* TLS negotiation failed; give an error. From outside, this function may
     be called again to try in clear on a new connection, if the options permit
 
     /* TLS negotiation failed; give an error. From outside, this function may
     be called again to try in clear on a new connection, if the options permit
@@ -1588,12 +1666,12 @@ if (tls_out.active >= 0)
 /* If the host is required to use a secure channel, ensure that we
 have one. */
 
 /* If the host is required to use a secure channel, ensure that we
 have one. */
 
-else if (  verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
-            host->address, NULL) == OK
-#ifdef EXPERIMENTAL_DANE
-       || verify_check_this_host(&(ob->hosts_require_dane), NULL, host->name,
+else if (
+# ifdef EXPERIMENTAL_DANE
+       dane ||
+# endif
+        verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
             host->address, NULL) == OK
             host->address, NULL) == OK
-#endif
        )
   {
   save_errno = ERRNO_TLSREQUIRED;
        )
   {
   save_errno = ERRNO_TLSREQUIRED;
@@ -1603,7 +1681,7 @@ else if (  verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
                  "the server did not offer TLS support");
   goto TLS_FAILED;
   }
                  "the server did not offer TLS support");
   goto TLS_FAILED;
   }
-#endif
+#endif /*SUPPORT_TLS*/
 
 /* If TLS is active, we have just started it up and re-done the EHLO command,
 so its response needs to be analyzed. If TLS is not active and this is a
 
 /* If TLS is active, we have just started it up and re-done the EHLO command,
 so its response needs to be analyzed. If TLS is not active and this is a
@@ -3299,10 +3377,6 @@ for (cutoff_retry = 0; expired &&
         && ob->tls_tempfail_tryclear
         && verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
              host->address, NULL) != OK
         && ob->tls_tempfail_tryclear
         && verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
              host->address, NULL) != OK
-# ifdef EXPERIMENTAL_DANE
-        && verify_check_this_host(&(ob->hosts_require_dane), NULL, host->name,
-             host->address, NULL) != OK
-# endif
         )
         {
         log_write(0, LOG_MAIN, "TLS session failure: delivering unencrypted "
         )
         {
         log_write(0, LOG_MAIN, "TLS session failure: delivering unencrypted "
index d2ecb9cdeebec18a9c0365a382e52fd0c0279de0..c25e6e2574a1276123a5ea0224c19d18f1d2ec69 100644 (file)
@@ -426,6 +426,10 @@ else
     BOOL esmtp;
     BOOL suppress_tls = FALSE;
     uschar *interface = NULL;  /* Outgoing interface to use; NULL => any */
     BOOL esmtp;
     BOOL suppress_tls = FALSE;
     uschar *interface = NULL;  /* Outgoing interface to use; NULL => any */
+#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
+    BOOL dane = FALSE;
+    dns_answer tlsa_dnsa;
+#endif
     uschar inbuffer[4096];
     uschar outbuffer[1024];
     uschar responsebuffer[4096];
     uschar inbuffer[4096];
     uschar outbuffer[1024];
     uschar responsebuffer[4096];
@@ -478,6 +482,37 @@ else
 
     HDEBUG(D_verify) debug_printf("interface=%s port=%d\n", interface, port);
 
 
     HDEBUG(D_verify) debug_printf("interface=%s port=%d\n", interface, port);
 
+#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
+      {
+      BOOL dane_required;
+      int rc;
+
+      tls_out.dane_verified = FALSE;
+      tls_out.tlsa_usage = 0;
+
+      dane_required = verify_check_this_host(&ob->hosts_require_dane, NULL,
+                               host->name, host->address, NULL) == OK;
+
+      if (host->dnssec == DS_YES)
+       {
+       if(  dane_required
+         || verify_check_this_host(&ob->hosts_try_dane, NULL,
+                               host->name, host->address, NULL) == OK
+         )
+         if ((rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK)
+           return rc;
+       }
+      else if (dane_required)
+       {
+       log_write(0, LOG_MAIN, "DANE error: %s lookup not DNSSEC", host->name);
+       return FAIL;
+       }
+
+      if (dane)
+       ob->tls_tempfail_tryclear = FALSE;
+      }
+#endif  /*DANE*/
+
     /* Set up the buffer for reading SMTP response packets. */
 
     inblock.buffer = inbuffer;
     /* Set up the buffer for reading SMTP response packets. */
 
     inblock.buffer = inbuffer;
@@ -654,7 +689,11 @@ else
        int rc;
 
        ob->command_timeout = callout;
        int rc;
 
        ob->command_timeout = callout;
-        rc = tls_client_start(inblock.sock, host, addr, addr->transport);
+        rc = tls_client_start(inblock.sock, host, addr, addr->transport
+#ifdef EXPERIMENTAL_DANE
+                           , dane ? &tlsa_dnsa : NULL
+#endif
+                           );
        ob->command_timeout = oldtimeout;
 
         /* TLS negotiation failed; give an error.  Try in clear on a new connection,
        ob->command_timeout = oldtimeout;
 
         /* TLS negotiation failed; give an error.  Try in clear on a new connection,
@@ -666,10 +705,6 @@ else
             && !smtps
             && verify_check_this_host(&(ob->hosts_require_tls), NULL,
               host->name, host->address, NULL) != OK
             && !smtps
             && verify_check_this_host(&(ob->hosts_require_tls), NULL,
               host->name, host->address, NULL) != OK
-#ifdef EXPERIMENTAL_DANE
-            && verify_check_this_host(&(ob->hosts_require_dane), NULL,
-              host->name, host->address, NULL) != OK
-#endif
             )
            {
            (void)close(inblock.sock);
             )
            {
            (void)close(inblock.sock);
@@ -704,12 +739,12 @@ else
 
     /* If the host is required to use a secure channel, ensure that we have one. */
     if (tls_out.active < 0)
 
     /* If the host is required to use a secure channel, ensure that we have one. */
     if (tls_out.active < 0)
-      if (  verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
-             host->address, NULL) == OK
+      if (
 #ifdef EXPERIMENTAL_DANE
 #ifdef EXPERIMENTAL_DANE
-        || verify_check_this_host(&(ob->hosts_require_dane), NULL, host->name,
-             host->address, NULL) == OK
+        dane ||
 #endif
 #endif
+         verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
+             host->address, NULL) == OK
         )
         {
         /*save_errno = ERRNO_TLSREQUIRED;*/
         )
         {
         /*save_errno = ERRNO_TLSREQUIRED;*/