Merge "email: add support for Server Name Indication (SNI)"
This commit is contained in:
commit
aa207cc6f1
@ -42,7 +42,7 @@ LOCAL_SRC_FILES += $(call all-java-files-under, $(apache_src_dir))
|
|||||||
LOCAL_SRC_FILES += $(imported_unified_email_files)
|
LOCAL_SRC_FILES += $(imported_unified_email_files)
|
||||||
LOCAL_SRC_FILES += $(call all-java-files-under, $(unified_email_src_dir)/com/android/emailcommon)
|
LOCAL_SRC_FILES += $(call all-java-files-under, $(unified_email_src_dir)/com/android/emailcommon)
|
||||||
|
|
||||||
LOCAL_SDK_VERSION := 14
|
LOCAL_SDK_VERSION := 17
|
||||||
|
|
||||||
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
|
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
|
||||||
|
|
||||||
|
@ -33,6 +33,10 @@
|
|||||||
|
|
||||||
package com.android.emailcommon.utility;
|
package com.android.emailcommon.utility;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.net.SSLCertificateSocketFactory;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
import org.apache.http.conn.scheme.HostNameResolver;
|
import org.apache.http.conn.scheme.HostNameResolver;
|
||||||
import org.apache.http.conn.scheme.LayeredSocketFactory;
|
import org.apache.http.conn.scheme.LayeredSocketFactory;
|
||||||
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
|
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
|
||||||
@ -42,7 +46,6 @@ import org.apache.http.conn.ssl.X509HostnameVerifier;
|
|||||||
import org.apache.http.params.HttpConnectionParams;
|
import org.apache.http.params.HttpConnectionParams;
|
||||||
import org.apache.http.params.HttpParams;
|
import org.apache.http.params.HttpParams;
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
|
||||||
import javax.net.ssl.KeyManager;
|
import javax.net.ssl.KeyManager;
|
||||||
import javax.net.ssl.KeyManagerFactory;
|
import javax.net.ssl.KeyManagerFactory;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
@ -156,21 +159,9 @@ public class SSLSocketFactory implements LayeredSocketFactory {
|
|||||||
|
|
||||||
public static final X509HostnameVerifier STRICT_HOSTNAME_VERIFIER
|
public static final X509HostnameVerifier STRICT_HOSTNAME_VERIFIER
|
||||||
= new StrictHostnameVerifier();
|
= new StrictHostnameVerifier();
|
||||||
/**
|
|
||||||
* The factory using the default JVM settings for secure connections.
|
|
||||||
*/
|
|
||||||
private static final SSLSocketFactory DEFAULT_FACTORY = new SSLSocketFactory();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets an singleton instance of the SSLProtocolSocketFactory.
|
|
||||||
* @return a SSLProtocolSocketFactory
|
|
||||||
*/
|
|
||||||
public static SSLSocketFactory getSocketFactory() {
|
|
||||||
return DEFAULT_FACTORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final SSLContext sslcontext;
|
private final SSLContext sslcontext;
|
||||||
private final javax.net.ssl.SSLSocketFactory socketfactory;
|
private final SSLCertificateSocketFactory socketfactory;
|
||||||
private final HostNameResolver nameResolver;
|
private final HostNameResolver nameResolver;
|
||||||
private X509HostnameVerifier hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
|
private X509HostnameVerifier hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
|
||||||
|
|
||||||
@ -197,7 +188,7 @@ public class SSLSocketFactory implements LayeredSocketFactory {
|
|||||||
}
|
}
|
||||||
sslcontext = SSLContext.getInstance(algorithm);
|
sslcontext = SSLContext.getInstance(algorithm);
|
||||||
sslcontext.init(keymanagers, trustmanagers, random);
|
sslcontext.init(keymanagers, trustmanagers, random);
|
||||||
socketfactory = sslcontext.getSocketFactory();
|
socketfactory = (SSLCertificateSocketFactory) sslcontext.getSocketFactory();
|
||||||
this.nameResolver = nameResolver;
|
this.nameResolver = nameResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,25 +217,13 @@ public class SSLSocketFactory implements LayeredSocketFactory {
|
|||||||
* Constructs an HttpClient SSLSocketFactory backed by the given JSSE
|
* Constructs an HttpClient SSLSocketFactory backed by the given JSSE
|
||||||
* SSLSocketFactory.
|
* SSLSocketFactory.
|
||||||
*/
|
*/
|
||||||
public SSLSocketFactory(javax.net.ssl.SSLSocketFactory socketfactory) {
|
public SSLSocketFactory(SSLCertificateSocketFactory socketfactory) {
|
||||||
super();
|
super();
|
||||||
sslcontext = null;
|
sslcontext = null;
|
||||||
this.socketfactory = socketfactory;
|
this.socketfactory = socketfactory;
|
||||||
nameResolver = null;
|
nameResolver = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the default SSL socket factory.
|
|
||||||
* This constructor is used exclusively to instantiate the factory for
|
|
||||||
* {@link #getSocketFactory getSocketFactory}.
|
|
||||||
*/
|
|
||||||
private SSLSocketFactory() {
|
|
||||||
super();
|
|
||||||
sslcontext = null;
|
|
||||||
socketfactory = HttpsURLConnection.getDefaultSSLSocketFactory();
|
|
||||||
nameResolver = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static KeyManager[] createKeyManagers(final KeyStore keystore, final String password)
|
private static KeyManager[] createKeyManagers(final KeyStore keystore, final String password)
|
||||||
throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
|
throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
|
||||||
if (keystore == null) {
|
if (keystore == null) {
|
||||||
@ -280,6 +259,7 @@ public class SSLSocketFactory implements LayeredSocketFactory {
|
|||||||
|
|
||||||
// non-javadoc, see interface org.apache.http.conn.SocketFactory
|
// non-javadoc, see interface org.apache.http.conn.SocketFactory
|
||||||
@Override
|
@Override
|
||||||
|
@TargetApi(17)
|
||||||
public Socket connectSocket(
|
public Socket connectSocket(
|
||||||
final Socket sock,
|
final Socket sock,
|
||||||
final String host,
|
final String host,
|
||||||
@ -323,6 +303,12 @@ public class SSLSocketFactory implements LayeredSocketFactory {
|
|||||||
sslsock.connect(remoteAddress, connTimeout);
|
sslsock.connect(remoteAddress, connTimeout);
|
||||||
|
|
||||||
sslsock.setSoTimeout(soTimeout);
|
sslsock.setSoTimeout(soTimeout);
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||||
|
// Turn on Server Name Indication (SNI)
|
||||||
|
socketfactory.setHostname(sslsock, host);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
hostnameVerifier.verify(host, sslsock);
|
hostnameVerifier.verify(host, sslsock);
|
||||||
// verifyHostName() didn't blowup - good!
|
// verifyHostName() didn't blowup - good!
|
||||||
@ -374,20 +360,44 @@ public class SSLSocketFactory implements LayeredSocketFactory {
|
|||||||
|
|
||||||
// non-javadoc, see interface LayeredSocketFactory
|
// non-javadoc, see interface LayeredSocketFactory
|
||||||
@Override
|
@Override
|
||||||
|
@TargetApi(17)
|
||||||
public Socket createSocket(
|
public Socket createSocket(
|
||||||
final Socket socket,
|
final Socket socket,
|
||||||
final String host,
|
final String host,
|
||||||
final int port,
|
final int port,
|
||||||
final boolean autoClose
|
final boolean autoClose
|
||||||
) throws IOException, UnknownHostException {
|
) throws IOException, UnknownHostException {
|
||||||
|
// Close the plain socket if requested. The underlaying socket factory will
|
||||||
|
// create a new socket.
|
||||||
|
if (autoClose) {
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't want to verify the hostname from the previous socket here (we must call
|
||||||
|
// setHostname in order to proper get SNI working), so just create a new ssl socket
|
||||||
|
// based in the previous socket
|
||||||
SSLSocket sslSocket = (SSLSocket) socketfactory.createSocket(
|
SSLSocket sslSocket = (SSLSocket) socketfactory.createSocket(
|
||||||
socket,
|
socket.getInetAddress(),
|
||||||
host,
|
port
|
||||||
port,
|
|
||||||
autoClose
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||||
|
// Turn on Server Name Indication (SNI)
|
||||||
|
socketfactory.setHostname(sslSocket, host);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
hostnameVerifier.verify(host, sslSocket);
|
hostnameVerifier.verify(host, sslSocket);
|
||||||
// verifyHostName() didn't blowup - good!
|
// verifyHostName() didn't blowup - good!
|
||||||
|
} catch (IOException iox) {
|
||||||
|
// close the socket before re-throwing the exception
|
||||||
|
if (autoClose) {
|
||||||
|
try { sslSocket.close(); } catch (Exception x) { /*ignore*/ }
|
||||||
|
}
|
||||||
|
throw iox;
|
||||||
|
}
|
||||||
|
|
||||||
|
// verifyHostName() didn't blowup - good!
|
||||||
return sslSocket;
|
return sslSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user