Commit b2be90d0 authored by Evan Stade's avatar Evan Stade Committed by Commit Bot

Componentize SSLErrorHandler::CalculateOptionsMask

This function will shortly need to be reused in WebLayer's initial
implementation of interstitials. To accomodate this, this CL
componentizes this function into a new ssl_error_options_mask.* that
also now includes the SSLErrorOptionsMask enum.

Code authored by blundell@chromium.org

TBR=eugenebut@chromium.org

Change-Id: I6fbfce25b705c0a6018fe42c516c6a554b4fc757
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1879256Reviewed-by: default avatarEvan Stade <estade@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Reviewed-by: default avatarCarlos IL <carlosil@chromium.org>
Commit-Queue: Evan Stade <estade@chromium.org>
Cr-Commit-Position: refs/heads/master@{#710407}
parent 4854c92d
......@@ -26,6 +26,7 @@
#include "components/security_interstitials/content/ssl_cert_reporter.h"
#include "components/security_interstitials/core/controller_client.h"
#include "components/security_interstitials/core/metrics_helper.h"
#include "components/security_interstitials/core/ssl_error_options_mask.h"
#include "components/security_interstitials/core/ssl_error_ui.h"
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/interstitial_page_delegate.h"
......@@ -243,8 +244,11 @@ void SSLBlockingPage::NotifyDenyCertificate() {
// static
bool SSLBlockingPage::IsOverridable(int options_mask) {
const bool is_overridable =
(options_mask & SSLErrorUI::SOFT_OVERRIDE_ENABLED) &&
!(options_mask & SSLErrorUI::STRICT_ENFORCEMENT) &&
!(options_mask & SSLErrorUI::HARD_OVERRIDE_DISABLED);
(options_mask &
security_interstitials::SSLErrorOptionsMask::SOFT_OVERRIDE_ENABLED) &&
!(options_mask &
security_interstitials::SSLErrorOptionsMask::STRICT_ENFORCEMENT) &&
!(options_mask &
security_interstitials::SSLErrorOptionsMask::HARD_OVERRIDE_DISABLED);
return is_overridable;
}
......@@ -52,7 +52,7 @@ class SSLBlockingPage : public SSLBlockingPageBase {
// Creates an SSL blocking page. If the blocking page isn't shown, the caller
// is responsible for cleaning up the blocking page, otherwise the
// interstitial takes ownership when shown. |options_mask| must be a bitwise
// mask of SSLErrorUI::SSLErrorOptionsMask values.
// mask of SSLErrorOptionsMask values.
// This is static because the constructor uses expensive to compute parameters
// more than once (e.g. overrideable).
static SSLBlockingPage* Create(
......
......@@ -36,6 +36,7 @@
#include "components/prefs/pref_service.h"
#include "components/security_interstitials/content/security_interstitial_page.h"
#include "components/security_interstitials/content/ssl_cert_reporter.h"
#include "components/security_interstitials/core/ssl_error_options_mask.h"
#include "components/security_interstitials/core/ssl_error_ui.h"
#include "components/ssl_errors/error_classification.h"
#include "components/ssl_errors/error_info.h"
......@@ -568,32 +569,6 @@ void SSLErrorHandlerDelegateImpl::OnBlockingPageReady(
}
}
int IsCertErrorFatal(int cert_error) {
switch (cert_error) {
case net::ERR_CERT_COMMON_NAME_INVALID:
case net::ERR_CERT_DATE_INVALID:
case net::ERR_CERT_AUTHORITY_INVALID:
case net::ERR_CERT_NO_REVOCATION_MECHANISM:
case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION:
case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM:
case net::ERR_CERT_WEAK_KEY:
case net::ERR_CERT_NAME_CONSTRAINT_VIOLATION:
case net::ERR_CERT_VALIDITY_TOO_LONG:
case net::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED:
case net::ERR_CERT_SYMANTEC_LEGACY:
return false;
case net::ERR_CERT_CONTAINS_ERRORS:
case net::ERR_CERT_REVOKED:
case net::ERR_CERT_INVALID:
case net::ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY:
case net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN:
return true;
default:
NOTREACHED();
return true;
}
}
} // namespace
static base::LazyInstance<ConfigSingleton>::Leaky g_config =
......@@ -624,8 +599,8 @@ void SSLErrorHandler::HandleSSLError(
bool hard_override_disabled =
!profile->GetPrefs()->GetBoolean(prefs::kSSLErrorOverrideAllowed);
int options_mask = CalculateOptionsMask(cert_error, hard_override_disabled,
ssl_info.is_fatal_cert_error);
int options_mask = security_interstitials::CalculateSSLErrorOptionsMask(
cert_error, hard_override_disabled, ssl_info.is_fatal_cert_error);
SSLErrorHandler* error_handler = new SSLErrorHandler(
std::unique_ptr<SSLErrorHandler::Delegate>(
......@@ -1057,22 +1032,4 @@ bool SSLErrorHandler::IsOnlyCertError(
!net::IsCertStatusError(other_errors);
}
// static
int SSLErrorHandler::CalculateOptionsMask(int cert_error,
bool hard_override_disabled,
bool should_ssl_errors_be_fatal) {
int options_mask = 0;
if (!IsCertErrorFatal(cert_error) && !hard_override_disabled &&
!should_ssl_errors_be_fatal) {
options_mask |= security_interstitials::SSLErrorUI::SOFT_OVERRIDE_ENABLED;
}
if (hard_override_disabled) {
options_mask |= security_interstitials::SSLErrorUI::HARD_OVERRIDE_DISABLED;
}
if (should_ssl_errors_be_fatal) {
options_mask |= security_interstitials::SSLErrorUI::STRICT_ENFORCEMENT;
}
return options_mask;
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(SSLErrorHandler)
......@@ -223,11 +223,6 @@ class SSLErrorHandler : public content::WebContentsUserData<SSLErrorHandler>,
bool IsOnlyCertError(net::CertStatus only_cert_error_expected) const;
// Calculates a mask encoded using flags in SSLErrorUI::SSLErrorOptionsMask.
static int CalculateOptionsMask(int cert_error,
bool hard_override_disabled,
bool should_ssl_errors_be_fatal);
std::unique_ptr<Delegate> delegate_;
content::WebContents* const web_contents_;
Profile* const profile_;
......
......@@ -31,6 +31,7 @@
#include "components/network_time/network_time_test_utils.h"
#include "components/network_time/network_time_tracker.h"
#include "components/prefs/testing_pref_service.h"
#include "components/security_interstitials/core/ssl_error_options_mask.h"
#include "components/security_interstitials/core/ssl_error_ui.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
......@@ -1518,47 +1519,3 @@ TEST_F(SSLErrorAssistantProtoTest,
TestNoMITMSoftwareInterstitial();
}
TEST(SSLErrorHandlerTest, CalculateOptionsMask) {
int mask;
// Non-overridable cert error.
mask = SSLErrorHandler::CalculateOptionsMask(
net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN, /* cert_error */
false, /* hard_override_disabled */
false /* should_ssl_errors_be_fatal */
);
EXPECT_EQ(0, mask);
mask = SSLErrorHandler::CalculateOptionsMask(
net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN, /* cert_error */
true, /* hard_override_disabled */
false /* should_ssl_errors_be_fatal */
);
EXPECT_EQ(security_interstitials::SSLErrorUI::HARD_OVERRIDE_DISABLED, mask);
mask = SSLErrorHandler::CalculateOptionsMask(
net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN, /* cert_error */
false, /* hard_override_disabled */
true /* should_ssl_errors_be_fatal */
);
EXPECT_EQ(security_interstitials::SSLErrorUI::STRICT_ENFORCEMENT, mask);
// Overridable cert error.
mask = SSLErrorHandler::CalculateOptionsMask(
net::ERR_CERT_DATE_INVALID, /* cert_error */
false, /* hard_override_disabled */
false /* should_ssl_errors_be_fatal */
);
EXPECT_EQ(security_interstitials::SSLErrorUI::SOFT_OVERRIDE_ENABLED, mask);
mask = SSLErrorHandler::CalculateOptionsMask(
net::ERR_CERT_DATE_INVALID, /* cert_error */
true, /* hard_override_disabled */
false /* should_ssl_errors_be_fatal */
);
EXPECT_EQ(security_interstitials::SSLErrorUI::HARD_OVERRIDE_DISABLED, mask);
mask = SSLErrorHandler::CalculateOptionsMask(
net::ERR_CERT_DATE_INVALID, /* cert_error */
false, /* hard_override_disabled */
true /* should_ssl_errors_be_fatal */
);
EXPECT_EQ(security_interstitials::SSLErrorUI::STRICT_ENFORCEMENT, mask);
}
......@@ -26,6 +26,7 @@
#include "components/grit/components_resources.h"
#include "components/safe_browsing/db/database_manager.h"
#include "components/security_interstitials/content/origin_policy_ui.h"
#include "components/security_interstitials/core/ssl_error_options_mask.h"
#include "components/security_interstitials/core/ssl_error_ui.h"
#include "content/public/browser/interstitial_page_delegate.h"
#include "content/public/browser/render_frame_host.h"
......@@ -181,9 +182,11 @@ SSLBlockingPage* CreateSSLBlockingPage(content::WebContents* web_contents) {
// This delegate doesn't create an interstitial.
int options_mask = 0;
if (overridable)
options_mask |= security_interstitials::SSLErrorUI::SOFT_OVERRIDE_ENABLED;
options_mask |=
security_interstitials::SSLErrorOptionsMask::SOFT_OVERRIDE_ENABLED;
if (strict_enforcement)
options_mask |= security_interstitials::SSLErrorUI::STRICT_ENFORCEMENT;
options_mask |=
security_interstitials::SSLErrorOptionsMask::STRICT_ENFORCEMENT;
return SSLBlockingPage::Create(
web_contents, cert_error, ssl_info, request_url, options_mask,
time_triggered_, GURL(), nullptr,
......@@ -251,9 +254,11 @@ BadClockBlockingPage* CreateBadClockBlockingPage(
// This delegate doesn't create an interstitial.
int options_mask = 0;
if (overridable)
options_mask |= security_interstitials::SSLErrorUI::SOFT_OVERRIDE_ENABLED;
options_mask |=
security_interstitials::SSLErrorOptionsMask::SOFT_OVERRIDE_ENABLED;
if (strict_enforcement)
options_mask |= security_interstitials::SSLErrorUI::STRICT_ENFORCEMENT;
options_mask |=
security_interstitials::SSLErrorOptionsMask::STRICT_ENFORCEMENT;
return new BadClockBlockingPage(
web_contents, cert_error, ssl_info, request_url, base::Time::Now(),
clock_state, nullptr,
......
......@@ -133,6 +133,7 @@ test("components_unittests") {
"//components/search:unit_tests",
"//components/search_engines:unit_tests",
"//components/search_provider_logos:unit_tests",
"//components/security_interstitials/core:unit_tests",
"//components/security_state/core:unit_tests",
"//components/services/heap_profiling/public/cpp:unit_tests",
"//components/services/storage:tests",
......
......@@ -22,6 +22,8 @@ static_library("core") {
"safe_browsing_loud_error_ui.h",
"safe_browsing_quiet_error_ui.cc",
"safe_browsing_quiet_error_ui.h",
"ssl_error_options_mask.cc",
"ssl_error_options_mask.h",
"ssl_error_ui.cc",
"ssl_error_ui.h",
"urls.cc",
......@@ -55,3 +57,17 @@ static_library("core") {
"//components/security_interstitials/core/common/mojom",
]
}
source_set("unit_tests") {
testonly = true
sources = [
"ssl_error_options_mask_unittest.cc",
]
deps = [
":core",
"//base",
"//net",
"//testing/gtest",
]
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/security_interstitials/core/ssl_error_options_mask.h"
#include "net/base/net_errors.h"
namespace security_interstitials {
namespace {
int IsCertErrorFatal(int cert_error) {
switch (cert_error) {
case net::ERR_CERT_COMMON_NAME_INVALID:
case net::ERR_CERT_DATE_INVALID:
case net::ERR_CERT_AUTHORITY_INVALID:
case net::ERR_CERT_NO_REVOCATION_MECHANISM:
case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION:
case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM:
case net::ERR_CERT_WEAK_KEY:
case net::ERR_CERT_NAME_CONSTRAINT_VIOLATION:
case net::ERR_CERT_VALIDITY_TOO_LONG:
case net::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED:
case net::ERR_CERT_SYMANTEC_LEGACY:
return false;
case net::ERR_CERT_CONTAINS_ERRORS:
case net::ERR_CERT_REVOKED:
case net::ERR_CERT_INVALID:
case net::ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY:
case net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN:
return true;
default:
NOTREACHED();
return true;
}
}
} // namespace
int CalculateSSLErrorOptionsMask(int cert_error,
bool hard_override_disabled,
bool should_ssl_errors_be_fatal) {
int options_mask = 0;
if (!IsCertErrorFatal(cert_error) && !hard_override_disabled &&
!should_ssl_errors_be_fatal) {
options_mask |=
security_interstitials::SSLErrorOptionsMask::SOFT_OVERRIDE_ENABLED;
}
if (hard_override_disabled) {
options_mask |=
security_interstitials::SSLErrorOptionsMask::HARD_OVERRIDE_DISABLED;
}
if (should_ssl_errors_be_fatal) {
options_mask |=
security_interstitials::SSLErrorOptionsMask::STRICT_ENFORCEMENT;
}
return options_mask;
}
} // namespace security_interstitials
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SECURITY_INTERSTITIALS_CORE_SSL_ERROR_OPTIONS_MASK_H_
#define COMPONENTS_SECURITY_INTERSTITIALS_CORE_SSL_ERROR_OPTIONS_MASK_H_
namespace security_interstitials {
enum SSLErrorOptionsMask {
// Indicates that the error UI should support dismissing the error and
// loading the page. By default, the errors cannot be overridden via the UI.
SOFT_OVERRIDE_ENABLED = 1 << 0,
// Indicates that the user should NOT be allowed to use a "secret code" to
// dismiss the error and load the page, even if the UI does not support it.
// By default, an error can be overridden via the "secret code."
HARD_OVERRIDE_DISABLED = 1 << 1,
// Indicates that the site the user is trying to connect to has requested
// strict enforcement of certificate validation (e.g. with HTTP
// Strict-Transport-Security). By default, the error assumes strict
// enforcement was not requested.
STRICT_ENFORCEMENT = 1 << 2,
};
// Calculates a mask encoded via the SSLErrorOptionsMaskFlag bitfields based
// on the passed-in parameters.
int CalculateSSLErrorOptionsMask(int cert_error,
bool hard_override_disabled,
bool should_ssl_errors_be_fatal);
} // namespace security_interstitials
#endif // COMPONENTS_SECURITY_INTERSTITIALS_CORE_SSL_ERROR_OPTIONS_MASK_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/security_interstitials/core/ssl_error_options_mask.h"
#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace security_interstitials {
TEST(SSLErrorOptionsMask, CalculateSSLErrorOptionsMask) {
int mask;
// Non-overridable cert error.
mask = CalculateSSLErrorOptionsMask(
net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN, /* cert_error */
false, /* hard_override_disabled */
false /* should_ssl_errors_be_fatal */
);
EXPECT_EQ(0, mask);
mask = CalculateSSLErrorOptionsMask(
net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN, /* cert_error */
true, /* hard_override_disabled */
false /* should_ssl_errors_be_fatal */
);
EXPECT_EQ(SSLErrorOptionsMask::HARD_OVERRIDE_DISABLED, mask);
mask = CalculateSSLErrorOptionsMask(
net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN, /* cert_error */
false, /* hard_override_disabled */
true /* should_ssl_errors_be_fatal */
);
EXPECT_EQ(SSLErrorOptionsMask::STRICT_ENFORCEMENT, mask);
// Overridable cert error.
mask =
CalculateSSLErrorOptionsMask(net::ERR_CERT_DATE_INVALID, /* cert_error */
false, /* hard_override_disabled */
false /* should_ssl_errors_be_fatal */
);
EXPECT_EQ(SSLErrorOptionsMask::SOFT_OVERRIDE_ENABLED, mask);
mask =
CalculateSSLErrorOptionsMask(net::ERR_CERT_DATE_INVALID, /* cert_error */
true, /* hard_override_disabled */
false /* should_ssl_errors_be_fatal */
);
EXPECT_EQ(SSLErrorOptionsMask::HARD_OVERRIDE_DISABLED, mask);
mask =
CalculateSSLErrorOptionsMask(net::ERR_CERT_DATE_INVALID, /* cert_error */
false, /* hard_override_disabled */
true /* should_ssl_errors_be_fatal */
);
EXPECT_EQ(SSLErrorOptionsMask::STRICT_ENFORCEMENT, mask);
}
} // namespace security_interstitials
......@@ -7,6 +7,7 @@
#include "base/i18n/time_formatting.h"
#include "components/security_interstitials/core/common_string_util.h"
#include "components/security_interstitials/core/metrics_helper.h"
#include "components/security_interstitials/core/ssl_error_options_mask.h"
#include "components/ssl_errors/error_classification.h"
#include "components/ssl_errors/error_info.h"
#include "components/strings/grit/components_strings.h"
......@@ -18,7 +19,7 @@ namespace {
// Path to the relevant help center page. Used if |support_url_| is invalid.
const char kHelpPath[] = "answer/6098869";
bool IsMasked(int options, SSLErrorUI::SSLErrorOptionsMask mask) {
bool IsMasked(int options, SSLErrorOptionsMask mask) {
return ((options & mask) != 0);
}
......
......@@ -21,21 +21,6 @@ class ControllerClient;
// determine what type of error should be displayed when.
class SSLErrorUI {
public:
enum SSLErrorOptionsMask {
// Indicates that the error UI should support dismissing the error and
// loading the page. By default, the errors cannot be overridden via the UI.
SOFT_OVERRIDE_ENABLED = 1 << 0,
// Indicates that the user should NOT be allowed to use a "secret code" to
// dismiss the error and load the page, even if the UI does not support it.
// By default, an error can be overridden via the "secret code."
HARD_OVERRIDE_DISABLED = 1 << 1,
// Indicates that the site the user is trying to connect to has requested
// strict enforcement of certificate validation (e.g. with HTTP
// Strict-Transport-Security). By default, the error assumes strict
// enforcement was not requested.
STRICT_ENFORCEMENT = 1 << 2,
};
SSLErrorUI(const GURL& request_url,
int cert_error,
const net::SSLInfo& ssl_info,
......
......@@ -31,7 +31,7 @@ class IOSSSLBlockingPage : public IOSSecurityInterstitialPage {
// Creates an SSL blocking page. If the blocking page isn't shown, the caller
// is responsible for cleaning up the blocking page, otherwise the
// interstitial takes ownership when shown. |options_mask| must be a bitwise
// mask of SSLErrorUI::SSLErrorOptionsMask values.
// mask of SSLErrorOptionsMask values.
IOSSSLBlockingPage(web::WebState* web_state,
int cert_error,
const net::SSLInfo& ssl_info,
......
......@@ -11,6 +11,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "components/security_interstitials/core/metrics_helper.h"
#include "components/security_interstitials/core/ssl_error_options_mask.h"
#include "components/security_interstitials/core/ssl_error_ui.h"
#include "components/strings/grit/components_strings.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
......@@ -26,6 +27,7 @@
#error "This file requires ARC support."
#endif
using security_interstitials::SSLErrorOptionsMask;
using security_interstitials::SSLErrorUI;
namespace {
......@@ -61,9 +63,9 @@ IOSSSLBlockingPage::IOSSSLBlockingPage(web::WebState* web_state,
IsOverridable(options_mask))))) {
// Override prefs for the SSLErrorUI.
if (overridable_)
options_mask |= SSLErrorUI::SOFT_OVERRIDE_ENABLED;
options_mask |= SSLErrorOptionsMask::SOFT_OVERRIDE_ENABLED;
else
options_mask &= ~SSLErrorUI::SOFT_OVERRIDE_ENABLED;
options_mask &= ~SSLErrorOptionsMask::SOFT_OVERRIDE_ENABLED;
ssl_error_ui_.reset(new SSLErrorUI(request_url, cert_error, ssl_info,
options_mask, time_triggered, GURL(),
......@@ -143,6 +145,6 @@ void IOSSSLBlockingPage::NotifyDenyCertificate() {
// static
bool IOSSSLBlockingPage::IsOverridable(int options_mask) {
return (options_mask & SSLErrorUI::SOFT_OVERRIDE_ENABLED) &&
!(options_mask & SSLErrorUI::STRICT_ENFORCEMENT);
return (options_mask & SSLErrorOptionsMask::SOFT_OVERRIDE_ENABLED) &&
!(options_mask & SSLErrorOptionsMask::STRICT_ENFORCEMENT);
}
......@@ -10,6 +10,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/strings/sys_string_conversions.h"
#include "components/captive_portal/captive_portal_detector.h"
#include "components/security_interstitials/core/ssl_error_options_mask.h"
#include "components/security_interstitials/core/ssl_error_ui.h"
#include "ios/chrome/browser/ssl/captive_portal_detector_tab_helper.h"
#include "ios/chrome/browser/ssl/captive_portal_features.h"
......@@ -128,8 +129,9 @@ void IOSSSLErrorHandler::ShowSSLInterstitial() {
}
int options_mask =
overridable_ ? security_interstitials::SSLErrorUI::SOFT_OVERRIDE_ENABLED
: security_interstitials::SSLErrorUI::STRICT_ENFORCEMENT;
overridable_
? security_interstitials::SSLErrorOptionsMask::SOFT_OVERRIDE_ENABLED
: security_interstitials::SSLErrorOptionsMask::STRICT_ENFORCEMENT;
if (!blocking_page_callback_.is_null()) {
auto page = std::make_unique<IOSSSLBlockingPage>(
web_state_, cert_error_, ssl_info_, request_url_, options_mask,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment