Bug 64263

Summary: TLSv1.3 with SSLVerifyClient optional inside a Location returns 403
Product: Apache httpd-2 Reporter: Vlad Mencl <vladimir.mencl>
Component: mod_sslAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: NEW ---    
Severity: normal CC: marc.deslauriers
Priority: P2    
Version: 2.4.41   
Target Milestone: ---   
Hardware: PC   
OS: Linux   

Description Vlad Mencl 2020-03-25 09:47:56 UTC

I have just ran into this on Ubuntu 18.04, as they just backported r1840585 into what they release is 2.4.29-1ubuntu4.13.

I have a config that enables *optional* client TLS authentication for a specific path:

    SSLCACertificateFile "/etc/ssl/certs/api-ca.crt"
    <Location /api>
        SSLVerifyClient optional
        RequestHeader set X509_DN "%{SSL_CLIENT_S_DN}s"

This config started breaking with:

[Wed Mar 25 16:08:02.648354 2020] [ssl:error] [pid 1801:tid 140236923303680] [client 2404:138:46::126:47888] AH: verify client post handshake
[Wed Mar 25 16:08:02.648403 2020] [ssl:error] [pid 1801:tid 140236923303680] [client 2404:138:46::126:47888] AH10158: cannot perform post-handshake authentication
[Wed Mar 25 16:08:02.648420 2020] [ssl:error] [pid 1801:tid 140236923303680] SSL Library Error: error:14268117:SSL routines:SSL_verify_client_post_handshake:extension not received

I have just confirmed and I get the same 2.4.41 downloaded from httpd.apache.org.

Just compiling the source distribution with --enable-ssl and adding

LoadModule ssl_module modules/mod_ssl.so
Listen 443 https
<VirtualHost _default_:443>
    SSLEngine on
    SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
    SSLHonorCipherOrder On
    SSLCertificateFile    /etc/ssl/certs/server.crt
    SSLCertificateKeyFile /etc/ssl/private/server.key

    SSLCipherSuite HIGH:!aNULL:!MD5:!SEED:!IDEA:!RC4:!LOW:!3DES:!kRSA:!SHA1:!SHA256:!SHA384
    <Location /api>
      SSLVerifyClient optional

to httpd.conf reproduces the issue - in logs/error_log, I get:

[Wed Mar 25 22:36:21.822805 2020] [ssl:error] [pid 21499:tid 140218342541056] [client ::1:52710] AH10158: cannot perform post-handshake authentication
[Wed Mar 25 22:36:21.823030 2020] [ssl:error] [pid 21499:tid 140218342541056] SSL Library Error: error:14268117:SSL routines:SSL_verify_client_post_handshake:extension not received

I see the commit message for r1840585 says:

* modules/ssl/ssl_engine_kernel.c (ssl_hook_Access_modern): Fail with
  403 if SSL_verify_client_post_handshake() fails, e.g. when the
  TLS/1.3 client didn't send the Post-Handshake Authentication

However, when authentication is optional (SSLVerifyClient optional) and no client authentication is provided, it should not count as a failure and request processing should continue...

Comment 1 Vlad Mencl 2020-03-25 09:55:44 UTC

I just realised I might not have been clear on expected / faulty behaviour: with the above config, hitting /api/ on the server with a TLSv1.3 client not providing any TLS client auth:

* should return 404 (nothing served at the URL)

* returns 403 - because the code from r1840585 explicitly fails the request processing.

Hope this clarifies it.

Comment 2 Vlad Mencl 2020-03-30 09:50:09 UTC

I have investigated this issue further...

I now understand that for essentially all HTTPS clients,
it is necessary to update SSL API calls to support TLSv1.3
post-handshake authentication.

And I have also checked with a version of curl built right off the
top of the github repo (7.70.0-DEV) - as an example of a client
capable of post-handshake authentication.

With this version of curl, Apache 2.4.49 works over TLSv1.3 with "SSLVerify optional" inside a <Location> for both authenticated and unauthenticated requests (client providing or not providing a client certificate).

The tricky edge-case is my use case of unauthenticated API (SSLVerify optional) - that used to work on older versions of Apache 2.4 over TLSv1.3 (with the initial support provided earlier) even with older clients only (not capable of post-handshake authentication), like curl 7.58.0 (bundled with Ubuntu 18.04), but breaks with 2.4.49 (as far as I can tell, due to the changes in r1840585.

I agree the main way forward is updating all clients to support TLSv1.3 properly - including post-handshake authentication.

The point of this bug report is whether to let older clients (not supporting post-handshake authentication) get by when authentication is not required.

Please let me know if you think this is worth addressing.

Comment 3 Joe Orton 2020-03-30 10:44:34 UTC
Thanks for the report.

It looks like SSL_verify_client_post_handshake() returns immediately with SSL_R_EXTENSION_NOT_RECEIVED (=> TLSv1.3 client which does NOT enable PHA) without doing any work, so I think it should be safe to detect that condition, and the "vmode_needed & SSL_VERIFY_FAIL_IF_NO_PEER_CERT" case ("optional" cert required) and then allow optional to work as with <1.3.