From: uazo <uazo@users.noreply.github.com>
Date: Mon, 26 Apr 2021 13:28:24 +0000
Subject: Add AllowUserCertificates flag

Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html
---
 .../src/org/chromium/chrome/browser/app/ChromeActivity.java  | 3 +++
 .../chromium/chrome/browser/app/flags/ChromeCachedFlags.java | 1 +
 chrome/browser/about_flags.cc                                | 4 ++++
 chrome/browser/flag_descriptions.cc                          | 5 +++++
 chrome/browser/flag_descriptions.h                           | 3 +++
 chrome/browser/flags/android/chrome_feature_list.cc          | 5 +++++
 chrome/browser/flags/android/chrome_feature_list.h           | 1 +
 .../chromium/chrome/browser/flags/CachedFeatureFlags.java    | 1 +
 .../org/chromium/chrome/browser/flags/ChromeFeatureList.java | 3 +++
 net/android/java/src/org/chromium/net/X509Util.java          | 5 +++++
 10 files changed, 31 insertions(+)

diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -226,6 +226,7 @@ import org.chromium.content_public.browser.ScreenOrientationProvider;
 import org.chromium.content_public.browser.SelectionPopupController;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_public.common.ContentSwitches;
+import org.chromium.net.X509Util;
 import org.chromium.printing.PrintManagerDelegateImpl;
 import org.chromium.printing.PrintingController;
 import org.chromium.printing.PrintingControllerImpl;
@@ -951,6 +952,8 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
         UpdateMenuItemHelper.getInstance().onStart();
         ChromeActivitySessionTracker.getInstance().onStartWithNative();
         ChromeCachedFlags.getInstance().cacheNativeFlags();
+        X509Util.AllowUserCertificates = ChromeFeatureList.isEnabled(
+                                            ChromeFeatureList.ALLOW_USER_CERTIFICATES);
         OfflineIndicatorController.initialize();
 
         // postDeferredStartupIfNeeded() is called in TabModelSelectorTabObsever#onLoadStopped(),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -78,6 +78,7 @@ public class ChromeCachedFlags {
                 add(ChromeFeatureList.sAndroidAuxiliarySearch);
                 add(ChromeFeatureList.sAnonymousUpdateChecks);
                 add(ChromeFeatureList.sAppMenuMobileSiteOption);
+                add(ChromeFeatureList.sAllowUserCertificates);
                 add(ChromeFeatureList.sBackGestureRefactorAndroid);
                 add(ChromeFeatureList.sCctBrandTransparency);
                 add(ChromeFeatureList.sCctIncognito);
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -8830,6 +8830,10 @@ const FeatureEntry kFeatureEntries[] = {
      FEATURE_VALUE_TYPE(features::kWin10TabSearchCaptionButton)},
 #endif  // BUILDFLAG(IS_WIN)
 
