]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Merged /httpd/httpd/trunk:r1920744
authorStefan Eissing <icing@apache.org>
Tue, 17 Sep 2024 11:17:23 +0000 (11:17 +0000)
committerStefan Eissing <icing@apache.org>
Tue, 17 Sep 2024 11:17:23 +0000 (11:17 +0000)
  *) mod_tls: removed the experimental module. It now is availble standalone
     from https://github.com/icing/mod_tls. The rustls provided API is not
     stable and does not align with the httpd release cycle.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1920745 13f79535-47bb-0310-9956-ffa450edef68

57 files changed:
.github/workflows/linux.yml
changes-entries/tls_removed.txt [new file with mode: 0644]
docs/manual/mod/allmodules.xml
docs/manual/mod/mod_tls.xml [deleted file]
modules/tls/Makefile.in [deleted file]
modules/tls/config2.m4 [deleted file]
modules/tls/mod_tls.c [deleted file]
modules/tls/mod_tls.h [deleted file]
modules/tls/tls_cache.c [deleted file]
modules/tls/tls_cache.h [deleted file]
modules/tls/tls_cert.c [deleted file]
modules/tls/tls_cert.h [deleted file]
modules/tls/tls_conf.c [deleted file]
modules/tls/tls_conf.h [deleted file]
modules/tls/tls_core.c [deleted file]
modules/tls/tls_core.h [deleted file]
modules/tls/tls_filter.c [deleted file]
modules/tls/tls_filter.h [deleted file]
modules/tls/tls_ocsp.c [deleted file]
modules/tls/tls_ocsp.h [deleted file]
modules/tls/tls_proto.c [deleted file]
modules/tls/tls_proto.h [deleted file]
modules/tls/tls_util.c [deleted file]
modules/tls/tls_util.h [deleted file]
modules/tls/tls_var.c [deleted file]
modules/tls/tls_var.h [deleted file]
modules/tls/tls_version.h [deleted file]
test/modules/tls/__init__.py [deleted file]
test/modules/tls/conf.py [deleted file]
test/modules/tls/conftest.py [deleted file]
test/modules/tls/env.py [deleted file]
test/modules/tls/htdocs/a.mod-tls.test/index.json [deleted file]
test/modules/tls/htdocs/a.mod-tls.test/vars.py [deleted file]
test/modules/tls/htdocs/b.mod-tls.test/dir1/vars.py [deleted file]
test/modules/tls/htdocs/b.mod-tls.test/index.json [deleted file]
test/modules/tls/htdocs/b.mod-tls.test/resp-jitter.py [deleted file]
test/modules/tls/htdocs/b.mod-tls.test/vars.py [deleted file]
test/modules/tls/htdocs/index.html [deleted file]
test/modules/tls/htdocs/index.json [deleted file]
test/modules/tls/test_01_apache.py [deleted file]
test/modules/tls/test_02_conf.py [deleted file]
test/modules/tls/test_03_sni.py [deleted file]
test/modules/tls/test_04_get.py [deleted file]
test/modules/tls/test_05_proto.py [deleted file]
test/modules/tls/test_06_ciphers.py [deleted file]
test/modules/tls/test_07_alpn.py [deleted file]
test/modules/tls/test_08_vars.py [deleted file]
test/modules/tls/test_09_timeout.py [deleted file]
test/modules/tls/test_10_session_id.py [deleted file]
test/modules/tls/test_11_md.py [deleted file]
test/modules/tls/test_12_cauth.py [deleted file]
test/modules/tls/test_13_proxy.py [deleted file]
test/modules/tls/test_14_proxy_ssl.py [deleted file]
test/modules/tls/test_15_proxy_tls.py [deleted file]
test/modules/tls/test_16_proxy_mixed.py [deleted file]
test/modules/tls/test_17_proxy_machine_cert.py [deleted file]
test/travis_run_linux.sh

index e3ff70d341e4b269e05073a23df012c86ad11d95..69c3fd380cf8c311682fd3caba8f6715f22d6d08 100644 (file)
@@ -224,17 +224,6 @@ jobs:
           #     TEST_MD=1
           # -------------------------------------------------------------------------
           ### TODO: if: *condition_not_24x
-          - name: MOD_TLS test suite
-            config: --enable-mods-shared=reallyall --with-mpm=event --enable-mpms-shared=event
-            pkgs: curl python3-pytest nghttp2-client python3-cryptography python3-requests python3-multipart python3-filelock python3-websockets cargo cbindgen
-            env: |
-              APR_VERSION=1.7.4
-              APU_VERSION=1.6.3
-              APU_CONFIG="--with-crypto"
-              RUSTLS_VERSION="v0.13.0"
-              NO_TEST_FRAMEWORK=1
-              TEST_INSTALL=1
-              TEST_MOD_TLS=1
           # -------------------------------------------------------------------------
           ### TODO if: *condition_not_24x
           ### TODO: Fails because :i386 packages are not being found.
diff --git a/changes-entries/tls_removed.txt b/changes-entries/tls_removed.txt
new file mode 100644 (file)
index 0000000..d56a3dc
--- /dev/null
@@ -0,0 +1,4 @@
+  *) mod_tls: removed the experimental module. It now is availble standalone
+     from https://github.com/icing/mod_tls. The rustls provided API is not
+     stable and does not align with the httpd release cycle.
+     [Stefan Eissing]
index 9f45eaafedbb19ed71444a7152ab5433ee8c299a..8fdd483eaa5898fdea82fbba4097765bce0f4839 100644 (file)
   <modulefile>mod_substitute.xml</modulefile>
   <modulefile>mod_suexec.xml</modulefile>
   <modulefile>mod_systemd.xml</modulefile>
-  <modulefile>mod_tls.xml</modulefile>
   <modulefile>mod_unique_id.xml</modulefile>
   <modulefile>mod_unixd.xml</modulefile>
   <modulefile>mod_userdir.xml</modulefile>
diff --git a/docs/manual/mod/mod_tls.xml b/docs/manual/mod/mod_tls.xml
deleted file mode 100644 (file)
index 8e88923..0000000
+++ /dev/null
@@ -1,640 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd">
-<?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?>
-<!-- $LastChangedRevision: 1895285 $ -->
-
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements.  See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<modulesynopsis metafile="mod_tls.xml.meta">
-
-    <name>mod_tls</name>
-    <description>TLS v1.2 and v1.3 implemented in memory-safe Rust via
-        the rustls library
-    </description>
-    <status>Experimental</status>
-    <sourcefile>mod_tls.c</sourcefile>
-    <identifier>tls_module</identifier>
-    <compatibility>Available in version 2.4.52 and later</compatibility>
-    <summary>
-        <p>
-            mod_tls is an alternative to <module>mod_ssl</module> for providing https to a server.
-            It's feature set is a subset, described in more detail below. It can
-            be used as a companion to <module>mod_ssl</module>, e.g. both modules can be loaded at
-            the same time.
-        </p><p>
-            mod_tls, being written in C, used the Rust implementation of TLS named
-            <a href="https://github.com/rustls/rustls">rustls</a> via its C interface
-            <a href="https://github.com/rustls/rustls-ffi">rustls-ffi</a>. This gives
-            <em>memory safe</em> cryptography and protocol handling at comparable
-            performance.
-        </p><p>
-            It can be configured for frontend and backend connections. The configuration
-            directive have been kept mostly similar to <module>mod_ssl</module> ones.
-        </p>
-    </summary>
-    <section id="vhost_context">
-        <title>TLS in a VirtualHost context</title>
-        <highlight language="config">
-Listen 443
-TLSEngine 443
-
-&lt;VirtualHost *:443>
-  ServerName example.net
-  TLSCertificate file_with_certificate.pem file_with_key.pem
-  ...
-&lt;/VirtualHost>
-        </highlight>
-        <p>
-            The above is a minimal configuration. Instead of enabling mod_tls
-            in every virtual host, the port for incoming TLS connections is
-            specified.
-        </p><p>
-            You cannot mix virtual hosts with <module>mod_ssl</module> and mod_tls on the same
-            port. It's either or. SNI and ALPN are supported. You may use several
-            virtual hosts on the same port and a mix of protocols like http/1.1
-            and h2.
-        </p>
-    </section>
-
-        <section id="comparison"><title>Feature Comparison with mod_ssl</title>
-        <p>
-            The table below gives a comparison of feature between
-            <module>mod_ssl</module> and mod_tls. If a feature of <module>mod_ssl</module> is no listed here,
-            it is not supported by mod_tls. The one difference, probably most relevant
-            is the lack for client certificate support in the current version of
-            mod_tls.
-        </p>
-            <table>
-                <tr><th>Feature</th><th>mod_ssl</th><th>mod_tls</th><th>Comment</th></tr>
-<tr><td>Frontend TLS</td><td>yes</td><td>yes</td><td></td></tr>
-<tr><td>Backend TLS</td><td>yes</td><td>yes</td><td></td></tr>
-<tr><td>TLS v1.3</td><td>yes*</td><td>yes</td><td>*)with recent OpenSSL</td></tr>
-<tr><td>TLS v1.2</td><td>yes</td><td>yes</td><td></td></tr>
-<tr><td>TLS v1.0</td><td>yes*</td><td>no</td><td>*)if enabled in OpenSSL</td></tr>
-<tr><td>SNI Virtual Hosts</td><td>yes</td><td>yes</td><td></td></tr>
-<tr><td>Client Certificates</td><td>yes</td><td>no</td><td></td></tr>
-<tr><td>Machine Certificates for Backend</td><td>yes</td><td>yes</td><td></td></tr>
-<tr><td>OCSP Stapling</td><td>yes</td><td>yes*</td><td>*)via <module>mod_md</module></td></tr>
-<tr><td>Backend OCSP check</td><td>yes</td><td>no*</td><td>*)stapling will be verified</td></tr>
-<tr><td>TLS version to allow</td><td>min-max</td><td>min</td><td></td></tr>
-<tr><td>TLS ciphers</td><td>exclusive list</td><td>preferred/suppressed</td><td></td></tr>
-<tr><td>TLS cipher ordering</td><td>client/server</td><td>client/server</td><td></td></tr>
-<tr><td>TLS sessions</td><td>yes</td><td>yes</td><td></td></tr>
-<tr><td>SNI strictness</td><td>default no</td><td>default yes</td><td></td></tr>
-<tr><td>Option EnvVars</td><td>exhaustive</td><td>limited*</td><td>*)see var list</td></tr>
-<tr><td>Option ExportCertData</td><td>client+server</td><td>server</td><td></td></tr>
-<tr><td>Backend CA</td><td>file/dir</td><td>file</td><td></td></tr>
-<tr><td>Revocation CRLs</td><td>yes</td><td>no</td><td></td></tr>
-<tr><td>TLS Renegotiation</td><td>yes*</td><td>no</td><td>*)in TLS v1.2</td></tr>
-<tr><td>Encrypted Cert Keys</td><td>yes</td><td>no</td><td></td></tr>
-            </table>
-        <p>
-       </p>
-        </section>
-
-        <section id="protocols"><title>TLS Protocols</title>
-        <p>
-            mod_tls supports TLS protocol version 1.2 and 1.3. Should there ever be
-            a version 1.4 and <code>rustls</code> supports it, it will be available as well.
-        </p>
-        <p>
-            In mod_tls, you configure the <em>minimum</em> version to use, never the maximum:
-        </p>
-        <highlight language="config">
-TLSProtocol TLSv1.3+
-        </highlight>
-        <p>
-            This allows only version 1.3 and whatever may be its successor one day when talking
-            to your server or to a particular virtual host.
-       </p>
-        </section>
-
-        <section id="ciphers"><title>TLS Ciphers</title>
-        <p>
-            The list of TLS ciphers supported in the <code>rustls</code> library,
-            can be found <a href="https://docs.rs/rustls/">here</a>. All TLS v1.3
-            ciphers are supported. For TLS v1.2, only ciphers that rustls considers
-            secure are available.
-        </p><p>
-            mod_tls supports the following names for TLS ciphers:
-        </p>
-        <ol>
-            <li>
-                The <a href="https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4">IANA assigned name</a>
-                which uses `_` to separate parts. Example: <code>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384</code>
-            </li>
-            <li>
-                The OpenSSL name, using `-` as separator (for 1.2). Example: <code>ECDHE-ECDSA-AES256-SHA384</code>.
-                Such names often appear in documentation. `mod_tls` defines them for all TLS v1.2 ciphers.
-                For TLS v1.3 ciphers, names starting with <code>TLS13_</code> are also supported.
-            </li>
-            <li>
-                The <a href="https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4">IANA assigned identifier</a>,
-                which is a 16-bit numeric value. Example: <code>0xc024</code>.
-                You can use this in configurations as <code>TLS_CIPHER_0xc024</code>.
-            </li>
-        </ol>
-        <p>
-            You can configure a preference for ciphers, which means they will be used
-            for clients that support them. If you do not configure a preference, <code>rustls</code>
-            will use the one that it considers best. This is recommended.
-        </p>
-        <p>
-            Should you nevertheless have the need to prefer one cipher over another, you
-            may configure it like this:
-        </p>
-        <highlight language="config">
-TLSCiphersPrefer ECDHE-ECDSA-AES256-SHA384
-# or several
-TLSCiphersPrefer ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305
-        </highlight>
-        <p>
-            If you name a cipher that is unknown, the configuration will fail.
-            If you name a cipher is not supported by <code>rustls</code> (or no
-            longer supported in an updated version of <code>rustls</code> for security
-            reasons), mod_tls will log a <code>WARNING</code>, but continue to work.
-       </p>
-        <p>
-            A similar mechanism exists, if you want to disable a particular cipher:
-        </p>
-        <highlight language="config">
-TLSCipherSuppress ECDHE-ECDSA-AES256-SHA384
-        </highlight>
-        <p>
-            A suppressed cipher will not longer be used.
-            If you name a cipher that is unknown, the configuration will fail.
-            If you name a cipher is not supported by <code>rustls</code> (or no
-            longer supported in an updated version of <code>rustls</code> for security
-            reasons), mod_tls will log a <code>WARNING</code>, but continue to work.
-        </p>
-        </section>
-
-        <section id="vhosts"><title>Virtual Hosts</title>
-        <p>
-            mod_tls uses the SNI (Server Name Indicator) to select one of the
-            configured virtual hosts that match the port being served. Should
-            the client not provide an SNI, the <em>first</em> configured
-            virtual host will be selected. If the client <em>does</em> provide
-            an SNI (as all today's clients do), it <em>must</em> match one
-            virtual host (<directive module="core">ServerName</directive> or
-            <directive module="core">ServerAlias</directive>)
-            or the connection will fail.
-        </p>
-        <p>
-            As with <module>mod_ssl</module>, you may specify ciphers and protocol
-            versions for the base server (global) and/or individual virtual hosts
-            that are selected via SNI by the client.
-        </p>
-        <highlight language="config">
-Listen 443
-TLSEngine 443
-
-&lt;VirtualHost *:443>
-  ServerName example1.net
-  TLSCertificate example1-cert.pem
-  ...
-&lt;/VirtualHost>
-
-&lt;VirtualHost *:443>
-  ServerName example2.net
-  TLSCertificate example2-cert.pem
-  ...
-  TLSProtocol v1.3+
-&lt;/VirtualHost>
-        </highlight>
-        <p>
-            The example above show different TLS settings for virtual hosts on the
-            same port. This is supported. <code>example1</code> can be contacted via
-            all TLS versions and <code>example2</code> only allows v1.3 or later.
-       </p>
-        </section>
-
-        <section id="ACME"><title>ACME Certificates</title>
-        <p>
-            ACME certificates via <module>mod_md</module> are supported, just as
-            for <module>mod_ssl</module>. A minimal configuration:
-        </p>
-        <highlight language="config">
-Listen 443
-TLSEngine 443
-MDomain example.net
-
-&lt;VirtualHost *:443>
-  ServerName example.net
-  ...
-&lt;/VirtualHost>
-        </highlight>
-        </section>
-
-        <section id="OCSP"><title>OCSP Stapling</title>
-        <p>
-            mod_tls has no own implementation to retrieve OCSP information for
-            a certificate. However, it will use such for Stapling if it is provided
-            by <module>mod_md</module>. See <module>mod_md</module>'s documentation
-            on how to enable this.
-        </p>
-        </section>
-
-        <section id="variables"><title>TLS Variables</title>
-        <p>
-            Via the directive <directive module="mod_tls">TLSOptions</directive>, several variables
-            are placed into the environment of requests and can be inspected, for
-            example in a CGI script.
-        </p>
-        <p>
-            The variable names are given by <module>mod_ssl</module>. Note that these
-            are only a subset of the many variables that <module>mod_ssl</module> exposes.
-       </p>
-        <table>
-            <tr><th>Variable</th><th>TLSOption</th><th>Description</th></tr>
-            <tr><td>SSL_TLS_SNI</td><td>*</td><td>the server name indicator (SNI) send by the client</td></tr>
-            <tr><td>SSL_PROTOCOL</td><td>*</td><td>the TLS protocol negotiated</td></tr>
-            <tr><td>SSL_CIPHER</td><td>*</td><td>the name of the TLS cipher negotiated</td></tr>
-            <tr><td>SSL_VERSION_INTERFACE</td><td>StdEnvVars</td><td>the module version</td></tr>
-            <tr><td>SSL_VERSION_LIBRARY</td><td>StdEnvVars</td><td>the rustls-ffi version</td></tr>
-            <tr><td>SSL_SECURE_RENEG</td><td>StdEnvVars</td><td>always `false`</td></tr>
-            <tr><td>SSL_COMPRESS_METHOD</td><td>StdEnvVars</td><td>always `false`</td></tr>
-            <tr><td>SSL_CIPHER_EXPORT</td><td>StdEnvVars</td><td>always `false`</td></tr>
-            <tr><td>SSL_CLIENT_VERIFY</td><td>StdEnvVars</td><td>always `false`</td></tr>
-            <tr><td>SSL_SESSION_RESUMED</td><td>StdEnvVars</td><td>either `Resumed` if a known TLS session id was presented by the client or `Initial` otherwise</td></tr>
-            <tr><td>SSL_SERVER_CERT</td><td>ExportCertData</td><td>the selected server certificate in PEM format</td></tr>
-        </table>
-        <p>
-           The variable <code>SSL_SESSION_ID</code> is intentionally not supported as
-            it contains sensitive information.
-        </p>
-        </section>
-
-        <section id="certificates"><title>Client Certificates</title>
-        <p>
-            While <code>rustls</code> supports client certificates in principle, parts
-            of the infrastructure to make <em>use</em> of these in a server are not
-            offered.
-        </p>
-        <p>
-            Among these features are: revocation lists, inspection of certificate
-            extensions and the matched issuer chain for OCSP validation. Without these,
-            revocation of client certificates is not possible. Offering authentication
-            without revocation is not considered an option.
-        </p>
-        <p>
-            Work will continue on this and client certificate support may become
-            available in a future release.
-        </p>
-        </section>
-
-    <directivesynopsis>
-        <name>TLSEngine</name>
-        <description>defines on which address+port the module shall handle incoming connections.</description>
-        <syntax>TLSEngine [<em>address</em>:]<em>port</em></syntax>
-        <contextlist>
-            <context>server config</context>
-        </contextlist>
-        <usage>
-            <p>
-                This is set on a global level, not in individual <directive module="core"
-                type="section">VirtualHost</directive>s.
-                It will affect all <directive module="core" type="section">VirtualHost</directive>
-                that match the specified address/port.
-                You can use <directive>TLSEngine</directive> several times to use more than one address/port.
-            </p><p>
-            </p>
-            <example><title>Example</title>
-                <highlight language="config">
-                    TLSEngine 443
-                </highlight>
-            </example>
-            <p>
-                The example tells mod_tls to handle incoming connection on port 443 for
-                all listeners.
-            </p>
-        </usage>
-    </directivesynopsis>
-
-    <directivesynopsis>
-        <name>TLSCertificate</name>
-        <description>adds a certificate and key (PEM encoded) to a server/virtual host.</description>
-        <syntax>TLSCertificate <em>cert_file</em> [<em>key_file</em>]</syntax>
-        <contextlist>
-            <context>server config</context>
-            <context>virtual host</context>
-        </contextlist>
-        <usage>
-            <p>
-                If you do not specify a separate key file, the key is assumed to also be
-                found in the first file. You may add more than one certificate to a
-                server/virtual host. The first certificate suitable for a client is then chosen.
-            </p><p>
-                The path can be specified relative to the server root.
-            </p>
-        </usage>
-    </directivesynopsis>
-
-    <directivesynopsis>
-        <name>TLSProtocol</name>
-        <description>specifies the minimum version of the TLS protocol to use.</description>
-        <syntax>TLSProtocol <em>version</em>+</syntax>
-        <default>TLSProtocol v1.2+</default>
-        <contextlist>
-            <context>server config</context>
-            <context>virtual host</context>
-        </contextlist>
-        <usage>
-            <p>
-                The default is `v1.2+`. Settings this to `v1.3+` would disable TLSv1.2.
-            </p>
-        </usage>
-    </directivesynopsis>
-
-    <directivesynopsis>
-        <name>TLSCiphersPrefer</name>
-        <description>defines ciphers that are preferred.</description>
-        <syntax>TLSCiphersPrefer <em>cipher(-list)</em></syntax>
-        <contextlist>
-            <context>server config</context>
-            <context>virtual host</context>
-        </contextlist>
-        <usage>
-            <p>
-                This will not disable any ciphers supported by `rustls`. If you
-                specify a cipher that is completely unknown, the configuration will
-                fail. If you specify a cipher that is known but not supported by `rustls`,
-                a warning will be logged but the server will continue.
-            </p><p>
-            </p>
-            <example><title>Example</title>
-                <highlight language="config">
-TLSCiphersPrefer ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305
-                </highlight>
-            </example>
-            <p>
-                The example gives 2 ciphers preference over others, in the
-                order they are mentioned.
-            </p>
-        </usage>
-    </directivesynopsis>
-
-    <directivesynopsis>
-        <name>TLSCiphersSuppress</name>
-        <description>defines ciphers that are not to be used.</description>
-        <syntax>TLSCiphersSuppress <em>cipher(-list)</em></syntax>
-        <contextlist>
-            <context>server config</context>
-            <context>virtual host</context>
-        </contextlist>
-        <usage>
-            <p>
-                This will not disable any unmentioned ciphers supported by `rustls`.
-                If you specify a cipher that is completely unknown, the configuration will fail.
-                If you specify a cipher that is known but not supported by `rustls`,
-                a warning will be logged but the server will continue.
-            </p><p>
-            </p>
-            <example><title>Example</title>
-                <highlight language="config">
-TLSCiphersSuppress ECDHE-ECDSA-CHACHA20-POLY1305
-                </highlight>
-            </example>
-            <p>
-                The example removes a cipher for use in connections.
-            </p>
-        </usage>
-    </directivesynopsis>
-
-    <directivesynopsis>
-        <name>TLSHonorClientOrder</name>
-        <description>determines if the order of ciphers supported by the client is honored</description>
-        <syntax>TLSHonorClientOrder on|off</syntax>
-        <default>TLSHonorClientOrder on</default>
-        <contextlist>
-            <context>server config</context>
-            <context>virtual host</context>
-        </contextlist>
-        <usage>
-            <p>
-                <directive>TLSHonorClientOrder</directive> determines if the order of ciphers
-                supported by the client is honored.
-            </p><p>
-            </p>
-        </usage>
-    </directivesynopsis>
-
-    <directivesynopsis>
-        <name>TLSOptions</name>
-        <description>enables SSL variables for requests.</description>
-        <syntax>TLSOptions [+|-]<em>option</em></syntax>
-        <contextlist>
-            <context>server config</context>
-            <context>virtual host</context>
-            <context>directory</context>
-            <context>.htaccess</context>
-        </contextlist>
-        <usage>
-            <p>
-                <directive>TLSOptions</directive> is analog to <directive
-                module="mod_ssl">SSLOptions</directive> in <module>mod_ssl</module>.
-                It can be set per directory/location and `option` can be:
-            </p>
-            <ul>
-                <li>`StdEnvVars`: adds more variables to the requests environment,
-                    as forwarded for example to CGI processing and other applications.
-                </li>
-                <li>`ExportCertData`: adds certificate related variables to the request environment.
-                </li>
-                <li>`Defaults`: resets all options to their default values.</li>
-            </ul>
-            <p>
-                Adding variables to a request environment adds overhead, especially
-                when certificates need to be inspected and fields extracted.
-                Therefore most variables are not set by default.
-            </p>
-            <p>
-                You can configure <directive>TLSOptions</directive> per location or generally on a
-                server/virtual host. Prefixing an option with `-` disables this
-                option while leaving others unchanged.
-                A `+` prefix is the same as writing the option without one.
-            </p>
-            <p>
-                The `Defaults` value can be used to reset any options that are
-                inherited from other locations or the virtual host/server.
-            </p>
-            <example><title>Example</title>
-                <highlight language="config">
-&lt;Location /myplace/app>
-  TLSOptions Defaults StdEnvVars
-  ...
-&lt;/Location>
-                </highlight>
-            </example>
-        </usage>
-    </directivesynopsis>
-
-    <directivesynopsis>
-        <name>TLSProxyEngine</name>
-        <description>enables TLS for backend connections.</description>
-        <syntax>TLSProxyEngine on|off</syntax>
-        <contextlist>
-            <context>server config</context>
-            <context>virtual host</context>
-            <context>proxy section</context>
-        </contextlist>
-        <usage>
-            <p>
-                <directive>TLSProxyEngine</directive> is analog to <directive
-                module="mod_ssl">SSLProxyEngine</directive> in <module>mod_ssl</module>.
-            </p><p>
-                This can be used in a server/virtual host or <directive module="mod_proxy"
-                type="section">Proxy</directive> section to
-                enable the module for outgoing connections using <module>mod_proxy</module>.
-            </p>
-        </usage>
-    </directivesynopsis>
-
-    <directivesynopsis>
-        <name>TLSProxyCA</name>
-        <description>sets the root certificates to validate the backend server with.</description>
-        <syntax>TLSProxyCA <em>file.pem</em></syntax>
-        <contextlist>
-            <context>server config</context>
-            <context>virtual host</context>
-            <context>proxy section</context>
-        </contextlist>
-        <usage>
-            <p>
-
-            </p>
-        </usage>
-    </directivesynopsis>
-
-    <directivesynopsis>
-        <name>TLSProxyProtocol</name>
-        <description>specifies the minimum version of the TLS protocol to use in proxy connections.</description>
-        <syntax>TLSProxyProtocol <em>version</em>+</syntax>
-        <default>TLSProxyProtocol v1.2+</default>
-        <contextlist>
-            <context>server config</context>
-            <context>virtual host</context>
-            <context>proxy section</context>
-        </contextlist>
-        <usage>
-            <p>
-                The default is `v1.2+`. Settings this to `v1.3+` would disable TLSv1.2.
-            </p>
-        </usage>
-    </directivesynopsis>
-
-    <directivesynopsis>
-        <name>TLSProxyCiphersPrefer</name>
-        <description>defines ciphers that are preferred for a proxy connection.</description>
-        <syntax>TLSProxyCiphersPrefer <em>cipher(-list)</em></syntax>
-        <contextlist>
-            <context>server config</context>
-            <context>virtual host</context>
-            <context>proxy section</context>
-        </contextlist>
-        <usage>
-            <p>
-                This will not disable any ciphers supported by `rustls`.
-                If you specify a cipher that is completely unknown, the configuration will fail.
-                If you specify a cipher that is known but not supported by `rustls`,
-                a warning will be logged but the server will continue.
-            </p>
-        </usage>
-    </directivesynopsis>
-
-    <directivesynopsis>
-        <name>TLSProxyCiphersSuppress</name>
-        <description>defines ciphers that are not to be used for a proxy connection.</description>
-        <syntax>TLSProxyCiphersSuppress <em>cipher(-list)</em></syntax>
-        <contextlist>
-            <context>server config</context>
-            <context>virtual host</context>
-            <context>proxy section</context>
-        </contextlist>
-        <usage>
-            <p>
-                This will not disable any unmentioned ciphers supported by `rustls`.
-                If you specify a cipher that is completely unknown, the configuration will fail.
-                If you specify a cipher that is known but not supported by `rustls`,
-                a warning will be logged but the server will continue.
-            </p>
-        </usage>
-    </directivesynopsis>
-
-    <directivesynopsis>
-        <name>TLSProxyMachineCertificate</name>
-        <description>adds a certificate and key file (PEM encoded) to a proxy setup.</description>
-        <syntax>TLSProxyMachineCertificate <em>cert_file</em> [<em>key_file</em>]</syntax>
-        <contextlist>
-            <context>server config</context>
-            <context>virtual host</context>
-            <context>proxy section</context>
-        </contextlist>
-        <usage>
-            <p>
-                The certificate is used to authenticate against a proxied backend server.
-            </p><p>
-                If you do not specify a separate key file, the key is assumed to also be
-                found in the first file. You may add more than one certificate to a proxy
-                setup. The first certificate suitable for a proxy connection to a backend
-                is then chosen by <code>rustls</code>.
-            </p>
-            <p>
-                The path can be specified relative to the server root.
-            </p>
-        </usage>
-    </directivesynopsis>
-
-    <directivesynopsis>
-        <name>TLSStrictSNI</name>
-        <description>enforces exact matches of client server indicators (SNI) against host names.</description>
-        <syntax>TLSStrictSNI on|off</syntax>
-        <default>TLSStrictSNI on</default>
-        <contextlist>
-            <context>server config</context>
-        </contextlist>
-        <usage>
-            <p>
-                Client connections using SNI will be unsuccessful if no match is found.
-            </p>
-        </usage>
-    </directivesynopsis>
-
-    <directivesynopsis>
-        <name>TLSSessionCache</name>
-        <description>specifies the cache for TLS session resumption.</description>
-        <syntax>TLSSessionCache <em>cache-spec</em></syntax>
-        <contextlist>
-            <context>server config</context>
-        </contextlist>
-        <usage>
-            <p>
-                This uses a cache on the server side to allow clients to resume connections.
-            </p><p>
-            You can set this to `none` or define a cache as in the <directive
-            module="mod_ssl">SSLSessionCache</directive>
-            directive of <module>mod_ssl</module>.
-            </p><p>
-            If not configured, `mod_tls` will try to create a shared memory cache on its own,
-            using `shmcb:tls/session-cache` as specification.
-            Should that fail, a warning is logged, but the server continues.
-            </p>
-        </usage>
-    </directivesynopsis>
-
-</modulesynopsis>
diff --git a/modules/tls/Makefile.in b/modules/tls/Makefile.in
deleted file mode 100644 (file)
index 4395bc3..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#
-#   standard stuff
-#
-
-include $(top_srcdir)/build/special.mk
diff --git a/modules/tls/config2.m4 b/modules/tls/config2.m4
deleted file mode 100644 (file)
index 8a32490..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-dnl Licensed to the Apache Software Foundation (ASF) under one or more
-dnl contributor license agreements.  See the NOTICE file distributed with
-dnl this work for additional information regarding copyright ownership.
-dnl The ASF licenses this file to You under the Apache License, Version 2.0
-dnl (the "License"); you may not use this file except in compliance with
-dnl the License.  You may obtain a copy of the License at
-dnl
-dnl      http://www.apache.org/licenses/LICENSE-2.0
-dnl
-dnl Unless required by applicable law or agreed to in writing, software
-dnl distributed under the License is distributed on an "AS IS" BASIS,
-dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-dnl See the License for the specific language governing permissions and
-dnl limitations under the License.
-
-dnl #  start of module specific part
-APACHE_MODPATH_INIT(tls)
-
-dnl #  list of module object files
-tls_objs="dnl
-mod_tls.lo dnl
-tls_cache.lo dnl
-tls_cert.lo dnl
-tls_conf.lo dnl
-tls_core.lo dnl
-tls_filter.lo dnl
-tls_ocsp.lo dnl
-tls_proto.lo dnl
-tls_util.lo dnl
-tls_var.lo dnl
-"
-
-dnl
-dnl APACHE_CHECK_TLS
-dnl
-dnl Configure for rustls, giving preference to
-dnl "--with-rustls=<path>" if it was specified.
-dnl
-AC_DEFUN([APACHE_CHECK_RUSTLS],[
-  AC_CACHE_CHECK([for rustls], [ac_cv_rustls], [
-    dnl initialise the variables we use
-    ac_cv_rustls=no
-    ap_rustls_found=""
-    ap_rustls_base=""
-    ap_rustls_libs=""
-
-    dnl Determine the rustls base directory, if any
-    AC_MSG_CHECKING([for user-provided rustls base directory])
-    AC_ARG_WITH(rustls, APACHE_HELP_STRING(--with-rustls=PATH, rustls installation directory), [
-      dnl If --with-rustls specifies a directory, we use that directory
-      if test "x$withval" != "xyes" -a "x$withval" != "x"; then
-        dnl This ensures $withval is actually a directory and that it is absolute
-        ap_rustls_base="`cd $withval ; pwd`"
-      fi
-    ])
-    if test "x$ap_rustls_base" = "x"; then
-      AC_MSG_RESULT(none)
-    else
-      AC_MSG_RESULT($ap_rustls_base)
-    fi
-
-    dnl Run header and version checks
-    saved_CPPFLAGS="$CPPFLAGS"
-    saved_LIBS="$LIBS"
-    saved_LDFLAGS="$LDFLAGS"
-
-    dnl Before doing anything else, load in pkg-config variables
-    if test -n "$PKGCONFIG"; then
-      saved_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
-      AC_MSG_CHECKING([for pkg-config along $PKG_CONFIG_PATH])
-      if test "x$ap_rustls_base" != "x" ; then
-        if test -f "${ap_rustls_base}/lib/pkgconfig/librustls.pc"; then
-          dnl Ensure that the given path is used by pkg-config too, otherwise
-          dnl the system librustls.pc might be picked up instead.
-          PKG_CONFIG_PATH="${ap_rustls_base}/lib/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
-          export PKG_CONFIG_PATH
-        elif test -f "${ap_rustls_base}/lib64/pkgconfig/librustls.pc"; then
-          dnl Ensure that the given path is used by pkg-config too, otherwise
-          dnl the system librustls.pc might be picked up instead.
-          PKG_CONFIG_PATH="${ap_rustls_base}/lib64/pkgconfig${PKG_CONFIG_PATH+:}${PKG_CONFIG_PATH}"
-          export PKG_CONFIG_PATH
-        fi
-      fi
-      ap_rustls_libs="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-l --silence-errors librustls`"
-      if test $? -eq 0; then
-        ap_rustls_found="yes"
-        pkglookup="`$PKGCONFIG --cflags-only-I librustls`"
-        APR_ADDTO(CPPFLAGS, [$pkglookup])
-        APR_ADDTO(MOD_CFLAGS, [$pkglookup])
-        pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-L librustls`"
-        APR_ADDTO(LDFLAGS, [$pkglookup])
-        APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
-        pkglookup="`$PKGCONFIG $PKGCONFIG_LIBOPTS --libs-only-other librustls`"
-        APR_ADDTO(LDFLAGS, [$pkglookup])
-        APR_ADDTO(MOD_LDFLAGS, [$pkglookup])
-      fi
-      PKG_CONFIG_PATH="$saved_PKG_CONFIG_PATH"
-    fi
-
-    dnl fall back to the user-supplied directory if not found via pkg-config
-    if test "x$ap_rustls_base" != "x" -a "x$ap_rustls_found" = "x"; then
-      APR_ADDTO(CPPFLAGS, [-I$ap_rustls_base/include])
-      APR_ADDTO(MOD_CFLAGS, [-I$ap_rustls_base/include])
-      APR_ADDTO(LDFLAGS, [-L$ap_rustls_base/lib])
-      APR_ADDTO(MOD_LDFLAGS, [-L$ap_rustls_base/lib])
-      if test "x$ap_platform_runtime_link_flag" != "x"; then
-        APR_ADDTO(LDFLAGS, [$ap_platform_runtime_link_flag$ap_rustls_base/lib])
-        APR_ADDTO(MOD_LDFLAGS, [$ap_platform_runtime_link_flag$ap_rustls_base/lib])
-      fi
-    fi
-
-    AC_MSG_CHECKING([for rustls version >= 0.9.2])
-    AC_TRY_COMPILE([#include <rustls.h>],[
-rustls_version();
-rustls_acceptor_new();
-],
-      [AC_MSG_RESULT(OK)
-       ac_cv_rustls=yes],
-      [AC_MSG_RESULT(FAILED)])
-
-    dnl restore
-    CPPFLAGS="$saved_CPPFLAGS"
-    LIBS="$saved_LIBS"
-    LDFLAGS="$saved_LDFLAGS"
-  ])
-  if test "x$ac_cv_rustls" = "xyes"; then
-    AC_DEFINE(HAVE_RUSTLS, 1, [Define if rustls is available])
-  fi
-])
-
-
-dnl # hook module into the Autoconf mechanism (--enable-http2)
-APACHE_MODULE(tls, [TLS protocol handling using rustls. Implemented by mod_tls.
-This module requires a librustls installation.
-See --with-rustls on how to manage non-standard locations. This module
-is usually linked shared and requires loading. ], $tls_objs, , most, [
-    APACHE_CHECK_RUSTLS
-    if test "$ac_cv_rustls" = "yes" ; then
-        if test "x$enable_tls" = "xshared"; then
-           case `uname` in
-             "Darwin")
-                MOD_TLS_LINK_LIBS="-lrustls -framework Security -framework Foundation"
-                ;;
-             *)
-                MOD_TLS_LINK_LIBS="-lrustls"
-                ;;
-           esac
-
-           # Some rustls versions need an extra -lm when linked
-           # See https://github.com/rustls/rustls-ffi/issues/133
-           rustls_version=`rustc --version`
-           case "$rustls_version" in
-              *1.55*) need_lm="yes" ;;
-              *1.56*) need_lm="yes" ;;
-              *1.57*) need_lm="yes" ;;
-           esac
-           if test "$need_lm" = "yes" ; then
-                MOD_TLS_LINK_LIBS="$MOD_TLS_LINK_LIBS -lm"
-           fi
-
-           # The only symbol which needs to be exported is the module
-           # structure, so ask libtool to hide everything else:
-           APR_ADDTO(MOD_TLS_LDADD, [$MOD_TLS_LINK_LIBS -export-symbols-regex tls_module])
-        fi
-    else
-        enable_tls=no
-    fi
-])
-
-
-dnl #  end of module specific part
-APACHE_MODPATH_FINISH
-
diff --git a/modules/tls/mod_tls.c b/modules/tls/mod_tls.c
deleted file mode 100644 (file)
index 9d79521..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <assert.h>
-#include <apr_optional.h>
-#include <apr_strings.h>
-
-#include <mpm_common.h>
-#include <httpd.h>
-#include <http_core.h>
-#include <http_connection.h>
-#include <http_log.h>
-#include <http_protocol.h>
-#include <http_ssl.h>
-#include <http_request.h>
-#include <ap_socache.h>
-
-#include <rustls.h>
-
-#include "mod_tls.h"
-#include "tls_conf.h"
-#include "tls_core.h"
-#include "tls_cache.h"
-#include "tls_proto.h"
-#include "tls_filter.h"
-#include "tls_var.h"
-#include "tls_version.h"
-
-#include "mod_proxy.h"
-
-static void tls_hooks(apr_pool_t *pool);
-
-AP_DECLARE_MODULE(tls) = {
-    STANDARD20_MODULE_STUFF,
-    tls_conf_create_dir,   /* create per dir config */
-    tls_conf_merge_dir,    /* merge per dir config */
-    tls_conf_create_svr,   /* create per server config */
-    tls_conf_merge_svr,    /* merge per server config (inheritance) */
-    tls_conf_cmds,         /* command handlers */
-    tls_hooks,
-#if defined(AP_MODULE_FLAG_NONE)
-    AP_MODULE_FLAG_ALWAYS_MERGE
-#endif
-};
-
-static const char* crustls_version(apr_pool_t *p)
-{
-    struct rustls_str rversion;
-
-    rversion = rustls_version();
-    return apr_pstrndup(p, rversion.data, rversion.len);
-}
-
-static int tls_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
-{
-    tls_proto_pre_config(pconf, ptemp);
-    tls_cache_pre_config(pconf, plog, ptemp);
-    return OK;
-}
-
-static apr_status_t tls_post_config(apr_pool_t *p, apr_pool_t *plog,
-                                    apr_pool_t *ptemp, server_rec *s)
-{
-    const char *tls_init_key = "mod_tls_init_counter";
-    tls_conf_server_t *sc;
-    void *data = NULL;
-
-    (void)plog;
-    sc = tls_conf_server_get(s);
-    assert(sc);
-    assert(sc->global);
-    sc->global->module_version = "mod_tls/" MOD_TLS_VERSION;
-    sc->global->crustls_version = crustls_version(p);
-
-    apr_pool_userdata_get(&data, tls_init_key, s->process->pool);
-    if (data == NULL) {
-        /* At the first start, httpd makes a config check dry run
-        * to see if the config is ok in principle.
-         */
-        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "post config dry run");
-        apr_pool_userdata_set((const void *)1, tls_init_key,
-                              apr_pool_cleanup_null, s->process->pool);
-    }
-    else {
-        ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(10365)
-                     "%s (%s), initializing...",
-                     sc->global->module_version,
-                     sc->global->crustls_version);
-    }
-
-    return tls_core_init(p, ptemp, s);
-}
-
-static apr_status_t tls_post_proxy_config(
-    apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(s);
-    (void)plog;
-    sc->global->mod_proxy_post_config_done = 1;
-    return tls_core_init(p, ptemp, s);
-}
-
-#if AP_MODULE_MAGIC_AT_LEAST(20120211, 109)
-static int tls_ssl_outgoing(conn_rec *c, ap_conf_vector_t *dir_conf, int enable_ssl)
-{
-    /* we are not handling proxy connections - for now */
-    tls_core_conn_bind(c, dir_conf);
-    if (enable_ssl && tls_core_setup_outgoing(c) == OK) {
-        ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, c->base_server,
-            "accepted ssl_bind_outgoing(enable=%d) for %s",
-            enable_ssl, c->base_server->server_hostname);
-        return OK;
-    }
-    tls_core_conn_disable(c);
-    ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, c->base_server,
-        "declined ssl_bind_outgoing(enable=%d) for %s",
-        enable_ssl, c->base_server->server_hostname);
-    return DECLINED;
-}
-
-#else /* #if AP_MODULE_MAGIC_AT_LEAST(20120211, 109) */
-
-APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *));
-APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *));
-APR_DECLARE_OPTIONAL_FN(int, ssl_engine_set, (conn_rec *,
-                                              ap_conf_vector_t *,
-                                              int proxy, int enable));
-static APR_OPTIONAL_FN_TYPE(ssl_engine_set) *module_ssl_engine_set;
-
-static int ssl_engine_set(
-    conn_rec *c, ap_conf_vector_t *dir_conf, int proxy, int enable)
-{
-    ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, c->base_server,
-        "ssl_engine_set(proxy=%d, enable=%d) for %s",
-        proxy, enable, c->base_server->server_hostname);
-    tls_core_conn_bind(c, dir_conf);
-    if (enable && tls_core_setup_outgoing(c) == OK) {
-        if (module_ssl_engine_set) {
-            module_ssl_engine_set(c, dir_conf, proxy, 0);
-        }
-        return 1;
-    }
-    if (proxy || !enable) {
-        /* we are not handling proxy connections - for now */
-        tls_core_conn_disable(c);
-    }
-    if (module_ssl_engine_set) {
-        return module_ssl_engine_set(c, dir_conf, proxy, enable);
-    }
-    return 0;
-}
-
-static int ssl_proxy_enable(conn_rec *c)
-{
-    return ssl_engine_set(c, NULL, 1, 1);
-}
-
-static int ssl_engine_disable(conn_rec *c)
-{
-    return ssl_engine_set(c, NULL, 0, 0);
-}
-
-static apr_status_t tls_post_config_proxy_ssl(
-    apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
-{
-    if (1) {
-        const char *tls_init_key = "mod_tls_proxy_ssl_counter";
-        void *data = NULL;
-        APR_OPTIONAL_FN_TYPE(ssl_engine_set) *fn_ssl_engine_set;
-
-        (void)p;
-        (void)plog;
-        (void)ptemp;
-        apr_pool_userdata_get(&data, tls_init_key, s->process->pool);
-        if (data == NULL) {
-            /* At the first start, httpd makes a config check dry run
-            * to see if the config is ok in principle.
-             */
-            apr_pool_userdata_set((const void *)1, tls_init_key,
-                                  apr_pool_cleanup_null, s->process->pool);
-            return APR_SUCCESS;
-        }
-
-        /* mod_ssl (if so loaded, has registered its optional functions.
-         * When mod_proxy runs in post-config, it looks up those functions and uses
-         * them to manipulate SSL status for backend connections.
-         * We provide our own implementations to avoid becoming active on such
-         * connections for now.
-         * */
-        fn_ssl_engine_set = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_set);
-        module_ssl_engine_set = (fn_ssl_engine_set
-            && fn_ssl_engine_set != ssl_engine_set)? fn_ssl_engine_set : NULL;
-        APR_REGISTER_OPTIONAL_FN(ssl_engine_set);
-        APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable);
-        APR_REGISTER_OPTIONAL_FN(ssl_engine_disable);
-    }
-    return APR_SUCCESS;
-}
-#endif /* #if AP_MODULE_MAGIC_AT_LEAST(20120211, 109) */
-
-static void tls_init_child(apr_pool_t *p, server_rec *s)
-{
-    tls_cache_init_child(p, s);
-}
-
-static int hook_pre_connection(conn_rec *c, void *csd)
-{
-    (void)csd; /* mpm specific socket data, not used */
-
-    /* are we on a primary connection? */
-    if (c->master) return DECLINED;
-
-    /* Decide connection TLS stats and install our
-     * input/output filters for handling TLS/application data
-     * if enabled.
-     */
-    return tls_filter_pre_conn_init(c);
-}
-
-static int hook_connection(conn_rec* c)
-{
-    tls_filter_conn_init(c);
-    /* we do *not* take over. we are not processing requests. */
-    return DECLINED;
-}
-
-static const char *tls_hook_http_scheme(const request_rec *r)
-{
-    return (tls_conn_check_ssl(r->connection) == OK)? "https" : NULL;
-}
-
-static apr_port_t tls_hook_default_port(const request_rec *r)
-{
-    return (tls_conn_check_ssl(r->connection) == OK) ? 443 : 0;
-}
-
-static const char* const mod_http2[]        = { "mod_http2.c", NULL};
-
-static void tls_hooks(apr_pool_t *pool)
-{
-    /* If our request check denies further processing, certain things
-     * need to be in place for the response to be correctly generated. */
-    static const char *dep_req_check[] = { "mod_setenvif.c", NULL };
-    static const char *dep_proxy[] = { "mod_proxy.c", NULL };
-
-    ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool, "installing hooks");
-    tls_filter_register(pool);
-
-    ap_hook_pre_config(tls_pre_config, NULL,NULL, APR_HOOK_MIDDLE);
-    /* run post-config hooks one before, one after mod_proxy, as the
-     * mod_proxy's own one calls us in its "section_post_config" hook. */
-    ap_hook_post_config(tls_post_config, NULL, dep_proxy, APR_HOOK_MIDDLE);
-    APR_OPTIONAL_HOOK(proxy, section_post_config,
-                      tls_proxy_section_post_config, NULL, NULL,
-                      APR_HOOK_MIDDLE);
-    ap_hook_post_config(tls_post_proxy_config, dep_proxy, NULL, APR_HOOK_MIDDLE);
-    ap_hook_child_init(tls_init_child, NULL,NULL, APR_HOOK_MIDDLE);
-    /* connection things */
-    ap_hook_pre_connection(hook_pre_connection, NULL, NULL, APR_HOOK_MIDDLE);
-    ap_hook_process_connection(hook_connection, NULL, mod_http2, APR_HOOK_MIDDLE);
-    /* request things */
-    ap_hook_default_port(tls_hook_default_port, NULL,NULL, APR_HOOK_MIDDLE);
-    ap_hook_http_scheme(tls_hook_http_scheme, NULL,NULL, APR_HOOK_MIDDLE);
-    ap_hook_post_read_request(tls_core_request_check, dep_req_check, NULL, APR_HOOK_MIDDLE);
-    ap_hook_fixups(tls_var_request_fixup, NULL,NULL, APR_HOOK_MIDDLE);
-
-    ap_hook_ssl_conn_is_ssl(tls_conn_check_ssl, NULL, NULL, APR_HOOK_MIDDLE);
-    ap_hook_ssl_var_lookup(tls_var_lookup, NULL, NULL, APR_HOOK_MIDDLE);
-
-#if AP_MODULE_MAGIC_AT_LEAST(20120211, 109)
-    ap_hook_ssl_bind_outgoing(tls_ssl_outgoing, NULL, NULL, APR_HOOK_MIDDLE);
-#else
-    ap_hook_post_config(tls_post_config_proxy_ssl, NULL, dep_proxy, APR_HOOK_MIDDLE);
-#endif
-
-}
diff --git a/modules/tls/mod_tls.h b/modules/tls/mod_tls.h
deleted file mode 100644 (file)
index db7dc41..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef mod_tls_h
-#define mod_tls_h
-
-#endif /* mod_tls_h */
\ No newline at end of file
diff --git a/modules/tls/tls_cache.c b/modules/tls/tls_cache.c
deleted file mode 100644 (file)
index de4be18..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <assert.h>
-#include <apr_lib.h>
-#include <apr_strings.h>
-#include <apr_hash.h>
-
-#include <httpd.h>
-#include <http_connection.h>
-#include <http_log.h>
-#include <ap_socache.h>
-#include <util_mutex.h>
-
-#include <rustls.h>
-
-#include "tls_conf.h"
-#include "tls_core.h"
-#include "tls_cache.h"
-
-extern module AP_MODULE_DECLARE_DATA tls_module;
-APLOG_USE_MODULE(tls);
-
-#define TLS_CACHE_DEF_PROVIDER      "shmcb"
-#define TLS_CACHE_DEF_DIR           "tls"
-#define TLS_CACHE_DEF_FILE          "session_cache"
-#define TLS_CACHE_DEF_SIZE          512000
-
-static const char *cache_provider_unknown(const char *name, apr_pool_t *p)
-{
-    apr_array_header_t *known;
-    const char *known_names;
-
-    known = ap_list_provider_names(p, AP_SOCACHE_PROVIDER_GROUP,
-                                   AP_SOCACHE_PROVIDER_VERSION);
-    known_names = apr_array_pstrcat(p, known, ',');
-    return apr_psprintf(p, "cache type '%s' not supported "
-                        "(known names: %s). Maybe you need to load the "
-                        "appropriate socache module (mod_socache_%s?).",
-                        name, known_names, name);
-}
-
-void tls_cache_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
-{
-    (void)plog;
-    (void)ptemp;
-    /* we make this visible, in case someone wants to configure it.
-     * this does not mean that we will really use it, which is determined
-     * by configuration and cache provider capabilities. */
-    ap_mutex_register(pconf, TLS_SESSION_CACHE_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
-}
-
-static const char *cache_init(tls_conf_global_t *gconf, apr_pool_t *p, apr_pool_t *ptemp)
-{
-    const char *err = NULL;
-    const char *name, *args = NULL;
-    apr_status_t rv;
-
-    if (gconf->session_cache) {
-        goto cleanup;
-    }
-    else if (!apr_strnatcasecmp("none", gconf->session_cache_spec)) {
-        gconf->session_cache_provider = NULL;
-        gconf->session_cache = NULL;
-        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, gconf->ap_server, APLOGNO(10346)
-                     "session cache explicitly disabled");
-        goto cleanup;
-    }
-    else if (!apr_strnatcasecmp("default", gconf->session_cache_spec)) {
-        const char *path = TLS_CACHE_DEF_DIR;
-
-#if AP_MODULE_MAGIC_AT_LEAST(20180906, 2)
-        path = ap_state_dir_relative(p, path);
-#endif
-        gconf->session_cache_spec = apr_psprintf(p, "%s:%s/%s(%ld)",
-            TLS_CACHE_DEF_PROVIDER, path, TLS_CACHE_DEF_FILE, (long)TLS_CACHE_DEF_SIZE);
-        gconf->session_cache_spec = "shmcb:mod_tls-sesss(64000)";
-    }
-
-    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, gconf->ap_server, APLOGNO(10347)
-                 "Using session cache: %s", gconf->session_cache_spec);
-    name = gconf->session_cache_spec;
-    args = ap_strchr((char*)name, ':');
-    if (args) {
-        name = apr_pstrmemdup(p, name, (apr_size_t)(args - name));
-        ++args;
-    }
-    gconf->session_cache_provider = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
-                                                       name, AP_SOCACHE_PROVIDER_VERSION);
-    if (!gconf->session_cache_provider) {
-        err = cache_provider_unknown(name, p);
-        goto cleanup;
-    }
-    err = gconf->session_cache_provider->create(&gconf->session_cache, args, ptemp, p);
-    if (err != NULL) goto cleanup;
-
-    if (gconf->session_cache_provider->flags & AP_SOCACHE_FLAG_NOTMPSAFE
-        && !gconf->session_cache_mutex) {
-        /* we need a global lock to access the cache */
-        rv = ap_global_mutex_create(&gconf->session_cache_mutex, NULL,
-            TLS_SESSION_CACHE_MUTEX_TYPE, NULL, gconf->ap_server, p, 0);
-        if (APR_SUCCESS != rv) {
-            err = apr_psprintf(p, "error setting up global %s mutex: %d",
-                TLS_SESSION_CACHE_MUTEX_TYPE, rv);
-            gconf->session_cache_mutex = NULL;
-            goto cleanup;
-        }
-    }
-
-cleanup:
-    if (NULL != err) {
-        gconf->session_cache_provider = NULL;
-        gconf->session_cache = NULL;
-    }
-    return err;
-}
-
-const char *tls_cache_set_specification(
-    const char *spec, tls_conf_global_t *gconf, apr_pool_t *p, apr_pool_t *ptemp)
-{
-    gconf->session_cache_spec = spec;
-    return cache_init(gconf, p, ptemp);
-}
-
-apr_status_t tls_cache_post_config(apr_pool_t *p, apr_pool_t *ptemp, server_rec *s)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(s);
-    const char *err;
-    apr_status_t rv = APR_SUCCESS;
-
-    err = cache_init(sc->global, p, ptemp);
-    if (err) {
-        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10348)
-                     "session cache [%s] could not be initialized, will continue "
-                     "without session one. Since this will impact performance, "
-                     "consider making use of the 'TLSSessionCache' directive. The "
-                     "error was: %s", sc->global->session_cache_spec, err);
-    }
-
-    if (sc->global->session_cache) {
-        struct ap_socache_hints hints;
-
-        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "provider init session cache [%s]",
-                     sc->global->session_cache_spec);
-        memset(&hints, 0, sizeof(hints));
-        hints.avg_obj_size = 100;
-        hints.avg_id_len = 33;
-        hints.expiry_interval = 30;
-
-        rv = sc->global->session_cache_provider->init(
-            sc->global->session_cache, "mod_tls-sess", &hints, s, p);
-        if (APR_SUCCESS != rv) {
-            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10349)
-                         "error initializing session cache.");
-        }
-    }
-    return rv;
-}
-
-void tls_cache_init_child(apr_pool_t *p, server_rec *s)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(s);
-    const char *lockfile;
-    apr_status_t rv;
-
-    if (sc->global->session_cache_mutex) {
-        lockfile = apr_global_mutex_lockfile(sc->global->session_cache_mutex);
-        rv = apr_global_mutex_child_init(&sc->global->session_cache_mutex, lockfile, p);
-        if (APR_SUCCESS != rv) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10350)
-                         "Cannot reinit %s mutex (file `%s`)",
-                         TLS_SESSION_CACHE_MUTEX_TYPE, lockfile? lockfile : "-");
-        }
-    }
-}
-
-void tls_cache_free(server_rec *s)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(s);
-    if (sc->global->session_cache_provider) {
-        sc->global->session_cache_provider->destroy(sc->global->session_cache, s);
-    }
-}
-
-static void tls_cache_lock(tls_conf_global_t *gconf)
-{
-    if (gconf->session_cache_mutex) {
-        apr_status_t rv = apr_global_mutex_lock(gconf->session_cache_mutex);
-        if (APR_SUCCESS != rv) {
-            ap_log_error(APLOG_MARK, APLOG_WARNING, rv, gconf->ap_server, APLOGNO(10351)
-                         "Failed to acquire TLS session cache lock");
-        }
-    }
-}
-
-static void tls_cache_unlock(tls_conf_global_t *gconf)
-{
-    if (gconf->session_cache_mutex) {
-        apr_status_t rv = apr_global_mutex_unlock(gconf->session_cache_mutex);
-        if (APR_SUCCESS != rv) {
-            ap_log_error(APLOG_MARK, APLOG_WARNING, rv, gconf->ap_server, APLOGNO(10352)
-                         "Failed to release TLS session cache lock");
-        }
-    }
-}
-
-static rustls_result tls_cache_get(
-    void *userdata,
-    const rustls_slice_bytes *key,
-    int remove_after,
-    unsigned char *buf,
-    size_t count,
-    size_t *out_n)
-{
-    conn_rec *c = userdata;
-    tls_conf_conn_t *cc = tls_conf_conn_get(c);
-    tls_conf_server_t *sc = tls_conf_server_get(cc->server);
-    apr_status_t rv = APR_ENOENT;
-    unsigned int vlen, klen;
-    const unsigned char *kdata;
-
-    if (!sc->global->session_cache) goto not_found;
-    tls_cache_lock(sc->global);
-
-    kdata = key->data;
-    klen = (unsigned int)key->len;
-    vlen = (unsigned int)count;
-    rv = sc->global->session_cache_provider->retrieve(
-        sc->global->session_cache, cc->server, kdata, klen, buf, &vlen, c->pool);
-
-    if (APLOGctrace4(c)) {
-        apr_ssize_t n = klen;
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE4, rv, c, "retrieve key %d[%8x], found %d val",
-            klen, apr_hashfunc_default((const char*)kdata, &n), vlen);
-    }
-    if (remove_after || (APR_SUCCESS != rv && !APR_STATUS_IS_NOTFOUND(rv))) {
-        sc->global->session_cache_provider->remove(
-            sc->global->session_cache, cc->server, key->data, klen, c->pool);
-    }
-
-    tls_cache_unlock(sc->global);
-    if (APR_SUCCESS != rv) goto not_found;
-    cc->session_id_cache_hit = 1;
-    *out_n = count;
-    return RUSTLS_RESULT_OK;
-
-not_found:
-    *out_n = 0;
-    return RUSTLS_RESULT_NOT_FOUND;
-}
-
-static rustls_result tls_cache_put(
-    void *userdata,
-    const rustls_slice_bytes *key,
-    const rustls_slice_bytes *val)
-{
-    conn_rec *c = userdata;
-    tls_conf_conn_t *cc = tls_conf_conn_get(c);
-    tls_conf_server_t *sc = tls_conf_server_get(cc->server);
-    apr_status_t rv = APR_ENOENT;
-    apr_time_t expires_at;
-    unsigned int klen, vlen;
-    const unsigned char *kdata;
-
-    if (!sc->global->session_cache) goto not_stored;
-    tls_cache_lock(sc->global);
-
-    expires_at = apr_time_now() + apr_time_from_sec(300);
-    kdata = key->data;
-    klen = (unsigned int)key->len;
-    vlen = (unsigned int)val->len;
-    rv = sc->global->session_cache_provider->store(sc->global->session_cache, cc->server,
-                                                   kdata, klen, expires_at,
-                                                   (unsigned char*)val->data, vlen, c->pool);
-    if (APLOGctrace4(c)) {
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE4, rv, c,
-            "stored %d key bytes, with %d val bytes", klen, vlen);
-    }
-    tls_cache_unlock(sc->global);
-    if (APR_SUCCESS != rv) goto not_stored;
-    return RUSTLS_RESULT_OK;
-
-not_stored:
-    return RUSTLS_RESULT_NOT_FOUND;
-}
-
-apr_status_t tls_cache_init_server(
-    rustls_server_config_builder *builder, server_rec *s)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(s);
-
-    if (sc && sc->global->session_cache) {
-        ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s, "adding session persistence to rustls");
-        rustls_server_config_builder_set_persistence(
-            builder, tls_cache_get, tls_cache_put);
-    }
-    return APR_SUCCESS;
-}
diff --git a/modules/tls/tls_cache.h b/modules/tls/tls_cache.h
deleted file mode 100644 (file)
index 64ca077..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef tls_cache_h
-#define tls_cache_h
-
-/* name of the global session cache mutex, should we need it */
-#define TLS_SESSION_CACHE_MUTEX_TYPE    "tls-session-cache"
-
-
-/**
- * Set the specification of the session cache to use. The syntax is
- *   "default|none|<provider_name>(:<arguments>)?"
- *
- * @param spec the cache specification
- * @param gconf the modules global configuration
- * @param p pool for permanent allocations
- * @param ptemp  pool for temporary allocations
- * @return NULL on success or an error message
- */
-const char *tls_cache_set_specification(
-    const char *spec, tls_conf_global_t *gconf, apr_pool_t *p, apr_pool_t *ptemp);
-
-/**
- * Setup before configuration runs, announces our potential global mutex.
- */
-void tls_cache_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp);
-
-/**
- * Verify the cache settings at the end of the configuration and
- * create the default session cache, if not already done.
- */
-apr_status_t tls_cache_post_config(apr_pool_t *p, apr_pool_t *ptemp, server_rec *s);
-
-/**
- * Started a new child, make sure that global mutex we might use is set up.
- */
-void tls_cache_init_child(apr_pool_t *p, server_rec *s);
-
-/**
- * Free all cache related resources.
- */
-void tls_cache_free(server_rec *s);
-
-/**
- * Initialize the session store for the server's config builder.
- */
-apr_status_t tls_cache_init_server(
-    rustls_server_config_builder *builder, server_rec *s);
-
-#endif /* tls_cache_h */
\ No newline at end of file
diff --git a/modules/tls/tls_cert.c b/modules/tls/tls_cert.c
deleted file mode 100644 (file)
index ffb941c..0000000
+++ /dev/null
@@ -1,583 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <assert.h>
-#include <apr_lib.h>
-#include <apr_encode.h>
-#include <apr_strings.h>
-
-#include <httpd.h>
-#include <http_connection.h>
-#include <http_core.h>
-#include <http_log.h>
-
-#include <rustls.h>
-
-#include "tls_cert.h"
-#include "tls_util.h"
-
-extern module AP_MODULE_DECLARE_DATA tls_module;
-APLOG_USE_MODULE(tls);
-
-
-apr_status_t tls_cert_load_pem(
-    apr_pool_t *p, const tls_cert_spec_t *cert, tls_cert_pem_t **ppem)
-{
-    apr_status_t rv;
-    const char *fpath;
-    tls_cert_pem_t *cpem;
-
-    ap_assert(cert->cert_file);
-    cpem = apr_pcalloc(p, sizeof(*cpem));
-    fpath = ap_server_root_relative(p, cert->cert_file);
-    if (NULL == fpath) {
-        rv = APR_ENOENT; goto cleanup;
-    }
-    rv = tls_util_file_load(p, fpath, 0, 100*1024, &cpem->cert_pem);
-    if (APR_SUCCESS != rv) goto cleanup;
-
-    if (cert->pkey_file) {
-        fpath = ap_server_root_relative(p, cert->pkey_file);
-        if (NULL == fpath) {
-            rv = APR_ENOENT; goto cleanup;
-        }
-        rv = tls_util_file_load(p, fpath, 0, 100*1024, &cpem->pkey_pem);
-        if (APR_SUCCESS != rv) goto cleanup;
-    }
-    else {
-        cpem->pkey_pem = cpem->cert_pem;
-    }
-cleanup:
-    *ppem = (APR_SUCCESS == rv)? cpem : NULL;
-    return rv;
-}
-
-#define PEM_IN_CHUNK    48      /* PEM demands at most 64 chars per line */
-
-static apr_status_t tls_der_to_pem(
-    const char **ppem, apr_pool_t *p,
-    const unsigned char *der_data, apr_size_t der_len,
-    const char *header, const char *footer)
-{
-    apr_status_t rv = APR_SUCCESS;
-    char *pem = NULL, *s;
-    apr_size_t b64_len, n, hd_len, ft_len;
-    apr_ssize_t in_len, i;
-
-    if (der_len > INT_MAX) {
-        rv = APR_ENOMEM;
-        goto cleanup;
-    }
-    in_len = (apr_ssize_t)der_len;
-    rv = apr_encode_base64(NULL, (const char*)der_data, in_len, APR_ENCODE_NONE, &b64_len);
-    if (APR_SUCCESS != rv) goto cleanup;
-    if (b64_len > INT_MAX) {
-        rv = APR_ENOMEM;
-        goto cleanup;
-    }
-    hd_len = header? strlen(header) : 0;
-    ft_len = footer? strlen(footer) : 0;
-    s = pem = apr_pcalloc(p,
-        + b64_len + (der_len/PEM_IN_CHUNK) + 1 /* \n per chunk */
-        + hd_len +1 + ft_len + 1 /* adding \n */
-        + 1); /* NUL-terminated */
-    if (header) {
-        strcpy(s, header);
-        s += hd_len;
-        *s++ = '\n';
-    }
-    for (i = 0; in_len > 0; i += PEM_IN_CHUNK, in_len -= PEM_IN_CHUNK) {
-        rv = apr_encode_base64(s,
-            (const char*)der_data + i, in_len > PEM_IN_CHUNK? PEM_IN_CHUNK : in_len,
-            APR_ENCODE_NONE, &n);
-        s += n;
-        *s++ = '\n';
-    }
-    if (footer) {
-        strcpy(s, footer);
-        s += ft_len;
-        *s++ = '\n';
-    }
-cleanup:
-    *ppem = (APR_SUCCESS == rv)? pem : NULL;
-    return rv;
-}
-
-#define PEM_CERT_HD     "-----BEGIN CERTIFICATE-----"
-#define PEM_CERT_FT     "-----END CERTIFICATE-----"
-
-apr_status_t tls_cert_to_pem(const char **ppem, apr_pool_t *p, const rustls_certificate *cert)
-{
-    const unsigned char* der_data;
-    size_t der_len;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    apr_status_t rv = APR_SUCCESS;
-    const char *pem = NULL;
-
-    rr = rustls_certificate_get_der(cert, &der_data, &der_len);
-    if (RUSTLS_RESULT_OK != rr) goto cleanup;
-    rv = tls_der_to_pem(&pem, p, der_data, der_len, PEM_CERT_HD, PEM_CERT_FT);
-cleanup:
-    if (RUSTLS_RESULT_OK != rr) {
-        rv = tls_util_rustls_error(p, rr, NULL);
-    }
-    *ppem = (APR_SUCCESS == rv)? pem : NULL;
-    return rv;
-}
-
-static void nullify_key_pem(tls_cert_pem_t *pems)
-{
-    if (pems->pkey_pem.len) {
-        memset((void*)pems->pkey_pem.data, 0, pems->pkey_pem.len);
-    }
-}
-
-static apr_status_t make_certified_key(
-    apr_pool_t *p, const char *name,
-    const tls_data_t *cert_pem, const tls_data_t *pkey_pem,
-    const rustls_certified_key **pckey)
-{
-    const rustls_certified_key *ckey = NULL;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    apr_status_t rv = APR_SUCCESS;
-
-    rr = rustls_certified_key_build(
-        cert_pem->data, cert_pem->len,
-        pkey_pem->data, pkey_pem->len,
-        &ckey);
-
-    if (RUSTLS_RESULT_OK != rr) {
-        const char *err_descr;
-        rv = tls_util_rustls_error(p, rr, &err_descr);
-        ap_log_perror(APLOG_MARK, APLOG_ERR, rv, p, APLOGNO(10363)
-                     "Failed to load certified key %s: [%d] %s",
-                     name, (int)rr, err_descr);
-    }
-    if (APR_SUCCESS == rv) {
-        *pckey = ckey;
-    }
-    else if (ckey) {
-        rustls_certified_key_free(ckey);
-    }
-    return rv;
-}
-
-apr_status_t tls_cert_load_cert_key(
-    apr_pool_t *p, const tls_cert_spec_t *spec,
-    const char **pcert_pem, const rustls_certified_key **pckey)
-{
-    apr_status_t rv = APR_SUCCESS;
-
-    if (spec->cert_file) {
-        tls_cert_pem_t *pems;
-
-        rv = tls_cert_load_pem(p, spec, &pems);
-        if (APR_SUCCESS != rv) goto cleanup;
-        if (pcert_pem) *pcert_pem = tls_data_to_str(p, &pems->cert_pem);
-        rv = make_certified_key(p, spec->cert_file, &pems->cert_pem, &pems->pkey_pem, pckey);
-        /* dont want them hanging around in memory unnecessarily. */
-        nullify_key_pem(pems);
-    }
-    else if (spec->cert_pem) {
-        tls_data_t pkey_pem, pem;
-        pem = tls_data_from_str(spec->cert_pem);
-        if (spec->pkey_pem) {
-            pkey_pem = tls_data_from_str(spec->pkey_pem);
-        }
-        else {
-            pkey_pem = pem;
-        }
-        if (pcert_pem) *pcert_pem = spec->cert_pem;
-        rv = make_certified_key(p, "memory", &pem, &pkey_pem, pckey);
-        /* pems provided from outside are responsibility of the caller */
-    }
-    else {
-        rv = APR_ENOENT; goto cleanup;
-    }
-cleanup:
-    return rv;
-}
-
-typedef struct {
-    const char *id;
-    const char *cert_pem;
-    server_rec *server;
-    const rustls_certified_key *certified_key;
-} tls_cert_reg_entry_t;
-
-static int reg_entry_cleanup(void *ctx, const void *key, apr_ssize_t klen, const void *val)
-{
-    tls_cert_reg_entry_t *entry = (tls_cert_reg_entry_t*)val;
-    (void)ctx; (void)key; (void)klen;
-    if (entry->certified_key) {
-        rustls_certified_key_free(entry->certified_key);
-        entry->certified_key = NULL;
-    }
-    return 1;
-}
-
-static apr_status_t reg_cleanup(void *data)
-{
-    tls_cert_reg_t *reg = data;
-    if (reg->id2entry) {
-        apr_hash_do(reg_entry_cleanup, reg, reg->id2entry);
-        apr_hash_clear(reg->id2entry);
-        if (reg->key2entry) apr_hash_clear(reg->key2entry);
-    }
-    return APR_SUCCESS;
-}
-
-tls_cert_reg_t *tls_cert_reg_make(apr_pool_t *p)
-{
-    tls_cert_reg_t *reg;
-
-    reg = apr_pcalloc(p, sizeof(*reg));
-    reg->pool = p;
-    reg->id2entry = apr_hash_make(p);
-    reg->key2entry = apr_hash_make(p);
-    apr_pool_cleanup_register(p, reg, reg_cleanup, apr_pool_cleanup_null);
-    return reg;
-}
-
-apr_size_t tls_cert_reg_count(tls_cert_reg_t *reg)
-{
-    return apr_hash_count(reg->id2entry);
-}
-
-static const char *cert_spec_to_id(const tls_cert_spec_t *spec)
-{
-    if (spec->cert_file) return spec->cert_file;
-    if (spec->cert_pem) return spec->cert_pem;
-    return NULL;
-}
-
-apr_status_t tls_cert_reg_get_certified_key(
-    tls_cert_reg_t *reg, server_rec *s, const tls_cert_spec_t *spec,
-    const rustls_certified_key **pckey)
-{
-    apr_status_t rv = APR_SUCCESS;
-    const char *id;
-    tls_cert_reg_entry_t *entry;
-
-    id = cert_spec_to_id(spec);
-    assert(id);
-    entry = apr_hash_get(reg->id2entry, id, APR_HASH_KEY_STRING);
-    if (!entry) {
-        const rustls_certified_key *certified_key;
-        const char *cert_pem;
-        rv = tls_cert_load_cert_key(reg->pool, spec, &cert_pem, &certified_key);
-        if (APR_SUCCESS != rv) goto cleanup;
-        entry = apr_pcalloc(reg->pool, sizeof(*entry));
-        entry->id = apr_pstrdup(reg->pool, id);
-        entry->cert_pem = cert_pem;
-        entry->server = s;
-        entry->certified_key = certified_key;
-        apr_hash_set(reg->id2entry, entry->id, APR_HASH_KEY_STRING, entry);
-        /* associates the pointer value */
-        apr_hash_set(reg->key2entry, &entry->certified_key, sizeof(entry->certified_key), entry);
-    }
-
-cleanup:
-    if (APR_SUCCESS == rv) {
-        *pckey = entry->certified_key;
-    }
-    else {
-        *pckey = NULL;
-    }
-    return rv;
-}
-
-typedef struct {
-    void *userdata;
-    tls_cert_reg_visitor *visitor;
-} reg_visit_ctx_t;
-
-static int reg_visit(void *vctx, const void *key, apr_ssize_t klen, const void *val)
-{
-    reg_visit_ctx_t *ctx = vctx;
-    tls_cert_reg_entry_t *entry = (tls_cert_reg_entry_t*)val;
-
-    (void)key; (void)klen;
-    return ctx->visitor(ctx->userdata, entry->server, entry->id, entry->cert_pem, entry->certified_key);
-}
-
-void tls_cert_reg_do(
-    tls_cert_reg_visitor *visitor, void *userdata, tls_cert_reg_t *reg)
-{
-    reg_visit_ctx_t ctx;
-    ctx.visitor = visitor;
-    ctx.userdata = userdata;
-    apr_hash_do(reg_visit, &ctx, reg->id2entry);
-}
-
-const char *tls_cert_reg_get_id(tls_cert_reg_t *reg, const rustls_certified_key *certified_key)
-{
-    tls_cert_reg_entry_t *entry;
-
-    entry = apr_hash_get(reg->key2entry, &certified_key, sizeof(certified_key));
-    return entry? entry->id : NULL;
-}
-
-apr_status_t tls_cert_load_root_store(
-    apr_pool_t *p, const char *store_file, const rustls_root_cert_store **pstore)
-{
-    const char *fpath;
-    tls_data_t pem;
-    rustls_root_cert_store_builder *store_builder = NULL;
-    const rustls_root_cert_store *store = NULL;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    apr_pool_t *ptemp = NULL;
-    apr_status_t rv;
-
-    ap_assert(store_file);
-
-    rv = apr_pool_create(&ptemp, p);
-    if (APR_SUCCESS != rv) goto cleanup;
-    apr_pool_tag(ptemp, "tls_load_root_cert_store");
-    fpath = ap_server_root_relative(ptemp, store_file);
-    if (NULL == fpath) {
-        rv = APR_ENOENT; goto cleanup;
-    }
-    /* we use this for client auth CAs. 1MB seems large enough. */
-    rv = tls_util_file_load(ptemp, fpath, 0, 1024*1024, &pem);
-    if (APR_SUCCESS != rv) goto cleanup;
-
-    store_builder = rustls_root_cert_store_builder_new();
-    rr = rustls_root_cert_store_builder_add_pem(store_builder, pem.data, pem.len, 1);
-    if (RUSTLS_RESULT_OK != rr) goto cleanup;
-
-    rr = rustls_root_cert_store_builder_build(store_builder, &store);
-    if (RUSTLS_RESULT_OK != rr) goto cleanup;
-
-cleanup:
-    if (store_builder != NULL) {
-        rustls_root_cert_store_builder_free(store_builder);
-    }
-    if (RUSTLS_RESULT_OK != rr) {
-        const char *err_descr;
-        rv = tls_util_rustls_error(p, rr, &err_descr);
-        ap_log_perror(APLOG_MARK, APLOG_ERR, rv, p, APLOGNO(10364)
-                     "Failed to load root store %s: [%d] %s",
-                     store_file, (int)rr, err_descr);
-    }
-    if (APR_SUCCESS == rv) {
-        *pstore = store;
-    }
-    else {
-        *pstore = NULL;
-        if (store) rustls_root_cert_store_free(store);
-    }
-    if (ptemp) apr_pool_destroy(ptemp);
-    return rv;
-}
-
-typedef struct {
-    const char *id;
-    const rustls_root_cert_store *store;
-} tls_cert_root_stores_entry_t;
-
-static int stores_entry_cleanup(void *ctx, const void *key, apr_ssize_t klen, const void *val)
-{
-    tls_cert_root_stores_entry_t *entry = (tls_cert_root_stores_entry_t*)val;
-    (void)ctx; (void)key; (void)klen;
-    if (entry->store) {
-        rustls_root_cert_store_free(entry->store);
-        entry->store = NULL;
-    }
-    return 1;
-}
-
-static apr_status_t stores_cleanup(void *data)
-{
-    tls_cert_root_stores_t *stores = data;
-    tls_cert_root_stores_clear(stores);
-    return APR_SUCCESS;
-}
-
-tls_cert_root_stores_t *tls_cert_root_stores_make(apr_pool_t *p)
-{
-    tls_cert_root_stores_t *stores;
-
-    stores = apr_pcalloc(p, sizeof(*stores));
-    stores->pool = p;
-    stores->file2store = apr_hash_make(p);
-    apr_pool_cleanup_register(p, stores, stores_cleanup, apr_pool_cleanup_null);
-    return stores;
-}
-
-void tls_cert_root_stores_clear(tls_cert_root_stores_t *stores)
-{
-    if (stores->file2store) {
-        apr_hash_do(stores_entry_cleanup, stores, stores->file2store);
-        apr_hash_clear(stores->file2store);
-    }
-}
-
-apr_status_t tls_cert_root_stores_get(
-    tls_cert_root_stores_t *stores,
-    const char *store_file,
-    const rustls_root_cert_store **pstore)
-{
-    apr_status_t rv = APR_SUCCESS;
-    tls_cert_root_stores_entry_t *entry;
-
-    entry = apr_hash_get(stores->file2store, store_file, APR_HASH_KEY_STRING);
-    if (!entry) {
-        const rustls_root_cert_store *store;
-        rv = tls_cert_load_root_store(stores->pool, store_file, &store);
-        if (APR_SUCCESS != rv) goto cleanup;
-        entry = apr_pcalloc(stores->pool, sizeof(*entry));
-        entry->id = apr_pstrdup(stores->pool, store_file);
-        entry->store = store;
-        apr_hash_set(stores->file2store, entry->id, APR_HASH_KEY_STRING, entry);
-    }
-
-cleanup:
-    if (APR_SUCCESS == rv) {
-        *pstore = entry->store;
-    }
-    else {
-        *pstore = NULL;
-    }
-    return rv;
-}
-
-typedef struct {
-    const char *id;
-    rustls_client_cert_verifier *client_verifier;
-    rustls_client_cert_verifier *client_verifier_opt;
-} tls_cert_verifiers_entry_t;
-
-static int verifiers_entry_cleanup(void *ctx, const void *key, apr_ssize_t klen, const void *val)
-{
-    tls_cert_verifiers_entry_t *entry = (tls_cert_verifiers_entry_t*)val;
-    (void)ctx; (void)key; (void)klen;
-    if (entry->client_verifier) {
-        rustls_client_cert_verifier_free(entry->client_verifier);
-        entry->client_verifier = NULL;
-    }
-    if (entry->client_verifier_opt) {
-        rustls_client_cert_verifier_free(entry->client_verifier_opt);
-        entry->client_verifier_opt = NULL;
-    }
-    return 1;
-}
-
-static apr_status_t verifiers_cleanup(void *data)
-{
-    tls_cert_verifiers_t *verifiers = data;
-    tls_cert_verifiers_clear(verifiers);
-    return APR_SUCCESS;
-}
-
-tls_cert_verifiers_t *tls_cert_verifiers_make(
-    apr_pool_t *p, tls_cert_root_stores_t *stores)
-{
-    tls_cert_verifiers_t *verifiers;
-
-    verifiers = apr_pcalloc(p, sizeof(*verifiers));
-    verifiers->pool = p;
-    verifiers->stores = stores;
-    verifiers->file2verifier = apr_hash_make(p);
-    apr_pool_cleanup_register(p, verifiers, verifiers_cleanup, apr_pool_cleanup_null);
-    return verifiers;
-}
-
-void tls_cert_verifiers_clear(tls_cert_verifiers_t *verifiers)
-{
-    if (verifiers->file2verifier) {
-        apr_hash_do(verifiers_entry_cleanup, verifiers, verifiers->file2verifier);
-        apr_hash_clear(verifiers->file2verifier);
-    }
-}
-
-static tls_cert_verifiers_entry_t * verifiers_get_or_make_entry(
-    tls_cert_verifiers_t *verifiers,
-    const char *store_file)
-{
-    tls_cert_verifiers_entry_t *entry;
-
-    entry = apr_hash_get(verifiers->file2verifier, store_file, APR_HASH_KEY_STRING);
-    if (!entry) {
-        entry = apr_pcalloc(verifiers->pool, sizeof(*entry));
-        entry->id = apr_pstrdup(verifiers->pool, store_file);
-        apr_hash_set(verifiers->file2verifier, entry->id, APR_HASH_KEY_STRING, entry);
-    }
-    return entry;
-}
-
-static apr_status_t tls_cert_client_verifiers_get_internal(
-        tls_cert_verifiers_t *verifiers,
-        const char *store_file,
-        const rustls_client_cert_verifier **pverifier,
-        bool allow_unauthenticated)
-{
-    apr_status_t rv = APR_SUCCESS;
-    tls_cert_verifiers_entry_t *entry;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    struct rustls_web_pki_client_cert_verifier_builder *verifier_builder = NULL;
-
-    entry = verifiers_get_or_make_entry(verifiers, store_file);
-    if (!entry->client_verifier) {
-        const rustls_root_cert_store *store;
-        rv = tls_cert_root_stores_get(verifiers->stores, store_file, &store);
-        if (APR_SUCCESS != rv) goto cleanup;
-        verifier_builder = rustls_web_pki_client_cert_verifier_builder_new(store);
-
-        if (allow_unauthenticated) {
-            rr = rustls_web_pki_client_cert_verifier_builder_allow_unauthenticated(verifier_builder);
-            if (rr != RUSTLS_RESULT_OK) {
-                goto cleanup;
-            }
-        }
-
-        rr = rustls_web_pki_client_cert_verifier_builder_build(verifier_builder, &entry->client_verifier);
-        if (rr != RUSTLS_RESULT_OK) {
-            goto cleanup;
-        }
-    }
-
-cleanup:
-    if (verifier_builder != NULL) {
-        rustls_web_pki_client_cert_verifier_builder_free(verifier_builder);
-    }
-    if (rr != RUSTLS_RESULT_OK) {
-        rv = tls_util_rustls_error(verifiers->pool, rr, NULL);
-    }
-    if (APR_SUCCESS == rv) {
-        *pverifier = entry->client_verifier;
-    }
-    else {
-        *pverifier = NULL;
-    }
-    return rv;
-}
-
-
-apr_status_t tls_cert_client_verifiers_get(
-    tls_cert_verifiers_t *verifiers,
-    const char *store_file,
-    const rustls_client_cert_verifier **pverifier)
-{
-    return tls_cert_client_verifiers_get_internal(verifiers, store_file, pverifier, false);
-}
-
-apr_status_t tls_cert_client_verifiers_get_optional(
-    tls_cert_verifiers_t *verifiers,
-    const char *store_file,
-    const rustls_client_cert_verifier **pverifier)
-{
-    return tls_cert_client_verifiers_get_internal(verifiers, store_file, pverifier, true);
-}
diff --git a/modules/tls/tls_cert.h b/modules/tls/tls_cert.h
deleted file mode 100644 (file)
index 3326f0e..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef tls_cert_h
-#define tls_cert_h
-
-#include "tls_util.h"
-
-/**
- * The PEM data of a certificate and its key.
- */
-typedef struct {
-    tls_data_t cert_pem;
-    tls_data_t pkey_pem;
-} tls_cert_pem_t;
-
-/**
- * Specify a certificate via files or PEM data.
- */
-typedef struct {
-    const char *cert_file; /* file path, relative to ap_root */
-    const char *pkey_file; /* file path, relative to ap_root */
-    const char *cert_pem;  /* NUL-terminated PEM string */
-    const char *pkey_pem;  /* NUL-terminated PEM string */
-} tls_cert_spec_t;
-
-/**
- * Load the PEM data for a certificate file and key file as given in `cert`.
- */
-apr_status_t tls_cert_load_pem(
-    apr_pool_t *p, const tls_cert_spec_t *cert, tls_cert_pem_t **ppem);
-
-apr_status_t tls_cert_to_pem(const char **ppem, apr_pool_t *p, const rustls_certificate *cert);
-
-/**
- * Load a rustls certified key from a certificate specification.
- * The returned `rustls_certified_key` is owned by the caller.
- * @param p the memory pool to use
- * @param spec the specification for the certificate (file or PEM data)
- * @param cert_pem return the PEM data used for loading the certificates, optional
- * @param pckey the loaded certified key on return
- */
-apr_status_t tls_cert_load_cert_key(
-    apr_pool_t *p, const tls_cert_spec_t *spec,
-    const char **pcert_pem, const rustls_certified_key **pckey);
-
-/**
- * A registry of rustls_certified_key* by identifier.
- */
-typedef struct tls_cert_reg_t tls_cert_reg_t;
-struct  tls_cert_reg_t{
-    apr_pool_t *pool;
-    apr_hash_t *id2entry;
-    apr_hash_t *key2entry;
-};
-
-/**
- * Create a new registry with lifetime based on the memory pool.
- * The registry will take care of its memory and allocated keys when
- * the pool is destroyed.
- */
-tls_cert_reg_t *tls_cert_reg_make(apr_pool_t *p);
-
-/**
- * Return the number of certified keys in the registry.
- */
-apr_size_t tls_cert_reg_count(tls_cert_reg_t *reg);
-
-/**
- * Get a the `rustls_certified_key` identified by `spec` from the registry.
- * This will load the key the first time it is requested.
- * The returned `rustls_certified_key` is owned by the registry.
- * @param reg the certified key registry
- * @param s the server_rec this is loaded into, useful for error logging
- * @param spec the specification of the certified key
- * @param pckey the certified key instance on return
- */
-apr_status_t tls_cert_reg_get_certified_key(
-    tls_cert_reg_t *reg, server_rec *s, const tls_cert_spec_t *spec, const rustls_certified_key **pckey);
-
-/**
- * Visit all certified keys in the registry.
- * The callback may return 0 to abort the iteration.
- * @param userdata supplied by the visit invocation
- * @param s the server_rec the certified was load into first
- * @param id internal identifier of the certified key
- * @param cert_pem the PEM data of the certificate and its chain
- * @param certified_key the key instance itself
- */
-typedef int tls_cert_reg_visitor(
-    void *userdata, server_rec *s,
-    const char *id, const char *cert_pem, const rustls_certified_key *certified_key);
-
-/**
- * Visit all certified_key entries in the registry.
- * @param visitor callback invoked on each entry until it returns 0.
- * @param userdata passed to callback
- * @param reg the registry to iterate over
- */
-void tls_cert_reg_do(
-    tls_cert_reg_visitor *visitor, void *userdata, tls_cert_reg_t *reg);
-
-/**
- * Get the identity assigned to a loaded, certified key. Returns NULL, if the
- * key is not part of the registry. The returned bytes are owned by the registry
- * entry.
- * @param reg the registry to look in.
- * @param certified_key the key to get the identifier for
- */
-const char *tls_cert_reg_get_id(tls_cert_reg_t *reg, const rustls_certified_key *certified_key);
-
-/**
- * Load all root certificates from a PEM file into a rustls_root_cert_store.
- * @param p the memory pool to use
- * @param store_file the (server relative) path of the PEM file
- * @param pstore the loaded root store on success
- */
-apr_status_t tls_cert_load_root_store(
-    apr_pool_t *p, const char *store_file, const rustls_root_cert_store **pstore);
-
-typedef struct tls_cert_root_stores_t tls_cert_root_stores_t;
-struct tls_cert_root_stores_t {
-    apr_pool_t *pool;
-    apr_hash_t *file2store;
-};
-
-/**
- * Create a new root stores registry with lifetime based on the memory pool.
- * The registry will take care of its memory and allocated stores when
- * the pool is destroyed.
- */
-tls_cert_root_stores_t *tls_cert_root_stores_make(apr_pool_t *p);
-
-/**
- * Clear the root stores registry, freeing all stores.
- */
-void tls_cert_root_stores_clear(tls_cert_root_stores_t *stores);
-
-/**
- * Load all root certificates from a PEM file into a rustls_root_cert_store.
- * @param p the memory pool to use
- * @param store_file the (server relative) path of the PEM file
- * @param pstore the loaded root store on success
- */
-apr_status_t tls_cert_root_stores_get(
-    tls_cert_root_stores_t *stores,
-    const char *store_file,
-    const rustls_root_cert_store **pstore);
-
-typedef struct tls_cert_verifiers_t tls_cert_verifiers_t;
-struct tls_cert_verifiers_t {
-    apr_pool_t *pool;
-    tls_cert_root_stores_t *stores;
-    apr_hash_t *file2verifier;
-};
-
-/**
- * Create a new registry for certificate verifiers with lifetime based on the memory pool.
- * The registry will take care of its memory and allocated verifiers when
- * the pool is destroyed.
- * @param p the memory pool to use
- * @param stores the store registry for lookups
- */
-tls_cert_verifiers_t *tls_cert_verifiers_make(
-    apr_pool_t *p, tls_cert_root_stores_t *stores);
-
-/**
- * Clear the verifiers registry, freeing all verifiers.
- */
-void tls_cert_verifiers_clear(
-    tls_cert_verifiers_t *verifiers);
-
-/**
- * Get the mandatory client certificate verifier for the
- * root certificate store in `store_file`. Will create
- * the verifier if not already known.
- * @param verifiers the registry of certificate verifiers
- * @param store_file the (server relative) path of the PEM file with certificates
- * @param pverifiers the verifier on success
- */
-apr_status_t tls_cert_client_verifiers_get(
-    tls_cert_verifiers_t *verifiers,
-    const char *store_file,
-    const rustls_client_cert_verifier **pverifier);
-
-/**
- * Get the optional client certificate verifier for the
- * root certificate store in `store_file`. Will create
- * the verifier if not already known.
- * @param verifiers the registry of certificate verifiers
- * @param store_file the (server relative) path of the PEM file with certificates
- * @param pverifiers the verifier on success
- */
-apr_status_t tls_cert_client_verifiers_get_optional(
-    tls_cert_verifiers_t *verifiers,
-    const char *store_file,
-    const rustls_client_cert_verifier **pverifier);
-
-#endif /* tls_cert_h */
diff --git a/modules/tls/tls_conf.c b/modules/tls/tls_conf.c
deleted file mode 100644 (file)
index a9f27de..0000000
+++ /dev/null
@@ -1,780 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <assert.h>
-#include <apr_lib.h>
-#include <apr_strings.h>
-#include <apr_version.h>
-
-#include <httpd.h>
-#include <http_core.h>
-#include <http_config.h>
-#include <http_log.h>
-#include <http_main.h>
-#include <ap_socache.h>
-
-#include <rustls.h>
-
-#include "tls_cert.h"
-#include "tls_proto.h"
-#include "tls_conf.h"
-#include "tls_util.h"
-#include "tls_var.h"
-#include "tls_cache.h"
-
-
-extern module AP_MODULE_DECLARE_DATA tls_module;
-APLOG_USE_MODULE(tls);
-
-static tls_conf_global_t *conf_global_get_or_make(apr_pool_t *pool, server_rec *s)
-{
-    tls_conf_global_t *gconf;
-
-    /* we create this only once for apache's one ap_server_conf.
-     * If this gets called for another server, we should already have
-     * done it for ap_server_conf. */
-    if (ap_server_conf && s != ap_server_conf) {
-        tls_conf_server_t *sconf = tls_conf_server_get(ap_server_conf);
-        ap_assert(sconf);
-        ap_assert(sconf->global);
-        return sconf->global;
-    }
-
-    gconf = apr_pcalloc(pool, sizeof(*gconf));
-    gconf->ap_server = ap_server_conf;
-    gconf->status = TLS_CONF_ST_INIT;
-    gconf->proto = tls_proto_init(pool, s);
-    gconf->proxy_configs = apr_array_make(pool, 10, sizeof(tls_conf_proxy_t*));
-
-    gconf->var_lookups = apr_hash_make(pool);
-    tls_var_init_lookup_hash(pool, gconf->var_lookups);
-    gconf->session_cache_spec = "default";
-
-    return gconf;
-}
-
-tls_conf_server_t *tls_conf_server_get(server_rec *s)
-{
-    tls_conf_server_t *sc = ap_get_module_config(s->module_config, &tls_module);
-    ap_assert(sc);
-    return sc;
-}
-
-
-#define CONF_S_NAME(s)  (s && s->server_hostname? s->server_hostname : "default")
-
-void *tls_conf_create_svr(apr_pool_t *pool, server_rec *s)
-{
-    tls_conf_server_t *conf;
-
-    conf = apr_pcalloc(pool, sizeof(*conf));
-    conf->global = conf_global_get_or_make(pool, s);
-    conf->server = s;
-
-    conf->enabled = TLS_FLAG_UNSET;
-    conf->cert_specs = apr_array_make(pool, 3, sizeof(tls_cert_spec_t*));
-    conf->honor_client_order = TLS_FLAG_UNSET;
-    conf->strict_sni = TLS_FLAG_UNSET;
-    conf->tls_protocol_min = TLS_FLAG_UNSET;
-    conf->tls_pref_ciphers = apr_array_make(pool, 3, sizeof(apr_uint16_t));;
-    conf->tls_supp_ciphers = apr_array_make(pool, 3, sizeof(apr_uint16_t));;
-    return conf;
-}
-
-#define MERGE_INT(base, add, field) \
-    (add->field == TLS_FLAG_UNSET)? base->field : add->field;
-
-void *tls_conf_merge_svr(apr_pool_t *pool, void *basev, void *addv)
-{
-    tls_conf_server_t *base = basev;
-    tls_conf_server_t *add = addv;
-    tls_conf_server_t *nconf;
-
-    nconf = apr_pcalloc(pool, sizeof(*nconf));
-    nconf->server = add->server;
-    nconf->global = add->global? add->global : base->global;
-
-    nconf->enabled = MERGE_INT(base, add, enabled);
-    nconf->cert_specs = apr_array_append(pool, base->cert_specs, add->cert_specs);
-    nconf->tls_protocol_min = MERGE_INT(base, add, tls_protocol_min);
-    nconf->tls_pref_ciphers = add->tls_pref_ciphers->nelts?
-        add->tls_pref_ciphers : base->tls_pref_ciphers;
-    nconf->tls_supp_ciphers = add->tls_supp_ciphers->nelts?
-        add->tls_supp_ciphers : base->tls_supp_ciphers;
-    nconf->honor_client_order = MERGE_INT(base, add, honor_client_order);
-    nconf->client_ca = add->client_ca? add->client_ca : base->client_ca;
-    nconf->client_auth = (add->client_auth != TLS_CLIENT_AUTH_UNSET)?
-        add->client_auth : base->client_auth;
-    nconf->var_user_name = add->var_user_name? add->var_user_name : base->var_user_name;
-    return nconf;
-}
-
-tls_conf_dir_t *tls_conf_dir_get(request_rec *r)
-{
-    tls_conf_dir_t *dc = ap_get_module_config(r->per_dir_config, &tls_module);
-    ap_assert(dc);
-    return dc;
-}
-
-tls_conf_dir_t *tls_conf_dir_server_get(server_rec *s)
-{
-    tls_conf_dir_t *dc = ap_get_module_config(s->lookup_defaults, &tls_module);
-    ap_assert(dc);
-    return dc;
-}
-
-void *tls_conf_create_dir(apr_pool_t *pool, char *dir)
-{
-    tls_conf_dir_t *conf;
-
-    (void)dir;
-    conf = apr_pcalloc(pool, sizeof(*conf));
-    conf->std_env_vars = TLS_FLAG_UNSET;
-    conf->proxy_enabled = TLS_FLAG_UNSET;
-    conf->proxy_protocol_min = TLS_FLAG_UNSET;
-    conf->proxy_pref_ciphers = apr_array_make(pool, 3, sizeof(apr_uint16_t));;
-    conf->proxy_supp_ciphers = apr_array_make(pool, 3, sizeof(apr_uint16_t));;
-    conf->proxy_machine_cert_specs = apr_array_make(pool, 3, sizeof(tls_cert_spec_t*));
-    return conf;
-}
-
-
-static int same_proxy_settings(tls_conf_dir_t *a, tls_conf_dir_t *b)
-{
-    return a->proxy_ca == b->proxy_ca;
-}
-
-static void dir_assign_merge(
-    tls_conf_dir_t *dest, apr_pool_t *pool, tls_conf_dir_t *base, tls_conf_dir_t *add)
-{
-    tls_conf_dir_t local;
-
-    memset(&local, 0, sizeof(local));
-    local.std_env_vars = MERGE_INT(base, add, std_env_vars);
-    local.export_cert_vars = MERGE_INT(base, add, export_cert_vars);
-    local.proxy_enabled = MERGE_INT(base, add, proxy_enabled);
-    local.proxy_ca = add->proxy_ca? add->proxy_ca : base->proxy_ca;
-    local.proxy_protocol_min = MERGE_INT(base, add, proxy_protocol_min);
-    local.proxy_pref_ciphers = add->proxy_pref_ciphers->nelts?
-        add->proxy_pref_ciphers : base->proxy_pref_ciphers;
-    local.proxy_supp_ciphers = add->proxy_supp_ciphers->nelts?
-        add->proxy_supp_ciphers : base->proxy_supp_ciphers;
-    local.proxy_machine_cert_specs = apr_array_append(pool,
-        base->proxy_machine_cert_specs, add->proxy_machine_cert_specs);
-    if (local.proxy_enabled == TLS_FLAG_TRUE) {
-        if (add->proxy_config) {
-            local.proxy_config = same_proxy_settings(&local, add)? add->proxy_config : NULL;
-        }
-        else if (base->proxy_config) {
-            local.proxy_config = same_proxy_settings(&local, base)? add->proxy_config : NULL;
-        }
-    }
-    memcpy(dest, &local, sizeof(*dest));
-}
-
-void *tls_conf_merge_dir(apr_pool_t *pool, void *basev, void *addv)
-{
-    tls_conf_dir_t *base = basev;
-    tls_conf_dir_t *add = addv;
-    tls_conf_dir_t *nconf = apr_pcalloc(pool, sizeof(*nconf));
-    dir_assign_merge(nconf, pool, base, add);
-    return nconf;
-}
-
-static void tls_conf_dir_set_options_defaults(apr_pool_t *pool, tls_conf_dir_t *dc)
-{
-    (void)pool;
-    dc->std_env_vars = TLS_FLAG_FALSE;
-    dc->export_cert_vars = TLS_FLAG_FALSE;
-}
-
-apr_status_t tls_conf_server_apply_defaults(tls_conf_server_t *sc, apr_pool_t *p)
-{
-    (void)p;
-    if (sc->enabled == TLS_FLAG_UNSET) sc->enabled = TLS_FLAG_FALSE;
-    if (sc->tls_protocol_min == TLS_FLAG_UNSET) sc->tls_protocol_min = 0;
-    if (sc->honor_client_order == TLS_FLAG_UNSET) sc->honor_client_order = TLS_FLAG_TRUE;
-    if (sc->strict_sni == TLS_FLAG_UNSET) sc->strict_sni = TLS_FLAG_TRUE;
-    if (sc->client_auth == TLS_CLIENT_AUTH_UNSET) sc->client_auth = TLS_CLIENT_AUTH_NONE;
-    return APR_SUCCESS;
-}
-
-apr_status_t tls_conf_dir_apply_defaults(tls_conf_dir_t *dc, apr_pool_t *p)
-{
-    (void)p;
-    if (dc->std_env_vars == TLS_FLAG_UNSET) dc->std_env_vars = TLS_FLAG_FALSE;
-    if (dc->export_cert_vars == TLS_FLAG_UNSET) dc->export_cert_vars = TLS_FLAG_FALSE;
-    if (dc->proxy_enabled == TLS_FLAG_UNSET) dc->proxy_enabled = TLS_FLAG_FALSE;
-    return APR_SUCCESS;
-}
-
-tls_conf_proxy_t *tls_conf_proxy_make(
-    apr_pool_t *p, tls_conf_dir_t *dc, tls_conf_global_t *gc, server_rec *s)
-{
-    tls_conf_proxy_t *pc = apr_pcalloc(p, sizeof(*pc));
-    pc->defined_in = s;
-    pc->global = gc;
-    pc->proxy_ca = dc->proxy_ca;
-    pc->proxy_protocol_min = dc->proxy_protocol_min;
-    pc->proxy_pref_ciphers = dc->proxy_pref_ciphers;
-    pc->proxy_supp_ciphers = dc->proxy_supp_ciphers;
-    pc->machine_cert_specs = dc->proxy_machine_cert_specs;
-    pc->machine_certified_keys = apr_array_make(p, 3, sizeof(const rustls_certified_key*));
-    return pc;
-}
-
-int tls_proxy_section_post_config(
-    apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s,
-    ap_conf_vector_t *section_config)
-{
-    tls_conf_dir_t *proxy_dc, *server_dc;
-    tls_conf_server_t *sc;
-
-    /* mod_proxy collects the <Proxy>...</Proxy> sections per server (base server or virtualhost)
-     * and in its post_config hook, calls our function registered at its hook for each with
-     * s - the server they were define in
-     * section_config - the set of dir_configs for a <Proxy> section
-     *
-     * If none of _our_ config directives had been used, here or in the server, we get a NULL.
-     * Which means we have to do nothing. Otherwise, we add to `proxy_dc` the
-     * settings from `server_dc` - since this is not automagically done by apache.
-     *
-     * `proxy_dc` is then complete and tells us if we handle outgoing connections
-     * here and with what parameter settings.
-     */
-    (void)ptemp; (void)plog;
-    ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
-        "%s: tls_proxy_section_post_config called", s->server_hostname);
-    proxy_dc = ap_get_module_config(section_config, &tls_module);
-    if (!proxy_dc) goto cleanup;
-    server_dc = ap_get_module_config(s->lookup_defaults, &tls_module);
-    ap_assert(server_dc);
-    dir_assign_merge(proxy_dc, p, server_dc, proxy_dc);
-    tls_conf_dir_apply_defaults(proxy_dc, p);
-    if (proxy_dc->proxy_enabled && !proxy_dc->proxy_config) {
-        /* remember `proxy_dc` for subsequent configuration of outoing TLS setups */
-        sc = tls_conf_server_get(s);
-        proxy_dc->proxy_config = tls_conf_proxy_make(p, proxy_dc, sc->global, s);
-        ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
-            "%s: adding proxy_conf to globals in proxy_post_config_section",
-            s->server_hostname);
-        APR_ARRAY_PUSH(sc->global->proxy_configs, tls_conf_proxy_t*) = proxy_dc->proxy_config;
-    }
-cleanup:
-    return OK;
-}
-
-static const char *cmd_check_file(cmd_parms *cmd, const char *fpath)
-{
-    char *real_path;
-
-    /* just a dump of the configuration, dont resolve/check */
-    if (ap_state_query(AP_SQ_RUN_MODE) == AP_SQ_RM_CONFIG_DUMP) {
-        return NULL;
-    }
-    real_path = ap_server_root_relative(cmd->pool, fpath);
-    if (!real_path) {
-        return apr_pstrcat(cmd->pool, cmd->cmd->name,
-                           ": Invalid file path ", fpath, NULL);
-    }
-    if (!tls_util_is_file(cmd->pool, real_path)) {
-        return apr_pstrcat(cmd->pool, cmd->cmd->name,
-                           ": file '", real_path,
-                           "' does not exist or is empty", NULL);
-    }
-    return NULL;
-}
-
-static const char *tls_conf_add_engine(cmd_parms *cmd, void *dc, const char*v)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(cmd->server);
-    tls_conf_global_t *gc = sc->global;
-    const char *err = NULL;
-    char *host, *scope_id;
-    apr_port_t port;
-    apr_sockaddr_t *sa;
-    server_addr_rec *sar;
-    apr_status_t rv;
-
-    (void)dc;
-    /* Example of use:
-     * TLSEngine 443
-     * TLSEngine hostname:443
-     * TLSEngine 91.0.0.1:443
-     * TLSEngine [::0]:443
-     */
-    rv = apr_parse_addr_port(&host, &scope_id, &port, v, cmd->pool);
-    if (APR_SUCCESS != rv) {
-        err = apr_pstrcat(cmd->pool, cmd->cmd->name,
-                          ": invalid address/port in '", v, "'", NULL);
-        goto cleanup;
-    }
-
-    /* translate host/port to a sockaddr that we can match with incoming connections */
-    rv = apr_sockaddr_info_get(&sa, host, APR_UNSPEC, port, 0, cmd->pool);
-    if (APR_SUCCESS != rv) {
-        err = apr_pstrcat(cmd->pool, cmd->cmd->name,
-                          ": unable to get sockaddr for '", host, "'", NULL);
-        goto cleanup;
-    }
-
-    if (scope_id) {
-#if APR_VERSION_AT_LEAST(1,7,0)
-        rv = apr_sockaddr_zone_set(sa, scope_id);
-        if (APR_SUCCESS != rv) {
-            err = apr_pstrcat(cmd->pool, cmd->cmd->name,
-                              ": error setting ipv6 scope id: '", scope_id, "'", NULL);
-            goto cleanup;
-        }
-#else
-        err = apr_pstrcat(cmd->pool, cmd->cmd->name,
-                          ": IPv6 scopes not supported by your APR: '", scope_id, "'", NULL);
-        goto cleanup;
-#endif
-    }
-
-    sar = apr_pcalloc(cmd->pool, sizeof(*sar));
-    sar->host_addr = sa;
-    sar->virthost = host;
-    sar->host_port = port;
-
-    sar->next = gc->tls_addresses;
-    gc->tls_addresses = sar;
-cleanup:
-    return err;
-}
-
-static int flag_value(
-    const char *arg)
-{
-    if (!strcasecmp(arg, "On")) {
-        return TLS_FLAG_TRUE;
-    }
-    else if (!strcasecmp(arg, "Off")) {
-        return TLS_FLAG_FALSE;
-    }
-    return TLS_FLAG_UNSET;
-}
-
-static const char *flag_err(
-    cmd_parms *cmd, const char *v)
-{
-    return apr_pstrcat(cmd->pool, cmd->cmd->name,
-        ": value must be 'On' or 'Off': '", v, "'", NULL);
-}
-
-static const char *tls_conf_add_certificate(
-    cmd_parms *cmd, void *dc, const char *cert_file, const char *pkey_file)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(cmd->server);
-    const char *err = NULL, *fpath;
-    tls_cert_spec_t *cert;
-
-    (void)dc;
-    if (NULL != (err = cmd_check_file(cmd, cert_file))) goto cleanup;
-    /* key file may be NULL, in which case cert_file must contain the key PEM */
-    if (pkey_file && NULL != (err = cmd_check_file(cmd, pkey_file))) goto cleanup;
-
-    cert = apr_pcalloc(cmd->pool, sizeof(*cert));
-    fpath = ap_server_root_relative(cmd->pool, cert_file);
-    if (!tls_util_is_file(cmd->pool, fpath)) {
-        return apr_pstrcat(cmd->pool, cmd->cmd->name,
-            ": unable to find certificate file: '", fpath, "'", NULL);
-    }
-    cert->cert_file = cert_file;
-    if (pkey_file) {
-        fpath = ap_server_root_relative(cmd->pool, pkey_file);
-        if (!tls_util_is_file(cmd->pool, fpath)) {
-            return apr_pstrcat(cmd->pool, cmd->cmd->name,
-                ": unable to find certificate key file: '", fpath, "'", NULL);
-        }
-    }
-    cert->pkey_file = pkey_file;
-    *(const tls_cert_spec_t **)apr_array_push(sc->cert_specs) = cert;
-
-cleanup:
-    return err;
-}
-
-static const char *parse_ciphers(
-    cmd_parms *cmd,
-    tls_conf_global_t *gc,
-    const char *nop_name,
-    int argc, char *const argv[],
-    apr_array_header_t *ciphers)
-{
-    apr_array_clear(ciphers);
-    if (argc > 1 || apr_strnatcasecmp(nop_name, argv[0])) {
-        apr_uint16_t cipher;
-        int i;
-
-        for (i = 0; i < argc; ++i) {
-            char *name, *last = NULL;
-            const char *value = argv[i];
-
-            name = apr_strtok(apr_pstrdup(cmd->pool, value), ":", &last);
-            while (name) {
-                if (tls_proto_get_cipher_by_name(gc->proto, name, &cipher) != APR_SUCCESS) {
-                    return apr_pstrcat(cmd->pool, cmd->cmd->name,
-                            ": cipher not recognized '", name, "'", NULL);
-                }
-                APR_ARRAY_PUSH(ciphers, apr_uint16_t) = cipher;
-                name = apr_strtok(NULL, ":", &last);
-            }
-        }
-    }
-    return NULL;
-}
-
-static const char *tls_conf_set_preferred_ciphers(
-    cmd_parms *cmd, void *dc, int argc, char *const argv[])
-{
-    tls_conf_server_t *sc = tls_conf_server_get(cmd->server);
-    const char *err = NULL;
-
-    (void)dc;
-    if (!argc) {
-        err = "specify the TLS ciphers to prefer or 'default' for the rustls default ordering.";
-        goto cleanup;
-    }
-    err = parse_ciphers(cmd, sc->global, "default", argc, argv, sc->tls_pref_ciphers);
-cleanup:
-    return err;
-}
-
-static const char *tls_conf_set_suppressed_ciphers(
-    cmd_parms *cmd, void *dc, int argc, char *const argv[])
-{
-    tls_conf_server_t *sc = tls_conf_server_get(cmd->server);
-    const char *err = NULL;
-
-    (void)dc;
-    if (!argc) {
-        err = "specify the TLS ciphers to never use or 'none'.";
-        goto cleanup;
-    }
-    err = parse_ciphers(cmd, sc->global, "none", argc, argv, sc->tls_supp_ciphers);
-cleanup:
-    return err;
-}
-
-static const char *tls_conf_set_honor_client_order(
-    cmd_parms *cmd, void *dc, const char *v)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(cmd->server);
-    int flag = flag_value(v);
-
-    (void)dc;
-    if (TLS_FLAG_UNSET == flag) return flag_err(cmd, v);
-    sc->honor_client_order = flag;
-    return NULL;
-}
-
-static const char *tls_conf_set_strict_sni(
-    cmd_parms *cmd, void *dc, const char *v)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(cmd->server);
-    int flag = flag_value(v);
-
-    (void)dc;
-    if (TLS_FLAG_UNSET == flag) return flag_err(cmd, v);
-    sc->strict_sni = flag;
-    return NULL;
-}
-
-static const char *get_min_protocol(
-    cmd_parms *cmd, const char *v, int *pmin)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(cmd->server);
-    const char *err = NULL;
-
-    if (!apr_strnatcasecmp("default", v)) {
-        *pmin = 0;
-    }
-    else if (*v && v[strlen(v)-1] == '+') {
-        char *name = apr_pstrdup(cmd->pool, v);
-        name[strlen(name)-1] = '\0';
-        *pmin = tls_proto_get_version_by_name(sc->global->proto, name);
-        if (!*pmin) {
-            err = apr_pstrcat(cmd->pool, cmd->cmd->name,
-                ": unrecognized protocol version specifier (try TLSv1.2+ or TLSv1.3+): '", v, "'", NULL);
-            goto cleanup;
-        }
-    }
-    else {
-        err = apr_pstrcat(cmd->pool, cmd->cmd->name,
-            ": value must be 'default', 'TLSv1.2+' or 'TLSv1.3+': '", v, "'", NULL);
-        goto cleanup;
-    }
-cleanup:
-    return err;
-}
-
-static const char *tls_conf_set_protocol(
-    cmd_parms *cmd, void *dc, const char *v)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(cmd->server);
-    (void)dc;
-    return get_min_protocol(cmd, v, &sc->tls_protocol_min);
-}
-
-static const char *tls_conf_set_options(
-    cmd_parms *cmd, void *dcv, int argc, char *const argv[])
-{
-    tls_conf_dir_t *dc = dcv;
-    const char *err = NULL, *option;
-    int i, val;
-
-    /* Are we only having deltas (+/-) or do we reset the options? */
-    for (i = 0; i < argc; ++i) {
-        if (argv[i][0] != '+' && argv[i][0] != '-') {
-            tls_conf_dir_set_options_defaults(cmd->pool, dc);
-            break;
-        }
-    }
-
-    for (i = 0; i < argc; ++i) {
-        option = argv[i];
-        if (!apr_strnatcasecmp("Defaults", option)) {
-            dc->std_env_vars = TLS_FLAG_FALSE;
-            dc->export_cert_vars = TLS_FLAG_FALSE;
-        }
-        else {
-            val = TLS_FLAG_TRUE;
-            if (*option == '+' || *option == '-') {
-                val = (*option == '+')? TLS_FLAG_TRUE : TLS_FLAG_FALSE;
-                ++option;
-            }
-
-            if (!apr_strnatcasecmp("StdEnvVars", option)) {
-                dc->std_env_vars = val;
-            }
-            else if (!apr_strnatcasecmp("ExportCertData", option)) {
-                dc->export_cert_vars = val;
-            }
-            else {
-                err = apr_pstrcat(cmd->pool, cmd->cmd->name,
-                                   ": unknown option '", option, "'", NULL);
-                goto cleanup;
-            }
-        }
-    }
-cleanup:
-    return err;
-}
-
-static const char *tls_conf_set_session_cache(
-    cmd_parms *cmd, void *dc, const char *value)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(cmd->server);
-    const char *err = NULL;
-
-    (void)dc;
-    if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) goto cleanup;
-
-    err = tls_cache_set_specification(value, sc->global, cmd->pool, cmd->temp_pool);
-cleanup:
-    return err;
-}
-
-static const char *tls_conf_set_proxy_engine(cmd_parms *cmd, void *dir_conf, int flag)
-{
-    tls_conf_dir_t *dc = dir_conf;
-    (void)cmd;
-    dc->proxy_enabled = flag ? TLS_FLAG_TRUE : TLS_FLAG_FALSE;
-    return NULL;
-}
-
-static const char *tls_conf_set_proxy_ca(
-    cmd_parms *cmd, void *dir_conf, const char *proxy_ca)
-{
-    tls_conf_dir_t *dc = dir_conf;
-    const char *err = NULL;
-
-    if (strcasecmp(proxy_ca, "default") && NULL != (err = cmd_check_file(cmd, proxy_ca))) goto cleanup;
-    dc->proxy_ca = proxy_ca;
-cleanup:
-    return err;
-}
-
-static const char *tls_conf_set_proxy_protocol(
-    cmd_parms *cmd, void *dir_conf, const char *v)
-{
-    tls_conf_dir_t *dc = dir_conf;
-    return get_min_protocol(cmd, v, &dc->proxy_protocol_min);
-}
-
-static const char *tls_conf_set_proxy_preferred_ciphers(
-    cmd_parms *cmd, void *dir_conf, int argc, char *const argv[])
-{
-    tls_conf_server_t *sc = tls_conf_server_get(cmd->server);
-    tls_conf_dir_t *dc = dir_conf;
-    const char *err = NULL;
-
-    if (!argc) {
-        err = "specify the proxy TLS ciphers to prefer or 'default' for the rustls default ordering.";
-        goto cleanup;
-    }
-    err = parse_ciphers(cmd, sc->global, "default", argc, argv, dc->proxy_pref_ciphers);
-cleanup:
-    return err;
-}
-
-static const char *tls_conf_set_proxy_suppressed_ciphers(
-    cmd_parms *cmd, void *dir_conf, int argc, char *const argv[])
-{
-    tls_conf_server_t *sc = tls_conf_server_get(cmd->server);
-    tls_conf_dir_t *dc = dir_conf;
-    const char *err = NULL;
-
-    if (!argc) {
-        err = "specify the proxy TLS ciphers to never use or 'none'.";
-        goto cleanup;
-    }
-    err = parse_ciphers(cmd, sc->global, "none", argc, argv, dc->proxy_supp_ciphers);
-cleanup:
-    return err;
-}
-
-#if TLS_CLIENT_CERTS
-
-static const char *tls_conf_set_client_ca(
-    cmd_parms *cmd, void *dc, const char *client_ca)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(cmd->server);
-    const char *err;
-
-    (void)dc;
-    if (NULL != (err = cmd_check_file(cmd, client_ca))) goto cleanup;
-    sc->client_ca = client_ca;
-cleanup:
-    return err;
-}
-
-static const char *tls_conf_set_client_auth(
-    cmd_parms *cmd, void *dc, const char *mode)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(cmd->server);
-    const char *err = NULL;
-    (void)dc;
-    if (!strcasecmp(mode, "required")) {
-        sc->client_auth = TLS_CLIENT_AUTH_REQUIRED;
-    }
-    else if (!strcasecmp(mode, "optional")) {
-        sc->client_auth = TLS_CLIENT_AUTH_OPTIONAL;
-    }
-    else if (!strcasecmp(mode, "none")) {
-        sc->client_auth = TLS_CLIENT_AUTH_NONE;
-    }
-    else {
-        err = apr_pstrcat(cmd->pool, cmd->cmd->name,
-            ": unknown value: '", mode, "', use required/optional/none.", NULL);
-    }
-    return err;
-}
-
-static const char *tls_conf_set_user_name(
-    cmd_parms *cmd, void *dc, const char *var_user_name)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(cmd->server);
-    (void)dc;
-    sc->var_user_name = var_user_name;
-    return NULL;
-}
-
-#endif /* if TLS_CLIENT_CERTS */
-
-#if TLS_MACHINE_CERTS
-
-static const char *tls_conf_add_proxy_machine_certificate(
-    cmd_parms *cmd, void *dir_conf, const char *cert_file, const char *pkey_file)
-{
-    tls_conf_dir_t *dc = dir_conf;
-    const char *err = NULL, *fpath;
-    tls_cert_spec_t *cert;
-
-    (void)dc;
-    if (NULL != (err = cmd_check_file(cmd, cert_file))) goto cleanup;
-    /* key file may be NULL, in which case cert_file must contain the key PEM */
-    if (pkey_file && NULL != (err = cmd_check_file(cmd, pkey_file))) goto cleanup;
-
-    cert = apr_pcalloc(cmd->pool, sizeof(*cert));
-    fpath = ap_server_root_relative(cmd->pool, cert_file);
-    if (!tls_util_is_file(cmd->pool, fpath)) {
-        return apr_pstrcat(cmd->pool, cmd->cmd->name,
-            ": unable to find certificate file: '", fpath, "'", NULL);
-    }
-    cert->cert_file = cert_file;
-    if (pkey_file) {
-        fpath = ap_server_root_relative(cmd->pool, pkey_file);
-        if (!tls_util_is_file(cmd->pool, fpath)) {
-            return apr_pstrcat(cmd->pool, cmd->cmd->name,
-                ": unable to find certificate key file: '", fpath, "'", NULL);
-        }
-    }
-    cert->pkey_file = pkey_file;
-    *(const tls_cert_spec_t **)apr_array_push(dc->proxy_machine_cert_specs) = cert;
-
-cleanup:
-    return err;
-}
-
-#endif  /* if TLS_MACHINE_CERTS */
-
-const command_rec tls_conf_cmds[] = {
-    AP_INIT_TAKE12("TLSCertificate", tls_conf_add_certificate, NULL, RSRC_CONF,
-        "Add a certificate to the server by specifying a file containing the "
-        "certificate PEM, followed by its chain PEMs. The PEM of the key must "
-        "either also be there or can be given as a separate file."),
-    AP_INIT_TAKE_ARGV("TLSCiphersPrefer", tls_conf_set_preferred_ciphers, NULL, RSRC_CONF,
-        "Set the TLS ciphers to prefer when negotiating with a client."),
-    AP_INIT_TAKE_ARGV("TLSCiphersSuppress", tls_conf_set_suppressed_ciphers, NULL, RSRC_CONF,
-        "Set the TLS ciphers to never use when negotiating with a client."),
-    AP_INIT_TAKE1("TLSHonorClientOrder", tls_conf_set_honor_client_order, NULL, RSRC_CONF,
-        "Set 'on' to have the server honor client preferences in cipher suites, default off."),
-    AP_INIT_TAKE1("TLSEngine", tls_conf_add_engine, NULL, RSRC_CONF,
-        "Specify an address+port where the module shall handle incoming TLS connections."),
-    AP_INIT_TAKE_ARGV("TLSOptions", tls_conf_set_options, NULL, OR_OPTIONS,
-        "En-/disables optional features in the module."),
-    AP_INIT_TAKE1("TLSProtocol", tls_conf_set_protocol, NULL, RSRC_CONF,
-        "Set the minimum TLS protocol version to use."),
-    AP_INIT_TAKE1("TLSStrictSNI", tls_conf_set_strict_sni, NULL, RSRC_CONF,
-        "Set strictness of client server name (SNI) check against hosts, default on."),
-    AP_INIT_TAKE1("TLSSessionCache", tls_conf_set_session_cache, NULL, RSRC_CONF,
-        "Set which cache to use for TLS sessions."),
-    AP_INIT_FLAG("TLSProxyEngine", tls_conf_set_proxy_engine, NULL, RSRC_CONF|PROXY_CONF,
-        "Enable TLS encryption of outgoing connections in this location/server."),
-    AP_INIT_TAKE1("TLSProxyCA", tls_conf_set_proxy_ca, NULL, RSRC_CONF|PROXY_CONF,
-        "Set the trust anchors for certificates from proxied backend servers from a PEM file."),
-    AP_INIT_TAKE1("TLSProxyProtocol", tls_conf_set_proxy_protocol, NULL, RSRC_CONF|PROXY_CONF,
-        "Set the minimum TLS protocol version to use for proxy connections."),
-    AP_INIT_TAKE_ARGV("TLSProxyCiphersPrefer", tls_conf_set_proxy_preferred_ciphers, NULL, RSRC_CONF|PROXY_CONF,
-        "Set the TLS ciphers to prefer when negotiating a proxy connection."),
-    AP_INIT_TAKE_ARGV("TLSProxyCiphersSuppress", tls_conf_set_proxy_suppressed_ciphers, NULL, RSRC_CONF|PROXY_CONF,
-        "Set the TLS ciphers to never use when negotiating a proxy connection."),
-#if TLS_CLIENT_CERTS
-    AP_INIT_TAKE1("TLSClientCA", tls_conf_set_client_ca, NULL, RSRC_CONF,
-        "Set the trust anchors for client certificates from a PEM file."),
-    AP_INIT_TAKE1("TLSClientCertificate", tls_conf_set_client_auth, NULL, RSRC_CONF,
-        "If TLS client authentication is 'required', 'optional' or 'none'."),
-    AP_INIT_TAKE1("TLSUserName", tls_conf_set_user_name, NULL, RSRC_CONF,
-        "Set the SSL variable to be used as user name."),
-#endif  /* if TLS_CLIENT_CERTS */
-#if TLS_MACHINE_CERTS
-    AP_INIT_TAKE12("TLSProxyMachineCertificate", tls_conf_add_proxy_machine_certificate, NULL, RSRC_CONF|PROXY_CONF,
-        "Add a certificate to be used as client certificate on a proxy connection. "),
-#endif  /* if TLS_MACHINE_CERTS */
-    AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
-};
diff --git a/modules/tls/tls_conf.h b/modules/tls/tls_conf.h
deleted file mode 100644 (file)
index e924412..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef tls_conf_h
-#define tls_conf_h
-
-/* Configuration flags */
-#define TLS_FLAG_UNSET  (-1)
-#define TLS_FLAG_FALSE  (0)
-#define TLS_FLAG_TRUE   (1)
-
-struct tls_proto_conf_t;
-struct tls_cert_reg_t;
-struct tls_cert_root_stores_t;
-struct tls_cert_verifiers_t;
-struct ap_socache_instance_t;
-struct ap_socache_provider_t;
-struct apr_global_mutex_t;
-
-
-/* disabled, since rustls support is lacking
- * - x.509 retrieval of certificate fields and extensions
- * - certificate revocation lists (CRL)
- * - x.509 access to issuer of trust chain in x.509 CA store:
- *      server CA has ca1, ca2, ca3
- *      client present certA
- *      rustls verifies that it is signed by *one of* ca* certs
- *      OCSP check needs (certA, issuing cert) for query
- */
-#define TLS_CLIENT_CERTS    0
-
-/* support for this exists as PR <https://github.com/rustls/rustls-ffi/pull/128>
- */
-#define TLS_MACHINE_CERTS    1
-
-
-typedef enum {
-    TLS_CLIENT_AUTH_UNSET,
-    TLS_CLIENT_AUTH_NONE,
-    TLS_CLIENT_AUTH_REQUIRED,
-    TLS_CLIENT_AUTH_OPTIONAL,
-} tls_client_auth_t;
-
-typedef enum {
-    TLS_CONF_ST_INIT,
-    TLS_CONF_ST_INCOMING_DONE,
-    TLS_CONF_ST_OUTGOING_DONE,
-    TLS_CONF_ST_DONE,
-} tls_conf_status_t;
-
-/* The global module configuration, created after post-config
- * and then readonly.
- */
-typedef struct {
-    server_rec *ap_server;            /* the global server we initialized on */
-    const char *module_version;
-    const char *crustls_version;
-
-    tls_conf_status_t status;
-    int mod_proxy_post_config_done;   /* if mod_proxy did its post-config things */
-
-    server_addr_rec *tls_addresses;   /* the addresses/ports our engine is enabled on */
-    apr_array_header_t *proxy_configs; /* tls_conf_proxy_t* collected from everywhere */
-
-    struct tls_proto_conf_t *proto;   /* TLS protocol/rustls specific globals */
-    apr_hash_t *var_lookups;          /* variable lookup functions by var name */
-    struct tls_cert_reg_t *cert_reg;  /* all certified keys loaded */
-    struct tls_cert_root_stores_t *stores; /* loaded certificate stores */
-    struct tls_cert_verifiers_t *verifiers; /* registry of certificate verifiers */
-
-    const char *session_cache_spec;   /* how the session cache was specified */
-    const struct ap_socache_provider_t *session_cache_provider; /* provider used for session cache */
-    struct ap_socache_instance_t *session_cache; /* session cache instance */
-    struct apr_global_mutex_t *session_cache_mutex; /* global mutex for access to session cache */
-
-    const rustls_server_config *rustls_hello_config; /* used for initial client hello parsing */
-} tls_conf_global_t;
-
-/* The module configuration for a server (vhost).
- * Populated during config parsing, merged and completed
- * in the post config phase. Readonly after that.
- */
-typedef struct {
-    server_rec *server;               /* server this config belongs to */
-    tls_conf_global_t *global;        /* global module config, singleton */
-
-    int enabled;                      /* TLS_FLAG_TRUE if mod_tls is active on this server */
-    apr_array_header_t *cert_specs;   /* array of (tls_cert_spec_t*) of configured certificates */
-    int tls_protocol_min;             /* the minimum TLS protocol version to use */
-    apr_array_header_t *tls_pref_ciphers;  /* List of apr_uint16_t cipher ids to prefer */
-    apr_array_header_t *tls_supp_ciphers;  /* List of apr_uint16_t cipher ids to suppress */
-    const apr_array_header_t *ciphersuites;  /* Computed post-config, ordered list of rustls cipher suites */
-    int honor_client_order;           /* honor client cipher ordering */
-    int strict_sni;
-
-    const char *client_ca;            /* PEM file with trust anchors for client certs */
-    tls_client_auth_t client_auth;    /* how client authentication with certificates is used */
-    const char *var_user_name;        /* which SSL variable to use as user name */
-
-    apr_array_header_t *certified_keys; /* rustls_certified_key list configured */
-    int base_server;                  /* != 0 iff this is the base server */
-    int service_unavailable;          /* TLS not trustworthy configured, return 503s */
-} tls_conf_server_t;
-
-typedef struct {
-    server_rec *defined_in;           /* the server/host defining this dir_conf */
-    tls_conf_global_t *global;        /* global module config, singleton */
-    const char *proxy_ca;             /* PEM file with trust anchors for proxied remote server certs */
-    int proxy_protocol_min;            /* the minimum TLS protocol version to use for proxy connections */
-    apr_array_header_t *proxy_pref_ciphers;  /* List of apr_uint16_t cipher ids to prefer */
-    apr_array_header_t *proxy_supp_ciphers;  /* List of apr_uint16_t cipher ids to suppress */
-    apr_array_header_t *machine_cert_specs; /* configured machine certificates specs */
-    apr_array_header_t *machine_certified_keys;  /* rustls_certified_key list */
-    const rustls_client_config *rustls_config;
-} tls_conf_proxy_t;
-
-typedef struct {
-    int std_env_vars;
-    int export_cert_vars;
-    int proxy_enabled;                /* TLS_FLAG_TRUE if mod_tls is active on outgoing connections */
-    const char *proxy_ca;             /* PEM file with trust anchors for proxied remote server certs */
-    int proxy_protocol_min;            /* the minimum TLS protocol version to use for proxy connections */
-    apr_array_header_t *proxy_pref_ciphers;  /* List of apr_uint16_t cipher ids to prefer */
-    apr_array_header_t *proxy_supp_ciphers;  /* List of apr_uint16_t cipher ids to suppress */
-    apr_array_header_t *proxy_machine_cert_specs; /* configured machine certificates specs */
-
-    tls_conf_proxy_t *proxy_config;
-} tls_conf_dir_t;
-
-/* our static registry of configuration directives. */
-extern const command_rec tls_conf_cmds[];
-
-/* create the modules configuration for a server_rec. */
-void *tls_conf_create_svr(apr_pool_t *pool, server_rec *s);
-
-/* merge (inherit) server configurations for the module.
- * Settings in 'add' overwrite the ones in 'base' and unspecified
- * settings shine through. */
-void *tls_conf_merge_svr(apr_pool_t *pool, void *basev, void *addv);
-
-/* create the modules configuration for a directory. */
-void *tls_conf_create_dir(apr_pool_t *pool, char *dir);
-
-/* merge (inherit) directory configurations for the module.
- * Settings in 'add' overwrite the ones in 'base' and unspecified
- * settings shine through. */
-void *tls_conf_merge_dir(apr_pool_t *pool, void *basev, void *addv);
-
-
-/* Get the server specific module configuration. */
-tls_conf_server_t *tls_conf_server_get(server_rec *s);
-
-/* Get the directory specific module configuration for the request. */
-tls_conf_dir_t *tls_conf_dir_get(request_rec *r);
-
-/* Get the directory specific module configuration for the server. */
-tls_conf_dir_t *tls_conf_dir_server_get(server_rec *s);
-
-/* If any configuration values are unset, supply the global server defaults. */
-apr_status_t tls_conf_server_apply_defaults(tls_conf_server_t *sc, apr_pool_t *p);
-
-/* If any configuration values are unset, supply the global dir defaults. */
-apr_status_t tls_conf_dir_apply_defaults(tls_conf_dir_t *dc, apr_pool_t *p);
-
-/* create a new proxy configuration from directory config in server */
-tls_conf_proxy_t *tls_conf_proxy_make(
-    apr_pool_t *p, tls_conf_dir_t *dc, tls_conf_global_t *gc, server_rec *s);
-
-int tls_proxy_section_post_config(
-    apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s,
-    ap_conf_vector_t *section_config);
-
-#endif /* tls_conf_h */
diff --git a/modules/tls/tls_core.c b/modules/tls/tls_core.c
deleted file mode 100644 (file)
index 1cef254..0000000
+++ /dev/null
@@ -1,1439 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <assert.h>
-#include <apr_lib.h>
-#include <apr_strings.h>
-#include <apr_network_io.h>
-
-#include <httpd.h>
-#include <http_core.h>
-#include <http_log.h>
-#include <http_protocol.h>
-#include <http_ssl.h>
-#include <http_vhost.h>
-#include <http_main.h>
-#include <ap_socache.h>
-
-#include <rustls.h>
-
-#include "tls_proto.h"
-#include "tls_cert.h"
-#include "tls_conf.h"
-#include "tls_core.h"
-#include "tls_ocsp.h"
-#include "tls_util.h"
-#include "tls_cache.h"
-#include "tls_var.h"
-
-
-extern module AP_MODULE_DECLARE_DATA tls_module;
-APLOG_USE_MODULE(tls);
-
-tls_conf_conn_t *tls_conf_conn_get(conn_rec *c)
-{
-    return ap_get_module_config(c->conn_config, &tls_module);
-}
-
-void tls_conf_conn_set(conn_rec *c, tls_conf_conn_t *cc)
-{
-    ap_set_module_config(c->conn_config, &tls_module, cc);
-}
-
-int tls_conn_check_ssl(conn_rec *c)
-{
-    tls_conf_conn_t *cc = tls_conf_conn_get(c->master? c->master : c);
-    if (TLS_CONN_ST_IS_ENABLED(cc)) {
-        return OK;
-    }
-    return DECLINED;
-}
-
-static int we_listen_on(tls_conf_global_t *gc, server_rec *s, tls_conf_server_t *sc)
-{
-    server_addr_rec *sa, *la;
-
-    if (gc->tls_addresses && sc->base_server) {
-        /* The base server listens to every port and may be selected via SNI */
-        return 1;
-    }
-    for (la = gc->tls_addresses; la; la = la->next) {
-        for (sa = s->addrs; sa; sa = sa->next) {
-            if (la->host_port == sa->host_port
-                && la->host_addr->ipaddr_len == sa->host_addr->ipaddr_len
-                && !memcmp(la->host_addr->ipaddr_ptr,
-                    la->host_addr->ipaddr_ptr, (size_t)la->host_addr->ipaddr_len)) {
-                /* exact match */
-                return 1;
-            }
-        }
-    }
-    return 0;
-}
-
-static apr_status_t tls_core_free(void *data)
-{
-    server_rec *base_server = (server_rec *)data;
-    tls_conf_server_t *sc = tls_conf_server_get(base_server);
-
-    if (sc && sc->global && sc->global->rustls_hello_config) {
-        rustls_server_config_free(sc->global->rustls_hello_config);
-        sc->global->rustls_hello_config = NULL;
-    }
-    tls_cache_free(base_server);
-    return APR_SUCCESS;
-}
-
-static apr_status_t load_certified_keys(
-    apr_array_header_t *keys, server_rec *s,
-    apr_array_header_t *cert_specs,
-    tls_cert_reg_t *cert_reg)
-{
-    apr_status_t rv = APR_SUCCESS;
-    const rustls_certified_key *ckey;
-    tls_cert_spec_t *spec;
-    int i;
-
-    if (cert_specs && cert_specs->nelts > 0) {
-        for (i = 0; i < cert_specs->nelts; ++i) {
-            spec = APR_ARRAY_IDX(cert_specs, i, tls_cert_spec_t*);
-            rv = tls_cert_reg_get_certified_key(cert_reg, s, spec, &ckey);
-            if (APR_SUCCESS != rv) {
-                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10318)
-                     "Failed to load certificate %d[cert=%s(%d), key=%s(%d)] for %s",
-                     i, spec->cert_file, (int)(spec->cert_pem? strlen(spec->cert_pem) : 0),
-                     spec->pkey_file, (int)(spec->pkey_pem? strlen(spec->pkey_pem) : 0),
-                     s->server_hostname);
-                goto cleanup;
-            }
-            assert(ckey);
-            APR_ARRAY_PUSH(keys, const rustls_certified_key*) = ckey;
-        }
-    }
-cleanup:
-    return rv;
-}
-
-static apr_status_t use_local_key(
-    conn_rec *c, const char *cert_pem, const char *pkey_pem)
-{
-    tls_conf_conn_t *cc = tls_conf_conn_get(c);
-    const rustls_certified_key *ckey = NULL;
-    tls_cert_spec_t spec;
-    apr_status_t rv = APR_SUCCESS;
-
-    memset(&spec, 0, sizeof(spec));
-    spec.cert_pem = cert_pem;
-    spec.pkey_pem = pkey_pem;
-    rv = tls_cert_load_cert_key(c->pool, &spec, NULL, &ckey);
-    if (APR_SUCCESS != rv) goto cleanup;
-
-    cc->local_keys = apr_array_make(c->pool, 2, sizeof(const rustls_certified_key*));
-    APR_ARRAY_PUSH(cc->local_keys, const rustls_certified_key*) = ckey;
-    ckey = NULL;
-
-cleanup:
-    if (ckey != NULL) rustls_certified_key_free(ckey);
-    return rv;
-}
-
-static void add_file_specs(
-    apr_array_header_t *certificates,
-    apr_pool_t *p,
-    apr_array_header_t *cert_files,
-    apr_array_header_t *key_files)
-{
-    tls_cert_spec_t *spec;
-    int i;
-
-    for (i = 0; i < cert_files->nelts; ++i) {
-        spec = apr_pcalloc(p, sizeof(*spec));
-        spec->cert_file = APR_ARRAY_IDX(cert_files, i, const char*);
-        spec->pkey_file = (i < key_files->nelts)? APR_ARRAY_IDX(key_files, i, const char*) : NULL;
-        *(const tls_cert_spec_t**)apr_array_push(certificates) = spec;
-    }
-}
-
-static apr_status_t calc_ciphers(
-    apr_pool_t *pool,
-    server_rec *s,
-    tls_conf_global_t *gc,
-    const char *proxy,
-    apr_array_header_t *pref_ciphers,
-    apr_array_header_t *supp_ciphers,
-    const apr_array_header_t **pciphers)
-{
-    apr_array_header_t *ordered_ciphers;
-    const apr_array_header_t *ciphers;
-    apr_array_header_t *unsupported = NULL;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    apr_status_t rv = APR_SUCCESS;
-    apr_uint16_t id;
-    int i;
-
-
-    /* remove all suppressed ciphers from the ones supported by rustls */
-    ciphers = tls_util_array_uint16_remove(pool, gc->proto->supported_cipher_ids, supp_ciphers);
-    ordered_ciphers = NULL;
-    /* if preferred ciphers are actually still present in allowed_ciphers, put
-     * them into `ciphers` in this order */
-    for (i = 0; i < pref_ciphers->nelts; ++i) {
-        id = APR_ARRAY_IDX(pref_ciphers, i, apr_uint16_t);
-        ap_log_error(APLOG_MARK, APLOG_TRACE4, rv, s,
-                     "checking preferred cipher %s: %d",
-                     s->server_hostname, id);
-        if (tls_util_array_uint16_contains(ciphers, id)) {
-            ap_log_error(APLOG_MARK, APLOG_TRACE4, rv, s,
-                         "checking preferred cipher %s: %d is known",
-                         s->server_hostname, id);
-            if (ordered_ciphers == NULL) {
-                ordered_ciphers = apr_array_make(pool, ciphers->nelts, sizeof(apr_uint16_t));
-            }
-            APR_ARRAY_PUSH(ordered_ciphers, apr_uint16_t) = id;
-        }
-        else if (!tls_proto_is_cipher_supported(gc->proto, id)) {
-            ap_log_error(APLOG_MARK, APLOG_TRACE4, rv, s,
-                         "checking preferred cipher %s: %d is unsupported",
-                         s->server_hostname, id);
-            if (!unsupported) unsupported = apr_array_make(pool, 5, sizeof(apr_uint16_t));
-            APR_ARRAY_PUSH(unsupported, apr_uint16_t) = id;
-        }
-    }
-    /* if we found ciphers with preference among allowed_ciphers,
-     * append all other allowed ciphers. */
-    if (ordered_ciphers) {
-        for (i = 0; i < ciphers->nelts; ++i) {
-            id = APR_ARRAY_IDX(ciphers, i, apr_uint16_t);
-            if (!tls_util_array_uint16_contains(ordered_ciphers, id)) {
-                APR_ARRAY_PUSH(ordered_ciphers, apr_uint16_t) = id;
-            }
-        }
-        ciphers = ordered_ciphers;
-    }
-
-    if (ciphers == gc->proto->supported_cipher_ids) {
-        ciphers = NULL;
-    }
-
-    if (unsupported && unsupported->nelts) {
-        ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(10319)
-                     "Server '%s' has TLS%sCiphersPrefer configured that are not "
-                     "supported by rustls. These will not have an effect: %s",
-                     s->server_hostname, proxy,
-                     tls_proto_get_cipher_names(gc->proto, unsupported, pool));
-    }
-
-    if (RUSTLS_RESULT_OK != rr) {
-        const char *err_descr;
-        rv = tls_util_rustls_error(pool, rr, &err_descr);
-        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10320)
-                     "Failed to configure ciphers %s: [%d] %s",
-                     s->server_hostname, (int)rr, err_descr);
-    }
-    *pciphers = (APR_SUCCESS == rv)? ciphers : NULL;
-    return rv;
-}
-
-static apr_status_t get_server_ciphersuites(
-    const apr_array_header_t **pciphersuites,
-    apr_pool_t *pool, tls_conf_server_t *sc)
-{
-    const apr_array_header_t *ciphers, *suites = NULL;
-    apr_status_t rv = APR_SUCCESS;
-
-    rv = calc_ciphers(pool, sc->server, sc->global,
-        "", sc->tls_pref_ciphers, sc->tls_supp_ciphers,
-        &ciphers);
-    if (APR_SUCCESS != rv) goto cleanup;
-
-    if (ciphers) {
-        suites = tls_proto_get_rustls_suites(
-            sc->global->proto, ciphers, pool);
-        if (APLOGtrace2(sc->server)) {
-            tls_proto_conf_t *conf = sc->global->proto;
-            ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, sc->server,
-                         "tls ciphers configured[%s]: %s",
-                         sc->server->server_hostname,
-                         tls_proto_get_cipher_names(conf, ciphers, pool));
-        }
-    }
-
-cleanup:
-    *pciphersuites = (APR_SUCCESS == rv)? suites : NULL;
-    return rv;
-}
-
-static apr_array_header_t *complete_cert_specs(
-    apr_pool_t *p, tls_conf_server_t *sc)
-{
-    apr_array_header_t *cert_adds, *key_adds, *specs;
-
-    /* Take the configured certificate specifications and ask
-     * around for other modules to add specifications to this server.
-     * This is the way mod_md provides certificates.
-     *
-     * If the server then still has no cert specifications, ask
-     * around for `fallback` certificates which are commonly self-signed,
-     * temporary ones which let the server startup in order to
-     * obtain the `real` certificates from sources like ACME.
-     * Servers will fallbacks will answer all requests with 503.
-     */
-    specs = apr_array_copy(p, sc->cert_specs);
-    cert_adds = apr_array_make(p, 2, sizeof(const char*));
-    key_adds = apr_array_make(p, 2, sizeof(const char*));
-
-    ap_ssl_add_cert_files(sc->server, p, cert_adds, key_adds);
-    ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, sc->server,
-                 "init server: complete_cert_specs added %d certs", cert_adds->nelts);
-    add_file_specs(specs, p, cert_adds, key_adds);
-
-    if (apr_is_empty_array(specs)) {
-        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, sc->server,
-                     "init server: no certs configured, looking for fallback");
-        ap_ssl_add_fallback_cert_files(sc->server, p, cert_adds, key_adds);
-        if (cert_adds->nelts > 0) {
-            add_file_specs(specs, p, cert_adds, key_adds);
-            sc->service_unavailable = 1;
-            ap_log_error(APLOG_MARK, APLOG_INFO, 0, sc->server, APLOGNO(10321)
-                         "Init: %s will respond with '503 Service Unavailable' for now. There "
-                         "are no SSL certificates configured and no other module contributed any.",
-                         sc->server->server_hostname);
-        }
-        else if (!sc->base_server) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, sc->server, APLOGNO(10322)
-                         "Init: %s has no certificates configured. Use 'TLSCertificate' to "
-                         "configure a certificate and key file.",
-                         sc->server->server_hostname);
-        }
-    }
-    return specs;
-}
-
-static const rustls_certified_key *select_certified_key(
-    void* userdata, const rustls_client_hello *hello)
-{
-    conn_rec *c = userdata;
-    tls_conf_conn_t *cc;
-    tls_conf_server_t *sc;
-    apr_array_header_t *keys;
-    const rustls_certified_key *clone;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    apr_status_t rv;
-
-    ap_assert(c);
-    cc = tls_conf_conn_get(c);
-    ap_assert(cc);
-    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, "client hello select certified key");
-    if (!cc || !cc->server) goto cleanup;
-    sc = tls_conf_server_get(cc->server);
-    if (!sc) goto cleanup;
-
-    cc->key = NULL;
-    cc->key_cloned = 0;
-    if (cc->local_keys && cc->local_keys->nelts > 0) {
-        keys = cc->local_keys;
-    }
-    else {
-        keys = sc->certified_keys;
-    }
-    if (!keys || keys->nelts <= 0) goto cleanup;
-
-    rr = rustls_client_hello_select_certified_key(hello,
-        (const rustls_certified_key**)keys->elts, (size_t)keys->nelts, &cc->key);
-    if (RUSTLS_RESULT_OK != rr) goto cleanup;
-
-    if (APR_SUCCESS == tls_ocsp_update_key(c, cc->key, &clone)) {
-        /* got OCSP response data for it, meaning the key was cloned and we need to remember */
-        cc->key_cloned = 1;
-        cc->key = clone;
-    }
-    if (APLOGctrace2(c)) {
-        const char *key_id = tls_cert_reg_get_id(sc->global->cert_reg, cc->key);
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, APLOGNO(10323)
-                      "client hello selected key: %s", key_id? key_id : "unknown");
-    }
-    return cc->key;
-
-cleanup:
-    if (RUSTLS_RESULT_OK != rr) {
-        const char *err_descr;
-        rv = tls_util_rustls_error(c->pool, rr, &err_descr);
-        ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(10324)
-                      "Failed to select certified key: [%d] %s", (int)rr, err_descr);
-    }
-    return NULL;
-}
-
-static apr_status_t server_conf_setup(
-    apr_pool_t *p, apr_pool_t *ptemp, tls_conf_server_t *sc, tls_conf_global_t *gc)
-{
-    apr_array_header_t *cert_specs;
-    apr_status_t rv = APR_SUCCESS;
-
-    /* TODO: most code has been stripped here with the changes in rustls-ffi v0.8.0
-     * and this means that any errors are only happening at connection setup, which
-     * is too late.
-     */
-    (void)p;
-    ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, sc->server,
-                 "init server: %s", sc->server->server_hostname);
-
-    if (sc->client_auth != TLS_CLIENT_AUTH_NONE && !sc->client_ca) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, sc->server, APLOGNO(10325)
-                     "TLSClientAuthentication is enabled for %s, but no client CA file is set. "
-                      "Use 'TLSClientCA <file>' to specify the trust anchors.",
-                     sc->server->server_hostname);
-        rv = APR_EINVAL; goto cleanup;
-    }
-
-    cert_specs = complete_cert_specs(ptemp, sc);
-    sc->certified_keys = apr_array_make(p, 3, sizeof(rustls_certified_key *));
-    rv = load_certified_keys(sc->certified_keys, sc->server, cert_specs, gc->cert_reg);
-    if (APR_SUCCESS != rv) goto cleanup;
-
-    rv = get_server_ciphersuites(&sc->ciphersuites, p, sc);
-    if (APR_SUCCESS != rv) goto cleanup;
-
-    ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, sc->server,
-                 "init server: %s with %d certificates loaded",
-                 sc->server->server_hostname, sc->certified_keys->nelts);
-cleanup:
-    return rv;
-}
-
-static apr_status_t get_proxy_ciphers(const apr_array_header_t **pciphersuites,
-    apr_pool_t *pool, tls_conf_proxy_t *pc)
-{
-    const apr_array_header_t *ciphers, *suites = NULL;
-    apr_status_t rv = APR_SUCCESS;
-
-    rv = calc_ciphers(pool, pc->defined_in, pc->global,
-        "", pc->proxy_pref_ciphers, pc->proxy_supp_ciphers, &ciphers);
-    if (APR_SUCCESS != rv) goto cleanup;
-
-    if (ciphers) {
-        suites = tls_proto_get_rustls_suites(pc->global->proto, ciphers, pool);
-        /* this changed the default rustls ciphers, configure it. */
-        if (APLOGtrace2(pc->defined_in)) {
-            tls_proto_conf_t *conf = pc->global->proto;
-            ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, pc->defined_in,
-                         "tls proxy ciphers configured[%s]: %s",
-                         pc->defined_in->server_hostname,
-                         tls_proto_get_cipher_names(conf, ciphers, pool));
-        }
-    }
-
-cleanup:
-    *pciphersuites = (APR_SUCCESS == rv)? suites : NULL;
-    return rv;
-}
-
-static apr_status_t proxy_conf_setup(
-    apr_pool_t *p, apr_pool_t *ptemp, tls_conf_proxy_t *pc, tls_conf_global_t *gc)
-{
-    apr_status_t rv = APR_SUCCESS;
-
-    (void)p; (void)ptemp;
-    ap_assert(pc->defined_in);
-    pc->global = gc;
-
-    if (pc->proxy_ca && strcasecmp(pc->proxy_ca, "default")) {
-        ap_log_error(APLOG_MARK, APLOG_TRACE2, rv, pc->defined_in,
-                     "proxy: will use roots in %s from %s",
-                     pc->defined_in->server_hostname, pc->proxy_ca);
-    }
-    else {
-        ap_log_error(APLOG_MARK, APLOG_WARNING, rv, pc->defined_in,
-                     "proxy: there is no TLSProxyCA configured in %s which means "
-                     "the certificates of remote servers contacted from here will not be trusted.",
-                     pc->defined_in->server_hostname);
-    }
-
-    if (pc->proxy_protocol_min > 0) {
-        apr_array_header_t *tls_versions;
-
-        ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, pc->defined_in,
-                     "init server: set proxy protocol min version %04x", pc->proxy_protocol_min);
-        tls_versions = tls_proto_create_versions_plus(
-            gc->proto, (apr_uint16_t)pc->proxy_protocol_min, ptemp);
-        if (tls_versions->nelts > 0) {
-            if (pc->proxy_protocol_min != APR_ARRAY_IDX(tls_versions, 0, apr_uint16_t)) {
-                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, pc->defined_in, APLOGNO(10326)
-                             "Init: the minimum proxy protocol version configured for %s (%04x) "
-                             "is not supported and version %04x was selected instead.",
-                             pc->defined_in->server_hostname, pc->proxy_protocol_min,
-                             APR_ARRAY_IDX(tls_versions, 0, apr_uint16_t));
-            }
-        }
-        else {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, pc->defined_in, APLOGNO(10327)
-                         "Unable to configure the proxy protocol version for %s: "
-                          "neither the configured minimum version (%04x), nor any higher one is "
-                         "available.", pc->defined_in->server_hostname, pc->proxy_protocol_min);
-            rv = APR_ENOTIMPL; goto cleanup;
-        }
-    }
-
-#if TLS_MACHINE_CERTS
-    rv = load_certified_keys(pc->machine_certified_keys, pc->defined_in,
-                             pc->machine_cert_specs, gc->cert_reg);
-    if (APR_SUCCESS != rv) goto cleanup;
-#endif
-
-cleanup:
-    return rv;
-}
-
-static const rustls_certified_key *extract_client_hello_values(
-    void* userdata, const rustls_client_hello *hello)
-{
-    conn_rec *c = userdata;
-    tls_conf_conn_t *cc = tls_conf_conn_get(c);
-    size_t i, len;
-    unsigned short n;
-
-    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, "extract client hello values");
-    if (!cc) goto cleanup;
-    cc->client_hello_seen = 1;
-    if (hello->server_name.len > 0) {
-        cc->sni_hostname = apr_pstrndup(c->pool, hello->server_name.data, hello->server_name.len);
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "sni detected: %s", cc->sni_hostname);
-    }
-    else {
-        cc->sni_hostname = NULL;
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "no sni from client");
-    }
-    if (APLOGctrace4(c) && hello->signature_schemes.len > 0) {
-        for (i = 0; i < hello->signature_schemes.len; ++i) {
-            n = hello->signature_schemes.data[i];
-            ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, c,
-                "client supports signature scheme: %x", (int)n);
-        }
-    }
-    if ((len = rustls_slice_slice_bytes_len(hello->alpn)) > 0) {
-        apr_array_header_t *alpn = apr_array_make(c->pool, 5, sizeof(const char*));
-        const char *protocol;
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "ALPN: client proposes %d protocols", (int)len);
-        for (i = 0; i < len; ++i) {
-            rustls_slice_bytes rs = rustls_slice_slice_bytes_get(hello->alpn, i);
-            protocol = apr_pstrndup(c->pool, (const char*)rs.data, rs.len);
-            APR_ARRAY_PUSH(alpn, const char*) = protocol;
-            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
-                "ALPN: client proposes %d: `%s`", (int)i, protocol);
-        }
-        cc->alpn = alpn;
-    }
-    else {
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, "ALPN: no alpn proposed by client");
-    }
-cleanup:
-    return NULL;
-}
-
-static apr_status_t setup_hello_config(apr_pool_t *p, server_rec *base_server, tls_conf_global_t *gc)
-{
-    rustls_server_config_builder *builder;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    apr_status_t rv = APR_SUCCESS;
-
-    builder = rustls_server_config_builder_new();
-    if (!builder) {
-        rr = RUSTLS_RESULT_PANIC; goto cleanup;
-    }
-    rustls_server_config_builder_set_hello_callback(builder, extract_client_hello_values);
-    gc->rustls_hello_config = rustls_server_config_builder_build(builder);
-    if (!gc->rustls_hello_config) {
-        rr = RUSTLS_RESULT_PANIC; goto cleanup;
-    }
-
-cleanup:
-    if (RUSTLS_RESULT_OK != rr) {
-        const char *err_descr = NULL;
-        rv = tls_util_rustls_error(p, rr, &err_descr);
-        ap_log_error(APLOG_MARK, APLOG_ERR, rv, base_server, APLOGNO(10328)
-                     "Failed to init generic hello config: [%d] %s", (int)rr, err_descr);
-        goto cleanup;
-    }
-    return rv;
-}
-
-static apr_status_t init_incoming(apr_pool_t *p, apr_pool_t *ptemp, server_rec *base_server)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(base_server);
-    tls_conf_global_t *gc = sc->global;
-    server_rec *s;
-    apr_status_t rv = APR_ENOMEM;
-
-    ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, base_server, "tls_core_init incoming");
-    apr_pool_cleanup_register(p, base_server, tls_core_free,
-                              apr_pool_cleanup_null);
-
-    rv = tls_proto_post_config(p, ptemp, base_server);
-    if (APR_SUCCESS != rv) goto cleanup;
-
-    for (s = base_server; s; s = s->next) {
-        sc = tls_conf_server_get(s);
-        assert(sc);
-        ap_assert(sc->global == gc);
-
-        /* If 'TLSEngine' has been configured, use those addresses to
-         * decide if we are enabled on this server. */
-        sc->base_server = (s == base_server);
-        sc->enabled = we_listen_on(gc, s, sc)? TLS_FLAG_TRUE : TLS_FLAG_FALSE;
-    }
-
-    rv = tls_cache_post_config(p, ptemp, base_server);
-    if (APR_SUCCESS != rv) goto cleanup;
-
-    rv = setup_hello_config(p, base_server, gc);
-    if (APR_SUCCESS != rv) goto cleanup;
-
-    /* Setup server configs and collect all certificates we use. */
-    gc->cert_reg = tls_cert_reg_make(p);
-    gc->stores = tls_cert_root_stores_make(p);
-    gc->verifiers = tls_cert_verifiers_make(p, gc->stores);
-    for (s = base_server; s; s = s->next) {
-        sc = tls_conf_server_get(s);
-        rv = tls_conf_server_apply_defaults(sc, p);
-        if (APR_SUCCESS != rv) goto cleanup;
-        if (sc->enabled != TLS_FLAG_TRUE) continue;
-        rv = server_conf_setup(p, ptemp, sc, gc);
-        if (APR_SUCCESS != rv) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "server setup failed: %s",
-                s->server_hostname);
-            goto cleanup;
-        }
-    }
-
-cleanup:
-    if (APR_SUCCESS != rv) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, rv, base_server, "error during post_config");
-    }
-    return rv;
-}
-
-static apr_status_t init_outgoing(apr_pool_t *p, apr_pool_t *ptemp, server_rec *base_server)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(base_server);
-    tls_conf_global_t *gc = sc->global;
-    tls_conf_dir_t *dc;
-    tls_conf_proxy_t *pc;
-    server_rec *s;
-    apr_status_t rv = APR_SUCCESS;
-    int i;
-
-    (void)p; (void)ptemp;
-    (void)gc;
-    ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, base_server, "tls_core_init outgoing");
-    ap_assert(gc->mod_proxy_post_config_done);
-    /* Collect all proxy'ing default server dir configs.
-     * All <Proxy> section dir_configs should already be there - if there were any. */
-    for (s = base_server; s; s = s->next) {
-        dc = tls_conf_dir_server_get(s);
-        rv = tls_conf_dir_apply_defaults(dc, p);
-        if (APR_SUCCESS != rv) goto cleanup;
-        if (dc->proxy_enabled != TLS_FLAG_TRUE) continue;
-        dc->proxy_config = tls_conf_proxy_make(p, dc, gc, s);
-        ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s, "%s: adding proxy_conf to globals",
-            s->server_hostname);
-        APR_ARRAY_PUSH(gc->proxy_configs, tls_conf_proxy_t*) = dc->proxy_config;
-    }
-    /* Now gc->proxy_configs contains all configurations we need to possibly
-     * act on for outgoing connections. */
-    for (i = 0; i < gc->proxy_configs->nelts; ++i) {
-        pc = APR_ARRAY_IDX(gc->proxy_configs, i, tls_conf_proxy_t*);
-        rv = proxy_conf_setup(p, ptemp, pc, gc);
-        if (APR_SUCCESS != rv) goto cleanup;
-    }
-
-cleanup:
-    return rv;
-}
-
-apr_status_t tls_core_init(apr_pool_t *p, apr_pool_t *ptemp, server_rec *base_server)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(base_server);
-    tls_conf_global_t *gc = sc->global;
-    apr_status_t rv = APR_SUCCESS;
-
-    ap_assert(gc);
-    if (TLS_CONF_ST_INIT == gc->status) {
-        rv = init_incoming(p, ptemp, base_server);
-        if (APR_SUCCESS != rv) goto cleanup;
-        gc->status = TLS_CONF_ST_INCOMING_DONE;
-    }
-    if (TLS_CONF_ST_INCOMING_DONE == gc->status) {
-        if (!gc->mod_proxy_post_config_done) goto cleanup;
-
-        rv = init_outgoing(p, ptemp, base_server);
-        if (APR_SUCCESS != rv) goto cleanup;
-        gc->status = TLS_CONF_ST_OUTGOING_DONE;
-    }
-    if (TLS_CONF_ST_OUTGOING_DONE == gc->status) {
-        /* register all loaded certificates for OCSP stapling */
-        rv = tls_ocsp_prime_certs(gc, p, base_server);
-        if (APR_SUCCESS != rv) goto cleanup;
-
-        if (gc->verifiers) tls_cert_verifiers_clear(gc->verifiers);
-        if (gc->stores) tls_cert_root_stores_clear(gc->stores);
-        gc->status = TLS_CONF_ST_DONE;
-    }
-cleanup:
-    return rv;
-}
-
-static apr_status_t tls_core_conn_free(void *data)
-{
-    tls_conf_conn_t *cc = data;
-
-    /* free all rustls things we are owning. */
-    if (cc->rustls_connection) {
-        rustls_connection_free(cc->rustls_connection);
-        cc->rustls_connection = NULL;
-    }
-    if (cc->rustls_server_config) {
-        rustls_server_config_free(cc->rustls_server_config);
-        cc->rustls_server_config = NULL;
-    }
-    if (cc->rustls_client_config) {
-        rustls_client_config_free(cc->rustls_client_config);
-        cc->rustls_client_config = NULL;
-    }
-    if (cc->key_cloned && cc->key) {
-        rustls_certified_key_free(cc->key);
-        cc->key = NULL;
-    }
-    if (cc->local_keys) {
-        const rustls_certified_key *key;
-        int i;
-
-        for (i = 0; i < cc->local_keys->nelts; ++i) {
-            key = APR_ARRAY_IDX(cc->local_keys, i, const rustls_certified_key*);
-            rustls_certified_key_free(key);
-        }
-        apr_array_clear(cc->local_keys);
-    }
-    return APR_SUCCESS;
-}
-
-static tls_conf_conn_t *cc_get_or_make(conn_rec *c)
-{
-    tls_conf_conn_t *cc = tls_conf_conn_get(c);
-    if (!cc) {
-        cc = apr_pcalloc(c->pool, sizeof(*cc));
-        cc->server = c->base_server;
-        cc->state = TLS_CONN_ST_INIT;
-        tls_conf_conn_set(c, cc);
-        apr_pool_cleanup_register(c->pool, cc, tls_core_conn_free,
-                                  apr_pool_cleanup_null);
-    }
-    return cc;
-}
-
-void tls_core_conn_disable(conn_rec *c)
-{
-    tls_conf_conn_t *cc;
-    cc = cc_get_or_make(c);
-    if (cc->state == TLS_CONN_ST_INIT) {
-        cc->state = TLS_CONN_ST_DISABLED;
-    }
-}
-
-void tls_core_conn_bind(conn_rec *c, ap_conf_vector_t *dir_conf)
-{
-    tls_conf_conn_t *cc = cc_get_or_make(c);
-    cc->dc = dir_conf? ap_get_module_config(dir_conf, &tls_module) : NULL;
-}
-
-
-static apr_status_t init_outgoing_connection(conn_rec *c)
-{
-    tls_conf_conn_t *cc = tls_conf_conn_get(c);
-    tls_conf_proxy_t *pc;
-    const apr_array_header_t *ciphersuites = NULL;
-    apr_array_header_t *tls_versions = NULL;
-    rustls_web_pki_server_cert_verifier_builder *verifier_builder = NULL;
-    struct rustls_server_cert_verifier *verifier = NULL;
-    rustls_client_config_builder *builder = NULL;
-    const rustls_root_cert_store *ca_store = NULL;
-    const char *hostname = NULL, *alpn_note = NULL;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    apr_status_t rv = APR_SUCCESS;
-
-    ap_assert(cc->outgoing);
-    ap_assert(cc->dc);
-    pc = cc->dc->proxy_config;
-    ap_assert(pc);
-
-    hostname = apr_table_get(c->notes, "proxy-request-hostname");
-    alpn_note = apr_table_get(c->notes, "proxy-request-alpn-protos");
-    ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, c->base_server,
-        "setup_outgoing: to %s [ALPN: %s] from configuration in %s"
-        " using CA %s", hostname, alpn_note, pc->defined_in->server_hostname, pc->proxy_ca);
-
-    rv = get_proxy_ciphers(&ciphersuites, c->pool, pc);
-    if (APR_SUCCESS != rv) goto cleanup;
-
-    if (pc->proxy_protocol_min > 0) {
-        tls_versions = tls_proto_create_versions_plus(
-            pc->global->proto, (apr_uint16_t)pc->proxy_protocol_min, c->pool);
-    }
-
-    if (ciphersuites && ciphersuites->nelts > 0
-        && tls_versions && tls_versions->nelts >= 0) {
-        rr = rustls_client_config_builder_new_custom(
-            (const struct rustls_supported_ciphersuite *const *)ciphersuites->elts,
-            (size_t)ciphersuites->nelts,
-            (const uint16_t *)tls_versions->elts, (size_t)tls_versions->nelts,
-            &builder);
-        if (RUSTLS_RESULT_OK != rr) goto cleanup;
-    }
-    else {
-        builder = rustls_client_config_builder_new();
-        if (NULL == builder) {
-            rv = APR_ENOMEM;
-            goto cleanup;
-        }
-    }
-
-    if (pc->proxy_ca && strcasecmp(pc->proxy_ca, "default")) {
-        rv = tls_cert_root_stores_get(pc->global->stores, pc->proxy_ca, &ca_store);
-        if (APR_SUCCESS != rv) goto cleanup;
-        verifier_builder = rustls_web_pki_server_cert_verifier_builder_new(ca_store);
-        rr = rustls_web_pki_server_cert_verifier_builder_build(verifier_builder, &verifier);
-        if (RUSTLS_RESULT_OK != rr) goto cleanup;
-        rustls_client_config_builder_set_server_verifier(builder, verifier);
-    }
-
-#if TLS_MACHINE_CERTS
-    if (pc->machine_certified_keys->nelts > 0) {
-        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, c->base_server,
-            "setup_outgoing: adding %d client certificate", (int)pc->machine_certified_keys->nelts);
-        rr = rustls_client_config_builder_set_certified_key(
-                builder, (const rustls_certified_key**)pc->machine_certified_keys->elts,
-                (size_t)pc->machine_certified_keys->nelts);
-        if (RUSTLS_RESULT_OK != rr) goto cleanup;
-    }
-#endif
-
-    if (hostname) {
-        rustls_client_config_builder_set_enable_sni(builder, true);
-    }
-    else {
-        hostname = "unknown.proxy.local";
-        rustls_client_config_builder_set_enable_sni(builder, false);
-    }
-
-    if (alpn_note) {
-        apr_array_header_t *alpn_proposed = NULL;
-        char *p, *last;
-        apr_size_t len;
-
-        alpn_proposed = apr_array_make(c->pool, 3, sizeof(const char*));
-        p = apr_pstrdup(c->pool, alpn_note);
-        while ((p = apr_strtok(p, ", ", &last))) {
-            len = (apr_size_t)(last - p - (*last? 1 : 0));
-            if (len > 255) {
-                ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(10329)
-                              "ALPN proxy protocol identifier too long: %s", p);
-                rv = APR_EGENERAL;
-                goto cleanup;
-            }
-            APR_ARRAY_PUSH(alpn_proposed, const char*) = apr_pstrndup(c->pool, p, len);
-            p = NULL;
-        }
-        if (alpn_proposed->nelts > 0) {
-            apr_array_header_t *rustls_protocols;
-            const char* proto;
-            rustls_slice_bytes bytes;
-            int i;
-
-            rustls_protocols = apr_array_make(c->pool, alpn_proposed->nelts, sizeof(rustls_slice_bytes));
-            for (i = 0; i < alpn_proposed->nelts; ++i) {
-                proto = APR_ARRAY_IDX(alpn_proposed, i, const char*);
-                bytes.data = (const unsigned char*)proto;
-                bytes.len = strlen(proto);
-                APR_ARRAY_PUSH(rustls_protocols, rustls_slice_bytes) = bytes;
-            }
-
-            rr = rustls_client_config_builder_set_alpn_protocols(builder,
-                (rustls_slice_bytes*)rustls_protocols->elts, (size_t)rustls_protocols->nelts);
-            if (RUSTLS_RESULT_OK != rr) goto cleanup;
-
-            ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, c->base_server,
-                "setup_outgoing: to %s, added %d ALPN protocols from %s",
-                hostname, rustls_protocols->nelts, alpn_note);
-        }
-    }
-
-    cc->rustls_client_config = rustls_client_config_builder_build(builder);
-    builder = NULL;
-
-    rr = rustls_client_connection_new(cc->rustls_client_config, hostname, &cc->rustls_connection);
-    if (RUSTLS_RESULT_OK != rr) goto cleanup;
-    rustls_connection_set_userdata(cc->rustls_connection, c);
-
-cleanup:
-    if (verifier_builder != NULL) rustls_web_pki_server_cert_verifier_builder_free(verifier_builder);
-    if (builder != NULL) rustls_client_config_builder_free(builder);
-    if (RUSTLS_RESULT_OK != rr) {
-        const char *err_descr = NULL;
-        rv = tls_util_rustls_error(c->pool, rr, &err_descr);
-        ap_log_error(APLOG_MARK, APLOG_ERR, rv, cc->server, APLOGNO(10330)
-                     "Failed to init pre_session for outgoing %s to %s: [%d] %s",
-                     cc->server->server_hostname, hostname, (int)rr, err_descr);
-        c->aborted = 1;
-        cc->state = TLS_CONN_ST_DISABLED;
-        goto cleanup;
-    }
-    return rv;
-}
-
-int tls_core_pre_conn_init(conn_rec *c)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(c->base_server);
-    tls_conf_conn_t *cc;
-
-    cc = cc_get_or_make(c);
-    if (cc->state == TLS_CONN_ST_INIT) {
-        /* Need to decide if we TLS this connection or not */
-        int enabled =
-#if AP_MODULE_MAGIC_AT_LEAST(20120211, 109)
-                !c->outgoing &&
-#endif
-                sc->enabled == TLS_FLAG_TRUE;
-        cc->state = enabled? TLS_CONN_ST_CLIENT_HELLO : TLS_CONN_ST_DISABLED;
-        cc->client_auth = sc->client_auth;
-        ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, c->base_server,
-            "tls_core_conn_init: %s for tls: %s",
-            enabled? "enabled" : "disabled", c->base_server->server_hostname);
-    }
-    else if (cc->state == TLS_CONN_ST_DISABLED) {
-        ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, c->base_server,
-            "tls_core_conn_init, not our connection: %s",
-            c->base_server->server_hostname);
-        goto cleanup;
-    }
-
-cleanup:
-    return TLS_CONN_ST_IS_ENABLED(cc)? OK : DECLINED;
-}
-
-apr_status_t tls_core_conn_init(conn_rec *c)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(c->base_server);
-    tls_conf_conn_t *cc;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    apr_status_t rv = APR_SUCCESS;
-
-    cc = tls_conf_conn_get(c);
-    if (cc && TLS_CONN_ST_IS_ENABLED(cc) && !cc->rustls_connection) {
-        if (cc->outgoing) {
-            rv = init_outgoing_connection(c);
-            if (APR_SUCCESS != rv) goto cleanup;
-        }
-        else {
-            /* Use a generic rustls_connection with its defaults, which we feed
-             * the first TLS bytes from the client. Its Hello message will trigger
-             * our callback where we can inspect the (possibly) supplied SNI and
-             * select another server.
-             */
-            rr = rustls_server_connection_new(sc->global->rustls_hello_config, &cc->rustls_connection);
-            if (RUSTLS_RESULT_OK != rr) goto cleanup;
-            /* we might refuse requests on this connection, e.g. ACME challenge */
-            cc->service_unavailable = sc->service_unavailable;
-        }
-        rustls_connection_set_userdata(cc->rustls_connection, c);
-    }
-
-cleanup:
-    if (RUSTLS_RESULT_OK != rr) {
-        const char *err_descr = NULL;
-        rv = tls_util_rustls_error(c->pool, rr, &err_descr);
-        ap_log_error(APLOG_MARK, APLOG_ERR, rv, sc->server, APLOGNO(10331)
-                     "Failed to init TLS connection for server %s: [%d] %s",
-                     sc->server->server_hostname, (int)rr, err_descr);
-        c->aborted = 1;
-        cc->state = TLS_CONN_ST_DISABLED;
-        goto cleanup;
-    }
-    return rv;
-}
-
-static int find_vhost(void *sni_hostname, conn_rec *c, server_rec *s)
-{
-    if (tls_util_name_matches_server(sni_hostname, s)) {
-        tls_conf_conn_t *cc = tls_conf_conn_get(c);
-        cc->server = s;
-        return 1;
-    }
-    return 0;
-}
-
-static apr_status_t select_application_protocol(
-    conn_rec *c, server_rec *s, rustls_server_config_builder *builder)
-{
-    tls_conf_conn_t *cc = tls_conf_conn_get(c);
-    const char *proposed;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    apr_status_t rv = APR_SUCCESS;
-
-    /* The server always has a protocol it uses, normally "http/1.1".
-     * if the client, via ALPN, proposes protocols, they are in
-     * order of preference.
-     * We propose those to modules registered in the server and
-     * get the protocol back that someone is willing to run on this
-     * connection.
-     * If this is different from what the connection already does,
-     * we tell the server (and all protocol modules) to switch.
-     * If successful, we announce that protocol back to the client as
-     * our only ALPN protocol and then do the 'real' handshake.
-     */
-    cc->application_protocol = ap_get_protocol(c);
-    if (cc->alpn && cc->alpn->nelts > 0) {
-        rustls_slice_bytes rsb;
-
-        proposed = ap_select_protocol(c, NULL, s, cc->alpn);
-        if (!proposed) {
-            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, c,
-                "ALPN: no protocol selected in server");
-            goto cleanup;
-        }
-
-        if (strcmp(proposed, cc->application_protocol)) {
-            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, c,
-                "ALPN: switching protocol from `%s` to `%s`", cc->application_protocol, proposed);
-            rv = ap_switch_protocol(c, NULL, cc->server, proposed);
-            if (APR_SUCCESS != rv) goto cleanup;
-        }
-
-        rsb.data = (const unsigned char*)proposed;
-        rsb.len = strlen(proposed);
-        rr = rustls_server_config_builder_set_alpn_protocols(builder, &rsb, 1);
-        if (RUSTLS_RESULT_OK != rr) goto cleanup;
-
-        cc->application_protocol = proposed;
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, c,
-            "ALPN: using connection protocol `%s`", cc->application_protocol);
-
-        /* protocol was switched, this could be a challenge protocol
-         * such as "acme-tls/1". Give handlers the opportunity to
-         * override the certificate for this connection. */
-        if (strcmp("h2", proposed) && strcmp("http/1.1", proposed)) {
-            const char *cert_pem = NULL, *key_pem = NULL;
-            if (ap_ssl_answer_challenge(c, cc->sni_hostname, &cert_pem, &key_pem)) {
-                /* With ACME we can have challenge connections to a unknown domains
-                 * that need to be answered with a special certificate and will
-                 * otherwise not answer any requests. See RFC 8555 */
-                rv = use_local_key(c, cert_pem, key_pem);
-                if (APR_SUCCESS != rv) goto cleanup;
-
-                cc->service_unavailable = 1;
-                cc->client_auth = TLS_CLIENT_AUTH_NONE;
-            }
-        }
-    }
-
-cleanup:
-    if (rr != RUSTLS_RESULT_OK) {
-        const char *err_descr = NULL;
-        rv = tls_util_rustls_error(c->pool, rr, &err_descr);
-        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(10332)
-                     "Failed to init session for server %s: [%d] %s",
-                     s->server_hostname, (int)rr, err_descr);
-        c->aborted = 1;
-        goto cleanup;
-    }
-    return rv;
-}
-
-static apr_status_t build_server_connection(rustls_connection **pconnection,
-                                            const rustls_server_config **pconfig,
-                                            conn_rec *c)
-{
-    tls_conf_conn_t *cc = tls_conf_conn_get(c);
-    tls_conf_server_t *sc;
-    const apr_array_header_t *tls_versions = NULL;
-    rustls_server_config_builder *builder = NULL;
-    const rustls_server_config *config = NULL;
-    rustls_connection *rconnection = NULL;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    apr_status_t rv = APR_SUCCESS;
-
-    sc = tls_conf_server_get(cc->server);
-
-    if (sc->tls_protocol_min > 0) {
-        ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, sc->server,
-                     "init server: set protocol min version %04x", sc->tls_protocol_min);
-        tls_versions = tls_proto_create_versions_plus(
-            sc->global->proto, (apr_uint16_t)sc->tls_protocol_min, c->pool);
-        if (tls_versions->nelts > 0) {
-            if (sc->tls_protocol_min != APR_ARRAY_IDX(tls_versions, 0, apr_uint16_t)) {
-                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, sc->server, APLOGNO(10333)
-                             "Init: the minimum protocol version configured for %s (%04x) "
-                             "is not supported and version %04x was selected instead.",
-                             sc->server->server_hostname, sc->tls_protocol_min,
-                             APR_ARRAY_IDX(tls_versions, 0, apr_uint16_t));
-            }
-        }
-        else {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, sc->server, APLOGNO(10334)
-                         "Unable to configure the protocol version for %s: "
-                          "neither the configured minimum version (%04x), nor any higher one is "
-                         "available.", sc->server->server_hostname, sc->tls_protocol_min);
-            rv = APR_ENOTIMPL; goto cleanup;
-        }
-    }
-    else if (sc->ciphersuites && sc->ciphersuites->nelts > 0) {
-        /* FIXME: rustls-ffi current has not way to make a builder with ALL_PROTOCOL_VERSIONS */
-        tls_versions = tls_proto_create_versions_plus(sc->global->proto, 0, c->pool);
-    }
-
-    if (sc->ciphersuites && sc->ciphersuites->nelts > 0
-        && tls_versions && tls_versions->nelts >= 0) {
-        rr = rustls_server_config_builder_new_custom(
-            (const struct rustls_supported_ciphersuite *const *)sc->ciphersuites->elts,
-            (size_t)sc->ciphersuites->nelts,
-            (const uint16_t *)tls_versions->elts, (size_t)tls_versions->nelts,
-            &builder);
-        if (RUSTLS_RESULT_OK != rr) goto cleanup;
-    }
-    else {
-        builder = rustls_server_config_builder_new();
-        if (NULL == builder) {
-            rv = APR_ENOMEM;
-            goto cleanup;
-        }
-    }
-
-    /* decide on the application protocol, this may change other
-     * settings like client_auth. */
-    rv = select_application_protocol(c, cc->server, builder);
-
-    if (cc->client_auth != TLS_CLIENT_AUTH_NONE) {
-        ap_assert(sc->client_ca);  /* checked in server_setup */
-        if (cc->client_auth == TLS_CLIENT_AUTH_REQUIRED) {
-            const rustls_client_cert_verifier *verifier;
-            rv = tls_cert_client_verifiers_get(sc->global->verifiers, sc->client_ca, &verifier);
-            if (APR_SUCCESS != rv) goto cleanup;
-            rustls_server_config_builder_set_client_verifier(builder, verifier);
-        }
-        else {
-            const rustls_client_cert_verifier *verifier;
-            rv = tls_cert_client_verifiers_get_optional(sc->global->verifiers, sc->client_ca, &verifier);
-            if (APR_SUCCESS != rv) goto cleanup;
-            rustls_server_config_builder_set_client_verifier(builder, verifier);
-        }
-    }
-
-    rustls_server_config_builder_set_hello_callback(builder, select_certified_key);
-
-    rr = rustls_server_config_builder_set_ignore_client_order(
-        builder, sc->honor_client_order == TLS_FLAG_FALSE);
-    if (RUSTLS_RESULT_OK != rr) goto cleanup;
-
-    rv = tls_cache_init_server(builder, sc->server);
-    if (APR_SUCCESS != rv) goto cleanup;
-
-    config = rustls_server_config_builder_build(builder);
-    builder = NULL;
-    if (!config) {
-        rv = APR_ENOMEM; goto cleanup;
-    }
-
-    rr = rustls_server_connection_new(config, &rconnection);
-    if (RUSTLS_RESULT_OK != rr) goto cleanup;
-    rustls_connection_set_userdata(rconnection, c);
-
-cleanup:
-    if (rr != RUSTLS_RESULT_OK) {
-        const char *err_descr = NULL;
-        rv = tls_util_rustls_error(c->pool, rr, &err_descr);
-        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, sc->server, APLOGNO(10335)
-                     "Failed to init session for server %s: [%d] %s",
-                     sc->server->server_hostname, (int)rr, err_descr);
-    }
-    if (APR_SUCCESS == rv) {
-        *pconfig = config;
-        *pconnection = rconnection;
-        ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, sc->server,
-                     "tls_core_conn_server_init done: %s",
-                     sc->server->server_hostname);
-    }
-    else {
-        ap_log_error(APLOG_MARK, APLOG_ERR, rv, sc->server, APLOGNO(10336)
-                     "Failed to init session for server %s",
-                     sc->server->server_hostname);
-        c->aborted = 1;
-        if (config) rustls_server_config_free(config);
-        if (builder) rustls_server_config_builder_free(builder);
-    }
-    return rv;
-}
-
-apr_status_t tls_core_conn_seen_client_hello(conn_rec *c)
-{
-    tls_conf_conn_t *cc = tls_conf_conn_get(c);
-    tls_conf_server_t *sc;
-    apr_status_t rv = APR_SUCCESS;
-    int sni_match = 0;
-
-    /* The initial rustls generic session has been fed the client hello and
-     * we have extracted SNI and ALPN values (so present).
-     * Time to select the actual server_rec and application protocol that
-     * will be used on this connection. */
-    ap_assert(cc);
-    sc = tls_conf_server_get(cc->server);
-    if (!cc->client_hello_seen) goto cleanup;
-
-    if (cc->sni_hostname) {
-        if (ap_vhost_iterate_given_conn(c, find_vhost, (void*)cc->sni_hostname)) {
-            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(10337)
-                "vhost_init: virtual host found for SNI '%s'", cc->sni_hostname);
-            sni_match = 1;
-        }
-        else if (tls_util_name_matches_server(cc->sni_hostname, ap_server_conf)) {
-            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(10338)
-                "vhost_init: virtual host NOT found, but base server[%s] matches SNI '%s'",
-                ap_server_conf->server_hostname, cc->sni_hostname);
-            cc->server = ap_server_conf;
-            sni_match = 1;
-        }
-        else if (sc->strict_sni == TLS_FLAG_FALSE) {
-            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(10339)
-                "vhost_init: no virtual host found, relaxed SNI checking enabled, SNI '%s'",
-                cc->sni_hostname);
-        }
-        else {
-            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(10340)
-                "vhost_init: no virtual host, nor base server[%s] matches SNI '%s'",
-                c->base_server->server_hostname, cc->sni_hostname);
-            cc->server = sc->global->ap_server;
-            rv = APR_NOTFOUND; goto cleanup;
-        }
-    }
-    else {
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(10341)
-            "vhost_init: no SNI hostname provided by client");
-    }
-
-    /* reinit, we might have a new server selected */
-    sc = tls_conf_server_get(cc->server);
-    /* on relaxed SNI matches, we do not enforce the 503 of fallback
-     * certificates. */
-    if (!cc->service_unavailable) {
-        cc->service_unavailable = sni_match? sc->service_unavailable : 0;
-    }
-
-    /* if found or not, cc->server will be the server we use now to do
-     * the real handshake and, if successful, the traffic after that.
-     * Free the current session and create the real one for the
-     * selected server. */
-    if (cc->rustls_server_config) {
-        rustls_server_config_free(cc->rustls_server_config);
-        cc->rustls_server_config = NULL;
-    }
-    rustls_connection_free(cc->rustls_connection);
-    cc->rustls_connection = NULL;
-
-    rv = build_server_connection(&cc->rustls_connection, &cc->rustls_server_config, c);
-
-cleanup:
-    return rv;
-}
-
-apr_status_t tls_core_conn_post_handshake(conn_rec *c)
-{
-    tls_conf_conn_t *cc = tls_conf_conn_get(c);
-    tls_conf_server_t *sc = tls_conf_server_get(cc->server);
-    const rustls_supported_ciphersuite *rsuite;
-    const rustls_certificate *cert;
-    apr_status_t rv = APR_SUCCESS;
-
-    if (rustls_connection_is_handshaking(cc->rustls_connection)) {
-        rv = APR_EGENERAL;
-        ap_log_error(APLOG_MARK, APLOG_ERR, rv, cc->server, APLOGNO(10342)
-                     "post handshake, but rustls claims to still be handshaking: %s",
-                     cc->server->server_hostname);
-        goto cleanup;
-    }
-
-    cc->tls_protocol_id = rustls_connection_get_protocol_version(cc->rustls_connection);
-    cc->tls_protocol_name = tls_proto_get_version_name(sc->global->proto,
-        cc->tls_protocol_id, c->pool);
-    rsuite = rustls_connection_get_negotiated_ciphersuite(cc->rustls_connection);
-    if (!rsuite) {
-        rv = APR_EGENERAL;
-        ap_log_error(APLOG_MARK, APLOG_ERR, rv, cc->server, APLOGNO(10343)
-                     "post handshake, but rustls does not report negotiated cipher suite: %s",
-                     cc->server->server_hostname);
-        goto cleanup;
-    }
-    cc->tls_cipher_id = rustls_supported_ciphersuite_get_suite(rsuite);
-    cc->tls_cipher_name = tls_proto_get_cipher_name(sc->global->proto,
-        cc->tls_cipher_id, c->pool);
-    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "post_handshake %s: %s [%s]",
-        cc->server->server_hostname, cc->tls_protocol_name, cc->tls_cipher_name);
-
-    cert = rustls_connection_get_peer_certificate(cc->rustls_connection, 0);
-    if (cert) {
-        size_t i = 0;
-
-        cc->peer_certs = apr_array_make(c->pool, 5, sizeof(const rustls_certificate*));
-        while (cert) {
-            APR_ARRAY_PUSH(cc->peer_certs, const rustls_certificate*) = cert;
-            cert = rustls_connection_get_peer_certificate(cc->rustls_connection, ++i);
-        }
-    }
-    if (!cc->peer_certs && sc->client_auth == TLS_CLIENT_AUTH_REQUIRED) {
-        ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(10344)
-              "A client certificate is required, but no acceptable certificate was presented.");
-        rv = APR_ECONNABORTED;
-    }
-
-    rv = tls_var_handshake_done(c);
-cleanup:
-    return rv;
-}
-
-/**
- * Return != 0, if a connection also serve requests for server <other>.
- */
-static int tls_conn_compatible_for(tls_conf_conn_t *cc, server_rec *other)
-{
-    tls_conf_server_t *oc, *sc;
-    const rustls_certified_key *sk, *ok;
-    int i;
-
-    /*   - differences in certificates are the responsibility of the client.
-     *     if it thinks the SNI server works for r->server, we are fine with that.
-     *   - if there are differences in requirements to client certificates, we
-     *     need to deny the request.
-     */
-    if (!cc->server || !other) return 0;
-    if (cc->server == other) return 1;
-    oc = tls_conf_server_get(other);
-    if (!oc) return 0;
-    sc = tls_conf_server_get(cc->server);
-    if (!sc) return 0;
-
-    /* same certified keys used? */
-    if (sc->certified_keys->nelts != oc->certified_keys->nelts) return 0;
-    for (i = 0; i < sc->certified_keys->nelts; ++i) {
-        sk = APR_ARRAY_IDX(sc->certified_keys, i, const rustls_certified_key*);
-        ok = APR_ARRAY_IDX(oc->certified_keys, i, const rustls_certified_key*);
-        if (sk != ok) return 0;
-    }
-
-    /* If the connection TLS version is below other other min one, no */
-    if (oc->tls_protocol_min > 0 && cc->tls_protocol_id < oc->tls_protocol_min) return 0;
-    /* If the connection TLS cipher is listed as suppressed by other, no */
-    if (oc->tls_supp_ciphers && tls_util_array_uint16_contains(
-        oc->tls_supp_ciphers, cc->tls_cipher_id)) return 0;
-    return 1;
-}
-
-int tls_core_request_check(request_rec *r)
-{
-    conn_rec *c = r->connection;
-    tls_conf_conn_t *cc = tls_conf_conn_get(c->master? c->master : c);
-    int rv = DECLINED; /* do not object to the request */
-
-    /* If we are not enabled on this connection, leave. We are not renegotiating.
-     * Otherwise:
-     * - service is unavailable when we have only a fallback certificate or
-     *   when a challenge protocol is active (ACME tls-alpn-01 for example).
-     * - with vhosts configured and no SNI from the client, deny access.
-     * - are servers compatible for connection sharing?
-     */
-    if (!TLS_CONN_ST_IS_ENABLED(cc)) goto cleanup;
-    
-    ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
-                 "tls_core_request_check[%s, %d]: %s", r->hostname,
-                 cc? cc->service_unavailable : 2, r->the_request);
-    if (cc->service_unavailable) {
-        rv = HTTP_SERVICE_UNAVAILABLE; goto cleanup;
-    }
-    if (!cc->sni_hostname && r->connection->vhost_lookup_data) {
-        rv = HTTP_FORBIDDEN; goto cleanup;
-    }
-    if (!tls_conn_compatible_for(cc, r->server)) {
-        rv = HTTP_MISDIRECTED_REQUEST;
-        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10345)
-                     "Connection host %s, selected via SNI, and request host %s"
-                     " have incompatible TLS configurations.",
-                     cc->server->server_hostname, r->hostname);
-        goto cleanup;
-    }
-cleanup:
-    return rv;
-}
-
-apr_status_t tls_core_error(conn_rec *c, rustls_result rr, const char **perrstr)
-{
-    tls_conf_conn_t *cc = tls_conf_conn_get(c);
-    apr_status_t rv;
-
-    rv = tls_util_rustls_error(c->pool, rr, perrstr);
-    if (cc) {
-        cc->last_error = rr;
-        cc->last_error_descr = *perrstr;
-    }
-    return rv;
-}
-
-int tls_core_setup_outgoing(conn_rec *c)
-{
-    tls_conf_conn_t *cc;
-    int rv = DECLINED;
-
-    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
-                 "tls_core_setup_outgoing called");
-#if AP_MODULE_MAGIC_AT_LEAST(20120211, 109)
-    if (!c->outgoing) goto cleanup;
-#endif
-    cc = cc_get_or_make(c);
-    if (cc->state == TLS_CONN_ST_DISABLED) {
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
-                     "tls_core_setup_outgoing: already disabled");
-        goto cleanup;
-    }
-    if (TLS_CONN_ST_IS_ENABLED(cc)) {
-        /* we already handle it, allow repeated calls */
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
-                     "tls_core_setup_outgoing: already enabled");
-        rv = OK; goto cleanup;
-    }
-    cc->outgoing = 1;
-    if (!cc->dc) {
-        /* In case there is not dir_conf bound for this connection, we fallback
-         * to the defaults in the base server (we have no virtual host config to use) */
-        cc->dc = ap_get_module_config(c->base_server->lookup_defaults, &tls_module);
-    }
-    if (cc->dc->proxy_enabled != TLS_FLAG_TRUE) {
-        cc->state = TLS_CONN_ST_DISABLED;
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
-                     "tls_core_setup_outgoing: TLSProxyEngine not configured");
-        goto cleanup;
-    }
-    /* we handle this connection */
-    cc->state = TLS_CONN_ST_CLIENT_HELLO;
-    rv = OK;
-
-cleanup:
-    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
-                 "tls_core_setup_outgoing returns %s", rv == OK? "OK" : "DECLINED");
-    return rv;
-}
diff --git a/modules/tls/tls_core.h b/modules/tls/tls_core.h
deleted file mode 100644 (file)
index 6ee1713..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef tls_core_h
-#define tls_core_h
-
-/* The module's state handling of a connection in normal chronological order,
- */
-typedef enum {
-    TLS_CONN_ST_INIT,             /* being initialized */
-    TLS_CONN_ST_DISABLED,         /* TLS is disabled here */
-    TLS_CONN_ST_CLIENT_HELLO,    /* TLS is enabled, prep handshake */
-    TLS_CONN_ST_HANDSHAKE,        /* TLS is enabled, handshake ongonig */
-    TLS_CONN_ST_TRAFFIC,          /* TLS is enabled, handshake done */
-    TLS_CONN_ST_NOTIFIED,         /* TLS is enabled, notification to end sent */
-    TLS_CONN_ST_DONE,             /* TLS is enabled, TLS has shut down */
-} tls_conn_state_t;
-
-#define TLS_CONN_ST_IS_ENABLED(cc)  (cc && cc->state >= TLS_CONN_ST_CLIENT_HELLO)
-
-struct tls_filter_ctx_t;
-
-/* The modules configuration for a connection. Created at connection
- * start and mutable during the lifetime of the connection.
- * (A conn_rec is only ever processed by one thread at a time.)
- */
-typedef struct {
-    server_rec *server;               /* the server_rec selected for this connection,
-                                       * initially c->base_server, to be negotiated via SNI. */
-    tls_conf_dir_t *dc;               /* directory config applying here */
-    tls_conn_state_t state;
-    int outgoing;                     /* != 0 iff outgoing connection (redundant once c->outgoing is everywhere) */
-    int service_unavailable;          /* we 503 all requests on this connection */
-    tls_client_auth_t client_auth;    /* how client authentication with certificates is used */
-    int client_hello_seen;            /* the client hello has been inspected */
-
-    rustls_connection *rustls_connection; /* the session used on this connection or NULL */
-    const rustls_server_config *rustls_server_config; /* the config made for this connection (incoming) or NULL */
-    const rustls_client_config *rustls_client_config; /* the config made for this connection (outgoing) or NULL */
-    struct tls_filter_ctx_t *filter_ctx; /* the context used by this connection's tls filters */
-
-    apr_array_header_t *local_keys;   /* rustls_certified_key* array of connection specific keys */
-    const rustls_certified_key *key;  /* the key selected for the session */
-    int key_cloned;                   /* != 0 iff the key is a unique clone, to be freed */
-    apr_array_header_t *peer_certs;   /* handshaked peer ceritificates or NULL */
-    const char *sni_hostname;         /* the SNI value from the client hello, or NULL */
-    const apr_array_header_t *alpn;   /* the protocols proposed via ALPN by the client */
-    const char *application_protocol;    /* the ALPN selected protocol or NULL */
-
-    int session_id_cache_hit;         /* if a submitted session id was found in our cache */
-
-    apr_uint16_t tls_protocol_id;      /* the TLS version negotiated */
-    const char *tls_protocol_name;     /* the name of the TLS version negotiated */
-    apr_uint16_t tls_cipher_id;       /* the TLS cipher suite negotiated */
-    const char *tls_cipher_name;      /* the name of TLS cipher suite negotiated */
-
-    const char *user_name;            /* != NULL if we derived a TLSUserName from the client_cert */
-    apr_table_t *subprocess_env;      /* common TLS variables for this connection */
-
-    rustls_result last_error;
-    const char *last_error_descr;
-
-} tls_conf_conn_t;
-
-/* Get the connection specific module configuration. */
-tls_conf_conn_t *tls_conf_conn_get(conn_rec *c);
-
-/* Set the module configuration for a connection. */
-void tls_conf_conn_set(conn_rec *c, tls_conf_conn_t *cc);
-
-/* Return OK iff this connection is a TSL connection (or a secondary on a TLS connection). */
-int tls_conn_check_ssl(conn_rec *c);
-
-/**
- * Initialize the module's global and server specific settings. This runs
- * in Apache's "post-config" phase, meaning the configuration has been read
- * and checked for syntactic and other easily verifiable errors and now
- * it is time to load everything in and make it ready for traffic.
- * <p>      a memory pool staying with us the whole time until the server stops/reloads.
- * <ptemp>  a temporary pool as a scratch buffer that will be destroyed shortly after.
- * <base_server> the server for the global configuration which links -> next to
- *          all contained virtual hosts configured.
- */
-apr_status_t tls_core_init(apr_pool_t *p, apr_pool_t *ptemp, server_rec *base_server);
-
-/**
- * Initialize the module's outgoing connection settings. This runs
- * in Apache's "post-config" phase after mod_proxy.
- */
-apr_status_t tls_core_init_outgoing(apr_pool_t *p, apr_pool_t *ptemp, server_rec *base_server);
-
-/**
- * Supply a directory configuration for the connection to work with. This
- * maybe NULL. This can be called several times during the lifetime of a
- * connection and must not change the current TLS state.
- * @param c the connection
- * @param dir_conf optional directory configuration that applies
- */
-void tls_core_conn_bind(conn_rec *c, ap_conf_vector_t *dir_conf);
-
-/**
- * Disable TLS on a new connection. Will do nothing on already initialized
- * connections.
- * @param c a new connection
- */
-void tls_core_conn_disable(conn_rec *c);
-
-/**
- * Initialize the tls_conf_connt_t for the connection
- * and decide if TLS is enabled or not.
- * @return OK if enabled, DECLINED otherwise
- */
-int tls_core_pre_conn_init(conn_rec *c);
-
-/**
- * Initialize the module for a TLS enabled connection.
- * @param c a new connection
- */
-apr_status_t tls_core_conn_init(conn_rec *c);
-
-/**
- * Called when the ClientHello has been received and values from it
- * have been extracted into the `tls_conf_conn_t` of the connection.
- *
- * Decides:
- * - which `server_rec` this connection is for (SNI)
- * - which application protocol to use (ALPN)
- * This may be unsuccessful for several reasons. The SNI
- * from the client may not be known or the selected server
- * has not certificates available. etc.
- * On success, a proper `rustls_connection` will have been
- * created and set in the `tls_conf_conn_t` of the connection.
- */
-apr_status_t tls_core_conn_seen_client_hello(conn_rec *c);
-
-/**
- * The TLS handshake for the connection has been successfully performed.
- * This means that TLS related properties, such as TLS version and cipher,
- * are known and the props in `tls_conf_conn_t` of the connection
- * can be set.
- */
-apr_status_t tls_core_conn_post_handshake(conn_rec *c);
-
-/**
- * After a request has been read, but before processing is started, we
- * check if everything looks good to us:
- * - was an SNI hostname provided by the client when we have vhosts to choose from?
- *   if not, we deny it.
- * - if the SNI hostname and request host are not the same, are they - from TLS
- *   point of view - 'compatible' enough? For example, if one server requires
- *   client certificates and the other not (or with different settings), such
- *   a request will also be denied.
- * returns DECLINED if everything is ok, otherwise an HTTP response code to
- *   generate an error page for.
- */
-int tls_core_request_check(request_rec *r);
-
-/**
- * A Rustls error happened while processing the connection. Look up an
- * error description, determine the apr_status_t to use for it and remember
- * this as the last error at tls_conf_conn_t.
- */
-apr_status_t tls_core_error(conn_rec *c, rustls_result rr, const char **perrstr);
-
-/**
- * Determine if we handle the TLS for an outgoing connection or not.
- * @param c the connection
- * @return OK if we handle the TLS, DECLINED otherwise.
- */
-int tls_core_setup_outgoing(conn_rec *c);
-
-#endif /* tls_core_h */
diff --git a/modules/tls/tls_filter.c b/modules/tls/tls_filter.c
deleted file mode 100644 (file)
index 0ee6be6..0000000
+++ /dev/null
@@ -1,1017 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <assert.h>
-#include <apr_lib.h>
-#include <apr_strings.h>
-
-#include <httpd.h>
-#include <http_connection.h>
-#include <http_core.h>
-#include <http_request.h>
-#include <http_log.h>
-#include <ap_socache.h>
-
-#include <rustls.h>
-
-#include "tls_proto.h"
-#include "tls_conf.h"
-#include "tls_core.h"
-#include "tls_filter.h"
-#include "tls_util.h"
-
-
-extern module AP_MODULE_DECLARE_DATA tls_module;
-APLOG_USE_MODULE(tls);
-
-
-static rustls_io_result tls_read_callback(
-    void *userdata, unsigned char *buf, size_t n, size_t *out_n)
-{
-    tls_data_t *d = userdata;
-    size_t len = d->len > n? n : d->len;
-    memcpy(buf, d->data, len);
-    *out_n = len;
-    return 0;
-}
-
-/**
- * Provide TLS encrypted data to the rustls server_session in <fctx->cc->rustls_connection>.
- *
- * If <fctx->fin_tls_bb> holds data, take it from there. Otherwise perform a
- * read via the network filters below us into that brigade.
- *
- * <fctx->fin_block> determines if we do a blocking read inititally or not.
- * If the first read did to not produce enough data, any secondary read is done
- * non-blocking.
- *
- * Had any data been added to <fctx->cc->rustls_connection>, call its "processing"
- * function to handle the added data before leaving.
- */
-static apr_status_t read_tls_to_rustls(
-    tls_filter_ctx_t *fctx, apr_size_t len, apr_read_type_e block, int errors_expected)
-{
-    tls_data_t d;
-    apr_size_t rlen;
-    apr_off_t passed = 0;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    int os_err;
-    apr_status_t rv = APR_SUCCESS;
-
-    if (APR_BRIGADE_EMPTY(fctx->fin_tls_bb)) {
-        ap_log_error(APLOG_MARK, APLOG_TRACE2, rv, fctx->cc->server,
-            "read_tls_to_rustls, get data from network, block=%d", block);
-        rv = ap_get_brigade(fctx->fin_ctx->next, fctx->fin_tls_bb,
-                            AP_MODE_READBYTES, block, (apr_off_t)len);
-        if (APR_SUCCESS != rv) {
-            goto cleanup;
-        }
-    }
-
-    while (!APR_BRIGADE_EMPTY(fctx->fin_tls_bb) && passed < (apr_off_t)len) {
-        apr_bucket *b = APR_BRIGADE_FIRST(fctx->fin_tls_bb);
-
-        if (APR_BUCKET_IS_EOS(b)) {
-            ap_log_error(APLOG_MARK, APLOG_TRACE2, rv, fctx->cc->server,
-                "read_tls_to_rustls, EOS");
-            if (fctx->fin_tls_buffer_bb) {
-                apr_brigade_cleanup(fctx->fin_tls_buffer_bb);
-            }
-            rv = APR_EOF; goto cleanup;
-        }
-
-        rv = apr_bucket_read(b, (const char**)&d.data, &d.len, block);
-        if (APR_STATUS_IS_EOF(rv)) {
-            apr_bucket_delete(b);
-            continue;
-        }
-        else if (APR_SUCCESS != rv) {
-            goto cleanup;
-        }
-
-        if (d.len > 0) {
-            /* got something, do not block on getting more */
-            block = APR_NONBLOCK_READ;
-
-            os_err = rustls_connection_read_tls(fctx->cc->rustls_connection,
-                                tls_read_callback, &d, &rlen);
-            if (os_err) {
-                rv = APR_FROM_OS_ERROR(os_err);
-                goto cleanup;
-            }
-
-            if (fctx->fin_tls_buffer_bb) {
-                /* we buffer for later replay on the 'real' rustls_connection */
-                apr_brigade_write(fctx->fin_tls_buffer_bb, NULL, NULL, (const char*)d.data, rlen);
-            }
-            if (rlen >= d.len) {
-                apr_bucket_delete(b);
-            }
-            else {
-                b->start += (apr_off_t)rlen;
-                b->length -= rlen;
-            }
-            fctx->fin_bytes_in_rustls += (apr_off_t)d.len;
-            passed += (apr_off_t)rlen;
-        }
-        else if (d.len == 0) {
-            apr_bucket_delete(b);
-        }
-    }
-
-    if (passed > 0) {
-        rr = rustls_connection_process_new_packets(fctx->cc->rustls_connection);
-        if (rr != RUSTLS_RESULT_OK) goto cleanup;
-    }
-
-cleanup:
-    if (rr != RUSTLS_RESULT_OK) {
-        rv = APR_ECONNRESET;
-        if (!errors_expected) {
-            const char *err_descr = "";
-            rv = tls_core_error(fctx->c, rr, &err_descr);
-            ap_log_cerror(APLOG_MARK, APLOG_WARNING, rv, fctx->c, APLOGNO(10353)
-                         "processing TLS data: [%d] %s", (int)rr, err_descr);
-        }
-    }
-    else if (APR_STATUS_IS_EOF(rv) && passed > 0) {
-        /* encountering EOF while actually having read sth is a success. */
-        rv = APR_SUCCESS;
-    }
-    else if (APR_SUCCESS == rv && passed == 0 && fctx->fin_block == APR_NONBLOCK_READ) {
-        rv = APR_EAGAIN;
-    }
-    else {
-        ap_log_error(APLOG_MARK, APLOG_TRACE2, rv, fctx->cc->server,
-            "read_tls_to_rustls, passed %ld bytes to rustls", (long)passed);
-    }
-    return rv;
-}
-
-static apr_status_t fout_pass_tls_to_net(tls_filter_ctx_t *fctx)
-{
-    apr_status_t rv = APR_SUCCESS;
-
-    if (!APR_BRIGADE_EMPTY(fctx->fout_tls_bb)) {
-        rv = ap_pass_brigade(fctx->fout_ctx->next, fctx->fout_tls_bb);
-        if (APR_SUCCESS == rv && fctx->c->aborted) {
-            rv = APR_ECONNRESET;
-        }
-        fctx->fout_bytes_in_tls_bb = 0;
-        apr_brigade_cleanup(fctx->fout_tls_bb);
-    }
-    return rv;
-}
-
-static apr_status_t fout_pass_all_to_net(
-    tls_filter_ctx_t *fctx, int flush);
-
-static apr_status_t filter_abort(
-    tls_filter_ctx_t *fctx)
-{
-    apr_status_t rv;
-
-    if (fctx->cc->state != TLS_CONN_ST_DONE) {
-        if (fctx->cc->state > TLS_CONN_ST_CLIENT_HELLO) {
-            rustls_connection_send_close_notify(fctx->cc->rustls_connection);
-            rv = fout_pass_all_to_net(fctx, 1);
-            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, fctx->c, "filter_abort, flushed output");
-        }
-        fctx->c->aborted = 1;
-        fctx->cc->state = TLS_CONN_ST_DONE;
-    }
-    return APR_ECONNABORTED;
-}
-
-static apr_status_t filter_recv_client_hello(tls_filter_ctx_t *fctx)
-{
-    apr_status_t rv = APR_SUCCESS;
-
-    ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, fctx->cc->server,
-        "tls_filter, server=%s, recv client hello", fctx->cc->server->server_hostname);
-    /* only for incoming connections */
-    ap_assert(!fctx->cc->outgoing);
-
-    if (rustls_connection_is_handshaking(fctx->cc->rustls_connection)) {
-        apr_bucket_brigade *bb_tmp;
-
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, fctx->c, "filter_recv_client_hello: start");
-        fctx->fin_tls_buffer_bb = apr_brigade_create(fctx->c->pool, fctx->c->bucket_alloc);
-        do {
-            if (rustls_connection_wants_read(fctx->cc->rustls_connection)) {
-                rv = read_tls_to_rustls(fctx, fctx->fin_max_in_rustls, APR_BLOCK_READ, 1);
-                if (APR_SUCCESS != rv) {
-                    if (fctx->cc->client_hello_seen) {
-                        rv = APR_EAGAIN;  /* we got what we needed */
-                        break;
-                    }
-                    /* Something went wrong before we saw the client hello.
-                     * This is a real error on which we should not continue. */
-                    goto cleanup;
-                }
-            }
-            /* Notice: we never write here to the client. We just want to inspect
-             * the client hello. */
-        } while (!fctx->cc->client_hello_seen);
-
-        /* We have seen the client hello and selected the server (vhost) to use
-         * on this connection. Set up the 'real' rustls_connection based on the
-         * servers 'real' rustls_config. */
-        rv = tls_core_conn_seen_client_hello(fctx->c);
-        if (APR_SUCCESS != rv) goto cleanup;
-
-        bb_tmp = fctx->fin_tls_bb; /* data we have yet to feed to rustls */
-        fctx->fin_tls_bb = fctx->fin_tls_buffer_bb; /* data we already fed to the pre_session */
-        fctx->fin_tls_buffer_bb = NULL;
-        APR_BRIGADE_CONCAT(fctx->fin_tls_bb, bb_tmp); /* all tls data from the client so far, reloaded */
-        apr_brigade_destroy(bb_tmp);
-        rv = APR_SUCCESS;
-    }
-
-cleanup:
-    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, fctx->c, "filter_recv_client_hello: done");
-    return rv;
-}
-
-static apr_status_t filter_send_client_hello(tls_filter_ctx_t *fctx)
-{
-    apr_status_t rv = APR_SUCCESS;
-
-    ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, fctx->cc->server,
-        "tls_filter, server=%s, send client hello", fctx->cc->server->server_hostname);
-    /* Only for outgoing connections */
-    ap_assert(fctx->cc->outgoing);
-    if (rustls_connection_is_handshaking(fctx->cc->rustls_connection)) {
-        while (rustls_connection_wants_write(fctx->cc->rustls_connection)) {
-            /* write flushed, so it really gets out */
-            rv = fout_pass_all_to_net(fctx, 1);
-            if (APR_SUCCESS != rv) goto cleanup;
-        }
-    }
-
-cleanup:
-    return rv;
-}
-
-/**
- * While <fctx->cc->rustls_connection> indicates that a handshake is ongoing,
- * write TLS data from and read network TLS data to the server session.
- *
- * @return APR_SUCCESS when the handshake is completed
- */
-static apr_status_t filter_do_handshake(
-    tls_filter_ctx_t *fctx)
-{
-    apr_status_t rv = APR_SUCCESS;
-
-    ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, fctx->cc->server,
-        "tls_filter, server=%s, do handshake", fctx->cc->server->server_hostname);
-    if (rustls_connection_is_handshaking(fctx->cc->rustls_connection)) {
-        do {
-            if (rustls_connection_wants_write(fctx->cc->rustls_connection)) {
-                rv = fout_pass_all_to_net(fctx, 1);
-                if (APR_SUCCESS != rv) goto cleanup;
-            }
-            else if (rustls_connection_wants_read(fctx->cc->rustls_connection)) {
-                rv = read_tls_to_rustls(fctx, fctx->fin_max_in_rustls, APR_BLOCK_READ, 0);
-                if (APR_SUCCESS != rv) goto cleanup;
-            }
-        }
-        while (rustls_connection_is_handshaking(fctx->cc->rustls_connection));
-
-        /* rustls reports the TLS handshake to be done, when it *internally* has
-         * processed everything into its buffers. Not when the buffers have been
-         * send to the other side. */
-        if (rustls_connection_wants_write(fctx->cc->rustls_connection)) {
-            rv = fout_pass_all_to_net(fctx, 1);
-            if (APR_SUCCESS != rv) goto cleanup;
-        }
-    }
-cleanup:
-    ap_log_error(APLOG_MARK, APLOG_TRACE2, rv, fctx->cc->server,
-        "tls_filter, server=%s, handshake done", fctx->cc->server->server_hostname);
-    if (APR_SUCCESS != rv) {
-        if (fctx->cc->last_error_descr) {
-            ap_log_cerror(APLOG_MARK, APLOG_INFO, APR_ECONNABORTED, fctx->c, APLOGNO(10354)
-                "handshake failed: %s", fctx->cc->last_error_descr);
-        }
-    }
-    return rv;
-}
-
-static apr_status_t progress_tls_atleast_to(tls_filter_ctx_t *fctx, tls_conn_state_t state)
-{
-    apr_status_t rv = APR_SUCCESS;
-
-    /* handle termination immediately */
-    if (state == TLS_CONN_ST_DONE) {
-        rv = APR_ECONNABORTED;
-        goto cleanup;
-    }
-
-    if (state > TLS_CONN_ST_CLIENT_HELLO
-        && TLS_CONN_ST_CLIENT_HELLO == fctx->cc->state) {
-        rv = tls_core_conn_init(fctx->c);
-        if (APR_SUCCESS != rv) goto cleanup;
-
-        if (fctx->cc->outgoing) {
-            rv = filter_send_client_hello(fctx);
-        }
-        else {
-            rv = filter_recv_client_hello(fctx);
-        }
-        if (APR_SUCCESS != rv) goto cleanup;
-        fctx->cc->state = TLS_CONN_ST_HANDSHAKE;
-    }
-
-    if (state > TLS_CONN_ST_HANDSHAKE
-        && TLS_CONN_ST_HANDSHAKE== fctx->cc->state) {
-        rv = filter_do_handshake(fctx);
-        if (APR_SUCCESS != rv) goto cleanup;
-        rv = tls_core_conn_post_handshake(fctx->c);
-        if (APR_SUCCESS != rv) goto cleanup;
-        fctx->cc->state = TLS_CONN_ST_TRAFFIC;
-    }
-
-    if (state < fctx->cc->state) {
-        rv = APR_ECONNABORTED;
-    }
-
-cleanup:
-    if (APR_SUCCESS != rv) {
-        filter_abort(fctx); /* does change the state itself */
-    }
-    return rv;
-}
-
-/**
- * The connection filter converting TLS encrypted network data into plain, unencrpyted
- * traffic data to be processed by filters above it in the filter chain.
- *
- * Unfortunately, Apache's filter infrastructure places a heavy implementation
- * complexity on its input filters for the various use cases its HTTP/1.x parser
- * (mainly) finds convenient:
- *
- * <bb>      the bucket brigade to place the data into.
- * <mode>    one of
- *     - AP_MODE_READBYTES: just add up to <readbytes> data into <bb>
- *     - AP_MODE_GETLINE: make a best effort to get data up to and including a CRLF.
- *                        it can be less, but not more t than that.
- *     - AP_MODE_EATCRLF: never used, we puke on it.
- *     - AP_MODE_SPECULATIVE: read data without consuming it.
- *     - AP_MODE_EXHAUSTIVE: never used, we puke on it.
- *     - AP_MODE_INIT: called once on a connection. needs to pass down the filter
- *                      chain, giving every filter the change to "INIT".
- * <block>   do blocking or non-blocking reads
- * <readbytes> max amount of data to add to <bb>, seems to be 0 for GETLINE
- */
-static apr_status_t filter_conn_input(
-    ap_filter_t *f, apr_bucket_brigade *bb, ap_input_mode_t mode,
-    apr_read_type_e block, apr_off_t readbytes)
-{
-    tls_filter_ctx_t *fctx = f->ctx;
-    apr_status_t rv = APR_SUCCESS;
-    apr_off_t passed = 0, nlen;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    apr_size_t in_buf_len;
-    char *in_buf = NULL;
-
-    fctx->fin_block = block;
-    if (f->c->aborted) {
-        rv = filter_abort(fctx); goto cleanup;
-    }
-
-    ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, fctx->cc->server,
-        "tls_filter_conn_input, server=%s, mode=%d, block=%d, readbytes=%ld",
-        fctx->cc->server->server_hostname, mode, block, (long)readbytes);
-
-    rv = progress_tls_atleast_to(fctx, TLS_CONN_ST_TRAFFIC);
-    if (APR_SUCCESS != rv) goto cleanup; /* this also leaves on APR_EAGAIN */
-
-    if (!fctx->cc->rustls_connection) {
-        return ap_get_brigade(f->next, bb, mode, block, readbytes);
-    }
-
-#if AP_MODULE_MAGIC_AT_LEAST(20200420, 1)
-    ap_filter_reinstate_brigade(f, fctx->fin_plain_bb, NULL);
-#endif
-
-    if (AP_MODE_INIT == mode) {
-        /* INIT is used to trigger the handshake, it does not return any traffic data. */
-        goto cleanup;
-    }
-
-    /* If we have nothing buffered, try getting more input.
-     * a) ask rustls_connection for decrypted data, if it has any.
-     *    Note that only full records can be decrypted. We might have
-     *    written TLS data to the session, but that does not mean it
-     *    can give unencryted data out again.
-     * b) read TLS bytes from the network and feed them to the rustls session.
-     * c) go back to a) if b) added data.
-     */
-    while (APR_BRIGADE_EMPTY(fctx->fin_plain_bb)) {
-        apr_size_t rlen = 0;
-        apr_bucket *b;
-
-        if (fctx->fin_bytes_in_rustls > 0) {
-            in_buf_len = APR_BUCKET_BUFF_SIZE;
-            in_buf = ap_calloc(in_buf_len, sizeof(char));
-            rr = rustls_connection_read(fctx->cc->rustls_connection,
-                (unsigned char*)in_buf, in_buf_len, &rlen);
-            if (rr == RUSTLS_RESULT_PLAINTEXT_EMPTY) {
-                rr = RUSTLS_RESULT_OK;
-                rlen = 0;
-            }
-            if (rr != RUSTLS_RESULT_OK) goto cleanup;
-            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, fctx->c,
-                         "tls_filter_conn_input: got %ld plain bytes from rustls", (long)rlen);
-            if (rlen > 0) {
-                b = apr_bucket_heap_create(in_buf, rlen, free, fctx->c->bucket_alloc);
-                APR_BRIGADE_INSERT_TAIL(fctx->fin_plain_bb, b);
-            }
-            else {
-                free(in_buf);
-            }
-            in_buf = NULL;
-        }
-        if (rlen == 0) {
-            /* that did not produce anything either. try getting more
-             * TLS data from the network into the rustls session. */
-            fctx->fin_bytes_in_rustls = 0;
-            rv = read_tls_to_rustls(fctx, fctx->fin_max_in_rustls, block, 0);
-            if (APR_SUCCESS != rv) goto cleanup; /* this also leave on APR_EAGAIN */
-        }
-    }
-
-    if (AP_MODE_GETLINE == mode) {
-        if (readbytes <= 0) readbytes = HUGE_STRING_LEN;
-        rv = tls_util_brigade_split_line(bb, fctx->fin_plain_bb, block, readbytes, &nlen);
-        if (APR_SUCCESS != rv) goto cleanup;
-        passed += nlen;
-    }
-    else if (AP_MODE_READBYTES == mode) {
-        ap_assert(readbytes > 0);
-        rv = tls_util_brigade_transfer(bb, fctx->fin_plain_bb, readbytes, &nlen);
-        if (APR_SUCCESS != rv) goto cleanup;
-        passed += nlen;
-    }
-    else if (AP_MODE_SPECULATIVE == mode) {
-        ap_assert(readbytes > 0);
-        rv = tls_util_brigade_copy(bb, fctx->fin_plain_bb, readbytes, &nlen);
-        if (APR_SUCCESS != rv) goto cleanup;
-        passed += nlen;
-    }
-    else if (AP_MODE_EXHAUSTIVE == mode) {
-        /* return all we have */
-        APR_BRIGADE_CONCAT(bb, fctx->fin_plain_bb);
-    }
-    else {
-        /* We do support any other mode */
-        rv = APR_ENOTIMPL; goto cleanup;
-    }
-
-    fout_pass_all_to_net(fctx, 0);
-
-cleanup:
-    if (NULL != in_buf) free(in_buf);
-
-    if (APLOGctrace3(fctx->c)) {
-        tls_util_bb_log(fctx->c, APLOG_TRACE3, "tls_input, fctx->fin_plain_bb", fctx->fin_plain_bb);
-        tls_util_bb_log(fctx->c, APLOG_TRACE3, "tls_input, bb", bb);
-    }
-    if (rr != RUSTLS_RESULT_OK) {
-        const char *err_descr = "";
-
-        rv = tls_core_error(fctx->c, rr, &err_descr);
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, fctx->c, APLOGNO(10355)
-                     "tls_filter_conn_input: [%d] %s", (int)rr, err_descr);
-    }
-    else if (APR_STATUS_IS_EAGAIN(rv)) {
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE4, rv, fctx->c,
-                     "tls_filter_conn_input: no data available");
-    }
-    else if (APR_SUCCESS != rv) {
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, fctx->c, APLOGNO(10356)
-                     "tls_filter_conn_input");
-    }
-    else {
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, fctx->c,
-                     "tls_filter_conn_input: passed %ld bytes", (long)passed);
-    }
-
-#if AP_MODULE_MAGIC_AT_LEAST(20200420, 1)
-    if (APR_SUCCESS == rv || APR_STATUS_IS_EAGAIN(rv)) {
-        ap_filter_setaside_brigade(f, fctx->fin_plain_bb);
-    }
-#endif
-    return rv;
-}
-
-static rustls_io_result tls_write_callback(
-    void *userdata, const unsigned char *buf, size_t n, size_t *out_n)
-{
-    tls_filter_ctx_t *fctx = userdata;
-    apr_status_t rv;
-
-    if ((apr_off_t)n + fctx->fout_bytes_in_tls_bb >= (apr_off_t)fctx->fout_auto_flush_size) {
-        apr_bucket *b = apr_bucket_transient_create((const char*)buf, n, fctx->fout_tls_bb->bucket_alloc);
-        APR_BRIGADE_INSERT_TAIL(fctx->fout_tls_bb, b);
-        fctx->fout_bytes_in_tls_bb += (apr_off_t)n;
-        rv = fout_pass_tls_to_net(fctx);
-        *out_n = n;
-    }
-    else {
-        rv = apr_brigade_write(fctx->fout_tls_bb, NULL, NULL, (const char*)buf, n);
-        if (APR_SUCCESS != rv) goto cleanup;
-        fctx->fout_bytes_in_tls_bb += (apr_off_t)n;
-        *out_n = n;
-    }
-cleanup:
-    ap_log_error(APLOG_MARK, APLOG_TRACE5, rv, fctx->cc->server,
-        "tls_write_callback: %ld bytes", (long)n);
-    return APR_TO_OS_ERROR(rv);
-}
-
-static rustls_io_result tls_write_vectored_callback(
-    void *userdata, const rustls_iovec *riov, size_t count, size_t *out_n)
-{
-    tls_filter_ctx_t *fctx = userdata;
-    const struct iovec *iov = (const struct iovec*)riov;
-    apr_status_t rv;
-    size_t i, n = 0;
-    apr_bucket *b;
-
-    for (i = 0; i < count; ++i, ++iov) {
-        b = apr_bucket_transient_create((const char*)iov->iov_base, iov->iov_len, fctx->fout_tls_bb->bucket_alloc);
-        APR_BRIGADE_INSERT_TAIL(fctx->fout_tls_bb, b);
-        n += iov->iov_len;
-    }
-    fctx->fout_bytes_in_tls_bb += (apr_off_t)n;
-    rv = fout_pass_tls_to_net(fctx);
-    *out_n = n;
-    ap_log_error(APLOG_MARK, APLOG_TRACE5, rv, fctx->cc->server,
-        "tls_write_vectored_callback: %ld bytes in %d slices", (long)n, (int)count);
-    return APR_TO_OS_ERROR(rv);
-}
-
-#define TLS_WRITE_VECTORED      1
-/**
- * Read TLS encrypted data from <fctx->cc->rustls_connection> and pass it down
- * Apache's filter chain to the network.
- *
- * For now, we always FLUSH the data, since that is what we need during handshakes.
- */
-static apr_status_t fout_pass_rustls_to_tls(tls_filter_ctx_t *fctx)
-{
-    apr_status_t rv = APR_SUCCESS;
-
-    if (rustls_connection_wants_write(fctx->cc->rustls_connection)) {
-        size_t dlen;
-        int os_err;
-
-        if (TLS_WRITE_VECTORED) {
-            do {
-                os_err = rustls_connection_write_tls_vectored(
-                    fctx->cc->rustls_connection, tls_write_vectored_callback, fctx, &dlen);
-                if (os_err) {
-                    rv = APR_FROM_OS_ERROR(os_err);
-                    goto cleanup;
-                }
-            }
-            while (rustls_connection_wants_write(fctx->cc->rustls_connection));
-        }
-        else {
-            do {
-                os_err = rustls_connection_write_tls(
-                    fctx->cc->rustls_connection, tls_write_callback, fctx, &dlen);
-                if (os_err) {
-                    rv = APR_FROM_OS_ERROR(os_err);
-                    goto cleanup;
-                }
-            }
-            while (rustls_connection_wants_write(fctx->cc->rustls_connection));
-            ap_log_cerror(APLOG_MARK, APLOG_TRACE3, rv, fctx->c,
-                "fout_pass_rustls_to_tls, %ld bytes ready for network", (long)fctx->fout_bytes_in_tls_bb);
-            fctx->fout_bytes_in_rustls = 0;
-        }
-    }
-cleanup:
-    return rv;
-}
-
-static apr_status_t fout_pass_buf_to_rustls(
-    tls_filter_ctx_t *fctx, const char *buf, apr_size_t len)
-{
-    apr_status_t rv = APR_SUCCESS;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    apr_size_t written;
-
-    while (len) {
-        /* check if we will exceed the limit of data in rustls.
-         * rustls does not guarantuee that it will accept all data, so we
-         * iterate and flush when needed. */
-        if (fctx->fout_bytes_in_rustls + (apr_off_t)len > (apr_off_t)fctx->fout_max_in_rustls) {
-            rv = fout_pass_rustls_to_tls(fctx);
-            if (APR_SUCCESS != rv) goto cleanup;
-        }
-
-        rr = rustls_connection_write(fctx->cc->rustls_connection,
-                                     (const unsigned char*)buf, len, &written);
-        if (rr != RUSTLS_RESULT_OK) goto cleanup;
-        ap_assert(written <= len);
-        fctx->fout_bytes_in_rustls += (apr_off_t)written;
-        buf += written;
-        len -= written;
-        if (written == 0) {
-            rv = APR_EAGAIN;
-            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, fctx->c, APLOGNO(10357)
-                         "fout_pass_buf_to_rustls: not read by rustls at all");
-            goto cleanup;
-        }
-    }
-cleanup:
-    if (rr != RUSTLS_RESULT_OK) {
-        const char *err_descr = "";
-        rv = tls_core_error(fctx->c, rr, &err_descr);
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, fctx->c, APLOGNO(10358)
-                     "fout_pass_buf_to_tls to rustls: [%d] %s", (int)rr, err_descr);
-    }
-    return rv;
-}
-
-static apr_status_t fout_pass_all_to_tls(tls_filter_ctx_t *fctx)
-{
-    apr_status_t rv = APR_SUCCESS;
-
-    if (fctx->fout_buf_plain_len) {
-        rv = fout_pass_buf_to_rustls(fctx, fctx->fout_buf_plain, fctx->fout_buf_plain_len);
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, fctx->c,
-                     "fout_pass_all_to_tls: %ld plain bytes written to rustls",
-                     (long)fctx->fout_buf_plain_len);
-        if (APR_SUCCESS != rv) goto cleanup;
-        fctx->fout_buf_plain_len = 0;
-    }
-
-    rv = fout_pass_rustls_to_tls(fctx);
-cleanup:
-    return rv;
-}
-
-static apr_status_t fout_pass_all_to_net(tls_filter_ctx_t *fctx, int flush)
-{
-    apr_status_t rv;
-
-    rv = fout_pass_all_to_tls(fctx);
-    if (APR_SUCCESS != rv) goto cleanup;
-    if (flush) {
-        apr_bucket *b = apr_bucket_flush_create(fctx->fout_tls_bb->bucket_alloc);
-        APR_BRIGADE_INSERT_TAIL(fctx->fout_tls_bb, b);
-    }
-    rv = fout_pass_tls_to_net(fctx);
-cleanup:
-    return rv;
-}
-
-static apr_status_t fout_add_bucket_to_plain(tls_filter_ctx_t *fctx, apr_bucket *b)
-{
-    const char *data;
-    apr_size_t dlen, buf_remain;
-    apr_status_t rv = APR_SUCCESS;
-
-    ap_assert((apr_size_t)-1 != b->length);
-    if (b->length == 0) {
-        apr_bucket_delete(b);
-        goto cleanup;
-    }
-
-    buf_remain = fctx->fout_buf_plain_size - fctx->fout_buf_plain_len;
-    if (buf_remain == 0) {
-        rv = fout_pass_all_to_tls(fctx);
-        if (APR_SUCCESS != rv) goto cleanup;
-        buf_remain = fctx->fout_buf_plain_size - fctx->fout_buf_plain_len;
-        ap_assert(buf_remain > 0);
-    }
-    if (b->length > buf_remain) {
-        apr_bucket_split(b, buf_remain);
-    }
-    rv = apr_bucket_read(b, &data, &dlen, APR_BLOCK_READ);
-    if (APR_SUCCESS != rv) goto cleanup;
-    /*if (dlen > TLS_PREF_PLAIN_CHUNK_SIZE)*/
-    ap_assert(dlen <= buf_remain);
-    memcpy(fctx->fout_buf_plain + fctx->fout_buf_plain_len, data, dlen);
-    fctx->fout_buf_plain_len += dlen;
-    apr_bucket_delete(b);
-cleanup:
-    return rv;
-}
-
-static apr_status_t fout_add_bucket_to_tls(tls_filter_ctx_t *fctx, apr_bucket *b)
-{
-    apr_status_t rv;
-
-    rv = fout_pass_all_to_tls(fctx);
-    if (APR_SUCCESS != rv) goto cleanup;
-    APR_BUCKET_REMOVE(b);
-    APR_BRIGADE_INSERT_TAIL(fctx->fout_tls_bb, b);
-    if (AP_BUCKET_IS_EOC(b)) {
-        rustls_connection_send_close_notify(fctx->cc->rustls_connection);
-        fctx->cc->state = TLS_CONN_ST_NOTIFIED;
-        rv = fout_pass_rustls_to_tls(fctx);
-        if (APR_SUCCESS != rv) goto cleanup;
-    }
-cleanup:
-    return rv;
-}
-
-static apr_status_t fout_append_plain(tls_filter_ctx_t *fctx, apr_bucket *b)
-{
-    const char *data;
-    apr_size_t dlen, buf_remain;
-    rustls_result rr = RUSTLS_RESULT_OK;
-    apr_status_t rv = APR_SUCCESS;
-    const char *lbuf = NULL;
-    int flush = 0;
-
-    if (b) {
-        /* if our plain buffer is full, now is a good time to flush it. */
-        buf_remain = fctx->fout_buf_plain_size - fctx->fout_buf_plain_len;
-        if (buf_remain == 0) {
-            rv = fout_pass_all_to_tls(fctx);
-            if (APR_SUCCESS != rv) goto cleanup;
-            buf_remain = fctx->fout_buf_plain_size - fctx->fout_buf_plain_len;
-            ap_assert(buf_remain > 0);
-        }
-
-        /* Resolve any indeterminate bucket to a "real" one by reading it. */
-        if ((apr_size_t)-1 == b->length) {
-            rv = apr_bucket_read(b, &data, &dlen, APR_BLOCK_READ);
-            if (APR_STATUS_IS_EOF(rv)) {
-                apr_bucket_delete(b);
-                goto maybe_flush;
-            }
-            else if (APR_SUCCESS != rv) goto cleanup;
-        }
-        /* Now `b` is the bucket that we need to append and consume */
-        if (APR_BUCKET_IS_METADATA(b)) {
-            /* outgoing buckets:
-             *   [PLAINDATA META PLAINDATA META META]
-             * need to become:
-             *   [TLSDATA META TLSDATA META META]
-             * because we need to send the meta buckets down the
-             * network filters. */
-            rv = fout_add_bucket_to_tls(fctx, b);
-            flush = 1;
-        }
-        else if (b->length == 0) {
-            apr_bucket_delete(b);
-        }
-        else if (b->length < 1024 || fctx->fout_buf_plain_len > 0) {
-            /* we want to buffer small chunks to create larger TLS records and
-             * not leak security relevant information. So, we buffer small
-             * chunks and add (parts of) later, larger chunks if the plain
-             * buffer contains data. */
-            rv = fout_add_bucket_to_plain(fctx, b);
-            if (APR_SUCCESS != rv) goto cleanup;
-        }
-        else {
-            /* we have a large chunk and our plain buffer is empty, write it
-             * directly into rustls. */
-#define TLS_FILE_CHUNK_SIZE  4 * TLS_PREF_PLAIN_CHUNK_SIZE
-            if (b->length > TLS_FILE_CHUNK_SIZE) {
-                apr_bucket_split(b, TLS_FILE_CHUNK_SIZE);
-            }
-
-            if (APR_BUCKET_IS_FILE(b)
-                && (lbuf = malloc(b->length))) {
-                /* A file bucket is a most wonderous thing. Since the dawn of time,
-                 * it has been subject to many optimizations for efficient handling
-                 * of large data in the server:
-                 * - unless one reads from it, it will just consist of a file handle
-                 *   and the offset+length information.
-                 * - a apr_bucket_read() will transform itself to a bucket holding
-                 *   some 8000 bytes of data (APR_BUCKET_BUFF_SIZE), plus a following
-                 *   bucket that continues to hold the file handle and updated offsets/length
-                 *   information.
-                 *   Using standard bucket brigade handling, one would send 8000 bytes
-                 *   chunks to the network and that is fine for many occasions.
-                 * - to have improved performance, the http: network handler takes
-                 *   the file handle directly and uses sendfile() when the OS supports it.
-                 * - But there is not sendfile() for TLS (netflix did some experiments).
-                 * So.
-                 * rustls will try to collect max length traffic data into ont TLS
-                 * message, but it can only work with what we gave it. If we give it buffers
-                 * that fit what it wants to assemble already, its work is much easier.
-                 *
-                 * We can read file buckets in large chunks than APR_BUCKET_BUFF_SIZE,
-                 * with a bit of knowledge about how they work.
-                 */
-                apr_bucket_file *f = (apr_bucket_file *)b->data;
-                apr_file_t *fd = f->fd;
-                apr_off_t offset = b->start;
-
-                dlen = b->length;
-                rv = apr_file_seek(fd, APR_SET, &offset);
-                if (APR_SUCCESS != rv) goto cleanup;
-                rv = apr_file_read(fd, (void*)lbuf, &dlen);
-                if (APR_SUCCESS != rv && !APR_STATUS_IS_EOF(rv)) goto cleanup;
-                rv = fout_pass_buf_to_rustls(fctx, lbuf, dlen);
-                if (APR_SUCCESS != rv) goto cleanup;
-                apr_bucket_delete(b);
-            }
-            else {
-                rv = apr_bucket_read(b, &data, &dlen, APR_BLOCK_READ);
-                if (APR_SUCCESS != rv) goto cleanup;
-                rv = fout_pass_buf_to_rustls(fctx, data, dlen);
-                if (APR_SUCCESS != rv) goto cleanup;
-                apr_bucket_delete(b);
-            }
-        }
-    }
-
-maybe_flush:
-    if (flush) {
-        rv = fout_pass_all_to_net(fctx, 1);
-        if (APR_SUCCESS != rv) goto cleanup;
-    }
-
-cleanup:
-    if (lbuf) free((void*)lbuf);
-    if (rr != RUSTLS_RESULT_OK) {
-        const char *err_descr = "";
-        rv = tls_core_error(fctx->c, rr, &err_descr);
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, fctx->c, APLOGNO(10359)
-                     "write_bucket_to_rustls: [%d] %s", (int)rr, err_descr);
-    }
-    return rv;
-}
-
-/**
- * The connection filter converting plain, unencrypted traffic data into TLS
- * encrypted bytes and send the down the Apache filter chain out to the network.
- *
- * <bb>    the data to send, including "meta data" such as FLUSH indicators
- *         to force filters to write any data set aside (an apache term for
- *         'buffering').
- *         The buckets in <bb> need to be completely consumed, e.g. <bb> will be
- *         empty on a successful return. but unless FLUSHed, filters may hold
- *         buckets back internally, for various reasons. However they always
- *         need to be processed in the order they arrive.
- */
-static apr_status_t filter_conn_output(
-    ap_filter_t *f, apr_bucket_brigade *bb)
-{
-    tls_filter_ctx_t *fctx = f->ctx;
-    apr_status_t rv = APR_SUCCESS;
-    rustls_result rr = RUSTLS_RESULT_OK;
-
-    if (f->c->aborted) {
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, fctx->c,
-            "tls_filter_conn_output: aborted conn");
-        apr_brigade_cleanup(bb);
-        rv = APR_ECONNABORTED; goto  cleanup;
-    }
-
-    rv = progress_tls_atleast_to(fctx, TLS_CONN_ST_TRAFFIC);
-    if (APR_SUCCESS != rv) goto cleanup; /* this also leaves on APR_EAGAIN */
-
-    if (fctx->cc->state == TLS_CONN_ST_DONE) {
-        /* have done everything, just pass through */
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, fctx->c,
-            "tls_filter_conn_output: tls session is already done");
-        rv = ap_pass_brigade(f->next, bb);
-        goto cleanup;
-    }
-
-    ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, fctx->cc->server,
-        "tls_filter_conn_output, server=%s", fctx->cc->server->server_hostname);
-    if (APLOGctrace5(fctx->c)) {
-        tls_util_bb_log(fctx->c, APLOG_TRACE5, "filter_conn_output", bb);
-    }
-
-    while (!APR_BRIGADE_EMPTY(bb)) {
-        rv = fout_append_plain(fctx, APR_BRIGADE_FIRST(bb));
-        if (APR_SUCCESS != rv) goto cleanup;
-    }
-
-    if (APLOGctrace5(fctx->c)) {
-        tls_util_bb_log(fctx->c, APLOG_TRACE5, "filter_conn_output, processed plain", bb);
-        tls_util_bb_log(fctx->c, APLOG_TRACE5, "filter_conn_output, tls", fctx->fout_tls_bb);
-    }
-
-cleanup:
-    if (rr != RUSTLS_RESULT_OK) {
-        const char *err_descr = "";
-        rv = tls_core_error(fctx->c, rr, &err_descr);
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, fctx->c, APLOGNO(10360)
-                     "tls_filter_conn_output: [%d] %s", (int)rr, err_descr);
-    }
-    else {
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, fctx->c,
-                     "tls_filter_conn_output: done");
-    }
-    return rv;
-}
-
-int tls_filter_pre_conn_init(conn_rec *c)
-{
-    tls_conf_conn_t *cc;
-    tls_filter_ctx_t *fctx;
-
-    if (OK != tls_core_pre_conn_init(c)) {
-        return DECLINED;
-    }
-
-    ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, c->base_server,
-        "tls_filter_pre_conn_init on %s", c->base_server->server_hostname);
-
-    cc = tls_conf_conn_get(c);
-    ap_assert(cc);
-
-    fctx = apr_pcalloc(c->pool, sizeof(*fctx));
-    fctx->c = c;
-    fctx->cc = cc;
-    cc->filter_ctx = fctx;
-
-    /* a bit tricky: registering out filters returns the ap_filter_t*
-     * that it created for it. The ->next field points always
-     * to the filter "below" our filter. That will be other registered
-     * filters and last, but not least, the network filter on the socket.
-     *
-     * Therefore, wenn we need to read/write TLS data during handshake, we can
-     * pass the data to/call on ->next- Since ->next can change during the setup of
-     * a connections (other modules register also sth.), we keep the ap_filter_t*
-     * returned here, since httpd core will update the ->next whenever someone
-     * adds a filter or removes one. This can potentially happen all the time.
-     */
-    fctx->fin_ctx = ap_add_input_filter(TLS_FILTER_RAW, fctx, NULL, c);
-    fctx->fin_tls_bb = apr_brigade_create(c->pool, c->bucket_alloc);
-    fctx->fin_tls_buffer_bb = NULL;
-    fctx->fin_plain_bb = apr_brigade_create(c->pool, c->bucket_alloc);
-    fctx->fout_ctx = ap_add_output_filter(TLS_FILTER_RAW, fctx, NULL, c);
-    fctx->fout_tls_bb = apr_brigade_create(c->pool, c->bucket_alloc);
-    fctx->fout_buf_plain_size = APR_BUCKET_BUFF_SIZE;
-    fctx->fout_buf_plain = apr_pcalloc(c->pool, fctx->fout_buf_plain_size);
-    fctx->fout_buf_plain_len = 0;
-
-    /* Let the filters have 2 max-length TLS Messages in the rustls buffers.
-     * The effects we would like to achieve here are:
-     * 1. pass data out, so that every bucket becomes its own TLS message.
-     *    This hides, if possible, the length of response parts.
-     *    If we give rustls enough plain data, it will use the max TLS message
-     *    size and things are more hidden. But we can only write what the application
-     *    or protocol gives us.
-     * 2. max length records result in less overhead for all layers involved.
-     * 3. a TLS message from the client can only be decrypted when it has
-     *    completely arrived. If we provide rustls with enough data (if the
-     *    network has it for us), it should always be able to decrypt at least
-     *    one TLS message and we have plain bytes to forward to the protocol
-     *    handler.
-     */
-    fctx->fin_max_in_rustls = 4 * TLS_REC_MAX_SIZE;
-    fctx->fout_max_in_rustls = 4 * TLS_PREF_PLAIN_CHUNK_SIZE;
-    fctx->fout_auto_flush_size = 2 * TLS_REC_MAX_SIZE;
-
-    return OK;
-}
-
-void tls_filter_conn_init(conn_rec *c)
-{
-    tls_conf_conn_t *cc = tls_conf_conn_get(c);
-
-    if (cc && cc->filter_ctx && !cc->outgoing) {
-        /* We are one in a row of hooks that - possibly - want to process this
-         * connection, the (HTTP) protocol handlers among them.
-         *
-         * For incoming connections, we need to select the protocol to use NOW,
-         * so that the later protocol handlers do the right thing.
-         * Send an INIT down the input filter chain to trigger the TLS handshake,
-         * which will select a protocol via ALPN. */
-        apr_bucket_brigade* temp;
-
-        ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, c->base_server,
-            "tls_filter_conn_init on %s, triggering handshake", c->base_server->server_hostname);
-        temp = apr_brigade_create(c->pool, c->bucket_alloc);
-        ap_get_brigade(c->input_filters, temp, AP_MODE_INIT, APR_BLOCK_READ, 0);
-        apr_brigade_destroy(temp);
-    }
-}
-
-void tls_filter_register(
-    apr_pool_t *pool)
-{
-    (void)pool;
-    ap_register_input_filter(TLS_FILTER_RAW, filter_conn_input,  NULL, AP_FTYPE_CONNECTION + 5);
-    ap_register_output_filter(TLS_FILTER_RAW, filter_conn_output, NULL, AP_FTYPE_CONNECTION + 5);
-}
diff --git a/modules/tls/tls_filter.h b/modules/tls/tls_filter.h
deleted file mode 100644 (file)
index 4f3d38b..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef tls_filter_h
-#define tls_filter_h
-
-#define TLS_FILTER_RAW    "TLS raw"
-
-typedef struct tls_filter_ctx_t tls_filter_ctx_t;
-
-struct tls_filter_ctx_t {
-    conn_rec *c;                         /* connection this context is for */
-    tls_conf_conn_t *cc;                 /* tls module configuration of connection */
-
-    ap_filter_t *fin_ctx;                /* Apache's entry into the input filter chain */
-    apr_bucket_brigade *fin_tls_bb;      /* TLS encrypted, incoming network data */
-    apr_bucket_brigade *fin_tls_buffer_bb; /* TLS encrypted, incoming network data buffering */
-    apr_bucket_brigade *fin_plain_bb;    /* decrypted, incoming traffic data */
-    apr_off_t fin_bytes_in_rustls;       /* # of input TLS bytes in rustls_connection */
-    apr_read_type_e fin_block;           /* Do we block on input reads or not? */
-
-    ap_filter_t *fout_ctx;               /* Apache's entry into the output filter chain */
-    char *fout_buf_plain;                /* a buffer to collect plain bytes for output */
-    apr_size_t fout_buf_plain_len;       /* the amount of bytes in the buffer */
-    apr_size_t fout_buf_plain_size;      /* the total size of the buffer */
-    apr_bucket_brigade *fout_tls_bb;     /* TLS encrypted, outgoing network data */
-    apr_off_t fout_bytes_in_rustls;      /* # of output plain bytes in rustls_connection */
-    apr_off_t fout_bytes_in_tls_bb;      /* # of output tls bytes in our brigade */
-
-    apr_size_t fin_max_in_rustls;         /* how much tls we like to read into rustls */
-    apr_size_t fout_max_in_rustls;        /* how much plain bytes we like in rustls */
-    apr_size_t fout_max_bucket_size;      /* how large bucket chunks we handle before splitting */
-    apr_size_t fout_auto_flush_size;      /* on much outoing TLS data we flush to network */
-};
-
-/**
- * Register the in-/output filters for converting TLS to application data and vice versa.
- */
-void tls_filter_register(apr_pool_t *pool);
-
-/**
- * Initialize the pre_connection state. Install all filters.
- *
- * @return OK if TLS on connection is enabled, DECLINED otherwise
- */
-int tls_filter_pre_conn_init(conn_rec *c);
-
-/**
- * Initialize the connection for use, perform the TLS handshake.
- *
- * Any failure will lead to the connection becoming aborted.
- */
-void tls_filter_conn_init(conn_rec *c);
-
-/*
- * <https://tools.ietf.org/html/rfc8449> says:
- * "For large data transfers, small record sizes can materially affect performance."
- * and
- * "For TLS 1.2 and earlier, that limit is 2^14 octets. TLS 1.3 uses a limit of
- * 2^14+1 octets."
- * Maybe future TLS versions will raise that value, but for now these limits stand.
- * Given the choice, we would like rustls to provide traffic data in those chunks.
- */
-#define TLS_PREF_PLAIN_CHUNK_SIZE       (16384)
-
-/*
- * When retrieving TLS chunks for rustls, or providing it a buffer
- * to pass out TLS chunks (which are then bucketed and written to the
- * network filters), we ideally would do that in multiples of TLS
- * messages sizes.
- * That would be TLS_PREF_WRITE_SIZE + TLS Message Overhead, such as
- * MAC and padding. But these vary with protocol and ciphers chosen, so
- * we define something which should be "large enough", but not overly so.
- */
-#define TLS_REC_EXTRA             (1024)
-#define TLS_REC_MAX_SIZE   (TLS_PREF_PLAIN_CHUNK_SIZE + TLS_REC_EXTRA)
-
-#endif /* tls_filter_h */
\ No newline at end of file
diff --git a/modules/tls/tls_ocsp.c b/modules/tls/tls_ocsp.c
deleted file mode 100644 (file)
index 37e95b1..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <assert.h>
-#include <apr_lib.h>
-#include <apr_strings.h>
-
-#include <httpd.h>
-#include <http_connection.h>
-#include <http_core.h>
-#include <http_log.h>
-#include <http_ssl.h>
-
-#include <rustls.h>
-
-#include "tls_cert.h"
-#include "tls_conf.h"
-#include "tls_core.h"
-#include "tls_proto.h"
-#include "tls_ocsp.h"
-
-extern module AP_MODULE_DECLARE_DATA tls_module;
-APLOG_USE_MODULE(tls);
-
-
-static int prime_cert(
-    void *userdata, server_rec *s, const char *cert_id, const char *cert_pem,
-    const rustls_certified_key *certified_key)
-{
-    apr_pool_t *p = userdata;
-    apr_status_t rv;
-
-    (void)certified_key;
-    rv = ap_ssl_ocsp_prime(s, p, cert_id, strlen(cert_id), cert_pem);
-    ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, s, "ocsp prime of cert [%s] from %s",
-                 cert_id, s->server_hostname);
-    return 1;
-}
-
-apr_status_t tls_ocsp_prime_certs(tls_conf_global_t *gc, apr_pool_t *p, server_rec *s)
-{
-    ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "ocsp priming of %d certs",
-                 (int)tls_cert_reg_count(gc->cert_reg));
-    tls_cert_reg_do(prime_cert, p, gc->cert_reg);
-    return APR_SUCCESS;
-}
-
-typedef struct {
-    conn_rec *c;
-    const rustls_certified_key *key_in;
-    const rustls_certified_key *key_out;
-} ocsp_copy_ctx_t;
-
-static void ocsp_clone_key(const unsigned char *der, apr_size_t der_len, void *userdata)
-{
-    ocsp_copy_ctx_t *ctx = userdata;
-    rustls_slice_bytes rslice;
-    rustls_result rr;
-
-    rslice.data = der;
-    rslice.len = der_len;
-
-    rr = rustls_certified_key_clone_with_ocsp(ctx->key_in, der_len? &rslice : NULL, &ctx->key_out);
-    if (RUSTLS_RESULT_OK != rr) {
-        const char *err_descr = NULL;
-        apr_status_t rv = tls_util_rustls_error(ctx->c->pool, rr, &err_descr);
-        ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, ctx->c, APLOGNO(10362)
-                     "Failed add OCSP data to certificate: [%d] %s", (int)rr, err_descr);
-    }
-    else {
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->c,
-            "provided %ld bytes of ocsp response DER data to key.", (long)der_len);
-    }
-}
-
-apr_status_t tls_ocsp_update_key(
-    conn_rec *c, const rustls_certified_key *certified_key,
-    const rustls_certified_key **pkey_out)
-{
-    tls_conf_conn_t *cc = tls_conf_conn_get(c);
-    tls_conf_server_t *sc;
-    const char *key_id;
-    apr_status_t rv = APR_SUCCESS;
-    ocsp_copy_ctx_t ctx;
-
-    assert(cc);
-    assert(cc->server);
-    sc = tls_conf_server_get(cc->server);
-    key_id = tls_cert_reg_get_id(sc->global->cert_reg, certified_key);
-    if (!key_id) {
-        rv = APR_ENOENT;
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c, "certified key not registered");
-        goto cleanup;
-    }
-
-    ctx.c = c;
-    ctx.key_in = certified_key;
-    ctx.key_out = NULL;
-    rv = ap_ssl_ocsp_get_resp(cc->server, c, key_id, strlen(key_id), ocsp_clone_key, &ctx);
-    if (APR_SUCCESS != rv) {
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
-            "ocsp response not available for cert %s", key_id);
-    }
-
-cleanup:
-    *pkey_out = (APR_SUCCESS == rv)? ctx.key_out : NULL;
-    return rv;
-}
diff --git a/modules/tls/tls_ocsp.h b/modules/tls/tls_ocsp.h
deleted file mode 100644 (file)
index 60770a9..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef tls_ocsp_h
-#define tls_ocsp_h
-
-/**
- * Prime the collected certified keys for OCSP response provisioning (aka. Stapling).
- *
- * To be called in the post-config phase of the server before connections are handled.
- * @param gc the global module configuration with the certified_key registry
- * @param p the pool to use for allocations
- * @param s the base server record
- */
-apr_status_t tls_ocsp_prime_certs(tls_conf_global_t *gc, apr_pool_t *p, server_rec *s);
-
-/**
- * Provide the OCSP response data for the certified_key into the offered buffer,
- * so available.
- * If not data is available `out_n` is set to 0. Same, if the offered buffer
- * is not large enough to hold the complete response.
- * If OCSP response DER data is copied, the number of copied bytes is given in `out_n`.
- *
- * Note that only keys that have been primed initially will have OCSP data available.
- * @param c the current connection
- * @param certified_key the key to get the OCSP response data for
- * @param buf a buffer which can hold up to `buf_len` bytes
- * @param buf_len the length of `buf`
- * @param out_n the number of OCSP response DER bytes copied or 0.
- */
-apr_status_t tls_ocsp_update_key(
-    conn_rec *c, const rustls_certified_key *certified_key,
-    const rustls_certified_key **key_out);
-
-#endif /* tls_ocsp_h */
diff --git a/modules/tls/tls_proto.c b/modules/tls/tls_proto.c
deleted file mode 100644 (file)
index 95a903b..0000000
+++ /dev/null
@@ -1,603 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <assert.h>
-#include <apr_lib.h>
-#include <apr_strings.h>
-
-#include <httpd.h>
-#include <http_connection.h>
-#include <http_core.h>
-#include <http_log.h>
-
-#include <rustls.h>
-
-#include "tls_proto.h"
-#include "tls_conf.h"
-#include "tls_util.h"
-
-extern module AP_MODULE_DECLARE_DATA tls_module;
-APLOG_USE_MODULE(tls);
-
-
-
-/**
- * Known cipher as registered in
- * <https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4>
- */
-static tls_cipher_t KNOWN_CIPHERS[] = {
-    { 0x0000, "TLS_NULL_WITH_NULL_NULL", NULL },
-    { 0x0001, "TLS_RSA_WITH_NULL_MD5", NULL },
-    { 0x0002, "TLS_RSA_WITH_NULL_SHA", NULL },
-    { 0x0003, "TLS_RSA_EXPORT_WITH_RC4_40_MD5", NULL },
-    { 0x0004, "TLS_RSA_WITH_RC4_128_MD5", NULL },
-    { 0x0005, "TLS_RSA_WITH_RC4_128_SHA", NULL },
-    { 0x0006, "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5", NULL },
-    { 0x0007, "TLS_RSA_WITH_IDEA_CBC_SHA", NULL },
-    { 0x0008, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA", NULL },
-    { 0x0009, "TLS_RSA_WITH_DES_CBC_SHA", NULL },
-    { 0x000a, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0x000b, "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", NULL },
-    { 0x000c, "TLS_DH_DSS_WITH_DES_CBC_SHA", NULL },
-    { 0x000d, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0x000e, "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", NULL },
-    { 0x000f, "TLS_DH_RSA_WITH_DES_CBC_SHA", NULL },
-    { 0x0010, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0x0011, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", NULL },
-    { 0x0012, "TLS_DHE_DSS_WITH_DES_CBC_SHA", NULL },
-    { 0x0013, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0x0014, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", NULL },
-    { 0x0015, "TLS_DHE_RSA_WITH_DES_CBC_SHA", NULL },
-    { 0x0016, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0x0017, "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5", NULL },
-    { 0x0018, "TLS_DH_anon_WITH_RC4_128_MD5", NULL },
-    { 0x0019, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA", NULL },
-    { 0x001a, "TLS_DH_anon_WITH_DES_CBC_SHA", NULL },
-    { 0x001b, "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0x001c, "SSL_FORTEZZA_KEA_WITH_NULL_SHA", NULL },
-    { 0x001d, "SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA", NULL },
-    { 0x001e, "TLS_KRB5_WITH_DES_CBC_SHA_or_SSL_FORTEZZA_KEA_WITH_RC4_128_SHA", NULL },
-    { 0x001f, "TLS_KRB5_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0x0020, "TLS_KRB5_WITH_RC4_128_SHA", NULL },
-    { 0x0021, "TLS_KRB5_WITH_IDEA_CBC_SHA", NULL },
-    { 0x0022, "TLS_KRB5_WITH_DES_CBC_MD5", NULL },
-    { 0x0023, "TLS_KRB5_WITH_3DES_EDE_CBC_MD5", NULL },
-    { 0x0024, "TLS_KRB5_WITH_RC4_128_MD5", NULL },
-    { 0x0025, "TLS_KRB5_WITH_IDEA_CBC_MD5", NULL },
-    { 0x0026, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", NULL },
-    { 0x0027, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", NULL },
-    { 0x0028, "TLS_KRB5_EXPORT_WITH_RC4_40_SHA", NULL },
-    { 0x0029, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", NULL },
-    { 0x002a, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", NULL },
-    { 0x002b, "TLS_KRB5_EXPORT_WITH_RC4_40_MD5", NULL },
-    { 0x002c, "TLS_PSK_WITH_NULL_SHA", NULL },
-    { 0x002d, "TLS_DHE_PSK_WITH_NULL_SHA", NULL },
-    { 0x002e, "TLS_RSA_PSK_WITH_NULL_SHA", NULL },
-    { 0x002f, "TLS_RSA_WITH_AES_128_CBC_SHA", NULL },
-    { 0x0030, "TLS_DH_DSS_WITH_AES_128_CBC_SHA", NULL },
-    { 0x0031, "TLS_DH_RSA_WITH_AES_128_CBC_SHA", NULL },
-    { 0x0032, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", NULL },
-    { 0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", NULL },
-    { 0x0034, "TLS_DH_anon_WITH_AES_128_CBC_SHA", NULL },
-    { 0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA", NULL },
-    { 0x0036, "TLS_DH_DSS_WITH_AES_256_CBC_SHA", NULL },
-    { 0x0037, "TLS_DH_RSA_WITH_AES_256_CBC_SHA", NULL },
-    { 0x0038, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", NULL },
-    { 0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", NULL },
-    { 0x003a, "TLS_DH_anon_WITH_AES_256_CBC_SHA", NULL },
-    { 0x003b, "TLS_RSA_WITH_NULL_SHA256", "NULL-SHA256" },
-    { 0x003c, "TLS_RSA_WITH_AES_128_CBC_SHA256", "AES128-SHA256" },
-    { 0x003d, "TLS_RSA_WITH_AES_256_CBC_SHA256", "AES256-SHA256" },
-    { 0x003e, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256", "DH-DSS-AES128-SHA256" },
-    { 0x003f, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256", "DH-RSA-AES128-SHA256" },
-    { 0x0040, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", "DHE-DSS-AES128-SHA256" },
-    { 0x0041, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", NULL },
-    { 0x0042, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", NULL },
-    { 0x0043, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", NULL },
-    { 0x0044, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", NULL },
-    { 0x0045, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", NULL },
-    { 0x0046, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA", NULL },
-    { 0x0047, "TLS_ECDH_ECDSA_WITH_NULL_SHA_draft", NULL },
-    { 0x0048, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA_draft", NULL },
-    { 0x0049, "TLS_ECDH_ECDSA_WITH_DES_CBC_SHA_draft", NULL },
-    { 0x004a, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA_draft", NULL },
-    { 0x004b, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA_draft", NULL },
-    { 0x004c, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA_draft", NULL },
-    { 0x004d, "TLS_ECDH_ECNRA_WITH_DES_CBC_SHA_draft", NULL },
-    { 0x004e, "TLS_ECDH_ECNRA_WITH_3DES_EDE_CBC_SHA_draft", NULL },
-    { 0x004f, "TLS_ECMQV_ECDSA_NULL_SHA_draft", NULL },
-    { 0x0050, "TLS_ECMQV_ECDSA_WITH_RC4_128_SHA_draft", NULL },
-    { 0x0051, "TLS_ECMQV_ECDSA_WITH_DES_CBC_SHA_draft", NULL },
-    { 0x0052, "TLS_ECMQV_ECDSA_WITH_3DES_EDE_CBC_SHA_draft", NULL },
-    { 0x0053, "TLS_ECMQV_ECNRA_NULL_SHA_draft", NULL },
-    { 0x0054, "TLS_ECMQV_ECNRA_WITH_RC4_128_SHA_draft", NULL },
-    { 0x0055, "TLS_ECMQV_ECNRA_WITH_DES_CBC_SHA_draft", NULL },
-    { 0x0056, "TLS_ECMQV_ECNRA_WITH_3DES_EDE_CBC_SHA_draft", NULL },
-    { 0x0057, "TLS_ECDH_anon_NULL_WITH_SHA_draft", NULL },
-    { 0x0058, "TLS_ECDH_anon_WITH_RC4_128_SHA_draft", NULL },
-    { 0x0059, "TLS_ECDH_anon_WITH_DES_CBC_SHA_draft", NULL },
-    { 0x005a, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA_draft", NULL },
-    { 0x005b, "TLS_ECDH_anon_EXPORT_WITH_DES40_CBC_SHA_draft", NULL },
-    { 0x005c, "TLS_ECDH_anon_EXPORT_WITH_RC4_40_SHA_draft", NULL },
-    { 0x0060, "TLS_RSA_EXPORT1024_WITH_RC4_56_MD5", NULL },
-    { 0x0061, "TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5", NULL },
-    { 0x0062, "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA", NULL },
-    { 0x0063, "TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA", NULL },
-    { 0x0064, "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA", NULL },
-    { 0x0065, "TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA", NULL },
-    { 0x0066, "TLS_DHE_DSS_WITH_RC4_128_SHA", NULL },
-    { 0x0067, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", "DHE-RSA-AES128-SHA256" },
-    { 0x0068, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256", "DH-DSS-AES256-SHA256" },
-    { 0x0069, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256", "DH-RSA-AES256-SHA256" },
-    { 0x006a, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", "DHE-DSS-AES256-SHA256" },
-    { 0x006b, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "DHE-RSA-AES256-SHA256" },
-    { 0x006c, "TLS_DH_anon_WITH_AES_128_CBC_SHA256", "ADH-AES128-SHA256" },
-    { 0x006d, "TLS_DH_anon_WITH_AES_256_CBC_SHA256", "ADH-AES256-SHA256" },
-    { 0x0072, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD", NULL },
-    { 0x0073, "TLS_DHE_DSS_WITH_AES_128_CBC_RMD", NULL },
-    { 0x0074, "TLS_DHE_DSS_WITH_AES_256_CBC_RMD", NULL },
-    { 0x0077, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD", NULL },
-    { 0x0078, "TLS_DHE_RSA_WITH_AES_128_CBC_RMD", NULL },
-    { 0x0079, "TLS_DHE_RSA_WITH_AES_256_CBC_RMD", NULL },
-    { 0x007c, "TLS_RSA_WITH_3DES_EDE_CBC_RMD", NULL },
-    { 0x007d, "TLS_RSA_WITH_AES_128_CBC_RMD", NULL },
-    { 0x007e, "TLS_RSA_WITH_AES_256_CBC_RMD", NULL },
-    { 0x0080, "TLS_GOSTR341094_WITH_28147_CNT_IMIT", NULL },
-    { 0x0081, "TLS_GOSTR341001_WITH_28147_CNT_IMIT", NULL },
-    { 0x0082, "TLS_GOSTR341094_WITH_NULL_GOSTR3411", NULL },
-    { 0x0083, "TLS_GOSTR341001_WITH_NULL_GOSTR3411", NULL },
-    { 0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", NULL },
-    { 0x0085, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", NULL },
-    { 0x0086, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", NULL },
-    { 0x0087, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", NULL },
-    { 0x0088, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", NULL },
-    { 0x0089, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA", NULL },
-    { 0x008a, "TLS_PSK_WITH_RC4_128_SHA", "PSK-RC4-SHA" },
-    { 0x008b, "TLS_PSK_WITH_3DES_EDE_CBC_SHA", "PSK-3DES-EDE-CBC-SHA" },
-    { 0x008c, "TLS_PSK_WITH_AES_128_CBC_SHA", NULL },
-    { 0x008d, "TLS_PSK_WITH_AES_256_CBC_SHA", NULL },
-    { 0x008e, "TLS_DHE_PSK_WITH_RC4_128_SHA", NULL },
-    { 0x008f, "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA", NULL },
-    { 0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA", NULL },
-    { 0x0092, "TLS_RSA_PSK_WITH_RC4_128_SHA", NULL },
-    { 0x0093, "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA", NULL },
-    { 0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA", NULL },
-    { 0x0096, "TLS_RSA_WITH_SEED_CBC_SHA", NULL },
-    { 0x0097, "TLS_DH_DSS_WITH_SEED_CBC_SHA", NULL },
-    { 0x0098, "TLS_DH_RSA_WITH_SEED_CBC_SHA", NULL },
-    { 0x0099, "TLS_DHE_DSS_WITH_SEED_CBC_SHA", NULL },
-    { 0x009a, "TLS_DHE_RSA_WITH_SEED_CBC_SHA", NULL },
-    { 0x009b, "TLS_DH_anon_WITH_SEED_CBC_SHA", NULL },
-    { 0x009c, "TLS_RSA_WITH_AES_128_GCM_SHA256", "AES128-GCM-SHA256" },
-    { 0x009d, "TLS_RSA_WITH_AES_256_GCM_SHA384", "AES256-GCM-SHA384" },
-    { 0x009e, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "DHE-RSA-AES128-GCM-SHA256" },
-    { 0x009f, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "DHE-RSA-AES256-GCM-SHA384" },
-    { 0x00a0, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256", "DH-RSA-AES128-GCM-SHA256" },
-    { 0x00a1, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384", "DH-RSA-AES256-GCM-SHA384" },
-    { 0x00a2, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", "DHE-DSS-AES128-GCM-SHA256" },
-    { 0x00a3, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", "DHE-DSS-AES256-GCM-SHA384" },
-    { 0x00a4, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256", "DH-DSS-AES128-GCM-SHA256" },
-    { 0x00a5, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384", "DH-DSS-AES256-GCM-SHA384" },
-    { 0x00a6, "TLS_DH_anon_WITH_AES_128_GCM_SHA256", "ADH-AES128-GCM-SHA256" },
-    { 0x00a7, "TLS_DH_anon_WITH_AES_256_GCM_SHA384", "ADH-AES256-GCM-SHA384" },
-    { 0x00a8, "TLS_PSK_WITH_AES_128_GCM_SHA256", NULL },
-    { 0x00a9, "TLS_PSK_WITH_AES_256_GCM_SHA384", NULL },
-    { 0x00aa, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", NULL },
-    { 0x00ab, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", NULL },
-    { 0x00ac, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", NULL },
-    { 0x00ad, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", NULL },
-    { 0x00ae, "TLS_PSK_WITH_AES_128_CBC_SHA256", "PSK-AES128-CBC-SHA" },
-    { 0x00af, "TLS_PSK_WITH_AES_256_CBC_SHA384", "PSK-AES256-CBC-SHA" },
-    { 0x00b0, "TLS_PSK_WITH_NULL_SHA256", NULL },
-    { 0x00b1, "TLS_PSK_WITH_NULL_SHA384", NULL },
-    { 0x00b2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", NULL },
-    { 0x00b3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", NULL },
-    { 0x00b4, "TLS_DHE_PSK_WITH_NULL_SHA256", NULL },
-    { 0x00b5, "TLS_DHE_PSK_WITH_NULL_SHA384", NULL },
-    { 0x00b6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", NULL },
-    { 0x00b7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", NULL },
-    { 0x00b8, "TLS_RSA_PSK_WITH_NULL_SHA256", NULL },
-    { 0x00b9, "TLS_RSA_PSK_WITH_NULL_SHA384", NULL },
-    { 0x00ba, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", NULL },
-    { 0x00bb, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256", NULL },
-    { 0x00bc, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256", NULL },
-    { 0x00bd, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", NULL },
-    { 0x00be, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", NULL },
-    { 0x00bf, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256", NULL },
-    { 0x00c0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", NULL },
-    { 0x00c1, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256", NULL },
-    { 0x00c2, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256", NULL },
-    { 0x00c3, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", NULL },
-    { 0x00c4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", NULL },
-    { 0x00c5, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256", NULL },
-    { 0x00ff, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV", NULL },
-    { 0x1301, "TLS_AES_128_GCM_SHA256", "TLS13_AES_128_GCM_SHA256" },
-    { 0x1302, "TLS_AES_256_GCM_SHA384", "TLS13_AES_256_GCM_SHA384" },
-    { 0x1303, "TLS_CHACHA20_POLY1305_SHA256", "TLS13_CHACHA20_POLY1305_SHA256" },
-    { 0x1304, "TLS_AES_128_CCM_SHA256", "TLS13_AES_128_CCM_SHA256" },
-    { 0x1305, "TLS_AES_128_CCM_8_SHA256", "TLS13_AES_128_CCM_8_SHA256" },
-    { 0xc001, "TLS_ECDH_ECDSA_WITH_NULL_SHA", NULL },
-    { 0xc002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA", NULL },
-    { 0xc003, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0xc004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", NULL },
-    { 0xc005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", NULL },
-    { 0xc006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA", NULL },
-    { 0xc007, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", NULL },
-    { 0xc008, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0xc009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", NULL },
-    { 0xc00a, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", NULL },
-    { 0xc00b, "TLS_ECDH_RSA_WITH_NULL_SHA", NULL },
-    { 0xc00c, "TLS_ECDH_RSA_WITH_RC4_128_SHA", NULL },
-    { 0xc00d, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0xc00e, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", NULL },
-    { 0xc00f, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", NULL },
-    { 0xc010, "TLS_ECDHE_RSA_WITH_NULL_SHA", NULL },
-    { 0xc011, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", NULL },
-    { 0xc012, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0xc013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", NULL },
-    { 0xc014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", NULL },
-    { 0xc015, "TLS_ECDH_anon_WITH_NULL_SHA", NULL },
-    { 0xc016, "TLS_ECDH_anon_WITH_RC4_128_SHA", NULL },
-    { 0xc017, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0xc018, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA", NULL },
-    { 0xc019, "TLS_ECDH_anon_WITH_AES_256_CBC_SHA", NULL },
-    { 0xc01a, "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0xc01b, "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0xc01c, "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0xc01d, "TLS_SRP_SHA_WITH_AES_128_CBC_SHA", NULL },
-    { 0xc01e, "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", NULL },
-    { 0xc01f, "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", NULL },
-    { 0xc020, "TLS_SRP_SHA_WITH_AES_256_CBC_SHA", NULL },
-    { 0xc021, "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", NULL },
-    { 0xc022, "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", NULL },
-    { 0xc023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "ECDHE-ECDSA-AES128-SHA256" },
-    { 0xc024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "ECDHE-ECDSA-AES256-SHA384" },
-    { 0xc025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", "ECDH-ECDSA-AES128-SHA256" },
-    { 0xc026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", "ECDH-ECDSA-AES256-SHA384" },
-    { 0xc027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "ECDHE-RSA-AES128-SHA256" },
-    { 0xc028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "ECDHE-RSA-AES256-SHA384" },
-    { 0xc029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", "ECDH-RSA-AES128-SHA256" },
-    { 0xc02a, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", "ECDH-RSA-AES256-SHA384" },
-    { 0xc02b, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "ECDHE-ECDSA-AES128-GCM-SHA256" },
-    { 0xc02c, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "ECDHE-ECDSA-AES256-GCM-SHA384" },
-    { 0xc02d, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", "ECDH-ECDSA-AES128-GCM-SHA256" },
-    { 0xc02e, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", "ECDH-ECDSA-AES256-GCM-SHA384" },
-    { 0xc02f, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "ECDHE-RSA-AES128-GCM-SHA256" },
-    { 0xc030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "ECDHE-RSA-AES256-GCM-SHA384" },
-    { 0xc031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", "ECDH-RSA-AES128-GCM-SHA256" },
-    { 0xc032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", "ECDH-RSA-AES256-GCM-SHA384" },
-    { 0xc033, "TLS_ECDHE_PSK_WITH_RC4_128_SHA", NULL },
-    { 0xc034, "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", NULL },
-    { 0xc035, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", NULL },
-    { 0xc036, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", NULL },
-    { 0xc037, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", NULL },
-    { 0xc038, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", NULL },
-    { 0xc039, "TLS_ECDHE_PSK_WITH_NULL_SHA", NULL },
-    { 0xc03a, "TLS_ECDHE_PSK_WITH_NULL_SHA256", NULL },
-    { 0xc03b, "TLS_ECDHE_PSK_WITH_NULL_SHA384", NULL },
-    { 0xc03c, "TLS_RSA_WITH_ARIA_128_CBC_SHA256", NULL },
-    { 0xc03d, "TLS_RSA_WITH_ARIA_256_CBC_SHA384", NULL },
-    { 0xc03e, "TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256", NULL },
-    { 0xc03f, "TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384", NULL },
-    { 0xc040, "TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256", NULL },
-    { 0xc041, "TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384", NULL },
-    { 0xc042, "TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256", NULL },
-    { 0xc043, "TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384", NULL },
-    { 0xc044, "TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256", NULL },
-    { 0xc045, "TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384", NULL },
-    { 0xc046, "TLS_DH_anon_WITH_ARIA_128_CBC_SHA256", NULL },
-    { 0xc047, "TLS_DH_anon_WITH_ARIA_256_CBC_SHA384", NULL },
-    { 0xc048, "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256", NULL },
-    { 0xc049, "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384", NULL },
-    { 0xc04a, "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256", NULL },
-    { 0xc04b, "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384", NULL },
-    { 0xc04c, "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256", NULL },
-    { 0xc04d, "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384", NULL },
-    { 0xc04e, "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256", NULL },
-    { 0xc04f, "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384", NULL },
-    { 0xc050, "TLS_RSA_WITH_ARIA_128_GCM_SHA256", NULL },
-    { 0xc051, "TLS_RSA_WITH_ARIA_256_GCM_SHA384", NULL },
-    { 0xc052, "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256", NULL },
-    { 0xc053, "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384", NULL },
-    { 0xc054, "TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256", NULL },
-    { 0xc055, "TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384", NULL },
-    { 0xc056, "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256", NULL },
-    { 0xc057, "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384", NULL },
-    { 0xc058, "TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256", NULL },
-    { 0xc059, "TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384", NULL },
-    { 0xc05a, "TLS_DH_anon_WITH_ARIA_128_GCM_SHA256", NULL },
-    { 0xc05b, "TLS_DH_anon_WITH_ARIA_256_GCM_SHA384", NULL },
-    { 0xc05c, "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256", NULL },
-    { 0xc05d, "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384", NULL },
-    { 0xc05e, "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256", NULL },
-    { 0xc05f, "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384", NULL },
-    { 0xc060, "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256", NULL },
-    { 0xc061, "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384", NULL },
-    { 0xc062, "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256", NULL },
-    { 0xc063, "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384", NULL },
-    { 0xc064, "TLS_PSK_WITH_ARIA_128_CBC_SHA256", NULL },
-    { 0xc065, "TLS_PSK_WITH_ARIA_256_CBC_SHA384", NULL },
-    { 0xc066, "TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256", NULL },
-    { 0xc067, "TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384", NULL },
-    { 0xc068, "TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256", NULL },
-    { 0xc069, "TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384", NULL },
-    { 0xc06a, "TLS_PSK_WITH_ARIA_128_GCM_SHA256", NULL },
-    { 0xc06b, "TLS_PSK_WITH_ARIA_256_GCM_SHA384", NULL },
-    { 0xc06c, "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256", NULL },
-    { 0xc06d, "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384", NULL },
-    { 0xc06e, "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256", NULL },
-    { 0xc06f, "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384", NULL },
-    { 0xc070, "TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256", NULL },
-    { 0xc071, "TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384", NULL },
-    { 0xc072, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", NULL },
-    { 0xc073, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", NULL },
-    { 0xc074, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", NULL },
-    { 0xc075, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", NULL },
-    { 0xc076, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", NULL },
-    { 0xc077, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", NULL },
-    { 0xc078, "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256", NULL },
-    { 0xc079, "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384", NULL },
-    { 0xc07a, "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256", NULL },
-    { 0xc07b, "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384", NULL },
-    { 0xc07c, "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", NULL },
-    { 0xc07d, "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", NULL },
-    { 0xc07e, "TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256", NULL },
-    { 0xc07f, "TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384", NULL },
-    { 0xc080, "TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256", NULL },
-    { 0xc081, "TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384", NULL },
-    { 0xc082, "TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256", NULL },
-    { 0xc083, "TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384", NULL },
-    { 0xc084, "TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256", NULL },
-    { 0xc085, "TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384", NULL },
-    { 0xc086, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", NULL },
-    { 0xc087, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", NULL },
-    { 0xc088, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", NULL },
-    { 0xc089, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", NULL },
-    { 0xc08a, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", NULL },
-    { 0xc08b, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", NULL },
-    { 0xc08c, "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256", NULL },
-    { 0xc08d, "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384", NULL },
-    { 0xc08e, "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256", NULL },
-    { 0xc08f, "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384", NULL },
-    { 0xc090, "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256", NULL },
-    { 0xc091, "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384", NULL },
-    { 0xc092, "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256", NULL },
-    { 0xc093, "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384", NULL },
-    { 0xc094, "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256", NULL },
-    { 0xc095, "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384", NULL },
-    { 0xc096, "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", NULL },
-    { 0xc097, "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", NULL },
-    { 0xc098, "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256", NULL },
-    { 0xc099, "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384", NULL },
-    { 0xc09a, "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", NULL },
-    { 0xc09b, "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", NULL },
-    { 0xc09c, "TLS_RSA_WITH_AES_128_CCM", NULL },
-    { 0xc09d, "TLS_RSA_WITH_AES_256_CCM", NULL },
-    { 0xc09e, "TLS_DHE_RSA_WITH_AES_128_CCM", NULL },
-    { 0xc09f, "TLS_DHE_RSA_WITH_AES_256_CCM", NULL },
-    { 0xc0a0, "TLS_RSA_WITH_AES_128_CCM_8", NULL },
-    { 0xc0a1, "TLS_RSA_WITH_AES_256_CCM_8", NULL },
-    { 0xc0a2, "TLS_DHE_RSA_WITH_AES_128_CCM_8", NULL },
-    { 0xc0a3, "TLS_DHE_RSA_WITH_AES_256_CCM_8", NULL },
-    { 0xc0a4, "TLS_PSK_WITH_AES_128_CCM", NULL },
-    { 0xc0a5, "TLS_PSK_WITH_AES_256_CCM", NULL },
-    { 0xc0a6, "TLS_DHE_PSK_WITH_AES_128_CCM", NULL },
-    { 0xc0a7, "TLS_DHE_PSK_WITH_AES_256_CCM", NULL },
-    { 0xc0a8, "TLS_PSK_WITH_AES_128_CCM_8", NULL },
-    { 0xc0a9, "TLS_PSK_WITH_AES_256_CCM_8", NULL },
-    { 0xc0aa, "TLS_PSK_DHE_WITH_AES_128_CCM_8", NULL },
-    { 0xc0ab, "TLS_PSK_DHE_WITH_AES_256_CCM_8", NULL },
-    { 0xcca8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "ECDHE-RSA-CHACHA20-POLY1305" },
-    { 0xcca9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "ECDHE-ECDSA-CHACHA20-POLY1305" },
-    { 0xccaa, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "DHE-RSA-CHACHA20-POLY1305" },
-    { 0xccab, "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256", "PSK-CHACHA20-POLY1305" },
-    { 0xccac, "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", "ECDHE-PSK-CHACHA20-POLY1305" },
-    { 0xccad, "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", "DHE-PSK-CHACHA20-POLY1305" },
-    { 0xccae, "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", "RSA-PSK-CHACHA20-POLY1305" },
-    { 0xfefe, "SSL_RSA_FIPS_WITH_DES_CBC_SHA", NULL },
-    { 0xfeff, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", NULL },
-};
-
-typedef struct {
-    apr_uint16_t id;
-    const rustls_supported_ciphersuite *rustls_suite;
-} rustls_cipher_t;
-
-tls_proto_conf_t *tls_proto_init(apr_pool_t *pool, server_rec *s)
-{
-    tls_proto_conf_t *conf;
-    tls_cipher_t *cipher;
-    const rustls_supported_ciphersuite *rustls_suite;
-    rustls_cipher_t *rcipher;
-    apr_uint16_t id;
-    apr_size_t i;
-
-    (void)s;
-    conf = apr_pcalloc(pool, sizeof(*conf));
-
-    conf->supported_versions = apr_array_make(pool, 3, sizeof(apr_uint16_t));
-    /* Until we can look that up at crustls, we assume what we currently know */
-    APR_ARRAY_PUSH(conf->supported_versions, apr_uint16_t) = TLS_VERSION_1_2;
-    APR_ARRAY_PUSH(conf->supported_versions, apr_uint16_t) = TLS_VERSION_1_3;
-
-    conf->known_ciphers_by_name = apr_hash_make(pool);
-    conf->known_ciphers_by_id = apr_hash_make(pool);
-    for (i = 0; i < TLS_DIM(KNOWN_CIPHERS); ++i) {
-        cipher = &KNOWN_CIPHERS[i];
-        apr_hash_set(conf->known_ciphers_by_id, &cipher->id, sizeof(apr_uint16_t), cipher);
-        apr_hash_set(conf->known_ciphers_by_name, cipher->name, APR_HASH_KEY_STRING, cipher);
-        if (cipher->alias) {
-            apr_hash_set(conf->known_ciphers_by_name, cipher->alias, APR_HASH_KEY_STRING, cipher);
-        }
-    }
-
-    conf->supported_cipher_ids = apr_array_make(pool, 10, sizeof(apr_uint16_t));
-    conf->rustls_ciphers_by_id = apr_hash_make(pool);
-    i = 0;
-    while ((rustls_suite = rustls_all_ciphersuites_get_entry(i++))) {
-        id = rustls_supported_ciphersuite_get_suite(rustls_suite);
-        rcipher = apr_pcalloc(pool, sizeof(*rcipher));
-        rcipher->id = id;
-        rcipher->rustls_suite = rustls_suite;
-        APR_ARRAY_PUSH(conf->supported_cipher_ids, apr_uint16_t) = id;
-        apr_hash_set(conf->rustls_ciphers_by_id, &rcipher->id, sizeof(apr_uint16_t), rcipher);
-
-    }
-
-    return conf;
-}
-
-const char *tls_proto_get_cipher_names(
-    tls_proto_conf_t *conf, const apr_array_header_t *ciphers, apr_pool_t *pool)
-{
-    apr_array_header_t *names;
-    int n;
-
-    names = apr_array_make(pool, ciphers->nelts, sizeof(const char*));
-    for (n = 0; n < ciphers->nelts; ++n) {
-        apr_uint16_t id = APR_ARRAY_IDX(ciphers, n, apr_uint16_t);
-        APR_ARRAY_PUSH(names, const char *) = tls_proto_get_cipher_name(conf, id, pool);
-    }
-    return apr_array_pstrcat(pool, names, ':');
-}
-
-apr_status_t tls_proto_pre_config(apr_pool_t *pool, apr_pool_t *ptemp)
-{
-    (void)pool;
-    (void)ptemp;
-    return APR_SUCCESS;
-}
-
-apr_status_t tls_proto_post_config(apr_pool_t *pool, apr_pool_t *ptemp, server_rec *s)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(s);
-    tls_proto_conf_t *conf = sc->global->proto;
-
-    (void)pool;
-    if (APLOGdebug(s)) {
-        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10314)
-                     "tls ciphers supported: %s",
-                     tls_proto_get_cipher_names(conf, conf->supported_cipher_ids, ptemp));
-    }
-    return APR_SUCCESS;
-}
-
-static apr_status_t get_uint16_from(const char *name, const char *prefix, apr_uint16_t *pint)
-{
-    apr_size_t plen = strlen(prefix);
-    if (strlen(name) == plen+4 && !strncmp(name, prefix, plen)) {
-        /* may be a hex notation cipher id */
-        char *end = NULL;
-        apr_int64_t code = apr_strtoi64(name + plen, &end, 16);
-        if ((!end || !*end) && code && code <= APR_UINT16_MAX) {
-            *pint = (apr_uint16_t)code;
-            return APR_SUCCESS;
-        }
-    }
-    return APR_ENOENT;
-}
-
-apr_uint16_t tls_proto_get_version_by_name(tls_proto_conf_t *conf, const char *name)
-{
-    apr_uint16_t version;
-    (void)conf;
-    if (!apr_strnatcasecmp(name, "TLSv1.2")) {
-        return TLS_VERSION_1_2;
-    }
-    else if (!apr_strnatcasecmp(name, "TLSv1.3")) {
-        return TLS_VERSION_1_3;
-    }
-    if (APR_SUCCESS == get_uint16_from(name, "TLSv0x", &version)) {
-        return version;
-    }
-    return 0;
-}
-
-const char *tls_proto_get_version_name(
-    tls_proto_conf_t *conf, apr_uint16_t id, apr_pool_t *pool)
-{
-    (void)conf;
-    switch (id) {
-    case TLS_VERSION_1_2:
-        return "TLSv1.2";
-    case TLS_VERSION_1_3:
-        return "TLSv1.3";
-    default:
-        return apr_psprintf(pool, "TLSv0x%04x", id);
-    }
-}
-
-apr_array_header_t *tls_proto_create_versions_plus(
-    tls_proto_conf_t *conf, apr_uint16_t min_version, apr_pool_t *pool)
-{
-    apr_array_header_t *versions = apr_array_make(pool, 3, sizeof(apr_uint16_t));
-    apr_uint16_t version;
-    int i;
-
-    for (i = 0; i < conf->supported_versions->nelts; ++i) {
-        version = APR_ARRAY_IDX(conf->supported_versions, i, apr_uint16_t);
-        if (version >= min_version) {
-            APR_ARRAY_PUSH(versions, apr_uint16_t) = version;
-        }
-    }
-    return versions;
-}
-
-int tls_proto_is_cipher_supported(tls_proto_conf_t *conf, apr_uint16_t cipher)
-{
-    return tls_util_array_uint16_contains(conf->supported_cipher_ids, cipher);
-}
-
-apr_status_t tls_proto_get_cipher_by_name(
-    tls_proto_conf_t *conf, const char *name, apr_uint16_t *pcipher)
-{
-    tls_cipher_t *cipher = apr_hash_get(conf->known_ciphers_by_name, name, APR_HASH_KEY_STRING);
-    if (cipher) {
-        *pcipher = cipher->id;
-        return APR_SUCCESS;
-    }
-    return get_uint16_from(name, "TLS_CIPHER_0x", pcipher);
-}
-
-const char *tls_proto_get_cipher_name(
-    tls_proto_conf_t *conf, apr_uint16_t id, apr_pool_t *pool)
-{
-    tls_cipher_t *cipher = apr_hash_get(conf->known_ciphers_by_id, &id, sizeof(apr_uint16_t));
-    if (cipher) {
-        return cipher->name;
-    }
-    return apr_psprintf(pool, "TLS_CIPHER_0x%04x", id);
-}
-
-apr_array_header_t *tls_proto_get_rustls_suites(
-    tls_proto_conf_t *conf, const apr_array_header_t *ids, apr_pool_t *pool)
-{
-    apr_array_header_t *suites;
-    rustls_cipher_t *rcipher;
-    apr_uint16_t id;
-    int i;
-
-    suites = apr_array_make(pool, ids->nelts, sizeof(const rustls_supported_ciphersuite*));
-    for (i = 0; i < ids->nelts; ++i) {
-        id = APR_ARRAY_IDX(ids, i, apr_uint16_t);
-        rcipher = apr_hash_get(conf->rustls_ciphers_by_id, &id, sizeof(apr_uint16_t));
-        if (rcipher) {
-            APR_ARRAY_PUSH(suites, const rustls_supported_ciphersuite *) = rcipher->rustls_suite;
-        }
-    }
-    return suites;
-}
diff --git a/modules/tls/tls_proto.h b/modules/tls/tls_proto.h
deleted file mode 100644 (file)
index a3fe881..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef tls_proto_h
-#define tls_proto_h
-
-#include "tls_util.h"
-
-
-#define TLS_VERSION_1_2   0x0303
-#define TLS_VERSION_1_3   0x0304
-
-/**
- * Specification of a TLS cipher by name, possible alias and its 16 bit value
- * as assigned by IANA.
- */
-typedef struct {
-    apr_uint16_t id;      /* IANA 16-bit assigned value as used on the wire */
-    const char *name;     /* IANA given name of the cipher */
-    const char *alias;    /* Optional, commonly known alternate name */
-} tls_cipher_t;
-
-/**
- * TLS protocol related definitions constructed
- * by querying crustls lib.
- */
-typedef struct tls_proto_conf_t tls_proto_conf_t;
-struct tls_proto_conf_t {
-    apr_array_header_t *supported_versions; /* supported protocol versions (apr_uint16_t) */
-    apr_hash_t *known_ciphers_by_name; /* hash by name of known tls_cipher_t* */
-    apr_hash_t *known_ciphers_by_id; /* hash by id of known tls_cipher_t* */
-    apr_hash_t *rustls_ciphers_by_id; /* hash by id of rustls rustls_supported_ciphersuite* */
-    apr_array_header_t *supported_cipher_ids; /* cipher ids (apr_uint16_t) supported by rustls */
-    const rustls_root_cert_store *native_roots;
-};
-
-/**
- * Create and populate the protocol configuration.
- */
-tls_proto_conf_t *tls_proto_init(apr_pool_t *p, server_rec *s);
-
-/**
- * Called during pre-config phase to start initialization
- * of the tls protocol configuration.
- */
-apr_status_t tls_proto_pre_config(apr_pool_t *pool, apr_pool_t *ptemp);
-
-/**
- * Called during post-config phase to conclude the initialization
- * of the tls protocol configuration.
- */
-apr_status_t tls_proto_post_config(apr_pool_t *p, apr_pool_t *ptemp, server_rec *s);
-
-/**
- * Get the TLS protocol identifier (as used on the wire) for the TLS
- * protocol of the given name. Returns 0 if protocol is unknown.
- */
-apr_uint16_t tls_proto_get_version_by_name(tls_proto_conf_t *conf, const char *name);
-
-/**
- * Get the name of the protocol version identified by its identifier. This
- * will return the name from the protocol configuration or, if unknown, create
- * the string `TLSv0x%04x` from the 16bit identifier.
- */
-const char *tls_proto_get_version_name(
-    tls_proto_conf_t *conf, apr_uint16_t id, apr_pool_t *pool);
-
-/**
- * Create an array of the given TLS protocol version identifier `min_version`
- * and all supported new ones. The array carries apr_uint16_t values.
- */
-apr_array_header_t *tls_proto_create_versions_plus(
-    tls_proto_conf_t *conf, apr_uint16_t min_version, apr_pool_t *pool);
-
-/**
- * Get a TLS cipher spec by name/alias.
- */
-apr_status_t tls_proto_get_cipher_by_name(
-    tls_proto_conf_t *conf, const char *name, apr_uint16_t *pcipher);
-
-/**
- * Return != 0 iff the cipher is supported by the rustls library.
- */
-int tls_proto_is_cipher_supported(tls_proto_conf_t *conf, apr_uint16_t cipher);
-
-/**
- * Get the name of a TLS cipher for the IANA assigned 16bit value. This will
- * return the name in the protocol configuration, if the cipher is known, and
- * create the string `TLS_CIPHER_0x%04x` for the 16bit cipher value.
- */
-const char *tls_proto_get_cipher_name(
-    tls_proto_conf_t *conf, apr_uint16_t cipher, apr_pool_t *pool);
-
-/**
- * Get the concatenated names with ':' as separator of all TLS cipher identifiers
- * as given in `ciphers`.
- * @param conf the TLS protocol configuration
- * @param ciphers the 16bit values of the TLS ciphers
- * @param pool to use for allocation the string.
- */
-const char *tls_proto_get_cipher_names(
-    tls_proto_conf_t *conf, const apr_array_header_t *ciphers, apr_pool_t *pool);
-
-/**
- * Convert an array of TLS cipher 16bit identifiers into the `rustls_supported_ciphersuite`
- * instances that can be passed to crustls in session configurations.
- * Any cipher identifier not supported by rustls we be silently omitted.
- */
-apr_array_header_t *tls_proto_get_rustls_suites(
-    tls_proto_conf_t *conf, const apr_array_header_t *ids, apr_pool_t *pool);
-
-#endif /* tls_proto_h */
diff --git a/modules/tls/tls_util.c b/modules/tls/tls_util.c
deleted file mode 100644 (file)
index 9eac212..0000000
+++ /dev/null
@@ -1,367 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <assert.h>
-#include <apr_lib.h>
-#include <apr_file_info.h>
-#include <apr_strings.h>
-
-#include <httpd.h>
-#include <http_core.h>
-#include <http_log.h>
-
-#include <rustls.h>
-
-#include "tls_proto.h"
-#include "tls_util.h"
-
-
-extern module AP_MODULE_DECLARE_DATA tls_module;
-APLOG_USE_MODULE(tls);
-
-
-tls_data_t tls_data_from_str(const char *s)
-{
-    tls_data_t d;
-    d.data = (const unsigned char*)s;
-    d.len = s? strlen(s) : 0;
-    return d;
-}
-
-tls_data_t tls_data_assign_copy(apr_pool_t *p, const tls_data_t *d)
-{
-    tls_data_t copy;
-    copy.data = apr_pmemdup(p, d->data, d->len);
-    copy.len = d->len;
-    return copy;
-}
-
-tls_data_t *tls_data_copy(apr_pool_t *p, const tls_data_t *d)
-{
-    tls_data_t *copy;
-    copy = apr_pcalloc(p, sizeof(*copy));
-    *copy = tls_data_assign_copy(p, d);
-    return copy;
-}
-
-const char *tls_data_to_str(apr_pool_t *p, const tls_data_t *d)
-{
-    char *s = apr_pcalloc(p, d->len+1);
-    memcpy(s, d->data, d->len);
-    return s;
-}
-
-apr_status_t tls_util_rustls_error(
-    apr_pool_t *p, rustls_result rr, const char **perr_descr)
-{
-    if (perr_descr) {
-        char buffer[HUGE_STRING_LEN];
-        apr_size_t len = 0;
-
-        rustls_error(rr, buffer, sizeof(buffer), &len);
-        *perr_descr = apr_pstrndup(p, buffer, len);
-    }
-    return APR_EGENERAL;
-}
-
-int tls_util_is_file(
-    apr_pool_t *p, const char *fpath)
-{
-    apr_finfo_t finfo;
-
-    return (fpath != NULL
-        && apr_stat(&finfo, fpath, APR_FINFO_TYPE|APR_FINFO_SIZE, p) == 0
-        && finfo.filetype == APR_REG);
-}
-
-apr_status_t tls_util_file_load(
-    apr_pool_t *p, const char *fpath, apr_size_t min_len, apr_size_t max_len, tls_data_t *data)
-{
-    apr_finfo_t finfo;
-    apr_status_t rv;
-    apr_file_t *f = NULL;
-    unsigned char *buffer;
-    apr_size_t len;
-    const char *err = NULL;
-    tls_data_t *d;
-
-    rv = apr_stat(&finfo, fpath, APR_FINFO_TYPE|APR_FINFO_SIZE, p);
-    if (APR_SUCCESS != rv) {
-        err = "cannot stat"; goto cleanup;
-    }
-    if (finfo.filetype != APR_REG) {
-        err = "not a plain file";
-        rv = APR_EINVAL; goto cleanup;
-    }
-    if (finfo.size > LONG_MAX) {
-        err = "file is too large";
-        rv = APR_EINVAL; goto cleanup;
-    }
-    len = (apr_size_t)finfo.size;
-    if (len < min_len || len > max_len) {
-        err = "file size not in allowed range";
-        rv = APR_EINVAL; goto cleanup;
-    }
-    d = apr_pcalloc(p, sizeof(*d));
-    buffer = apr_pcalloc(p, len+1); /* keep it NUL terminated in any case */
-    rv = apr_file_open(&f, fpath, APR_FOPEN_READ, 0, p);
-    if (APR_SUCCESS != rv) {
-        err = "error opening"; goto cleanup;
-    }
-    rv = apr_file_read(f, buffer, &len);
-    if (APR_SUCCESS != rv) {
-        err = "error reading"; goto cleanup;
-    }
-cleanup:
-    if (f) apr_file_close(f);
-    if (APR_SUCCESS == rv) {
-        data->data = buffer;
-        data->len = len;
-    }
-    else {
-        memset(data, 0, sizeof(*data));
-        ap_log_perror(APLOG_MARK, APLOG_ERR, rv, p, APLOGNO(10361)
-                      "Failed to load file %s: %s", fpath, err? err: "-");
-    }
-    return rv;
-}
-
-int tls_util_array_uint16_contains(const apr_array_header_t* a, apr_uint16_t n)
-{
-    int i;
-    for (i = 0; i < a->nelts; ++i) {
-        if (APR_ARRAY_IDX(a, i, apr_uint16_t) == n) return 1;
-    }
-    return 0;
-}
-
-const apr_array_header_t *tls_util_array_uint16_remove(
-    apr_pool_t *pool, const apr_array_header_t* from, const apr_array_header_t* others)
-{
-    apr_array_header_t *na = NULL;
-    apr_uint16_t id;
-    int i, j;
-
-    for (i = 0; i < from->nelts; ++i) {
-        id = APR_ARRAY_IDX(from, i, apr_uint16_t);
-        if (tls_util_array_uint16_contains(others, id)) {
-            if (na == NULL) {
-                /* first removal, make a new result array, copy elements before */
-                na = apr_array_make(pool, from->nelts, sizeof(apr_uint16_t));
-                for (j = 0; j < i; ++j) {
-                    APR_ARRAY_PUSH(na, apr_uint16_t) = APR_ARRAY_IDX(from, j, apr_uint16_t);
-                }
-            }
-        }
-        else if (na) {
-            APR_ARRAY_PUSH(na, apr_uint16_t) = id;
-        }
-    }
-    return na? na : from;
-}
-
-apr_status_t tls_util_brigade_transfer(
-    apr_bucket_brigade *dest, apr_bucket_brigade *src, apr_off_t length,
-    apr_off_t *pnout)
-{
-    apr_bucket *b;
-    apr_off_t remain = length;
-    apr_status_t rv = APR_SUCCESS;
-    const char *ign;
-    apr_size_t ilen;
-
-    *pnout = 0;
-    while (!APR_BRIGADE_EMPTY(src)) {
-        b = APR_BRIGADE_FIRST(src);
-
-        if (APR_BUCKET_IS_METADATA(b)) {
-            APR_BUCKET_REMOVE(b);
-            APR_BRIGADE_INSERT_TAIL(dest, b);
-        }
-        else {
-            if (remain == (apr_off_t)b->length) {
-                /* fall through */
-            }
-            else if (remain <= 0) {
-                goto cleanup;
-            }
-            else {
-                if (b->length == ((apr_size_t)-1)) {
-                    rv= apr_bucket_read(b, &ign, &ilen, APR_BLOCK_READ);
-                    if (APR_SUCCESS != rv) goto cleanup;
-                }
-                if (remain < (apr_off_t)b->length) {
-                    apr_bucket_split(b, (apr_size_t)remain);
-                }
-            }
-            APR_BUCKET_REMOVE(b);
-            APR_BRIGADE_INSERT_TAIL(dest, b);
-            remain -= (apr_off_t)b->length;
-            *pnout += (apr_off_t)b->length;
-        }
-    }
-cleanup:
-    return rv;
-}
-
-apr_status_t tls_util_brigade_copy(
-    apr_bucket_brigade *dest, apr_bucket_brigade *src, apr_off_t length,
-    apr_off_t *pnout)
-{
-    apr_bucket *b, *next;
-    apr_off_t remain = length;
-    apr_status_t rv = APR_SUCCESS;
-    const char *ign;
-    apr_size_t ilen;
-
-    *pnout = 0;
-    for (b = APR_BRIGADE_FIRST(src);
-         b != APR_BRIGADE_SENTINEL(src);
-         b = next) {
-        next = APR_BUCKET_NEXT(b);
-
-        if (APR_BUCKET_IS_METADATA(b)) {
-            /* fall through */
-        }
-        else {
-            if (remain == (apr_off_t)b->length) {
-                /* fall through */
-            }
-            else if (remain <= 0) {
-                goto cleanup;
-            }
-            else {
-                if (b->length == ((apr_size_t)-1)) {
-                    rv = apr_bucket_read(b, &ign, &ilen, APR_BLOCK_READ);
-                    if (APR_SUCCESS != rv) goto cleanup;
-                }
-                if (remain < (apr_off_t)b->length) {
-                    apr_bucket_split(b, (apr_size_t)remain);
-                }
-            }
-        }
-        rv = apr_bucket_copy(b, &b);
-        if (APR_SUCCESS != rv) goto cleanup;
-        APR_BRIGADE_INSERT_TAIL(dest, b);
-        remain -= (apr_off_t)b->length;
-        *pnout += (apr_off_t)b->length;
-    }
-cleanup:
-    return rv;
-}
-
-apr_status_t tls_util_brigade_split_line(
-    apr_bucket_brigade *dest, apr_bucket_brigade *src,
-    apr_read_type_e block, apr_off_t length,
-    apr_off_t *pnout)
-{
-    apr_off_t nstart, nend;
-    apr_status_t rv;
-
-    apr_brigade_length(dest, 0, &nstart);
-    rv = apr_brigade_split_line(dest, src, block, length);
-    if (APR_SUCCESS != rv) goto cleanup;
-    apr_brigade_length(dest, 0, &nend);
-    /* apr_brigade_split_line() has the nasty habit of leaving a 0-length bucket
-     * at the start of the brigade when it transferred the whole content. Get rid of it.
-     */
-    if (!APR_BRIGADE_EMPTY(src)) {
-         apr_bucket *b = APR_BRIGADE_FIRST(src);
-        if (!APR_BUCKET_IS_METADATA(b) && 0 == b->length) {
-            APR_BUCKET_REMOVE(b);
-            apr_bucket_delete(b);
-        }
-    }
-cleanup:
-    *pnout = (APR_SUCCESS == rv)? (nend - nstart) : 0;
-    return rv;
-}
-
-int tls_util_name_matches_server(const char *name, server_rec *s)
-{
-    apr_array_header_t *names;
-    char **alias;
-    int i;
-
-    if (!s || !s->server_hostname) return 0;
-    if (!strcasecmp(name, s->server_hostname)) return 1;
-    /* first the fast equality match, then the pattern wild_name matches */
-    names = s->names;
-    if (!names) return 0;
-    alias = (char **)names->elts;
-    for (i = 0; i < names->nelts; ++i) {
-        if (alias[i] && !strcasecmp(name, alias[i])) return 1;
-    }
-    names = s->wild_names;
-    if (!names) return 0;
-    alias = (char **)names->elts;
-    for (i = 0; i < names->nelts; ++i) {
-        if (alias[i] && !ap_strcasecmp_match(name, alias[i])) return 1;
-    }
-    return 0;
-}
-
-apr_size_t tls_util_bucket_print(char *buffer, apr_size_t bmax,
-                                 apr_bucket *b, const char *sep)
-{
-    apr_size_t off = 0;
-    if (sep && *sep) {
-        off += (size_t)apr_snprintf(buffer+off, bmax-off, "%s", sep);
-    }
-
-    if (bmax <= off) {
-        return off;
-    }
-    else if (APR_BUCKET_IS_METADATA(b)) {
-        off += (size_t)apr_snprintf(buffer+off, bmax-off, "%s", b->type->name);
-    }
-    else if (bmax > off) {
-        off += (size_t)apr_snprintf(buffer+off, bmax-off, "%s[%ld]",
-                                    b->type->name, (long)(b->length == ((apr_size_t)-1)?
-                                   -1 : (int)b->length));
-    }
-    return off;
-}
-
-apr_size_t tls_util_bb_print(char *buffer, apr_size_t bmax,
-                             const char *tag, const char *sep,
-                             apr_bucket_brigade *bb)
-{
-    apr_size_t off = 0;
-    const char *sp = "";
-    apr_bucket *b;
-
-    if (bmax > 1) {
-        if (bb) {
-            memset(buffer, 0, bmax--);
-            off += (size_t)apr_snprintf(buffer+off, bmax-off, "%s(", tag);
-            for (b = APR_BRIGADE_FIRST(bb);
-                 (bmax > off) && (b != APR_BRIGADE_SENTINEL(bb));
-                 b = APR_BUCKET_NEXT(b)) {
-
-                off += tls_util_bucket_print(buffer+off, bmax-off, b, sp);
-                sp = " ";
-            }
-            if (bmax > off) {
-                off += (size_t)apr_snprintf(buffer+off, bmax-off, ")%s", sep);
-            }
-        }
-        else {
-            off += (size_t)apr_snprintf(buffer+off, bmax-off, "%s(null)%s", tag, sep);
-        }
-    }
-    return off;
-}
-
diff --git a/modules/tls/tls_util.h b/modules/tls/tls_util.h
deleted file mode 100644 (file)
index 18ae4df..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef tls_util_h
-#define tls_util_h
-
-#define TLS_DIM(a)      (sizeof(a)/sizeof(a[0]))
-
-
-/**
- * Simple struct to hold a range of bytes and its length together.
- */
-typedef struct tls_data_t tls_data_t;
-struct tls_data_t {
-    const unsigned char* data;
-    apr_size_t len;
-};
-
-/**
- * Return a tls_data_t for a string.
- */
-tls_data_t tls_data_from_str(const char *s);
-
-/**
- * Create a copy of a tls_data_t using the given pool.
- */
-tls_data_t *tls_data_copy(apr_pool_t *p, const tls_data_t *d);
-
-/**
- * Return a copy of a tls_data_t bytes allocated from pool.
- */
-tls_data_t tls_data_assign_copy(apr_pool_t *p, const tls_data_t *d);
-
-/**
- * Convert the data bytes in `d` into a NUL-terminated string.
- * There is no check if the data bytes already contain NUL.
- */
-const char *tls_data_to_str(apr_pool_t *p, const tls_data_t *d);
-
-/**
- * Return != 0 if fpath is a 'real' file.
- */
-int tls_util_is_file(apr_pool_t *p, const char *fpath);
-
-/**
- * Inspect a 'rustls_result', retrieve the error description for it and
- * return the apr_status_t to use as our error status.
- */
-apr_status_t tls_util_rustls_error(apr_pool_t *p, rustls_result rr, const char **perr_descr);
-
-/**
- *  Load up to `max_len` bytes into a buffer allocated from the pool.
- *  @return ARP_SUCCESS on successful load.
- *          APR_EINVAL when the file was not a regular file or is too large.
- */
-apr_status_t tls_util_file_load(
-    apr_pool_t *p, const char *fpath, size_t min_len, size_t max_len, tls_data_t *data);
-
-/**
- * Return != 0 iff the array of apr_uint16_t contains value n.
- */
-int tls_util_array_uint16_contains(const apr_array_header_t* a, apr_uint16_t n);
-
-/**
- * Remove all apr_uint16_t in `others` from array `from`.
- * Returns the new array or, if no overlap was found, the `from` array unchanged.
- */
-const apr_array_header_t *tls_util_array_uint16_remove(
-    apr_pool_t *pool, const apr_array_header_t* from, const apr_array_header_t* others);
-
-/**
- * Transfer up to <length> bytes from <src> to <dest>, including all
- * encountered meta data buckets. The transferred buckets/data are
- * removed from <src>.
- * Return the actual byte count transferred in <pnout>.
- */
-apr_status_t tls_util_brigade_transfer(
-    apr_bucket_brigade *dest, apr_bucket_brigade *src, apr_off_t length,
-    apr_off_t *pnout);
-
-/**
- * Copy up to <length> bytes from <src> to <dest>, including all
- * encountered meta data buckets. <src> remains semantically unchaanged,
- * meaning there might have been buckets split or changed while reading
- * their content.
- * Return the actual byte count copied in <pnout>.
- */
-apr_status_t tls_util_brigade_copy(
-    apr_bucket_brigade *dest, apr_bucket_brigade *src, apr_off_t length,
-    apr_off_t *pnout);
-
-/**
- * Get a line of max `length` bytes from `src` into `dest`.
- * Return the number of bytes transferred in `pnout`.
- */
-apr_status_t tls_util_brigade_split_line(
-    apr_bucket_brigade *dest, apr_bucket_brigade *src,
-    apr_read_type_e block, apr_off_t length,
-    apr_off_t *pnout);
-
-/**
- * Return != 0 iff the given <name> matches the configured 'ServerName'
- * or one of the 'ServerAlias' name of <s>, including wildcard patterns
- * as understood by ap_strcasecmp_match().
- */
-int tls_util_name_matches_server(const char *name, server_rec *s);
-
-
-/**
- * Print a bucket's meta data (type and length) to the buffer.
- * @return number of characters printed
- */
-apr_size_t tls_util_bucket_print(char *buffer, apr_size_t bmax,
-                                 apr_bucket *b, const char *sep);
-
-/**
- * Prints the brigade bucket types and lengths into the given buffer
- * up to bmax.
- * @return number of characters printed
- */
-apr_size_t tls_util_bb_print(char *buffer, apr_size_t bmax,
-                             const char *tag, const char *sep,
-                             apr_bucket_brigade *bb);
-/**
- * Logs the bucket brigade (which bucket types with what length)
- * to the log at the given level.
- * @param c the connection to log for
- * @param sid the stream identifier this brigade belongs to
- * @param level the log level (as in APLOG_*)
- * @param tag a short message text about the context
- * @param bb the brigade to log
- */
-#define tls_util_bb_log(c, level, tag, bb) \
-do { \
-    char buffer[4 * 1024]; \
-    const char *line = "(null)"; \
-    apr_size_t len, bmax = sizeof(buffer)/sizeof(buffer[0]); \
-    len = tls_util_bb_print(buffer, bmax, (tag), "", (bb)); \
-    ap_log_cerror(APLOG_MARK, level, 0, (c), "bb_dump(%ld): %s", \
-        ((c)->master? (c)->master->id : (c)->id), (len? buffer : line)); \
-} while(0)
-
-
-
-#endif /* tls_util_h */
diff --git a/modules/tls/tls_var.c b/modules/tls/tls_var.c
deleted file mode 100644 (file)
index fa4ae2a..0000000
+++ /dev/null
@@ -1,397 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <assert.h>
-#include <apr_lib.h>
-#include <apr_strings.h>
-
-#include <httpd.h>
-#include <http_connection.h>
-#include <http_core.h>
-#include <http_main.h>
-#include <http_log.h>
-#include <ap_socache.h>
-
-#include <rustls.h>
-
-#include "tls_conf.h"
-#include "tls_core.h"
-#include "tls_cert.h"
-#include "tls_util.h"
-#include "tls_var.h"
-#include "tls_version.h"
-
-
-extern module AP_MODULE_DECLARE_DATA tls_module;
-APLOG_USE_MODULE(tls);
-
-typedef struct {
-    apr_pool_t *p;
-    server_rec *s;
-    conn_rec *c;
-    request_rec *r;
-    tls_conf_conn_t *cc;
-    const char *name;
-    const char *arg_s;
-    int arg_i;
-} tls_var_lookup_ctx_t;
-
-typedef const char *var_lookup(const tls_var_lookup_ctx_t *ctx);
-
-static const char *var_get_ssl_protocol(const tls_var_lookup_ctx_t *ctx)
-{
-    return ctx->cc->tls_protocol_name;
-}
-
-static const char *var_get_ssl_cipher(const tls_var_lookup_ctx_t *ctx)
-{
-    return ctx->cc->tls_cipher_name;
-}
-
-static const char *var_get_sni_hostname(const tls_var_lookup_ctx_t *ctx)
-{
-    return ctx->cc->sni_hostname;
-}
-
-static const char *var_get_version_interface(const tls_var_lookup_ctx_t *ctx)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(ctx->s);
-    return sc->global->module_version;
-}
-
-static const char *var_get_version_library(const tls_var_lookup_ctx_t *ctx)
-{
-    tls_conf_server_t *sc = tls_conf_server_get(ctx->s);
-    return sc->global->crustls_version;
-}
-
-static const char *var_get_false(const tls_var_lookup_ctx_t *ctx)
-{
-    (void)ctx;
-    return "false";
-}
-
-static const char *var_get_null(const tls_var_lookup_ctx_t *ctx)
-{
-    (void)ctx;
-    return "NULL";
-}
-
-static const char *var_get_client_s_dn_cn(const tls_var_lookup_ctx_t *ctx)
-{
-    /* There is no support in the crustls/rustls/webpki APIs to
-     * parse X.509 certificates and extract information about
-     * subject, issuer, etc. */
-    if (!ctx->cc->peer_certs || !ctx->cc->peer_certs->nelts) return NULL;
-    return "Not Implemented";
-}
-
-static const char *var_get_client_verify(const tls_var_lookup_ctx_t *ctx)
-{
-    return ctx->cc->peer_certs? "SUCCESS" : "NONE";
-}
-
-static const char *var_get_session_resumed(const tls_var_lookup_ctx_t *ctx)
-{
-    return ctx->cc->session_id_cache_hit? "Resumed" : "Initial";
-}
-
-static const char *var_get_client_cert(const tls_var_lookup_ctx_t *ctx)
-{
-    const rustls_certificate *cert;
-    const char *pem;
-    apr_status_t rv;
-    int cert_idx = 0;
-
-    if (ctx->arg_s) {
-        if (strcmp(ctx->arg_s, "chain")) return NULL;
-        /* ctx->arg_i'th chain cert, which is in out list as */
-        cert_idx = ctx->arg_i + 1;
-    }
-    if (!ctx->cc->peer_certs || cert_idx >= ctx->cc->peer_certs->nelts) return NULL;
-    cert = APR_ARRAY_IDX(ctx->cc->peer_certs, cert_idx, const rustls_certificate*);
-    if (APR_SUCCESS != (rv = tls_cert_to_pem(&pem, ctx->p, cert))) {
-        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ctx->s, APLOGNO(10315)
-                         "Failed to create client certificate PEM");
-        return NULL;
-    }
-    return pem;
-}
-
-static const char *var_get_server_cert(const tls_var_lookup_ctx_t *ctx)
-{
-    const rustls_certificate *cert;
-    const char *pem;
-    apr_status_t rv;
-
-    if (!ctx->cc->key) return NULL;
-    cert = rustls_certified_key_get_certificate(ctx->cc->key, 0);
-    if (!cert) return NULL;
-    if (APR_SUCCESS != (rv = tls_cert_to_pem(&pem, ctx->p, cert))) {
-        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ctx->s, APLOGNO(10316)
-                         "Failed to create server certificate PEM");
-        return NULL;
-    }
-    return pem;
-}
-
-typedef struct {
-    const char *name;
-    var_lookup* fn;
-    const char *arg_s;
-    int arg_i;
-} var_def_t;
-
-static const var_def_t VAR_DEFS[] = {
-    { "SSL_PROTOCOL", var_get_ssl_protocol, NULL, 0 },
-    { "SSL_CIPHER", var_get_ssl_cipher, NULL, 0 },
-    { "SSL_TLS_SNI", var_get_sni_hostname, NULL, 0 },
-    { "SSL_CLIENT_S_DN_CN", var_get_client_s_dn_cn, NULL, 0 },
-    { "SSL_VERSION_INTERFACE", var_get_version_interface, NULL, 0 },
-    { "SSL_VERSION_LIBRARY", var_get_version_library, NULL, 0 },
-    { "SSL_SECURE_RENEG", var_get_false, NULL, 0 },
-    { "SSL_COMPRESS_METHOD", var_get_null, NULL, 0 },
-    { "SSL_CIPHER_EXPORT", var_get_false, NULL, 0 },
-    { "SSL_CLIENT_VERIFY", var_get_client_verify, NULL, 0 },
-    { "SSL_SESSION_RESUMED", var_get_session_resumed, NULL, 0 },
-    { "SSL_CLIENT_CERT", var_get_client_cert, NULL, 0 },
-    { "SSL_CLIENT_CHAIN_0", var_get_client_cert, "chain", 0 },
-    { "SSL_CLIENT_CHAIN_1", var_get_client_cert, "chain", 1 },
-    { "SSL_CLIENT_CHAIN_2", var_get_client_cert, "chain", 2 },
-    { "SSL_CLIENT_CHAIN_3", var_get_client_cert, "chain", 3 },
-    { "SSL_CLIENT_CHAIN_4", var_get_client_cert, "chain", 4 },
-    { "SSL_CLIENT_CHAIN_5", var_get_client_cert, "chain", 5 },
-    { "SSL_CLIENT_CHAIN_6", var_get_client_cert, "chain", 6 },
-    { "SSL_CLIENT_CHAIN_7", var_get_client_cert, "chain", 7 },
-    { "SSL_CLIENT_CHAIN_8", var_get_client_cert, "chain", 8 },
-    { "SSL_CLIENT_CHAIN_9", var_get_client_cert, "chain", 9 },
-    { "SSL_SERVER_CERT", var_get_server_cert, NULL, 0 },
-};
-
-static const char *const TlsAlwaysVars[] = {
-    "SSL_TLS_SNI",
-    "SSL_PROTOCOL",
-    "SSL_CIPHER",
-    "SSL_CLIENT_S_DN_CN",
-};
-
-/* what mod_ssl defines, plus server cert and client cert DN and SAN entries */
-static const char *const StdEnvVars[] = {
-    "SSL_VERSION_INTERFACE", /* implemented: module version string */
-    "SSL_VERSION_LIBRARY",   /* implemented: crustls/rustls version string */
-    "SSL_SECURE_RENEG",      /* implemented: always "false" */
-    "SSL_COMPRESS_METHOD",   /* implemented: always "NULL" */
-    "SSL_CIPHER_EXPORT",     /* implemented: always "false" */
-    "SSL_CIPHER_USEKEYSIZE",
-    "SSL_CIPHER_ALGKEYSIZE",
-    "SSL_CLIENT_VERIFY",     /* implemented: always "SUCCESS" or "NONE" */
-    "SSL_CLIENT_M_VERSION",
-    "SSL_CLIENT_M_SERIAL",
-    "SSL_CLIENT_V_START",
-    "SSL_CLIENT_V_END",
-    "SSL_CLIENT_V_REMAIN",
-    "SSL_CLIENT_S_DN",
-    "SSL_CLIENT_I_DN",
-    "SSL_CLIENT_A_KEY",
-    "SSL_CLIENT_A_SIG",
-    "SSL_CLIENT_CERT_RFC4523_CEA",
-    "SSL_SERVER_M_VERSION",
-    "SSL_SERVER_M_SERIAL",
-    "SSL_SERVER_V_START",
-    "SSL_SERVER_V_END",
-    "SSL_SERVER_S_DN",
-    "SSL_SERVER_I_DN",
-    "SSL_SERVER_A_KEY",
-    "SSL_SERVER_A_SIG",
-    "SSL_SESSION_ID",        /* not implemented: highly sensitive data we do not expose */
-    "SSL_SESSION_RESUMED",   /* implemented: if our cache was hit successfully */
-};
-
-/* Cert related variables, export when TLSOption ExportCertData is set */
-static const char *const ExportCertVars[] = {
-    "SSL_CLIENT_CERT",       /* implemented: */
-    "SSL_CLIENT_CHAIN_0",    /* implemented: */
-    "SSL_CLIENT_CHAIN_1",    /* implemented: */
-    "SSL_CLIENT_CHAIN_2",    /* implemented: */
-    "SSL_CLIENT_CHAIN_3",    /* implemented: */
-    "SSL_CLIENT_CHAIN_4",    /* implemented: */
-    "SSL_CLIENT_CHAIN_5",    /* implemented: */
-    "SSL_CLIENT_CHAIN_6",    /* implemented: */
-    "SSL_CLIENT_CHAIN_7",    /* implemented: */
-    "SSL_CLIENT_CHAIN_8",    /* implemented: */
-    "SSL_CLIENT_CHAIN_9",    /* implemented: */
-    "SSL_SERVER_CERT",       /* implemented: */
-};
-
-void tls_var_init_lookup_hash(apr_pool_t *pool, apr_hash_t *map)
-{
-    const var_def_t *def;
-    apr_size_t i;
-
-    (void)pool;
-    for (i = 0; i < TLS_DIM(VAR_DEFS); ++i) {
-        def = &VAR_DEFS[i];
-        apr_hash_set(map, def->name, APR_HASH_KEY_STRING, def);
-    }
-}
-
-static const char *invoke(var_def_t* def, tls_var_lookup_ctx_t *ctx)
-{
-    if (TLS_CONN_ST_IS_ENABLED(ctx->cc)) {
-        const char *val = ctx->cc->subprocess_env?
-            apr_table_get(ctx->cc->subprocess_env, def->name) : NULL;
-        if (val && *val) return val;
-        ctx->arg_s = def->arg_s;
-        ctx->arg_i = def->arg_i;
-        return def->fn(ctx);
-    }
-    return NULL;
-}
-
-static void set_var(
-    tls_var_lookup_ctx_t *ctx, apr_hash_t *lookups, apr_table_t *table)
-{
-    var_def_t* def = apr_hash_get(lookups, ctx->name, APR_HASH_KEY_STRING);
-    if (def) {
-        const char *val = invoke(def, ctx);
-        if (val && *val) {
-            apr_table_setn(table, ctx->name, val);
-        }
-    }
-}
-
-const char *tls_var_lookup(
-    apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *name)
-{
-    const char *val = NULL;
-    tls_conf_server_t *sc;
-    var_def_t* def;
-
-    ap_assert(p);
-    ap_assert(name);
-    s = s? s : (r? r->server : (c? c->base_server : NULL));
-    c = c? c : (r? r->connection : NULL);
-
-    sc = tls_conf_server_get(s? s : ap_server_conf);
-    def = apr_hash_get(sc->global->var_lookups, name, APR_HASH_KEY_STRING);
-    if (def) {
-        tls_var_lookup_ctx_t ctx;
-        ctx.p = p;
-        ctx.s = s;
-        ctx.c = c;
-        ctx.r = r;
-        ctx.cc = c? tls_conf_conn_get(c->master? c->master : c) : NULL;
-                ctx.cc = c? tls_conf_conn_get(c->master? c->master : c) : NULL;
-        ctx.name = name;
-        val = invoke(def, &ctx);
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c, "tls lookup of var '%s' -> '%s'", name, val);
-    }
-    return val;
-}
-
-static void add_vars(apr_table_t *env, conn_rec *c, server_rec *s, request_rec *r)
-{
-    tls_conf_server_t *sc;
-    tls_conf_dir_t *dc, *sdc;
-    tls_var_lookup_ctx_t ctx;
-    apr_size_t i;
-    int overlap;
-
-    sc = tls_conf_server_get(s);
-    dc = r? tls_conf_dir_get(r) : tls_conf_dir_server_get(s);
-    sdc = r? tls_conf_dir_server_get(s): dc;
-    ctx.p = r? r->pool : c->pool;
-    ctx.s = s;
-    ctx.c = c;
-    ctx.r = r;
-    ctx.cc = tls_conf_conn_get(c->master? c->master : c);
-    /* Can we re-use the precomputed connection values? */
-    overlap = (r && ctx.cc->subprocess_env && r->server == ctx.cc->server);
-    if (overlap) {
-        apr_table_overlap(env, ctx.cc->subprocess_env, APR_OVERLAP_TABLES_SET);
-    }
-    else {
-        apr_table_setn(env, "HTTPS", "on");
-        for (i = 0; i < TLS_DIM(TlsAlwaysVars); ++i) {
-            ctx.name = TlsAlwaysVars[i];
-            set_var(&ctx, sc->global->var_lookups, env);
-        }
-    }
-    if (dc->std_env_vars == TLS_FLAG_TRUE) {
-        for (i = 0; i < TLS_DIM(StdEnvVars); ++i) {
-            ctx.name = StdEnvVars[i];
-            set_var(&ctx, sc->global->var_lookups, env);
-        }
-    }
-    else if (overlap && sdc->std_env_vars == TLS_FLAG_TRUE) {
-        /* Remove variables added on connection init that are disabled here */
-        for (i = 0; i < TLS_DIM(StdEnvVars); ++i) {
-            apr_table_unset(env, StdEnvVars[i]);
-        }
-    }
-    if (dc->export_cert_vars == TLS_FLAG_TRUE) {
-        for (i = 0; i < TLS_DIM(ExportCertVars); ++i) {
-            ctx.name = ExportCertVars[i];
-            set_var(&ctx, sc->global->var_lookups, env);
-        }
-    }
-    else if (overlap && sdc->std_env_vars == TLS_FLAG_TRUE) {
-        /* Remove variables added on connection init that are disabled here */
-        for (i = 0; i < TLS_DIM(ExportCertVars); ++i) {
-            apr_table_unset(env, ExportCertVars[i]);
-        }
-    }
- }
-
-apr_status_t tls_var_handshake_done(conn_rec *c)
-{
-    tls_conf_conn_t *cc;
-    tls_conf_server_t *sc;
-    apr_status_t rv = APR_SUCCESS;
-
-    cc = tls_conf_conn_get(c);
-    if (!TLS_CONN_ST_IS_ENABLED(cc)) goto cleanup;
-
-    sc = tls_conf_server_get(cc->server);
-    if (cc->peer_certs && sc->var_user_name) {
-        cc->user_name = tls_var_lookup(c->pool, cc->server, c, NULL, sc->var_user_name);
-        if (!cc->user_name) {
-            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cc->server, APLOGNO(10317)
-                "Failed to set r->user to '%s'", sc->var_user_name);
-        }
-    }
-    cc->subprocess_env = apr_table_make(c->pool, 5);
-    add_vars(cc->subprocess_env, c, cc->server, NULL);
-
-cleanup:
-    return rv;
-}
-
-int tls_var_request_fixup(request_rec *r)
-{
-    conn_rec *c = r->connection;
-    tls_conf_conn_t *cc;
-
-    cc = tls_conf_conn_get(c->master? c->master : c);
-    if (!TLS_CONN_ST_IS_ENABLED(cc)) goto cleanup;
-    if (cc->user_name) {
-        /* why is r->user a char* and not const? */
-        r->user = apr_pstrdup(r->pool, cc->user_name);
-    }
-    add_vars(r->subprocess_env, c, r->server, r);
-
-cleanup:
-    return DECLINED;
-}
diff --git a/modules/tls/tls_var.h b/modules/tls/tls_var.h
deleted file mode 100644 (file)
index 2e8c0bb..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef tls_var_h
-#define tls_var_h
-
-void tls_var_init_lookup_hash(apr_pool_t *pool, apr_hash_t *map);
-
-/**
- * Callback for installation in Apache's 'ssl_var_lookup' hook to provide
- * SSL related variable lookups to other modules.
- */
-const char *tls_var_lookup(
-    apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *name);
-
-/**
- * A connection has been handshaked. Prepare commond TLS variables on this connection.
- */
-apr_status_t tls_var_handshake_done(conn_rec *c);
-
-/**
- * A request is ready for processing, add TLS variables r->subprocess_env if applicable.
- * This is a hook function returning OK/DECLINED.
- */
-int tls_var_request_fixup(request_rec *r);
-
-#endif /* tls_var_h */
\ No newline at end of file
diff --git a/modules/tls/tls_version.h b/modules/tls/tls_version.h
deleted file mode 100644 (file)
index bc9fb0b..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef mod_tls_version_h
-#define mod_tls_version_h
-
-#undef PACKAGE_VERSION
-#undef PACKAGE_TARNAME
-#undef PACKAGE_STRING
-#undef PACKAGE_NAME
-#undef PACKAGE_BUGREPORT
-
-/**
- * @macro
- * Version number of the md module as c string
- */
-#define MOD_TLS_VERSION "0.9.0"
-
-/**
- * @macro
- * Numerical representation of the version number of the md module
- * release. This is a 24 bit number with 8 bits for major number, 8 bits
- * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
- */
-#define MOD_TLS_VERSION_NUM 0x000900
-
-#endif /* mod_md_md_version_h */
diff --git a/test/modules/tls/__init__.py b/test/modules/tls/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/test/modules/tls/conf.py b/test/modules/tls/conf.py
deleted file mode 100644 (file)
index b34f746..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-import os
-from typing import List, Dict, Any
-
-from pyhttpd.conf import  HttpdConf
-from pyhttpd.env import HttpdTestEnv
-
-
-class TlsTestConf(HttpdConf):
-
-    def __init__(self, env: HttpdTestEnv, extras: Dict[str, Any] = None):
-        extras = extras if extras is not None else {}
-        super().__init__(env=env, extras=extras)
-
-    def start_tls_vhost(self, domains: List[str], port=None, ssl_module=None):
-        if ssl_module is None:
-            if not self.env.has_shared_module("tls"):
-                ssl_module = "mod_ssl"
-            else:
-                ssl_module = 'mod_tls'
-        super().start_vhost(domains=domains, port=port, doc_root=f"htdocs/{domains[0]}", ssl_module=ssl_module)
-
-    def end_tls_vhost(self):
-        self.end_vhost()
-
-    def add_tls_vhosts(self, domains: List[str], port=None, ssl_module=None):
-        for domain in domains:
-            self.start_tls_vhost(domains=[domain], port=port, ssl_module=ssl_module)
-            self.end_tls_vhost()
-
-    def add_md_vhosts(self, domains: List[str], port = None):
-        self.add([
-            f"LoadModule md_module       {self.env.libexec_dir}/mod_md.so",
-            "LogLevel md:debug",
-        ])
-        for domain in domains:
-            self.add(f"<MDomain {domain}>")
-            for cred in self.env.ca.get_credentials_for_name(domain):
-                cert_file = os.path.relpath(cred.cert_file, self.env.server_dir)
-                pkey_file = os.path.relpath(cred.pkey_file, self.env.server_dir) if cred.pkey_file else cert_file
-                self.add([
-                    f"    MDCertificateFile {cert_file}",
-                    f"    MDCertificateKeyFile {pkey_file}",
-                    ])
-            self.add("</MDomain>")
-            if self.env.has_shared_module("tls"):
-                ssl_module= "mod_tls"
-            else:
-                ssl_module= "mod_ssl"
-            super().add_vhost(domains=[domain], port=port, doc_root=f"htdocs/{domain}",
-                              with_ssl=True, with_certificates=False, ssl_module=ssl_module)
-
-    def add_md_base(self, domain: str):
-        self.add([
-            f"LoadModule md_module       {self.env.libexec_dir}/mod_md.so",
-            "LogLevel md:debug",
-            f"ServerName {domain}",
-            "MDBaseServer on",
-        ])
-        self.add(f"TLSEngine {self.env.https_port}")
-        self.add(f"<MDomain {domain}>")
-        for cred in self.env.ca.get_credentials_for_name(domain):
-            cert_file = os.path.relpath(cred.cert_file, self.env.server_dir)
-            pkey_file = os.path.relpath(cred.pkey_file, self.env.server_dir) if cred.pkey_file else cert_file
-            self.add([
-                f"MDCertificateFile {cert_file}",
-                f"MDCertificateKeyFile {pkey_file}",
-            ])
-        self.add("</MDomain>")
diff --git a/test/modules/tls/conftest.py b/test/modules/tls/conftest.py
deleted file mode 100644 (file)
index 6f6f983..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-import logging
-import os
-import sys
-import pytest
-
-sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
-
-from .env import TlsTestEnv
-
-
-def pytest_report_header(config, startdir):
-    _x = config
-    _x = startdir
-    env = TlsTestEnv()
-    return "mod_tls [apache: {aversion}({prefix})]".format(
-        prefix=env.prefix,
-        aversion=env.get_httpd_version()
-    )
-
-
-@pytest.fixture(scope="package")
-def env(pytestconfig) -> TlsTestEnv:
-    level = logging.INFO
-    console = logging.StreamHandler()
-    console.setLevel(level)
-    console.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
-    logging.getLogger('').addHandler(console)
-    logging.getLogger('').setLevel(level=level)
-    env = TlsTestEnv(pytestconfig=pytestconfig)
-    env.setup_httpd()
-    env.apache_access_log_clear()
-    env.httpd_error_log.clear_log()
-    return env
-
-@pytest.fixture(autouse=True, scope="package")
-def _stop_package_scope(env):
-    yield
-    assert env.apache_stop() == 0
diff --git a/test/modules/tls/env.py b/test/modules/tls/env.py
deleted file mode 100644 (file)
index efc4f0b..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-import inspect
-import logging
-import os
-import re
-import subprocess
-
-from datetime import timedelta, datetime
-from typing import List, Optional, Dict, Tuple, Union
-
-from pyhttpd.certs import CertificateSpec
-from pyhttpd.env import HttpdTestEnv, HttpdTestSetup
-from pyhttpd.result import ExecResult
-
-log = logging.getLogger(__name__)
-
-
-class TlsTestSetup(HttpdTestSetup):
-
-    def __init__(self, env: 'HttpdTestEnv'):
-        super().__init__(env=env)
-        self.add_source_dir(os.path.dirname(inspect.getfile(TlsTestSetup)))
-        self.add_modules(["tls", "http2", "cgid", "watchdog", "proxy_http2"])
-
-
-class TlsCipher:
-
-    def __init__(self, id: int, name: str, flavour: str,
-                 min_version: float, max_version: float = None,
-                 openssl: str = None):
-        self.id = id
-        self.name = name
-        self.flavour = flavour
-        self.min_version = min_version
-        self.max_version = max_version if max_version is not None else self.min_version
-        if openssl is None:
-            if name.startswith('TLS13_'):
-                openssl = re.sub(r'^TLS13_', 'TLS_', name)
-            else:
-                openssl = re.sub(r'^TLS_', '', name)
-                openssl = re.sub(r'_WITH_([^_]+)_', r'_\1_', openssl)
-                openssl = re.sub(r'_AES_(\d+)', r'_AES\1', openssl)
-                openssl = re.sub(r'(_POLY1305)_\S+$', r'\1', openssl)
-                openssl = re.sub(r'_', '-', openssl)
-        self.openssl_name = openssl
-        self.id_name = "TLS_CIPHER_0x{0:04x}".format(self.id)
-
-    def __repr__(self):
-        return self.name
-
-    def __str__(self):
-        return self.name
-
-
-class TlsTestEnv(HttpdTestEnv):
-
-    CURL_SUPPORTS_TLS_1_3 = None
-
-    @classmethod
-    @property
-    def is_unsupported(cls):
-        mpm_module = f"mpm_{os.environ['MPM']}" if 'MPM' in os.environ else 'mpm_event'
-        return mpm_module == 'mpm_prefork'
-
-    @classmethod
-    def curl_supports_tls_1_3(cls) -> bool:
-        if cls.CURL_SUPPORTS_TLS_1_3 is None:
-            # Unfortunately, there is no reliable, platform-independant
-            # way to verify that TLSv1.3 is properly supported by curl.
-            #
-            # p = subprocess.run(['curl', '--tlsv1.3', 'https://shouldneverexistreally'],
-            #                    stderr=subprocess.PIPE, stdout=subprocess.PIPE)
-            # return code 6 means the site could not be resolved, but the
-            # tls parameter was recognized
-            cls.CURL_SUPPORTS_TLS_1_3 = False
-        return cls.CURL_SUPPORTS_TLS_1_3
-
-
-    # current rustls supported ciphers in their order of preference
-    # used to test cipher selection, see test_06_ciphers.py
-    RUSTLS_CIPHERS = [
-        TlsCipher(0x1303, "TLS13_CHACHA20_POLY1305_SHA256", "CHACHA", 1.3),
-        TlsCipher(0x1302, "TLS13_AES_256_GCM_SHA384", "AES", 1.3),
-        TlsCipher(0x1301, "TLS13_AES_128_GCM_SHA256", "AES", 1.3),
-        TlsCipher(0xcca9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "ECDSA", 1.2),
-        TlsCipher(0xcca8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "RSA", 1.2),
-        TlsCipher(0xc02c, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "ECDSA", 1.2),
-        TlsCipher(0xc02b, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "ECDSA", 1.2),
-        TlsCipher(0xc030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "RSA", 1.2),
-        TlsCipher(0xc02f, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "RSA", 1.2),
-    ]
-
-    def __init__(self, pytestconfig=None):
-        super().__init__(pytestconfig=pytestconfig)
-        self._domain_a = "a.mod-tls.test"
-        self._domain_b = "b.mod-tls.test"
-        self.add_httpd_conf([
-            f'<Directory "{self.server_dir}/htdocs/{self.domain_a}">',
-            '    AllowOverride None',
-            '    Require all granted',
-            '    AddHandler cgi-script .py',
-            '    Options +ExecCGI',
-            '</Directory>',
-            f'<Directory "{self.server_dir}/htdocs/{self.domain_b}">',
-            '    AllowOverride None',
-            '    Require all granted',
-            '    AddHandler cgi-script .py',
-            '    Options +ExecCGI',
-            '</Directory>',
-            f'<VirtualHost *:{self.http_port}>',
-            '    ServerName localhost',
-            '    DocumentRoot "htdocs"',
-            '</VirtualHost>',
-            f'<VirtualHost *:{self.http_port}>',
-            f'    ServerName {self.domain_a}',
-            '    DocumentRoot "htdocs/a.mod-tls.test"',
-            '</VirtualHost>',
-            f'<VirtualHost *:{self.http_port}>',
-            f'    ServerName {self.domain_b}',
-            '    DocumentRoot "htdocs/b.mod-tls.test"',
-            '</VirtualHost>',
-        ])
-        self.add_cert_specs([
-            CertificateSpec(domains=[self.domain_a]),
-            CertificateSpec(domains=[self.domain_b], key_type='secp256r1', single_file=True),
-            CertificateSpec(domains=[self.domain_b], key_type='rsa4096'),
-            CertificateSpec(name="clientsX", sub_specs=[
-                CertificateSpec(name="user1", client=True, single_file=True),
-                CertificateSpec(name="user2", client=True, single_file=True),
-                CertificateSpec(name="user_expired", client=True,
-                                single_file=True, valid_from=timedelta(days=-91),
-                                valid_to=timedelta(days=-1)),
-            ]),
-            CertificateSpec(name="clientsY", sub_specs=[
-                CertificateSpec(name="user1", client=True, single_file=True),
-            ]),
-            CertificateSpec(name="user1", client=True, single_file=True),
-        ])
-        if not HttpdTestEnv.has_shared_module("tls"):
-            self.add_httpd_log_modules(['ssl'])
-        else:
-            self.add_httpd_log_modules(['tls'])
-
-
-    def setup_httpd(self, setup: TlsTestSetup = None):
-        if setup is None:
-            setup = TlsTestSetup(env=self)
-        super().setup_httpd(setup=setup)
-
-    @property
-    def domain_a(self) -> str:
-        return self._domain_a
-
-    @property
-    def domain_b(self) -> str:
-        return self._domain_b
-
-    def tls_get(self, domain, paths: Union[str, List[str]], options: List[str] = None, no_stdout_list = False) -> ExecResult:
-        if isinstance(paths, str):
-            paths = [paths]
-        urls = [f"https://{domain}:{self.https_port}{path}" for path in paths]
-        return self.curl_raw(urls=urls, options=options, no_stdout_list=no_stdout_list)
-
-    def tls_get_json(self, domain: str, path: str, options=None):
-        r = self.tls_get(domain=domain, paths=path, options=options)
-        return r.json
-
-    def run_diff(self, fleft: str, fright: str) -> ExecResult:
-        return self.run(['diff', '-u', fleft, fright])
-
-    def openssl(self, args: List[str]) -> ExecResult:
-        return self.run(['openssl'] + args)
-
-    def openssl_client(self, domain, extra_args: List[str] = None) -> ExecResult:
-        args = ["s_client", "-CAfile", self.ca.cert_file, "-servername", domain,
-                "-connect", "localhost:{port}".format(
-                    port=self.https_port
-                )]
-        if extra_args:
-            args.extend(extra_args)
-        args.extend([])
-        return self.openssl(args)
-
-    OPENSSL_SUPPORTED_PROTOCOLS = None
-
-    @staticmethod
-    def openssl_supports_tls_1_3() -> bool:
-        if TlsTestEnv.OPENSSL_SUPPORTED_PROTOCOLS is None:
-            env = TlsTestEnv()
-            r = env.openssl(args=["ciphers", "-v"])
-            protos = set()
-            ciphers = set()
-            for line in r.stdout.splitlines():
-                m = re.match(r'^(\S+)\s+(\S+)\s+(.*)$', line)
-                if m:
-                    ciphers.add(m.group(1))
-                    protos.add(m.group(2))
-            TlsTestEnv.OPENSSL_SUPPORTED_PROTOCOLS = protos
-            TlsTestEnv.OPENSSL_SUPPORTED_CIPHERS = ciphers
-        return "TLSv1.3" in TlsTestEnv.OPENSSL_SUPPORTED_PROTOCOLS
diff --git a/test/modules/tls/htdocs/a.mod-tls.test/index.json b/test/modules/tls/htdocs/a.mod-tls.test/index.json
deleted file mode 100644 (file)
index ffc32cb..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "domain": "a.mod-tls.test"
-}
\ No newline at end of file
diff --git a/test/modules/tls/htdocs/a.mod-tls.test/vars.py b/test/modules/tls/htdocs/a.mod-tls.test/vars.py
deleted file mode 100755 (executable)
index bd520e2..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env python3
-import json
-import os, sys
-from urllib import parse
-import multipart # https://github.com/andrew-d/python-multipart (`apt install python3-multipart`)
-
-
-def get_request_params():
-    oforms = {}
-    ofiles = {}
-    if "REQUEST_URI" in os.environ:
-        qforms = parse.parse_qs(parse.urlsplit(os.environ["REQUEST_URI"]).query)
-        for name, values in qforms.items():
-            oforms[name] = values[0]
-    if "HTTP_CONTENT_TYPE" in os.environ:
-        ctype = os.environ["HTTP_CONTENT_TYPE"]
-        if ctype == "application/x-www-form-urlencoded":
-            qforms = parse.parse_qs(parse.urlsplit(sys.stdin.read()).query)
-            for name, values in qforms.items():
-                oforms[name] = values[0]
-        elif ctype.startswith("multipart/"):
-            def on_field(field):
-                oforms[field.field_name] = field.value
-            def on_file(file):
-                ofiles[field.field_name] = field.value
-            multipart.parse_form(headers={"Content-Type": ctype}, input_stream=sys.stdin.buffer, on_field=on_field, on_file=on_file)
-    return oforms, ofiles
-
-
-forms, files = get_request_params()
-
-jenc = json.JSONEncoder()
-
-def get_var(name: str, def_val: str = ""):
-    if name in os.environ:
-        return os.environ[name]
-    return def_val
-
-def get_json_var(name: str, def_val: str = ""):
-    var = get_var(name, def_val=def_val)
-    return jenc.encode(var)
-
-
-name = forms['name'] if 'name' in forms else None
-
-print("Content-Type: application/json\n")
-if name:
-    print(f"""{{ "{name}" : {get_json_var(name, '')}}}""")
-else:
-    print(f"""{{ "https" : {get_json_var('HTTPS', '')},
-  "host" : {get_json_var('SERVER_NAME', '')},
-  "protocol" : {get_json_var('SERVER_PROTOCOL', '')},
-  "ssl_protocol" : {get_json_var('SSL_PROTOCOL', '')},
-  "ssl_cipher" : {get_json_var('SSL_CIPHER', '')}
-}}""")
-
diff --git a/test/modules/tls/htdocs/b.mod-tls.test/dir1/vars.py b/test/modules/tls/htdocs/b.mod-tls.test/dir1/vars.py
deleted file mode 100755 (executable)
index b86a968..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python3
-import os
-
-def get_var(name: str, def_val: str = ""):
-    if name in os.environ:
-        return os.environ[name]
-    return def_val
-
-print("Content-Type: application/json")
-print()
-print("""{{ "https" : "{https}",
-  "host" : "{server_name}",
-  "protocol" : "{protocol}",
-  "ssl_protocol" : "{ssl_protocol}",
-  "ssl_cipher" : "{ssl_cipher}"
-}}""".format(
-    https=get_var('HTTPS', ''),
-    server_name=get_var('SERVER_NAME', ''),
-    protocol=get_var('SERVER_PROTOCOL', ''),
-    ssl_protocol=get_var('SSL_PROTOCOL', ''),
-    ssl_cipher=get_var('SSL_CIPHER', ''),
-))
-
diff --git a/test/modules/tls/htdocs/b.mod-tls.test/index.json b/test/modules/tls/htdocs/b.mod-tls.test/index.json
deleted file mode 100644 (file)
index e5d3ccf..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "domain": "b.mod-tls.test"
-}
\ No newline at end of file
diff --git a/test/modules/tls/htdocs/b.mod-tls.test/resp-jitter.py b/test/modules/tls/htdocs/b.mod-tls.test/resp-jitter.py
deleted file mode 100755 (executable)
index f7b1349..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python3
-import random
-import sys
-import time
-from datetime import timedelta
-
-random.seed()
-to_write = total_len = random.randint(1, 10*1024*1024)
-
-sys.stdout.write("Content-Type: application/octet-stream\n")
-sys.stdout.write(f"Content-Length: {total_len}\n")
-sys.stdout.write("\n")
-sys.stdout.flush()
-
-while to_write > 0:
-    len = random.randint(1, 1024*1024)
-    len = min(len, to_write)
-    sys.stdout.buffer.write(random.randbytes(len))
-    to_write -= len
-    delay = timedelta(seconds=random.uniform(0.0, 0.5))
-    time.sleep(delay.total_seconds())
-sys.stdout.flush()
-
diff --git a/test/modules/tls/htdocs/b.mod-tls.test/vars.py b/test/modules/tls/htdocs/b.mod-tls.test/vars.py
deleted file mode 100755 (executable)
index bd520e2..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env python3
-import json
-import os, sys
-from urllib import parse
-import multipart # https://github.com/andrew-d/python-multipart (`apt install python3-multipart`)
-
-
-def get_request_params():
-    oforms = {}
-    ofiles = {}
-    if "REQUEST_URI" in os.environ:
-        qforms = parse.parse_qs(parse.urlsplit(os.environ["REQUEST_URI"]).query)
-        for name, values in qforms.items():
-            oforms[name] = values[0]
-    if "HTTP_CONTENT_TYPE" in os.environ:
-        ctype = os.environ["HTTP_CONTENT_TYPE"]
-        if ctype == "application/x-www-form-urlencoded":
-            qforms = parse.parse_qs(parse.urlsplit(sys.stdin.read()).query)
-            for name, values in qforms.items():
-                oforms[name] = values[0]
-        elif ctype.startswith("multipart/"):
-            def on_field(field):
-                oforms[field.field_name] = field.value
-            def on_file(file):
-                ofiles[field.field_name] = field.value
-            multipart.parse_form(headers={"Content-Type": ctype}, input_stream=sys.stdin.buffer, on_field=on_field, on_file=on_file)
-    return oforms, ofiles
-
-
-forms, files = get_request_params()
-
-jenc = json.JSONEncoder()
-
-def get_var(name: str, def_val: str = ""):
-    if name in os.environ:
-        return os.environ[name]
-    return def_val
-
-def get_json_var(name: str, def_val: str = ""):
-    var = get_var(name, def_val=def_val)
-    return jenc.encode(var)
-
-
-name = forms['name'] if 'name' in forms else None
-
-print("Content-Type: application/json\n")
-if name:
-    print(f"""{{ "{name}" : {get_json_var(name, '')}}}""")
-else:
-    print(f"""{{ "https" : {get_json_var('HTTPS', '')},
-  "host" : {get_json_var('SERVER_NAME', '')},
-  "protocol" : {get_json_var('SERVER_PROTOCOL', '')},
-  "ssl_protocol" : {get_json_var('SSL_PROTOCOL', '')},
-  "ssl_cipher" : {get_json_var('SSL_CIPHER', '')}
-}}""")
-
diff --git a/test/modules/tls/htdocs/index.html b/test/modules/tls/htdocs/index.html
deleted file mode 100644 (file)
index 3c07626..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-    <head>
-        <title>mod_h2 test site generic</title>
-    </head>
-    <body>
-        <h1>mod_h2 test site generic</h1>
-    </body>
-</html>
-
diff --git a/test/modules/tls/htdocs/index.json b/test/modules/tls/htdocs/index.json
deleted file mode 100644 (file)
index 6d456e0..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "domain": "localhost"
-}
\ No newline at end of file
diff --git a/test/modules/tls/test_01_apache.py b/test/modules/tls/test_01_apache.py
deleted file mode 100644 (file)
index cb6af6d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-import pytest
-
-from .conf import TlsTestConf
-
-
-class TestApache:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        TlsTestConf(env=env).install()
-        assert env.apache_restart() == 0
-
-    def test_tls_01_apache_http(self, env):
-        assert env.is_live(env.http_base_url)
diff --git a/test/modules/tls/test_02_conf.py b/test/modules/tls/test_02_conf.py
deleted file mode 100644 (file)
index 88be80c..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-import os
-from datetime import timedelta
-
-import pytest
-
-from .conf import TlsTestConf
-
-
-class TestConf:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        TlsTestConf(env=env).install()
-        assert env.apache_restart() == 0
-
-    @pytest.fixture(autouse=True, scope='function')
-    def _function_scope(self, env):
-        if env.is_live(timeout=timedelta(milliseconds=100)):
-            assert env.apache_stop() == 0
-
-    def test_tls_02_conf_cert_args_missing(self, env):
-        conf = TlsTestConf(env=env)
-        conf.add("TLSCertificate")
-        conf.install()
-        assert env.apache_fail() == 0
-
-    def test_tls_02_conf_cert_single_arg(self, env):
-        conf = TlsTestConf(env=env)
-        conf.add("TLSCertificate cert.pem")
-        conf.install()
-        assert env.apache_fail() == 0
-
-    def test_tls_02_conf_cert_file_missing(self, env):
-        conf = TlsTestConf(env=env)
-        conf.add("TLSCertificate cert.pem key.pem")
-        conf.install()
-        assert env.apache_fail() == 0
-
-    def test_tls_02_conf_cert_file_exist(self, env):
-        conf = TlsTestConf(env=env)
-        conf.add("TLSCertificate test-02-cert.pem test-02-key.pem")
-        conf.install()
-        for name in ["test-02-cert.pem", "test-02-key.pem"]:
-            with open(os.path.join(env.server_dir, name), "w") as fd:
-                fd.write("")
-        assert env.apache_fail() == 0
-
-    def test_tls_02_conf_cert_listen_missing(self, env):
-        conf = TlsTestConf(env=env)
-        conf.add("TLSEngine")
-        conf.install()
-        assert env.apache_fail() == 0
-
-    def test_tls_02_conf_cert_listen_wrong(self, env):
-        conf = TlsTestConf(env=env)
-        conf.add("TLSEngine ^^^^^")
-        conf.install()
-        assert env.apache_fail() == 0
-
-    @pytest.mark.parametrize("listen", [
-        "443",
-        "129.168.178.188:443",
-        "[::]:443",
-    ])
-    def test_tls_02_conf_cert_listen_valid(self, env, listen: str):
-        conf = TlsTestConf(env=env)
-        if not env.has_shared_module("tls"):
-            # Without cert/key openssl will complain
-            conf.add("SSLEngine on");
-            conf.install()
-            assert env.apache_restart() == 1
-        else:
-            conf.add("TLSEngine {listen}".format(listen=listen))
-            conf.install()
-            assert env.apache_restart() == 0
-
-    def test_tls_02_conf_cert_listen_cert(self, env):
-        domain = env.domain_a
-        conf = TlsTestConf(env=env)
-        conf.add_tls_vhosts(domains=[domain])
-        conf.install()
-        assert env.apache_restart() == 0
-
-    def test_tls_02_conf_proto_wrong(self, env):
-        conf = TlsTestConf(env=env)
-        conf.add("TLSProtocol wrong")
-        conf.install()
-        assert env.apache_fail() == 0
-
-    @pytest.mark.parametrize("proto", [
-        "default",
-        "TLSv1.2+",
-        "TLSv1.3+",
-        "TLSv0x0303+",
-    ])
-    def test_tls_02_conf_proto_valid(self, env, proto):
-        conf = TlsTestConf(env=env)
-        conf.add("TLSProtocol {proto}".format(proto=proto))
-        conf.install()
-        assert env.apache_restart() == 0
-
-    def test_tls_02_conf_honor_wrong(self, env):
-        conf = TlsTestConf(env=env)
-        conf.add("TLSHonorClientOrder wrong")
-        conf.install()
-        assert env.apache_fail() == 0
-
-    @pytest.mark.parametrize("honor", [
-        "on",
-        "OfF",
-    ])
-    def test_tls_02_conf_honor_valid(self, env, honor: str):
-        conf = TlsTestConf(env=env)
-        conf.add("TLSHonorClientOrder {honor}".format(honor=honor))
-        conf.install()
-        assert env.apache_restart() == 0
-
-    @pytest.mark.parametrize("cipher", [
-        "default",
-        "TLS13_AES_128_GCM_SHA256:TLS13_AES_256_GCM_SHA384:TLS13_CHACHA20_POLY1305_SHA256",
-        "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:"
-        "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:"
-        "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
-        """TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 \\
-        TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384  TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\\
-        TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"""
-    ])
-    def test_tls_02_conf_cipher_valid(self, env, cipher):
-        conf = TlsTestConf(env=env)
-        conf.add("TLSCiphersPrefer {cipher}".format(cipher=cipher))
-        conf.install()
-        assert env.apache_restart() == 0
-
-    @pytest.mark.parametrize("cipher", [
-        "wrong",
-        "YOLO",
-        "TLS_NULL_WITH_NULL_NULLX",       # not supported
-        "TLS_DHE_RSA_WITH_AES128_GCM_SHA256",     # not supported
-    ])
-    def test_tls_02_conf_cipher_wrong(self, env, cipher):
-        conf = TlsTestConf(env=env)
-        conf.add("TLSCiphersPrefer {cipher}".format(cipher=cipher))
-        conf.install()
-        assert env.apache_fail() == 0
diff --git a/test/modules/tls/test_03_sni.py b/test/modules/tls/test_03_sni.py
deleted file mode 100644 (file)
index cbd142a..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-from datetime import timedelta
-
-import pytest
-
-from .conf import TlsTestConf
-from .env import TlsTestEnv
-
-
-class TestSni:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        conf = TlsTestConf(env=env)
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-
-    @pytest.fixture(autouse=True, scope='function')
-    def _function_scope(self, env):
-        pass
-
-    def test_tls_03_sni_get_a(self, env):
-        # do we see the correct json for the domain_a?
-        data = env.tls_get_json(env.domain_a, "/index.json")
-        assert data == {'domain': env.domain_a}
-
-    def test_tls_03_sni_get_b(self, env):
-        # do we see the correct json for the domain_a?
-        data = env.tls_get_json(env.domain_b, "/index.json")
-        assert data == {'domain': env.domain_b}
-
-    def test_tls_03_sni_unknown(self, env):
-        # connection will be denied as cert does not cover this domain
-        domain_unknown = "unknown.test"
-        r = env.tls_get(domain_unknown, "/index.json")
-        assert r.exit_code != 0
-        #
-        env.httpd_error_log.ignore_recent(
-            lognos = [
-                "AH10353"   # cannot decrypt peer's message
-            ]
-        )
-
-    def test_tls_03_sni_request_other_same_config(self, env):
-        # do we see the first vhost response for another domain with different certs?
-        r = env.tls_get(env.domain_a, "/index.json", options=[
-            "-vvvv", "--header", "Host: {0}".format(env.domain_b)
-        ])
-        # request is marked as misdirected
-        assert r.exit_code == 0
-        assert r.json is None
-        assert r.response['status'] == 421
-        #
-        env.httpd_error_log.ignore_recent(
-            lognos = [
-                "AH10345"   # Connection host selected via SNI and request have incompatible TLS configurations
-            ]
-        )
-
-    def test_tls_03_sni_request_other_other_honor(self, env):
-        # do we see the first vhost response for an unknown domain?
-        conf = TlsTestConf(env=env, extras={
-            env.domain_a: "TLSProtocol TLSv1.2+",
-            env.domain_b: "TLSProtocol TLSv1.3+"
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-        r = env.tls_get(env.domain_a, "/index.json", options=[
-            "-vvvv", "--tls-max", "1.2", "--header", "Host: {0}".format(env.domain_b)
-        ])
-        # request denied
-        assert r.exit_code == 0
-        assert r.json is None
-        #
-        env.httpd_error_log.ignore_recent(
-            lognos = [
-                "AH10345"   # Connection host selected via SNI and request have incompatible TLS configurations
-            ]
-        )
-
-    @pytest.mark.skip('openssl behaviour changed on ventura, unreliable')
-    def test_tls_03_sni_bad_hostname(self, env):
-        # curl checks hostnames we give it, but the openssl client
-        # does not. Good for us, since we need to test it.
-        r = env.openssl(["s_client", "-connect",
-                          "localhost:{0}".format(env.https_port),
-                          "-servername", b'x\x2f.y'.decode()])
-        assert r.exit_code == 1, r.stderr
diff --git a/test/modules/tls/test_04_get.py b/test/modules/tls/test_04_get.py
deleted file mode 100644 (file)
index 6944381..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-import os
-import time
-from datetime import timedelta
-
-import pytest
-
-from .env import TlsTestEnv
-from .conf import TlsTestConf
-
-
-def mk_text_file(fpath: str, lines: int):
-    t110 = 11 * "0123456789"
-    with open(fpath, "w") as fd:
-        for i in range(lines):
-            fd.write("{0:015d}: ".format(i))  # total 128 bytes per line
-            fd.write(t110)
-            fd.write("\n")
-
-
-class TestGet:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        conf = TlsTestConf(env=env)
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        docs_a = os.path.join(env.server_docs_dir, env.domain_a)
-        mk_text_file(os.path.join(docs_a, "1k.txt"), 8)
-        mk_text_file(os.path.join(docs_a, "10k.txt"), 80)
-        mk_text_file(os.path.join(docs_a, "100k.txt"), 800)
-        mk_text_file(os.path.join(docs_a, "1m.txt"), 8000)
-        mk_text_file(os.path.join(docs_a, "10m.txt"), 80000)
-        assert env.apache_restart() == 0
-
-    @pytest.mark.parametrize("fname, flen", [
-        ("1k.txt", 1024),
-        ("10k.txt", 10*1024),
-        ("100k.txt", 100 * 1024),
-        ("1m.txt", 1000 * 1024),
-        ("10m.txt", 10000 * 1024),
-    ])
-    def test_tls_04_get(self, env, fname, flen):
-        # do we see the correct json for the domain_a?
-        docs_a = os.path.join(env.server_docs_dir, env.domain_a)
-        r = env.tls_get(env.domain_a, "/{0}".format(fname))
-        assert r.exit_code == 0
-        assert len(r.stdout) == flen
-        pref = os.path.join(docs_a, fname)
-        pout = os.path.join(docs_a, "{0}.out".format(fname))
-        with open(pout, 'w') as fd:
-            fd.write(r.stdout)
-        dr = env.run_diff(pref, pout)
-        assert dr.exit_code == 0, "differences found:\n{0}".format(dr.stdout)
-
-    @pytest.mark.parametrize("fname, flen", [
-        ("1k.txt", 1024),
-    ])
-    def test_tls_04_double_get(self, env, fname, flen):
-        # we'd like to check that we can do >1 requests on the same connection
-        # however curl hides that from us, unless we analyze its verbose output
-        docs_a = os.path.join(env.server_docs_dir, env.domain_a)
-        r = env.tls_get(env.domain_a, no_stdout_list=True, paths=[
-            "/{0}".format(fname),
-            "/{0}".format(fname)
-        ])
-        assert r.exit_code == 0
-        assert len(r.stdout) == 2*flen
diff --git a/test/modules/tls/test_05_proto.py b/test/modules/tls/test_05_proto.py
deleted file mode 100644 (file)
index d874a90..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-import time
-from datetime import timedelta
-import socket
-from threading import Thread
-
-import pytest
-
-from .conf import TlsTestConf
-from .env import TlsTestEnv
-
-
-class TestProto:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        conf = TlsTestConf(env=env, extras={
-            env.domain_a: "TLSProtocol TLSv1.3+",
-            env.domain_b: [
-                "# the commonly used name",
-                "TLSProtocol TLSv1.2+",
-                "# the numeric one (yes, this is 1.2)",
-                "TLSProtocol TLSv0x0303+",
-            ],
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-
-    @pytest.fixture(autouse=True, scope='function')
-    def _function_scope(self, env):
-        pass
-
-    def test_tls_05_proto_1_2(self, env):
-        r = env.tls_get(env.domain_b, "/index.json", options=["--tlsv1.2"])
-        assert r.exit_code == 0, r.stderr
-
-    @pytest.mark.skip('curl does not have TLSv1.3 on all platforms')
-    def test_tls_05_proto_1_3(self, env):
-        r = env.tls_get(env.domain_a, "/index.json", options=["--tlsv1.3", '-v'])
-        if True: # testing TlsTestEnv.curl_supports_tls_1_3() is unreliable (curl should support TLS1.3 nowadays..)
-            assert r.exit_code == 0, f'{r}'
-        else:
-            assert r.exit_code == 4, f'{r}'
-
-    def test_tls_05_proto_close(self, env):
-        s = socket.create_connection(('localhost', env.https_port))
-        time.sleep(0.1)
-        s.close()
-
-    def test_tls_05_proto_ssl_close(self, env):
-        conf = TlsTestConf(env=env, extras={
-            'base': "LogLevel ssl:debug",
-            env.domain_a: "SSLProtocol TLSv1.3",
-            env.domain_b: "SSLProtocol TLSv1.2",
-        })
-        for d in [env.domain_a, env.domain_b]:
-            conf.add_vhost(domains=[d], port=env.https_port)
-        conf.install()
-        assert env.apache_restart() == 0
-        s = socket.create_connection(('localhost', env.https_port))
-        time.sleep(0.1)
-        s.close()
-
-
diff --git a/test/modules/tls/test_06_ciphers.py b/test/modules/tls/test_06_ciphers.py
deleted file mode 100644 (file)
index 4bedd69..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-import re
-from datetime import timedelta
-
-import pytest
-
-from .env import TlsTestEnv
-from .conf import TlsTestConf
-
-
-class TestCiphers:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        conf = TlsTestConf(env=env, extras={
-            'base': "TLSHonorClientOrder off",
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-
-    @pytest.fixture(autouse=True, scope='function')
-    def _function_scope(self, env):
-        pass
-
-    def _get_protocol_cipher(self, output: str):
-        protocol = None
-        cipher = None
-        for line in output.splitlines():
-            m = re.match(r'^\s+Protocol\s*:\s*(\S+)$', line)
-            if m:
-                protocol = m.group(1)
-                continue
-            m = re.match(r'^\s+Cipher\s*:\s*(\S+)$', line)
-            if m:
-                cipher = m.group(1)
-        return protocol, cipher
-
-    def test_tls_06_ciphers_ecdsa(self, env):
-        ecdsa_1_2 = [c for c in env.RUSTLS_CIPHERS
-                     if c.max_version == 1.2 and c.flavour == 'ECDSA'][0]
-        # client speaks only this cipher, see that it gets it
-        r = env.openssl_client(env.domain_b, extra_args=[
-            "-cipher", ecdsa_1_2.openssl_name, "-tls1_2"
-        ])
-        protocol, cipher = self._get_protocol_cipher(r.stdout)
-        assert protocol == "TLSv1.2", r.stdout
-        assert cipher == ecdsa_1_2.openssl_name, r.stdout
-
-    def test_tls_06_ciphers_rsa(self, env):
-        rsa_1_2 = [c for c in env.RUSTLS_CIPHERS
-                   if c.max_version == 1.2 and c.flavour == 'RSA'][0]
-        # client speaks only this cipher, see that it gets it
-        r = env.openssl_client(env.domain_b, extra_args=[
-            "-cipher", rsa_1_2.openssl_name, "-tls1_2"
-        ])
-        protocol, cipher = self._get_protocol_cipher(r.stdout)
-        assert protocol == "TLSv1.2", r.stdout
-        assert cipher == rsa_1_2.openssl_name, r.stdout
-
-    @pytest.mark.parametrize("cipher", [
-        c for c in TlsTestEnv.RUSTLS_CIPHERS if c.max_version == 1.2 and c.flavour == 'ECDSA'
-    ], ids=[
-        c.name for c in TlsTestEnv.RUSTLS_CIPHERS if c.max_version == 1.2 and c.flavour == 'ECDSA'
-    ])
-    def test_tls_06_ciphers_server_prefer_ecdsa(self, env, cipher):
-        # Select a ECSDA ciphers as preference and suppress all RSA ciphers.
-        # The last is not strictly necessary since rustls prefers ECSDA anyway
-        suppress_names = [c.name for c in env.RUSTLS_CIPHERS
-                          if c.max_version == 1.2 and c.flavour == 'RSA']
-        conf = TlsTestConf(env=env, extras={
-            env.domain_b: [
-                "TLSHonorClientOrder off",
-                f"TLSCiphersPrefer {cipher.name}",
-                f"TLSCiphersSuppress {':'.join(suppress_names)}",
-            ]
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-        r = env.openssl_client(env.domain_b, extra_args=["-tls1_2"])
-        client_proto, client_cipher = self._get_protocol_cipher(r.stdout)
-        assert client_proto == "TLSv1.2", r.stdout
-        assert client_cipher == cipher.openssl_name, r.stdout
-
-    @pytest.mark.skip(reason="Wrong certified key selected by rustls")
-    # see <https://github.com/rustls/rustls-ffi/issues/236>
-    @pytest.mark.parametrize("cipher", [
-        c for c in TlsTestEnv.RUSTLS_CIPHERS if c.max_version == 1.2 and c.flavour == 'RSA'
-    ], ids=[
-        c.name for c in TlsTestEnv.RUSTLS_CIPHERS if c.max_version == 1.2 and c.flavour == 'RSA'
-    ])
-    def test_tls_06_ciphers_server_prefer_rsa(self, env, cipher):
-        # Select a RSA ciphers as preference and suppress all ECDSA ciphers.
-        # The last is necessary since rustls prefers ECSDA and openssl leaks that it can.
-        suppress_names = [c.name for c in env.RUSTLS_CIPHERS
-                          if c.max_version == 1.2 and c.flavour == 'ECDSA']
-        conf = TlsTestConf(env=env, extras={
-            env.domain_b: [
-                "TLSHonorClientOrder off",
-                f"TLSCiphersPrefer {cipher.name}",
-                f"TLSCiphersSuppress {':'.join(suppress_names)}",
-            ]
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-        r = env.openssl_client(env.domain_b, extra_args=["-tls1_2"])
-        client_proto, client_cipher = self._get_protocol_cipher(r.stdout)
-        assert client_proto == "TLSv1.2", r.stdout
-        assert client_cipher == cipher.openssl_name, r.stdout
-
-    @pytest.mark.skip(reason="Wrong certified key selected by rustls")
-    # see <https://github.com/rustls/rustls-ffi/issues/236>
-    @pytest.mark.parametrize("cipher", [
-        c for c in TlsTestEnv.RUSTLS_CIPHERS if c.max_version == 1.2 and c.flavour == 'RSA'
-    ], ids=[
-        c.openssl_name for c in TlsTestEnv.RUSTLS_CIPHERS if c.max_version == 1.2 and c.flavour == 'RSA'
-    ])
-    def test_tls_06_ciphers_server_prefer_rsa_alias(self, env, cipher):
-        # same as above, but using openssl names for ciphers
-        suppress_names = [c.openssl_name for c in env.RUSTLS_CIPHERS
-                          if c.max_version == 1.2 and c.flavour == 'ECDSA']
-        conf = TlsTestConf(env=env, extras={
-            env.domain_b: [
-                "TLSHonorClientOrder off",
-                f"TLSCiphersPrefer {cipher.openssl_name}",
-                f"TLSCiphersSuppress {':'.join(suppress_names)}",
-            ]
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-        r = env.openssl_client(env.domain_b, extra_args=["-tls1_2"])
-        client_proto, client_cipher = self._get_protocol_cipher(r.stdout)
-        assert client_proto == "TLSv1.2", r.stdout
-        assert client_cipher == cipher.openssl_name, r.stdout
-
-    @pytest.mark.skip(reason="Wrong certified key selected by rustls")
-    # see <https://github.com/rustls/rustls-ffi/issues/236>
-    @pytest.mark.parametrize("cipher", [
-        c for c in TlsTestEnv.RUSTLS_CIPHERS if c.max_version == 1.2 and c.flavour == 'RSA'
-    ], ids=[
-        c.id_name for c in TlsTestEnv.RUSTLS_CIPHERS if c.max_version == 1.2 and c.flavour == 'RSA'
-    ])
-    def test_tls_06_ciphers_server_prefer_rsa_id(self, env, cipher):
-        # same as above, but using openssl names for ciphers
-        suppress_names = [c.id_name for c in env.RUSTLS_CIPHERS
-                          if c.max_version == 1.2 and c.flavour == 'ECDSA']
-        conf = TlsTestConf(env=env, extras={
-            env.domain_b: [
-                "TLSHonorClientOrder off",
-                f"TLSCiphersPrefer {cipher.id_name}",
-                f"TLSCiphersSuppress {':'.join(suppress_names)}",
-            ]
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-        r = env.openssl_client(env.domain_b, extra_args=["-tls1_2"])
-        client_proto, client_cipher = self._get_protocol_cipher(r.stdout)
-        assert client_proto == "TLSv1.2", r.stdout
-        assert client_cipher == cipher.openssl_name, r.stdout
-
-    def test_tls_06_ciphers_pref_unknown(self, env):
-        conf = TlsTestConf(env=env, extras={
-            env.domain_b: "TLSCiphersPrefer TLS_MY_SUPER_CIPHER:SSL_WHAT_NOT"
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() != 0
-        # get a working config again, so that subsequent test cases do not stumble
-        conf = TlsTestConf(env=env)
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        env.apache_restart()
-
-    def test_tls_06_ciphers_pref_unsupported(self, env):
-        # a warning on preferring a known, but not supported cipher
-        conf = TlsTestConf(env=env, extras={
-            env.domain_b: "TLSCiphersPrefer TLS_NULL_WITH_NULL_NULL"
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        if not conf.env.has_shared_module("tls"):
-            assert env.apache_restart() != 0
-        else:
-            assert env.apache_restart() == 0
-        #
-        env.httpd_error_log.ignore_recent(
-            lognos = [
-                "AH10319"   # Server has TLSCiphersPrefer configured that are not supported by rustls
-            ]
-        )
-
-    def test_tls_06_ciphers_supp_unknown(self, env):
-        conf = TlsTestConf(env=env, extras={
-            env.domain_b: "TLSCiphersSuppress TLS_MY_SUPER_CIPHER:SSL_WHAT_NOT"
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() != 0
-
-    def test_tls_06_ciphers_supp_unsupported(self, env):
-        # no warnings on suppressing known, but not supported ciphers
-        conf = TlsTestConf(env=env, extras={
-            env.domain_b: "TLSCiphersSuppress TLS_NULL_WITH_NULL_NULL"
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        if not conf.env.has_shared_module("tls"):
-            return
-        assert env.apache_restart() == 0
diff --git a/test/modules/tls/test_07_alpn.py b/test/modules/tls/test_07_alpn.py
deleted file mode 100644 (file)
index 6017372..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-import re
-from datetime import timedelta
-
-import pytest
-
-from .conf import TlsTestConf
-from .env import TlsTestEnv
-
-
-@pytest.mark.skipif(condition=TlsTestEnv.is_unsupported, reason="h2 not supported here")
-class TestAlpn:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        conf = TlsTestConf(env=env, extras={
-            env.domain_b: "Protocols h2 http/1.1"
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-
-    @pytest.fixture(autouse=True, scope='function')
-    def _function_scope(self, env):
-        pass
-
-    def _get_protocol(self, output: str):
-        for line in output.splitlines():
-            m = re.match(r'^\*\s+ALPN[:,] server accepted (to use\s+)?(.*)$', line)
-            if m:
-                return m.group(2)
-        return None
-
-    def test_tls_07_alpn_get_a(self, env):
-        # do we see the correct json for the domain_a?
-        r = env.tls_get(env.domain_a, "/index.json", options=["-vvvvvv", "--http1.1"])
-        assert r.exit_code == 0, r.stderr
-        protocol = self._get_protocol(r.stderr)
-        assert protocol == "http/1.1", r.stderr
-
-    def test_tls_07_alpn_get_b(self, env):
-        # do we see the correct json for the domain_b?
-        r = env.tls_get(env.domain_b, "/index.json", options=["-vvvvvv"])
-        assert r.exit_code == 0, r.stderr
-        protocol = self._get_protocol(r.stderr)
-        assert protocol == "h2", r.stderr
diff --git a/test/modules/tls/test_08_vars.py b/test/modules/tls/test_08_vars.py
deleted file mode 100644 (file)
index 0e3ee74..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-import re
-
-import pytest
-
-from .conf import TlsTestConf
-from .env import TlsTestEnv
-
-
-class TestVars:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        conf = TlsTestConf(env=env, extras={
-            'base': [
-                "TLSHonorClientOrder off",
-                "TLSOptions +StdEnvVars",
-            ]
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-
-    def test_tls_08_vars_root(self, env):
-        # in domain_b root, the StdEnvVars is switch on
-        exp_proto = "TLSv1.2"
-        if env.has_shared_module("tls"):
-            exp_cipher = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
-        else:
-            exp_cipher = "ECDHE-ECDSA-AES256-GCM-SHA384"
-        options = [ '--tls-max', '1.2']
-        r = env.tls_get(env.domain_b, "/vars.py", options=options)
-        assert r.exit_code == 0, r.stderr
-        assert r.json == {
-            'https': 'on',
-            'host': 'b.mod-tls.test',
-            'protocol': 'HTTP/1.1',
-            'ssl_protocol': exp_proto,
-            # this will vary by client potentially
-            'ssl_cipher': exp_cipher,
-        }
-
-    @pytest.mark.parametrize("name, value", [
-        ("SERVER_NAME", "b.mod-tls.test"),
-        ("SSL_SESSION_RESUMED", "Initial"),
-        ("SSL_SECURE_RENEG", "false"),
-        ("SSL_COMPRESS_METHOD", "NULL"),
-        ("SSL_CIPHER_EXPORT", "false"),
-        ("SSL_CLIENT_VERIFY", "NONE"),
-    ])
-    def test_tls_08_vars_const(self, env, name: str, value: str):
-        r = env.tls_get(env.domain_b, f"/vars.py?name={name}")
-        assert r.exit_code == 0, r.stderr
-        if env.has_shared_module("tls"):
-            assert r.json == {name: value}, r.stdout
-        else:
-            if name == "SSL_SECURE_RENEG":
-                value = "true"
-            assert r.json == {name: value}, r.stdout
-
-    @pytest.mark.parametrize("name, pattern", [
-        ("SSL_VERSION_INTERFACE", r'mod_tls/\d+\.\d+\.\d+'),
-        ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+(\.\d+)?'),
-    ])
-    def test_tls_08_vars_match(self, env, name: str, pattern: str):
-        r = env.tls_get(env.domain_b, f"/vars.py?name={name}")
-        assert r.exit_code == 0, r.stderr
-        assert name in r.json
-        if env.has_shared_module("tls"):
-            assert re.match(pattern, r.json[name]), r.json
-        else:
-            if name == "SSL_VERSION_INTERFACE":
-                pattern = r'mod_ssl/\d+\.\d+\.\d+'
-            else:
-                pattern = r'OpenSSL/\d+\.\d+\.\d+'
-            assert re.match(pattern, r.json[name]), r.json
diff --git a/test/modules/tls/test_09_timeout.py b/test/modules/tls/test_09_timeout.py
deleted file mode 100644 (file)
index 70cc894..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-import socket
-from datetime import timedelta
-
-import pytest
-
-from .conf import TlsTestConf
-
-
-class TestTimeout:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        conf = TlsTestConf(env=env, extras={
-            'base': "RequestReadTimeout handshake=1",
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-
-    @pytest.fixture(autouse=True, scope='function')
-    def _function_scope(self, env):
-        pass
-
-    def test_tls_09_timeout_handshake(self, env):
-        # in domain_b root, the StdEnvVars is switch on
-        s = socket.create_connection(('localhost', env.https_port))
-        s.send(b'1234')
-        s.settimeout(0.0)
-        try:
-            s.recv(1024)
-            assert False, "able to recv() on a TLS connection before we sent a hello"
-        except BlockingIOError:
-            pass
-        s.settimeout(3.0)
-        try:
-            while True:
-                buf = s.recv(1024)
-                if not buf:
-                    break
-                print("recv() -> {0}".format(buf))
-        except (socket.timeout, BlockingIOError):
-            assert False, "socket not closed as handshake timeout should trigger"
-        s.close()
diff --git a/test/modules/tls/test_10_session_id.py b/test/modules/tls/test_10_session_id.py
deleted file mode 100644 (file)
index 848bc1a..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-import re
-from typing import List
-
-import pytest
-
-from pyhttpd.result import ExecResult
-from .env import TlsTestEnv
-from .conf import TlsTestConf
-
-
-class TestSessionID:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        conf = TlsTestConf(env=env)
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-
-    def find_openssl_session_ids(self, r: ExecResult) -> List[str]:
-        ids = []
-        for line in r.stdout.splitlines():
-            m = re.match(r'^\s*Session-ID: (\S+)$', line)
-            if m:
-                ids.append(m.group(1))
-        return ids
-
-    def test_tls_10_session_id_12(self, env):
-        r = env.openssl_client(env.domain_b, extra_args=[
-            "-reconnect", "-tls1_2"
-        ])
-        session_ids = self.find_openssl_session_ids(r)
-        assert 1 < len(session_ids), "expected several session-ids: {0}, stderr={1}".format(
-            session_ids, r.stderr
-        )
-        assert 1 == len(set(session_ids)), "sesion-ids should all be the same: {0}".format(session_ids)
-
-    @pytest.mark.skipif(True or not TlsTestEnv.openssl_supports_tls_1_3(),
-                        reason="openssl TLSv1.3 session storage test incomplete")
-    def test_tls_10_session_id_13(self, env):
-        r = env.openssl_client(env.domain_b, extra_args=[
-            "-reconnect", "-tls1_3"
-        ])
-        # openssl -reconnect closes connection immediately after the handhshake, so
-        # the Session data in TLSv1.3 is not seen and not found in its output.
-        # FIXME: how to check session data with TLSv1.3?
-        session_ids = self.find_openssl_session_ids(r)
-        assert 0 == len(session_ids), "expected no session-ids: {0}, stderr={1}".format(
-            session_ids, r.stdout
-        )
diff --git a/test/modules/tls/test_11_md.py b/test/modules/tls/test_11_md.py
deleted file mode 100644 (file)
index 9d733db..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-import time
-from datetime import timedelta
-
-import pytest
-
-from .conf import TlsTestConf
-
-
-class TestMD:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        conf = TlsTestConf(env=env, extras={
-            'base': "LogLevel md:trace4"
-        })
-        conf.add_md_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-
-    def test_tls_11_get_a(self, env):
-        # do we see the correct json for the domain_a?
-        data = env.tls_get_json(env.domain_a, "/index.json")
-        assert data == {'domain': env.domain_a}
-
-    def test_tls_11_get_b(self, env):
-        # do we see the correct json for the domain_a?
-        data = env.tls_get_json(env.domain_b, "/index.json")
-        assert data == {'domain': env.domain_b}
-
-    def test_tls_11_get_base(self, env):
-        # give the base server domain_a and lookup its index.json
-        conf = TlsTestConf(env=env)
-        conf.add_md_base(domain=env.domain_a)
-        conf.install()
-        assert env.apache_restart() == 0
-        data = env.tls_get_json(env.domain_a, "/index.json")
-        assert data == {'domain': 'localhost'}
diff --git a/test/modules/tls/test_12_cauth.py b/test/modules/tls/test_12_cauth.py
deleted file mode 100644 (file)
index 1411609..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-import os
-from datetime import timedelta
-from typing import Optional
-
-import pytest
-
-from pyhttpd.certs import Credentials
-from .conf import TlsTestConf
-
-
-@pytest.fixture
-def clients_x(env):
-    return env.ca.get_first("clientsX")
-
-
-@pytest.fixture
-def clients_y(env):
-    return env.ca.get_first("clientsY")
-
-
-@pytest.fixture
-def cax_file(clients_x):
-    return os.path.join(os.path.dirname(clients_x.cert_file), "clientX-ca.pem")
-
-
-@pytest.mark.skip(reason="client certs disabled")
-class TestTLS:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env, clients_x, cax_file):
-        with open(cax_file, 'w') as fd:
-            fd.write("".join(open(clients_x.cert_file).readlines()))
-            fd.write("".join(open(env.ca.cert_file).readlines()))
-
-    @pytest.fixture(autouse=True, scope='function')
-    def _function_scope(self, env):
-        if env.is_live(timeout=timedelta(milliseconds=100)):
-            assert env.apache_stop() == 0
-
-    def get_ssl_var(self, env, domain: str, cert: Optional[Credentials], name: str):
-        r = env.tls_get(domain, f"/vars.py?name={name}", options=[
-            "--cert", cert.cert_file
-        ] if cert else [])
-        assert r.exit_code == 0, r.stderr
-        assert r.json, r.stderr + r.stdout
-        return r.json[name] if name in r.json else None
-
-    def test_tls_12_set_ca_non_existing(self, env):
-        conf = TlsTestConf(env=env, extras={
-            env.domain_a: "TLSClientCA xxx"
-        })
-        conf.add_md_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 1
-
-    def test_tls_12_set_ca_existing(self, env, cax_file):
-        conf = TlsTestConf(env=env, extras={
-            env.domain_a: f"TLSClientCA {cax_file}"
-        })
-        conf.add_md_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-
-    def test_tls_12_set_auth_no_ca(self, env):
-        conf = TlsTestConf(env=env, extras={
-            env.domain_a: "TLSClientCertificate required"
-        })
-        conf.add_md_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        # will fail bc lacking clien CA
-        assert env.apache_restart() == 1
-
-    def test_tls_12_auth_option_std(self, env, cax_file, clients_x):
-        conf = TlsTestConf(env=env, extras={
-            env.domain_b: [
-                f"TLSClientCertificate required",
-                f"TLSClientCA {cax_file}",
-                "# TODO: TLSUserName SSL_CLIENT_S_DN_CN",
-                "TLSOptions +StdEnvVars",
-            ]
-        })
-        conf.add_md_vhosts(domains=[env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-        # should be denied
-        r = env.tls_get(domain=env.domain_b, paths="/index.json")
-        assert r.exit_code != 0, r.stdout
-        # should work
-        ccert = clients_x.get_first("user1")
-        data = env.tls_get_json(env.domain_b, "/index.json", options=[
-            "--cert", ccert.cert_file
-        ])
-        assert data == {'domain': env.domain_b}
-        r = env.tls_get(env.domain_b, "/vars.py?name=SSL_CLIENT_S_DN_CN")
-        assert r.exit_code != 0, "should have been prevented"
-        val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_S_DN_CN")
-        assert val == 'Not Implemented'
-        # TODO
-        # val = self.get_ssl_var(env, env.domain_b, ccert, "REMOTE_USER")
-        # assert val == 'Not Implemented'
-        # not set on StdEnvVars, needs option ExportCertData
-        val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_CERT")
-        assert val == ""
-
-    def test_tls_12_auth_option_cert(self, env, test_ca, cax_file, clients_x):
-        conf = TlsTestConf(env=env, extras={
-            env.domain_b: [
-                "TLSClientCertificate required",
-                f"TLSClientCA {cax_file}",
-                "TLSOptions Defaults +ExportCertData",
-            ]
-        })
-        conf.add_md_vhosts(domains=[env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-        ccert = clients_x.get_first("user1")
-        val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_CERT")
-        assert val == ccert.cert_pem.decode()
-        # no chain should be present
-        val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_CHAIN_0")
-        assert val == ''
-        val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_SERVER_CERT")
-        assert val
-        server_certs = test_ca.get_credentials_for_name(env.domain_b)
-        assert val in [c.cert_pem.decode() for c in server_certs]
-
-    def test_tls_12_auth_ssl_optional(self, env, cax_file, clients_x):
-        domain = env.domain_b
-        conf = TlsTestConf(env=env, extras={
-            domain: [
-                "SSLVerifyClient optional",
-                "SSLVerifyDepth 2",
-                "SSLOptions +StdEnvVars +ExportCertData",
-                f"SSLCACertificateFile {cax_file}",
-                "SSLUserName SSL_CLIENT_S_DN",
-            ]
-        })
-        conf.add_ssl_vhosts(domains=[domain])
-        conf.install()
-        assert env.apache_restart() == 0
-        # should work either way
-        data = env.tls_get_json(domain, "/index.json")
-        assert data == {'domain': domain}
-        # no client cert given, we expect the server variable to be empty
-        val = self.get_ssl_var(env, env.domain_b, None, "SSL_CLIENT_S_DN_CN")
-        assert val == ''
-        ccert = clients_x.get_first("user1")
-        data = env.tls_get_json(domain, "/index.json", options=[
-            "--cert", ccert.cert_file
-        ])
-        assert data == {'domain': domain}
-        val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_S_DN_CN")
-        assert val == 'user1'
-        val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_S_DN")
-        assert val == 'O=abetterinternet-mod_tls,OU=clientsX,CN=user1'
-        val = self.get_ssl_var(env, env.domain_b, ccert, "REMOTE_USER")
-        assert val == 'O=abetterinternet-mod_tls,OU=clientsX,CN=user1'
-        val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_I_DN")
-        assert val == 'O=abetterinternet-mod_tls,OU=clientsX'
-        val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_I_DN_CN")
-        assert val == ''
-        val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_I_DN_OU")
-        assert val == 'clientsX'
-        val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_CERT")
-        assert val == ccert.cert_pem.decode()
-
-    def test_tls_12_auth_optional(self, env, cax_file, clients_x):
-        domain = env.domain_b
-        conf = TlsTestConf(env=env, extras={
-            domain: [
-                "TLSClientCertificate optional",
-                f"TLSClientCA {cax_file}",
-            ]
-        })
-        conf.add_md_vhosts(domains=[domain])
-        conf.install()
-        assert env.apache_restart() == 0
-        # should work either way
-        data = env.tls_get_json(domain, "/index.json")
-        assert data == {'domain': domain}
-        # no client cert given, we expect the server variable to be empty
-        r = env.tls_get(domain, "/vars.py?name=SSL_CLIENT_S_DN_CN")
-        assert r.exit_code == 0, r.stderr
-        assert r.json == {
-            'SSL_CLIENT_S_DN_CN': '',
-        }, r.stdout
-        data = env.tls_get_json(domain, "/index.json", options=[
-            "--cert", clients_x.get_first("user1").cert_file
-        ])
-        assert data == {'domain': domain}
-        r = env.tls_get(domain, "/vars.py?name=SSL_CLIENT_S_DN_CN", options=[
-            "--cert", clients_x.get_first("user1").cert_file
-        ])
-        # with client cert, we expect the server variable to show? Do we?
-        assert r.exit_code == 0, r.stderr
-        assert r.json == {
-            'SSL_CLIENT_S_DN_CN': 'Not Implemented',
-        }, r.stdout
-
-    def test_tls_12_auth_expired(self, env, cax_file, clients_x):
-        conf = TlsTestConf(env=env, extras={
-            env.domain_b: [
-                "TLSClientCertificate required",
-                f"TLSClientCA {cax_file}",
-            ]
-        })
-        conf.add_md_vhosts(domains=[env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-        # should not work
-        r = env.tls_get(domain=env.domain_b, paths="/index.json", options=[
-            "--cert", clients_x.get_first("user_expired").cert_file
-        ])
-        assert r.exit_code != 0
-
-    def test_tls_12_auth_other_ca(self, env, cax_file, clients_y):
-        conf = TlsTestConf(env=env, extras={
-            env.domain_b: [
-                "TLSClientCertificate required",
-                f"TLSClientCA {cax_file}",
-            ]
-        })
-        conf.add_md_vhosts(domains=[env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-        # should not work
-        r = env.tls_get(domain=env.domain_b, paths="/index.json", options=[
-            "--cert", clients_y.get_first("user1").cert_file
-        ])
-        assert r.exit_code != 0
-        # This will work, as the CA root is present in the CA file
-        r = env.tls_get(domain=env.domain_b, paths="/index.json", options=[
-            "--cert", env.ca.get_first("user1").cert_file
-        ])
-        assert r.exit_code == 0
diff --git a/test/modules/tls/test_13_proxy.py b/test/modules/tls/test_13_proxy.py
deleted file mode 100644 (file)
index 8bd305f..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-from datetime import timedelta
-
-import pytest
-
-from .conf import TlsTestConf
-
-
-class TestProxy:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        conf = TlsTestConf(env=env, extras={
-            'base': "LogLevel proxy:trace1 proxy_http:trace1 ssl:trace1",
-            env.domain_b: [
-                "ProxyPreserveHost on",
-                f'ProxyPass "/proxy/" "http://127.0.0.1:{env.http_port}/"',
-                f'ProxyPassReverse "/proxy/" "http://{env.domain_b}:{env.http_port}"',
-            ]
-        })
-        # add vhosts a+b and a ssl proxy from a to b
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-
-    def test_tls_13_proxy_http_get(self, env):
-        data = env.tls_get_json(env.domain_b, "/proxy/index.json")
-        assert data == {'domain': env.domain_b}
-
-    @pytest.mark.parametrize("name, value", [
-        ("SERVER_NAME", "b.mod-tls.test"),
-        ("SSL_SESSION_RESUMED", ""),
-        ("SSL_SECURE_RENEG", ""),
-        ("SSL_COMPRESS_METHOD", ""),
-        ("SSL_CIPHER_EXPORT", ""),
-        ("SSL_CLIENT_VERIFY", ""),
-    ])
-    def test_tls_13_proxy_http_vars(self, env, name: str, value: str):
-        r = env.tls_get(env.domain_b, f"/proxy/vars.py?name={name}")
-        assert r.exit_code == 0, r.stderr
-        assert r.json == {name: value}, r.stdout
diff --git a/test/modules/tls/test_14_proxy_ssl.py b/test/modules/tls/test_14_proxy_ssl.py
deleted file mode 100644 (file)
index 81cb4f3..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-import re
-import pytest
-
-from .conf import TlsTestConf
-from .env import TlsTestEnv
-from pyhttpd.env import HttpdTestEnv
-
-
-class TestProxySSL:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        # add vhosts a+b and a ssl proxy from a to b
-        if not HttpdTestEnv.has_shared_module("tls"):
-            myoptions="SSLOptions +StdEnvVars"
-            myssl="mod_ssl"
-        else:
-            myoptions="TLSOptions +StdEnvVars"
-            myssl="mod_tls"
-        conf = TlsTestConf(env=env, extras={
-            'base': [
-                "LogLevel proxy:trace1 proxy_http:trace1 ssl:trace1 proxy_http2:trace1",
-                f"<Proxy https://127.0.0.1:{env.https_port}/>",
-                "    SSLProxyEngine on",
-                "    SSLProxyVerify require",
-                f"    SSLProxyCACertificateFile {env.ca.cert_file}",
-                "  ProxyPreserveHost on",
-                "</Proxy>",
-                f"<Proxy https://localhost:{env.https_port}/>",
-                "    ProxyPreserveHost on",
-                "</Proxy>",
-                f"<Proxy h2://127.0.0.1:{env.https_port}/>",
-                "    SSLProxyEngine on",
-                "    SSLProxyVerify require",
-                f"    SSLProxyCACertificateFile {env.ca.cert_file}",
-                "    ProxyPreserveHost on",
-                "</Proxy>",
-                ],
-            env.domain_b: [
-                "Protocols h2 http/1.1",
-                f'ProxyPass /proxy-ssl/ https://127.0.0.1:{env.https_port}/',
-                f'ProxyPass /proxy-local/ https://localhost:{env.https_port}/',
-                f'ProxyPass /proxy-h2-ssl/ h2://127.0.0.1:{env.https_port}/',
-                myoptions,
-            ],
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b], ssl_module=myssl)
-        conf.install()
-        assert env.apache_restart() == 0
-
-    def test_tls_14_proxy_ssl_get(self, env):
-        data = env.tls_get_json(env.domain_b, "/proxy-ssl/index.json")
-        assert data == {'domain': env.domain_b}
-
-    def test_tls_14_proxy_ssl_get_local(self, env):
-        # does not work, since SSLProxy* not configured
-        data = env.tls_get_json(env.domain_b, "/proxy-local/index.json")
-        assert data is None
-        #
-        env.httpd_error_log.ignore_recent(
-            lognos = [
-                "AH01961",  # failed to enable ssl support [Hint: if using mod_ssl, see SSLProxyEngine]
-                "AH00961"   # failed to enable ssl support (mod_proxy)
-            ]
-        )
-
-    @pytest.mark.skipif(condition=TlsTestEnv.is_unsupported, reason="h2 not supported here")
-    def test_tls_14_proxy_ssl_h2_get(self, env):
-        r = env.tls_get(env.domain_b, "/proxy-h2-ssl/index.json")
-        assert r.exit_code == 0
-        assert r.json == {'domain': env.domain_b}
-
-    @pytest.mark.parametrize("name, value", [
-        ("SERVER_NAME", "b.mod-tls.test"),
-        ("SSL_SESSION_RESUMED", "Initial"),
-        ("SSL_SECURE_RENEG", "false"),
-        ("SSL_COMPRESS_METHOD", "NULL"),
-        ("SSL_CIPHER_EXPORT", "false"),
-        ("SSL_CLIENT_VERIFY", "NONE"),
-    ])
-    def test_tls_14_proxy_ssl_vars_const(self, env, name: str, value: str):
-        if not HttpdTestEnv.has_shared_module("tls"):
-            return
-        r = env.tls_get(env.domain_b, f"/proxy-ssl/vars.py?name={name}")
-        assert r.exit_code == 0, r.stderr
-        assert r.json == {name: value}, r.stdout
-
-    @pytest.mark.parametrize("name, value", [
-        ("SERVER_NAME", "b.mod-tls.test"),
-        ("SSL_SESSION_RESUMED", "Initial"),
-        ("SSL_SECURE_RENEG", "true"),
-        ("SSL_COMPRESS_METHOD", "NULL"),
-        ("SSL_CIPHER_EXPORT", "false"),
-        ("SSL_CLIENT_VERIFY", "NONE"),
-    ])
-    def test_tls_14_proxy_ssl_vars_const(self, env, name: str, value: str):
-        if HttpdTestEnv.has_shared_module("tls"):
-            return
-        r = env.tls_get(env.domain_b, f"/proxy-ssl/vars.py?name={name}")
-        assert r.exit_code == 0, r.stderr
-        assert r.json == {name: value}, r.stdout
-
-    @pytest.mark.parametrize("name, pattern", [
-        ("SSL_VERSION_INTERFACE", r'mod_tls/\d+\.\d+\.\d+'),
-        ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+(\.\d+)?'),
-    ])
-    def test_tls_14_proxy_ssl_vars_match(self, env, name: str, pattern: str):
-        if not HttpdTestEnv.has_shared_module("tls"):
-            return
-        r = env.tls_get(env.domain_b, f"/proxy-ssl/vars.py?name={name}")
-        assert r.exit_code == 0, r.stderr
-        assert name in r.json
-        assert re.match(pattern, r.json[name]), r.json
-
-    @pytest.mark.parametrize("name, pattern", [
-        ("SSL_VERSION_INTERFACE", r'mod_ssl/\d+\.\d+\.\d+'),
-        ("SSL_VERSION_LIBRARY", r'OpenSSL/\d+\.\d+\.\d+'),
-    ])
-    def test_tls_14_proxy_ssl_vars_match(self, env, name: str, pattern: str):
-        if HttpdTestEnv.has_shared_module("tls"):
-            return
-        r = env.tls_get(env.domain_b, f"/proxy-ssl/vars.py?name={name}")
-        assert r.exit_code == 0, r.stderr
-        assert name in r.json
-        assert re.match(pattern, r.json[name]), r.json
diff --git a/test/modules/tls/test_15_proxy_tls.py b/test/modules/tls/test_15_proxy_tls.py
deleted file mode 100644 (file)
index 3fe6cfe..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-from datetime import timedelta
-
-import pytest
-
-from .conf import TlsTestConf
-from .env import TlsTestEnv
-from pyhttpd.env import HttpdTestEnv
-
-@pytest.mark.skipif(condition=not HttpdTestEnv.has_shared_module("tls"), reason="no mod_tls available")
-
-class TestProxyTLS:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        # add vhosts a+b and a ssl proxy from a to b
-        conf = TlsTestConf(env=env, extras={
-            'base': [
-                "LogLevel proxy:trace1 proxy_http:trace1 proxy_http2:trace2 http2:trace2 cgid:trace4",
-                "TLSProxyProtocol TLSv1.3+",
-                f"<Proxy https://127.0.0.1:{env.https_port}/>",
-                "    TLSProxyEngine on",
-                f"    TLSProxyCA {env.ca.cert_file}",
-                "    TLSProxyProtocol TLSv1.2+",
-                "    TLSProxyCiphersPrefer TLS13_AES_256_GCM_SHA384",
-                "    TLSProxyCiphersSuppress TLS13_AES_128_GCM_SHA256",
-                "    ProxyPreserveHost on",
-                "</Proxy>",
-                f"<Proxy https://localhost:{env.https_port}/>",
-                "    ProxyPreserveHost on",
-                "</Proxy>",
-                f"<Proxy h2://127.0.0.1:{env.https_port}/>",
-                "    TLSProxyEngine on",
-                f"    TLSProxyCA {env.ca.cert_file}",
-                "    TLSProxyCiphersSuppress TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256",
-                "    ProxyPreserveHost on",
-                "</Proxy>",
-            ],
-            env.domain_b: [
-                "Protocols h2 http/1.1",
-                f"ProxyPass /proxy-tls/ https://127.0.0.1:{env.https_port}/",
-                f"ProxyPass /proxy-local/ https://localhost:{env.https_port}/",
-                f"ProxyPass /proxy-h2-tls/ h2://127.0.0.1:{env.https_port}/",
-                "TLSOptions +StdEnvVars",
-            ],
-        })
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-
-    def test_tls_15_proxy_tls_get(self, env):
-        data = env.tls_get_json(env.domain_b, "/proxy-tls/index.json")
-        assert data == {'domain': env.domain_b}
-
-    def test_tls_15_proxy_tls_get_local(self, env):
-        # does not work, since SSLProxy* not configured
-        data = env.tls_get_json(env.domain_b, "/proxy-local/index.json")
-        assert data is None
-        #
-        env.httpd_error_log.ignore_recent(
-            lognos = [
-                "AH01961",  # failed to enable ssl support [Hint: if using mod_ssl, see SSLProxyEngine]
-                "AH00961"   # failed to enable ssl support (mod_proxy)
-            ]
-        )
-
-    @pytest.mark.skipif(condition=TlsTestEnv.is_unsupported, reason="h2 not supported here")
-    def test_tls_15_proxy_tls_h2_get(self, env):
-        r = env.tls_get(env.domain_b, "/proxy-h2-tls/index.json")
-        assert r.exit_code == 0
-        assert r.json == {'domain': env.domain_b}, f"{r.stdout}"
-
-    @pytest.mark.parametrize("name, value", [
-        ("SERVER_NAME", "b.mod-tls.test"),
-        ("SSL_PROTOCOL", "TLSv1.3"),
-        ("SSL_CIPHER", "TLS_AES_256_GCM_SHA384"),
-        ("SSL_SESSION_RESUMED", "Initial"),
-        ("SSL_SECURE_RENEG", "false"),
-        ("SSL_COMPRESS_METHOD", "NULL"),
-        ("SSL_CIPHER_EXPORT", "false"),
-        ("SSL_CLIENT_VERIFY", "NONE"),
-    ])
-    def test_tls_15_proxy_tls_h1_vars(self, env, name: str, value: str):
-        r = env.tls_get(env.domain_b, f"/proxy-tls/vars.py?name={name}")
-        assert r.exit_code == 0, r.stderr
-        assert r.json == {name: value}, r.stdout
-
-    @pytest.mark.parametrize("name, value", [
-        ("SERVER_NAME", "b.mod-tls.test"),
-        ("SSL_PROTOCOL", "TLSv1.3"),
-        ("SSL_CIPHER", "TLS_CHACHA20_POLY1305_SHA256"),
-        ("SSL_SESSION_RESUMED", "Initial"),
-    ])
-    @pytest.mark.skipif(condition=TlsTestEnv.is_unsupported, reason="h2 not supported here")
-    def test_tls_15_proxy_tls_h2_vars(self, env, name: str, value: str):
-        r = env.tls_get(env.domain_b, f"/proxy-h2-tls/vars.py?name={name}")
-        assert r.exit_code == 0, r.stderr
-        assert r.json == {name: value}, r.stdout
diff --git a/test/modules/tls/test_16_proxy_mixed.py b/test/modules/tls/test_16_proxy_mixed.py
deleted file mode 100644 (file)
index 88b351f..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-import time
-
-import pytest
-
-from .conf import TlsTestConf
-from pyhttpd.env import HttpdTestEnv
-
-@pytest.mark.skipif(condition=not HttpdTestEnv.has_shared_module("tls"), reason="no mod_tls available")
-
-
-class TestProxyMixed:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(self, env):
-        conf = TlsTestConf(env=env, extras={
-            'base': [
-                "LogLevel proxy:trace1 proxy_http:trace1 ssl:trace1 proxy_http2:trace1 http2:debug",
-                "ProxyPreserveHost on",
-            ],
-            env.domain_a: [
-                "Protocols h2 http/1.1",
-                "TLSProxyEngine on",
-                f"TLSProxyCA {env.ca.cert_file}",
-                "<Location /proxy-tls/>",
-                f"    ProxyPass h2://127.0.0.1:{env.https_port}/",
-                "</Location>",
-            ],
-            env.domain_b: [
-                "SSLProxyEngine on",
-                "SSLProxyVerify require",
-                f"SSLProxyCACertificateFile {env.ca.cert_file}",
-                "<Location /proxy-ssl/>",
-                f"    ProxyPass https://127.0.0.1:{env.https_port}/",
-                "</Location>",
-            ],
-        })
-        # add vhosts a+b and a ssl proxy from a to b
-        conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
-        conf.install()
-        assert env.apache_restart() == 0
-
-    def test_tls_16_proxy_mixed_ssl_get(self, env, repeat):
-        data = env.tls_get_json(env.domain_b, "/proxy-ssl/index.json")
-        assert data == {'domain': env.domain_b}
-
-    def test_tls_16_proxy_mixed_tls_get(self, env, repeat):
-        data = env.tls_get_json(env.domain_a, "/proxy-tls/index.json")
-        if data is None:
-            time.sleep(300)
-        assert data == {'domain': env.domain_a}
diff --git a/test/modules/tls/test_17_proxy_machine_cert.py b/test/modules/tls/test_17_proxy_machine_cert.py
deleted file mode 100644 (file)
index a5410d6..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-import os
-
-import pytest
-
-from .conf import TlsTestConf
-from pyhttpd.env import HttpdTestEnv
-
-@pytest.mark.skipif(condition=not HttpdTestEnv.has_shared_module("tls"), reason="no mod_tls available")
-class TestProxyMachineCert:
-
-    @pytest.fixture(autouse=True, scope='class')
-    def clients_x(cls, env):
-        return env.ca.get_first("clientsX")
-
-    @pytest.fixture(autouse=True, scope='class')
-    def clients_y(cls, env):
-        return env.ca.get_first("clientsY")
-
-    @pytest.fixture(autouse=True, scope='class')
-    def cax_file(cls, clients_x):
-        return os.path.join(os.path.dirname(clients_x.cert_file), "clientsX-ca.pem")
-
-    @pytest.fixture(autouse=True, scope='class')
-    def _class_scope(cls, env, cax_file, clients_x):
-        # add vhosts a(tls)+b(ssl, port2) and a ssl proxy from a to b with a machine cert
-        # host b requires a client certificate
-        conf = TlsTestConf(env=env, extras={
-            'base': [
-                "LogLevel proxy:trace1 proxy_http:trace1 ssl:trace4 proxy_http2:trace1",
-                "ProxyPreserveHost on",
-                f"Listen {env.proxy_port}",
-            ],
-        })
-        conf.start_tls_vhost(domains=[env.domain_a], port=env.https_port)
-        conf.add([
-            "Protocols h2 http/1.1",
-            "TLSProxyEngine on",
-            f"TLSProxyCA {env.ca.cert_file}",
-            f"TLSProxyMachineCertificate {clients_x.get_first('user1').cert_file}",
-            "<Location /proxy-tls/>",
-            f"    ProxyPass https://127.0.0.1:{env.proxy_port}/",
-            "</Location>",
-        ])
-        conf.end_tls_vhost()
-        conf.start_vhost(domains=[env.domain_a], port=env.proxy_port,
-                         doc_root=f"htdocs/{env.domain_a}", with_ssl=True)
-        conf.add([
-            "SSLVerifyClient require",
-            "SSLVerifyDepth 2",
-            "SSLOptions +StdEnvVars +ExportCertData",
-            f"SSLCACertificateFile {cax_file}",
-            "SSLUserName SSL_CLIENT_S_DN_CN"
-        ])
-        conf.end_vhost()
-        conf.install()
-        assert env.apache_restart() == 0
-
-    def test_tls_17_proxy_machine_cert_get_a(self, env):
-        data = env.tls_get_json(env.domain_a, "/proxy-tls/index.json")
-        assert data == {'domain': env.domain_a}
-
-    @pytest.mark.parametrize("name, value", [
-        ("SERVER_NAME", "a.mod-tls.test"),
-        ("SSL_CLIENT_VERIFY", "SUCCESS"),
-        ("REMOTE_USER", "user1"),
-    ])
-    def test_tls_17_proxy_machine_cert_vars(self, env, name: str, value: str):
-        r = env.tls_get(env.domain_a, f"/proxy-tls/vars.py?name={name}")
-        assert r.exit_code == 0, r.stderr
-        assert r.json == {name: value}, r.stdout
index 373e6668ee688f32a0d1a6b91ed00bf3267e975d..67d9d005054db899a7cd41f630765799edde8ac0 100755 (executable)
@@ -215,14 +215,6 @@ if ! test -v SKIP_TESTING; then
         RV=$?
     fi
 
-    if test -v TEST_MOD_TLS -a $RV -eq 0; then
-        # Run mod_tls tests. The underlying librustls was build
-        # and installed before we configured the server (see top of file).
-        # This will be replaved once librustls is available as a package.
-        py.test-3 test/modules/tls
-        RV=$?
-    fi
-
     # Catch cases where abort()s get logged to stderr by libraries but
     # only cause child processes to terminate e.g. during shutdown,
     # which may not otherwise trigger test failures.