Merge "Use SSLCertificateSocketFactory to generate "insecure" ssl socket."
This commit is contained in:
commit
ea1eb7a231
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.email.mail.store;
|
||||
|
||||
import com.android.common.DomainNameValidator;
|
||||
import com.android.email.Email;
|
||||
|
||||
import org.apache.harmony.xnet.provider.jsse.SSLParameters;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
/**
|
||||
* This factory creates and returns two types of TrustManagers.
|
||||
*
|
||||
* The "secure" trust manager performs standard tests of certificates, and throws
|
||||
* CertificateException when the tests fail.
|
||||
*
|
||||
* The "simple" trust manager performs no tests, effectively accepting all certificates.
|
||||
*/
|
||||
public final class TrustManagerFactory {
|
||||
private static X509TrustManager sUnsecureTrustManager = new SimpleX509TrustManager();
|
||||
|
||||
/**
|
||||
* This trust manager performs no tests, effectively accepting all certificates.
|
||||
*/
|
||||
private static class SimpleX509TrustManager implements X509TrustManager {
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) {
|
||||
logCertificates(chain, "Trusting client", false);
|
||||
}
|
||||
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) {
|
||||
logCertificates(chain, "Trusting server", false);
|
||||
}
|
||||
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This trust manager performs full tests, requiring a valid, trusted certificate.
|
||||
*/
|
||||
private static class SecureX509TrustManager implements X509TrustManager {
|
||||
private X509TrustManager mTrustManager;
|
||||
private String mHost;
|
||||
|
||||
SecureX509TrustManager(X509TrustManager trustManager, String host) {
|
||||
mTrustManager = trustManager;
|
||||
mHost = host;
|
||||
}
|
||||
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType)
|
||||
throws CertificateException {
|
||||
try {
|
||||
mTrustManager.checkClientTrusted(chain, authType);
|
||||
} catch (CertificateException ce) {
|
||||
logCertificates(chain, "Failed client", true);
|
||||
throw ce;
|
||||
}
|
||||
}
|
||||
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType)
|
||||
throws CertificateException {
|
||||
|
||||
try {
|
||||
mTrustManager.checkServerTrusted(chain, authType);
|
||||
} catch (CertificateException ce) {
|
||||
logCertificates(chain, "Failed server", true);
|
||||
throw ce;
|
||||
}
|
||||
|
||||
if (!DomainNameValidator.match(chain[0], mHost)) {
|
||||
logCertificates(chain, "Failed domain name", true);
|
||||
throw new CertificateException("Certificate domain name does not match " + mHost);
|
||||
}
|
||||
}
|
||||
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return mTrustManager.getAcceptedIssuers();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logging of certificates, to help debugging trust issues. Logging strategy:
|
||||
* Trusting a certificate: Lightweight log about it
|
||||
* Fully checking: Silent if OK, verbose log it failure
|
||||
*
|
||||
* @param chain the certificate chain to dump
|
||||
* @param caller a prefix that will be added to each log
|
||||
* @param verbose if true, the issuer and dates will also be logged
|
||||
*/
|
||||
private static void logCertificates(X509Certificate[] chain, String caller, boolean verbose) {
|
||||
if (Email.DEBUG) {
|
||||
for (int i = 0; i < chain.length; ++i) {
|
||||
Log.d(Email.LOG_TAG, caller + " Certificate #" + i);
|
||||
Log.d(Email.LOG_TAG, " subject=" + chain[i].getSubjectDN());
|
||||
if (verbose) {
|
||||
Log.d(Email.LOG_TAG, " issuer=" + chain[i].getIssuerDN());
|
||||
Log.d(Email.LOG_TAG, " dates=" + chain[i].getNotBefore()
|
||||
+ " to " + chain[i].getNotAfter());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private TrustManagerFactory() {
|
||||
}
|
||||
|
||||
public static X509TrustManager get(String host, boolean secure) {
|
||||
if (secure) {
|
||||
return new SecureX509TrustManager(SSLParameters.getDefaultTrustManager(), host) ;
|
||||
} else {
|
||||
return sUnsecureTrustManager;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,7 +20,6 @@ import com.android.email.Email;
|
|||
import com.android.email.mail.CertificateValidationException;
|
||||
import com.android.email.mail.MessagingException;
|
||||
import com.android.email.mail.Transport;
|
||||
import com.android.email.mail.store.TrustManagerFactory;
|
||||
|
||||
import android.util.Config;
|
||||
import android.util.Log;
|
||||
|
@ -153,11 +152,7 @@ public class MailTransport implements Transport {
|
|||
try {
|
||||
SocketAddress socketAddress = new InetSocketAddress(getHost(), getPort());
|
||||
if (canTrySslSecurity()) {
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(null, new TrustManager[] {
|
||||
TrustManagerFactory.get(getHost(), !canTrustAllCertificates())
|
||||
}, new SecureRandom());
|
||||
mSocket = sslContext.getSocketFactory().createSocket();
|
||||
mSocket = SSLUtils.getSSLSocketFactory(canTrustAllCertificates()).createSocket();
|
||||
} else {
|
||||
mSocket = new Socket();
|
||||
}
|
||||
|
@ -170,11 +165,6 @@ public class MailTransport implements Transport {
|
|||
Log.d(Email.LOG_TAG, e.toString());
|
||||
}
|
||||
throw new CertificateValidationException(e.getMessage(), e);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
if (Config.LOGD && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, gse.toString());
|
||||
}
|
||||
throw new MessagingException(MessagingException.GENERAL_SECURITY, gse.toString());
|
||||
} catch (IOException ioe) {
|
||||
if (Config.LOGD && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, ioe.toString());
|
||||
|
@ -190,12 +180,8 @@ public class MailTransport implements Transport {
|
|||
*/
|
||||
public void reopenTls() throws MessagingException {
|
||||
try {
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(null, new TrustManager[] {
|
||||
TrustManagerFactory.get(getHost(), !canTrustAllCertificates())
|
||||
}, new SecureRandom());
|
||||
mSocket = sslContext.getSocketFactory().createSocket(mSocket, getHost(), getPort(),
|
||||
true);
|
||||
mSocket = SSLUtils.getSSLSocketFactory(canTrustAllCertificates())
|
||||
.createSocket(mSocket, getHost(), getPort(), true);
|
||||
mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
|
||||
mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);
|
||||
mOut = new BufferedOutputStream(mSocket.getOutputStream(), 512);
|
||||
|
@ -205,11 +191,6 @@ public class MailTransport implements Transport {
|
|||
Log.d(Email.LOG_TAG, e.toString());
|
||||
}
|
||||
throw new CertificateValidationException(e.getMessage(), e);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
if (Config.LOGD && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, gse.toString());
|
||||
}
|
||||
throw new MessagingException(MessagingException.GENERAL_SECURITY, gse.toString());
|
||||
} catch (IOException ioe) {
|
||||
if (Config.LOGD && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, ioe.toString());
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.email.mail.transport;
|
||||
|
||||
import android.net.SSLCertificateSocketFactory;
|
||||
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
public class SSLUtils {
|
||||
private static SSLSocketFactory sInsecureFactory;
|
||||
private static SSLSocketFactory sSecureFactory;
|
||||
|
||||
/**
|
||||
* Returns a {@link SSLSocketFactory}. Optionally bypass all SSL certificate checks.
|
||||
*
|
||||
* @param insecure if true, bypass all SSL certificate checks
|
||||
*/
|
||||
public synchronized static final SSLSocketFactory getSSLSocketFactory(boolean insecure) {
|
||||
if (insecure) {
|
||||
if (sInsecureFactory == null) {
|
||||
sInsecureFactory = SSLCertificateSocketFactory.getInsecure(0, null);
|
||||
}
|
||||
return sInsecureFactory;
|
||||
} else {
|
||||
if (sSecureFactory == null) {
|
||||
sSecureFactory = SSLCertificateSocketFactory.getDefault(0, null);
|
||||
}
|
||||
return sSecureFactory;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,7 +21,7 @@ import com.android.email.AccountBackupRestore;
|
|||
import com.android.email.Email;
|
||||
import com.android.email.SecurityPolicy;
|
||||
import com.android.email.mail.MessagingException;
|
||||
import com.android.email.mail.store.TrustManagerFactory;
|
||||
import com.android.email.mail.transport.SSLUtils;
|
||||
import com.android.email.provider.EmailContent;
|
||||
import com.android.email.provider.EmailContent.Account;
|
||||
import com.android.email.provider.EmailContent.Attachment;
|
||||
|
@ -1054,30 +1054,16 @@ public class SyncManager extends Service implements Runnable {
|
|||
PlainSocketFactory.getSocketFactory(), 80));
|
||||
registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
|
||||
|
||||
// Create a new SSLSocketFactory for our "trusted ssl"
|
||||
// Get the unsecure trust manager from the factory
|
||||
X509TrustManager trustManager = TrustManagerFactory.get(null, false);
|
||||
TrustManager[] trustManagers = new TrustManager[] {trustManager};
|
||||
SSLContext sslcontext;
|
||||
try {
|
||||
sslcontext = SSLContext.getInstance("TLS");
|
||||
try {
|
||||
sslcontext.init(null, trustManagers, null);
|
||||
} catch (KeyManagementException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
// Ok, now make our factory
|
||||
SSLSocketFactory sf = new SSLSocketFactory(sslcontext.getSocketFactory());
|
||||
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||
// Register the httpts scheme with our factory
|
||||
registry.register(new Scheme("httpts", sf, 443));
|
||||
// And create a ccm with our registry
|
||||
HttpParams params = new BasicHttpParams();
|
||||
params.setIntParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 25);
|
||||
params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, sConnPerRoute);
|
||||
sClientConnectionManager = new ThreadSafeClientConnManager(params, registry);
|
||||
} catch (NoSuchAlgorithmException e2) {
|
||||
}
|
||||
// Use "insecure" socket factory.
|
||||
SSLSocketFactory sf = new SSLSocketFactory(SSLUtils.getSSLSocketFactory(true));
|
||||
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||
// Register the httpts scheme with our factory
|
||||
registry.register(new Scheme("httpts", sf, 443));
|
||||
// And create a ccm with our registry
|
||||
HttpParams params = new BasicHttpParams();
|
||||
params.setIntParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 25);
|
||||
params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, sConnPerRoute);
|
||||
sClientConnectionManager = new ThreadSafeClientConnManager(params, registry);
|
||||
}
|
||||
// Null is a valid return result if we get an exception
|
||||
return sClientConnectionManager;
|
||||
|
|
Loading…
Reference in New Issue