From 63aae8a111a4e22e99f95096cf469d08b2f4a5a1 Mon Sep 17 00:00:00 2001 From: xuelei Date: Mon, 28 Nov 2011 02:35:19 -0800 Subject: [PATCH] 7115524: sun.security.provider.certpath.ssl.SSLServerCertStore no longer works Reviewed-by: weijun --- .../certpath/ssl/SSLServerCertStore.java | 149 ++++++++++++++---- 1 file changed, 118 insertions(+), 31 deletions(-) diff --git a/src/share/classes/sun/security/provider/certpath/ssl/SSLServerCertStore.java b/src/share/classes/sun/security/provider/certpath/ssl/SSLServerCertStore.java index 5109e132d..f2a999f51 100644 --- a/src/share/classes/sun/security/provider/certpath/ssl/SSLServerCertStore.java +++ b/src/share/classes/sun/security/provider/certpath/ssl/SSLServerCertStore.java @@ -44,12 +44,16 @@ import java.security.cert.CertStoreSpi; import java.security.cert.CRLSelector; import java.security.cert.X509Certificate; import java.security.cert.X509CRL; +import java.net.Socket; +import java.net.URLConnection; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; +import javax.net.ssl.X509ExtendedTrustManager; /** * A CertStore that retrieves an SSL server's certificate chain. @@ -57,31 +61,74 @@ import javax.net.ssl.X509TrustManager; public final class SSLServerCertStore extends CertStoreSpi { private final URI uri; + private final static GetChainTrustManager trustManager; + private final static SSLSocketFactory socketFactory; + private final static HostnameVerifier hostnameVerifier; + + static { + trustManager = new GetChainTrustManager(); + hostnameVerifier = new HostnameVerifier() { + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + + SSLSocketFactory tempFactory; + try { + SSLContext context = SSLContext.getInstance("SSL"); + context.init(null, new TrustManager[] { trustManager }, null); + tempFactory = context.getSocketFactory(); + } catch (GeneralSecurityException gse) { + tempFactory = null; + } + + socketFactory = tempFactory; + } SSLServerCertStore(URI uri) throws InvalidAlgorithmParameterException { super(null); this.uri = uri; } - public synchronized Collection engineGetCertificates - (CertSelector selector) throws CertStoreException - { + public Collection engineGetCertificates + (CertSelector selector) throws CertStoreException { + try { - SSLContext sc = SSLContext.getInstance("SSL"); - GetChainTrustManager xtm = new GetChainTrustManager(); - sc.init(null, new TrustManager[] { xtm }, null); - HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); - HttpsURLConnection.setDefaultHostnameVerifier( - new HostnameVerifier() { - public boolean verify(String hostname, SSLSession session) { - return true; + URLConnection urlConn = uri.toURL().openConnection(); + if (urlConn instanceof HttpsURLConnection) { + if (socketFactory == null) { + throw new CertStoreException( + "No initialized SSLSocketFactory"); + } + + HttpsURLConnection https = (HttpsURLConnection)urlConn; + https.setSSLSocketFactory(socketFactory); + https.setHostnameVerifier(hostnameVerifier); + synchronized (trustManager) { + try { + https.connect(); + return getMatchingCerts( + trustManager.serverChain, selector); + } catch (IOException ioe) { + // If the server certificate has already been + // retrieved, don't mind the connection state. + if (trustManager.exchangedServerCerts) { + return getMatchingCerts( + trustManager.serverChain, selector); + } + + // otherwise, rethrow the exception + throw ioe; + } finally { + trustManager.cleanup(); } - }); - uri.toURL().openConnection().connect(); - return getMatchingCerts(xtm.serverChain, selector); - } catch (GeneralSecurityException | IOException e) { - throw new CertStoreException(e); + } + } + } catch (IOException ioe) { + throw new CertStoreException(ioe); } + + return Collections.emptySet(); } private static List getMatchingCerts @@ -106,37 +153,77 @@ public final class SSLServerCertStore extends CertStoreSpi { throw new UnsupportedOperationException(); } - static synchronized CertStore getInstance(URI uri) + static CertStore getInstance(URI uri) throws InvalidAlgorithmParameterException { return new CS(new SSLServerCertStore(uri), null, "SSLServer", null); } /* - * An X509TrustManager that simply stores a reference to the server's - * certificate chain. + * An X509ExtendedTrustManager that ignores the server certificate + * validation. */ - private static class GetChainTrustManager implements X509TrustManager { - private List serverChain; + private static class GetChainTrustManager + extends X509ExtendedTrustManager { + + private List serverChain = + Collections.emptyList(); + private boolean exchangedServerCerts = false; + @Override public X509Certificate[] getAcceptedIssuers() { - throw new UnsupportedOperationException(); + return new X509Certificate[0]; } + @Override public void checkClientTrusted(X509Certificate[] chain, - String authType) - throws CertificateException - { + String authType) throws CertificateException { + + throw new UnsupportedOperationException(); + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType, + Socket socket) throws CertificateException { + throw new UnsupportedOperationException(); } + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType, + SSLEngine engine) throws CertificateException { + + throw new UnsupportedOperationException(); + } + + @Override public void checkServerTrusted(X509Certificate[] chain, - String authType) - throws CertificateException - { + String authType) throws CertificateException { + + exchangedServerCerts = true; this.serverChain = (chain == null) - ? Collections.emptyList() - : Arrays.asList(chain); + ? Collections.emptyList() + : Arrays.asList(chain); + + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType, + Socket socket) throws CertificateException { + + checkServerTrusted(chain, authType); + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType, + SSLEngine engine) throws CertificateException { + + checkServerTrusted(chain, authType); + } + + void cleanup() { + exchangedServerCerts = false; + serverChain = Collections.emptyList(); } } -- GitLab