| Index: net/cert/multi_log_ct_verifier.cc
|
| diff --git a/net/cert/multi_log_ct_verifier.cc b/net/cert/multi_log_ct_verifier.cc
|
| deleted file mode 100644
|
| index 6c8d5bd2762bafaf5aad25d65b6e404d0a1da1d2..0000000000000000000000000000000000000000
|
| --- a/net/cert/multi_log_ct_verifier.cc
|
| +++ /dev/null
|
| @@ -1,236 +0,0 @@
|
| -// Copyright 2013 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 "net/cert/multi_log_ct_verifier.h"
|
| -
|
| -#include <vector>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/callback_helpers.h"
|
| -#include "base/metrics/histogram.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/base/net_log.h"
|
| -#include "net/cert/ct_log_verifier.h"
|
| -#include "net/cert/ct_objects_extractor.h"
|
| -#include "net/cert/ct_serialization.h"
|
| -#include "net/cert/ct_signed_certificate_timestamp_log_param.h"
|
| -#include "net/cert/ct_verify_result.h"
|
| -#include "net/cert/sct_status_flags.h"
|
| -#include "net/cert/x509_certificate.h"
|
| -
|
| -namespace net {
|
| -
|
| -namespace {
|
| -
|
| -// Record SCT verification status. This metric would help detecting presence
|
| -// of unknown CT logs as well as bad deployments (invalid SCTs).
|
| -void LogSCTStatusToUMA(ct::SCTVerifyStatus status) {
|
| - UMA_HISTOGRAM_ENUMERATION(
|
| - "Net.CertificateTransparency.SCTStatus", status, ct::SCT_STATUS_MAX);
|
| -}
|
| -
|
| -// Record SCT origin enum. This metric measure the popularity
|
| -// of the various channels of providing SCTs for a certificate.
|
| -void LogSCTOriginToUMA(ct::SignedCertificateTimestamp::Origin origin) {
|
| - UMA_HISTOGRAM_ENUMERATION("Net.CertificateTransparency.SCTOrigin",
|
| - origin,
|
| - ct::SignedCertificateTimestamp::SCT_ORIGIN_MAX);
|
| -}
|
| -
|
| -// Count the number of SCTs that were available for each SSL connection
|
| -// (including SCTs embedded in the certificate).
|
| -// This metric would allow measuring:
|
| -// * Of all SSL connections, how many had SCTs available for validation.
|
| -// * When SCTs are available, how many are available per connection.
|
| -void LogNumSCTsToUMA(const ct::CTVerifyResult& result) {
|
| - UMA_HISTOGRAM_CUSTOM_COUNTS("Net.CertificateTransparency.SCTsPerConnection",
|
| - result.invalid_scts.size() +
|
| - result.verified_scts.size() +
|
| - result.unknown_logs_scts.size(),
|
| - 1,
|
| - 10,
|
| - 11);
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -MultiLogCTVerifier::MultiLogCTVerifier() { }
|
| -
|
| -MultiLogCTVerifier::~MultiLogCTVerifier() { }
|
| -
|
| -void MultiLogCTVerifier::AddLog(scoped_ptr<CTLogVerifier> log_verifier) {
|
| - DCHECK(log_verifier);
|
| - if (!log_verifier)
|
| - return;
|
| -
|
| - linked_ptr<CTLogVerifier> log(log_verifier.release());
|
| - logs_[log->key_id()] = log;
|
| -}
|
| -
|
| -void MultiLogCTVerifier::AddLogs(
|
| - ScopedVector<CTLogVerifier> log_verifiers) {
|
| - for (ScopedVector<CTLogVerifier>::iterator it =
|
| - log_verifiers.begin(); it != log_verifiers.end(); ++it) {
|
| - linked_ptr<CTLogVerifier> log(*it);
|
| - VLOG(1) << "Adding CT log: " << log->description();
|
| - logs_[log->key_id()] = log;
|
| - }
|
| -
|
| - // Ownership of the pointers in |log_verifiers| is transferred to |logs_|
|
| - log_verifiers.weak_clear();
|
| -}
|
| -
|
| -int MultiLogCTVerifier::Verify(
|
| - X509Certificate* cert,
|
| - const std::string& stapled_ocsp_response,
|
| - const std::string& sct_list_from_tls_extension,
|
| - ct::CTVerifyResult* result,
|
| - const BoundNetLog& net_log) {
|
| - DCHECK(cert);
|
| - DCHECK(result);
|
| -
|
| - result->verified_scts.clear();
|
| - result->invalid_scts.clear();
|
| - result->unknown_logs_scts.clear();
|
| -
|
| - bool has_verified_scts = false;
|
| -
|
| - std::string embedded_scts;
|
| - if (!cert->GetIntermediateCertificates().empty() &&
|
| - ct::ExtractEmbeddedSCTList(
|
| - cert->os_cert_handle(),
|
| - &embedded_scts)) {
|
| - ct::LogEntry precert_entry;
|
| -
|
| - has_verified_scts =
|
| - ct::GetPrecertLogEntry(
|
| - cert->os_cert_handle(),
|
| - cert->GetIntermediateCertificates().front(),
|
| - &precert_entry) &&
|
| - VerifySCTs(
|
| - embedded_scts,
|
| - precert_entry,
|
| - ct::SignedCertificateTimestamp::SCT_EMBEDDED,
|
| - result);
|
| - }
|
| -
|
| - std::string sct_list_from_ocsp;
|
| - if (!stapled_ocsp_response.empty() &&
|
| - !cert->GetIntermediateCertificates().empty()) {
|
| - ct::ExtractSCTListFromOCSPResponse(
|
| - cert->GetIntermediateCertificates().front(), cert->serial_number(),
|
| - stapled_ocsp_response, &sct_list_from_ocsp);
|
| - }
|
| -
|
| - // Log to Net Log, after extracting SCTs but before possibly failing on
|
| - // X.509 entry creation.
|
| - NetLog::ParametersCallback net_log_callback =
|
| - base::Bind(&NetLogRawSignedCertificateTimestampCallback,
|
| - &embedded_scts, &sct_list_from_ocsp, &sct_list_from_tls_extension);
|
| -
|
| - net_log.AddEvent(
|
| - NetLog::TYPE_SIGNED_CERTIFICATE_TIMESTAMPS_RECEIVED,
|
| - net_log_callback);
|
| -
|
| - ct::LogEntry x509_entry;
|
| - if (ct::GetX509LogEntry(cert->os_cert_handle(), &x509_entry)) {
|
| - has_verified_scts |= VerifySCTs(
|
| - sct_list_from_ocsp,
|
| - x509_entry,
|
| - ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE,
|
| - result);
|
| -
|
| - has_verified_scts |= VerifySCTs(
|
| - sct_list_from_tls_extension,
|
| - x509_entry,
|
| - ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION,
|
| - result);
|
| - }
|
| -
|
| - NetLog::ParametersCallback net_log_checked_callback =
|
| - base::Bind(&NetLogSignedCertificateTimestampCallback, result);
|
| -
|
| - net_log.AddEvent(
|
| - NetLog::TYPE_SIGNED_CERTIFICATE_TIMESTAMPS_CHECKED,
|
| - net_log_checked_callback);
|
| -
|
| - LogNumSCTsToUMA(*result);
|
| -
|
| - if (has_verified_scts)
|
| - return OK;
|
| -
|
| - return ERR_CT_NO_SCTS_VERIFIED_OK;
|
| -}
|
| -
|
| -bool MultiLogCTVerifier::VerifySCTs(
|
| - const std::string& encoded_sct_list,
|
| - const ct::LogEntry& expected_entry,
|
| - ct::SignedCertificateTimestamp::Origin origin,
|
| - ct::CTVerifyResult* result) {
|
| - if (logs_.empty())
|
| - return false;
|
| -
|
| - base::StringPiece temp(encoded_sct_list);
|
| - std::vector<base::StringPiece> sct_list;
|
| -
|
| - if (!ct::DecodeSCTList(&temp, &sct_list))
|
| - return false;
|
| -
|
| - bool verified = false;
|
| - for (std::vector<base::StringPiece>::const_iterator it = sct_list.begin();
|
| - it != sct_list.end(); ++it) {
|
| - base::StringPiece encoded_sct(*it);
|
| - LogSCTOriginToUMA(origin);
|
| -
|
| - scoped_refptr<ct::SignedCertificateTimestamp> decoded_sct;
|
| - if (!DecodeSignedCertificateTimestamp(&encoded_sct, &decoded_sct)) {
|
| - LogSCTStatusToUMA(ct::SCT_STATUS_NONE);
|
| - // XXX(rsleevi): Should we really just skip over bad SCTs?
|
| - continue;
|
| - }
|
| - decoded_sct->origin = origin;
|
| -
|
| - verified |= VerifySingleSCT(decoded_sct, expected_entry, result);
|
| - }
|
| -
|
| - return verified;
|
| -}
|
| -
|
| -bool MultiLogCTVerifier::VerifySingleSCT(
|
| - scoped_refptr<ct::SignedCertificateTimestamp> sct,
|
| - const ct::LogEntry& expected_entry,
|
| - ct::CTVerifyResult* result) {
|
| -
|
| - // Assume this SCT is untrusted until proven otherwise.
|
| - IDToLogMap::iterator it = logs_.find(sct->log_id);
|
| - if (it == logs_.end()) {
|
| - DVLOG(1) << "SCT does not match any known log.";
|
| - result->unknown_logs_scts.push_back(sct);
|
| - LogSCTStatusToUMA(ct::SCT_STATUS_LOG_UNKNOWN);
|
| - return false;
|
| - }
|
| -
|
| - sct->log_description = it->second->description();
|
| -
|
| - if (!it->second->Verify(expected_entry, *sct.get())) {
|
| - DVLOG(1) << "Unable to verify SCT signature.";
|
| - result->invalid_scts.push_back(sct);
|
| - LogSCTStatusToUMA(ct::SCT_STATUS_INVALID);
|
| - return false;
|
| - }
|
| -
|
| - // SCT verified ok, just make sure the timestamp is legitimate.
|
| - if (sct->timestamp > base::Time::Now()) {
|
| - DVLOG(1) << "SCT is from the future!";
|
| - result->invalid_scts.push_back(sct);
|
| - LogSCTStatusToUMA(ct::SCT_STATUS_INVALID);
|
| - return false;
|
| - }
|
| -
|
| - LogSCTStatusToUMA(ct::SCT_STATUS_OK);
|
| - result->verified_scts.push_back(sct);
|
| - return true;
|
| -}
|
| -
|
| -} // namespace net
|
|
|