Details
-
Wish
-
Status: Resolved
-
Minor
-
Resolution: Fixed
-
None
-
None
Description
This issue brings to the fore that part of HTTPCLIENT-2134 which is actually within the scope of HttpClient: the possibility of using JSSE inbuilt endpoint identification ("HTTPS") instead of performing those checks externally (typically in org.apache.hc.client5.http.ssl.DefaultHostnameVerifier).
Java 1.7 added the method SSLParameters.setEndpointIdentificationAlgorithm(String). Calling this method with the argument "HTTPS" (case-insensitive) will result in the endpoint identification checks from RFC 2818 being automatically done by JSSE during the handshake (specifically when the X509TrustManager validates the server certificate). Note that the setting can also be interrogated via SSLParameters.getEndpointIdentificationAlgorithm.
This has some minor advantages relative to performing the checks externally:
- The check is done earlier in the handshake, reducing the cost of failed connections. (Technically this might still be achieved anyway by wrapping the X509TrustManager and applying a HostnameVerifier at that stage).
- Per my comments in
HTTPCLIENT-2134, in some nuanced situations SunJSSE will be willing to resume a session only if it knows for sure that endpoint identification is being used (which it can't know for an arbitrary HostnameVerifier). - SunJSSE's HTTPS endpoint identification has special (less-restrictive) rules for wildcard characters when the trust anchor is a certificate from the 'cacerts' file (what it calls a "public root CA").
There may be other implications that I am unaware of, but I think this establishes that some users may prefer (or even need) to delegate endpoint identification to JSSE in this way. They presumably will not then want a duplicate check in DefaultHostnameVerifier.
I am not yet that familiar with HttpClient, but I assume a user could already provide a custom SSLSocketFactory which enables JSSE endpoint identification on sockets before returning them, and then separately configure a no-op HostnameVerifier. I consider that to be rather fragile and it's easy to see mistakes leading to no endpoint identification being performed.
I am proposing that HttpClient support this via a simpler configuration mechanism. To loosely outline some basic options:
IGNORE: don't even check whether JSSE endpoint identification was enabled (i.e. assume it wasn't).
AWARE: check at runtime whether JSSE endpoint identification was "HTTPS" for a given socket connection.
DISABLE: remove any existing setting for JSSE endpoint identification (set it to "").
FORCE: overwrite any existing setting for JSSE endpoint identification (set it to "HTTPS").
So we would consider some value that came to us via the SSLSocketFactory's default socket setup, and whether to ignore it, respect it, or force it on/off. DefaultHostnameVerifier can then be set to possibly skip its own endpoint checks when appropriate.