Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Unified Diff: net/http/transport_security_state_unittest.cc

Issue 2040513003: Implement Expect-Staple (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Don't report private certificates Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/http/transport_security_state_unittest.cc
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index 009c7d64991b9e612ade248f6d19b7194d054994..e83786b4c58e8c8d3f799fca8bd1df97afe3ef9f 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -26,6 +26,8 @@
#include "net/cert/cert_verifier.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/ct_policy_status.h"
+#include "net/cert/expect_staple_report.h"
+#include "net/cert/internal/test_helpers.h"
#include "net/cert/test_root_certs.h"
#include "net/cert/x509_cert_types.h"
#include "net/cert/x509_certificate.h"
@@ -78,7 +80,11 @@ const char* const kBadPath[] = {
nullptr,
};
-// A mock ReportSenderInterface that just remembers the latest report
+const char kOCSPPathPrefix[] = "net/data/parse_ocsp_unittest/";
+
+const base::TimeDelta& kAgeTenYears = base::TimeDelta::FromDays(3650);
estark 2016/06/15 23:51:47 ditto about naming for what is it rather than the
dadrian 2016/06/16 03:27:24 Done.
+
+// A mock ReportSender that just remembers the latest report
// URI and report to be sent.
class MockCertificateReportSender
: public TransportSecurityState::ReportSenderInterface {
@@ -1869,4 +1875,228 @@ TEST_F(TransportSecurityStateTest, ExpectCTReporter) {
EXPECT_EQ(GURL(kExpectCTStaticReportURI), reporter.report_uri());
}
+class MockExpectStapleReportSender : public MockCertificateReportSender {
+ public:
+ bool ReportSent() { return latest_report() != ""; }
+};
+
+class ExpectStapleTest : public TransportSecurityStateTest {
+ public:
+ void SetUp() override {
+ TransportSecurityStateTest::SetUp();
+ security_state_.SetReportSender(&report_sender_);
+ EnableStaticExpectStaple(&security_state_);
+ verify_time_ = base::Time::Now();
+ }
+
+ struct OCSPTest {
+ std::string response;
+ scoped_refptr<X509Certificate> certificate;
+ };
+
+ static bool LoadOCSPFromFile(std::string file_name, OCSPTest* ocsp) {
+ std::string ca_data;
+ std::string cert_data;
+ const PemBlockMapping mappings[] = {
+ {"OCSP RESPONSE", &ocsp->response},
+ {"CA CERTIFICATE", &ca_data},
+ {"CERTIFICATE", &cert_data},
+ };
+ std::string full_path = std::string(kOCSPPathPrefix) + file_name;
+ if (!ReadTestDataFromPemFile(full_path, mappings))
+ return false;
+
+ // Parse the server certificate
+ CertificateList server_cert_list =
+ X509Certificate::CreateCertificateListFromBytes(
+ cert_data.data(), cert_data.size(),
+ X509Certificate::FORMAT_SINGLE_CERTIFICATE);
+ ocsp->certificate = server_cert_list[0];
+ return true;
+ }
+
+ static void CheckExpectStapleReport(
+ const std::string& serialized_report,
+ const HostPortPair& host_port,
+ const X509Certificate& served_certificate_chain,
+ bool is_issued_by_known_root,
+ const ExpectStapleReport& report) {
+ std::unique_ptr<base::Value> value(
+ base::JSONReader::Read(serialized_report));
+ ASSERT_TRUE(value);
+ ASSERT_TRUE(value->IsType(base::Value::TYPE_DICTIONARY));
+
+ base::DictionaryValue* report_dict;
+ ASSERT_TRUE(value->GetAsDictionary(&report_dict));
+ std::string report_hostname;
+ EXPECT_TRUE(report_dict->GetString("hostname", &report_hostname));
+ EXPECT_EQ(host_port.host(), report_hostname);
+ int report_port;
+ EXPECT_TRUE(report_dict->GetInteger("port", &report_port));
+ EXPECT_EQ(host_port.port(), report_port);
+
+ // Check certificate chain.
+ const base::ListValue* report_served_certificate_chain = nullptr;
+ if (is_issued_by_known_root) {
+ ASSERT_TRUE(report_dict->GetList("served-certificate-chain",
+ &report_served_certificate_chain));
+ std::vector<std::string> pem_encoded_chain;
+ served_certificate_chain.GetPEMEncodedChain(&pem_encoded_chain);
+ ASSERT_EQ(pem_encoded_chain.size(),
+ report_served_certificate_chain->GetSize());
+ for (size_t i = 0; i < pem_encoded_chain.size(); i++) {
+ std::string cert_pem;
+ ASSERT_TRUE(report_served_certificate_chain->GetString(i, &cert_pem));
+ EXPECT_EQ(pem_encoded_chain[i], cert_pem);
+ }
+ } else {
+ EXPECT_FALSE(report_dict->GetList("served-certificate-chain",
+ &report_served_certificate_chain));
+ }
+
+ // Check stapled responses.
+ const base::ListValue* report_ocsp_responses = nullptr;
+ ASSERT_TRUE(report_dict->GetList("ocsp-responses", &report_ocsp_responses));
+ const auto& ocsp_responses = report.stapled_responses();
+ ASSERT_EQ(ocsp_responses.size(), report_ocsp_responses->GetSize());
+ for (size_t i = 0; i < ocsp_responses.size(); i++) {
+ const base::DictionaryValue* report_ocsp_response = nullptr;
+ report_ocsp_responses->GetDictionary(i, &report_ocsp_response);
+ bool is_date_valid;
+ ASSERT_TRUE(
+ report_ocsp_response->GetBoolean("is-date-valid", &is_date_valid));
+ EXPECT_EQ(ocsp_responses[i].is_date_valid, is_date_valid);
+ bool is_correct_certificate;
+ ASSERT_TRUE(report_ocsp_response->GetBoolean("is-correct-certificate",
+ &is_correct_certificate));
+ EXPECT_EQ(ocsp_responses[i].is_correct_certificate,
+ is_correct_certificate);
+ }
+ }
+
+ protected:
+ static bool SerializeExpectStapleReport(
+ const HostPortPair& host_port_pair,
+ const X509Certificate& unverified_certificate,
+ bool is_issued_by_known_root,
+ const ExpectStapleReport& report,
+ std::string* serialized_report) {
+ return TransportSecurityState::SerializeExpectStapleReport(
+ host_port_pair, unverified_certificate, is_issued_by_known_root, report,
+ serialized_report);
+ }
+
+ TransportSecurityState security_state_;
+ MockExpectStapleReportSender report_sender_;
+ base::Time verify_time_;
+};
+
+TEST_F(ExpectStapleTest, NoReportGoodResponse) {
+ OCSPTest ocsp_test;
+ ASSERT_TRUE(LoadOCSPFromFile("good_response.pem", &ocsp_test));
+ HostPortPair host_port(kExpectStapleStaticHostname, 443);
+ security_state_.CheckExpectStaple(host_port, *ocsp_test.certificate,
+ *ocsp_test.certificate, true, verify_time_,
+ kAgeTenYears, ocsp_test.response);
+ EXPECT_FALSE(report_sender_.ReportSent());
+};
+
+TEST_F(ExpectStapleTest, ReportMissingResponse) {
+ OCSPTest ocsp_test;
+ ASSERT_TRUE(LoadOCSPFromFile("missing_response.pem", &ocsp_test));
+ HostPortPair host_port(kExpectStapleStaticHostname, 443);
+ security_state_.CheckExpectStaple(host_port, *ocsp_test.certificate,
+ *ocsp_test.certificate, true, verify_time_,
+ kAgeTenYears, ocsp_test.response);
+ EXPECT_TRUE(report_sender_.ReportSent());
+};
+
+TEST_F(ExpectStapleTest, ReportOldResponse) {
+ OCSPTest ocsp_test;
+ ASSERT_TRUE(LoadOCSPFromFile("good_response.pem", &ocsp_test));
+ HostPortPair host_port(kExpectStapleStaticHostname, 443);
+ security_state_.CheckExpectStaple(
+ host_port, *ocsp_test.certificate, *ocsp_test.certificate, true,
+ verify_time_, base::TimeDelta::FromDays(7), ocsp_test.response);
+ EXPECT_TRUE(report_sender_.ReportSent());
+};
+
+TEST_F(ExpectStapleTest, RevokedResponse) {
+ OCSPTest ocsp_test;
+ ASSERT_TRUE(LoadOCSPFromFile("revoke_response.pem", &ocsp_test));
+ HostPortPair host_port(kExpectStapleStaticHostname, 443);
+ security_state_.CheckExpectStaple(host_port, *ocsp_test.certificate,
+ *ocsp_test.certificate, true, verify_time_,
+ kAgeTenYears, ocsp_test.response);
+ EXPECT_TRUE(report_sender_.ReportSent());
+};
+
+TEST_F(ExpectStapleTest, HasExtensions) {
+ OCSPTest ocsp_test;
+ ASSERT_TRUE(LoadOCSPFromFile("has_extension.pem", &ocsp_test));
+ HostPortPair host_port(kExpectStapleStaticHostname, 443);
+ security_state_.CheckExpectStaple(host_port, *ocsp_test.certificate,
+ *ocsp_test.certificate, true, verify_time_,
+ kAgeTenYears, ocsp_test.response);
+ EXPECT_FALSE(report_sender_.ReportSent());
+};
+
+TEST_F(ExpectStapleTest, MultipleResponse) {
+ OCSPTest ocsp_test;
+ ASSERT_TRUE(LoadOCSPFromFile("multiple_response.pem", &ocsp_test));
+ HostPortPair host_port(kExpectStapleStaticHostname, 443);
+ security_state_.CheckExpectStaple(host_port, *ocsp_test.certificate,
+ *ocsp_test.certificate, true, verify_time_,
+ kAgeTenYears, ocsp_test.response);
+ EXPECT_FALSE(report_sender_.ReportSent());
+};
+
+TEST_F(ExpectStapleTest, SerializeEmptyReport) {
+ OCSPTest ocsp_test;
+ ASSERT_TRUE(LoadOCSPFromFile("missing_response.pem", &ocsp_test));
+ HostPortPair host_port(kExpectStapleStaticHostname, 443);
+ std::unique_ptr<ExpectStapleReport> report =
+ ExpectStapleReport::FromRawOCSPResponse(ocsp_test.response, verify_time_,
+ kAgeTenYears,
+ *ocsp_test.certificate);
+ ASSERT_TRUE(report);
+ std::string serialized_report;
+ ASSERT_TRUE(SerializeExpectStapleReport(host_port, *ocsp_test.certificate,
+ true, *report, &serialized_report));
+ ASSERT_NO_FATAL_FAILURE(CheckExpectStapleReport(
+ serialized_report, host_port, *ocsp_test.certificate, true, *report));
+};
+
+TEST_F(ExpectStapleTest, SerializeMultipleResponses) {
+ OCSPTest ocsp_test;
+ ASSERT_TRUE(LoadOCSPFromFile("multiple_response.pem", &ocsp_test));
+ HostPortPair host_port(kExpectStapleStaticHostname, 443);
+ std::unique_ptr<ExpectStapleReport> report =
+ ExpectStapleReport::FromRawOCSPResponse(ocsp_test.response, verify_time_,
+ kAgeTenYears,
+ *ocsp_test.certificate);
+ ASSERT_TRUE(report);
+ std::string serialized_report;
+ ASSERT_TRUE(SerializeExpectStapleReport(host_port, *ocsp_test.certificate,
+ true, *report, &serialized_report));
+ ASSERT_NO_FATAL_FAILURE(CheckExpectStapleReport(
+ serialized_report, host_port, *ocsp_test.certificate, true, *report));
+};
+
+TEST_F(ExpectStapleTest, SerializeMultipleResponsesPrivateRoot) {
+ OCSPTest ocsp_test;
+ ASSERT_TRUE(LoadOCSPFromFile("multiple_response.pem", &ocsp_test));
+ HostPortPair host_port(kExpectStapleStaticHostname, 443);
+ std::unique_ptr<ExpectStapleReport> report =
+ ExpectStapleReport::FromRawOCSPResponse(ocsp_test.response, verify_time_,
+ kAgeTenYears,
+ *ocsp_test.certificate);
+ ASSERT_TRUE(report);
+ std::string serialized_report;
+ ASSERT_TRUE(SerializeExpectStapleReport(host_port, *ocsp_test.certificate,
+ false, *report, &serialized_report));
+ ASSERT_NO_FATAL_FAILURE(CheckExpectStapleReport(
+ serialized_report, host_port, *ocsp_test.certificate, false, *report));
+};
+
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698