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 30007caab17d9ed60f8237f806d39e641e62634d..ed5fb6a5eef87f157f807e931483ff6a9e093bda 100644 |
--- a/net/android/java/src/org/chromium/net/X509Util.java |
+++ b/net/android/java/src/org/chromium/net/X509Util.java |
@@ -4,8 +4,14 @@ |
package org.chromium.net; |
+import android.content.BroadcastReceiver; |
+import android.content.Context; |
+import android.content.Intent; |
+import android.content.IntentFilter; |
+import android.security.KeyChain; |
import android.util.Log; |
+import org.chromium.base.JNINamespace; |
import org.chromium.net.CertVerifyResultAndroid; |
import java.io.ByteArrayInputStream; |
@@ -25,10 +31,33 @@ import javax.net.ssl.TrustManager; |
import javax.net.ssl.TrustManagerFactory; |
import javax.net.ssl.X509TrustManager; |
+@JNINamespace("net") |
public class X509Util { |
private static final String TAG = "X509Util"; |
+ public static final class TrustStorageListener extends BroadcastReceiver { |
+ @Override public void onReceive(Context context, Intent intent) { |
+ if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) { |
+ try { |
+ reloadDefaultTrustManager(context); |
+ } |
+ catch (CertificateException e) { |
+ Log.e(TAG, "Uable to reload the default TrustManager", |
+ e); |
+ } |
+ catch (KeyStoreException e) { |
+ Log.e(TAG, "Uable to reload the default TrustManager", |
+ e); |
+ } |
+ catch (NoSuchAlgorithmException e) { |
+ Log.e(TAG, "Uable to reload the default TrustManager", |
+ e); |
+ } |
+ } |
+ } |
+ } |
+ |
private static CertificateFactory sCertificateFactory; |
private static final String OID_TLS_SERVER_AUTH = "1.3.6.1.5.5.7.3.1"; |
@@ -45,6 +74,12 @@ public class X509Util { |
private static X509TrustManager sDefaultTrustManager; |
/** |
+ * BroadcastReceiver that listen to change in the system keystore to invalidate certificate |
wtc
2013/10/16 15:37:34
Nit: listen => listens
qsr
2013/10/16 16:02:09
Done.
|
+ * caches. |
+ */ |
+ private static TrustStorageListener sTrustStorageListener; |
+ |
+ /** |
* Trust manager backed up by a custom certificate store. We need such manager to plant test |
* root CA to the trust store in testing. |
*/ |
@@ -59,7 +94,7 @@ public class X509Util { |
/** |
* Ensures that the trust managers and certificate factory are initialized. |
*/ |
- private static void ensureInitialized() throws CertificateException, |
+ private static void ensureInitialized(Context context) throws CertificateException, |
KeyStoreException, NoSuchAlgorithmException { |
synchronized(sLock) { |
if (sCertificateFactory == null) { |
@@ -77,6 +112,11 @@ public class X509Util { |
if (sTestTrustManager == null) { |
sTestTrustManager = X509Util.createTrustManager(sTestKeyStore); |
} |
+ if (sTrustStorageListener == null) { |
+ sTrustStorageListener = new TrustStorageListener(); |
+ context.registerReceiver(sTrustStorageListener, |
+ new IntentFilter(KeyChain.ACTION_STORAGE_CHANGED)); |
+ } |
} |
} |
@@ -108,19 +148,29 @@ public class X509Util { |
} |
/** |
+ * After each modification by the systen of the key store, trust manager has to be regenerated. |
wtc
2013/10/16 15:37:34
Typo: systen => system
qsr
2013/10/16 16:02:09
Done.
|
+ */ |
+ private static void reloadDefaultTrustManager(Context context) throws KeyStoreException, |
+ NoSuchAlgorithmException, CertificateException { |
+ sDefaultTrustManager = null; |
+ nativeNotifyCertDatabaseUpdated(); |
+ ensureInitialized(context); |
+ } |
+ |
+ /** |
* Convert a DER encoded certificate to an X509Certificate. |
*/ |
- public static X509Certificate createCertificateFromBytes(byte[] derBytes) throws |
- CertificateException, KeyStoreException, NoSuchAlgorithmException { |
- ensureInitialized(); |
+ public static X509Certificate createCertificateFromBytes(Context context, byte[] derBytes) |
+ throws CertificateException, KeyStoreException, NoSuchAlgorithmException { |
+ ensureInitialized(context); |
return (X509Certificate) sCertificateFactory.generateCertificate( |
new ByteArrayInputStream(derBytes)); |
} |
- public static void addTestRootCertificate(byte[] rootCertBytes) throws CertificateException, |
- KeyStoreException, NoSuchAlgorithmException { |
- ensureInitialized(); |
- X509Certificate rootCert = createCertificateFromBytes(rootCertBytes); |
+ public static void addTestRootCertificate(Context context, byte[] rootCertBytes) |
+ throws CertificateException, KeyStoreException, NoSuchAlgorithmException { |
+ ensureInitialized(context); |
+ X509Certificate rootCert = createCertificateFromBytes(context, rootCertBytes); |
synchronized (sLock) { |
sTestKeyStore.setCertificateEntry( |
"root_cert_" + Integer.toString(sTestKeyStore.size()), rootCert); |
@@ -128,9 +178,9 @@ public class X509Util { |
} |
} |
- public static void clearTestRootCertificates() throws NoSuchAlgorithmException, |
+ public static void clearTestRootCertificates(Context context) throws NoSuchAlgorithmException, |
CertificateException, KeyStoreException { |
- ensureInitialized(); |
+ ensureInitialized(context); |
synchronized (sLock) { |
try { |
sTestKeyStore.load(null); |
@@ -174,7 +224,7 @@ public class X509Util { |
return false; |
} |
- public static int verifyServerCertificates(byte[][] certChain, String authType) |
+ public static int verifyServerCertificates(Context context, byte[][] certChain, String authType) |
throws KeyStoreException, NoSuchAlgorithmException { |
if (certChain == null || certChain.length == 0 || certChain[0] == null) { |
throw new IllegalArgumentException("Expected non-null and non-empty certificate " + |
@@ -182,7 +232,7 @@ public class X509Util { |
} |
try { |
- ensureInitialized(); |
+ ensureInitialized(context); |
} catch (CertificateException e) { |
return CertVerifyResultAndroid.VERIFY_FAILED; |
} |
@@ -190,7 +240,7 @@ public class X509Util { |
X509Certificate[] serverCertificates = new X509Certificate[certChain.length]; |
try { |
for (int i = 0; i < certChain.length; ++i) { |
- serverCertificates[i] = createCertificateFromBytes(certChain[i]); |
+ serverCertificates[i] = createCertificateFromBytes(context, certChain[i]); |
} |
} catch (CertificateException e) { |
return CertVerifyResultAndroid.VERIFY_UNABLE_TO_PARSE; |
@@ -230,4 +280,10 @@ public class X509Util { |
} |
} |
} |
+ |
+ /** |
+ * Notify the native cert database that the system database has been updated. |
wtc
2013/10/16 15:37:34
Nit: cert database => net::CertDatabase class
to
qsr
2013/10/16 16:02:09
Done.
|
+ */ |
+ private static native void nativeNotifyCertDatabaseUpdated(); |
+ |
} |