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

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: address Ryan's remarks Created 8 years 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
« no previous file with comments | « net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java ('k') | net/android/network_library.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..cbd4f4cf80f3a334bbc96aadb03708a49e539134 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,56 @@ 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. We need such manager to plant test
+ * root CA to the trust store in testing.
*/
- private static synchronized void ensureInitialized() throws CertificateException,
+ private static X509TrustManager sTestTrustManager;
+ private static KeyStore sTestKeyStore;
+
+ /**
+ * Lock object used to synchronize all calls that modify or depend on the trust managers.
+ */
+ 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 (sTestKeyStore == null) {
+ sTestKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ try {
+ sTestKeyStore.load(null);
+ } catch(IOException e) {} // No IO operation is attempted.
+ }
+ if (sTestTrustManager == null) {
+ sTestTrustManager = X509Util.createTrustManager(sTestKeyStore);
+ }
}
}
/**
- * 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 +86,15 @@ public class X509Util {
}
/**
- * Convert a DER encoded certificate to an X509Certificate
+ * After each modification of test key store, trust manager has to be generated again.
+ */
+ private static void reloadTestTrustManager() throws KeyStoreException,
+ NoSuchAlgorithmException {
+ sTestTrustManager = X509Util.createTrustManager(sTestKeyStore);
+ }
+
+ /**
+ * Convert a DER encoded certificate to an X509Certificate.
*/
public static X509Certificate createCertificateFromBytes(byte[] derBytes) throws
CertificateException, KeyStoreException, NoSuchAlgorithmException {
@@ -75,6 +103,28 @@ public class X509Util {
new ByteArrayInputStream(derBytes));
}
+ public static void addTestRootCertificate(byte[] rootCertBytes) throws CertificateException,
+ KeyStoreException, NoSuchAlgorithmException {
+ ensureInitialized();
+ X509Certificate rootCert = createCertificateFromBytes(rootCertBytes);
+ synchronized(sLock) {
+ sTestKeyStore.setCertificateEntry(
+ "root_cert_" + Integer.toString(sTestKeyStore.size()), rootCert);
+ reloadTestTrustManager();
+ }
+ }
+
+ public static void clearTestRootCertificates() throws NoSuchAlgorithmException,
+ CertificateException, KeyStoreException {
+ ensureInitialized();
+ synchronized(sLock) {
+ try {
+ sTestKeyStore.load(null);
+ reloadTestTrustManager();
+ } catch(IOException e) {} // No IO operation is attempted.
+ }
+ }
+
public static boolean verifyServerCertificates(byte[][] certChain, String authType)
throws CertificateException, KeyStoreException, NoSuchAlgorithmException {
if (certChain == null || certChain.length == 0 || certChain[0] == null) {
@@ -88,14 +138,24 @@ public class X509Util {
serverCertificates[i] = createCertificateFromBytes(certChain[i]);
}
- try {
- sDefaultTrustManager.checkServerTrusted(serverCertificates, authType);
- return true;
- } catch (CertificateException e) {
- Log.i(TAG, "failed to validate the certificate chain, error: " +
- e.getMessage());
+ synchronized (sLock) {
+ try {
+ sDefaultTrustManager.checkServerTrusted(serverCertificates, authType);
+ return true;
+ } catch (CertificateException eDefaultManager) {
+ try {
+ sTestTrustManager.checkServerTrusted(serverCertificates, authType);
+ return true;
+ } catch (CertificateException eTestManager) {
+ /*
+ * Neither of the trust managers confirms the validity of the certificate
+ * chain, we emit the error message returned by the system trust manager.
+ */
+ Log.i(TAG, "failed to validate the certificate chain, error: " +
+ eDefaultManager.getMessage());
+ }
+ }
}
return false;
}
-
-}
+}
« no previous file with comments | « net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java ('k') | net/android/network_library.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698