| 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 ab82077e920251d8912fb2952fb95adeada91b2d..b6671aa08660248d0f137df828738e1f27c152b2 100644
|
| --- a/net/android/java/src/org/chromium/net/X509Util.java
|
| +++ b/net/android/java/src/org/chromium/net/X509Util.java
|
| @@ -15,6 +15,7 @@ import android.security.KeyChain;
|
| import android.util.Log;
|
| import android.util.Pair;
|
|
|
| +import org.chromium.base.BuildInfo;
|
| import org.chromium.base.ContextUtils;
|
| import org.chromium.base.annotations.JNINamespace;
|
| import org.chromium.base.annotations.SuppressFBWarnings;
|
| @@ -52,9 +53,45 @@ public class X509Util {
|
|
|
| private static final String TAG = "X509Util";
|
|
|
| + // For Android O+, ACTION_STORAGE_CHANGED is split into several different
|
| + // intents.
|
| + //
|
| + // TODO(davidben): Replace these with the constants from android.security.Keychain once O is
|
| + // released.
|
| + private static final String ACTION_KEYCHAIN_CHANGED =
|
| + "android.security.action.KEYCHAIN_CHANGED";
|
| + private static final String ACTION_KEY_ACCESS_CHANGED =
|
| + "android.security.action.KEY_ACCESS_CHANGED";
|
| + private static final String ACTION_TRUST_STORE_CHANGED =
|
| + "android.security.action.TRUST_STORE_CHANGED";
|
| + private static final String EXTRA_KEY_ACCESSIBLE = "android.security.extra.KEY_ACCESSIBLE";
|
| +
|
| private static final class TrustStorageListener extends BroadcastReceiver {
|
| - @Override public void onReceive(Context context, Intent intent) {
|
| - if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
|
| + @Override
|
| + public void onReceive(Context context, Intent intent) {
|
| + boolean shouldReloadTrustManager = false;
|
| + if (BuildInfo.isAtLeastO()) {
|
| + if (ACTION_KEYCHAIN_CHANGED.equals(intent.getAction())
|
| + || ACTION_TRUST_STORE_CHANGED.equals(intent.getAction())) {
|
| + // TODO(davidben): ACTION_KEYCHAIN_CHANGED indicates client certificates
|
| + // changed, not the trust store. The two signals within CertDatabase are
|
| + // identical, so we are reloading more than needed. But note b/36492171.
|
| + shouldReloadTrustManager = true;
|
| + } else if (ACTION_KEY_ACCESS_CHANGED.equals(intent.getAction())
|
| + && !intent.getBooleanExtra(EXTRA_KEY_ACCESSIBLE, false)) {
|
| + // We lost access to a client certificate key. Reload all client certificate
|
| + // state as we are not currently able to forget an individual identity.
|
| + shouldReloadTrustManager = true;
|
| + }
|
| + } else {
|
| + // Before Android O, KeyChain only emitted a coarse-grained intent. This fires much
|
| + // more often than it should (https://crbug.com/381912), but there are no APIs to
|
| + // distinguish the various cases.
|
| + shouldReloadTrustManager =
|
| + KeyChain.ACTION_STORAGE_CHANGED.equals(intent.getAction());
|
| + }
|
| +
|
| + if (shouldReloadTrustManager) {
|
| try {
|
| reloadDefaultTrustManager();
|
| } catch (CertificateException e) {
|
| @@ -241,8 +278,15 @@ public class X509Util {
|
| }
|
| if (!sDisableNativeCodeForTest && sTrustStorageListener == null) {
|
| sTrustStorageListener = new TrustStorageListener();
|
| - ContextUtils.getApplicationContext().registerReceiver(
|
| - sTrustStorageListener, new IntentFilter(KeyChain.ACTION_STORAGE_CHANGED));
|
| + IntentFilter filter = new IntentFilter();
|
| + if (BuildInfo.isAtLeastO()) {
|
| + filter.addAction(ACTION_KEYCHAIN_CHANGED);
|
| + filter.addAction(ACTION_KEY_ACCESS_CHANGED);
|
| + filter.addAction(ACTION_TRUST_STORE_CHANGED);
|
| + } else {
|
| + filter.addAction(KeyChain.ACTION_STORAGE_CHANGED);
|
| + }
|
| + ContextUtils.getApplicationContext().registerReceiver(sTrustStorageListener, filter);
|
| }
|
| }
|
|
|
|
|