DANE/GnuTLS: ignore traditional CA anchor validation in DANE-EE mode
authorJeremy Harris <jgh146exb@wizmail.org>
Wed, 20 Dec 2017 21:14:06 +0000 (21:14 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Wed, 20 Dec 2017 22:03:23 +0000 (22:03 +0000)
Not quite right for a mixed TA+EE set of TLSA records, but better than always-enforcing

12 files changed:
src/src/tls-gnu.c
test/confs/5820
test/confs/5840
test/dnszones-src/db.example.com
test/log/5820
test/log/5840
test/scripts/5820-DANE-GnuTLS/5820
test/scripts/5840-DANE-OpenSSL/5840
test/stderr/5820
test/stderr/5840
test/stdout/5820
test/stdout/5840

index 9f166691a0221e56d4a497046effc87f2d472a63..8c8a00f72c01c5500b57ce295ef98512fe6d2acb 100644 (file)
@@ -1573,7 +1573,7 @@ Returns:
 */
 
 static BOOL
-verify_certificate(exim_gnutls_state_st *state, uschar ** errstr)
+verify_certificate(exim_gnutls_state_st * state, uschar ** errstr)
 {
 int rc;
 uint verify;
@@ -1625,6 +1625,16 @@ else
       goto badcert;
       }
     state->peer_dane_verified = TRUE;
+
+    /* If there were only EE-mode TLSA records present, no checks on cert anchor
+    valididation or cert names are required.  For a TA record only, or a mixed
+    set, do them (we cannot tell if an EE record worked). */
+
+    if (!(tls_out.tlsa_usage & (1 << 2)))
+      {
+      state->peer_cert_verified = TRUE;
+      goto goodcert;
+      }
     }
 #endif
 
@@ -1633,9 +1643,7 @@ else
 
 /* Handle the result of verification. INVALID is set if any others are. */
 
-if (rc < 0 ||
-    verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED)
-   )
+if (rc < 0 || verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED))
   {
   state->peer_cert_verified = FALSE;
   if (!*errstr)
@@ -1676,8 +1684,9 @@ else
       state->peerdn ? state->peerdn : US"<unset>");
   }
 
-state->tlsp->peerdn = state->peerdn;
-return TRUE;
+goodcert:
+  state->tlsp->peerdn = state->peerdn;
+  return TRUE;
 
 badcert:
   gnutls_alert_send(state->session, GNUTLS_AL_FATAL, GNUTLS_A_BAD_CERTIFICATE);
index d4dce2f85fb4dc6dfddce4cf4c0fa5e1cd54b41a..72402881a750f264cd6ac90d5aa9f302107a0134 100644 (file)
@@ -64,7 +64,7 @@ begin transports
 send_to_server:
   driver = smtp
   allow_localhost
-  port = ${if match {$host}{\Ntest.ex$\N} {PORT_D}{25}}
+  port = PORT_D
 
   hosts_try_dane =     *
   hosts_require_dane = HOSTIPV4
index 10ca2111b25dbf938ef1e2801f73407461b1f784..754945d6ea87c83a13702b960b262bb7b6b7da7f 100644 (file)
@@ -69,7 +69,7 @@ begin transports
 send_to_server:
   driver = smtp
   allow_localhost
-  port = ${if match {$host}{\Ntest.ex$\N} {PORT_D}{25}}
+  port = PORT_D
 
   hosts_try_dane =     *
   hosts_require_dane = HOSTIPV4
index bc209ce5a6039679906e32b6672deff1c43ce82d..b00c87d130b4ac060f565a0a10a7321923bcb71a 100644 (file)
@@ -22,4 +22,24 @@ example.com.     NS      exim.example.com.
 
 server1     A       HOSTIPV4
 
