We have a problem with doing a handshake for the certificate like
javax.net.ssl.SSLPeerUnverifiedException: Certificate for <g.i.t.n.c.com> doesn't match any of the subject alternative names: [*.t.n.c.com]
Our ingress is configured to provide a certificate with alternative name g.i.t.n.c.com
if we access it through DNS name and *.t.n.c.com
if we access through the IP.
But in our code we just have a Spring WS
client using Apache Http Client
under the hood.
Caused by: javax.net.ssl.SSLPeerUnverifiedException: Certificate for <g.i.t.n.c.com> doesn't match any of the subject alternative names: [*.t.n.c.com]
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:507)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:437)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:384)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:374)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
at org.springframework.ws.transport.http.HttpComponentsConnection.onSendAfterWrite(HttpComponentsConnection.java:121)
at org.springframework.ws.transport.AbstractWebServiceConnection.send(AbstractWebServiceConnection.java:48)
at org.springframework.ws.client.core.WebServiceTemplate.sendRequest(WebServiceTemplate.java:658)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:606)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
And for unknown reason that started happening at some time, and at some time it was ok and SslSocket
was established retrieving the right certificate (like it was accessing our Ingress
via DNS
hostname with SNI
hostname data) and at some point (causing the above exception) the call for establishing connection was using IP without DNS hostname
and no SNI
data, and we got the broken certificate that appears only if our ingress is accessed without DNS name
in SNI
.
To get SNI
details (ClientHello
message) you may run Java app with
-Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager
And you will have extra loggin to std.out
like
javax.net.ssl|DEBUG|02 14|XNIO-1 task-9|2023-09-04 12:48:06.626 MSK|Finished.java:860|Consuming server Finished handshake message (
How to force it to use only one way to connect, using the DNS name at any time?
We use Java 11.
https://bugs.openjdk.org/browse/JDK-8220723 this was the root cause of the problem
To work it around we forced the TLS1.2 to work to avoid using TLS1.3 through
adding
-Djdk.tls.client.protocols=TLSv1.2
or
-Dhttps.protocols=TLSv1.2