email: add support for Server Name Indication (SNI)
Change the underlying socket factory reference to SSLCertificateSocketFactory which has support for SNI since 4.2, and remove the access to the obsolete methods from the old factory reference. This change will setup the socket with a proper hostname prior to the ssl handshake. Change-Id: Ic3315f3924f33470ea2da14e8ac3b946d039b1d5 JIRA: CYAN-3775 Issue: https://jira.cyanogenmod.org/browse/CYAN-3775 Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
This commit is contained in:
parent
68cce7faee
commit
761a860cee
|
@ -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,8 @@
|
||||||
|
|
||||||
package com.android.emailcommon.utility;
|
package com.android.emailcommon.utility;
|
||||||
|
|
||||||
|
import com.android.mail.utils.LogUtils;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -49,7 +51,10 @@ import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLSocket;
|
import javax.net.ssl.SSLSocket;
|
||||||
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.TrustManager;
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
import javax.net.ssl.TrustManagerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
@ -144,6 +149,9 @@ import java.security.UnrecoverableKeyException;
|
||||||
|
|
||||||
public class SSLSocketFactory implements LayeredSocketFactory {
|
public class SSLSocketFactory implements LayeredSocketFactory {
|
||||||
|
|
||||||
|
private static final boolean LOG_ENABLED = false;
|
||||||
|
private static final String TAG = "Email.SslFactory";
|
||||||
|
|
||||||
public static final String TLS = "TLS";
|
public static final String TLS = "TLS";
|
||||||
public static final String SSL = "SSL";
|
public static final String SSL = "SSL";
|
||||||
public static final String SSLV2 = "SSLv2";
|
public static final String SSLV2 = "SSLv2";
|
||||||
|
@ -323,6 +331,10 @@ public class SSLSocketFactory implements LayeredSocketFactory {
|
||||||
sslsock.connect(remoteAddress, connTimeout);
|
sslsock.connect(remoteAddress, connTimeout);
|
||||||
|
|
||||||
sslsock.setSoTimeout(soTimeout);
|
sslsock.setSoTimeout(soTimeout);
|
||||||
|
|
||||||
|
// Set Server Name Indication if is available for this socket
|
||||||
|
setSocketHostname(sslsock, host);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
hostnameVerifier.verify(host, sslsock);
|
hostnameVerifier.verify(host, sslsock);
|
||||||
// verifyHostName() didn't blowup - good!
|
// verifyHostName() didn't blowup - good!
|
||||||
|
@ -386,6 +398,10 @@ public class SSLSocketFactory implements LayeredSocketFactory {
|
||||||
port,
|
port,
|
||||||
autoClose
|
autoClose
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Set Server Name Indication if it's available for this socket
|
||||||
|
setSocketHostname(sslSocket, host);
|
||||||
|
|
||||||
hostnameVerifier.verify(host, sslSocket);
|
hostnameVerifier.verify(host, sslSocket);
|
||||||
// verifyHostName() didn't blowup - good!
|
// verifyHostName() didn't blowup - good!
|
||||||
return sslSocket;
|
return sslSocket;
|
||||||
|
@ -402,4 +418,21 @@ public class SSLSocketFactory implements LayeredSocketFactory {
|
||||||
return hostnameVerifier;
|
return hostnameVerifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setSocketHostname(SSLSocket sslSocket, String hostname) {
|
||||||
|
try {
|
||||||
|
Method method = sslSocket.getClass().getMethod("setHostname", String.class);
|
||||||
|
method.invoke(sslSocket, hostname);
|
||||||
|
return;
|
||||||
|
} catch (NoSuchMethodException ex) {
|
||||||
|
// Ignore
|
||||||
|
} catch (InvocationTargetException ex) {
|
||||||
|
// Ignore
|
||||||
|
} catch (IllegalAccessException ex) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
if (LOG_ENABLED) {
|
||||||
|
LogUtils.i(TAG, "setHostname isn't available for this socket.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue