DevHeads.net

Unexpected result of requesting client certificate when requesting locations with different SSLVerifyClient settings

Hello,

I ran into a problem when configuring different locations for Apache HTTP
Server while utilizing client certificate. The client certificate is not
stored permanently on the browser; It is expected that the client
certificate will be inserted by encrypted USB stick before the user is
clicking on the protected location.

Let's say I have a virtual host (<a href="https://host/" title="https://host/">https://host/</a>) with SSLVerifyClient
optional and a location inside that v-host (<a href="https://host/require" title="https://host/require">https://host/require</a>) with
SSLVerifyClient require.

<VirtualHost _default_:443>
ServerName host
........
SSLVerifyClient optional
SSLVerifyDepth 10
SSLOptions +FakeBasicAuth +ExportCertData
.......
<Location /require>
SSLVerifyClient require
</Location>
</VirtualHost>

When I either directly visit <a href="https://host/require" title="https://host/require">https://host/require</a> or <a href="https://host/" title="https://host/">https://host/</a>, they
both request client certificate normally; the difference is that if I
cancel submitting certificate, the latter one would still allow access,
while the former one rejecting access by SSL error:
ERR_BAD_SSL_CLIENT_AUTH_CERT.
The problem happens when I DOESN'T submit the certificate (or don't have a
certificate at the time) when I visit <a href="https://host/" title="https://host/">https://host/</a>, then I acquired the
client certificate and then browse to <a href="https://host/require" title="https://host/require">https://host/require</a> in the same
browser tab. Ideally it should request client certificate once more, but it
doesn't; instead it emits ERR_BAD_SSL_CLIENT_AUTH_CERT immediately. Only
after I clicked the Refresh button on <a href="https://host/require" title="https://host/require">https://host/require</a>, then it request
client certificate as normal.

I checked the debug log and it looks like the following:

