Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Unified Diff: net/android/java/src/org/chromium/net/X509Util.java

Issue 11316210: Implement TestRootCerts for Android (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: remove an obsolete findbugs suppression Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/android/java/src/org/chromium/net/X509Util.java
diff --git a/net/android/java/src/org/chromium/net/X509Util.java b/net/android/java/src/org/chromium/net/X509Util.java
index 0c43b29b65e9bb860b5305d9a9dc357b940c4ad3..07956305701bbd4f28993f7558f8b3614ece6f34 100644
--- a/net/android/java/src/org/chromium/net/X509Util.java
+++ b/net/android/java/src/org/chromium/net/X509Util.java
@@ -7,6 +7,7 @@ package org.chromium.net;
import android.util.Log;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
@@ -25,37 +26,63 @@ public class X509Util {
private static CertificateFactory sCertificateFactory;
/**
- * Default sources of authentication trust decisions and certificate object
- * creation.
+ * Trust manager backed up by the read-only system certificate store.
*/
private static X509TrustManager sDefaultTrustManager;
/**
- * Ensures that |sCertificateFactory| and |sDefaultTrustManager| are
- * initialized.
+ * Trust manager backed up by a custom certificate store.
*/
- private static synchronized void ensureInitialized() throws CertificateException,
+ private static X509TrustManager sLocalTrustManager;
+ private static KeyStore sLocalKeyStore;
+
+ /**
+ * The trust manager used to make trust decisions. If |sLocalKeyStore| is nonempty, this is
+ * |sLocalTrustManager|, otherwise this is |sDefaultTrustManager|.
+ */
+ private static X509TrustManager sTrustManager;
Ryan Sleevi 2012/12/03 02:29:03 Note: On all other platforms, TestRootCerts is add
digit1 2012/12/03 13:44:13 Ah, my bad, I was the one advising ppi to implemen
+
+ /**
+ * Lock used to synchronize all calls that initialize or modify the trust managers or
+ * certificate factory.
+ */
+ private static final Object sLock = new Object();
+
+ /**
+ * Ensures that the trust managers and certificate factory are initialized.
+ */
+ private static void ensureInitialized() throws CertificateException,
KeyStoreException, NoSuchAlgorithmException {
- if (sCertificateFactory == null) {
- sCertificateFactory = CertificateFactory.getInstance("X.509");
- }
- if (sDefaultTrustManager == null) {
- sDefaultTrustManager = X509Util.createDefaultTrustManager();
+ synchronized(sLock) {
+ if (sCertificateFactory == null) {
+ sCertificateFactory = CertificateFactory.getInstance("X.509");
+ }
+ if (sDefaultTrustManager == null) {
+ sDefaultTrustManager = X509Util.createTrustManager(null);
+ }
+ if (sLocalKeyStore == null) {
+ sLocalKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ try {
+ sLocalKeyStore.load(null);
+ } catch(IOException e) {} // No IO operation is attempted.
+ }
+ if (sLocalTrustManager == null) {
+ sLocalTrustManager = X509Util.createTrustManager(sLocalKeyStore);
+ }
+ sTrustManager = sLocalKeyStore.size() > 0 ? sLocalTrustManager : sDefaultTrustManager;
}
}
/**
- * Creates a TrustManagerFactory and returns the X509TrustManager instance
- * if one can be found.
- *
- * @throws CertificateException,KeyStoreException,NoSuchAlgorithmException
- * on error initializing the TrustManager.
+ * Creates a X509TrustManager backed up by the given key store. When null is passed as a key
+ * store, system default trust store is used.
+ * @throws KeyStoreException, NoSuchAlgorithmException on error initializing the TrustManager.
*/
- private static X509TrustManager createDefaultTrustManager()
- throws KeyStoreException, NoSuchAlgorithmException {
+ private static X509TrustManager createTrustManager(KeyStore keyStore) throws KeyStoreException,
+ NoSuchAlgorithmException {
String algorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
- tmf.init((KeyStore) null);
+ tmf.init(keyStore);
for (TrustManager tm : tmf.getTrustManagers()) {
if (tm instanceof X509TrustManager) {
@@ -66,7 +93,7 @@ public class X509Util {
}
/**
- * Convert a DER encoded certificate to an X509Certificate
+ * Convert a DER encoded certificate to an X509Certificate.
*/
public static X509Certificate createCertificateFromBytes(byte[] derBytes) throws
CertificateException, KeyStoreException, NoSuchAlgorithmException {
@@ -75,6 +102,30 @@ public class X509Util {
new ByteArrayInputStream(derBytes));
}
+ public static void addTestRootCertificate(byte[] rootCertBytes) throws CertificateException,
+ KeyStoreException, NoSuchAlgorithmException {
+ ensureInitialized();
+ X509Certificate rootCert = createCertificateFromBytes(rootCertBytes);
+ synchronized(sLock) {
+ sLocalKeyStore.setCertificateEntry(
+ "root_cert_" + Integer.toString(sLocalKeyStore.size()), rootCert);
+
+ sTrustManager = sLocalTrustManager;
+ }
+ }
+
+ public static void clearTestRootCertificates() throws NoSuchAlgorithmException,
+ CertificateException, KeyStoreException {
+ ensureInitialized();
+ synchronized(sLock) {
+ try {
+ sLocalKeyStore.load(null);
+ } catch(IOException e) {} // No IO operation is attempted.
+
+ sTrustManager = sDefaultTrustManager;
+ }
+ }
+
public static boolean verifyServerCertificates(byte[][] certChain, String authType)
throws CertificateException, KeyStoreException, NoSuchAlgorithmException {
if (certChain == null || certChain.length == 0 || certChain[0] == null) {
@@ -89,13 +140,13 @@ public class X509Util {
}
try {
- sDefaultTrustManager.checkServerTrusted(serverCertificates, authType);
+ synchronized (sLock) {
+ sTrustManager.checkServerTrusted(serverCertificates, authType);
+ }
return true;
} catch (CertificateException e) {
- Log.i(TAG, "failed to validate the certificate chain, error: " +
- e.getMessage());
+ Log.i(TAG, "failed to validate the certificate chain, error: " + e.getMessage());
}
return false;
}
-
-}
+}

Powered by Google App Engine
This is Rietveld 408576698