diff options
author | estark <estark@chromium.org> | 2015-07-28 15:42:46 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-28 22:43:18 +0000 |
commit | 0c388aaf008fe3549e436fdfa3b2d2ee95b9a011 (patch) | |
tree | a19334865538c338914fc5edbe492a63be997a86 | |
parent | 772c9c76dd4af50f697e67751867686c15321435 (diff) | |
download | chromium_src-0c388aaf008fe3549e436fdfa3b2d2ee95b9a011.zip chromium_src-0c388aaf008fe3549e436fdfa3b2d2ee95b9a011.tar.gz chromium_src-0c388aaf008fe3549e436fdfa3b2d2ee95b9a011.tar.bz2 |
Revert of Attach a SecurityStyle to each request in ResourceLoader (patchset #9 id:160001 of https://codereview.chromium.org/1244863003/)
Reason for revert:
SecurityStyleChanged browser test is flaky after this change: http://build.chromium.org/p/chromium.linux/builders/Linux%20Tests
Original issue's description:
> Attach a SecurityStyle to each request in ResourceLoader
>
> This CL adds a SecurityStyle to the serialized security information that
> is sent with each request from the browser to the renderer. The
> SecurityStyle describes the individual resource, not any bigger-picture
> concerns like mixed content. The per-request SecurityStyle will be
> displayed in DevTools to help developers diagnose SSL issues on
> subresources.
>
> BUG=502118, 445234
>
> Committed: https://crrev.com/5318895a4dd623caf5d152461684935c6e874e12
> Cr-Commit-Position: refs/heads/master@{#340762}
TBR=creis@chromium.org,davidben@chromium.org,palmer@chromium.org,msw@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=502118, 445234
Review URL: https://codereview.chromium.org/1259253009
Cr-Commit-Position: refs/heads/master@{#340785}
-rw-r--r-- | chrome/browser/ui/browser_browsertest.cc | 41 | ||||
-rw-r--r-- | content/browser/loader/resource_loader.cc | 89 | ||||
-rw-r--r-- | content/browser/loader/resource_loader_unittest.cc | 124 | ||||
-rw-r--r-- | content/browser/ssl/ssl_manager.cc | 17 | ||||
-rw-r--r-- | content/browser/ssl/ssl_manager.h | 7 | ||||
-rw-r--r-- | content/browser/ssl/ssl_policy.cc | 48 | ||||
-rw-r--r-- | content/browser/ssl/ssl_policy.h | 17 | ||||
-rw-r--r-- | content/common/ssl_status_serialization.cc | 51 | ||||
-rw-r--r-- | content/common/ssl_status_serialization.h | 21 | ||||
-rw-r--r-- | content/common/ssl_status_serialization_unittest.cc | 65 | ||||
-rw-r--r-- | content/renderer/render_view_browsertest.cc | 8 |
11 files changed, 135 insertions, 353 deletions
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc index 43f0e76..43ca353 100644 --- a/chrome/browser/ui/browser_browsertest.cc +++ b/chrome/browser/ui/browser_browsertest.cc @@ -384,8 +384,7 @@ class SecurityStyleTestObserver : public WebContentsObserver { // Check that |observer|'s latest event was for an expired certificate // and that it saw the proper SecurityStyle and explanations. -void CheckBrokenSecurityStyle(const SecurityStyleTestObserver& observer, - int error) { +void CheckExpiredSecurityStyle(const SecurityStyleTestObserver& observer) { EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN, observer.latest_security_style()); @@ -398,7 +397,8 @@ void CheckBrokenSecurityStyle(const SecurityStyleTestObserver& observer, EXPECT_EQ(l10n_util::GetStringUTF8(IDS_CERTIFICATE_CHAIN_ERROR), expired_explanation.broken_explanations[0].summary); - base::string16 error_string = base::UTF8ToUTF16(net::ErrorToString(error)); + base::string16 error_string = + base::UTF8ToUTF16(net::ErrorToString(net::ERR_CERT_DATE_INVALID)); EXPECT_EQ(l10n_util::GetStringFUTF8( IDS_CERTIFICATE_CHAIN_ERROR_DESCRIPTION_FORMAT, error_string), expired_explanation.broken_explanations[0].description); @@ -2950,29 +2950,6 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, SecurityStyleChangedObserver) { EXPECT_EQ(0u, observer.latest_explanations().warning_explanations.size()); EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size()); - // Navigate to a bad HTTPS page on a different host, and then click - // Back to verify that the previous good security style is seen again. - host_resolver()->AddRule("www.example_broken.test", "127.0.0.1"); - GURL::Replacements replace_host; - replace_host.SetHostStr("www.example_broken.test"); - GURL https_url_different_host = - valid_https_url.ReplaceComponents(replace_host); - ui_test_utils::NavigateToURL(browser(), https_url_different_host); - CheckBrokenSecurityStyle(observer, net::ERR_CERT_COMMON_NAME_INVALID); - ProceedThroughInterstitial(web_contents); - CheckBrokenSecurityStyle(observer, net::ERR_CERT_COMMON_NAME_INVALID); - - content::WindowedNotificationObserver back_nav_load_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>(&web_contents->GetController())); - chrome::GoBack(browser(), CURRENT_TAB); - back_nav_load_observer.Wait(); - - EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED, - observer.latest_security_style()); - EXPECT_EQ(0u, observer.latest_explanations().warning_explanations.size()); - EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size()); - // Visit an (otherwise valid) HTTPS page that displays mixed content. std::string replacement_path; ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( @@ -3000,7 +2977,7 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, SecurityStyleChangedObserver) { // interstitial should fire. content::WaitForInterstitialAttach(web_contents); EXPECT_TRUE(web_contents->ShowingInterstitialPage()); - CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID); + CheckExpiredSecurityStyle(observer); // Before clicking through, navigate to a different page, and then go // back to the interstitial. @@ -3015,16 +2992,16 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, SecurityStyleChangedObserver) { ui_test_utils::NavigateToURL(browser(), expired_url); content::WaitForInterstitialAttach(web_contents); EXPECT_TRUE(web_contents->ShowingInterstitialPage()); - CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID); + CheckExpiredSecurityStyle(observer); // Since the next expected style is the same as the previous, clear // the observer (to make sure that the event fires twice and we don't // just see the previous event's style). observer.ClearLatestSecurityStyleAndExplanations(); - // Other conditions cannot be tested on this host after clicking - // through because once the interstitial is clicked through, all URLs - // for this host will remain in a broken state. + // Other conditions cannot be tested after clicking through because + // once the interstitial is clicked through, all URLs for this host + // will remain in a broken state. ProceedThroughInterstitial(web_contents); - CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID); + CheckExpiredSecurityStyle(observer); } diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc index 0339cf1..5c2b9b8 100644 --- a/content/browser/loader/resource_loader.cc +++ b/content/browser/loader/resource_loader.cc @@ -20,7 +20,6 @@ #include "content/browser/service_worker/service_worker_request_handler.h" #include "content/browser/ssl/ssl_client_auth_handler.h" #include "content/browser/ssl/ssl_manager.h" -#include "content/browser/ssl/ssl_policy.h" #include "content/common/ssl_status_serialization.h" #include "content/public/browser/cert_store.h" #include "content/public/browser/resource_context.h" @@ -30,7 +29,6 @@ #include "content/public/common/content_switches.h" #include "content/public/common/process_type.h" #include "content/public/common/resource_response.h" -#include "content/public/common/security_style.h" #include "net/base/io_buffer.h" #include "net/base/load_flags.h" #include "net/http/http_response_headers.h" @@ -77,43 +75,6 @@ void PopulateResourceResponse(ResourceRequestInfoImpl* info, request->GetLoadTimingInfo(&response->head.load_timing); } -void StoreSignedCertificateTimestamps( - const net::SignedCertificateTimestampAndStatusList& sct_list, - int process_id, - SignedCertificateTimestampIDStatusList* sct_ids) { - SignedCertificateTimestampStore* sct_store( - SignedCertificateTimestampStore::GetInstance()); - - for (auto iter = sct_list.begin(); iter != sct_list.end(); ++iter) { - const int sct_id(sct_store->Store(iter->sct.get(), process_id)); - sct_ids->push_back( - SignedCertificateTimestampIDAndStatus(sct_id, iter->status)); - } -} - -void GetSSLStatusForRequest(const GURL& url, - const net::SSLInfo& ssl_info, - int child_id, - SSLStatus* ssl_status) { - DCHECK(ssl_info.cert); - - int cert_id = - CertStore::GetInstance()->StoreCert(ssl_info.cert.get(), child_id); - - SignedCertificateTimestampIDStatusList signed_certificate_timestamp_ids; - StoreSignedCertificateTimestamps(ssl_info.signed_certificate_timestamps, - child_id, &signed_certificate_timestamp_ids); - - ssl_status->cert_id = cert_id; - ssl_status->cert_status = ssl_info.cert_status; - ssl_status->security_bits = ssl_info.security_bits; - ssl_status->connection_status = ssl_info.connection_status; - ssl_status->signed_certificate_timestamp_ids = - signed_certificate_timestamp_ids; - ssl_status->security_style = - SSLPolicy::GetSecurityStyleForResource(url, *ssl_status); -} - } // namespace ResourceLoader::ResourceLoader(scoped_ptr<net::URLRequest> request, @@ -582,17 +543,42 @@ void ResourceLoader::CancelRequestInternal(int error, bool from_renderer) { } } +void ResourceLoader::StoreSignedCertificateTimestamps( + const net::SignedCertificateTimestampAndStatusList& sct_list, + int process_id, + SignedCertificateTimestampIDStatusList* sct_ids) { + SignedCertificateTimestampStore* sct_store( + SignedCertificateTimestampStore::GetInstance()); + + for (net::SignedCertificateTimestampAndStatusList::const_iterator iter = + sct_list.begin(); iter != sct_list.end(); ++iter) { + const int sct_id(sct_store->Store(iter->sct.get(), process_id)); + sct_ids->push_back( + SignedCertificateTimestampIDAndStatus(sct_id, iter->status)); + } +} + void ResourceLoader::CompleteResponseStarted() { ResourceRequestInfoImpl* info = GetRequestInfo(); scoped_refptr<ResourceResponse> response(new ResourceResponse()); PopulateResourceResponse(info, request_.get(), response.get()); if (request_->ssl_info().cert.get()) { - SSLStatus ssl_status; - GetSSLStatusForRequest(request_->url(), request_->ssl_info(), - info->GetChildID(), &ssl_status); - - response->head.security_info = SerializeSecurityInfo(ssl_status); + int cert_id = CertStore::GetInstance()->StoreCert( + request_->ssl_info().cert.get(), info->GetChildID()); + + SignedCertificateTimestampIDStatusList signed_certificate_timestamp_ids; + StoreSignedCertificateTimestamps( + request_->ssl_info().signed_certificate_timestamps, + info->GetChildID(), + &signed_certificate_timestamp_ids); + + response->head.security_info = SerializeSecurityInfo( + cert_id, + request_->ssl_info().cert_status, + request_->ssl_info().security_bits, + request_->ssl_info().connection_status, + signed_certificate_timestamp_ids); } else { // We should not have any SSL state. DCHECK(!request_->ssl_info().cert_status && @@ -708,11 +694,16 @@ void ResourceLoader::ResponseCompleted() { std::string security_info; const net::SSLInfo& ssl_info = request_->ssl_info(); if (ssl_info.cert.get() != NULL) { - SSLStatus ssl_status; - GetSSLStatusForRequest(request_->url(), ssl_info, info->GetChildID(), - &ssl_status); - - security_info = SerializeSecurityInfo(ssl_status); + int cert_id = CertStore::GetInstance()->StoreCert(ssl_info.cert.get(), + info->GetChildID()); + SignedCertificateTimestampIDStatusList signed_certificate_timestamp_ids; + StoreSignedCertificateTimestamps(ssl_info.signed_certificate_timestamps, + info->GetChildID(), + &signed_certificate_timestamp_ids); + + security_info = SerializeSecurityInfo( + cert_id, ssl_info.cert_status, ssl_info.security_bits, + ssl_info.connection_status, signed_certificate_timestamp_ids); } bool defer = false; diff --git a/content/browser/loader/resource_loader_unittest.cc b/content/browser/loader/resource_loader_unittest.cc index 14ee69b..7b4000e 100644 --- a/content/browser/loader/resource_loader_unittest.cc +++ b/content/browser/loader/resource_loader_unittest.cc @@ -14,8 +14,6 @@ #include "content/browser/browser_thread_impl.h" #include "content/browser/loader/redirect_to_file_resource_handler.h" #include "content/browser/loader/resource_loader_delegate.h" -#include "content/common/ssl_status_serialization.h" -#include "content/public/browser/cert_store.h" #include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/resource_request_info.h" #include "content/public/common/content_paths.h" @@ -32,16 +30,12 @@ #include "net/base/mock_file_stream.h" #include "net/base/net_errors.h" #include "net/base/request_priority.h" -#include "net/base/test_data_directory.h" #include "net/base/upload_bytes_element_reader.h" #include "net/cert/x509_certificate.h" #include "net/ssl/client_cert_store.h" #include "net/ssl/ssl_cert_request_info.h" -#include "net/test/cert_test_util.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/url_request/url_request.h" -#include "net/url_request/url_request_filter.h" -#include "net/url_request/url_request_interceptor.h" #include "net/url_request/url_request_job_factory.h" #include "net/url_request/url_request_job_factory_impl.h" #include "net/url_request/url_request_test_job.h" @@ -170,63 +164,6 @@ class MockClientCertJobProtocolHandler } }; -// Set up dummy values to use in test HTTPS requests. - -scoped_refptr<net::X509Certificate> GetTestCert() { - return net::ImportCertFromFile(net::GetTestCertsDirectory(), - "test_mail_google_com.pem"); -} - -const net::CertStatus kTestCertError = net::CERT_STATUS_DATE_INVALID; -const int kTestSecurityBits = 256; -// SSL3 TLS_DHE_RSA_WITH_AES_256_CBC_SHA -const int kTestConnectionStatus = 0x300039; - -// A mock URLRequestJob which simulates an HTTPS request. -class MockHTTPSURLRequestJob : public net::URLRequestTestJob { - public: - MockHTTPSURLRequestJob(net::URLRequest* request, - net::NetworkDelegate* network_delegate, - const std::string& response_headers, - const std::string& response_data, - bool auto_advance) - : net::URLRequestTestJob(request, - network_delegate, - response_headers, - response_data, - auto_advance) {} - - // net::URLRequestTestJob: - void GetResponseInfo(net::HttpResponseInfo* info) override { - // Get the original response info, but override the SSL info. - net::URLRequestJob::GetResponseInfo(info); - info->ssl_info.cert = GetTestCert(); - info->ssl_info.cert_status = kTestCertError; - info->ssl_info.security_bits = kTestSecurityBits; - info->ssl_info.connection_status = kTestConnectionStatus; - } - - private: - ~MockHTTPSURLRequestJob() override {} - - DISALLOW_COPY_AND_ASSIGN(MockHTTPSURLRequestJob); -}; - -class MockHTTPSJobURLRequestInterceptor : public net::URLRequestInterceptor { - public: - MockHTTPSJobURLRequestInterceptor() {} - ~MockHTTPSJobURLRequestInterceptor() override {} - - // net::URLRequestInterceptor: - net::URLRequestJob* MaybeInterceptRequest( - net::URLRequest* request, - net::NetworkDelegate* network_delegate) const override { - return new MockHTTPSURLRequestJob(request, network_delegate, - net::URLRequestTestJob::test_headers(), - "dummy response", true); - } -}; - // Arbitrary read buffer size. const int kReadBufSize = 1024; @@ -601,29 +538,6 @@ class ClientCertResourceLoaderTest : public ResourceLoaderTest { } }; -// A ResourceLoaderTest that intercepts https://example.test URLs and -// sets SSL info on the responses. -class HTTPSSecurityInfoResourceLoaderTest : public ResourceLoaderTest { - public: - HTTPSSecurityInfoResourceLoaderTest() - : ResourceLoaderTest(), test_https_url_("https://example.test") {} - - ~HTTPSSecurityInfoResourceLoaderTest() override {} - - const GURL& test_https_url() { return test_https_url_; } - - protected: - void SetUp() override { - ResourceLoaderTest::SetUp(); - net::URLRequestFilter::GetInstance()->AddHostnameInterceptor( - "https", "example.test", scoped_ptr<net::URLRequestInterceptor>( - new MockHTTPSJobURLRequestInterceptor)); - } - - private: - const GURL test_https_url_; -}; - // Tests that client certificates are requested with ClientCertStore lookup. TEST_F(ClientCertResourceLoaderTest, WithStoreLookup) { // Set up the test client cert store. @@ -1079,42 +993,4 @@ TEST_F(ResourceLoaderRedirectToFileTest, DownstreamDeferStart) { EXPECT_FALSE(base::PathExists(temp_path())); } -// Test that an HTTPS resource has the expected security info attached -// to it. -TEST_F(HTTPSSecurityInfoResourceLoaderTest, SecurityInfoOnHTTPSResource) { - // Start the request and wait for it to finish. - scoped_ptr<net::URLRequest> request( - resource_context_.GetRequestContext()->CreateRequest( - test_https_url(), net::DEFAULT_PRIORITY, nullptr /* delegate */)); - SetUpResourceLoader(request.Pass()); - - // Send the request and wait until it completes. - loader_->StartRequest(); - base::RunLoop().RunUntilIdle(); - ASSERT_EQ(net::URLRequestStatus::SUCCESS, - raw_ptr_to_request_->status().status()); - ASSERT_TRUE(raw_ptr_resource_handler_->received_response_completed()); - - ResourceResponse* response = raw_ptr_resource_handler_->response(); - ASSERT_TRUE(response); - - // Deserialize the security info from the response and check that it - // is as expected. - SSLStatus deserialized; - ASSERT_TRUE( - DeserializeSecurityInfo(response->head.security_info, &deserialized)); - - // Expect a BROKEN security style because the cert status has errors. - EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN, - deserialized.security_style); - scoped_refptr<net::X509Certificate> cert; - ASSERT_TRUE( - CertStore::GetInstance()->RetrieveCert(deserialized.cert_id, &cert)); - EXPECT_TRUE(cert->Equals(GetTestCert().get())); - - EXPECT_EQ(kTestCertError, deserialized.cert_status); - EXPECT_EQ(kTestConnectionStatus, deserialized.connection_status); - EXPECT_EQ(kTestSecurityBits, deserialized.security_bits); -} - } // namespace content diff --git a/content/browser/ssl/ssl_manager.cc b/content/browser/ssl/ssl_manager.cc index e4c71e3..ab1048c 100644 --- a/content/browser/ssl/ssl_manager.cc +++ b/content/browser/ssl/ssl_manager.cc @@ -121,10 +121,7 @@ void SSLManager::DidCommitProvisionalLoad(const LoadCommittedDetails& details) { } } - policy()->UpdateEntry(entry, controller_->delegate()->GetWebContents()); - // Always notify the WebContents that the SSL state changed when a - // load is committed, in case the active navigation entry has changed. - NotifyDidChangeVisibleSSLState(); + UpdateEntry(entry); } void SSLManager::DidDisplayInsecureContent() { @@ -187,16 +184,12 @@ void SSLManager::UpdateEntry(NavigationEntryImpl* entry) { SSLStatus original_ssl_status = entry->GetSSL(); // Copy! - policy()->UpdateEntry(entry, controller_->delegate()->GetWebContents()); - - if (!entry->GetSSL().Equals(original_ssl_status)) - NotifyDidChangeVisibleSSLState(); -} - -void SSLManager::NotifyDidChangeVisibleSSLState() { WebContentsImpl* contents = static_cast<WebContentsImpl*>(controller_->delegate()->GetWebContents()); - contents->DidChangeVisibleSSLState(); + policy()->UpdateEntry(entry, contents); + + if (!entry->GetSSL().Equals(original_ssl_status)) + contents->DidChangeVisibleSSLState(); } } // namespace content diff --git a/content/browser/ssl/ssl_manager.h b/content/browser/ssl/ssl_manager.h index fbf3e39..d4fca43 100644 --- a/content/browser/ssl/ssl_manager.h +++ b/content/browser/ssl/ssl_manager.h @@ -82,14 +82,9 @@ class SSLManager { void DidRunInsecureContent(const std::string& security_origin); private: - // Updates the NavigationEntry with our current state. This will - // notify the WebContents of an SSL state change if a change was - // actually made. + // Update the NavigationEntry with our current state. void UpdateEntry(NavigationEntryImpl* entry); - // Notifies the WebContents that the SSL state changed. - void NotifyDidChangeVisibleSSLState(); - // The backend for the SSLPolicy to actuate its decisions. SSLPolicyBackend backend_; diff --git a/content/browser/ssl/ssl_policy.cc b/content/browser/ssl/ssl_policy.cc index 8804409..f038444 100644 --- a/content/browser/ssl/ssl_policy.cc +++ b/content/browser/ssl/ssl_policy.cc @@ -19,12 +19,11 @@ #include "content/browser/ssl/ssl_request_info.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/content_browser_client.h" -#include "content/public/browser/web_contents.h" #include "content/public/common/resource_type.h" #include "content/public/common/ssl_status.h" #include "content/public/common/url_constants.h" #include "net/ssl/ssl_info.h" -#include "url/gurl.h" + namespace content { @@ -139,22 +138,37 @@ void SSLPolicy::OnRequestStarted(SSLRequestInfo* info) { } void SSLPolicy::UpdateEntry(NavigationEntryImpl* entry, - WebContents* web_contents) { + WebContentsImpl* web_contents) { DCHECK(entry); InitializeEntryIfNeeded(entry); - if (entry->GetSSL().security_style == SECURITY_STYLE_UNAUTHENTICATED) + if (!entry->GetURL().SchemeIsCryptographic()) return; if (!web_contents->DisplayedInsecureContent()) entry->GetSSL().content_status &= ~SSLStatus::DISPLAYED_INSECURE_CONTENT; + // An HTTPS response may not have a certificate for some reason. When that + // happens, use the unauthenticated (HTTP) rather than the authentication + // broken security style so that we can detect this error condition. + if (!entry->GetSSL().cert_id) { + entry->GetSSL().security_style = SECURITY_STYLE_UNAUTHENTICATED; + return; + } + if (web_contents->DisplayedInsecureContent()) entry->GetSSL().content_status |= SSLStatus::DISPLAYED_INSECURE_CONTENT; - if (entry->GetSSL().security_style == SECURITY_STYLE_AUTHENTICATION_BROKEN) + if (net::IsCertStatusError(entry->GetSSL().cert_status)) { + // Minor errors don't lower the security style to + // SECURITY_STYLE_AUTHENTICATION_BROKEN. + if (!net::IsCertStatusMinorError(entry->GetSSL().cert_status)) { + entry->GetSSL().security_style = + SECURITY_STYLE_AUTHENTICATION_BROKEN; + } return; + } SiteInstance* site_instance = entry->site_instance(); // Note that |site_instance| can be NULL here because NavigationEntries don't @@ -170,25 +184,6 @@ void SSLPolicy::UpdateEntry(NavigationEntryImpl* entry, } } -// Static -SecurityStyle SSLPolicy::GetSecurityStyleForResource(const GURL& url, - const SSLStatus& ssl) { - // An HTTPS response may not have a certificate for some reason. When that - // happens, use the unauthenticated (HTTP) rather than the authentication - // broken security style so that we can detect this error condition. - if (!url.SchemeIsCryptographic() || !ssl.cert_id) - return SECURITY_STYLE_UNAUTHENTICATED; - - // Minor errors don't lower the security style to - // SECURITY_STYLE_AUTHENTICATION_BROKEN. - if (net::IsCertStatusError(ssl.cert_status) && - !net::IsCertStatusMinorError(ssl.cert_status)) { - return SECURITY_STYLE_AUTHENTICATION_BROKEN; - } - - return SECURITY_STYLE_AUTHENTICATED; -} - void SSLPolicy::OnAllowCertificate(scoped_refptr<SSLCertErrorHandler> handler, bool allow) { DCHECK(handler->ssl_info().is_valid()); @@ -256,8 +251,9 @@ void SSLPolicy::InitializeEntryIfNeeded(NavigationEntryImpl* entry) { if (entry->GetSSL().security_style != SECURITY_STYLE_UNKNOWN) return; - entry->GetSSL().security_style = - GetSecurityStyleForResource(entry->GetURL(), entry->GetSSL()); + entry->GetSSL().security_style = entry->GetURL().SchemeIsCryptographic() + ? SECURITY_STYLE_AUTHENTICATED + : SECURITY_STYLE_UNAUTHENTICATED; } void SSLPolicy::OriginRanInsecureContent(const std::string& origin, int pid) { diff --git a/content/browser/ssl/ssl_policy.h b/content/browser/ssl/ssl_policy.h index 8998d1f..78dbb6d 100644 --- a/content/browser/ssl/ssl_policy.h +++ b/content/browser/ssl/ssl_policy.h @@ -9,17 +9,13 @@ #include "base/memory/ref_counted.h" #include "content/public/common/resource_type.h" -#include "content/public/common/security_style.h" - -class GURL; namespace content { class NavigationEntryImpl; class SSLCertErrorHandler; class SSLPolicyBackend; class SSLRequestInfo; -class WebContents; -struct SSLStatus; +class WebContentsImpl; // SSLPolicy // @@ -41,17 +37,12 @@ class SSLPolicy { void OnRequestStarted(SSLRequestInfo* info); // Update the SSL information in |entry| to match the current state. - // |web_contents| is the WebContents associated with this entry. - void UpdateEntry(NavigationEntryImpl* entry, WebContents* web_contents); + // |web_contents| is the WebContentsImpl associated with this entry. + void UpdateEntry(NavigationEntryImpl* entry, + WebContentsImpl* web_contents); SSLPolicyBackend* backend() const { return backend_; } - // Returns a security style describing an individual resource. Does - // not take into account any of the page- or host-level state such as - // mixed content or whether the host has run insecure content. - static SecurityStyle GetSecurityStyleForResource(const GURL& url, - const SSLStatus& ssl); - private: enum OnCertErrorInternalOptionsMask { OVERRIDABLE = 1 << 0, diff --git a/content/common/ssl_status_serialization.cc b/content/common/ssl_status_serialization.cc index 26cb1cd..364dba0 100644 --- a/content/common/ssl_status_serialization.cc +++ b/content/common/ssl_status_serialization.cc @@ -7,37 +7,24 @@ #include "base/logging.h" #include "base/pickle.h" -namespace { - -// Checks that an integer |security_style| is a valid SecurityStyle enum -// value. Returns true if valid, false otherwise. -bool CheckSecurityStyle(int security_style) { - switch (security_style) { - case content::SECURITY_STYLE_UNKNOWN: - case content::SECURITY_STYLE_UNAUTHENTICATED: - case content::SECURITY_STYLE_AUTHENTICATION_BROKEN: - case content::SECURITY_STYLE_WARNING: - case content::SECURITY_STYLE_AUTHENTICATED: - return true; - } - return false; -} - -} // namespace - namespace content { -std::string SerializeSecurityInfo(const SSLStatus& ssl_status) { +std::string SerializeSecurityInfo( + int cert_id, + net::CertStatus cert_status, + int security_bits, + int ssl_connection_status, + const SignedCertificateTimestampIDStatusList& + signed_certificate_timestamp_ids) { base::Pickle pickle; - pickle.WriteInt(ssl_status.security_style); - pickle.WriteInt(ssl_status.cert_id); - pickle.WriteUInt32(ssl_status.cert_status); - pickle.WriteInt(ssl_status.security_bits); - pickle.WriteInt(ssl_status.connection_status); - pickle.WriteInt(ssl_status.signed_certificate_timestamp_ids.size()); + pickle.WriteInt(cert_id); + pickle.WriteUInt32(cert_status); + pickle.WriteInt(security_bits); + pickle.WriteInt(ssl_connection_status); + pickle.WriteInt(signed_certificate_timestamp_ids.size()); for (SignedCertificateTimestampIDStatusList::const_iterator iter = - ssl_status.signed_certificate_timestamp_ids.begin(); - iter != ssl_status.signed_certificate_timestamp_ids.end(); ++iter) { + signed_certificate_timestamp_ids.begin(); + iter != signed_certificate_timestamp_ids.end(); ++iter) { pickle.WriteInt(iter->id); pickle.WriteUInt16(iter->status); } @@ -54,9 +41,8 @@ bool DeserializeSecurityInfo(const std::string& state, SSLStatus* ssl_status) { base::Pickle pickle(state.data(), static_cast<int>(state.size())); base::PickleIterator iter(pickle); - int security_style; int num_scts_to_read; - if (!iter.ReadInt(&security_style) || !iter.ReadInt(&ssl_status->cert_id) || + if (!iter.ReadInt(&ssl_status->cert_id) || !iter.ReadUInt32(&ssl_status->cert_status) || !iter.ReadInt(&ssl_status->security_bits) || !iter.ReadInt(&ssl_status->connection_status) || @@ -65,13 +51,6 @@ bool DeserializeSecurityInfo(const std::string& state, SSLStatus* ssl_status) { return false; } - if (!CheckSecurityStyle(security_style)) { - *ssl_status = SSLStatus(); - return false; - } - - ssl_status->security_style = static_cast<SecurityStyle>(security_style); - // Sanity check |security_bits|: the only allowed negative value is -1. if (ssl_status->security_bits < -1) { *ssl_status = SSLStatus(); diff --git a/content/common/ssl_status_serialization.h b/content/common/ssl_status_serialization.h index ed40623..08819d3 100644 --- a/content/common/ssl_status_serialization.h +++ b/content/common/ssl_status_serialization.h @@ -13,17 +13,20 @@ namespace content { -// Serializes the given security info. Does NOT include -// |ssl_status.content_status| in the serialized info. -CONTENT_EXPORT std::string SerializeSecurityInfo(const SSLStatus& ssl_status); +// Serializes the given security info. +CONTENT_EXPORT std::string SerializeSecurityInfo( + int cert_id, + net::CertStatus cert_status, + int security_bits, + int connection_status, + const SignedCertificateTimestampIDStatusList& + signed_certificate_timestamp_ids); // Deserializes the given security info into |ssl_status|. Note that -// this returns the |content_status| field with its default -// value. Returns true on success and false if the state couldn't be -// deserialized. If false, all fields in |ssl_status| will be set to -// their default values. Note that this function does not validate that -// the deserialized SSLStatus is internally consistent (e.g. that the -// |security_style| matches up with the rest of the fields). +// this returns the SecurityStyle and ContentStatus fields with default +// values. Returns true on success and false if the state couldn't be +// deserialized. If false, all fields in |ssl_status| will be set to their +// default values. bool CONTENT_EXPORT DeserializeSecurityInfo(const std::string& state, SSLStatus* ssl_status) WARN_UNUSED_RESULT; diff --git a/content/common/ssl_status_serialization_unittest.cc b/content/common/ssl_status_serialization_unittest.cc index f8b4852..f5595c2 100644 --- a/content/common/ssl_status_serialization_unittest.cc +++ b/content/common/ssl_status_serialization_unittest.cc @@ -13,28 +13,28 @@ namespace content { // deserialization and deserializes correctly. TEST(SSLStatusSerializationTest, DeserializeSerializedStatus) { // Serialize dummy data and test that it deserializes properly. - SSLStatus status; - status.security_style = SECURITY_STYLE_AUTHENTICATED; - status.cert_id = 1; - status.cert_status = net::CERT_STATUS_DATE_INVALID; - status.security_bits = 80; - status.connection_status = net::SSL_CONNECTION_VERSION_TLS1_2; + int cert_id = 1; + net::CertStatus cert_status = net::CERT_STATUS_DATE_INVALID; + int security_bits = 80; + int connection_status = net::SSL_CONNECTION_VERSION_TLS1_2; + SignedCertificateTimestampIDStatusList sct_list; SignedCertificateTimestampIDAndStatus sct(1, net::ct::SCT_STATUS_OK); - status.signed_certificate_timestamp_ids.push_back(sct); + sct_list.push_back(sct); - std::string serialized = SerializeSecurityInfo(status); + std::string serialized = SerializeSecurityInfo( + cert_id, cert_status, security_bits, connection_status, sct_list); SSLStatus deserialized; ASSERT_TRUE(DeserializeSecurityInfo(serialized, &deserialized)); - EXPECT_EQ(status.security_style, deserialized.security_style); - EXPECT_EQ(status.cert_id, deserialized.cert_id); - EXPECT_EQ(status.cert_status, deserialized.cert_status); - EXPECT_EQ(status.security_bits, deserialized.security_bits); - EXPECT_EQ(status.connection_status, deserialized.connection_status); - EXPECT_EQ(status.signed_certificate_timestamp_ids.size(), + EXPECT_EQ(cert_id, deserialized.cert_id); + EXPECT_EQ(cert_status, deserialized.cert_status); + EXPECT_EQ(security_bits, deserialized.security_bits); + EXPECT_EQ(connection_status, deserialized.connection_status); + EXPECT_EQ(sct_list.size(), deserialized.signed_certificate_timestamp_ids.size()); EXPECT_EQ(sct, deserialized.signed_certificate_timestamp_ids[0]); - // Test that |content_status| has the default (initialized) value. + // Test that the other fields have default (initialized) values. + EXPECT_EQ(SECURITY_STYLE_UNKNOWN, deserialized.security_style); EXPECT_EQ(SSLStatus::NORMAL_CONTENT, deserialized.content_status); } @@ -62,37 +62,18 @@ TEST(SSLStatusSerializationTest, DeserializeBogusStatus) { // Serialize a status with a bad |security_bits| value and test that // deserializing it fails. - SSLStatus status; - status.security_style = SECURITY_STYLE_AUTHENTICATED; - status.cert_id = 1; - status.cert_status = net::CERT_STATUS_DATE_INVALID; + int cert_id = 1; + net::CertStatus cert_status = net::CERT_STATUS_DATE_INVALID; // |security_bits| must be <-1. (-1 means the strength is unknown, and // |0 means the connection is not encrypted). - status.security_bits = -5; - status.connection_status = net::SSL_CONNECTION_VERSION_TLS1_2; + int security_bits = -5; + int connection_status = net::SSL_CONNECTION_VERSION_TLS1_2; + SignedCertificateTimestampIDStatusList sct_list; SignedCertificateTimestampIDAndStatus sct(1, net::ct::SCT_STATUS_OK); - status.signed_certificate_timestamp_ids.push_back(sct); + sct_list.push_back(sct); - std::string serialized = SerializeSecurityInfo(status); - ASSERT_FALSE(DeserializeSecurityInfo(serialized, &invalid_deserialized)); - - EXPECT_EQ(default_ssl_status.security_style, - invalid_deserialized.security_style); - EXPECT_EQ(default_ssl_status.cert_id, invalid_deserialized.cert_id); - EXPECT_EQ(default_ssl_status.cert_status, invalid_deserialized.cert_status); - EXPECT_EQ(default_ssl_status.security_bits, - invalid_deserialized.security_bits); - EXPECT_EQ(default_ssl_status.connection_status, - invalid_deserialized.connection_status); - EXPECT_EQ(default_ssl_status.content_status, - invalid_deserialized.content_status); - EXPECT_EQ(0u, invalid_deserialized.signed_certificate_timestamp_ids.size()); - - // Now serialize a status with a bad |security_style| value and test - // that deserializing fails. - status.security_bits = 128; - status.security_style = static_cast<SecurityStyle>(100); - serialized = SerializeSecurityInfo(status); + std::string serialized = SerializeSecurityInfo( + cert_id, cert_status, security_bits, connection_status, sct_list); ASSERT_FALSE(DeserializeSecurityInfo(serialized, &invalid_deserialized)); EXPECT_EQ(default_ssl_status.security_style, diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index 1eadf06..cfc1ec2 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc @@ -1953,10 +1953,10 @@ TEST_F(RenderViewImplTest, GetSSLStatusOfFrame) { SSLStatus ssl_status = view()->GetSSLStatusOfFrame(frame); EXPECT_FALSE(net::IsCertStatusError(ssl_status.cert_status)); - SSLStatus status; - status.cert_status = net::CERT_STATUS_ALL_ERRORS; - const_cast<blink::WebURLResponse&>(frame->dataSource()->response()) - .setSecurityInfo(SerializeSecurityInfo(status)); + const_cast<blink::WebURLResponse&>(frame->dataSource()->response()). + setSecurityInfo( + SerializeSecurityInfo(0, net::CERT_STATUS_ALL_ERRORS, 0, 0, + SignedCertificateTimestampIDStatusList())); ssl_status = view()->GetSSLStatusOfFrame(frame); EXPECT_TRUE(net::IsCertStatusError(ssl_status.cert_status)); } |