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 |