| 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 788f226b922a54e5f41eda91e6cbe9ec1aa8191a..97eaa9df47b940ab18f69e7406843c5e988011a2 100644
|
| --- a/net/android/java/src/org/chromium/net/X509Util.java
|
| +++ b/net/android/java/src/org/chromium/net/X509Util.java
|
| @@ -152,16 +152,23 @@ public class X509Util {
|
| private static Set<Pair<X500Principal, PublicKey>> sSystemTrustRoots;
|
|
|
| /**
|
| + * True if the system trust roots were initialized. (sSystemTrustRoots may
|
| + * still be null if system trust roots cannot be distinguished from
|
| + * user-installed ones.)
|
| + */
|
| + private static boolean sLoadedSystemTrustRoots;
|
| +
|
| + /**
|
| * Lock object used to synchronize all calls that modify or depend on the trust managers.
|
| */
|
| private static final Object sLock = new Object();
|
|
|
| - /*
|
| - * Allow disabling registering the observer for the certificat changes. Net unit tests do not
|
| - * load native libraries which prevent this to succeed. Moreover, the system does not allow to
|
| - * interact with the certificate store without user interaction.
|
| + /**
|
| + * Allow disabling registering the observer and recording histograms for the certificate
|
| + * changes. Net unit tests do not load native libraries which prevent this to succeed. Moreover,
|
| + * the system does not allow to interact with the certificate store without user interaction.
|
| */
|
| - private static boolean sDisableCertificateObservationForTest = false;
|
| + private static boolean sDisableNativeCodeForTest = false;
|
|
|
| /**
|
| * Ensures that the trust managers and certificate factory are initialized.
|
| @@ -175,8 +182,18 @@ public class X509Util {
|
| if (sDefaultTrustManager == null) {
|
| sDefaultTrustManager = X509Util.createTrustManager(null);
|
| }
|
| - if (sSystemTrustRoots == null) {
|
| - sSystemTrustRoots = buildSystemTrustRootSet();
|
| + if (!sLoadedSystemTrustRoots) {
|
| + try {
|
| + sSystemTrustRoots = buildSystemTrustRootSet();
|
| + } catch (KeyStoreException e) {
|
| + // If the device does not have an "AndroidCAStore" KeyStore, don't make the
|
| + // failure fatal. Instead default conservatively to setting isIssuedByKnownRoot
|
| + // to false everywhere.
|
| + Log.w(TAG, "Could not load system trust root set", e);
|
| + }
|
| + if (!sDisableNativeCodeForTest)
|
| + nativeRecordCertVerifyCapabilitiesHistogram(sSystemTrustRoots != null);
|
| + sLoadedSystemTrustRoots = true;
|
| }
|
| if (sTestKeyStore == null) {
|
| sTestKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
| @@ -189,8 +206,7 @@ public class X509Util {
|
| if (sTestTrustManager == null) {
|
| sTestTrustManager = X509Util.createTrustManager(sTestKeyStore);
|
| }
|
| - if (!sDisableCertificateObservationForTest &&
|
| - sTrustStorageListener == null) {
|
| + if (!sDisableNativeCodeForTest && sTrustStorageListener == null) {
|
| sTrustStorageListener = new TrustStorageListener();
|
| nativeGetApplicationContext().registerReceiver(sTrustStorageListener,
|
| new IntentFilter(KeyChain.ACTION_STORAGE_CHANGED));
|
| @@ -240,7 +256,7 @@ public class X509Util {
|
| for (TrustManager tm : tmf.getTrustManagers()) {
|
| if (tm instanceof X509TrustManager) {
|
| try {
|
| - if (Build.VERSION.SDK_INT >= 17) {
|
| + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
| return new X509TrustManagerJellyBean((X509TrustManager) tm);
|
| } else {
|
| return new X509TrustManagerIceCreamSandwich((X509TrustManager) tm);
|
| @@ -268,6 +284,7 @@ public class X509Util {
|
| NoSuchAlgorithmException, CertificateException {
|
| sDefaultTrustManager = null;
|
| sSystemTrustRoots = null;
|
| + sLoadedSystemTrustRoots = false;
|
| nativeNotifyKeyChainChanged();
|
| ensureInitialized();
|
| }
|
| @@ -404,7 +421,7 @@ public class X509Util {
|
| }
|
|
|
| boolean isIssuedByKnownRoot = false;
|
| - if (verifiedChain.size() > 0) {
|
| + if (sSystemTrustRoots != null && verifiedChain.size() > 0) {
|
| X509Certificate root = verifiedChain.get(verifiedChain.size() - 1);
|
| isIssuedByKnownRoot = sSystemTrustRoots.contains(
|
| new Pair<X500Principal, PublicKey>(root.getSubjectX500Principal(),
|
| @@ -416,8 +433,8 @@ public class X509Util {
|
| }
|
| }
|
|
|
| - public static void setDisableCertificateObservationForTest(boolean disabled) {
|
| - sDisableCertificateObservationForTest = disabled;
|
| + public static void setDisableNativeCodeForTest(boolean disabled) {
|
| + sDisableNativeCodeForTest = disabled;
|
| }
|
| /**
|
| * Notify the native net::CertDatabase instance that the system database has been updated.
|
| @@ -425,6 +442,12 @@ public class X509Util {
|
| private static native void nativeNotifyKeyChainChanged();
|
|
|
| /**
|
| + * Record histograms on the platform's certificate verification capabilities.
|
| + */
|
| + private static native void nativeRecordCertVerifyCapabilitiesHistogram(
|
| + boolean foundSystemTrustRoots);
|
| +
|
| + /**
|
| * Returns the application context.
|
| */
|
| private static native Context nativeGetApplicationContext();
|
|
|