blob: f06d666acf97ec1d24333faf8e4c096c5b967502 [file] [log] [blame]
// Copyright 2020 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 SERVICES_NETWORK_SCT_AUDITING_CACHE_H_
#define SERVICES_NETWORK_SCT_AUDITING_CACHE_H_
#include <map>
#include <string>
#include <vector>
#include "base/component_export.h"
#include "base/containers/mru_cache.h"
#include "base/time/time.h"
#include "net/base/hash_value.h"
#include "net/base/host_port_pair.h"
#include "net/cert/sct_auditing_delegate.h"
#include "net/cert/signed_certificate_timestamp_and_status.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "services/network/public/proto/sct_audit_report.pb.h"
namespace net {
class X509Certificate;
}
namespace network {
class NetworkContext;
// SCTAuditingCache tracks SCTs seen during CT verification. The cache supports
// a configurable sample rate to reduce load, and deduplicates SCTs seen more
// than once. The cache evicts least-recently-used entries after it reaches its
// capacity.
//
// The SCTAuditingCache also handles sending reports to a specified report URL
// using a specific NetworkContext. These are configured by the embedder via the
// network service's ConfigureSCTAuditing() API.
//
// A single SCTAuditingCache should be shared among all contexts that want to
// deduplicate reports and use a single sampling mechanism. Currently, one
// SCTAuditingCache is created and owned by the NetworkService and shared
// across all NetworkContexts.
class COMPONENT_EXPORT(NETWORK_SERVICE) SCTAuditingCache {
public:
explicit SCTAuditingCache(size_t cache_size);
~SCTAuditingCache();
SCTAuditingCache(const SCTAuditingCache&) = delete;
SCTAuditingCache& operator=(const SCTAuditingCache&) = delete;
// Creates a report containing the details about the connection context and
// SCTs and adds it to the cache if the SCTs are not already in the
// cache. If the SCTs were not already in the cache, a random sample is drawn
// to determine whether to send a report. This means we sample a subset of
// *certificates* rather than a subset of *connections*.
void MaybeEnqueueReport(
NetworkContext* context,
const net::HostPortPair& host_port_pair,
const net::X509Certificate* validated_certificate_chain,
const net::SignedCertificateTimestampAndStatusList&
signed_certificate_timestamps);
sct_auditing::SCTClientReport* GetPendingReport(
const net::SHA256HashValue& cache_key);
// Sends the report associated with `cache_key` to `report_uri` (which is
// specified by the embedder). When the request completes (on success or
// failure), `callback` will be called with the response details.
void SendReport(const net::SHA256HashValue& cache_key);
void ClearCache();
void set_enabled(bool enabled) { enabled_ = enabled; }
void set_sampling_rate(double rate) { sampling_rate_ = rate; }
void set_report_uri(const GURL& report_uri) { report_uri_ = report_uri; }
void set_traffic_annotation(
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
traffic_annotation_ = traffic_annotation;
}
void set_url_loader_factory(
mojo::PendingRemote<mojom::URLLoaderFactory> factory) {
url_loader_factory_.Bind(std::move(factory));
}
base::MRUCache<net::SHA256HashValue,
std::unique_ptr<sct_auditing::SCTClientReport>>*
GetCacheForTesting() {
return &cache_;
}
private:
void OnReportComplete(const net::SHA256HashValue& cache_key,
int net_error,
int http_response_code);
base::MRUCache<net::SHA256HashValue,
std::unique_ptr<sct_auditing::SCTClientReport>>
cache_;
bool enabled_ = false;
double sampling_rate_ = 0;
GURL report_uri_;
net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
mojo::Remote<mojom::URLLoaderFactory> url_loader_factory_;
size_t cache_size_hwm_;
base::WeakPtrFactory<SCTAuditingCache> weak_factory_{this};
};
} // namespace network
#endif // SERVICES_NETWORK_SCT_AUDITING_CACHE_H_