[exim-cvs] TLS: Fix handling for server cert/key file SNI r…

Góra strony
Delete this message
Reply to this message
Autor: Exim Git Commits Mailing List
Data:  
Dla: exim-cvs
Temat: [exim-cvs] TLS: Fix handling for server cert/key file SNI re-expansion forced-fail
Gitweb: https://git.exim.org/exim.git/commitdiff/520ef00f56cea3d35688bf4e13599a6e37ba275f
Commit:     520ef00f56cea3d35688bf4e13599a6e37ba275f
Parent:     4f7a93c27e3d43b44c42d3fc503f03b9b42ca622
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Sun Dec 11 15:14:54 2022 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Sun Dec 11 16:54:54 2022 +0000


    TLS: Fix handling for server cert/key file SNI re-expansion forced-fail
---
 doc/doc-docbook/spec.xfpt      |  4 +--
 src/src/tls-gnu.c              | 31 ++++++++++++++++-----
 src/src/tls-openssl.c          | 38 +++++++++++++++++---------
 test/confs/2031                | 62 ++++++++++++++++++++++--------------------
 test/confs/2131                | 60 ++++++++++++++++++++++++++--------------
 test/log/2031                  | 38 +++++++++++++++++++-------
 test/log/2131                  | 44 +++++++++++++++++++++++-------
 test/paniclog/2131             |  8 ++++++
 test/scripts/2000-GnuTLS/2031  | 51 +++++++++++++++++++++++++++++-----
 test/scripts/2100-OpenSSL/2131 | 50 ++++++++++++++++++++++++++++------
 test/stderr/2131               |  8 ++++++
 11 files changed, 288 insertions(+), 106 deletions(-)


diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 75a53786d..cd9259612 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -11763,8 +11763,8 @@ Case and collation order are defined per the system C locale.
SRS decode. See SECT &<<SECTSRS>>& for details.


-.vitem &*inlist&~{*&<&'string1'&>&*}{*&<&'string2'&>&*}*& &&&
-       &*inlisti&~{*&<&'string1'&>&*}{*&<&'string2'&>&*}*&
+.vitem &*inlist&~{*&<&'subject'&>&*}{*&<&'list'&>&*}*& &&&
+       &*inlisti&~{*&<&'subject'&>&*}{*&<&'list'&>&*}*&
 .cindex "string" "comparison"
 .cindex "list" "iterative conditions"
 Both strings are expanded; the second string is treated as a list of simple
diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c
index 69387a3a7..f8cc34406 100644
--- a/src/src/tls-gnu.c
+++ b/src/src/tls-gnu.c
@@ -398,7 +398,8 @@ tls_error_gnu(exim_gnutls_state_st * state, const uschar *prefix, int err,
 {
 return tls_error(prefix,
   state && err == GNUTLS_E_FATAL_ALERT_RECEIVED
-  ? US gnutls_alert_get_name(gnutls_alert_get(state->session))
+  ? string_sprintf("rxd alert: %s",
+          US gnutls_alert_get_name(gnutls_alert_get(state->session)))
   : US gnutls_strerror(err),
   state ? state->host : NULL,
   errstr);
@@ -1293,7 +1294,7 @@ while (cfile = string_nextinlist(&clist, &csep, NULL, 0))


   if (!(kfile = string_nextinlist(&klist, &ksep, NULL, 0)))
     return tls_error(US"cert/key setup: out of keys", NULL, NULL, errstr);
-  else if ((rc = tls_add_certfile(state, NULL, cfile, kfile, errstr)) > 0)
+  else if ((rc = tls_add_certfile(state, NULL, cfile, kfile, errstr)) != OK)
     return rc;
   else
     {
@@ -1810,8 +1811,13 @@ D-H generation. */


 if (!state->lib_state.conn_certs)
   {
-  if (!Expand_check_tlsvar(tls_certificate, errstr))
+  if (  !Expand_check_tlsvar(tls_certificate, errstr)
+     || f.expand_string_forcedfail)
+    {
+    if (f.expand_string_forcedfail)
+      *errstr = US"expansion of tls_certificate failed";
     return DEFER;
+    }


/* certificate is mandatory in server, optional in client */

@@ -1823,8 +1829,14 @@ if (!state->lib_state.conn_certs)
     else
       DEBUG(D_tls) debug_printf("TLS: no client certificate specified; okay\n");


-  if (state->tls_privatekey && !Expand_check_tlsvar(tls_privatekey, errstr))
+  if (  state->tls_privatekey && !Expand_check_tlsvar(tls_privatekey, errstr)
+     || f.expand_string_forcedfail
+     )
+    {
+    if (f.expand_string_forcedfail)
+      *errstr = US"expansion of tls_privatekey failed";
     return DEFER;
+    }


/* tls_privatekey is optional, defaulting to same file as certificate */

@@ -1866,7 +1878,11 @@ if (!state->lib_state.conn_certs)
                   tls_ocsp_file,
 #endif
                   errstr)
-       )  ) return rc;
+       )  )
+      {
+      DEBUG(D_tls) debug_printf("load-cert: '%s'\n", *errstr);
+      return rc;
+      }
     }
   }
 else