+; DANE testing
+
+; a broken dane config where the name does not match in the cert, TA-mode, dane-requested
+; NOTE: the server uses the example.net cert hence the mismatch
+;
+; openssl x509 -in aux-fixed/exim-ca/example.net/CA/CA.pem -fingerprint -sha256 -noout \
+;  | awk -F= '{print $2}' | tr -d : | tr '[A-F]' '[a-f]'
+;
+;
+DNSSEC danebroken7  A       127.0.0.1
+DNSSEC _1225._tcp.danebroken7 TLSA 2 0 1 13646cc92c038932f57f752559271b893045eda39f765fc8369b05b2b9c3ac88
+
+; the same, EE-mode
+;
+; openssl x509 -in aux-fixed/exim-ca/example.net/server1.example.net/server1.example.net.pem -noout -pubkey \
+; | openssl pkey -pubin -outform DER | openssl dgst -sha256 | awk '{print $2}'
+;
+DNSSEC danebroken8  A       127.0.0.1
+DNSSEC _1225._tcp.danebroken8 TLSA 3 1 1 3cc2a6efabd847663b92f827681fd8612fd4d001ea85057d79ea541fb2de02ac
+
 ; End
index 767e70e68712cd2d2a6a42584ba889c017383af0..81d4d0799a62fe9664282972baa48791d6b3069a 100644 (file)
 1999-03-02 09:44:33 10HmbV-0005vi-00 ** CALLER@danebroken6.test.ex R=client T=send_to_server: DANE error: danebroken6.test.ex lookup not DNSSEC
 1999-03-02 09:44:33 10HmbV-0005vi-00 CALLER@danebroken6.test.ex: error ignored
 1999-03-02 09:44:33 10HmbV-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbW-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for CALLER@danebroken7.example.com
+1999-03-02 09:44:33 10HmbW-0005vi-00 DANE attempt failed; TLS connection to danebroken7.example.com [127.0.0.1]: (certificate verification failed): certificate invalid
+1999-03-02 09:44:33 10HmbW-0005vi-00 == CALLER@danebroken7.example.com R=client T=send_to_server defer (-37) H=danebroken7.example.com [127.0.0.1]: TLS session: (certificate verification failed): certificate invalid
+1999-03-02 09:44:33 10HmbX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for CALLER@danebroken8.example.com
+1999-03-02 09:44:33 10HmbX-0005vi-00 => CALLER@danebroken8.example.com R=client T=send_to_server H=danebroken8.example.com [127.0.0.1] X=TLS1.x:ke_RSA_AES_256_CBC_SHAnnn:256 CV=dane DN="CN=server1.example.net" C="250 OK id=10HmbY-0005vi-00"
+1999-03-02 09:44:33 10HmbX-0005vi-00 Completed
 
 ******** SERVER ********
 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
 1999-03-02 09:44:33 10HmbU-0005vi-00 <= <> H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke_RSA_AES_256_CBC_SHAnnn:256 CV=no S=sss id=E10HmbT-0005vi-00@myhost.test.ex for CALLER@danebroken5.test.ex
 1999-03-02 09:44:33 10HmbU-0005vi-00 => :blackhole: <CALLER@danebroken5.test.ex> R=server
 1999-03-02 09:44:33 10HmbU-0005vi-00 Completed
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 TLS error on connection from localhost [127.0.0.1] (recv): A TLS fatal alert has been received.: Certificate is bad
+1999-03-02 09:44:33 TLS error on connection from localhost [127.0.0.1] (send): The specified session has been invalidated for some reason.
+1999-03-02 09:44:33 "rcpt ACL"
+1999-03-02 09:44:33 10HmbY-0005vi-00 <= <> H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke_RSA_AES_256_CBC_SHAnnn:256 CV=no S=sss id=E10HmbX-0005vi-00@myhost.test.ex for CALLER@danebroken8.example.com
+1999-03-02 09:44:33 10HmbY-0005vi-00 => :blackhole: <CALLER@danebroken8.example.com> R=server
+1999-03-02 09:44:33 10HmbY-0005vi-00 Completed
index 2c9a16f0f8cb0200faf3002e4369d19b496abc91..756f442fbb0944dcbd63f8bff0dc3abc87773524 100644 (file)
 1999-03-02 09:44:33 10HmbX-0005vi-00 ** CALLER@danebroken6.test.ex R=client T=send_to_server: DANE error: danebroken6.test.ex lookup not DNSSEC
 1999-03-02 09:44:33 10HmbX-0005vi-00 CALLER@danebroken6.test.ex: error ignored
 1999-03-02 09:44:33 10HmbX-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for CALLER@danebroken7.example.com
