Loading core/java/android/net/http/CertificateChainValidator.java +71 −29 Original line number Diff line number Diff line Loading @@ -16,22 +16,26 @@ package android.net.http; import com.android.org.conscrypt.SSLParametersImpl; import com.android.org.conscrypt.TrustManagerImpl; import android.util.Slog; import java.io.ByteArrayInputStream; import java.io.IOException; import java.lang.reflect.Method; import java.security.GeneralSecurityException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import javax.net.ssl.DefaultHostnameVerifier; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import javax.net.ssl.X509TrustManager; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509ExtendedTrustManager; /** * Class responsible for all server certificate validation functionality Loading @@ -39,28 +43,51 @@ import javax.net.ssl.X509TrustManager; * {@hide} */ public class CertificateChainValidator { private static final String TAG = "CertificateChainValidator"; private static class NoPreloadHolder { /** * The singleton instance of the certificate chain validator * The singleton instance of the certificate chain validator. */ private static final CertificateChainValidator sInstance = new CertificateChainValidator(); private static final CertificateChainValidator sInstance = new CertificateChainValidator(); /** * The singleton instance of the hostname verifier. */ private static final HostnameVerifier sVerifier = HttpsURLConnection .getDefaultHostnameVerifier(); } private static final DefaultHostnameVerifier sVerifier = new DefaultHostnameVerifier(); private X509ExtendedTrustManager mTrustManager; /** * @return The singleton instance of the certificates chain validator */ public static CertificateChainValidator getInstance() { return sInstance; return NoPreloadHolder.sInstance; } /** * Creates a new certificate chain validator. This is a private constructor. * If you need a Certificate chain validator, call getInstance(). */ private CertificateChainValidator() {} private CertificateChainValidator() { try { TrustManagerFactory tmf = TrustManagerFactory.getInstance("X.509"); for (TrustManager tm : tmf.getTrustManagers()) { if (tm instanceof X509ExtendedTrustManager) { mTrustManager = (X509ExtendedTrustManager) tm; } } } catch (NoSuchAlgorithmException e) { throw new RuntimeException("X.509 TrustManager factory must be available", e); } if (mTrustManager == null) { throw new RuntimeException( "None of the X.509 TrustManagers are X509ExtendedTrustManager"); } } /** * Performs the handshake and server certificates validation Loading Loading @@ -136,14 +163,27 @@ public class CertificateChainValidator { * Handles updates to credential storage. */ public static void handleTrustStorageUpdate() { TrustManagerFactory tmf; try { tmf = TrustManagerFactory.getInstance("X.509"); } catch (NoSuchAlgorithmException e) { Slog.w(TAG, "Couldn't find default X.509 TrustManagerFactory"); return; } TrustManager[] tms = tmf.getTrustManagers(); boolean sentUpdate = false; for (TrustManager tm : tms) { try { X509TrustManager x509TrustManager = SSLParametersImpl.getDefaultX509TrustManager(); if( x509TrustManager instanceof TrustManagerImpl ) { TrustManagerImpl trustManager = (TrustManagerImpl) x509TrustManager; trustManager.handleTrustStorageUpdate(); Method updateMethod = tm.getClass().getDeclaredMethod("handleTrustStorageUpdate"); updateMethod.setAccessible(true); updateMethod.invoke(tm); sentUpdate = true; } catch (Exception e) { } } } catch (KeyManagementException ignored) { if (!sentUpdate) { Slog.w(TAG, "Didn't find a TrustManager to handle CA list update"); } } Loading @@ -166,7 +206,8 @@ public class CertificateChainValidator { boolean valid = domain != null && !domain.isEmpty() && sVerifier.verify(domain, currCertificate); && NoPreloadHolder.sVerifier.verify(domain, new DelegatingSSLSession.CertificateWrap(currCertificate)); if (!valid) { if (HttpLog.LOGV) { HttpLog.v("certificate not for this host: " + domain); Loading @@ -175,13 +216,8 @@ public class CertificateChainValidator { } try { X509TrustManager x509TrustManager = SSLParametersImpl.getDefaultX509TrustManager(); if (x509TrustManager instanceof TrustManagerImpl) { TrustManagerImpl trustManager = (TrustManagerImpl) x509TrustManager; trustManager.checkServerTrusted(chain, authType, domain); } else { x509TrustManager.checkServerTrusted(chain, authType); } getInstance().getTrustManager().checkServerTrusted(chain, authType, new DelegatingSocketWrapper(domain)); return null; // No errors. } catch (GeneralSecurityException e) { if (HttpLog.LOGV) { Loading @@ -192,6 +228,12 @@ public class CertificateChainValidator { } } /** * Returns the platform default {@link X509ExtendedTrustManager}. */ private X509ExtendedTrustManager getTrustManager() { return mTrustManager; } private void closeSocketThrowException( SSLSocket socket, String errorMessage, String defaultErrorMessage) Loading core/java/android/net/http/DelegatingSSLSession.java 0 → 100644 +172 −0 Original line number Diff line number Diff line /* * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.http; import java.security.Principal; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSessionContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.X509ExtendedTrustManager; /** * This is used when only a {@code hostname} is available but usage of the new API * {@link X509ExtendedTrustManager#checkServerTrusted(X509Certificate[], String, Socket)} * requires a {@link SSLSocket}. * * @hide */ public class DelegatingSSLSession implements SSLSession { protected DelegatingSSLSession() { } public static class HostnameWrap extends DelegatingSSLSession { private final String mHostname; public HostnameWrap(String hostname) { mHostname = hostname; } @Override public String getPeerHost() { return mHostname; } } public static class CertificateWrap extends DelegatingSSLSession { private final Certificate mCertificate; public CertificateWrap(Certificate certificate) { mCertificate = certificate; } @Override public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { return new Certificate[] { mCertificate }; } } @Override public int getApplicationBufferSize() { throw new UnsupportedOperationException(); } @Override public String getCipherSuite() { throw new UnsupportedOperationException(); } @Override public long getCreationTime() { throw new UnsupportedOperationException(); } @Override public byte[] getId() { throw new UnsupportedOperationException(); } @Override public long getLastAccessedTime() { throw new UnsupportedOperationException(); } @Override public Certificate[] getLocalCertificates() { throw new UnsupportedOperationException(); } @Override public Principal getLocalPrincipal() { throw new UnsupportedOperationException(); } @Override public int getPacketBufferSize() { throw new UnsupportedOperationException(); } @Override public javax.security.cert.X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException { throw new UnsupportedOperationException(); } @Override public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { throw new UnsupportedOperationException(); } @Override public String getPeerHost() { throw new UnsupportedOperationException(); } @Override public int getPeerPort() { throw new UnsupportedOperationException(); } @Override public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { throw new UnsupportedOperationException(); } @Override public String getProtocol() { throw new UnsupportedOperationException(); } @Override public SSLSessionContext getSessionContext() { throw new UnsupportedOperationException(); } @Override public Object getValue(String name) { throw new UnsupportedOperationException(); } @Override public String[] getValueNames() { throw new UnsupportedOperationException(); } @Override public void invalidate() { throw new UnsupportedOperationException(); } @Override public boolean isValid() { throw new UnsupportedOperationException(); } @Override public void putValue(String name, Object value) { throw new UnsupportedOperationException(); } @Override public void removeValue(String name) { throw new UnsupportedOperationException(); } } No newline at end of file core/java/android/net/http/DelegatingSocketWrapper.java 0 → 100644 +127 −0 Original line number Diff line number Diff line /* * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.http; import java.io.IOException; import javax.net.ssl.HandshakeCompletedListener; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import javax.net.ssl.X509ExtendedTrustManager; /** * This is used when only a {@code hostname} is available for * {@link X509ExtendedTrustManager#checkServerTrusted(java.security.cert.X509Certificate[], String, Socket)} * but we want to use the new API that requires a {@link SSLSocket}. */ class DelegatingSocketWrapper extends SSLSocket { private String hostname; public DelegatingSocketWrapper(String hostname) { this.hostname = hostname; } @Override public String[] getSupportedCipherSuites() { throw new UnsupportedOperationException(); } @Override public String[] getEnabledCipherSuites() { throw new UnsupportedOperationException(); } @Override public void setEnabledCipherSuites(String[] suites) { throw new UnsupportedOperationException(); } @Override public String[] getSupportedProtocols() { throw new UnsupportedOperationException(); } @Override public String[] getEnabledProtocols() { throw new UnsupportedOperationException(); } @Override public void setEnabledProtocols(String[] protocols) { throw new UnsupportedOperationException(); } @Override public SSLSession getSession() { return new DelegatingSSLSession.HostnameWrap(hostname); } @Override public void addHandshakeCompletedListener(HandshakeCompletedListener listener) { throw new UnsupportedOperationException(); } @Override public void removeHandshakeCompletedListener(HandshakeCompletedListener listener) { throw new UnsupportedOperationException(); } @Override public void startHandshake() throws IOException { throw new UnsupportedOperationException(); } @Override public void setUseClientMode(boolean mode) { throw new UnsupportedOperationException(); } @Override public boolean getUseClientMode() { throw new UnsupportedOperationException(); } @Override public void setNeedClientAuth(boolean need) { throw new UnsupportedOperationException(); } @Override public void setWantClientAuth(boolean want) { throw new UnsupportedOperationException(); } @Override public boolean getNeedClientAuth() { throw new UnsupportedOperationException(); } @Override public boolean getWantClientAuth() { throw new UnsupportedOperationException(); } @Override public void setEnableSessionCreation(boolean flag) { throw new UnsupportedOperationException(); } @Override public boolean getEnableSessionCreation() { throw new UnsupportedOperationException(); } } No newline at end of file core/java/android/net/http/X509TrustManagerExtensions.java +17 −5 Original line number Diff line number Diff line Loading @@ -22,14 +22,25 @@ import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.List; import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLSocket; import javax.net.ssl.X509ExtendedTrustManager; import javax.net.ssl.X509TrustManager; /** * X509TrustManager wrapper exposing Android-added features. * * <p> The checkServerTrusted method allows callers to perform additional * verification of certificate chains after they have been successfully * verified by the platform.</p> * <p> * The checkServerTrusted method allows callers to perform additional * verification of certificate chains after they have been successfully verified * by the platform. * </p> * <p> * If the returned certificate list is not needed, see also * {@code X509ExtendedTrustManager#checkServerTrusted(X509Certificate[], String, java.net.Socket)} * where an {@link SSLSocket} can be used to verify the given hostname during * handshake using * {@code SSLParameters#setEndpointIdentificationAlgorithm(String)}. * </p> */ public class X509TrustManagerExtensions { Loading Loading @@ -61,6 +72,7 @@ public class X509TrustManagerExtensions { */ public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType, String host) throws CertificateException { return mDelegate.checkServerTrusted(chain, authType, host); return mDelegate.checkServerTrusted(chain, authType, new DelegatingSSLSession.HostnameWrap(host)); } } Loading
core/java/android/net/http/CertificateChainValidator.java +71 −29 Original line number Diff line number Diff line Loading @@ -16,22 +16,26 @@ package android.net.http; import com.android.org.conscrypt.SSLParametersImpl; import com.android.org.conscrypt.TrustManagerImpl; import android.util.Slog; import java.io.ByteArrayInputStream; import java.io.IOException; import java.lang.reflect.Method; import java.security.GeneralSecurityException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import javax.net.ssl.DefaultHostnameVerifier; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import javax.net.ssl.X509TrustManager; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509ExtendedTrustManager; /** * Class responsible for all server certificate validation functionality Loading @@ -39,28 +43,51 @@ import javax.net.ssl.X509TrustManager; * {@hide} */ public class CertificateChainValidator { private static final String TAG = "CertificateChainValidator"; private static class NoPreloadHolder { /** * The singleton instance of the certificate chain validator * The singleton instance of the certificate chain validator. */ private static final CertificateChainValidator sInstance = new CertificateChainValidator(); private static final CertificateChainValidator sInstance = new CertificateChainValidator(); /** * The singleton instance of the hostname verifier. */ private static final HostnameVerifier sVerifier = HttpsURLConnection .getDefaultHostnameVerifier(); } private static final DefaultHostnameVerifier sVerifier = new DefaultHostnameVerifier(); private X509ExtendedTrustManager mTrustManager; /** * @return The singleton instance of the certificates chain validator */ public static CertificateChainValidator getInstance() { return sInstance; return NoPreloadHolder.sInstance; } /** * Creates a new certificate chain validator. This is a private constructor. * If you need a Certificate chain validator, call getInstance(). */ private CertificateChainValidator() {} private CertificateChainValidator() { try { TrustManagerFactory tmf = TrustManagerFactory.getInstance("X.509"); for (TrustManager tm : tmf.getTrustManagers()) { if (tm instanceof X509ExtendedTrustManager) { mTrustManager = (X509ExtendedTrustManager) tm; } } } catch (NoSuchAlgorithmException e) { throw new RuntimeException("X.509 TrustManager factory must be available", e); } if (mTrustManager == null) { throw new RuntimeException( "None of the X.509 TrustManagers are X509ExtendedTrustManager"); } } /** * Performs the handshake and server certificates validation Loading Loading @@ -136,14 +163,27 @@ public class CertificateChainValidator { * Handles updates to credential storage. */ public static void handleTrustStorageUpdate() { TrustManagerFactory tmf; try { tmf = TrustManagerFactory.getInstance("X.509"); } catch (NoSuchAlgorithmException e) { Slog.w(TAG, "Couldn't find default X.509 TrustManagerFactory"); return; } TrustManager[] tms = tmf.getTrustManagers(); boolean sentUpdate = false; for (TrustManager tm : tms) { try { X509TrustManager x509TrustManager = SSLParametersImpl.getDefaultX509TrustManager(); if( x509TrustManager instanceof TrustManagerImpl ) { TrustManagerImpl trustManager = (TrustManagerImpl) x509TrustManager; trustManager.handleTrustStorageUpdate(); Method updateMethod = tm.getClass().getDeclaredMethod("handleTrustStorageUpdate"); updateMethod.setAccessible(true); updateMethod.invoke(tm); sentUpdate = true; } catch (Exception e) { } } } catch (KeyManagementException ignored) { if (!sentUpdate) { Slog.w(TAG, "Didn't find a TrustManager to handle CA list update"); } } Loading @@ -166,7 +206,8 @@ public class CertificateChainValidator { boolean valid = domain != null && !domain.isEmpty() && sVerifier.verify(domain, currCertificate); && NoPreloadHolder.sVerifier.verify(domain, new DelegatingSSLSession.CertificateWrap(currCertificate)); if (!valid) { if (HttpLog.LOGV) { HttpLog.v("certificate not for this host: " + domain); Loading @@ -175,13 +216,8 @@ public class CertificateChainValidator { } try { X509TrustManager x509TrustManager = SSLParametersImpl.getDefaultX509TrustManager(); if (x509TrustManager instanceof TrustManagerImpl) { TrustManagerImpl trustManager = (TrustManagerImpl) x509TrustManager; trustManager.checkServerTrusted(chain, authType, domain); } else { x509TrustManager.checkServerTrusted(chain, authType); } getInstance().getTrustManager().checkServerTrusted(chain, authType, new DelegatingSocketWrapper(domain)); return null; // No errors. } catch (GeneralSecurityException e) { if (HttpLog.LOGV) { Loading @@ -192,6 +228,12 @@ public class CertificateChainValidator { } } /** * Returns the platform default {@link X509ExtendedTrustManager}. */ private X509ExtendedTrustManager getTrustManager() { return mTrustManager; } private void closeSocketThrowException( SSLSocket socket, String errorMessage, String defaultErrorMessage) Loading
core/java/android/net/http/DelegatingSSLSession.java 0 → 100644 +172 −0 Original line number Diff line number Diff line /* * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.http; import java.security.Principal; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSessionContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.X509ExtendedTrustManager; /** * This is used when only a {@code hostname} is available but usage of the new API * {@link X509ExtendedTrustManager#checkServerTrusted(X509Certificate[], String, Socket)} * requires a {@link SSLSocket}. * * @hide */ public class DelegatingSSLSession implements SSLSession { protected DelegatingSSLSession() { } public static class HostnameWrap extends DelegatingSSLSession { private final String mHostname; public HostnameWrap(String hostname) { mHostname = hostname; } @Override public String getPeerHost() { return mHostname; } } public static class CertificateWrap extends DelegatingSSLSession { private final Certificate mCertificate; public CertificateWrap(Certificate certificate) { mCertificate = certificate; } @Override public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { return new Certificate[] { mCertificate }; } } @Override public int getApplicationBufferSize() { throw new UnsupportedOperationException(); } @Override public String getCipherSuite() { throw new UnsupportedOperationException(); } @Override public long getCreationTime() { throw new UnsupportedOperationException(); } @Override public byte[] getId() { throw new UnsupportedOperationException(); } @Override public long getLastAccessedTime() { throw new UnsupportedOperationException(); } @Override public Certificate[] getLocalCertificates() { throw new UnsupportedOperationException(); } @Override public Principal getLocalPrincipal() { throw new UnsupportedOperationException(); } @Override public int getPacketBufferSize() { throw new UnsupportedOperationException(); } @Override public javax.security.cert.X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException { throw new UnsupportedOperationException(); } @Override public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { throw new UnsupportedOperationException(); } @Override public String getPeerHost() { throw new UnsupportedOperationException(); } @Override public int getPeerPort() { throw new UnsupportedOperationException(); } @Override public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { throw new UnsupportedOperationException(); } @Override public String getProtocol() { throw new UnsupportedOperationException(); } @Override public SSLSessionContext getSessionContext() { throw new UnsupportedOperationException(); } @Override public Object getValue(String name) { throw new UnsupportedOperationException(); } @Override public String[] getValueNames() { throw new UnsupportedOperationException(); } @Override public void invalidate() { throw new UnsupportedOperationException(); } @Override public boolean isValid() { throw new UnsupportedOperationException(); } @Override public void putValue(String name, Object value) { throw new UnsupportedOperationException(); } @Override public void removeValue(String name) { throw new UnsupportedOperationException(); } } No newline at end of file
core/java/android/net/http/DelegatingSocketWrapper.java 0 → 100644 +127 −0 Original line number Diff line number Diff line /* * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.http; import java.io.IOException; import javax.net.ssl.HandshakeCompletedListener; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import javax.net.ssl.X509ExtendedTrustManager; /** * This is used when only a {@code hostname} is available for * {@link X509ExtendedTrustManager#checkServerTrusted(java.security.cert.X509Certificate[], String, Socket)} * but we want to use the new API that requires a {@link SSLSocket}. */ class DelegatingSocketWrapper extends SSLSocket { private String hostname; public DelegatingSocketWrapper(String hostname) { this.hostname = hostname; } @Override public String[] getSupportedCipherSuites() { throw new UnsupportedOperationException(); } @Override public String[] getEnabledCipherSuites() { throw new UnsupportedOperationException(); } @Override public void setEnabledCipherSuites(String[] suites) { throw new UnsupportedOperationException(); } @Override public String[] getSupportedProtocols() { throw new UnsupportedOperationException(); } @Override public String[] getEnabledProtocols() { throw new UnsupportedOperationException(); } @Override public void setEnabledProtocols(String[] protocols) { throw new UnsupportedOperationException(); } @Override public SSLSession getSession() { return new DelegatingSSLSession.HostnameWrap(hostname); } @Override public void addHandshakeCompletedListener(HandshakeCompletedListener listener) { throw new UnsupportedOperationException(); } @Override public void removeHandshakeCompletedListener(HandshakeCompletedListener listener) { throw new UnsupportedOperationException(); } @Override public void startHandshake() throws IOException { throw new UnsupportedOperationException(); } @Override public void setUseClientMode(boolean mode) { throw new UnsupportedOperationException(); } @Override public boolean getUseClientMode() { throw new UnsupportedOperationException(); } @Override public void setNeedClientAuth(boolean need) { throw new UnsupportedOperationException(); } @Override public void setWantClientAuth(boolean want) { throw new UnsupportedOperationException(); } @Override public boolean getNeedClientAuth() { throw new UnsupportedOperationException(); } @Override public boolean getWantClientAuth() { throw new UnsupportedOperationException(); } @Override public void setEnableSessionCreation(boolean flag) { throw new UnsupportedOperationException(); } @Override public boolean getEnableSessionCreation() { throw new UnsupportedOperationException(); } } No newline at end of file
core/java/android/net/http/X509TrustManagerExtensions.java +17 −5 Original line number Diff line number Diff line Loading @@ -22,14 +22,25 @@ import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.List; import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLSocket; import javax.net.ssl.X509ExtendedTrustManager; import javax.net.ssl.X509TrustManager; /** * X509TrustManager wrapper exposing Android-added features. * * <p> The checkServerTrusted method allows callers to perform additional * verification of certificate chains after they have been successfully * verified by the platform.</p> * <p> * The checkServerTrusted method allows callers to perform additional * verification of certificate chains after they have been successfully verified * by the platform. * </p> * <p> * If the returned certificate list is not needed, see also * {@code X509ExtendedTrustManager#checkServerTrusted(X509Certificate[], String, java.net.Socket)} * where an {@link SSLSocket} can be used to verify the given hostname during * handshake using * {@code SSLParameters#setEndpointIdentificationAlgorithm(String)}. * </p> */ public class X509TrustManagerExtensions { Loading Loading @@ -61,6 +72,7 @@ public class X509TrustManagerExtensions { */ public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType, String host) throws CertificateException { return mDelegate.checkServerTrusted(chain, authType, host); return mDelegate.checkServerTrusted(chain, authType, new DelegatingSSLSession.HostnameWrap(host)); } }