@@ -2710,11 +2726,12 @@ if ((rc = tls_expand_session_files(state, &dummy_errstr)) != OK)
   {
   /* If the setup of certs/etc failed before handshake, TLS would not have
   been offered.  The best we can do now is abort. */
-  return GNUTLS_E_APPLICATION_ERROR_MIN;
+  DEBUG(D_tls) debug_printf("expansion for SNI-dependent session files failed\n");
+  return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
   }


rc = tls_set_remaining_x509(state, &dummy_errstr);
-if (rc != OK) return GNUTLS_E_APPLICATION_ERROR_MIN;
+if (rc != OK) return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;

 return 0;
 }
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index db77a1274..3b060cc9c 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -1553,8 +1553,13 @@ else
      )  )
     reexpand_tls_files_for_sni = TRUE;


-  if (!expand_check(state->certificate, US"tls_certificate", &expanded, errstr))
+  if (  !expand_check(state->certificate, US"tls_certificate", &expanded, errstr)
+     || f.expand_string_forcedfail)
+    {
+    if (f.expand_string_forcedfail)
+      *errstr = US"expansion of tls_certificate failed";
     return DEFER;
+    }


   if (expanded)
     if (state->is_server)
@@ -1622,9 +1627,14 @@ else
       if ((err = tls_add_certfile(sctx, state, expanded, errstr)))
     return err;


-  if (  state->privatekey
-     && !expand_check(state->privatekey, US"tls_privatekey", &expanded, errstr))
+  if (     state->privatekey
+        && !expand_check(state->privatekey, US"tls_privatekey", &expanded, errstr)
+     || f.expand_string_forcedfail)
+    {
+    if (f.expand_string_forcedfail)
+      *errstr = US"expansion of tls_privatekey failed";
     return DEFER;
+    }


/* If expansion was forced to fail, key_expanded will be NULL. If the result
of the expansion is an empty string, ignore it also, and assume the private
@@ -2201,13 +2211,13 @@ per https://www.openssl.org/docs/manmaster/man3/SSL_client_hello_cb_fn.html

#ifdef EXIM_HAVE_OPENSSL_TLSEXT
static int
-tls_servername_cb(SSL *s, int *ad ARG_UNUSED, void *arg)
+tls_servername_cb(SSL * s, int * ad ARG_UNUSED, void * arg)
{
-const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
-exim_openssl_state_st *state = (exim_openssl_state_st *) arg;
+const char * servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
+exim_openssl_state_st * state = (exim_openssl_state_st *) arg;
int rc;
int old_pool = store_pool;
-uschar * dummy_errstr;
+uschar * errstr;

if (!servername)
return SSL_TLSEXT_ERR_OK;
@@ -2227,7 +2237,7 @@ if (!reexpand_tls_files_for_sni)
not confident that memcpy wouldn't break some internal reference counting.
Especially since there's a references struct member, which would be off. */

-if (lib_ctx_new(&server_sni, NULL, &dummy_errstr) != OK)
+if (lib_ctx_new(&server_sni, NULL, &errstr) != OK)
goto bad;

