summaryrefslogtreecommitdiffstats
path: root/chromium/net/cert/multi_log_ct_verifier_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/cert/multi_log_ct_verifier_unittest.cc')
-rw-r--r--chromium/net/cert/multi_log_ct_verifier_unittest.cc174
1 files changed, 150 insertions, 24 deletions
diff --git a/chromium/net/cert/multi_log_ct_verifier_unittest.cc b/chromium/net/cert/multi_log_ct_verifier_unittest.cc
index b1d1aa889e8..c2ae25e3073 100644
--- a/chromium/net/cert/multi_log_ct_verifier_unittest.cc
+++ b/chromium/net/cert/multi_log_ct_verifier_unittest.cc
@@ -8,6 +8,10 @@
#include "base/file_util.h"
#include "base/files/file_path.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_samples.h"
+#include "base/metrics/statistics_recorder.h"
+#include "base/values.h"
#include "net/base/capturing_net_log.h"
#include "net/base/net_errors.h"
#include "net/base/net_log.h"
@@ -16,6 +20,7 @@
#include "net/cert/ct_serialization.h"
#include "net/cert/ct_verify_result.h"
#include "net/cert/pem_tokenizer.h"
+#include "net/cert/sct_status_flags.h"
#include "net/cert/signed_certificate_timestamp.h"
#include "net/cert/x509_certificate.h"
#include "net/test/cert_test_util.h"
@@ -27,6 +32,8 @@ namespace net {
namespace {
const char kLogDescription[] = "somelog";
+const char kSCTCountHistogram[] =
+ "Net.CertificateTransparency.SCTsPerConnection";
class MultiLogCTVerifierTest : public ::testing::Test {
public:
@@ -42,6 +49,12 @@ class MultiLogCTVerifierTest : public ::testing::Test {
der_test_cert.data(),
der_test_cert.length());
ASSERT_TRUE(chain_);
+
+ embedded_sct_chain_ =
+ CreateCertificateChainFromFile(GetTestCertsDirectory(),
+ "ct-test-embedded-cert.pem",
+ X509Certificate::FORMAT_AUTO);
+ ASSERT_TRUE(embedded_sct_chain_);
}
bool CheckForSingleVerifiedSCTInResult(const ct::CTVerifyResult& result) {
@@ -64,45 +77,121 @@ class MultiLogCTVerifierTest : public ::testing::Test {
if (entries.size() != 2)
return false;
- const CapturingNetLog::CapturedEntry& received(entries[0]);
+ const CapturingNetLog::CapturedEntry& received = entries[0];
std::string embedded_scts;
if (!received.GetStringValue("embedded_scts", &embedded_scts))
return false;
if (embedded_scts.empty())
return false;
- //XXX(eranm): entries[1] is the NetLog message with the checked SCTs.
- //When CapturedEntry has methods to get a dictionary, rather than just
- //a string, add more checks here.
+ const CapturingNetLog::CapturedEntry& parsed = entries[1];
+ base::ListValue* verified_scts;
+ if (!parsed.GetListValue("verified_scts", &verified_scts) ||
+ verified_scts->GetSize() != 1) {
+ return false;
+ }
+
+ base::DictionaryValue* the_sct;
+ if (!verified_scts->GetDictionary(0, &the_sct))
+ return false;
+
+ std::string origin;
+ if (!the_sct->GetString("origin", &origin))
+ return false;
+ if (origin != "embedded_in_certificate")
+ return false;
+
+ base::ListValue* other_scts;
+ if (!parsed.GetListValue("invalid_scts", &other_scts) ||
+ !other_scts->empty()) {
+ return false;
+ }
+
+ if (!parsed.GetListValue("unknown_logs_scts", &other_scts) ||
+ !other_scts->empty()) {
+ return false;
+ }
return true;
}
+ std::string GetSCTListWithInvalidSCT() {
+ std::string sct(ct::GetTestSignedCertificateTimestamp());
+
+ // Change a byte inside the Log ID part of the SCT so it does
+ // not match the log used in the tests
+ sct[15] = 't';
+
+ std::string sct_list;
+ ct::EncodeSCTListForTesting(sct, &sct_list);
+ return sct_list;
+ }
+
+ bool VerifySinglePrecertificateChain(scoped_refptr<X509Certificate> chain,
+ const BoundNetLog& bound_net_log,
+ ct::CTVerifyResult* result) {
+ return verifier_->Verify(
+ chain, std::string(), std::string(), result, bound_net_log) ==
+ OK;
+ }
+
+ bool VerifySinglePrecertificateChain(scoped_refptr<X509Certificate> chain) {
+ ct::CTVerifyResult result;
+ CapturingNetLog net_log;
+ BoundNetLog bound_net_log =
+ BoundNetLog::Make(&net_log, NetLog::SOURCE_CONNECT_JOB);
+
+ return verifier_->Verify(
+ chain, std::string(), std::string(), &result, bound_net_log) ==
+ OK;
+ }
+
bool CheckPrecertificateVerification(scoped_refptr<X509Certificate> chain) {
ct::CTVerifyResult result;
CapturingNetLog net_log;
BoundNetLog bound_net_log =
BoundNetLog::Make(&net_log, NetLog::SOURCE_CONNECT_JOB);
- return (verifier_->Verify(chain, std::string(), std::string(), &result,
- bound_net_log) == OK) &&
- CheckForSingleVerifiedSCTInResult(result) &&
- CheckForSCTOrigin(
- result, ct::SignedCertificateTimestamp::SCT_EMBEDDED) &&
- CheckForEmbeddedSCTInNetLog(net_log);
+ return (VerifySinglePrecertificateChain(chain, bound_net_log, &result) &&
+ CheckForSingleVerifiedSCTInResult(result) &&
+ CheckForSCTOrigin(result,
+ ct::SignedCertificateTimestamp::SCT_EMBEDDED) &&
+ CheckForEmbeddedSCTInNetLog(net_log));
+ }
+
+ // Histogram-related helper methods
+ int GetValueFromHistogram(std::string histogram_name, int sample_index) {
+ base::Histogram* histogram = static_cast<base::Histogram*>(
+ base::StatisticsRecorder::FindHistogram(histogram_name));
+
+ if (histogram == NULL)
+ return 0;
+
+ scoped_ptr<base::HistogramSamples> samples = histogram->SnapshotSamples();
+ return samples->GetCount(sample_index);
+ }
+
+ int NumConnectionsWithSingleSCT() {
+ return GetValueFromHistogram(kSCTCountHistogram, 1);
+ }
+
+ int NumEmbeddedSCTsInHistogram() {
+ return GetValueFromHistogram("Net.CertificateTransparency.SCTOrigin",
+ ct::SignedCertificateTimestamp::SCT_EMBEDDED);
+ }
+
+ int NumValidSCTsInStatusHistogram() {
+ return GetValueFromHistogram("Net.CertificateTransparency.SCTStatus",
+ ct::SCT_STATUS_OK);
}
protected:
scoped_ptr<MultiLogCTVerifier> verifier_;
scoped_refptr<X509Certificate> chain_;
+ scoped_refptr<X509Certificate> embedded_sct_chain_;
};
TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCT) {
- scoped_refptr<X509Certificate> chain(
- CreateCertificateChainFromFile(GetTestCertsDirectory(),
- "ct-test-embedded-cert.pem",
- X509Certificate::FORMAT_AUTO));
- ASSERT_TRUE(chain);
- ASSERT_TRUE(CheckPrecertificateVerification(chain));
+ ASSERT_TRUE(CheckPrecertificateVerification(embedded_sct_chain_));
}
TEST_F(MultiLogCTVerifierTest, VerifiesEmbeddedSCTWithPreCA) {
@@ -151,21 +240,58 @@ TEST_F(MultiLogCTVerifierTest,
TEST_F(MultiLogCTVerifierTest,
IdentifiesSCTFromUnknownLog) {
- std::string sct(ct::GetTestSignedCertificateTimestamp());
+ std::string sct_list = GetSCTListWithInvalidSCT();
+ ct::CTVerifyResult result;
- // Change a byte inside the Log ID part of the SCT so it does
- // not match the log used in the tests
- sct[15] = 't';
+ EXPECT_NE(OK,
+ verifier_->Verify(
+ chain_, std::string(), sct_list, &result, BoundNetLog()));
+ EXPECT_EQ(1U, result.unknown_logs_scts.size());
+ EXPECT_EQ("", result.unknown_logs_scts[0]->log_description);
+}
- std::string sct_list;
- ASSERT_TRUE(ct::EncodeSCTListForTesting(sct, &sct_list));
+TEST_F(MultiLogCTVerifierTest, CountsValidSCTsInStatusHistogram) {
+ int num_valid_scts = NumValidSCTsInStatusHistogram();
+
+ ASSERT_TRUE(VerifySinglePrecertificateChain(embedded_sct_chain_));
+
+ EXPECT_EQ(num_valid_scts + 1, NumValidSCTsInStatusHistogram());
+}
+TEST_F(MultiLogCTVerifierTest, CountsInvalidSCTsInStatusHistogram) {
+ std::string sct_list = GetSCTListWithInvalidSCT();
ct::CTVerifyResult result;
+ int num_valid_scts = NumValidSCTsInStatusHistogram();
+ int num_invalid_scts = GetValueFromHistogram(
+ "Net.CertificateTransparency.SCTStatus", ct::SCT_STATUS_LOG_UNKNOWN);
+
EXPECT_NE(OK,
verifier_->Verify(chain_, std::string(), sct_list, &result,
BoundNetLog()));
- EXPECT_EQ(1U, result.unknown_logs_scts.size());
- EXPECT_EQ("", result.unknown_logs_scts[0]->log_description);
+
+ ASSERT_EQ(num_valid_scts, NumValidSCTsInStatusHistogram());
+ ASSERT_EQ(num_invalid_scts + 1,
+ GetValueFromHistogram("Net.CertificateTransparency.SCTStatus",
+ ct::SCT_STATUS_LOG_UNKNOWN));
+}
+
+TEST_F(MultiLogCTVerifierTest, CountsSingleEmbeddedSCTInConnectionsHistogram) {
+ int old_sct_count = NumConnectionsWithSingleSCT();
+ ASSERT_TRUE(CheckPrecertificateVerification(embedded_sct_chain_));
+ EXPECT_EQ(old_sct_count + 1, NumConnectionsWithSingleSCT());
+}
+
+TEST_F(MultiLogCTVerifierTest, CountsSingleEmbeddedSCTInOriginsHistogram) {
+ int old_embedded_count = NumEmbeddedSCTsInHistogram();
+ ASSERT_TRUE(CheckPrecertificateVerification(embedded_sct_chain_));
+ EXPECT_EQ(old_embedded_count + 1, NumEmbeddedSCTsInHistogram());
+}
+
+TEST_F(MultiLogCTVerifierTest, CountsZeroSCTsCorrectly) {
+ int connections_without_scts = GetValueFromHistogram(kSCTCountHistogram, 0);
+ EXPECT_FALSE(VerifySinglePrecertificateChain(chain_));
+ ASSERT_EQ(connections_without_scts + 1,
+ GetValueFromHistogram(kSCTCountHistogram, 0));
}
} // namespace