diff options
author | jbroman <jbroman@chromium.org> | 2015-09-04 21:30:09 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-09-05 04:31:02 +0000 |
commit | 782fdafb6dcdbbc8221ef82f032e92de1d342237 (patch) | |
tree | a0794960b0c84c1c710bcef19b7a6617d75702fc /chrome/browser/ssl | |
parent | c249c9597b460a38507953a901942f4c09499c99 (diff) | |
download | chromium_src-782fdafb6dcdbbc8221ef82f032e92de1d342237.zip chromium_src-782fdafb6dcdbbc8221ef82f032e92de1d342237.tar.gz chromium_src-782fdafb6dcdbbc8221ef82f032e92de1d342237.tar.bz2 |
Revert of Componentize CertificateErrorReport and CertificateErrorReporter (patchset #12 id:210001 of https://codereview.chromium.org/1302423003/ )
Reason for revert:
Speculative revert to fix:
http://build.chromium.org/p/chromium.mac/builders/iOS_Device/builds/19626
http://build.chromium.org/p/chromium.mac/builders/iOS_Simulator_(dbg)
Original issue's description:
> Componentize CertificateErrorReport and CertificateErrorReporter
>
> BUG=516697
>
> Committed: https://crrev.com/93df64e3cdc40d6a30f7944e211e334ce1880cf7
> Cr-Commit-Position: refs/heads/master@{#347551}
TBR=droger@chromium.org,felt@chromium.org,blundell@chromium.org,mattm@chromium.org,thestig@chromium.org,davidben@chromium.org,estark@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=516697
Review URL: https://codereview.chromium.org/1332473002
Cr-Commit-Position: refs/heads/master@{#347555}
Diffstat (limited to 'chrome/browser/ssl')
-rw-r--r-- | chrome/browser/ssl/BUILD.gn | 12 | ||||
-rw-r--r-- | chrome/browser/ssl/captive_portal_blocking_page.cc | 8 | ||||
-rw-r--r-- | chrome/browser/ssl/cert_logger.proto | 92 | ||||
-rw-r--r-- | chrome/browser/ssl/cert_report_helper.cc | 11 | ||||
-rw-r--r-- | chrome/browser/ssl/cert_report_helper.h | 22 | ||||
-rw-r--r-- | chrome/browser/ssl/certificate_error_report.cc | 124 | ||||
-rw-r--r-- | chrome/browser/ssl/certificate_error_report.h | 71 | ||||
-rw-r--r-- | chrome/browser/ssl/certificate_error_report_unittest.cc | 137 | ||||
-rw-r--r-- | chrome/browser/ssl/certificate_reporting_test_utils.cc | 28 | ||||
-rw-r--r-- | chrome/browser/ssl/certificate_reporting_test_utils.h | 1 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_blocking_page.cc | 13 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_blocking_page.h | 2 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_browser_tests.cc | 4 |
13 files changed, 482 insertions, 43 deletions
diff --git a/chrome/browser/ssl/BUILD.gn b/chrome/browser/ssl/BUILD.gn new file mode 100644 index 0000000..88f00288 --- /dev/null +++ b/chrome/browser/ssl/BUILD.gn @@ -0,0 +1,12 @@ +# Copyright 2015 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. + +import("//third_party/protobuf/proto_library.gni") + +# GYP version: chrome/chrome_browser.gypi:cert_logger_proto +proto_library("cert_logger_proto") { + sources = [ + "cert_logger.proto", + ] +} diff --git a/chrome/browser/ssl/captive_portal_blocking_page.cc b/chrome/browser/ssl/captive_portal_blocking_page.cc index 31562da..6c460e1 100644 --- a/chrome/browser/ssl/captive_portal_blocking_page.cc +++ b/chrome/browser/ssl/captive_portal_blocking_page.cc @@ -17,7 +17,6 @@ #include "chrome/browser/ssl/ssl_cert_reporter.h" #include "chrome/common/pref_names.h" #include "components/captive_portal/captive_portal_detector.h" -#include "components/certificate_reporting/error_reporter.h" #include "components/url_formatter/url_formatter.h" #include "components/wifi/wifi_service.h" #include "content/public/browser/web_contents.h" @@ -63,8 +62,7 @@ CaptivePortalBlockingPage::CaptivePortalBlockingPage( if (ssl_cert_reporter) { cert_report_helper_.reset(new CertReportHelper( ssl_cert_reporter.Pass(), web_contents, request_url, ssl_info, - certificate_reporting::ErrorReport::INTERSTITIAL_CAPTIVE_PORTAL, false, - nullptr)); + CertificateErrorReport::INTERSTITIAL_CAPTIVE_PORTAL, false, nullptr)); } RecordUMA(SHOW_ALL); @@ -205,7 +203,7 @@ void CaptivePortalBlockingPage::OnProceed() { // Finish collecting information about invalid certificates, if the // user opted in to. cert_report_helper_->FinishCertCollection( - certificate_reporting::ErrorReport::USER_PROCEEDED); + CertificateErrorReport::USER_PROCEEDED); } } @@ -214,7 +212,7 @@ void CaptivePortalBlockingPage::OnDontProceed() { // Finish collecting information about invalid certificates, if the // user opted in to. cert_report_helper_->FinishCertCollection( - certificate_reporting::ErrorReport::USER_DID_NOT_PROCEED); + CertificateErrorReport::USER_DID_NOT_PROCEED); } // Need to explicity deny the certificate via the callback, otherwise memory diff --git a/chrome/browser/ssl/cert_logger.proto b/chrome/browser/ssl/cert_logger.proto new file mode 100644 index 0000000..bb11bf2 --- /dev/null +++ b/chrome/browser/ssl/cert_logger.proto @@ -0,0 +1,92 @@ +// Copyright 2015 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. +// +// This protobuffer is intended to store reports from Chrome users of +// certificate errors. A report will be sent from Chrome when it gets +// e.g. a certificate for google.com that chains up to a root CA not expected by +// Chrome for that origin, such as DigiNotar (compromised in July 2011), or +// other pinning errors such as a blacklisted cert in the chain, or +// (when opted in) other certificate validation errors like an expired +// cert. The report from the user will include the hostname being accessed, +// the full certificate chain (in PEM format), and the +// timestamp of when the client tried to access the site. A response is +// generated by the frontend and logged, including validation and error checking +// done on the client's input data. + +syntax = "proto2"; + +// Chrome requires this. +option optimize_for = LITE_RUNTIME; + +// Protocol types + +message CertLoggerInterstitialInfo { + // The different reasons that an SSL warning interstitial could be shown to + // a user. + enum InterstitialReason { + UNKNOWN_INTERSTITIAL_REASON = 0; + // A standard SSL interstitial + INTERSTITIAL_SSL = 1; + // An interstitial alerting the user that they are in a captive portal + INTERSTITIAL_CAPTIVE_PORTAL = 2; + // An interstitial telling the user to update their system clock + INTERSTITIAL_CLOCK = 3; + } + + // The type of interstitial that was shown + optional InterstitialReason interstitial_reason = 1; + // True if the user clicked through to the offending website + optional bool user_proceeded = 2; + // True if the user was shown an option to click through + optional bool overridable = 3; +} + +message CertLoggerRequest { + // The hostname being accessed (required as the cert could be valid for + // multiple hosts, e.g. a wildcard or a SubjectAltName. + required string hostname = 1; + // The certificate chain as a series of PEM-encoded certificates, including + // intermediates but not necessarily the root. + required string cert_chain = 2; + // The time (in usec since the epoch) when the client attempted to access the + // site generating the pinning error. + required int64 time_usec = 3; + // public_key_hash contains the string forms of the hashes calculated for + // the chain. (I.e. "sha1/<base64 data>".) + repeated string public_key_hash = 4; + // pin contains the string forms of the pins that were matched against for + // this host. + repeated string pin = 5; + + enum CertError { + UNKNOWN_CERT_ERROR = 0; + ERR_CERT_REVOKED = 1; + ERR_CERT_INVALID = 2; + ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN = 3; + ERR_CERT_AUTHORITY_INVALID = 4; + ERR_CERT_COMMON_NAME_INVALID = 5; + ERR_CERT_NAME_CONSTRAINT_VIOLATION = 6; + ERR_CERT_WEAK_SIGNATURE_ALGORITHM = 7; + ERR_CERT_WEAK_KEY = 8; + ERR_CERT_DATE_INVALID = 9; + ERR_CERT_VALIDITY_TOO_LONG = 10; + ERR_CERT_UNABLE_TO_CHECK_REVOCATION = 11; + ERR_CERT_NO_REVOCATION_MECHANISM = 12; + ERR_CERT_NON_UNIQUE_NAME = 13; + }; + + // Certificate errors encountered (if any) when validating this + // certificate chain. + repeated CertError cert_error = 6; + + // Information about the interstitial that was shown to the user for + // this certificate error. + optional CertLoggerInterstitialInfo interstitial_info = 7; + + // The unverified certificate chain as received by the client, as a + // series of PEM-encoded certificates. Can be different than + // |cert_chain|, which is the chain the client built during + // verification. + optional string unverified_cert_chain = 8; +};
\ No newline at end of file diff --git a/chrome/browser/ssl/cert_report_helper.cc b/chrome/browser/ssl/cert_report_helper.cc index 2e3e120..2f85c84 100644 --- a/chrome/browser/ssl/cert_report_helper.cc +++ b/chrome/browser/ssl/cert_report_helper.cc @@ -34,7 +34,7 @@ CertReportHelper::CertReportHelper( content::WebContents* web_contents, const GURL& request_url, const net::SSLInfo& ssl_info, - certificate_reporting::ErrorReport::InterstitialReason interstitial_reason, + CertificateErrorReport::InterstitialReason interstitial_reason, bool overridable, security_interstitials::MetricsHelper* metrics_helper) : ssl_cert_reporter_(ssl_cert_reporter.Pass()), @@ -75,7 +75,7 @@ void CertReportHelper::PopulateExtendedReportingOption( } void CertReportHelper::FinishCertCollection( - certificate_reporting::ErrorReport::ProceedDecision user_proceeded) { + CertificateErrorReport::ProceedDecision user_proceeded) { if (!ShouldShowCertificateReporterCheckbox()) return; @@ -91,13 +91,12 @@ void CertReportHelper::FinishCertCollection( return; std::string serialized_report; - certificate_reporting::ErrorReport report(request_url_.host(), ssl_info_); + CertificateErrorReport report(request_url_.host(), ssl_info_); report.SetInterstitialInfo( interstitial_reason_, user_proceeded, - overridable_ - ? certificate_reporting::ErrorReport::INTERSTITIAL_OVERRIDABLE - : certificate_reporting::ErrorReport::INTERSTITIAL_NOT_OVERRIDABLE); + overridable_ ? CertificateErrorReport::INTERSTITIAL_OVERRIDABLE + : CertificateErrorReport::INTERSTITIAL_NOT_OVERRIDABLE); if (!report.Serialize(&serialized_report)) { LOG(ERROR) << "Failed to serialize certificate report."; diff --git a/chrome/browser/ssl/cert_report_helper.h b/chrome/browser/ssl/cert_report_helper.h index 3e63405..6bebaff 100644 --- a/chrome/browser/ssl/cert_report_helper.h +++ b/chrome/browser/ssl/cert_report_helper.h @@ -8,7 +8,7 @@ #include <string> #include "chrome/browser/interstitials/security_interstitial_page.h" -#include "components/certificate_reporting/error_report.h" +#include "chrome/browser/ssl/certificate_error_report.h" #include "net/ssl/ssl_info.h" #include "url/gurl.h" @@ -36,14 +36,14 @@ class CertReportHelper { static const char kFinchGroupDontShowDontSend[]; static const char kFinchParamName[]; - CertReportHelper(scoped_ptr<SSLCertReporter> ssl_cert_reporter, - content::WebContents* web_contents, - const GURL& request_url, - const net::SSLInfo& ssl_info, - certificate_reporting::ErrorReport::InterstitialReason - interstitial_reason, - bool overridable, - security_interstitials::MetricsHelper* metrics_helper); + CertReportHelper( + scoped_ptr<SSLCertReporter> ssl_cert_reporter, + content::WebContents* web_contents, + const GURL& request_url, + const net::SSLInfo& ssl_info, + CertificateErrorReport::InterstitialReason interstitial_reason, + bool overridable, + security_interstitials::MetricsHelper* metrics_helper); virtual ~CertReportHelper(); @@ -55,7 +55,7 @@ class CertReportHelper { // server. |user_proceeded| indicates whether the user clicked through // the interstitial or not, and will be included in the report. void FinishCertCollection( - certificate_reporting::ErrorReport::ProceedDecision user_proceeded); + CertificateErrorReport::ProceedDecision user_proceeded); // Allows tests to inject a mock reporter. void SetSSLCertReporterForTesting( @@ -83,7 +83,7 @@ class CertReportHelper { // The SSLInfo used in this helper's report. const net::SSLInfo ssl_info_; // The reason for the interstitial, included in this helper's report. - certificate_reporting::ErrorReport::InterstitialReason interstitial_reason_; + CertificateErrorReport::InterstitialReason interstitial_reason_; // True if the user was given the option to proceed through the // certificate chain error being reported. bool overridable_; diff --git a/chrome/browser/ssl/certificate_error_report.cc b/chrome/browser/ssl/certificate_error_report.cc new file mode 100644 index 0000000..49ca918 --- /dev/null +++ b/chrome/browser/ssl/certificate_error_report.cc @@ -0,0 +1,124 @@ +// Copyright 2015 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 "chrome/browser/ssl/certificate_error_report.h" + +#include <vector> + +#include "base/stl_util.h" +#include "base/strings/string_util.h" +#include "base/time/time.h" +#include "chrome/browser/ssl/cert_logger.pb.h" +#include "net/cert/cert_status_flags.h" +#include "net/cert/x509_certificate.h" +#include "net/ssl/ssl_info.h" + +namespace { + +void AddCertStatusToReportErrors(net::CertStatus cert_status, + CertLoggerRequest* report) { +#define COPY_CERT_STATUS(error) RENAME_CERT_STATUS(error, CERT_##error) +#define RENAME_CERT_STATUS(status_error, logger_error) \ + if (cert_status & net::CERT_STATUS_##status_error) \ + report->add_cert_error(CertLoggerRequest::ERR_##logger_error); + + COPY_CERT_STATUS(REVOKED) + COPY_CERT_STATUS(INVALID) + RENAME_CERT_STATUS(PINNED_KEY_MISSING, SSL_PINNED_KEY_NOT_IN_CERT_CHAIN) + COPY_CERT_STATUS(AUTHORITY_INVALID) + COPY_CERT_STATUS(COMMON_NAME_INVALID) + COPY_CERT_STATUS(NON_UNIQUE_NAME) + COPY_CERT_STATUS(NAME_CONSTRAINT_VIOLATION) + COPY_CERT_STATUS(WEAK_SIGNATURE_ALGORITHM) + COPY_CERT_STATUS(WEAK_KEY) + COPY_CERT_STATUS(DATE_INVALID) + COPY_CERT_STATUS(VALIDITY_TOO_LONG) + COPY_CERT_STATUS(UNABLE_TO_CHECK_REVOCATION) + COPY_CERT_STATUS(NO_REVOCATION_MECHANISM) + +#undef RENAME_CERT_STATUS +#undef COPY_CERT_STATUS +} + +bool CertificateChainToString(scoped_refptr<net::X509Certificate> cert, + std::string* result) { + std::vector<std::string> pem_encoded_chain; + if (!cert->GetPEMEncodedChain(&pem_encoded_chain)) + return false; + + *result = base::JoinString(pem_encoded_chain, ""); + return true; +} + +} // namespace + +CertificateErrorReport::CertificateErrorReport() + : cert_report_(new CertLoggerRequest()) { +} + +CertificateErrorReport::CertificateErrorReport(const std::string& hostname, + const net::SSLInfo& ssl_info) + : cert_report_(new CertLoggerRequest()) { + base::Time now = base::Time::Now(); + cert_report_->set_time_usec(now.ToInternalValue()); + cert_report_->set_hostname(hostname); + + if (!CertificateChainToString(ssl_info.cert, + cert_report_->mutable_cert_chain())) { + LOG(ERROR) << "Could not get PEM encoded chain."; + } + + if (ssl_info.unverified_cert && + !CertificateChainToString( + ssl_info.unverified_cert, + cert_report_->mutable_unverified_cert_chain())) { + LOG(ERROR) << "Could not get PEM encoded unverified certificate chain."; + } + + cert_report_->add_pin(ssl_info.pinning_failure_log); + + AddCertStatusToReportErrors(ssl_info.cert_status, cert_report_.get()); +} + +CertificateErrorReport::~CertificateErrorReport() { +} + +bool CertificateErrorReport::InitializeFromString( + const std::string& serialized_report) { + return cert_report_->ParseFromString(serialized_report); +} + +bool CertificateErrorReport::Serialize(std::string* output) const { + return cert_report_->SerializeToString(output); +} + +void CertificateErrorReport::SetInterstitialInfo( + const InterstitialReason& interstitial_reason, + const ProceedDecision& proceed_decision, + const Overridable& overridable) { + CertLoggerInterstitialInfo* interstitial_info = + cert_report_->mutable_interstitial_info(); + + switch (interstitial_reason) { + case INTERSTITIAL_SSL: + interstitial_info->set_interstitial_reason( + CertLoggerInterstitialInfo::INTERSTITIAL_SSL); + break; + case INTERSTITIAL_CAPTIVE_PORTAL: + interstitial_info->set_interstitial_reason( + CertLoggerInterstitialInfo::INTERSTITIAL_CAPTIVE_PORTAL); + break; + case INTERSTITIAL_CLOCK: + interstitial_info->set_interstitial_reason( + CertLoggerInterstitialInfo::INTERSTITIAL_CLOCK); + break; + } + + interstitial_info->set_user_proceeded(proceed_decision == USER_PROCEEDED); + interstitial_info->set_overridable(overridable == INTERSTITIAL_OVERRIDABLE); +} + +const std::string& CertificateErrorReport::hostname() const { + return cert_report_->hostname(); +} diff --git a/chrome/browser/ssl/certificate_error_report.h b/chrome/browser/ssl/certificate_error_report.h new file mode 100644 index 0000000..61830dc --- /dev/null +++ b/chrome/browser/ssl/certificate_error_report.h @@ -0,0 +1,71 @@ +// Copyright 2015 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 CHROME_BROWSER_SSL_CERTIFICATE_ERROR_REPORT_H_ +#define CHROME_BROWSER_SSL_CERTIFICATE_ERROR_REPORT_H_ + +#include <string> + +#include "base/memory/scoped_ptr.h" + +namespace net { +class SSLInfo; +} // namespace net + +class CertLoggerRequest; + +// This class builds and serializes reports for invalid SSL certificate +// chains, intended to be sent with +// chrome_browser_net::CertificateErrorReporter. +class CertificateErrorReport { + public: + // Describes the type of interstitial that the user was shown for the + // error that this report represents. Gets mapped to + // |CertLoggerInterstitialInfo::InterstitialReason|. + enum InterstitialReason { + INTERSTITIAL_SSL, + INTERSTITIAL_CAPTIVE_PORTAL, + INTERSTITIAL_CLOCK + }; + + // Whether the user clicked through the interstitial or not. + enum ProceedDecision { USER_PROCEEDED, USER_DID_NOT_PROCEED }; + + // Whether the user was shown an option to click through the + // interstitial. + enum Overridable { INTERSTITIAL_OVERRIDABLE, INTERSTITIAL_NOT_OVERRIDABLE }; + + // Constructs an empty report. + CertificateErrorReport(); + + // Constructs a report for the given |hostname| using the SSL + // properties in |ssl_info|. + CertificateErrorReport(const std::string& hostname, + const net::SSLInfo& ssl_info); + + ~CertificateErrorReport(); + + // Initializes an empty report by parsing the given serialized + // report. |serialized_report| should be a serialized + // CertLoggerRequest protobuf. Returns true if the report could be + // successfully parsed and false otherwise. + bool InitializeFromString(const std::string& serialized_report); + + // Serializes the report. The output will be a serialized + // CertLoggerRequest protobuf. Returns true if the serialization was + // successful and false otherwise. + bool Serialize(std::string* output) const; + + void SetInterstitialInfo(const InterstitialReason& interstitial_reason, + const ProceedDecision& proceed_decision, + const Overridable& overridable); + + // Gets the hostname to which this report corresponds. + const std::string& hostname() const; + + private: + scoped_ptr<CertLoggerRequest> cert_report_; +}; + +#endif // CHROME_BROWSER_SSL_CERTIFICATE_ERROR_REPORT_H_ diff --git a/chrome/browser/ssl/certificate_error_report_unittest.cc b/chrome/browser/ssl/certificate_error_report_unittest.cc new file mode 100644 index 0000000..5c712ee --- /dev/null +++ b/chrome/browser/ssl/certificate_error_report_unittest.cc @@ -0,0 +1,137 @@ +// Copyright 2015 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 "chrome/browser/ssl/certificate_error_report.h" + +#include <set> +#include <string> + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/path_service.h" +#include "chrome/browser/ssl/cert_logger.pb.h" +#include "chrome/common/chrome_paths.h" +#include "net/base/test_data_directory.h" +#include "net/cert/cert_status_flags.h" +#include "net/ssl/ssl_info.h" +#include "net/test/cert_test_util.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using net::SSLInfo; +using testing::UnorderedElementsAre; + +namespace { + +const char kDummyHostname[] = "dummy.hostname.com"; +const char kDummyFailureLog[] = "dummy failure log"; +const char kTestCertFilename[] = "test_mail_google_com.pem"; + +const net::CertStatus kCertStatus = + net::CERT_STATUS_COMMON_NAME_INVALID | net::CERT_STATUS_REVOKED; + +const CertLoggerRequest::CertError kFirstReportedCertError = + CertLoggerRequest::ERR_CERT_COMMON_NAME_INVALID; +const CertLoggerRequest::CertError kSecondReportedCertError = + CertLoggerRequest::ERR_CERT_REVOKED; + +// Whether to include an unverified certificate chain in the test +// SSLInfo. In production code, an unverified cert chain will not be +// present if the resource was loaded from cache. +enum UnverifiedCertChainStatus { + INCLUDE_UNVERIFIED_CERT_CHAIN, + EXCLUDE_UNVERIFIED_CERT_CHAIN +}; + +SSLInfo GetTestSSLInfo(UnverifiedCertChainStatus unverified_cert_chain_status) { + SSLInfo info; + info.cert = + net::ImportCertFromFile(net::GetTestCertsDirectory(), kTestCertFilename); + if (unverified_cert_chain_status == INCLUDE_UNVERIFIED_CERT_CHAIN) { + info.unverified_cert = net::ImportCertFromFile(net::GetTestCertsDirectory(), + kTestCertFilename); + } + info.is_issued_by_known_root = true; + info.cert_status = kCertStatus; + info.pinning_failure_log = kDummyFailureLog; + return info; +} + +std::string GetPEMEncodedChain() { + base::FilePath cert_path = + net::GetTestCertsDirectory().AppendASCII(kTestCertFilename); + std::string cert_data; + EXPECT_TRUE(base::ReadFileToString(cert_path, &cert_data)); + return cert_data; +} + +// Test that a serialized CertificateErrorReport can be deserialized as +// a CertLoggerRequest protobuf (which is the format that the receiving +// server expects it in) with the right data in it. +TEST(CertificateErrorReportTest, SerializedReportAsProtobuf) { + std::string serialized_report; + CertificateErrorReport report(kDummyHostname, + GetTestSSLInfo(INCLUDE_UNVERIFIED_CERT_CHAIN)); + ASSERT_TRUE(report.Serialize(&serialized_report)); + + CertLoggerRequest deserialized_report; + ASSERT_TRUE(deserialized_report.ParseFromString(serialized_report)); + EXPECT_EQ(kDummyHostname, deserialized_report.hostname()); + EXPECT_EQ(GetPEMEncodedChain(), deserialized_report.cert_chain()); + EXPECT_EQ(GetPEMEncodedChain(), deserialized_report.unverified_cert_chain()); + EXPECT_EQ(1, deserialized_report.pin().size()); + EXPECT_EQ(kDummyFailureLog, deserialized_report.pin().Get(0)); + + EXPECT_THAT( + deserialized_report.cert_error(), + UnorderedElementsAre(kFirstReportedCertError, kSecondReportedCertError)); +} + +TEST(CertificateErrorReportTest, + SerializedReportAsProtobufWithInterstitialInfo) { + std::string serialized_report; + // Use EXCLUDE_UNVERIFIED_CERT_CHAIN here to exercise the code path + // where SSLInfo does not contain the unverified cert chain. (The test + // above exercises the path where it does.) + CertificateErrorReport report(kDummyHostname, + GetTestSSLInfo(EXCLUDE_UNVERIFIED_CERT_CHAIN)); + + report.SetInterstitialInfo(CertificateErrorReport::INTERSTITIAL_CLOCK, + CertificateErrorReport::USER_PROCEEDED, + CertificateErrorReport::INTERSTITIAL_OVERRIDABLE); + + ASSERT_TRUE(report.Serialize(&serialized_report)); + + CertLoggerRequest deserialized_report; + ASSERT_TRUE(deserialized_report.ParseFromString(serialized_report)); + EXPECT_EQ(kDummyHostname, deserialized_report.hostname()); + EXPECT_EQ(GetPEMEncodedChain(), deserialized_report.cert_chain()); + EXPECT_EQ(std::string(), deserialized_report.unverified_cert_chain()); + EXPECT_EQ(1, deserialized_report.pin().size()); + EXPECT_EQ(kDummyFailureLog, deserialized_report.pin().Get(0)); + + EXPECT_EQ(CertLoggerInterstitialInfo::INTERSTITIAL_CLOCK, + deserialized_report.interstitial_info().interstitial_reason()); + EXPECT_EQ(true, deserialized_report.interstitial_info().user_proceeded()); + EXPECT_EQ(true, deserialized_report.interstitial_info().overridable()); + + EXPECT_THAT( + deserialized_report.cert_error(), + UnorderedElementsAre(kFirstReportedCertError, kSecondReportedCertError)); +} + +// Test that a serialized report can be parsed. +TEST(CertificateErrorReportTest, ParseSerializedReport) { + std::string serialized_report; + CertificateErrorReport report(kDummyHostname, + GetTestSSLInfo(EXCLUDE_UNVERIFIED_CERT_CHAIN)); + EXPECT_EQ(kDummyHostname, report.hostname()); + ASSERT_TRUE(report.Serialize(&serialized_report)); + + CertificateErrorReport parsed; + ASSERT_TRUE(parsed.InitializeFromString(serialized_report)); + EXPECT_EQ(report.hostname(), parsed.hostname()); +} + +} // namespace diff --git a/chrome/browser/ssl/certificate_reporting_test_utils.cc b/chrome/browser/ssl/certificate_reporting_test_utils.cc index b99a36e..b61340e 100644 --- a/chrome/browser/ssl/certificate_reporting_test_utils.cc +++ b/chrome/browser/ssl/certificate_reporting_test_utils.cc @@ -16,22 +16,22 @@ #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/safe_browsing/ui_manager.h" #include "chrome/browser/ssl/cert_report_helper.h" +#include "chrome/browser/ssl/certificate_error_report.h" #include "chrome/browser/ssl/ssl_cert_reporter.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/pref_names.h" -#include "components/certificate_reporting/error_report.h" -#include "components/certificate_reporting/error_reporter.h" #include "components/variations/variations_associated_data.h" #include "net/url_request/certificate_report_sender.h" #include "net/url_request/url_request_context.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" +using chrome_browser_net::CertificateErrorReporter; + namespace { -void SetMockReporter( - SafeBrowsingService* safe_browsing_service, - scoped_ptr<certificate_reporting::ErrorReporter> reporter) { +void SetMockReporter(SafeBrowsingService* safe_browsing_service, + scoped_ptr<CertificateErrorReporter> reporter) { safe_browsing_service->ping_manager()->SetCertificateErrorReporterForTesting( reporter.Pass()); } @@ -80,14 +80,14 @@ namespace certificate_reporting_test_utils { // most recent hostname for which an extended reporting report would // have been sent over the network. class CertificateReportingTest::MockReporter - : public certificate_reporting::ErrorReporter { + : public chrome_browser_net::CertificateErrorReporter { public: MockReporter( net::URLRequestContext* request_context, const GURL& upload_url, net::CertificateReportSender::CookiesPreference cookies_preference); - // ErrorReporter implementation. + // CertificateErrorReporter implementation. void SendExtendedReportingReport( const std::string& serialized_report) override; @@ -107,13 +107,13 @@ CertificateReportingTest::MockReporter::MockReporter( net::URLRequestContext* request_context, const GURL& upload_url, net::CertificateReportSender::CookiesPreference cookies_preference) - : certificate_reporting::ErrorReporter(request_context, - upload_url, - cookies_preference) {} + : CertificateErrorReporter(request_context, + upload_url, + cookies_preference) {} void CertificateReportingTest::MockReporter::SendExtendedReportingReport( const std::string& serialized_report) { - certificate_reporting::ErrorReport report; + CertificateErrorReport report; ASSERT_TRUE(report.InitializeFromString(serialized_report)); latest_hostname_reported_ = report.hostname(); } @@ -134,9 +134,9 @@ void CertificateReportingTest::SetUpMockReporter() { content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, - base::Bind(SetMockReporter, safe_browsing_service, - base::Passed(scoped_ptr<certificate_reporting::ErrorReporter>( - reporter_)))); + base::Bind( + SetMockReporter, safe_browsing_service, + base::Passed(scoped_ptr<CertificateErrorReporter>(reporter_)))); } const std::string& CertificateReportingTest::GetLatestHostnameReported() const { diff --git a/chrome/browser/ssl/certificate_reporting_test_utils.h b/chrome/browser/ssl/certificate_reporting_test_utils.h index 29cd62b..81d3d91 100644 --- a/chrome/browser/ssl/certificate_reporting_test_utils.h +++ b/chrome/browser/ssl/certificate_reporting_test_utils.h @@ -7,6 +7,7 @@ #include <string> +#include "chrome/browser/net/certificate_error_reporter.h" #include "chrome/test/base/in_process_browser_test.h" class Browser; diff --git a/chrome/browser/ssl/ssl_blocking_page.cc b/chrome/browser/ssl/ssl_blocking_page.cc index 97148f3..61ca1ac 100644 --- a/chrome/browser/ssl/ssl_blocking_page.cc +++ b/chrome/browser/ssl/ssl_blocking_page.cc @@ -25,6 +25,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_preferences_util.h" #include "chrome/browser/ssl/cert_report_helper.h" +#include "chrome/browser/ssl/certificate_error_report.h" #include "chrome/browser/ssl/ssl_cert_reporter.h" #include "chrome/browser/ssl/ssl_error_classification.h" #include "chrome/browser/ssl/ssl_error_info.h" @@ -149,10 +150,10 @@ SSLBlockingPage::SSLBlockingPage(content::WebContents* web_contents, metrics_helper()->RecordUserInteraction( security_interstitials::MetricsHelper::TOTAL_VISITS); - cert_report_helper_.reset(new CertReportHelper( - ssl_cert_reporter.Pass(), web_contents, request_url, ssl_info, - certificate_reporting::ErrorReport::INTERSTITIAL_SSL, overridable_, - metrics_helper())); + cert_report_helper_.reset( + new CertReportHelper(ssl_cert_reporter.Pass(), web_contents, request_url, + ssl_info, CertificateErrorReport::INTERSTITIAL_SSL, + overridable_, metrics_helper())); ssl_error_classification_.reset(new SSLErrorClassification( web_contents, @@ -383,7 +384,7 @@ void SSLBlockingPage::OnProceed() { // Finish collecting information about invalid certificates, if the // user opted in to. cert_report_helper_->FinishCertCollection( - certificate_reporting::ErrorReport::USER_PROCEEDED); + CertificateErrorReport::USER_PROCEEDED); RecordSSLExpirationPageEventState( expired_but_previously_allowed_, true, overridable_); @@ -398,7 +399,7 @@ void SSLBlockingPage::OnDontProceed() { // Finish collecting information about invalid certificates, if the // user opted in to. cert_report_helper_->FinishCertCollection( - certificate_reporting::ErrorReport::USER_DID_NOT_PROCEED); + CertificateErrorReport::USER_DID_NOT_PROCEED); RecordSSLExpirationPageEventState( expired_but_previously_allowed_, false, overridable_); diff --git a/chrome/browser/ssl/ssl_blocking_page.h b/chrome/browser/ssl/ssl_blocking_page.h index 0c45e31..f096278 100644 --- a/chrome/browser/ssl/ssl_blocking_page.h +++ b/chrome/browser/ssl/ssl_blocking_page.h @@ -14,8 +14,8 @@ #include "base/time/time.h" #include "chrome/browser/interstitials/security_interstitial_page.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ssl/certificate_error_report.h" #include "chrome/browser/ssl/ssl_cert_reporter.h" -#include "components/certificate_reporting/error_report.h" #include "net/ssl/ssl_info.h" #include "url/gurl.h" diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc index be0c1bb..d817a77 100644 --- a/chrome/browser/ssl/ssl_browser_tests.cc +++ b/chrome/browser/ssl/ssl_browser_tests.cc @@ -21,10 +21,13 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/interstitials/security_interstitial_page_test_utils.h" +#include "chrome/browser/net/certificate_error_reporter.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ssl/bad_clock_blocking_page.h" +#include "chrome/browser/ssl/cert_logger.pb.h" #include "chrome/browser/ssl/cert_report_helper.h" #include "chrome/browser/ssl/cert_verifier_browser_test.h" +#include "chrome/browser/ssl/certificate_error_report.h" #include "chrome/browser/ssl/certificate_reporting_test_utils.h" #include "chrome/browser/ssl/chrome_ssl_host_state_delegate.h" #include "chrome/browser/ssl/common_name_mismatch_handler.h" @@ -83,6 +86,7 @@ using base::ASCIIToUTF16; using chrome_browser_interstitials::SecurityInterstitialIDNTest; +using chrome_browser_net::CertificateErrorReporter; using content::InterstitialPage; using content::NavigationController; using content::NavigationEntry; |