I am trying to figure out how to send a successful HTTP GET request to a server requiring SNI.
I searched in SO and elsewhere and found several articles that said SNI is now supported in JDK7, as well as Apache HTTP components.
https://issues.apache.org/jira/browse/HTTPCLIENT-1119 https://wiki.apache.org/HttpComponents/SNISupport
Corresponding SO article: Certificate chain other than HTTPSURLconnection and Apache (System) DefaultHttpClient
-
However, I cannot find any documents that show how to make this work.
Here is the code I'm using ...
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); String trustedCertsPath = System.getenv("JAVA_HOME") + "/jre/lib/security/cacerts"; FileInputStream certstream = new FileInputStream(new File(trustedCertsPath)); try { trustStore.load(certstream, "changeit".toCharArray()); } finally { certstream.close(); } // Trust own CA and all self-signed certs SSLContext sslcontext = SSLContexts.custom() .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()) .build(); // Allow TLSv1 protocol only SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); CloseableHttpClient httpclient2 = HttpClients.custom() .setSSLSocketFactory(sslsf) .build(); CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpget = new HttpGet(uri); CloseableHttpResponse response = httpclient.execute(httpget); try { HttpEntity entity = response.getEntity(); if (entity != null) { tempFile = File.createTempFile(httpFile.getTempFilePrefix(), httpFile.getTempFilePosfix()); FileOutputStream os = new FileOutputStream(tempFile); InputStream instream = entity.getContent(); try { IOUtils.copy(instream, os); } finally { try { instream.close(); } catch (Exception e) {} try { os.close(); } catch (Exception e) {} } } } finally { response.close(); }
When I run this, the request fails.
The server requires an SNI in the request, and without it, it returns an expired certificate that has the wrong CommonName, because of which it is rejected.
If I use an instance of httpclient2 that is configured using a custom SSL context to allow all hTTP certificates, the request succeeds. However, this is not what I want to enable on a server that does a lot of downloads per day against different hosts.
I am using httpclient v 4.3.5
Any help was appreciated.
Thanks.
feroze
source share