summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestark <estark@chromium.org>2015-12-09 12:55:41 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-09 20:56:42 +0000
commit910b457a9d91a7e8858121d4c199c301bb3e8f10 (patch)
tree29917f7fbda46939b66e6ca5bb0b575d048f3ed1
parentd89375a7b98ba2551855cc7967b20f95e251beb0 (diff)
downloadchromium_src-910b457a9d91a7e8858121d4c199c301bb3e8f10.zip
chromium_src-910b457a9d91a7e8858121d4c199c301bb3e8f10.tar.gz
chromium_src-910b457a9d91a7e8858121d4c199c301bb3e8f10.tar.bz2
Reland of Downgrade lock icon for broken-HTTPS subresources (patchset #2 id:300001 of https://codereview.chromium.org/1497423002/ )
Reason for revert: Relanding since the speculative revert didn't seem to help with crbug.com/565540 Original issue's description: > Revert of Downgrade lock icon for broken-HTTPS subresources (patchset #11 id:200001 of https://codereview.chromium.org/1415923015/ ) > > Reason for revert: > Speculatively reverting to see if it makes https://code.google.com/p/chromium/issues/detail?id=565540 go away > > Note that this revert preserves the histogrammed > bad_message.h value that was added in CL 1415923015 > > Original issue's description: > > Downgrade lock icon for broken-HTTPS subresources > > > > This CL attaches a boolean to resource responses to indicate if they > > have certificate errors. If Blink sees a resource with a cert error, it > > notifies the renderer via FrameLoaderClient, who then notifies the > > browser, who treats the situation like mixed content. > > > > The browser (//content) ignores subresources with cert errors on HTTP > > pages, and subresources with the same cert errors as the main > > resource. This allows embedders to distinguish broken-HTTPS foo.com with > > a subresource from broken-HTTPS bar.com and broken-HTTPS foo.com with a > > subresource from broken-HTTPS foo.com. > > > > BUG=477868 > > > > Committed: https://crrev.com/8bfb78c859ab5993eada6db30e4de50aa7403f1c > > Cr-Commit-Position: refs/heads/master@{#362246} > > TBR=jochen@chromium.org,jww@chromium.org,mkwst@chromium.org > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=477868 > > Committed: https://crrev.com/51ea371ad45bb5887dacf7fca6fe0feef8941262 > Cr-Commit-Position: refs/heads/master@{#363388} TBR=jochen@chromium.org,jww@chromium.org,mkwst@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=477868 Review URL: https://codereview.chromium.org/1506203004 Cr-Commit-Position: refs/heads/master@{#364152}
-rw-r--r--chrome/browser/ssl/ssl_browser_tests.cc105
-rw-r--r--chrome/test/data/ssl/page_with_dynamic_unsafe_image.html13
-rw-r--r--chrome/test/data/ssl/page_with_unsafe_image.html14
-rw-r--r--content/browser/loader/resource_loader.cc3
-rw-r--r--content/browser/ssl/ssl_manager.cc6
-rw-r--r--content/browser/ssl/ssl_manager.h4
-rw-r--r--content/browser/ssl/ssl_policy.cc18
-rw-r--r--content/browser/ssl/ssl_policy.h2
-rw-r--r--content/browser/web_contents/web_contents_impl.cc43
-rw-r--r--content/browser/web_contents/web_contents_impl.h8
-rw-r--r--content/child/web_url_loader_impl.cc1
-rw-r--r--content/common/frame_messages.h15
-rw-r--r--content/common/resource_messages.h1
-rw-r--r--content/public/common/resource_response.cc2
-rw-r--r--content/public/common/resource_response_info.cc6
-rw-r--r--content/public/common/resource_response_info.h3
-rw-r--r--content/renderer/render_frame_impl.cc61
-rw-r--r--content/renderer/render_frame_impl.h10
-rw-r--r--third_party/WebKit/Source/core/loader/EmptyClients.h2
-rw-r--r--third_party/WebKit/Source/core/loader/FrameFetchContext.cpp4
-rw-r--r--third_party/WebKit/Source/core/loader/FrameLoaderClient.h7
-rw-r--r--third_party/WebKit/Source/core/loader/MixedContentChecker.cpp21
-rw-r--r--third_party/WebKit/Source/core/loader/MixedContentChecker.h5
-rw-r--r--third_party/WebKit/Source/core/loader/MixedContentCheckerTest.cpp47
-rw-r--r--third_party/WebKit/Source/platform/exported/WebURLResponse.cpp5
-rw-r--r--third_party/WebKit/Source/platform/network/ResourceResponse.cpp4
-rw-r--r--third_party/WebKit/Source/platform/network/ResourceResponse.h8
-rw-r--r--third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp12
-rw-r--r--third_party/WebKit/Source/web/FrameLoaderClientImpl.h2
-rw-r--r--third_party/WebKit/public/platform/WebURLResponse.h2
-rw-r--r--third_party/WebKit/public/web/WebFrameClient.h8
31 files changed, 378 insertions, 64 deletions
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc
index 061b4f9..c56e085 100644
--- a/chrome/browser/ssl/ssl_browser_tests.cc
+++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -555,6 +555,36 @@ class SSLUITest
net::EmbeddedTestServer https_server_mismatched_;
net::SpawnedTestServer wss_server_expired_;
+ protected:
+ // Navigates to an interstitial and clicks through the certificate
+ // error; then navigates to a page at |path| that loads unsafe content.
+ void SetUpUnsafeContentsWithUserException(const std::string& path) {
+ ASSERT_TRUE(https_server_.Start());
+ // Note that it is necessary to user https_server_mismatched_ here over the
+ // other invalid cert servers. This is because the test relies on the two
+ // servers having different hosts since SSL exceptions are per-host, not per
+ // origin, and https_server_mismatched_ uses 'localhost' rather than
+ // '127.0.0.1'.
+ ASSERT_TRUE(https_server_mismatched_.Start());
+
+ // Navigate to an unsafe site. Proceed with interstitial page to indicate
+ // the user approves the bad certificate.
+ ui_test_utils::NavigateToURL(
+ browser(), https_server_mismatched_.GetURL("/ssl/blank_page.html"));
+ WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
+ CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
+ AuthState::SHOWING_INTERSTITIAL);
+ ProceedThroughInterstitial(tab);
+ CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
+ AuthState::NONE);
+
+ std::string replacement_path;
+ GetFilePathWithHostAndPortReplacement(
+ path, https_server_mismatched_.host_port_pair(), &replacement_path);
+ ui_test_utils::NavigateToURL(browser(),
+ https_server_.GetURL(replacement_path));
+ }
+
private:
typedef net::SpawnedTestServer::SSLOptions SSLOptions;
@@ -2125,10 +2155,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerFiltered) {
// This test, and the related test TestUnsafeContentsWithUserException, verify
// that if unsafe content is loaded but the host of that unsafe content has a
-// user exception, the content runs and the security style remains
-// authenticated. This is not necessarily the behavior that should exist, but it
-// is verification that it does behave that way. See https://crbug.com/477868
-// for more inforamtion on this.
+// user exception, the content runs and the security style is downgraded.
IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerWithUserException) {
ASSERT_TRUE(https_server_.Start());
// Note that it is necessary to user https_server_mismatched_ here over the
@@ -2158,44 +2185,56 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerWithUserException) {
ui_test_utils::NavigateToURL(
browser(), https_server_.GetURL(page_with_unsafe_worker_path));
CheckWorkerLoadResult(tab, true); // Worker loads insecure content
- CheckAuthenticatedState(tab, CertError::NONE);
+ CheckAuthenticationBrokenState(tab, CertError::NONE,
+ AuthState::RAN_INSECURE_CONTENT);
}
// Visits a page with unsafe content and makes sure that if a user exception to
// the certificate error is present, the image is loaded and script executes.
-//
-// See the comment above SSLUITest.TestUnsafeContentsInWorkerWithUserException
-// for a discussion about the desired behavior.
IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsWithUserException) {
- ASSERT_TRUE(https_server_.Start());
- // Note that it is necessary to user https_server_mismatched_ here over the
- // other invalid cert servers. This is because the test relies on the two
- // servers having different hosts since SSL exceptions are per-host, not per
- // origin, and https_server_mismatched_ uses 'localhost' rather than
- // '127.0.0.1'.
- ASSERT_TRUE(https_server_mismatched_.Start());
-
- // Navigate to an unsafe site. Proceed with interstitial page to indicate
- // the user approves the bad certificate.
- ui_test_utils::NavigateToURL(
- browser(), https_server_mismatched_.GetURL("/ssl/blank_page.html"));
WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
- CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
- AuthState::SHOWING_INTERSTITIAL);
- ProceedThroughInterstitial(tab);
- CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
- AuthState::NONE);
+ ASSERT_NO_FATAL_FAILURE(SetUpUnsafeContentsWithUserException(
+ "/ssl/page_with_unsafe_contents.html"));
+ CheckAuthenticationBrokenState(
+ tab, CertError::NONE,
+ AuthState::RAN_INSECURE_CONTENT | AuthState::DISPLAYED_INSECURE_CONTENT);
+ int img_width;
+ EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
+ tab, "window.domAutomationController.send(ImageWidth());", &img_width));
+ // In order to check that the image was loaded, we check its width.
+ // The actual image (Google logo) is 114 pixels wide, so we assume a good
+ // image is greater than 100.
+ EXPECT_GT(img_width, 100);
+
+ bool js_result = false;
+ EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+ tab, "window.domAutomationController.send(IsFooSet());", &js_result));
+ EXPECT_TRUE(js_result);
+
+ // Test that active subresources with the same certificate errors as
+ // the main resources don't cause mixed content UI downgrades. (Such
+ // errors would be confusing and duplicative.)
std::string replacement_path;
GetFilePathWithHostAndPortReplacement(
"/ssl/page_with_unsafe_contents.html",
https_server_mismatched_.host_port_pair(), &replacement_path);
- ui_test_utils::NavigateToURL(browser(),
- https_server_.GetURL(replacement_path));
+ ui_test_utils::NavigateToURL(
+ browser(), https_server_mismatched_.GetURL(replacement_path));
+ js_result = false;
+ EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+ tab, "window.domAutomationController.send(IsFooSet());", &js_result));
+ EXPECT_TRUE(js_result);
+ CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
+ AuthState::NONE);
+}
- // When the bad content is filtered, the state is expected to be
- // authenticated.
- CheckAuthenticatedState(tab, AuthState::NONE);
+// Like the test above, but only displaying inactive content (an image).
+IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeImageWithUserException) {
+ WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
+ ASSERT_NO_FATAL_FAILURE(
+ SetUpUnsafeContentsWithUserException("/ssl/page_with_unsafe_image.html"));
+ CheckAuthenticatedState(tab, AuthState::DISPLAYED_INSECURE_CONTENT);
int img_width;
EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
@@ -2204,12 +2243,6 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsWithUserException) {
// The actual image (Google logo) is 114 pixels wide, so we assume a good
// image is greater than 100.
EXPECT_GT(img_width, 100);
-
- bool js_result = false;
- EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
- tab, "window.domAutomationController.send(IsFooSet());", &js_result));
- EXPECT_TRUE(js_result);
- CheckAuthenticatedState(tab, CertError::NONE);
}
// Test that when the browser blocks displaying insecure content (images), the
diff --git a/chrome/test/data/ssl/page_with_dynamic_unsafe_image.html b/chrome/test/data/ssl/page_with_dynamic_unsafe_image.html
new file mode 100644
index 0000000..d232531
--- /dev/null
+++ b/chrome/test/data/ssl/page_with_dynamic_unsafe_image.html
@@ -0,0 +1,13 @@
+<html>
+<head><title>Page with unsafe image loaded dynamically</title>
+<script>
+ var url = "https://REPLACE_WITH_HOST_AND_PORT/ssl/google_files/logo.gif";
+
+ function AddImage() {
+ var img = document.createElement("img");
+ img.src = url;
+ document.body.appendChild(img);
+ }
+</script>
+<body></body>
+</html>
diff --git a/chrome/test/data/ssl/page_with_unsafe_image.html b/chrome/test/data/ssl/page_with_unsafe_image.html
new file mode 100644
index 0000000..9136e37
--- /dev/null
+++ b/chrome/test/data/ssl/page_with_unsafe_image.html
@@ -0,0 +1,14 @@
+<html>
+<head><title>Page with unsafe image</title>
+<script>
+ function ImageWidth() {
+ return document.getElementById("bad_image").width;
+ }
+</script>
+</head>
+
+<body>
+This page contains an image which is served over an insecure HTTPS connection...<br>
+<img id="bad_image" src="https://REPLACE_WITH_HOST_AND_PORT/ssl/google_files/logo.gif"/>
+</body>
+</html>
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc
index 6238b25..e8a404f 100644
--- a/content/browser/loader/resource_loader.cc
+++ b/content/browser/loader/resource_loader.cc
@@ -115,6 +115,9 @@ void PopulateResourceResponse(ResourceRequestInfoImpl* info,
GetSSLStatusForRequest(request->url(), request->ssl_info(),
info->GetChildID(), &ssl_status);
response->head.security_info = SerializeSecurityInfo(ssl_status);
+ response->head.has_major_certificate_errors =
+ net::IsCertStatusError(ssl_status.cert_status) &&
+ !net::IsCertStatusMinorError(ssl_status.cert_status);
} else {
// We should not have any SSL state.
DCHECK(!request->ssl_info().cert_status);
diff --git a/content/browser/ssl/ssl_manager.cc b/content/browser/ssl/ssl_manager.cc
index cd6c2be..c1b42f0 100644
--- a/content/browser/ssl/ssl_manager.cc
+++ b/content/browser/ssl/ssl_manager.cc
@@ -134,11 +134,7 @@ void SSLManager::DidCommitProvisionalLoad(const LoadCommittedDetails& details) {
NotifyDidChangeVisibleSSLState();
}
-void SSLManager::DidDisplayInsecureContent() {
- UpdateEntry(controller_->GetLastCommittedEntry());
-}
-
-void SSLManager::DidRunInsecureContent(const std::string& security_origin) {
+void SSLManager::DidRunInsecureContent(const GURL& security_origin) {
NavigationEntryImpl* navigation_entry = controller_->GetLastCommittedEntry();
policy()->DidRunInsecureContent(navigation_entry, security_origin);
UpdateEntry(navigation_entry);
diff --git a/content/browser/ssl/ssl_manager.h b/content/browser/ssl/ssl_manager.h
index 6e46705..fb31a25 100644
--- a/content/browser/ssl/ssl_manager.h
+++ b/content/browser/ssl/ssl_manager.h
@@ -31,6 +31,7 @@ struct LoadCommittedDetails;
struct LoadFromMemoryCacheDetails;
struct ResourceRedirectDetails;
struct ResourceRequestDetails;
+struct SSLStatus;
// The SSLManager SSLManager controls the SSL UI elements in a WebContents. It
// listens for various events that influence when these elements should or
@@ -88,8 +89,7 @@ class CONTENT_EXPORT SSLManager {
void DidReceiveResourceRedirect(const ResourceRedirectDetails& details);
// Insecure content entry point.
- void DidDisplayInsecureContent();
- void DidRunInsecureContent(const std::string& security_origin);
+ void DidRunInsecureContent(const GURL& security_origin);
private:
// Updates the NavigationEntry with our current state. This will
diff --git a/content/browser/ssl/ssl_policy.cc b/content/browser/ssl/ssl_policy.cc
index ed8d80b3..06677dc 100644
--- a/content/browser/ssl/ssl_policy.cc
+++ b/content/browser/ssl/ssl_policy.cc
@@ -105,7 +105,7 @@ void SSLPolicy::OnCertError(SSLCertErrorHandler* handler) {
}
void SSLPolicy::DidRunInsecureContent(NavigationEntryImpl* entry,
- const std::string& security_origin) {
+ const GURL& security_origin) {
if (!entry)
return;
@@ -113,20 +113,16 @@ void SSLPolicy::DidRunInsecureContent(NavigationEntryImpl* entry,
if (!site_instance)
return;
- backend_->HostRanInsecureContent(GURL(security_origin).host(),
+ backend_->HostRanInsecureContent(security_origin.host(),
site_instance->GetProcess()->GetID());
}
void SSLPolicy::OnRequestStarted(SSLRequestInfo* info) {
- // TODO(abarth): This mechanism is wrong. What we should be doing is sending
- // this information back through WebKit and out some FrameLoaderClient
- // methods.
-
- if (net::IsCertStatusError(info->ssl_cert_status())) {
- backend_->HostRanInsecureContent(info->url().host(), info->child_id());
- } else if (info->ssl_cert_id() && info->url().SchemeIsCryptographic()) {
- // If the scheme is https: or wss: *and* the security info for the cert has
- // been set (i.e. the cert id is not 0), revoke any previous decisions that
+ if (info->ssl_cert_id() && info->url().SchemeIsCryptographic() &&
+ !net::IsCertStatusError(info->ssl_cert_status())) {
+ // If the scheme is https: or wss: *and* the security info for the
+ // cert has been set (i.e. the cert id is not 0) and the cert did
+ // not have any errors, revoke any previous decisions that
// have occurred. If the cert info has not been set, do nothing since it
// isn't known if the connection was actually a valid connection or if it
// had a cert error.
diff --git a/content/browser/ssl/ssl_policy.h b/content/browser/ssl/ssl_policy.h
index 2855a1b..c002bfc 100644
--- a/content/browser/ssl/ssl_policy.h
+++ b/content/browser/ssl/ssl_policy.h
@@ -36,7 +36,7 @@ class SSLPolicy {
void OnCertError(SSLCertErrorHandler* handler);
void DidRunInsecureContent(NavigationEntryImpl* entry,
- const std::string& security_origin);
+ const GURL& security_origin);
// We have started a resource request with the given info.
void OnRequestStarted(SSLRequestInfo* info);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 327617d..1ca34e2 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -632,6 +632,10 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
OnDidDisplayInsecureContent)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidRunInsecureContent,
OnDidRunInsecureContent)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidDisplayContentWithCertificateErrors,
+ OnDidDisplayContentWithCertificateErrors)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidRunContentWithCertificateErrors,
+ OnDidRunContentWithCertificateErrors)
IPC_MESSAGE_HANDLER(ViewHostMsg_GoToEntryAtOffset, OnGoToEntryAtOffset)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateZoomLimits, OnUpdateZoomLimits)
IPC_MESSAGE_HANDLER(ViewHostMsg_PageScaleFactorChanged,
@@ -3170,12 +3174,12 @@ void WebContentsImpl::OnDidDisplayInsecureContent() {
GetController().GetBrowserContext());
}
-void WebContentsImpl::OnDidRunInsecureContent(
- const std::string& security_origin, const GURL& target_url) {
+void WebContentsImpl::OnDidRunInsecureContent(const GURL& security_origin,
+ const GURL& target_url) {
LOG(WARNING) << security_origin << " ran insecure content from "
<< target_url.possibly_invalid_spec();
RecordAction(base::UserMetricsAction("SSL.RanInsecureContent"));
- if (base::EndsWith(security_origin, kDotGoogleDotCom,
+ if (base::EndsWith(security_origin.spec(), kDotGoogleDotCom,
base::CompareCase::INSENSITIVE_ASCII))
RecordAction(base::UserMetricsAction("SSL.RanInsecureContentGoogle"));
controller_.ssl_manager()->DidRunInsecureContent(security_origin);
@@ -3183,6 +3187,39 @@ void WebContentsImpl::OnDidRunInsecureContent(
GetController().GetBrowserContext());
}
+void WebContentsImpl::OnDidDisplayContentWithCertificateErrors(
+ const GURL& url,
+ const std::string& security_info) {
+ SSLStatus ssl;
+ if (!DeserializeSecurityInfo(security_info, &ssl)) {
+ bad_message::ReceivedBadMessage(
+ GetRenderProcessHost(),
+ bad_message::WC_CONTENT_WITH_CERT_ERRORS_BAD_SECURITY_INFO);
+ return;
+ }
+
+ displayed_insecure_content_ = true;
+ SSLManager::NotifySSLInternalStateChanged(
+ GetController().GetBrowserContext());
+}
+
+void WebContentsImpl::OnDidRunContentWithCertificateErrors(
+ const GURL& security_origin,
+ const GURL& url,
+ const std::string& security_info) {
+ SSLStatus ssl;
+ if (!DeserializeSecurityInfo(security_info, &ssl)) {
+ bad_message::ReceivedBadMessage(
+ GetRenderProcessHost(),
+ bad_message::WC_CONTENT_WITH_CERT_ERRORS_BAD_SECURITY_INFO);
+ return;
+ }
+
+ controller_.ssl_manager()->DidRunInsecureContent(security_origin);
+ SSLManager::NotifySSLInternalStateChanged(
+ GetController().GetBrowserContext());
+}
+
void WebContentsImpl::OnDocumentLoadedInFrame() {
if (!HasValidFrameSource())
return;
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 5ef8108..a46f717 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -837,8 +837,14 @@ class CONTENT_EXPORT WebContentsImpl
const std::string& mime_type,
ResourceType resource_type);
void OnDidDisplayInsecureContent();
- void OnDidRunInsecureContent(const std::string& security_origin,
+ void OnDidRunInsecureContent(const GURL& security_origin,
const GURL& target_url);
+ void OnDidDisplayContentWithCertificateErrors(
+ const GURL& url,
+ const std::string& security_info);
+ void OnDidRunContentWithCertificateErrors(const GURL& security_origin,
+ const GURL& url,
+ const std::string& security_info);
void OnDocumentLoadedInFrame();
void OnDidFinishLoad(const GURL& url);
void OnGoToEntryAtOffset(int offset);
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc
index bea6020..dbcff21 100644
--- a/content/child/web_url_loader_impl.cc
+++ b/content/child/web_url_loader_impl.cc
@@ -887,6 +887,7 @@ void WebURLLoaderImpl::PopulateURLResponse(const GURL& url,
response->setTextEncodingName(WebString::fromUTF8(info.charset));
response->setExpectedContentLength(info.content_length);
response->setSecurityInfo(info.security_info);
+ response->setHasMajorCertificateErrors(info.has_major_certificate_errors);
response->setAppCacheID(info.appcache_id);
response->setAppCacheManifestURL(info.appcache_manifest_url);
response->setWasCached(!info.load_timing.request_start_time.is_null() &&
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index 72d6751..f9604de 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -1225,9 +1225,22 @@ IPC_MESSAGE_ROUTED0(FrameHostMsg_DidDisplayInsecureContent)
// Sent when the renderer runs insecure content in a secure origin.
IPC_MESSAGE_ROUTED2(FrameHostMsg_DidRunInsecureContent,
- std::string /* security_origin */,
+ GURL /* security_origin */,
GURL /* target URL */)
+// Sent when the renderer displays content that was loaded with
+// certificate errors.
+IPC_MESSAGE_ROUTED2(FrameHostMsg_DidDisplayContentWithCertificateErrors,
+ GURL /* resource url */,
+ std::string /* serialized security info */)
+
+// Sent when the renderer runs content that was loaded with certificate
+// errors.
+IPC_MESSAGE_ROUTED3(FrameHostMsg_DidRunContentWithCertificateErrors,
+ GURL /* security_origin */,
+ GURL /* resource url */,
+ std::string /* serialized security info */)
+
// Response to FrameMsg_GetSavableResourceLinks.
IPC_MESSAGE_ROUTED3(FrameHostMsg_SavableResourceLinksResponse,
std::vector<GURL> /* savable resource links */,
diff --git a/content/common/resource_messages.h b/content/common/resource_messages.h
index 0c970ae..65e7f00 100644
--- a/content/common/resource_messages.h
+++ b/content/common/resource_messages.h
@@ -119,6 +119,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::ResourceResponseInfo)
IPC_STRUCT_TRAITS_MEMBER(mime_type)
IPC_STRUCT_TRAITS_MEMBER(charset)
IPC_STRUCT_TRAITS_MEMBER(security_info)
+ IPC_STRUCT_TRAITS_MEMBER(has_major_certificate_errors)
IPC_STRUCT_TRAITS_MEMBER(content_length)
IPC_STRUCT_TRAITS_MEMBER(encoded_data_length)
IPC_STRUCT_TRAITS_MEMBER(appcache_id)
diff --git a/content/public/common/resource_response.cc b/content/public/common/resource_response.cc
index 12f1dd7..1277355 100644
--- a/content/public/common/resource_response.cc
+++ b/content/public/common/resource_response.cc
@@ -19,6 +19,8 @@ scoped_refptr<ResourceResponse> ResourceResponse::DeepCopy() const {
new_response->head.mime_type = head.mime_type;
new_response->head.charset = head.charset;
new_response->head.security_info = head.security_info;
+ new_response->head.has_major_certificate_errors =
+ head.has_major_certificate_errors;
new_response->head.content_length = head.content_length;
new_response->head.encoded_data_length = head.encoded_data_length;
new_response->head.appcache_id = head.appcache_id;
diff --git a/content/public/common/resource_response_info.cc b/content/public/common/resource_response_info.cc
index 1d4e304..f05ee19 100644
--- a/content/public/common/resource_response_info.cc
+++ b/content/public/common/resource_response_info.cc
@@ -10,7 +10,8 @@
namespace content {
ResourceResponseInfo::ResourceResponseInfo()
- : content_length(-1),
+ : has_major_certificate_errors(false),
+ content_length(-1),
encoded_data_length(-1),
appcache_id(kAppCacheNoCacheId),
was_fetched_via_spdy(false),
@@ -22,8 +23,7 @@ ResourceResponseInfo::ResourceResponseInfo()
was_fallback_required_by_service_worker(false),
response_type_via_service_worker(
blink::WebServiceWorkerResponseTypeDefault),
- is_using_lofi(false) {
-}
+ is_using_lofi(false) {}
ResourceResponseInfo::~ResourceResponseInfo() {
}
diff --git a/content/public/common/resource_response_info.h b/content/public/common/resource_response_info.h
index 1a0f126..8b81f6d 100644
--- a/content/public/common/resource_response_info.h
+++ b/content/public/common/resource_response_info.h
@@ -50,6 +50,9 @@ struct ResourceResponseInfo {
// response. This may include information about the SSL connection used.
std::string security_info;
+ // True if the resource was loaded in spite of certificate errors.
+ bool has_major_certificate_errors;
+
// Content length if available. -1 if not available
int64 content_length;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 271720e..9e432ba9 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -48,6 +48,7 @@
#include "content/common/savable_subframe.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/common/site_isolation_policy.h"
+#include "content/common/ssl_status_serialization.h"
#include "content/common/swapped_out_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/bindings_policy.h"
@@ -575,6 +576,38 @@ WebString ConvertRelativePathToHtmlAttribute(const base::FilePath& path) {
path.NormalizePathSeparatorsTo(FILE_PATH_LITERAL('/')).AsUTF8Unsafe());
}
+bool IsContentWithCertificateErrorsRelevantToUI(
+ const blink::WebURL& url,
+ const blink::WebCString& security_info,
+ const blink::WebURL& main_resource_url,
+ const blink::WebCString& main_resource_security_info) {
+ content::SSLStatus ssl_status;
+ content::SSLStatus main_resource_ssl_status;
+ CHECK(DeserializeSecurityInfo(security_info, &ssl_status));
+ CHECK(DeserializeSecurityInfo(main_resource_security_info,
+ &main_resource_ssl_status));
+
+ if (!GURL(main_resource_url).SchemeIsCryptographic())
+ return false;
+
+ // Do not handle subresource certificate errors if they are the same
+ // as errors that occured during the main page load. This compares
+ // most, but not all, fields of SSLStatus. For example, this check
+ // does not compare |content_status| because the navigation entry
+ // might have mixed content but also have the exact same SSL
+ // connection properties as the subresource, thereby making the
+ // subresource errors duplicative.
+ return (!url::Origin(GURL(url))
+ .IsSameOriginWith(url::Origin(GURL(main_resource_url))) ||
+ main_resource_ssl_status.security_style !=
+ ssl_status.security_style ||
+ main_resource_ssl_status.cert_id != ssl_status.cert_id ||
+ main_resource_ssl_status.cert_status != ssl_status.cert_status ||
+ main_resource_ssl_status.security_bits != ssl_status.security_bits ||
+ main_resource_ssl_status.connection_status !=
+ ssl_status.connection_status);
+}
+
} // namespace
// static
@@ -3680,12 +3713,38 @@ void RenderFrameImpl::didRunInsecureContent(
const blink::WebSecurityOrigin& origin,
const blink::WebURL& target) {
Send(new FrameHostMsg_DidRunInsecureContent(
- routing_id_, origin.toString().utf8(), target));
+ routing_id_, GURL(origin.toString().utf8()), target));
GetContentClient()->renderer()->RecordRapporURL(
"ContentSettings.MixedScript.RanMixedScript",
GURL(origin.toString().utf8()));
}
+void RenderFrameImpl::didDisplayContentWithCertificateErrors(
+ const blink::WebURL& url,
+ const blink::WebCString& security_info,
+ const blink::WebURL& main_resource_url,
+ const blink::WebCString& main_resource_security_info) {
+ if (!IsContentWithCertificateErrorsRelevantToUI(
+ url, security_info, main_resource_url, main_resource_security_info)) {
+ return;
+ }
+ Send(new FrameHostMsg_DidDisplayContentWithCertificateErrors(routing_id_, url,
+ security_info));
+}
+
+void RenderFrameImpl::didRunContentWithCertificateErrors(
+ const blink::WebURL& url,
+ const blink::WebCString& security_info,
+ const blink::WebURL& main_resource_url,
+ const blink::WebCString& main_resource_security_info) {
+ if (!IsContentWithCertificateErrorsRelevantToUI(
+ url, security_info, main_resource_url, main_resource_security_info)) {
+ return;
+ }
+ Send(new FrameHostMsg_DidRunContentWithCertificateErrors(
+ routing_id_, GURL(main_resource_url).GetOrigin(), url, security_info));
+}
+
void RenderFrameImpl::didChangePerformanceTiming() {
FOR_EACH_OBSERVER(RenderFrameObserver,
observers_,
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 8d3c4f3..9da61e0 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -522,6 +522,16 @@ class CONTENT_EXPORT RenderFrameImpl
void didDisplayInsecureContent() override;
void didRunInsecureContent(const blink::WebSecurityOrigin& origin,
const blink::WebURL& target) override;
+ void didDisplayContentWithCertificateErrors(
+ const blink::WebURL& url,
+ const blink::WebCString& security_info,
+ const blink::WebURL& main_resource_url,
+ const blink::WebCString& main_resource_security_info) override;
+ void didRunContentWithCertificateErrors(
+ const blink::WebURL& url,
+ const blink::WebCString& security_info,
+ const blink::WebURL& main_resource_url,
+ const blink::WebCString& main_resource_security_info) override;
void didChangePerformanceTiming() override;
void didCreateScriptContext(blink::WebLocalFrame* frame,
v8::Local<v8::Context> context,
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.h b/third_party/WebKit/Source/core/loader/EmptyClients.h
index 9f4f7bd..a0ae277 100644
--- a/third_party/WebKit/Source/core/loader/EmptyClients.h
+++ b/third_party/WebKit/Source/core/loader/EmptyClients.h
@@ -234,6 +234,8 @@ public:
void didRunInsecureContent(SecurityOrigin*, const KURL&) override {}
void didDetectXSS(const KURL&, bool) override {}
void didDispatchPingLoader(const KURL&) override {}
+ void didDisplayContentWithCertificateErrors(const KURL&, const CString&, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo) override {}
+ void didRunContentWithCertificateErrors(const KURL&, const CString&, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo) override {}
void selectorMatchChanged(const Vector<String>&, const Vector<String>&) override {}
PassRefPtrWillBeRawPtr<LocalFrame> createFrame(const FrameLoadRequest&, const AtomicString&, HTMLFrameOwnerElement*) override;
PassRefPtrWillBeRawPtr<Widget> createPlugin(HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool, DetachedPluginPolicy) override;
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
index 6be16e9..41bed10 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -34,6 +34,7 @@
#include "bindings/core/v8/ScriptController.h"
#include "core/dom/Document.h"
#include "core/fetch/ClientHintsPreferences.h"
+#include "core/fetch/ResourceLoader.h"
#include "core/fetch/UniqueIdentifier.h"
#include "core/frame/FrameConsole.h"
#include "core/frame/FrameHost.h"
@@ -239,6 +240,9 @@ void FrameFetchContext::dispatchDidReceiveResponse(unsigned long identifier, con
m_documentLoader->clientHintsPreferences().updateFromAcceptClientHintsHeader(response.httpHeaderField("accept-ch"), fetcher);
}
+ if (response.hasMajorCertificateErrors() && resourceLoader)
+ MixedContentChecker::handleCertificateError(frame(), resourceLoader->originalRequest(), response);
+
frame()->loader().progress().incrementProgress(identifier, response);
frame()->loader().client()->dispatchDidReceiveResponse(m_documentLoader, identifier, response);
TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceReceiveResponse", TRACE_EVENT_SCOPE_THREAD, "data", InspectorReceiveResponseEvent::data(identifier, frame(), response));
diff --git a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
index b492489..42e507d 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
+++ b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
@@ -129,6 +129,13 @@ public:
virtual void didDetectXSS(const KURL&, bool didBlockEntirePage) = 0;
virtual void didDispatchPingLoader(const KURL&) = 0;
+ // The given main resource displayed content with certificate errors
+ // with the given URL and security info.
+ virtual void didDisplayContentWithCertificateErrors(const KURL&, const CString& securityInfo, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo) = 0;
+ // The given main resource ran content with certificate errors with
+ // the given URL and security info.
+ virtual void didRunContentWithCertificateErrors(const KURL&, const CString& securityInfo, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo) = 0;
+
// Will be called when |PerformanceTiming| events are updated
virtual void didChangePerformanceTiming() { }
diff --git a/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp b/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp
index fdcc09b..f525cda 100644
--- a/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp
+++ b/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp
@@ -458,6 +458,27 @@ LocalFrame* MixedContentChecker::effectiveFrameForFrameType(LocalFrame* frame, W
return effectiveFrame;
}
+void MixedContentChecker::handleCertificateError(LocalFrame* frame, const ResourceRequest& request, const ResourceResponse& response)
+{
+ WebURLRequest::FrameType frameType = request.frameType();
+ LocalFrame* effectiveFrame = effectiveFrameForFrameType(frame, frameType);
+ if (frameType == WebURLRequest::FrameTypeTopLevel || !effectiveFrame)
+ return;
+
+ FrameLoaderClient* client = effectiveFrame->loader().client();
+ WebURLRequest::RequestContext requestContext = request.requestContext();
+ ContextType contextType = MixedContentChecker::contextTypeFromContext(requestContext, frame);
+ if (contextType == ContextTypeBlockable) {
+ client->didRunContentWithCertificateErrors(response.url(), response.getSecurityInfo(), effectiveFrame->document()->url(), effectiveFrame->loader().documentLoader()->response().getSecurityInfo());
+ } else {
+ // contextTypeFromContext() never returns NotMixedContent (it
+ // computes the type of mixed content, given that the content is
+ // mixed).
+ ASSERT(contextType != ContextTypeNotMixedContent);
+ client->didDisplayContentWithCertificateErrors(response.url(), response.getSecurityInfo(), effectiveFrame->document()->url(), effectiveFrame->loader().documentLoader()->response().getSecurityInfo());
+ }
+}
+
MixedContentChecker::ContextType MixedContentChecker::contextTypeForInspector(LocalFrame* frame, const ResourceRequest& request)
{
LocalFrame* effectiveFrame = effectiveFrameForFrameType(frame, request.frameType());
diff --git a/third_party/WebKit/Source/core/loader/MixedContentChecker.h b/third_party/WebKit/Source/core/loader/MixedContentChecker.h
index d88780b..e2e50c4 100644
--- a/third_party/WebKit/Source/core/loader/MixedContentChecker.h
+++ b/third_party/WebKit/Source/core/loader/MixedContentChecker.h
@@ -31,6 +31,7 @@
#ifndef MixedContentChecker_h
#define MixedContentChecker_h
+#include "base/gtest_prod_util.h"
#include "core/CoreExport.h"
#include "platform/heap/Handle.h"
#include "platform/network/ResourceRequest.h"
@@ -42,6 +43,7 @@ namespace blink {
class FrameLoaderClient;
class LocalFrame;
class KURL;
+class ResourceResponse;
class SecurityOrigin;
class CORE_EXPORT MixedContentChecker final {
@@ -75,7 +77,10 @@ public:
// for a mixed content check for the given frame type.
static LocalFrame* effectiveFrameForFrameType(LocalFrame*, WebURLRequest::FrameType);
+ static void handleCertificateError(LocalFrame*, const ResourceRequest&, const ResourceResponse&);
+
private:
+ FRIEND_TEST_ALL_PREFIXES(MixedContentCheckerTest, HandleCertificateError);
enum MixedContentType {
Display,
Execution,
diff --git a/third_party/WebKit/Source/core/loader/MixedContentCheckerTest.cpp b/third_party/WebKit/Source/core/loader/MixedContentCheckerTest.cpp
index 4291c0a..8b4cb21 100644
--- a/third_party/WebKit/Source/core/loader/MixedContentCheckerTest.cpp
+++ b/third_party/WebKit/Source/core/loader/MixedContentCheckerTest.cpp
@@ -5,9 +5,12 @@
#include "config.h"
#include "core/loader/MixedContentChecker.h"
+#include "core/loader/EmptyClients.h"
#include "core/testing/DummyPageHolder.h"
+#include "platform/network/ResourceResponse.h"
#include "platform/weborigin/KURL.h"
#include "platform/weborigin/SecurityOrigin.h"
+#include "testing/gmock/include/gmock/gmock-generated-function-mockers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "wtf/RefPtr.h"
#include <base/macros.h>
@@ -67,4 +70,48 @@ TEST(MixedContentCheckerTest, ContextTypeForInspector)
EXPECT_EQ(MixedContentChecker::ContextTypeOptionallyBlockable, MixedContentChecker::contextTypeForInspector(&dummyPageHolder->frame(), blockableMixedContent));
}
+namespace {
+
+ class MockFrameLoaderClient : public EmptyFrameLoaderClient {
+ public:
+ MockFrameLoaderClient()
+ : EmptyFrameLoaderClient()
+ {
+ }
+ MOCK_METHOD4(didDisplayContentWithCertificateErrors, void(const KURL&, const CString&, const WebURL&, const CString&));
+ MOCK_METHOD4(didRunContentWithCertificateErrors, void(const KURL&, const CString&, const WebURL&, const CString&));
+ };
+
+} // namespace
+
+TEST(MixedContentCheckerTest, HandleCertificateError)
+{
+ MockFrameLoaderClient* client = new MockFrameLoaderClient;
+ OwnPtr<DummyPageHolder> dummyPageHolder = DummyPageHolder::create(IntSize(1, 1), nullptr, adoptPtrWillBeNoop(client));
+
+ KURL mainResourceUrl(KURL(), "https://example.test");
+ KURL displayedUrl(KURL(), "https://example-displayed.test");
+ KURL ranUrl(KURL(), "https://example-ran.test");
+
+ dummyPageHolder->frame().document()->setURL(mainResourceUrl);
+ ResourceRequest request1(ranUrl);
+ request1.setRequestContext(WebURLRequest::RequestContextScript);
+ request1.setFrameType(WebURLRequest::FrameTypeNone);
+ ResourceResponse response1;
+ response1.setURL(ranUrl);
+ response1.setSecurityInfo("security info1");
+ EXPECT_CALL(*client, didRunContentWithCertificateErrors(ranUrl, response1.getSecurityInfo(), WebURL(mainResourceUrl), CString()));
+ MixedContentChecker::handleCertificateError(&dummyPageHolder->frame(), request1, response1);
+
+ ResourceRequest request2(displayedUrl);
+ request2.setRequestContext(WebURLRequest::RequestContextImage);
+ request2.setFrameType(WebURLRequest::FrameTypeNone);
+ ResourceResponse response2;
+ ASSERT_EQ(MixedContentChecker::ContextTypeOptionallyBlockable, MixedContentChecker::contextTypeFromContext(request2.requestContext(), &dummyPageHolder->frame()));
+ response2.setURL(displayedUrl);
+ response2.setSecurityInfo("security info2");
+ EXPECT_CALL(*client, didDisplayContentWithCertificateErrors(displayedUrl, response2.getSecurityInfo(), WebURL(mainResourceUrl), CString()));
+ MixedContentChecker::handleCertificateError(&dummyPageHolder->frame(), request2, response2);
+}
+
} // namespace blink
diff --git a/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp b/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp
index 46f5dbf..6998d9a 100644
--- a/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp
@@ -305,6 +305,11 @@ void WebURLResponse::setSecurityInfo(const WebCString& securityInfo)
m_private->m_resourceResponse->setSecurityInfo(securityInfo);
}
+void WebURLResponse::setHasMajorCertificateErrors(bool value)
+{
+ m_private->m_resourceResponse->setHasMajorCertificateErrors(value);
+}
+
WebURLResponse::SecurityStyle WebURLResponse::securityStyle() const
{
return static_cast<SecurityStyle>(m_private->m_resourceResponse->securityStyle());
diff --git a/third_party/WebKit/Source/platform/network/ResourceResponse.cpp b/third_party/WebKit/Source/platform/network/ResourceResponse.cpp
index 37de0b6..1ba750e 100644
--- a/third_party/WebKit/Source/platform/network/ResourceResponse.cpp
+++ b/third_party/WebKit/Source/platform/network/ResourceResponse.cpp
@@ -48,6 +48,7 @@ ResourceResponse::ResourceResponse()
, m_date(0.0)
, m_expires(0.0)
, m_lastModified(0.0)
+ , m_hasMajorCertificateErrors(false)
, m_securityStyle(SecurityStyleUnknown)
, m_httpVersion(HTTPVersionUnknown)
, m_appCacheID(0)
@@ -84,6 +85,7 @@ ResourceResponse::ResourceResponse(const KURL& url, const AtomicString& mimeType
, m_date(0.0)
, m_expires(0.0)
, m_lastModified(0.0)
+ , m_hasMajorCertificateErrors(false)
, m_securityStyle(SecurityStyleUnknown)
, m_httpVersion(HTTPVersionUnknown)
, m_appCacheID(0)
@@ -116,6 +118,7 @@ PassOwnPtr<ResourceResponse> ResourceResponse::adopt(PassOwnPtr<CrossThreadResou
response->setLastModifiedDate(data->m_lastModifiedDate);
response->setResourceLoadTiming(data->m_resourceLoadTiming.release());
response->m_securityInfo = data->m_securityInfo;
+ response->m_hasMajorCertificateErrors = data->m_hasMajorCertificateErrors;
response->m_securityStyle = data->m_securityStyle;
response->m_securityDetails.protocol = data->m_securityDetails.protocol;
response->m_securityDetails.cipher = data->m_securityDetails.cipher;
@@ -161,6 +164,7 @@ PassOwnPtr<CrossThreadResourceResponseData> ResourceResponse::copyData() const
if (m_resourceLoadTiming)
data->m_resourceLoadTiming = m_resourceLoadTiming->deepCopy();
data->m_securityInfo = CString(m_securityInfo.data(), m_securityInfo.length());
+ data->m_hasMajorCertificateErrors = m_hasMajorCertificateErrors;
data->m_securityStyle = m_securityStyle;
data->m_securityDetails.protocol = m_securityDetails.protocol.isolatedCopy();
data->m_securityDetails.cipher = m_securityDetails.cipher.isolatedCopy();
diff --git a/third_party/WebKit/Source/platform/network/ResourceResponse.h b/third_party/WebKit/Source/platform/network/ResourceResponse.h
index 58080de..9c19606 100644
--- a/third_party/WebKit/Source/platform/network/ResourceResponse.h
+++ b/third_party/WebKit/Source/platform/network/ResourceResponse.h
@@ -160,6 +160,9 @@ public:
const CString& getSecurityInfo() const { return m_securityInfo; }
void setSecurityInfo(const CString& securityInfo) { m_securityInfo = securityInfo; }
+ bool hasMajorCertificateErrors() const { return m_hasMajorCertificateErrors; }
+ void setHasMajorCertificateErrors(bool hasMajorCertificateErrors) { m_hasMajorCertificateErrors = hasMajorCertificateErrors; }
+
SecurityStyle securityStyle() const { return m_securityStyle; }
void setSecurityStyle(SecurityStyle securityStyle) { m_securityStyle = securityStyle; }
@@ -268,6 +271,10 @@ private:
// string if not over HTTPS).
CString m_securityInfo;
+ // True if the resource was retrieved by the embedder in spite of
+ // certificate errors.
+ bool m_hasMajorCertificateErrors;
+
// The security style of the resource.
// This only contains a valid value when the DevTools Network domain is
// enabled. (Otherwise, it contains a default value of Unknown.)
@@ -357,6 +364,7 @@ public:
time_t m_lastModifiedDate;
RefPtr<ResourceLoadTiming> m_resourceLoadTiming;
CString m_securityInfo;
+ bool m_hasMajorCertificateErrors;
ResourceResponse::SecurityStyle m_securityStyle;
ResourceResponse::SecurityDetails m_securityDetails;
ResourceResponse::HTTPVersion m_httpVersion;
diff --git a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp
index df4026a..19de8ca 100644
--- a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp
+++ b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp
@@ -677,6 +677,18 @@ void FrameLoaderClientImpl::didDispatchPingLoader(const KURL& url)
m_webFrame->client()->didDispatchPingLoader(m_webFrame, url);
}
+void FrameLoaderClientImpl::didDisplayContentWithCertificateErrors(const KURL& url, const CString& securityInfo, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo)
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->didDisplayContentWithCertificateErrors(url, securityInfo, mainResourceUrl, mainResourceSecurityInfo);
+}
+
+void FrameLoaderClientImpl::didRunContentWithCertificateErrors(const KURL& url, const CString& securityInfo, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo)
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->didRunContentWithCertificateErrors(url, securityInfo, mainResourceUrl, mainResourceSecurityInfo);
+}
+
void FrameLoaderClientImpl::didChangePerformanceTiming()
{
if (m_webFrame->client())
diff --git a/third_party/WebKit/Source/web/FrameLoaderClientImpl.h b/third_party/WebKit/Source/web/FrameLoaderClientImpl.h
index 518325b..360f5b0 100644
--- a/third_party/WebKit/Source/web/FrameLoaderClientImpl.h
+++ b/third_party/WebKit/Source/web/FrameLoaderClientImpl.h
@@ -113,6 +113,8 @@ public:
void didRunInsecureContent(SecurityOrigin*, const KURL& insecureURL) override;
void didDetectXSS(const KURL&, bool didBlockEntirePage) override;
void didDispatchPingLoader(const KURL&) override;
+ void didDisplayContentWithCertificateErrors(const KURL&, const CString& securityInfo, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo) override;
+ void didRunContentWithCertificateErrors(const KURL&, const CString& securityInfo, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo) override;
void didChangePerformanceTiming() override;
void selectorMatchChanged(const Vector<String>& addedSelectors, const Vector<String>& removedSelectors) override;
PassRefPtrWillBeRawPtr<DocumentLoader> createDocumentLoader(LocalFrame*, const ResourceRequest&, const SubstituteData&) override;
diff --git a/third_party/WebKit/public/platform/WebURLResponse.h b/third_party/WebKit/public/platform/WebURLResponse.h
index c7a5b0b..3a64468 100644
--- a/third_party/WebKit/public/platform/WebURLResponse.h
+++ b/third_party/WebKit/public/platform/WebURLResponse.h
@@ -146,6 +146,8 @@ public:
BLINK_PLATFORM_EXPORT WebCString securityInfo() const;
BLINK_PLATFORM_EXPORT void setSecurityInfo(const WebCString&);
+ BLINK_PLATFORM_EXPORT void setHasMajorCertificateErrors(bool);
+
BLINK_PLATFORM_EXPORT SecurityStyle securityStyle() const;
BLINK_PLATFORM_EXPORT void setSecurityStyle(SecurityStyle);
diff --git a/third_party/WebKit/public/web/WebFrameClient.h b/third_party/WebKit/public/web/WebFrameClient.h
index e603a05..89f2cef 100644
--- a/third_party/WebKit/public/web/WebFrameClient.h
+++ b/third_party/WebKit/public/web/WebFrameClient.h
@@ -67,6 +67,7 @@ class WebColorChooser;
class WebColorChooserClient;
class WebContentDecryptionModule;
class WebCookieJar;
+class WebCString;
class WebDataSource;
class WebEncryptedMediaClient;
class WebExternalPopupMenu;
@@ -449,6 +450,13 @@ public:
// A PingLoader was created, and a request dispatched to a URL.
virtual void didDispatchPingLoader(WebLocalFrame*, const WebURL&) { }
+ // This frame has displayed inactive content (such as an image) from
+ // a connection with certificate errors.
+ virtual void didDisplayContentWithCertificateErrors(const WebURL& url, const WebCString& securityInfo, const WebURL& mainResourceUrl, const WebCString& mainResourceSecurityInfo) {}
+ // This frame has run active content (such as a script) from a
+ // connection with certificate errors.
+ virtual void didRunContentWithCertificateErrors(const WebURL& url, const WebCString& securityInfo, const WebURL& mainResourceUrl, const WebCString& mainResourceSecurityInfo) {}
+
// A performance timing event (e.g. first paint) occurred
virtual void didChangePerformanceTiming() { }