_________Visiting <a href="https://host/_________" title="https://host/_________">https://host/_________</a>
[Wed Apr 10 23:13:49.290449 2019] [ssl:debug] [pid 2656:tid
140593581737728] ssl_engine_kernel.c(746): [client 10.111.84.227:62107]
AH02255: Changed client verification type will force renegotiation
[Wed Apr 10 23:13:49.290476 2019] [ssl:info] [pid 2656:tid 140593581737728]
[client 10.111.84.227:62107] AH02221: Requesting connection re-negotiation
[Wed Apr 10 23:13:49.290485 2019] [ssl:debug] [pid 2656:tid
140593581737728] ssl_engine_kernel.c(975): [client 10.111.84.227:62107]
AH02260: Performing full renegotiation: complete handshake protocol (client
does support secure renegotiation)
[Wed Apr 10 23:13:49.290530 2019] [ssl:info] [pid 2656:tid 140593581737728]
[client 10.111.84.227:62107] AH02226: Awaiting re-negotiation handshake
[Wed Apr 10 23:13:49.292550 2019] [ssl:error] [pid 2656:tid
140593581737728] [client 10.111.84.227:62107] AH02261: Re-negotiation
handshake failed
_________Clicking "cancel" on submitting certificate to
<a href="https://host/_________" title="https://host/_________">https://host/_________</a>
[Wed Apr 10 23:13:50.788696 2019] [ssl:debug] [pid 2656:tid
140593573345024] ssl_engine_kernel.c(746): [client 10.111.84.227:62108]
AH02255: Changed client verification type will force renegotiation
[Wed Apr 10 23:13:50.788795 2019] [ssl:info] [pid 2656:tid 140593573345024]
[client 10.111.84.227:62108] AH02221: Requesting connection re-negotiation
[Wed Apr 10 23:13:50.788832 2019] [ssl:debug] [pid 2656:tid
140593573345024] ssl_engine_kernel.c(975): [client 10.111.84.227:62108]
AH02260: Performing full renegotiation: complete handshake protocol (client
does support secure renegotiation)
[Wed Apr 10 23:13:50.789059 2019] [ssl:info] [pid 2656:tid 140593573345024]
[client 10.111.84.227:62108] AH02226: Awaiting re-negotiation handshake
[Wed Apr 10 23:13:50.794931 2019] [authz_core:debug] [pid 2656:tid
140593573345024] mod_authz_core.c(820): [client 10.111.84.227:62108]
AH01626: authorization result of Require all granted: granted
[Wed Apr 10 23:13:50.794940 2019] [authz_core:debug] [pid 2656:tid
140593573345024] mod_authz_core.c(820): [client 10.111.84.227:62108]
AH01626: authorization result of <RequireAny>: granted
[Wed Apr 10 23:13:50.798066 2019] [authz_core:debug] [pid 2656:tid
140593564952320] mod_authz_core.c(820): [client 10.111.84.227:62108]
AH01626: authorization result of Require all granted: granted
[Wed Apr 10 23:13:50.798075 2019] [authz_core:debug] [pid 2656:tid
140593564952320] mod_authz_core.c(820): [client 10.111.84.227:62108]
AH01626: authorization result of <RequireAny>: granted
[Wed Apr 10 23:13:50.798100 2019] [authz_core:debug] [pid 2656:tid
140593564952320] mod_authz_core.c(820): [client 10.111.84.227:62108]
AH01626: authorization result of Require all granted: granted
[Wed Apr 10 23:13:50.798103 2019] [authz_core:debug] [pid 2656:tid
140593564952320] mod_authz_core.c(820): [client 10.111.84.227:62108]
AH01626: authorization result of <RequireAny>: granted
_________Visiting <a href="https://host/require_________" title="https://host/require_________">https://host/require_________</a>
[Wed Apr 10 23:14:08.548394 2019] [ssl:debug] [pid 2534:tid
140593665664768] ssl_engine_kernel.c(746): [client 10.111.84.227:62110]
AH02255: Changed client verification type will force renegotiation
[Wed Apr 10 23:14:08.548469 2019] [ssl:info] [pid 2534:tid 140593665664768]
[client 10.111.84.227:62110] AH02221: Requesting connection re-negotiation
[Wed Apr 10 23:14:08.548505 2019] [ssl:debug] [pid 2534:tid
140593665664768] ssl_engine_kernel.c(975): [client 10.111.84.227:62110]
AH02260: Performing full renegotiation: complete handshake protocol (client
does support secure renegotiation)
[Wed Apr 10 23:14:08.548659 2019] [ssl:info] [pid 2534:tid 140593665664768]
[client 10.111.84.227:62110] AH02226: Awaiting re-negotiation handshake
[Wed Apr 10 23:14:08.553605 2019] [ssl:error] [pid 2534:tid
140593665664768] [client 10.111.84.227:62110] AH02261: Re-negotiation
handshake failed
[Wed Apr 10 23:14:08.559173 2019] [ssl:debug] [pid 2656:tid
140593531381504] ssl_engine_kernel.c(746): [client 10.111.84.227:62111]
AH02255: Changed client verification type will force renegotiation
[Wed Apr 10 23:14:08.559240 2019] [ssl:info] [pid 2656:tid 140593531381504]
[client 10.111.84.227:62111] AH02221: Requesting connection re-negotiation
[Wed Apr 10 23:14:08.559275 2019] [ssl:debug] [pid 2656:tid
140593531381504] ssl_engine_kernel.c(975): [client 10.111.84.227:62111]
AH02260: Performing full renegotiation: complete handshake protocol (client
does support secure renegotiation)
[Wed Apr 10 23:14:08.559395 2019] [ssl:info] [pid 2656:tid 140593531381504]
[client 10.111.84.227:62111] AH02226: Awaiting re-negotiation handshake
[Wed Apr 10 23:14:08.565194 2019] [ssl:error] [pid 2656:tid
140593531381504] [client 10.111.84.227:62111] AH02261: Re-negotiation
handshake failed
[Wed Apr 10 23:14:08.565268 2019] [ssl:error] [pid 2656:tid
140593531381504] SSL Library Error: error:1417C0C7:SSL
routines:tls_process_client_certificate:peer did not return a certificate
-- No CAs known to server for verification?