/* Not sure how many of these are actually needed, since SSL object
@@ -2247,8 +2257,8 @@ already exists. Might even need this selfsame callback, for reneg? */
SSL_CTX_set_tlsext_servername_arg(server_sni, state);
}

-if (  !init_dh(server_sni, state->dhparam, &dummy_errstr)
-   || !init_ecdh(server_sni, &dummy_errstr)
+if (  !init_dh(server_sni, state->dhparam, &errstr)
+   || !init_ecdh(server_sni, &errstr)
    )
   goto bad;


@@ -2267,7 +2277,7 @@ if (state->u_ocsp.server.file)
   {
   uschar * v_certs = tls_verify_certificates;
   if ((rc = setup_certs(server_sni, &v_certs, tls_crl, NULL,
-            &dummy_errstr)) != OK)
+            &errstr)) != OK)
     goto bad;


if (v_certs && *v_certs)
@@ -2276,14 +2286,16 @@ if (state->u_ocsp.server.file)

/* do this after setup_certs, because this can require the certs for verifying
OCSP information. */
-if ((rc = tls_expand_session_files(server_sni, state, &dummy_errstr)) != OK)
+if ((rc = tls_expand_session_files(server_sni, state, &errstr)) != OK)
goto bad;

DEBUG(D_tls) debug_printf("Switching SSL context.\n");
SSL_set_SSL_CTX(s, server_sni);
return SSL_TLSEXT_ERR_OK;

-bad: return SSL_TLSEXT_ERR_ALERT_FATAL;
+bad:
+ log_write(0, LOG_MAIN|LOG_PANIC, "%s", errstr);
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
}
#endif /* EXIM_HAVE_OPENSSL_TLSEXT */

diff --git a/test/confs/2031 b/test/confs/2031
index af27b2ffd..62577a61a 100644
--- a/test/confs/2031
+++ b/test/confs/2031
@@ -1,4 +1,4 @@
-# Exim test configuration 2030
+# Exim test configuration 2031
# SNI

SERVER =
@@ -17,21 +17,33 @@ remote_max_parallel = 1

tls_advertise_hosts = *

-# Set certificate only if server
-
-tls_certificate = ${if eq {SERVER}{server} \
-    {DIR/aux-fixed/${if eq {$tls_in_sni}{bill} \
-        {exim-ca/example.com/server1.example.com/server1.example.com.pem} \
+tls_certificate = DIR/aux-fixed/${if inlist {$tls_in_sni}{ : normal : badkey : noneistkeyfile : expansionfailkey} \
         {cert1} \
-            }\
-    }fail}
-
-tls_privatekey = ${if eq {SERVER}{server} \
-    {DIR/aux-fixed/${if eq {$tls_in_sni}{bill} \
-        {exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key} \
+        {${if eq {$tls_in_sni}{alternate} \
+          {exim-ca/example.com/server1.example.com/server1.example.com.pem} \
+          {${if eq {$tls_in_sni}{badcert} \
+        {exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key} \
+        {${if eq {$tls_in_sni}{nonexistcertfile} \
+          {nonexistent_file} \
+          fail \
+        } } \
+          } } \
+        } } \
+            }
+
+tls_privatekey = DIR/aux-fixed/${if inlist {$tls_in_sni}{ : normal : badcert : nonexistcertfile : expansionfailedcert} \
         {cert1} \
-            }\
-    }fail}
+        {${if eq {$tls_in_sni}{alternate} \
+          {exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key} \
+          {${if eq {$tls_in_sni}{badkey} \
+        {cert2} \
+        {${if eq {$tls_in_sni}{noneistkeyfile} \
+          {nonexist_file} \
+          fail \
+        } } \
+          } } \
+        } } \
+            }



# ------ ACL ------
@@ -49,7 +61,7 @@ begin routers
client:
driver = accept
condition = ${if !eq {SERVER}{server}}
- transport = send_to_server${if eq{$local_part}{abcd}{2}{1}}
+ transport = send_to_server

server:
driver = redirect
@@ -60,22 +72,14 @@ server:

begin transports

-send_to_server1:
-  driver = smtp
-  allow_localhost
-  hosts = HOSTIPV4
-  port = PORT_D
-  hosts_try_fastopen =    :
-  tls_sni = fred
-
-send_to_server2:
-  driver = smtp
+send_to_server:
+  driver =        smtp
   allow_localhost