+    {"allow-user-certificates",
+     flag_descriptions::kAllowUserCertificatesName,
+     flag_descriptions::kAllowUserCertificatesDescription, kOsAndroid,
+     FEATURE_VALUE_TYPE(chrome::android::kAllowUserCertificates)},
     {"omnibox-updated-connection-security-indicators",
      flag_descriptions::kOmniboxUpdatedConnectionSecurityIndicatorsName,
      flag_descriptions::kOmniboxUpdatedConnectionSecurityIndicatorsDescription,
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -13,6 +13,11 @@
 
 namespace flag_descriptions {
 
+const char kAllowUserCertificatesName[] = "Allow user certificates";
+const char kAllowUserCertificatesDescription[] =
+    "Allow user CA certificates during "
+    "validation of the certificate chain";
+
 const char kAccelerated2dCanvasName[] = "Accelerated 2D canvas";
 const char kAccelerated2dCanvasDescription[] =
     "Enables the use of the GPU to perform 2d canvas rendering instead of "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -40,6 +40,9 @@ namespace flag_descriptions {
 
 // Cross-platform -------------------------------------------------------------
 
+extern const char kAllowUserCertificatesName[];
+extern const char kAllowUserCertificatesDescription[];
+
 extern const char kAccelerated2dCanvasName[];
 extern const char kAccelerated2dCanvasDescription[];
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -148,6 +148,7 @@ const base::Feature* const kFeaturesExposedToJava[] = {
     &feed::kFeedNoViewCache,
     &feed::kFeedReplaceAll,
     &feed::kInterestFeedContentSuggestions,
+    &kAllowUserCertificates,
     &feed::kInterestFeedV1ClicksAndViewsConditionalUpload,
     &feed::kInterestFeedV2,
     &feed::kInterestFeedV2Autoplay,
@@ -468,6 +469,10 @@ BASE_FEATURE(kAllowNewIncognitoTabIntents,
              "AllowNewIncognitoTabIntents",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+BASE_FEATURE(kAllowUserCertificates,
+             "AllowUserCertificates",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 BASE_FEATURE(kFocusOmniboxInIncognitoTabIntents,
              "FocusOmniboxInIncognitoTabIntents",
              base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
--- a/chrome/browser/flags/android/chrome_feature_list.h
+++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -12,6 +12,7 @@
 namespace chrome {
 namespace android {
 
+extern const base::Feature kAllowUserCertificates;
 // Alphabetical:
 BASE_DECLARE_FEATURE(kAdaptiveButtonInTopToolbar);
 BASE_DECLARE_FEATURE(kAdaptiveButtonInTopToolbarCustomizationV2);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
@@ -50,6 +50,7 @@ public class CachedFeatureFlags {
             ImmutableMap.<String, Boolean>builder()
                     .put(ChromeFeatureList.ANONYMOUS_UPDATE_CHECKS, true)
                     .put(ChromeFeatureList.APP_MENU_MOBILE_SITE_OPTION, false)
+                    .put(ChromeFeatureList.ALLOW_USER_CERTIFICATES, false)
                     .put(ChromeFeatureList.BACK_GESTURE_REFACTOR, false)
                     .put(ChromeFeatureList.CCT_BRAND_TRANSPARENCY, false)
                     .put(ChromeFeatureList.CCT_INCOGNITO, true)
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -193,6 +193,7 @@ public abstract class ChromeFeatureList {
     }
 
     /* Alphabetical: */
+    public static final String ALLOW_USER_CERTIFICATES = "AllowUserCertificates";
     public static final String ABOUT_THIS_SITE_BANNER = "AboutThisSiteBanner";
     public static final String ADAPTIVE_BUTTON_IN_TOP_TOOLBAR = "AdaptiveButtonInTopToolbar";
     public static final String ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION_V2 =
@@ -648,6 +649,8 @@ public abstract class ChromeFeatureList {
     public static final String FEED_REPLACE_ALL = "FeedReplaceAll";
 
     /* Alphabetical: */
+    public static final CachedFlag sAllowUserCertificates =
+            new CachedFlag(ALLOW_USER_CERTIFICATES, false);
     public static final CachedFlag sAndroidAuxiliarySearch =
             new CachedFlag(OMNIBOX_ANDROID_AUXILIARY_SEARCH, false);
     public static final CachedFlag sAnonymousUpdateChecks =
diff --git a/net/android/java/src/org/chromium/net/X509Util.java b/net/android/java/src/org/chromium/net/X509Util.java
--- a/net/android/java/src/org/chromium/net/X509Util.java
+++ b/net/android/java/src/org/chromium/net/X509Util.java
@@ -437,6 +437,8 @@ public class X509Util {
         return false;
     }
 
+    public static boolean AllowUserCertificates = false;
+
     public static AndroidCertVerifyResult verifyServerCertificates(byte[][] certChain,
                                                                    String authType,
                                                                    String host)
@@ -517,6 +519,9 @@ public class X509Util {
                 isIssuedByKnownRoot = isKnownRoot(root);
             }
 
+            if (AllowUserCertificates == false && isIssuedByKnownRoot == false)
+                return new AndroidCertVerifyResult(CertVerifyStatusAndroid.NO_TRUSTED_ROOT);
+
             return new AndroidCertVerifyResult(CertVerifyStatusAndroid.OK,
                                                isIssuedByKnownRoot, verifiedChain);
         }
--
2.25.1
