I have a custom HostnameVerifier that attempts to examine the certificate chain using SSLSession#getPeerCertificates(). After upgrading to Java 11, where it seems that TLSv1.3 is used by default, I am seeing that getPeerCertificates() throws an SSLPeerUnverifiedException after an HTTP redirect has occurred. If I force the protocol to TLSv1.2 this does not occur. If there is no redirect, then this does not occur.
Is this a bug in Java or a change in behavior with TLSv1.3? The code below demonstrates the problem when 'protocol' is either 'TLS' or 'TLSv1.3' and path is '/redirect'. doTest("TLSv1.3", "/redirect"); // Fails with SSLPeerUnverifiedException doTest("TLSv1.3", "/content"); // Succeeds doTest("TLSv1.2", "/redirect"); // Succeeds doTest("TLSv1.2", "/content"); // Succeeds private void doTest(String protocol, String path) throws IOException, NoSuchAlgorithmException, KeyManagementException { whenHttp(server) .match(get("/redirect")) .then(status(HttpStatus.MOVED_PERMANENTLY_301), contentType("text/html"), header("Location", "/content"), stringContent("redirected")); whenHttp(server) .match(get("/content")) .then(ok(), contentType("text/html"), stringContent("ok")); URL url = new URL("https", "localhost", server.getPort(), path); HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); SSLContext ctx = SSLContext.getInstance(protocol); TrustManager[] tms = {new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType){} @Override public void checkServerTrusted(X509Certificate[] chain, String authType){} @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }}; ctx.init(null, tms, new SecureRandom()); conn.setSSLSocketFactory(ctx.getSocketFactory()); conn.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { java.security.cert.Certificate[] chain = null; try { chain = session.getPeerCertificates(); } catch (SSLPeerUnverifiedException e) { throw new RuntimeException(e); } return true; } }); int status = conn.getResponseCode(); assertEquals(200, status); } Thanks, Dan Daniel L. Christensen Distinguished Engineer Micro Focus http://www.microfocus.com
<<attachment: Daniel_Christensen.vcf>>