-  hosts = HOSTIPV4
-  port = PORT_D
+  hosts =        HOSTIPV4
+  port =        PORT_D
   hosts_try_fastopen =    :
-  tls_sni = bill
-
+  hosts_require_tls =    *
+  tls_sni =        ${local_part}


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

diff --git a/test/confs/2131 b/test/confs/2131
index e4d4ae551..a9924ab5b 100644
--- a/test/confs/2131
+++ b/test/confs/2131
@@ -17,13 +17,34 @@ remote_max_parallel = 1

tls_advertise_hosts = *

-tls_certificate = DIR/aux-fixed/${if eq {$tls_in_sni}{bill} \
-        {exim-ca/example.com/server1.example.com/server1.example.com.pem} \
-        {cert1} }
+tls_certificate = DIR/aux-fixed/${if inlist {$tls_in_sni}{ : normal : badkey : noneistkeyfile : expansionfailkey} \
+        {cert1} \
+        {${if eq {$tls_in_sni}{alternate} \
+          {exim-ca/example.com/server1.example.com/server1.example.com.pem} \
+          {${if eq {$tls_in_sni}{badcert} \
+        {exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key} \
+        {${if eq {$tls_in_sni}{nonexistcertfile} \
+          {nonexistent_file} \
+          fail \
+        } } \
+          } } \
+        } } \
+            }
+
+tls_privatekey = DIR/aux-fixed/${if inlist {$tls_in_sni}{ : normal : badcert : nonexistcertfile : expansionfailedcert} \
+        {cert1} \
+        {${if eq {$tls_in_sni}{alternate} \
+          {exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key} \
+          {${if eq {$tls_in_sni}{badkey} \
+        {cert2} \
+        {${if eq {$tls_in_sni}{noneistkeyfile} \
+          {nonexist_file} \
+          fail \
+        } } \
+          } } \
+        } } \
+            }


-tls_privatekey = DIR/aux-fixed/${if eq {$tls_in_sni}{bill} \
-        {exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key} \
-        {cert1} }


# ------ ACL ------

@@ -40,7 +61,7 @@ begin routers
client:
driver = accept
condition = ${if !eq {SERVER}{server}}
- transport = send_to_server${if eq{$local_part}{abcd}{2}{1}}
+ transport = send_to_server_${if inlist {$local_part}{normal} {1}{2}}

server:
driver = redirect
@@ -51,29 +72,28 @@ server:

begin transports

-send_to_server1:
-  driver = smtp
+send_to_server_1:
+  driver =        smtp
   allow_localhost
-  hosts = HOSTIPV4
-  port = PORT_D
+  hosts =        HOSTIPV4
+  port =        PORT_D
   hosts_try_fastopen =    :
-  tls_sni = fred
-  hosts_require_tls = *
+  hosts_require_tls =    *
+  tls_sni =        ${local_part}
   tls_verify_certificates = DIR/aux-fixed/cert1
   tls_verify_cert_hostnames = :


-send_to_server2:
-  driver = smtp
+send_to_server_2:
+  driver =        smtp
   allow_localhost
-  hosts = HOSTIPV4
-  port = PORT_D
+  hosts =        HOSTIPV4
+  port =        PORT_D
   hosts_try_fastopen =    :
-  tls_sni = bill
-  hosts_require_tls = *
+  hosts_require_tls =    *
+  tls_sni =        ${local_part}
   tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/server1.example.com/ca_chain.pem
   tls_verify_cert_hostnames = :


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


