Good Morning,
Server version: Apache/2.4.6 (CentOS)
I’m running an apache virtual host that proxies traffic to a Java-based web
application. Apache is configured to impose client authentication (via
certificate) using the following directives:
<VirtualHost _default_:443>
SSLEngine on
SSLProtocol -ALL +TLSv1.2
SSLCertificateFile crt.pem
SSLCertificateKeyFile key.pem
SSLCertificateChainFile chain.pem
#
# some other miscellaneous configuration directives
#
SSLCACertificateFile ca.pem
SSLCARevocationCheck chain
SSLCARevocationFile crl.pem
<Location /foo>
SSLVerifyClient require
SSLVerifyDepth 2
Require expr %{SSL_CLIENT_S_DN_OU} -strcmatch “TRUSTED”
</Location>
</VirtualHost>
When testing this configuration, I find that the server rejects bad requests in
two distinct manners with regards to the client certificates. Requests using
client certificates which do not contain the OU string identified in the
Require directive are rejected at the HTTP level, with a 403 status code
returned. However, requests using a client certificate that is invalid for
most other reasons (expired, not in the required trust chain, self-signed,
etc.) are met with an SSL Handshake error.
This second case is technically valid TLS behavior per
https://tools.ietf.org/html/rfc5246#section-7.4.6: “if some aspect of the
certificate chain was unacceptable (e.g., it was not signed by a known, trusted
CA), the server MAY at its discretion either continue the handshake
(considering the client unauthenticated) or send a fatal alert.” However,
httpd seems to THINK that it is providing an HTTP 403 response, which would be
the desired behavior for this application. Setting my LogLevel to trace7, I
can observe the following:
[Mon Apr 08 14:30:11.315870 2019] [ssl:trace3] [pid 28414]
ssl_engine_kernel.c(1790): [client 205.201.96.138:54346] OpenSSL: Write: SSLv3
read client certificate B
[Mon Apr 08 14:30:11.315900 2019] [ssl:trace3] [pid 28414]
ssl_engine_kernel.c(1809): [client 205.201.96.138:54346] OpenSSL: Exit: error
in error
[Mon Apr 08 14:30:11.315904 2019] [ssl:error] [pid 28414] [client
205.201.96.138:54346] AH02261: Re-negotiation handshake failed
[Mon Apr 08 14:30:11.315930 2019] [ssl:error] [pid 28414] SSL Library Error:
error:14089086:SSL routines:ssl3_get_client_certificate:certificate verify
failed
[Mon Apr 08 14:30:11.315935 2019] [core:trace3] [pid 28414] request.c(119):
[client 205.201.96.138:54346] auth phase 'check access (with Satisfy All)' gave
status 403: /path/to/my/app
[Mon Apr 08 14:30:11.315972 2019] [http:trace3] [pid 28414]
http_filters.c(1129): [client 205.201.96.138:54346] Response sent with status
403, headers:
[Mon Apr 08 14:30:11.315975 2019] [http:trace5] [pid 28414]
http_filters.c(1136): [client 205.201.96.138:54346] Date: Mon, 08 Apr 2019
14:30:08 GMT
[Mon Apr 08 14:30:11.315977 2019] [http:trace5] [pid 28414]
http_filters.c(1139): [client 205.201.96.138:54346] Server: Apache
[Mon Apr 08 14:30:11.315980 2019] [http:trace4] [pid 28414]
http_filters.c(958): [client 205.201.96.138:54346] Content-Length: 226
[Mon Apr 08 14:30:11.315982 2019] [http:trace4] [pid 28414]
http_filters.c(958): [client 205.201.96.138:54346] Connection: close
[Mon Apr 08 14:30:11.315984 2019] [http:trace4] [pid 28414]
http_filters.c(958): [client 205.201.96.138:54346] Content-Type: text/html;
charset=iso-8859-1
[Mon Apr 08 14:30:11.315987 2019] [ssl:trace4] [pid 28414]
ssl_engine_io.c(1515): [client 205.201.96.138:54346] coalesce: have 0 bytes,
adding 164 more
[Mon Apr 08 14:30:11.315994 2019] [ssl:trace3] [pid 28414]
ssl_engine_kernel.c(1809): [client 205.201.96.138:54346] OpenSSL: Exit: error
in error
[Mon Apr 08 14:30:11.315999 2019] [ssl:info] [pid 28414] [client
205.201.96.138:54346] AH02008: SSL library error 1 in handshake (server
foo.bar.com:443)
[Mon Apr 08 14:30:11.316012 2019] [ssl:info] [pid 28414] SSL Library Error:
error:140800FF:SSL routines:ssl3_accept:unknown state
[Mon Apr 08 14:30:11.316015 2019] [ssl:info] [pid 28414] [client
205.201.96.138:54346] AH01998: Connection closed to child 2 with abortive
shutdown (server foo.bar.com:443)
Unless I’m mistaken, it appears as though the sever is attempting to return an
HTTP 403 Response in these cases as well (and is logging that this response has
been sent), but client is receiving the handshake error before it gets the
response. Is this expected behavior, or is there some way to ensure that the
403 response gets propagated back to the client? I've tried moving the
SSLVerifyClient directive to the VirtualHost scope but still seem to get the
same result. Thanks,
Scott Kirby
Interoperability Developer
PCC - Physicians Computer Company
800-722-7708
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]