I tried with the following scenarios:
1. The Vhost root use SSLVerifyClient none and Location uses
SSLVerifyClient require: the latter emits no error before requesting client
certificate;
2. The Vhost root use SSLVerifyClient none, Location1 uses SSLVerifyClient
optional, and Location2 uses SSLVerifyClient require: If I have visited
Location1 and submitted no client certificate, Location2 will emit
ERR_BAD_SSL_CLIENT_AUTH_CERT before requesting client certificate, no
matter if I am jumping from root or Location 1.

I suspect there is a bug involved in the SSL client verification type
changing and the re-negotiation flow. While I admit it may be a corner case
but the original use case is very crucial to my current user base. I
checked the Bug database and there is a similar bug except that is related
to TLSv1.3. For browser compatibility, I am currently disabling TLSv1.3,
although I am testing with Apache 2.4.38 and OpenSSL 1.1.1b.
I would love to hear any suggestions on an alternative configuration to
support my scenario, and thank you very much in advance.

Regards,
Hao Du

Comments

Re: Unexpected result of requesting client certifi

By William A. Rowe Jr. at 04/10/2019 - 13:14

Hello Du Hau,

you probably want to abandon your current approach. With TLSv1.3, which
will come to dominate and eliminate earlier TLS protocols, there is no
mechanism for renegotiation. The entire site (defined using SNI, server
name indication) will need to share a common handshake, the idea of only
locking down <a href="https://site.example.co/protected/" title="https://site.example.co/protected/">https://site.example.co/protected/</a> gets eliminated with this
protocol, and with many only TLS's which actively disable renegotiation due
to the underlying potential security holes over time.

Re: Unexpected result of requesting client certifi

By Du Hao at 04/10/2019 - 20:30

Is Apache HTTP Server going to drop TLSv1.2 support in near future? If not,
it is a bug that affects user who voluntarily choose to not use TLSv1.3.

William A Rowe Jr <wrowe@rowe-clan.net> 于 2019年4月11日周四 01:24写道:

Re: Unexpected result of requesting client certifi

By William A. Rowe Jr. at 04/12/2019 - 12:05

Because 2.4 dates all the way back to the now-unsupported 0.9.8 lifecycle,
it seems unlikely that any httpd 2.4.x would entirely drop this or later
support, but note these EOL dates from the OpenSSL project as published at
<a href="https://www.openssl.org/policies/releasestrat.html" title="https://www.openssl.org/policies/releasestrat.html">https://www.openssl.org/policies/releasestrat.html</a>

The next version of OpenSSL will be 3.0.0.
Version 1.1.1 will be supported until 2023-09-11 (LTS).
Version 1.1.0 will be supported until 2019-09-11.
Version 1.0.2 will be supported until 2019-12-31 (LTS).
Version 1.0.1 is no longer supported.
Version 1.0.0 is no longer supported.
Version 0.9.8 is no longer supported.

So it's entirely reasonable that any 2.next or 3.0 release of Apache HTTP
Server by midyear could elect to drop all support for any 1.0.1 or earlier
flavor, and if not released until next year - could might even drop support
for all flavors earlier than 1.1.1. Not certain what course the project
will choose to follow, since these antique flavors are still found across
many flavors of commonly provisioned OS's.

Best practices and PCI standards already discourage and will eventually
forbid the use of context-specific renegotiation, and will eventually drop
TLS 1.2 itself. Some useful information on such guidelines are summarized
and maintained at <a href="https://en.wikipedia.org/wiki/Transport_Layer_Security" title="https://en.wikipedia.org/wiki/Transport_Layer_Security">https://en.wikipedia.org/wiki/Transport_Layer_Security</a>