[exim-cvs] Add observability variables and provision for avo…

Top Page
Delete this message
Reply to this message
Author: Exim Git Commits Mailing List
Date:  
To: exim-cvs
Subject: [exim-cvs] Add observability variables and provision for avoiding OCSP conflicts
Gitweb: http://git.exim.org/exim.git/commitdiff/594706ea2e56fe8c972eab772bd3e58c7a0c89ab
Commit:     594706ea2e56fe8c972eab772bd3e58c7a0c89ab
Parent:     fde080a4f34a8eb0f92af6dfc7e4e6ae01fd61f8
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Sun Aug 17 00:41:17 2014 +0100
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Sun Aug 17 00:41:17 2014 +0100


    Add observability variables and provision for avoiding OCSP conflicts
---
 doc/doc-txt/experimental-spec.txt |   25 ++++++++++++++++++++++++-
 src/src/expand.c                  |    6 ++++++
 src/src/globals.c                 |    2 ++
 src/src/globals.h                 |    1 +
 src/src/tls-openssl.c             |   32 +++++++++++++++++++++++++-------
 test/confs/5840                   |    3 +++
 6 files changed, 61 insertions(+), 8 deletions(-)


diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt
index b1b89e0..c060a6c 100644
--- a/doc/doc-txt/experimental-spec.txt
+++ b/doc/doc-txt/experimental-spec.txt
@@ -1235,7 +1235,25 @@ 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.
+this is likely to only be usable with DANE_TA.  NOTE: the
+default is to request OCSP for all hosts; the certificate
+chain in DANE_EE usage will be insufficient to validate
+the OCSP proof and verification will fail.  Either disable
+OCSP completely or use the (new) variable $tls_out_tlsa_usage
+like so:
+
+  hosts_request_ocsp = ${if or { {= {4}{$tls_out_tlsa_usage}} \
+                 {= {0}{$tls_out_tlsa_usage}} } \
+                         {*}{}}
+The variable 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.
+
+[ All a bit complicated.  Should we make that definition
+the default?  Should we override the user's definition? ]



For client-side DANE there are two new smtp transport options,
@@ -1260,6 +1278,11 @@ and dnssec_require_domains is ignored.
If verification was successful using DANE then the "CV" item
in the delivery log line will show as "CV=dane".

+There is a new variable $tls_out_dane which will have "yes" if
+verification succeeded using DANE and "no" otherwise (only useful
+in combination with EXPERIMENTAL_TPDA), and a new variable
+$tls_out_tlsa_usage (detailed above).
+

 --------------------------------------------------------------
 End of file
diff --git a/src/src/expand.c b/src/src/expand.c
index e5af63d..ba2c6f7 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -684,6 +684,9 @@ static var_entry var_table[] = {
   { "tls_out_bits",        vtype_int,         &tls_out.bits },
   { "tls_out_certificate_verified", vtype_int,&tls_out.certificate_verified },
   { "tls_out_cipher",      vtype_stringptr,   &tls_out.cipher },
+#ifdef EXPERIMENTAL_DANE
+  { "tls_out_dane",        vtype_bool,        &tls_out.dane_verified },
+#endif
   { "tls_out_ocsp",        vtype_int,         &tls_out.ocsp },
   { "tls_out_ourcert",     vtype_cert,        &tls_out.ourcert },
   { "tls_out_peercert",    vtype_cert,        &tls_out.peercert },
@@ -691,6 +694,9 @@ static var_entry var_table[] = {
 #if defined(SUPPORT_TLS)
   { "tls_out_sni",         vtype_stringptr,   &tls_out.sni },
 #endif
+#ifdef EXPERIMENTAL_DANE
+  { "tls_out_tlsa_usage",  vtype_int,         &tls_out.tlsa_usage },
+#endif


   { "tls_peerdn",          vtype_stringptr,   &tls_in.peerdn },    /* mind the alphabetical order! */
 #if defined(SUPPORT_TLS)
diff --git a/src/src/globals.c b/src/src/globals.c
index d09903d..409c324 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -105,6 +105,7 @@ tls_support tls_in = {
  FALSE,/* tls_certificate_verified */
 #ifdef EXPERIMENTAL_DANE
  FALSE,/* dane_verified */
+ 0,    /* tlsa_usage */
 #endif
  NULL, /* tls_cipher */
  FALSE,/* tls_on_connect */
@@ -121,6 +122,7 @@ tls_support tls_out = {
  FALSE,/* tls_certificate_verified */
 #ifdef EXPERIMENTAL_DANE
  FALSE,/* dane_verified */
+ 0,    /* tlsa_usage */
 #endif
  NULL, /* tls_cipher */
  FALSE,/* tls_on_connect */
diff --git a/src/src/globals.h b/src/src/globals.h
index 6541148..1adda64 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -84,6 +84,7 @@ typedef struct {
   BOOL    certificate_verified; /* Client certificate verified */
 #ifdef EXPERIMENTAL_DANE
   BOOL    dane_verified;        /* ... via DANE */
+  int     tlsa_usage;         /* TLSA record(s) usage */
 #endif
   uschar *cipher;             /* Cipher used */
   BOOL    on_connect;         /* For older MTAs that don't STARTTLS */
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index 144be6f..57b0808 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -1693,6 +1693,8 @@ for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
       return tls_error(US"tlsa load", host, NULL);
     case 1:    break;
     }
+
+  tls_out.tlsa_usage |= 1<<usage;
   }


if (found)
@@ -1745,6 +1747,7 @@ BOOL dane_required;

 #ifdef EXPERIMENTAL_DANE
 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;


@@ -1764,7 +1767,6 @@ else if (dane_required)
log_write(0, LOG_MAIN, "DANE error: previous lookup not DNSSEC");
return FAIL;
}
-
#endif

 #ifndef DISABLE_OCSP
@@ -1855,23 +1857,39 @@ if (ob->tls_sni)
     }
   }


+#ifdef EXPERIMENTAL_DANE
+if (dane)
+  if ((rc = dane_tlsa_load(client_ssl, host, &tlsa_dnsa)) != OK)
+    return rc;
+#endif
+
 #ifndef DISABLE_OCSP
 /* Request certificate status at connection-time.  If the server
 does OCSP stapling we will get the callback (set in tls_init()) */
 if (request_ocsp)
   {
+  const uschar * s;
+  if (  (s = ob->hosts_require_ocsp) && Ustrstr(s, US"tls_out_tlsa_usage")
+     || (s = ob->hosts_request_ocsp) && Ustrstr(s, US"tls_out_tlsa_usage")
+     )
+    {    /* Re-eval now $tls_out_tlsa_usage is populated.  If
+        this means we avoid the OCSP request, we wasted the setup
+    cost in tls_init(). */
+    require_ocsp = verify_check_this_host(&ob->hosts_require_ocsp,
+      NULL, host->name, host->address, NULL) == OK;
+    request_ocsp = require_ocsp ? TRUE
+      : verify_check_this_host(&ob->hosts_request_ocsp,
+      NULL, host->name, host->address, NULL) == OK;
+    }
+  }
+if (request_ocsp)
+  {
   SSL_set_tlsext_status_type(client_ssl, TLSEXT_STATUSTYPE_ocsp);
   client_static_cbinfo->u_ocsp.client.verify_required = require_ocsp;
   tls_out.ocsp = OCSP_NOT_RESP;
   }
 #endif


-#ifdef EXPERIMENTAL_DANE
-if (dane)
-  if ((rc = dane_tlsa_load(client_ssl, host, &tlsa_dnsa)) != OK)
-    return rc;
-#endif
-


/* There doesn't seem to be a built-in timeout on connection. */

diff --git a/test/confs/5840 b/test/confs/5840
index c381ef6..4359b9a 100644
--- a/test/confs/5840
+++ b/test/confs/5840
@@ -67,6 +67,9 @@ send_to_server:

 #  hosts_try_dane = *
   hosts_require_dane = *
+  hosts_request_ocsp = ${if or { {= {4}{$tls_out_tlsa_usage}} \
+                 {= {0}{$tls_out_tlsa_usage}} } \
+                        {*}{}}



# ----- Retry -----