+1999-03-02 09:44:33 10HmbY-0005vi-00 DANE attempt failed; TLS connection to danebroken7.example.com [127.0.0.1]: (SSL_connect): error:xxxxxxxx:SSL routines:ssl3_get_server_certificate:certificate verify failed
+1999-03-02 09:44:33 10HmbY-0005vi-00 == CALLER@danebroken7.example.com R=client T=send_to_server defer (-37) H=danebroken7.example.com [127.0.0.1]: TLS session: (SSL_connect): error: <<detail omitted>>
+1999-03-02 09:44:33 10HmbZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for CALLER@danebroken8.example.com
+1999-03-02 09:44:33 10HmbZ-0005vi-00 => CALLER@danebroken8.example.com R=client T=send_to_server H=danebroken8.example.com [127.0.0.1] X=TLSv1:ke-RSA-AES256-SHA:xxx CV=dane DN="/CN=server1.example.net" C="250 OK id=10HmcA-0005vi-00"
+1999-03-02 09:44:33 10HmbZ-0005vi-00 Completed
 
 ******** SERVER ********
 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
 1999-03-02 09:44:33 10HmbW-0005vi-00 <= <> H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLSv1:ke-RSA-AES256-SHA:xxx CV=no S=sss id=E10HmbV-0005vi-00@myhost.test.ex for CALLER@danebroken5.test.ex
 1999-03-02 09:44:33 10HmbW-0005vi-00 => :blackhole: <CALLER@danebroken5.test.ex> R=server
 1999-03-02 09:44:33 10HmbW-0005vi-00 Completed
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 TLS error on connection from localhost (myhost.test.ex) [127.0.0.1] (SSL_accept): error: <<detail omitted>>
+1999-03-02 09:44:33 "rcpt ACL"
+1999-03-02 09:44:33 10HmcA-0005vi-00 <= <> H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLSv1:ke-RSA-AES256-SHA:xxx CV=no S=sss id=E10HmbZ-0005vi-00@myhost.test.ex for CALLER@danebroken8.example.com
+1999-03-02 09:44:33 10HmcA-0005vi-00 => :blackhole: <CALLER@danebroken8.example.com> R=server
+1999-03-02 09:44:33 10HmcA-0005vi-00 Completed
index 84684da53ca6e3b3b00e81f5538c9a7be3169e3e..f5ac4a7feb58391b34877d44e9f0e1afc0d7dd9e 100644 (file)
@@ -103,4 +103,19 @@ Testing
 ****
 #
 killdaemon
+
+
+### A server with a name not matching the cert.  TA-mode; should fail
+exim -DSERVER=server -DDETAILS=cert.net -bd -oX PORT_D
+****
+exim -odf CALLER@danebroken7.example.com
+Testing
+****
+#
+### A server with a name not matching the cert.  EE-mode; should deliver and claim DANE mode
+exim -odf CALLER@danebroken8.example.com
+Testing
+****
+#
+killdaemon
 no_msglog_check
index 7d86621cc223e8ee09b40b0e5f8b3b02c7c98d9b..b1ea2f30720f40fccb4b1824d0a968150ff6e092 100644 (file)
@@ -111,4 +111,19 @@ Testing
 ****
 #
 killdaemon
+
+
+### A server with a name not matching the cert.  TA-mode; should fail
+exim -DSERVER=server -DDETAILS=cert.net -bd -oX PORT_D
+****
+exim -odf CALLER@danebroken7.example.com
+Testing
+****
+#
+### A server with a name not matching the cert.  EE-mode; should deliver and claim DANE mode
+exim -odf CALLER@danebroken8.example.com
+Testing
+****
+#
+killdaemon
 no_msglog_check
index 8cd66384e10128fc0a2782ea042509cd74a022bc..43492b5f7b9e1417e51080252b542567f0985375 100644 (file)
@@ -79,6 +79,8 @@ LOG: unexpected disconnection while reading SMTP command from [127.0.0.1] D=qqs
 ### A server insecurely serving a good TLSA record, dane required (delivery should fail)
 ### A server insecurely serving a good A record, dane requested only (should deliver, non-DANE)
 ### A server insecurely serving a good A record, dane required (delivery should fail)
+### A server with a name not matching the cert.  TA-mode; should fail
+### A server with a name not matching the cert.  EE-mode; should deliver and claim DANE mode
 
 ******** SERVER ********
 ### TLSA (3 1 1)
@@ -98,3 +100,5 @@ LOG: unexpected disconnection while reading SMTP command from [127.0.0.1] D=qqs
 ### A server insecurely serving a good TLSA record, dane required (delivery should fail)
 ### A server insecurely serving a good A record, dane requested only (should deliver, non-DANE)
 ### A server insecurely serving a good A record, dane required (delivery should fail)
+### A server with a name not matching the cert.  TA-mode; should fail
+### A server with a name not matching the cert.  EE-mode; should deliver and claim DANE mode
index 81a8121495ffd9a27bdaed8a7120e281880902ed..62927712615ad81dc9947ab59e422253489eecbd 100644 (file)
@@ -81,6 +81,8 @@ LOG: unexpected disconnection while reading SMTP command from [127.0.0.1] D=qqs
 ### A server insecurely serving a good TLSA record, dane required (delivery should fail)
 ### A server insecurely serving a good A record, dane requested only (should deliver, non-DANE)
 ### A server insecurely serving a good A record, dane required (delivery should fail)
+### A server with a name not matching the cert.  TA-mode; should fail
+### A server with a name not matching the cert.  EE-mode; should deliver and claim DANE mode
 
 ******** SERVER ********
 ### TLSA (3 1 1)
@@ -101,3 +103,5 @@ LOG: unexpected disconnection while reading SMTP command from [127.0.0.1] D=qqs
 ### A server insecurely serving a good TLSA record, dane required (delivery should fail)
 ### A server insecurely serving a good A record, dane requested only (should deliver, non-DANE)
 ### A server insecurely serving a good A record, dane required (delivery should fail)
+### A server with a name not matching the cert.  TA-mode; should fail
+### A server with a name not matching the cert.  EE-mode; should deliver and claim DANE mode
index 49dac098a7f728bcb867f105f45ad68034984aea..35e52c5d15a9b269e66fcea5d26b65284344fdac 100644 (file)
@@ -24,6 +24,8 @@
 ### A server insecurely serving a good TLSA record, dane required (delivery should fail)
 ### A server insecurely serving a good A record, dane requested only (should deliver, non-DANE)
 ### A server insecurely serving a good A record, dane required (delivery should fail)
+### A server with a name not matching the cert.  TA-mode; should fail
+### A server with a name not matching the cert.  EE-mode; should deliver and claim DANE mode
 
 ******** SERVER ********
 ### TLSA (3 1 1)
@@ -43,3 +45,5 @@
 ### A server insecurely serving a good TLSA record, dane required (delivery should fail)
 ### A server insecurely serving a good A record, dane requested only (should deliver, non-DANE)
 ### A server insecurely serving a good A record, dane required (delivery should fail)
+### A server with a name not matching the cert.  TA-mode; should fail
+### A server with a name not matching the cert.  EE-mode; should deliver and claim DANE mode
index 36a3bd158101d483db97d41bce26dba1841dbdff..947f802a7cce6998e6976386a98f00671d3e1504 100644 (file)
@@ -25,6 +25,8 @@
 ### A server insecurely serving a good TLSA record, dane required (delivery should fail)
 ### A server insecurely serving a good A record, dane requested only (should deliver, non-DANE)
 ### A server insecurely serving a good A record, dane required (delivery should fail)
+### A server with a name not matching the cert.  TA-mode; should fail
+### A server with a name not matching the cert.  EE-mode; should deliver and claim DANE mode
 
 ******** SERVER ********
 ### TLSA (3 1 1)
@@ -45,3 +47,5 @@
 ### A server insecurely serving a good TLSA record, dane required (delivery should fail)
 ### A server insecurely serving a good A record, dane requested only (should deliver, non-DANE)
 ### A server insecurely serving a good A record, dane required (delivery should fail)
+### A server with a name not matching the cert.  TA-mode; should fail
+### A server with a name not matching the cert.  EE-mode; should deliver and claim DANE mode