Merge "Use SSLCertificateSocketFactory to generate "insecure" ssl socket."
diff --git a/src/com/android/email/mail/store/TrustManagerFactory.java b/src/com/android/email/mail/store/TrustManagerFactory.java
deleted file mode 100644
index 7f07845..0000000
--- a/src/com/android/email/mail/store/TrustManagerFactory.java
+++ /dev/null
@@ -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;
- }
- }
-}
diff --git a/src/com/android/email/mail/transport/MailTransport.java b/src/com/android/email/mail/transport/MailTransport.java
index bdfc7bb..a42bd24 100644
--- a/src/com/android/email/mail/transport/MailTransport.java
+++ b/src/com/android/email/mail/transport/MailTransport.java
@@ -20,7 +20,6 @@
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 @@
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 @@
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 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 @@
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());
diff --git a/src/com/android/email/mail/transport/SSLUtils.java b/src/com/android/email/mail/transport/SSLUtils.java
new file mode 100644
index 0000000..499a8b1
--- /dev/null
+++ b/src/com/android/email/mail/transport/SSLUtils.java
@@ -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;
+ }
+ }
+}
diff --git a/src/com/android/exchange/SyncManager.java b/src/com/android/exchange/SyncManager.java
index 74d93a1..d2e7121 100644
--- a/src/com/android/exchange/SyncManager.java
+++ b/src/com/android/exchange/SyncManager.java
@@ -21,7 +21,7 @@
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 @@
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;