13bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath/*
23bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/conn/ssl/SSLSocketFactory.java $
33bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * $Revision: 659194 $
43bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * $Date: 2008-05-22 11:33:47 -0700 (Thu, 22 May 2008) $
53bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *
63bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * ====================================================================
73bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * Licensed to the Apache Software Foundation (ASF) under one
83bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * or more contributor license agreements.  See the NOTICE file
93bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * distributed with this work for additional information
103bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * regarding copyright ownership.  The ASF licenses this file
113bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * to you under the Apache License, Version 2.0 (the
123bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * "License"); you may not use this file except in compliance
133bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * with the License.  You may obtain a copy of the License at
143bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *
153bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *   http://www.apache.org/licenses/LICENSE-2.0
163bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *
173bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * Unless required by applicable law or agreed to in writing,
183bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * software distributed under the License is distributed on an
193bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
203bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * KIND, either express or implied.  See the License for the
213bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * specific language governing permissions and limitations
223bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * under the License.
233bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * ====================================================================
243bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *
253bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * This software consists of voluntary contributions made by many
263bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * individuals on behalf of the Apache Software Foundation.  For more
273bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * information on the Apache Software Foundation, please see
283bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * <http://www.apache.org/>.
293bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *
303bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath */
313bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
323bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathpackage org.apache.http.conn.ssl;
333bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
343bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport org.apache.http.conn.scheme.HostNameResolver;
353bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport org.apache.http.conn.scheme.LayeredSocketFactory;
363bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport org.apache.http.params.HttpConnectionParams;
373bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport org.apache.http.params.HttpParams;
383bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
393bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport javax.net.ssl.HttpsURLConnection;
403bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport javax.net.ssl.KeyManager;
413bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport javax.net.ssl.KeyManagerFactory;
423bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport javax.net.ssl.SSLContext;
433bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport javax.net.ssl.SSLSocket;
443bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport javax.net.ssl.TrustManager;
453bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport javax.net.ssl.TrustManagerFactory;
463bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport java.io.IOException;
473bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport java.net.InetAddress;
483bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport java.net.InetSocketAddress;
493bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport java.net.Socket;
503bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport java.net.UnknownHostException;
513bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport java.security.KeyManagementException;
523bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport java.security.KeyStore;
533bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport java.security.KeyStoreException;
543bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport java.security.NoSuchAlgorithmException;
553bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport java.security.SecureRandom;
563bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathimport java.security.UnrecoverableKeyException;
573bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
583bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath/**
593bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * Layered socket factory for TLS/SSL connections, based on JSSE.
603bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *.
613bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * <p>
623bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * SSLSocketFactory can be used to validate the identity of the HTTPS
633bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * server against a list of trusted certificates and to authenticate to
643bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * the HTTPS server using a private key.
653bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * </p>
663bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *
673bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * <p>
683bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * SSLSocketFactory will enable server authentication when supplied with
693bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * a {@link KeyStore truststore} file containg one or several trusted
703bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * certificates. The client secure socket will reject the connection during
713bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * the SSL session handshake if the target HTTPS server attempts to
723bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * authenticate itself with a non-trusted certificate.
733bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * </p>
743bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *
753bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * <p>
763bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * Use JDK keytool utility to import a trusted certificate and generate a truststore file:
773bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *    <pre>
783bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     keytool -import -alias "my server cert" -file server.crt -keystore my.truststore
793bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *    </pre>
803bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * </p>
813bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *
823bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * <p>
833bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * SSLSocketFactory will enable client authentication when supplied with
843bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * a {@link KeyStore keystore} file containg a private key/public certificate
853bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * pair. The client secure socket will use the private key to authenticate
863bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * itself to the target HTTPS server during the SSL session handshake if
873bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * requested to do so by the server.
883bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * The target HTTPS server will in its turn verify the certificate presented
893bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * by the client in order to establish client's authenticity
903bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * </p>
913bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *
923bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * <p>
933bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * Use the following sequence of actions to generate a keystore file
943bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * </p>
953bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *   <ul>
963bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     <li>
973bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      <p>
983bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      Use JDK keytool utility to generate a new key
993bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      <pre>keytool -genkey -v -alias "my client key" -validity 365 -keystore my.keystore</pre>
1003bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      For simplicity use the same password for the key as that of the keystore
1013bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      </p>
1023bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     </li>
1033bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     <li>
1043bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      <p>
1053bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      Issue a certificate signing request (CSR)
1063bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      <pre>keytool -certreq -alias "my client key" -file mycertreq.csr -keystore my.keystore</pre>
1073bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     </p>
1083bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     </li>
1093bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     <li>
1103bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      <p>
1113bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      Send the certificate request to the trusted Certificate Authority for signature.
1123bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      One may choose to act as her own CA and sign the certificate request using a PKI
1133bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      tool, such as OpenSSL.
1143bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      </p>
1153bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     </li>
1163bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     <li>
1173bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      <p>
1183bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *       Import the trusted CA root certificate
1193bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *       <pre>keytool -import -alias "my trusted ca" -file caroot.crt -keystore my.keystore</pre>
1203bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      </p>
1213bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     </li>
1223bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     <li>
1233bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      <p>
1243bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *       Import the PKCS#7 file containg the complete certificate chain
1253bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *       <pre>keytool -import -alias "my client key" -file mycert.p7 -keystore my.keystore</pre>
1263bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      </p>
1273bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     </li>
1283bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     <li>
1293bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      <p>
1303bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *       Verify the content the resultant keystore file
1313bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *       <pre>keytool -list -v -keystore my.keystore</pre>
1323bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *      </p>
1333bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     </li>
1343bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *   </ul>
1353bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
1363bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * @author Julius Davies
1373bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *
1383bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * @deprecated Please use {@link java.net.URL#openConnection} instead.
1393bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
1403bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath *     for further details.
1413bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath */
1423bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath@Deprecated
1433bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamathpublic class SSLSocketFactory implements LayeredSocketFactory {
1443bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
1453bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public static final String TLS   = "TLS";
1463bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public static final String SSL   = "SSL";
1473bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public static final String SSLV2 = "SSLv2";
1483bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
1493bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public static final X509HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER
1503bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        = new AllowAllHostnameVerifier();
1513bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
1523bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public static final X509HostnameVerifier BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
1533bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        = new BrowserCompatHostnameVerifier();
1543bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
1553bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public static final X509HostnameVerifier STRICT_HOSTNAME_VERIFIER
1563bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        = new StrictHostnameVerifier();
1573bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
1583bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    /*
1593bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * Put defaults into holder class to avoid class preloading creating an
1603bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * instance of the classes referenced.
1613bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     */
1623bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    private static class NoPreloadHolder {
1633bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        /**
1643bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath         * The factory using the default JVM settings for secure connections.
1653bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath         */
1663bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        private static final SSLSocketFactory DEFAULT_FACTORY = new SSLSocketFactory();
1673bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
1683bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
1693bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    /**
1703bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * Gets an singleton instance of the SSLProtocolSocketFactory.
1713bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * @return a SSLProtocolSocketFactory
1723bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     */
1733bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public static SSLSocketFactory getSocketFactory() {
1743bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        return NoPreloadHolder.DEFAULT_FACTORY;
1753bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
1763bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
1773bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    private final SSLContext sslcontext;
1783bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    private final javax.net.ssl.SSLSocketFactory socketfactory;
1793bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    private final HostNameResolver nameResolver;
1803bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    private X509HostnameVerifier hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
1813bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
1823bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public SSLSocketFactory(
1833bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        String algorithm,
1843bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        final KeyStore keystore,
1853bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        final String keystorePassword,
1863bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        final KeyStore truststore,
1873bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        final SecureRandom random,
1883bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        final HostNameResolver nameResolver)
1893bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException
1903bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    {
1913bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        super();
1923bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        if (algorithm == null) {
1933bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            algorithm = TLS;
1943bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        }
1953bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        KeyManager[] keymanagers = null;
1963bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        if (keystore != null) {
1973bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            keymanagers = createKeyManagers(keystore, keystorePassword);
1983bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        }
1993bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        TrustManager[] trustmanagers = null;
2003bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        if (truststore != null) {
2013bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            trustmanagers = createTrustManagers(truststore);
2023bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        }
2033bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        this.sslcontext = SSLContext.getInstance(algorithm);
2043bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        this.sslcontext.init(keymanagers, trustmanagers, random);
2053bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        this.socketfactory = this.sslcontext.getSocketFactory();
2063bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        this.nameResolver = nameResolver;
2073bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
2083bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
2093bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public SSLSocketFactory(
2103bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            final KeyStore keystore,
2113bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            final String keystorePassword,
2123bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            final KeyStore truststore)
2133bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException
2143bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    {
2153bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        this(TLS, keystore, keystorePassword, truststore, null, null);
2163bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
2173bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
2183bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public SSLSocketFactory(final KeyStore keystore, final String keystorePassword)
2193bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException
2203bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    {
2213bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        this(TLS, keystore, keystorePassword, null, null, null);
2223bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
2233bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
2243bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public SSLSocketFactory(final KeyStore truststore)
2253bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException
2263bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    {
2273bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        this(TLS, null, null, truststore, null, null);
2283bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
2293bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
2303bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    /**
2313bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * Constructs an HttpClient SSLSocketFactory backed by the given JSSE
2323bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * SSLSocketFactory.
2333bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     *
2343bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * @hide
2353bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     */
2363bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public SSLSocketFactory(javax.net.ssl.SSLSocketFactory socketfactory) {
2373bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        super();
2383bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        this.sslcontext = null;
2393bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        this.socketfactory = socketfactory;
2403bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        this.nameResolver = null;
2413bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
2423bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
2433bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    /**
2443bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * Creates the default SSL socket factory.
2453bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * This constructor is used exclusively to instantiate the factory for
2463bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * {@link #getSocketFactory getSocketFactory}.
2473bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     */
2483bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    private SSLSocketFactory() {
2493bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        super();
2503bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        this.sslcontext = null;
2513bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        this.socketfactory = HttpsURLConnection.getDefaultSSLSocketFactory();
2523bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        this.nameResolver = null;
2533bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
2543bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
2553bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    private static KeyManager[] createKeyManagers(final KeyStore keystore, final String password)
2563bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
2573bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        if (keystore == null) {
2583bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            throw new IllegalArgumentException("Keystore may not be null");
2593bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        }
2603bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(
2613bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            KeyManagerFactory.getDefaultAlgorithm());
2623bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        kmfactory.init(keystore, password != null ? password.toCharArray(): null);
2633bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        return kmfactory.getKeyManagers();
2643bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
2653bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
2663bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    private static TrustManager[] createTrustManagers(final KeyStore keystore)
2673bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        throws KeyStoreException, NoSuchAlgorithmException {
2683bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        if (keystore == null) {
2693bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            throw new IllegalArgumentException("Keystore may not be null");
2703bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        }
2713bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
2723bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            TrustManagerFactory.getDefaultAlgorithm());
2733bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        tmfactory.init(keystore);
2743bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        return tmfactory.getTrustManagers();
2753bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
2763bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
2773bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
2783bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    // non-javadoc, see interface org.apache.http.conn.SocketFactory
2793bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public Socket createSocket()
2803bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        throws IOException {
2813bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
2823bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        // the cast makes sure that the factory is working as expected
2833bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        return (SSLSocket) this.socketfactory.createSocket();
2843bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
2853bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
2863bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
2873bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    // non-javadoc, see interface org.apache.http.conn.SocketFactory
2883bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public Socket connectSocket(
2893bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        final Socket sock,
2903bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        final String host,
2913bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        final int port,
2923bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        final InetAddress localAddress,
2933bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        int localPort,
2943bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        final HttpParams params
2953bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    ) throws IOException {
2963bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
2973bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        if (host == null) {
2983bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            throw new IllegalArgumentException("Target host may not be null.");
2993bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        }
3003bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        if (params == null) {
3013bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            throw new IllegalArgumentException("Parameters may not be null.");
3023bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        }
3033bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3043bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        SSLSocket sslsock = (SSLSocket)
3053bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            ((sock != null) ? sock : createSocket());
3063bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3073bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        if ((localAddress != null) || (localPort > 0)) {
3083bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3093bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            // we need to bind explicitly
3103bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            if (localPort < 0)
3113bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath                localPort = 0; // indicates "any"
3123bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3133bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            InetSocketAddress isa =
3143bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath                new InetSocketAddress(localAddress, localPort);
3153bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            sslsock.bind(isa);
3163bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        }
3173bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3183bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
3193bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        int soTimeout = HttpConnectionParams.getSoTimeout(params);
3203bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3213bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        InetSocketAddress remoteAddress;
3223bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        if (this.nameResolver != null) {
3233bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            remoteAddress = new InetSocketAddress(this.nameResolver.resolve(host), port);
3243bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        } else {
3253bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            remoteAddress = new InetSocketAddress(host, port);
3263bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        }
3273bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3283bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        sslsock.connect(remoteAddress, connTimeout);
3293bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3303bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        sslsock.setSoTimeout(soTimeout);
3313bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        try {
332423a47bb025e8e15c9c25c4500315f8013637097Kenny Root            // BEGIN android-added
333423a47bb025e8e15c9c25c4500315f8013637097Kenny Root            /*
334423a47bb025e8e15c9c25c4500315f8013637097Kenny Root             * Make sure we have started the handshake before verifying.
335423a47bb025e8e15c9c25c4500315f8013637097Kenny Root             * Otherwise when we go to the hostname verifier, it directly calls
336423a47bb025e8e15c9c25c4500315f8013637097Kenny Root             * SSLSocket#getSession() which swallows SSL handshake errors.
337423a47bb025e8e15c9c25c4500315f8013637097Kenny Root             */
338423a47bb025e8e15c9c25c4500315f8013637097Kenny Root            sslsock.startHandshake();
339423a47bb025e8e15c9c25c4500315f8013637097Kenny Root            // END android-added
3403bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            hostnameVerifier.verify(host, sslsock);
3413bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            // verifyHostName() didn't blowup - good!
3423bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        } catch (IOException iox) {
3433bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            // close the socket before re-throwing the exception
3443bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            try { sslsock.close(); } catch (Exception x) { /*ignore*/ }
3453bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            throw iox;
3463bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        }
3473bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3483bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        return sslsock;
3493bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
3503bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3513bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3523bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    /**
3533bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * Checks whether a socket connection is secure.
3543bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * This factory creates TLS/SSL socket connections
3553bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * which, by default, are considered secure.
3563bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * <br/>
3573bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * Derived classes may override this method to perform
3583bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * runtime checks, for example based on the cypher suite.
3593bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     *
3603bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * @param sock      the connected socket
3613bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     *
3623bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * @return  <code>true</code>
3633bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     *
3643bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     * @throws IllegalArgumentException if the argument is invalid
3653bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath     */
3663bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public boolean isSecure(Socket sock)
3673bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        throws IllegalArgumentException {
3683bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3693bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        if (sock == null) {
3703bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            throw new IllegalArgumentException("Socket may not be null.");
3713bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        }
3723bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        // This instanceof check is in line with createSocket() above.
3733bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        if (!(sock instanceof SSLSocket)) {
3743bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            throw new IllegalArgumentException
3753bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath                ("Socket not created by this factory.");
3763bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        }
3773bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        // This check is performed last since it calls the argument object.
3783bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        if (sock.isClosed()) {
3793bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            throw new IllegalArgumentException("Socket is closed.");
3803bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        }
3813bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3823bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        return true;
3833bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3843bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    } // isSecure
3853bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3863bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
3873bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    // non-javadoc, see interface LayeredSocketFactory
3883bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public Socket createSocket(
3893bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        final Socket socket,
3903bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        final String host,
3913bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        final int port,
3923bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        final boolean autoClose
3933bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    ) throws IOException, UnknownHostException {
3943bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket(
3953bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath              socket,
3963bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath              host,
3973bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath              port,
3983bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath              autoClose
3993bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        );
400725a4a71b8f2a5493628d87556c78860f66d2308Kenny Root        // BEGIN android-added
401725a4a71b8f2a5493628d87556c78860f66d2308Kenny Root        /*
402725a4a71b8f2a5493628d87556c78860f66d2308Kenny Root         * Make sure we have started the handshake before verifying.
403725a4a71b8f2a5493628d87556c78860f66d2308Kenny Root         * Otherwise when we go to the hostname verifier, it directly calls
404725a4a71b8f2a5493628d87556c78860f66d2308Kenny Root         * SSLSocket#getSession() which swallows SSL handshake errors.
405725a4a71b8f2a5493628d87556c78860f66d2308Kenny Root         */
406725a4a71b8f2a5493628d87556c78860f66d2308Kenny Root        sslSocket.startHandshake();
407725a4a71b8f2a5493628d87556c78860f66d2308Kenny Root        // END android-added
4083bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        hostnameVerifier.verify(host, sslSocket);
4093bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        // verifyHostName() didn't blowup - good!
4103bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        return sslSocket;
4113bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
4123bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
4133bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public void setHostnameVerifier(X509HostnameVerifier hostnameVerifier) {
4143bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        if ( hostnameVerifier == null ) {
4153bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath            throw new IllegalArgumentException("Hostname verifier may not be null");
4163bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        }
4173bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        this.hostnameVerifier = hostnameVerifier;
4183bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
4193bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
4203bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    public X509HostnameVerifier getHostnameVerifier() {
4213bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath        return hostnameVerifier;
4223bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath    }
4233bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath
4243bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath}
425