diff --git a/test/log/2031 b/test/log/2031
index 2173cd8fd..387ff4110 100644
--- a/test/log/2031
+++ b/test/log/2031
@@ -1,17 +1,35 @@
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for CALLER@???
-1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER@??? R=client T=send_to_server1 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" C="250 OK id=10HmaY-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for normal@???
+1999-03-02 09:44:33 10HmaX-0005vi-00 => normal@??? R=client T=send_to_server H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" C="250 OK id=10HmaY-0005vi-00"
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for abcd@???
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => abcd@??? R=client T=send_to_server2 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no DN="CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for alternate@???
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => alternate@??? R=client T=send_to_server H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no DN="CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for badkey@???
+1999-03-02 09:44:33 10HmbB-0005vi-00 == badkey@??? R=client T=send_to_server defer (-37) H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: TLS session: (gnutls_handshake): rxd alert: Internal error
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for noneistkeyfile@???
+1999-03-02 09:44:33 10HmbC-0005vi-00 == noneistkeyfile@??? R=client T=send_to_server defer (-37) H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: TLS session: (gnutls_handshake): rxd alert: Internal error
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for expansionfailkey@???
+1999-03-02 09:44:33 10HmbD-0005vi-00 == expansionfailkey@??? R=client T=send_to_server defer (-37) H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: TLS session: (gnutls_handshake): rxd alert: Internal error
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for badcert@???
+1999-03-02 09:44:33 10HmbE-0005vi-00 == badcert@??? R=client T=send_to_server defer (-37) H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: TLS session: (gnutls_handshake): rxd alert: Internal error
+1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for nonexistcertfile@???
+1999-03-02 09:44:33 10HmbF-0005vi-00 == nonexistcertfile@??? R=client T=send_to_server defer (-37) H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: TLS session: (gnutls_handshake): rxd alert: Internal error
+1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for expansionfailedcert@???
+1999-03-02 09:44:33 10HmbG-0005vi-00 == expansionfailedcert@??? R=client T=send_to_server defer (-37) H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: TLS session: (gnutls_handshake): rxd alert: Internal error

******** SERVER ********
1999-03-02 09:44:33 exim x.yz daemon started: pid=p1234, no queue runs, listening for SMTP on port PORT_D
-1999-03-02 09:44:33 SNI <fred>
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@??? H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no SNI=fred S=sss id=E10HmaX-0005vi-00@??? for CALLER@???
-1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <CALLER@???> R=server
+1999-03-02 09:44:33 SNI <normal>
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@??? H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no SNI=normal S=sss id=E10HmaX-0005vi-00@??? for normal@???
+1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <normal@???> R=server
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 SNI <bill>
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@??? H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no SNI=bill S=sss id=E10HmaZ-0005vi-00@??? for abcd@???
-1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <abcd@???> R=server
+1999-03-02 09:44:33 SNI <alternate>
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@??? H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no SNI=alternate S=sss id=E10HmaZ-0005vi-00@??? for alternate@???
+1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <alternate@???> R=server
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (gnutls_handshake): The requested data were not available.
+1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (gnutls_handshake): The requested data were not available.
+1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (gnutls_handshake): The requested data were not available.
+1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (gnutls_handshake): The requested data were not available.
+1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (gnutls_handshake): The requested data were not available.
+1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (gnutls_handshake): The requested data were not available.
diff --git a/test/log/2131 b/test/log/2131
index 4bd677d97..96c4fe980 100644
--- a/test/log/2131
+++ b/test/log/2131
@@ -1,17 +1,41 @@
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for CALLER@???
-1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER@??? R=client T=send_to_server1 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmaY-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for normal@???
+1999-03-02 09:44:33 10HmaX-0005vi-00 => normal@??? R=client T=send_to_server_1 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmaY-0005vi-00"
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for abcd@???
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => abcd@??? R=client T=send_to_server2 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for alternate@???
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => alternate@??? R=client T=send_to_server_2 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for badkey@???
+1999-03-02 09:44:33 10HmbB-0005vi-00 == badkey@??? R=client T=send_to_server_2 defer (-37) H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: TLS session: (SSL_connect): error: <<detail omitted>>
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for noneistkeyfile@???
+1999-03-02 09:44:33 10HmbC-0005vi-00 == noneistkeyfile@??? R=client T=send_to_server_2 defer (-37) H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: TLS session: (SSL_connect): error: <<detail omitted>>
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for expansionfailkey@???
+1999-03-02 09:44:33 10HmbD-0005vi-00 == expansionfailkey@??? R=client T=send_to_server_2 defer (-37) H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: TLS session: (SSL_connect): error: <<detail omitted>>
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for badcert@???
+1999-03-02 09:44:33 10HmbE-0005vi-00 == badcert@??? R=client T=send_to_server_2 defer (-37) H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: TLS session: (SSL_connect): error: <<detail omitted>>
+1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for nonexistcertfile@???
+1999-03-02 09:44:33 10HmbF-0005vi-00 == nonexistcertfile@??? R=client T=send_to_server_2 defer (-37) H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: TLS session: (SSL_connect): error: <<detail omitted>>
+1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss for expansionfailedcert@???
+1999-03-02 09:44:33 10HmbG-0005vi-00 == expansionfailedcert@??? R=client T=send_to_server_2 defer (-37) H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: TLS session: (SSL_connect): error: <<detail omitted>>

