Merge "Get SSLSocketFactory from GmsCore" into ub-gmail-ur14-dev

This commit is contained in:
Martin Hibdon 2014-10-03 02:14:00 +00:00 committed by Android (Google) Code Review
commit 46f1b89fef
2 changed files with 49 additions and 14 deletions

View File

@ -21,6 +21,7 @@ import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.net.SSLCertificateSocketFactory; import android.net.SSLCertificateSocketFactory;
import android.net.SSLSessionCache;
import android.security.KeyChain; import android.security.KeyChain;
import android.security.KeyChainException; import android.security.KeyChainException;
@ -49,7 +50,7 @@ import javax.net.ssl.X509TrustManager;
public class SSLUtils { public class SSLUtils {
// All secure factories are the same; all insecure factories are associated with HostAuth's // All secure factories are the same; all insecure factories are associated with HostAuth's
private static SSLCertificateSocketFactory sSecureFactory; private static javax.net.ssl.SSLSocketFactory sSecureFactory;
private static final boolean LOG_ENABLED = false; private static final boolean LOG_ENABLED = false;
private static final String TAG = "Email.Ssl"; private static final String TAG = "Email.Ssl";
@ -137,40 +138,73 @@ public class SSLUtils {
} }
} }
public static abstract class ExternalSecureSocketFactoryBuilder {
abstract public javax.net.ssl.SSLSocketFactory createSecureSocketFactory(
final Context context, final int handshakeTimeoutMillis);
}
private static ExternalSecureSocketFactoryBuilder sExternalSocketFactoryBuilder;
public static void setExternalSecureSocketFactoryBuilder(
ExternalSecureSocketFactoryBuilder builder) {
sExternalSocketFactoryBuilder = builder;
}
/** /**
* Returns a {@link javax.net.ssl.SSLSocketFactory}. * Returns a {@link javax.net.ssl.SSLSocketFactory}.
* Optionally bypass all SSL certificate checks. * Optionally bypass all SSL certificate checks.
* *
* @param insecure if true, bypass all SSL certificate checks * @param insecure if true, bypass all SSL certificate checks
*/ */
public synchronized static SSLCertificateSocketFactory getSSLSocketFactory(Context context, public synchronized static javax.net.ssl.SSLSocketFactory getSSLSocketFactory(
HostAuth hostAuth, boolean insecure) { final Context context, final HostAuth hostAuth, final KeyManager keyManager,
final boolean insecure) {
if (insecure) { if (insecure) {
SSLCertificateSocketFactory insecureFactory = (SSLCertificateSocketFactory) final SSLCertificateSocketFactory insecureFactory = (SSLCertificateSocketFactory)
SSLCertificateSocketFactory.getInsecure(SSL_HANDSHAKE_TIMEOUT, null); SSLCertificateSocketFactory.getInsecure(SSL_HANDSHAKE_TIMEOUT, null);
insecureFactory.setTrustManagers( insecureFactory.setTrustManagers(
new TrustManager[] { new TrustManager[] {
new SameCertificateCheckingTrustManager(context, hostAuth)}); new SameCertificateCheckingTrustManager(context, hostAuth)});
if (keyManager != null) {
insecureFactory.setKeyManagers(new KeyManager[] { keyManager });
}
return insecureFactory; return insecureFactory;
} else { } else {
if (sSecureFactory == null) { if (sSecureFactory == null) {
sSecureFactory = (SSLCertificateSocketFactory) // First try to get use an externally supplied, more secure SSLSocketBuilder.
SSLCertificateSocketFactory.getDefault(SSL_HANDSHAKE_TIMEOUT, null); // If so we should use that.
javax.net.ssl.SSLSocketFactory socketFactory = null;
if (sExternalSocketFactoryBuilder != null) {
socketFactory = sExternalSocketFactoryBuilder.createSecureSocketFactory(
context, SSL_HANDSHAKE_TIMEOUT);
}
if (socketFactory != null) {
sSecureFactory = socketFactory;
LogUtils.d(TAG, "Using externally created CertificateSocketFactory");
return sSecureFactory;
}
// Only fall back to the platform one if that fails.
LogUtils.d(TAG, "Falling back to platform CertificateSocketFactory");
final SSLCertificateSocketFactory certificateSocketFactory =
(SSLCertificateSocketFactory)
SSLCertificateSocketFactory.getDefault(SSL_HANDSHAKE_TIMEOUT,
new SSLSessionCache(context));
if (keyManager != null) {
certificateSocketFactory.setKeyManagers(new KeyManager[] { keyManager });
}
sSecureFactory = certificateSocketFactory;
} }
return sSecureFactory; return sSecureFactory;
} }
} }
/** /**
* Returns a {@link org.apache.http.conn.ssl.SSLSocketFactory SSLSocketFactory} for use with the * Returns a com.android.emailcommon.utility.SSLSocketFactory
* Apache HTTP stack.
*/ */
public static SSLSocketFactory getHttpSocketFactory(Context context, HostAuth hostAuth, public static SSLSocketFactory getHttpSocketFactory(Context context, HostAuth hostAuth,
KeyManager keyManager, boolean insecure) { KeyManager keyManager, boolean insecure) {
SSLCertificateSocketFactory underlying = getSSLSocketFactory(context, hostAuth, insecure); javax.net.ssl.SSLSocketFactory underlying = getSSLSocketFactory(context, hostAuth,
if (keyManager != null) { keyManager, insecure);
underlying.setKeyManagers(new KeyManager[] { keyManager });
}
SSLSocketFactory wrapped = new SSLSocketFactory(underlying); SSLSocketFactory wrapped = new SSLSocketFactory(underlying);
if (insecure) { if (insecure) {
wrapped.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); wrapped.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

View File

@ -112,7 +112,7 @@ public class MailTransport {
SocketAddress socketAddress = new InetSocketAddress(getHost(), getPort()); SocketAddress socketAddress = new InetSocketAddress(getHost(), getPort());
if (canTrySslSecurity()) { if (canTrySslSecurity()) {
mSocket = SSLUtils.getSSLSocketFactory( mSocket = SSLUtils.getSSLSocketFactory(
mContext, mHostAuth, canTrustAllCertificates()).createSocket(); mContext, mHostAuth, null, canTrustAllCertificates()).createSocket();
} else { } else {
mSocket = new Socket(); mSocket = new Socket();
} }
@ -152,7 +152,8 @@ public class MailTransport {
*/ */
public void reopenTls() throws MessagingException { public void reopenTls() throws MessagingException {
try { try {
mSocket = SSLUtils.getSSLSocketFactory(mContext, mHostAuth, canTrustAllCertificates()) mSocket = SSLUtils.getSSLSocketFactory(mContext, mHostAuth, null,
canTrustAllCertificates())
.createSocket(mSocket, getHost(), getPort(), true); .createSocket(mSocket, getHost(), getPort(), true);
mSocket.setSoTimeout(SOCKET_READ_TIMEOUT); mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
mIn = new BufferedInputStream(mSocket.getInputStream(), 1024); mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);