Implement dane_require_tls_ciphers (theoretically)
[exim.git] / src / src / tls-openssl.c
index 4dfeac06d35f12586174fe042ca2af6d5a641f0d..c142bd05926dcab759a61484eeba75886c570187 100644 (file)
@@ -152,7 +152,6 @@ typedef struct tls_ext_ctx_cb {
   uschar *certificate;
   uschar *privatekey;
   BOOL is_server;
-  STACK_OF(X509_NAME) * acceptable_certnames;
 #ifndef DISABLE_OCSP
   STACK_OF(X509) *verify_stack;                /* chain for verifying the proof */
   union {
@@ -905,7 +904,7 @@ We do not free the stack since it could be needed a second time for
 SNI handling.
 
 Separately we might try to replace using OCSP_basic_verify() - which seems to not
-be a public interface into the OpenSSL library (there's no manual entry) - 
+be a public interface into the OpenSSL library (there's no manual entry) -
 But what with?  We also use OCSP_basic_verify in the client stapling callback.
 And there we NEED it; we must verify that status... unless the
 library does it for us anyway?  */
@@ -1511,7 +1510,6 @@ cbinfo = store_malloc(sizeof(tls_ext_ctx_cb));
 cbinfo->certificate = certificate;
 cbinfo->privatekey = privatekey;
 cbinfo->is_server = host==NULL;
-cbinfo->acceptable_certnames = NULL;
 #ifndef DISABLE_OCSP
 cbinfo->verify_stack = NULL;
 if (!host)
@@ -1859,21 +1857,11 @@ if (expcerts && *expcerts)
       */
       if (file)
        {
-       tls_ext_ctx_cb * cbinfo = host
-         ? client_static_cbinfo : server_static_cbinfo;
-       STACK_OF(X509_NAME) * names;
-
-       if ((names = cbinfo->acceptable_certnames))
-         {
-         sk_X509_NAME_pop_free(names, X509_NAME_free);
-         cbinfo->acceptable_certnames = NULL;
-         }
-       names = SSL_load_client_CA_file(CS file);
+       STACK_OF(X509_NAME) * names = SSL_load_client_CA_file(CS file);
 
        SSL_CTX_set_client_CA_list(sctx, names);
        DEBUG(D_tls) debug_printf("Added %d certificate authorities.\n",
                                    sk_X509_NAME_num(names));
-       cbinfo->acceptable_certnames = names;
        }
       }
     }
@@ -2113,7 +2101,7 @@ DEBUG(D_tls)
  */
 if (!ssl_xfer_buffer) ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
 ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
-ssl_xfer_eof = ssl_xfer_error = 0;
+ssl_xfer_eof = ssl_xfer_error = FALSE;
 
 receive_getc = tls_getc;
 receive_getbuf = tls_getbuf;
@@ -2312,8 +2300,23 @@ if (rc != OK) return rc;
 tls_out.certificate_verified = FALSE;
 client_verify_callback_called = FALSE;
 
-if (!expand_check(ob->tls_require_ciphers, US"tls_require_ciphers",
-    &expciphers, errstr))
+expciphers = NULL;
+#ifdef SUPPORT_DANE
+if (tlsa_dnsa)
+  {
+  /* We fall back to tls_require_ciphers if unset, empty or forced failure, but
+  other failures should be treated as problems. */
+  if (ob->dane_require_tls_ciphers &&
+      !expand_check(ob->dane_require_tls_ciphers, US"dane_require_tls_ciphers",
+        &expciphers, errstr))
+    return FAIL;
+  if (expciphers && *expciphers == '\0')
+    expciphers = NULL;
+  }
+#endif
+if (!expciphers &&
+    !expand_check(ob->tls_require_ciphers, US"tls_require_ciphers",
+      &expciphers, errstr))
   return FAIL;
 
 /* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
@@ -2488,11 +2491,9 @@ if (error == SSL_ERROR_ZERO_RETURN)
        SSL_shutdown(server_ssl);
 
   sk_X509_pop_free(server_static_cbinfo->verify_stack, X509_free);
-  sk_X509_NAME_pop_free(server_static_cbinfo->acceptable_certnames, X509_NAME_free);
   SSL_free(server_ssl);
   SSL_CTX_free(server_ctx);
   server_static_cbinfo->verify_stack = NULL;
-  server_static_cbinfo->acceptable_certnames = NULL;
   server_ctx = NULL;
   server_ssl = NULL;
   tls_in.active = -1;
@@ -2510,14 +2511,14 @@ else if (error == SSL_ERROR_SSL)
   {
   ERR_error_string(ERR_get_error(), ssl_errstring);
   log_write(0, LOG_MAIN, "TLS error (SSL_read): %s", ssl_errstring);
-  ssl_xfer_error = 1;
+  ssl_xfer_error = TRUE;
   return FALSE;
   }
 
 else if (error != SSL_ERROR_NONE)
   {
   DEBUG(D_tls) debug_printf("Got SSL error %d\n", error);
-  ssl_xfer_error = 1;
+  ssl_xfer_error = TRUE;
   return FALSE;
   }
 
@@ -2769,10 +2770,7 @@ if (shutdown)
 if (is_server)
   {
   sk_X509_pop_free(server_static_cbinfo->verify_stack, X509_free);
-  sk_X509_NAME_pop_free(server_static_cbinfo->acceptable_certnames,
-    X509_NAME_free);
   server_static_cbinfo->verify_stack = NULL;
-  server_static_cbinfo->acceptable_certnames = NULL;
   }
 
 SSL_CTX_free(*ctxp);