******** SERVER ********
1999-03-02 09:44:33 exim x.yz daemon started: pid=p1234, no queue runs, listening for SMTP on port PORT_D
-1999-03-02 09:44:33 SNI <fred>
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@??? H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no SNI=fred S=sss id=E10HmaX-0005vi-00@??? for CALLER@???
-1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <CALLER@???> R=server
+1999-03-02 09:44:33 SNI <normal>
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@??? H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no SNI=normal S=sss id=E10HmaX-0005vi-00@??? for normal@???
+1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <normal@???> R=server
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 SNI <bill>
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@??? H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no SNI=bill S=sss id=E10HmaZ-0005vi-00@??? for abcd@???
-1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <abcd@???> R=server
+1999-03-02 09:44:33 SNI <alternate>
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@??? H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no SNI=alternate S=sss id=E10HmaZ-0005vi-00@??? for alternate@???
+1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <alternate@???> R=server
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 (SSL_CTX_use_PrivateKey_file file=TESTSUITE/aux-fixed/cert2): error:05800074:x509 certificate routines::key values mismatch
+1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
+1999-03-02 09:44:33 (SSL_CTX_use_PrivateKey_file file=TESTSUITE/aux-fixed/nonexist_file): error:80000002:system library::No such file or directory
+1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
+1999-03-02 09:44:33 expansion of tls_privatekey failed
+1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
+1999-03-02 09:44:33 (SSL_CTX_use_certificate_chain_file file=TESTSUITE/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key): error:0480006C:PEM routines::no start line
+1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
+1999-03-02 09:44:33 (SSL_CTX_use_certificate_chain_file file=TESTSUITE/aux-fixed/nonexistent_file): error:80000002:system library::No such file or directory
+1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
+1999-03-02 09:44:33 expansion of tls_certificate failed
+1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
diff --git a/test/paniclog/2131 b/test/paniclog/2131
new file mode 100644
index 000000000..22ed5322c
--- /dev/null
+++ b/test/paniclog/2131
@@ -0,0 +1,8 @@
+
+******** SERVER ********
+1999-03-02 09:44:33 (SSL_CTX_use_PrivateKey_file file=TESTSUITE/aux-fixed/cert2): error:05800074:x509 certificate routines::key values mismatch
+1999-03-02 09:44:33 (SSL_CTX_use_PrivateKey_file file=TESTSUITE/aux-fixed/nonexist_file): error:80000002:system library::No such file or directory
+1999-03-02 09:44:33 expansion of tls_privatekey failed
+1999-03-02 09:44:33 (SSL_CTX_use_certificate_chain_file file=TESTSUITE/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key): error:0480006C:PEM routines::no start line
+1999-03-02 09:44:33 (SSL_CTX_use_certificate_chain_file file=TESTSUITE/aux-fixed/nonexistent_file): error:80000002:system library::No such file or directory
+1999-03-02 09:44:33 expansion of tls_certificate failed
diff --git a/test/scripts/2000-GnuTLS/2031 b/test/scripts/2000-GnuTLS/2031
index d302738fd..fdf17f705 100644
--- a/test/scripts/2000-GnuTLS/2031
+++ b/test/scripts/2000-GnuTLS/2031
@@ -1,19 +1,56 @@
# TLS server: SNI used to select certificate
+#
+# The interesting output is the DN of server logged by the client
gnutls
exim -DSERVER=server -bd -oX PORT_D
****
-# Extended: certificate choice is unchanged by received SNI
-exim CALLER@???
+# certificate choice is unchanged by a received SNI
+exim -odf normal@???
Test message.
****
-sleep 1
#
#
-# Extended: server uses SNI to choose certificate
-exim abcd@???
-Test message.
+# server uses SNI to choose certificate
+exim -odf alternate@???
+****
+#
+# server picks a key file with bad content
+exim -odf badkey@???
+****
+sudo rm DIR/spool/db/retry
+#
+# server picks a non-existing filenam for key
+exim -odf noneistkeyfile@???
****
-sleep 1
+sudo rm DIR/spool/db/retry
+#
+#
+# server gets an expansion-fail for the keyfile
+exim -odf expansionfailkey@???
+****
+sudo rm DIR/spool/db/retry
+#
+#
+#
+#
+# server picks a cert file with bad content
+exim -odf badcert@???
+****
+sudo rm DIR/spool/db/retry
+#
+# server picks a non-existing filenam for cert
+exim -odf nonexistcertfile@???
+****
+sudo rm DIR/spool/db/retry
+#
+#
+# server picks a non-existing filenam for cert
+exim -odf expansionfailedcert@???
+****
+sudo rm DIR/spool/db/retry
+#
+#
#
#
killdaemon
+no_msglog_check
diff --git a/test/scripts/2100-OpenSSL/2131 b/test/scripts/2100-OpenSSL/2131
index c1029bb8f..9a0885308 100644
--- a/test/scripts/2100-OpenSSL/2131
+++ b/test/scripts/2100-OpenSSL/2131
@@ -1,20 +1,54 @@
# TLS server: SNI used to select certificate
#
+# The interesting output is the DN of server logged by the client
exim -DSERVER=server -bd -oX PORT_D
****
-# Extended: certificate choice is unchanged by received SNI
-exim CALLER@???
+# certificate choice is unchanged by a received SNI
+exim -odf normal@???
Test message.
****
-sleep 2
#
#
-# Extended: server uses SNI to change certificate
-exim abcd@???
-Test message.
+# server uses SNI to choose certificate
+exim -odf alternate@???
+****
+#
+# server picks a key file with bad content
+exim -odf badkey@???
+****
+sudo rm DIR/spool/db/retry
+#
+# server picks a non-existing filenam for key
+exim -odf noneistkeyfile@???
****
-millisleep 500
+sudo rm DIR/spool/db/retry
+#
+#
+# server gets an expansion-fail for the keyfile
+exim -odf expansionfailkey@???
+****
+sudo rm DIR/spool/db/retry
+#
+#
+#
+#
+# server picks a cert file with bad content
+exim -odf badcert@???
+****
+sudo rm DIR/spool/db/retry
+#
+# server picks a non-existing filenam for cert
+exim -odf nonexistcertfile@???
+****
+sudo rm DIR/spool/db/retry
+#
+# server gets an expansion-fail for the certfile
+exim -odf expansionfailedcert@???
+****
+sudo rm DIR/spool/db/retry
+#
+#
#
#
killdaemon
-sleep 2
+no_msglog_check
diff --git a/test/stderr/2131 b/test/stderr/2131
new file mode 100644
index 000000000..22ed5322c
--- /dev/null
+++ b/test/stderr/2131
@@ -0,0 +1,8 @@
+
+******** SERVER ********
+1999-03-02 09:44:33 (SSL_CTX_use_PrivateKey_file file=TESTSUITE/aux-fixed/cert2): error:05800074:x509 certificate routines::key values mismatch
+1999-03-02 09:44:33 (SSL_CTX_use_PrivateKey_file file=TESTSUITE/aux-fixed/nonexist_file): error:80000002:system library::No such file or directory
+1999-03-02 09:44:33 expansion of tls_privatekey failed
+1999-03-02 09:44:33 (SSL_CTX_use_certificate_chain_file file=TESTSUITE/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key): error:0480006C:PEM routines::no start line
+1999-03-02 09:44:33 (SSL_CTX_use_certificate_chain_file file=TESTSUITE/aux-fixed/nonexistent_file): error:80000002:system library::No such file or directory
+1999-03-02 09:44:33 expansion of tls_certificate failed