19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.net; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 192269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport com.android.internal.net.DomainNameValidator; 202269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackborn 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Config; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 258f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.InetAddress; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.Socket; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.security.GeneralSecurityException; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.security.KeyManagementException; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.security.KeyStore; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.security.KeyStoreException; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.security.NoSuchAlgorithmException; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.security.cert.Certificate; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.security.cert.X509Certificate; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.SocketFactory; 3834c0b2ee11c237be5244eecc34814862b3003822Dan Egnorimport javax.net.ssl.HostnameVerifier; 3934c0b2ee11c237be5244eecc34814862b3003822Dan Egnorimport javax.net.ssl.HttpsURLConnection; 4034c0b2ee11c237be5244eecc34814862b3003822Dan Egnorimport javax.net.ssl.SSLException; 4134c0b2ee11c237be5244eecc34814862b3003822Dan Egnorimport javax.net.ssl.SSLPeerUnverifiedException; 4234c0b2ee11c237be5244eecc34814862b3003822Dan Egnorimport javax.net.ssl.SSLSession; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.ssl.SSLSocket; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.ssl.SSLSocketFactory; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.ssl.TrustManager; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.ssl.TrustManagerFactory; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.ssl.X509TrustManager; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnorimport org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.xnet.provider.jsse.SSLContextImpl; 52e97c2006bf7c391c933307e520a392e532aa5d6aBob Leeimport org.apache.harmony.xnet.provider.jsse.SSLParameters; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 5560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * SSLSocketFactory implementation with several extra features: 5634c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 5760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * <ul> 5860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * <li>Timeout specification for SSL handshake operations 5934c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * <li>Hostname verification in most cases (see WARNINGs below) 6060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * <li>Optional SSL session caching with {@link SSLSessionCache} 619d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * <li>Optionally bypass all SSL certificate checks 6260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * </ul> 6334c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 6434c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * The handshake timeout does not apply to actual TCP socket connection. 6534c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * If you want a connection timeout as well, use {@link #createSocket()} 6634c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * and {@link Socket#connect(SocketAddress, int)}, after which you 6734c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * must verify the identity of the server you are connected to. 6834c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 6934c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * <p class="caution"><b>Most {@link SSLSocketFactory} implementations do not 7034c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * verify the server's identity, allowing man-in-the-middle attacks.</b> 7134c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * This implementation does check the server's certificate hostname, but only 7234c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * for createSocket variants that specify a hostname. When using methods that 7334c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * use {@link InetAddress} or which return an unconnected socket, you MUST 7434c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * verify the server's identity yourself to ensure a secure connection.</p> 7534c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 7634c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * <p>One way to verify the server's identity is to use 7734c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * {@link HttpsURLConnection#getDefaultHostnameVerifier()} to get a 7834c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * {@link HostnameVerifier} to verify the certificate hostname. 7934c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 8034c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * <p>On development devices, "setprop socket.relaxsslcheck yes" bypasses all 8134c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * SSL certificate and hostname checks for testing purposes. This setting 8234c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * requires root access. 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SSLCertificateSocketFactory extends SSLSocketFactory { 8560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private static final String TAG = "SSLCertificateSocketFactory"; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private static final TrustManager[] INSECURE_TRUST_MANAGER = new TrustManager[] { 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new X509TrustManager() { 8960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public X509Certificate[] getAcceptedIssuers() { return null; } 9060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public void checkClientTrusted(X509Certificate[] certs, String authType) { } 9160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public void checkServerTrusted(X509Certificate[] certs, String authType) { } 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9534c0b2ee11c237be5244eecc34814862b3003822Dan Egnor private static final HostnameVerifier HOSTNAME_VERIFIER = 9634c0b2ee11c237be5244eecc34814862b3003822Dan Egnor HttpsURLConnection.getDefaultHostnameVerifier(); 9734c0b2ee11c237be5244eecc34814862b3003822Dan Egnor 9860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private SSLSocketFactory mInsecureFactory = null; 9960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private SSLSocketFactory mSecureFactory = null; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private final int mHandshakeTimeoutMillis; 10260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private final SSLClientSessionCache mSessionCache; 1039d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor private final boolean mSecure; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor /** @deprecated Use {@link #getDefault(int)} instead. */ 10660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public SSLCertificateSocketFactory(int handshakeTimeoutMillis) { 1079d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor this(handshakeTimeoutMillis, null, true); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor private SSLCertificateSocketFactory( 1119d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor int handshakeTimeoutMillis, SSLSessionCache cache, boolean secure) { 11260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor mHandshakeTimeoutMillis = handshakeTimeoutMillis; 11360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor mSessionCache = cache == null ? null : cache.mSessionCache; 1149d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor mSecure = secure; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1189d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * Returns a new socket factory instance with an optional handshake timeout. 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0 12160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * for none. The socket timeout is reset to 0 after the handshake. 12234c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * @return a new SSLSocketFactory with the specified parameters 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public static SocketFactory getDefault(int handshakeTimeoutMillis) { 1259d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor return new SSLCertificateSocketFactory(handshakeTimeoutMillis, null, true); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1299d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * Returns a new socket factory instance with an optional handshake timeout 1309d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * and SSL session cache. 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0 13360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * for none. The socket timeout is reset to 0 after the handshake. 13460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * @param cache The {@link SSLClientSessionCache} to use, or null for no cache. 13534c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * @return a new SSLSocketFactory with the specified parameters 13660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor */ 1379d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor public static SSLSocketFactory getDefault(int handshakeTimeoutMillis, SSLSessionCache cache) { 1389d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor return new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache, true); 1399d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor } 1409d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor 1419d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor /** 1429d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * Returns a new instance of a socket factory with all SSL security checks 1439d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * disabled, using an optional handshake timeout and SSL session cache. 14434c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 14534c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * <p class="caution"><b>Warning:</b> Sockets created using this factory 14634c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * are vulnerable to man-in-the-middle attacks!</p> 1479d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * 1489d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0 1499d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * for none. The socket timeout is reset to 0 after the handshake. 1509d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * @param cache The {@link SSLClientSessionCache} to use, or null for no cache. 15134c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * @return an insecure SSLSocketFactory with the specified parameters 1529d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor */ 1539d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor public static SSLSocketFactory getInsecure(int handshakeTimeoutMillis, SSLSessionCache cache) { 1549d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor return new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache, false); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor /** 15860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * Returns a socket factory (also named SSLSocketFactory, but in a different 15960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * namespace) for use with the Apache HTTP stack. 16060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * 16160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0 16260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * for none. The socket timeout is reset to 0 after the handshake. 16360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * @param cache The {@link SSLClientSessionCache} to use, or null for no cache. 16460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * @return a new SocketFactory with the specified parameters 16560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor */ 16660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public static org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory( 16760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor int handshakeTimeoutMillis, 16860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor SSLSessionCache cache) { 16960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return new org.apache.http.conn.ssl.SSLSocketFactory( 1709d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache, true)); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17334c0b2ee11c237be5244eecc34814862b3003822Dan Egnor /** 17434c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * Verify the hostname of the certificate used by the other end of a 17534c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * connected socket. You MUST call this if you did not supply a hostname 17634c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * to {@link #createSocket()}. It is harmless to call this method 17734c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * redundantly if the hostname has already been verified. 17834c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 17934c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * <p>Wildcard certificates are allowed to verify any matching hostname, 18034c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * so "foo.bar.example.com" is verified if the peer has a certificate 18134c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * for "*.example.com". 18234c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 18334c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * @param socket An SSL socket which has been connected to a server 18434c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * @param hostname The expected hostname of the remote server 18534c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * @throws IOException if something goes wrong handshaking with the server 18634c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * @throws SSLPeerUnverifiedException if the server cannot prove its identity 18734c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 18834c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * @hide 18934c0b2ee11c237be5244eecc34814862b3003822Dan Egnor */ 19034c0b2ee11c237be5244eecc34814862b3003822Dan Egnor public static void verifyHostname(Socket socket, String hostname) throws IOException { 19134c0b2ee11c237be5244eecc34814862b3003822Dan Egnor if (!(socket instanceof SSLSocket)) { 19234c0b2ee11c237be5244eecc34814862b3003822Dan Egnor throw new IllegalArgumentException("Attempt to verify non-SSL socket"); 19334c0b2ee11c237be5244eecc34814862b3003822Dan Egnor } 19434c0b2ee11c237be5244eecc34814862b3003822Dan Egnor 19534c0b2ee11c237be5244eecc34814862b3003822Dan Egnor if (!isSslCheckRelaxed()) { 19634c0b2ee11c237be5244eecc34814862b3003822Dan Egnor // The code at the start of OpenSSLSocketImpl.startHandshake() 19734c0b2ee11c237be5244eecc34814862b3003822Dan Egnor // ensures that the call is idempotent, so we can safely call it. 19834c0b2ee11c237be5244eecc34814862b3003822Dan Egnor SSLSocket ssl = (SSLSocket) socket; 19934c0b2ee11c237be5244eecc34814862b3003822Dan Egnor ssl.startHandshake(); 20034c0b2ee11c237be5244eecc34814862b3003822Dan Egnor 20134c0b2ee11c237be5244eecc34814862b3003822Dan Egnor SSLSession session = ssl.getSession(); 20234c0b2ee11c237be5244eecc34814862b3003822Dan Egnor if (session == null) { 20334c0b2ee11c237be5244eecc34814862b3003822Dan Egnor throw new SSLException("Cannot verify SSL socket without session"); 20434c0b2ee11c237be5244eecc34814862b3003822Dan Egnor } 20534c0b2ee11c237be5244eecc34814862b3003822Dan Egnor if (!HOSTNAME_VERIFIER.verify(hostname, session)) { 20634c0b2ee11c237be5244eecc34814862b3003822Dan Egnor throw new SSLPeerUnverifiedException("Cannot verify hostname: " + hostname); 20734c0b2ee11c237be5244eecc34814862b3003822Dan Egnor } 20834c0b2ee11c237be5244eecc34814862b3003822Dan Egnor } 20934c0b2ee11c237be5244eecc34814862b3003822Dan Egnor } 21034c0b2ee11c237be5244eecc34814862b3003822Dan Egnor 21160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private SSLSocketFactory makeSocketFactory(TrustManager[] trustManagers) { 21260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor try { 21360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor SSLContextImpl sslContext = new SSLContextImpl(); 21460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor sslContext.engineInit(null, trustManagers, null, mSessionCache, null); 21560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return sslContext.engineGetSocketFactory(); 21660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor } catch (KeyManagementException e) { 21760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor Log.wtf(TAG, e); 21860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return (SSLSocketFactory) SSLSocketFactory.getDefault(); // Fallback 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor } 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22234c0b2ee11c237be5244eecc34814862b3003822Dan Egnor private static boolean isSslCheckRelaxed() { 22334c0b2ee11c237be5244eecc34814862b3003822Dan Egnor return "1".equals(SystemProperties.get("ro.debuggable")) && 22434c0b2ee11c237be5244eecc34814862b3003822Dan Egnor "yes".equals(SystemProperties.get("socket.relaxsslcheck")); 22534c0b2ee11c237be5244eecc34814862b3003822Dan Egnor } 22634c0b2ee11c237be5244eecc34814862b3003822Dan Egnor 22760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private synchronized SSLSocketFactory getDelegate() { 2289d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor // Relax the SSL check if instructed (for this factory, or systemwide) 22934c0b2ee11c237be5244eecc34814862b3003822Dan Egnor if (!mSecure || isSslCheckRelaxed()) { 23060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor if (mInsecureFactory == null) { 2319d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor if (mSecure) { 2329d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor Log.w(TAG, "*** BYPASSING SSL SECURITY CHECKS (socket.relaxsslcheck=yes) ***"); 2339d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor } else { 2349d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor Log.w(TAG, "Bypassing SSL security checks at caller's request"); 2359d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor } 23660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor mInsecureFactory = makeSocketFactory(INSECURE_TRUST_MANAGER); 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return mInsecureFactory; 23960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor } else { 24060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor if (mSecureFactory == null) { 24160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor mSecureFactory = makeSocketFactory(null); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return mSecureFactory; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24734c0b2ee11c237be5244eecc34814862b3003822Dan Egnor /** 24834c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * {@inheritDoc} 24934c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 250f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler * <p>This method verifies the peer's certificate hostname after connecting 251f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler * (unless created with {@link #getInsecure(int, SSLSessionCache)}). 25234c0b2ee11c237be5244eecc34814862b3003822Dan Egnor */ 25360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 25460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public Socket createSocket(Socket k, String host, int port, boolean close) throws IOException { 25560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(k, host, port, close); 25660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor s.setHandshakeTimeout(mHandshakeTimeoutMillis); 257f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler if (mSecure) { 258f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler verifyHostname(s, host); 259f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler } 26060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return s; 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26334c0b2ee11c237be5244eecc34814862b3003822Dan Egnor /** 26434c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * Creates a new socket which is not connected to any remote host. 26534c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * You must use {@link Socket#connect} to connect the socket. 26634c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 26734c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * <p class="caution"><b>Warning:</b> Hostname verification is not performed 26834c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * with this method. You MUST verify the server's identity after connecting 26934c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * the socket to avoid man-in-the-middle attacks.</p> 27034c0b2ee11c237be5244eecc34814862b3003822Dan Egnor */ 27160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 27260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public Socket createSocket() throws IOException { 27360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(); 27460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor s.setHandshakeTimeout(mHandshakeTimeoutMillis); 27560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return s; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27834c0b2ee11c237be5244eecc34814862b3003822Dan Egnor /** 27934c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * {@inheritDoc} 28034c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 28134c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * <p class="caution"><b>Warning:</b> Hostname verification is not performed 28234c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * with this method. You MUST verify the server's identity after connecting 28334c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * the socket to avoid man-in-the-middle attacks.</p> 28434c0b2ee11c237be5244eecc34814862b3003822Dan Egnor */ 28560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 28660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public Socket createSocket(InetAddress addr, int port, InetAddress localAddr, int localPort) 28760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor throws IOException { 28860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket( 28960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor addr, port, localAddr, localPort); 29060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor s.setHandshakeTimeout(mHandshakeTimeoutMillis); 29160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return s; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29434c0b2ee11c237be5244eecc34814862b3003822Dan Egnor /** 29534c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * {@inheritDoc} 29634c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 29734c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * <p class="caution"><b>Warning:</b> Hostname verification is not performed 29834c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * with this method. You MUST verify the server's identity after connecting 29934c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * the socket to avoid man-in-the-middle attacks.</p> 30034c0b2ee11c237be5244eecc34814862b3003822Dan Egnor */ 30160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 30260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public Socket createSocket(InetAddress addr, int port) throws IOException { 30360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(addr, port); 30460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor s.setHandshakeTimeout(mHandshakeTimeoutMillis); 30560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return s; 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30834c0b2ee11c237be5244eecc34814862b3003822Dan Egnor /** 30934c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * {@inheritDoc} 31034c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 311f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler * <p>This method verifies the peer's certificate hostname after connecting 312f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler * (unless created with {@link #getInsecure(int, SSLSessionCache)}). 31334c0b2ee11c237be5244eecc34814862b3003822Dan Egnor */ 31460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 31560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public Socket createSocket(String host, int port, InetAddress localAddr, int localPort) 31660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor throws IOException { 31760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket( 31860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor host, port, localAddr, localPort); 31960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor s.setHandshakeTimeout(mHandshakeTimeoutMillis); 320f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler if (mSecure) { 321f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler verifyHostname(s, host); 322f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler } 32360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return s; 32460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor } 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32634c0b2ee11c237be5244eecc34814862b3003822Dan Egnor /** 32734c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * {@inheritDoc} 32834c0b2ee11c237be5244eecc34814862b3003822Dan Egnor * 329f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler * <p>This method verifies the peer's certificate hostname after connecting 330f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler * (unless created with {@link #getInsecure(int, SSLSessionCache)}). 33134c0b2ee11c237be5244eecc34814862b3003822Dan Egnor */ 33260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 33360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public Socket createSocket(String host, int port) throws IOException { 33460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(host, port); 33560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor s.setHandshakeTimeout(mHandshakeTimeoutMillis); 336f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler if (mSecure) { 337f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler verifyHostname(s, host); 338f1f07993792dbf2d49613d474a696ec0927828d2Andrew Stadler } 33960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return s; 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String[] getDefaultCipherSuites() { 34460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return getDelegate().getSupportedCipherSuites(); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String[] getSupportedCipherSuites() { 34960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return getDelegate().getSupportedCipherSuites(); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 352