Commit 74acd6f2 authored by rtenneti's avatar rtenneti Committed by Commit bot

QUIC - Race Cert Verification with host resolution if certs are

availiable when race_cert_verification network session param is enabled.

This experiment is not enabled in chromium.
CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:closure_compilation

R=eroman@chromium.org, mef@chromium.org, rch@chromium.org,
TBR=eroman@chromium.org (for net-internals changes)

Review-Url: https://codereview.chromium.org/2120703003
Cr-Commit-Position: refs/heads/master@{#404568}
parent 2ece5a75
......@@ -15,6 +15,7 @@
<li>Idle Connection Timeout In Seconds: <span jscontent="$this.idle_connection_timeout_seconds"></span></li>
<li>Disable PreConnect If 0RTT: <span jscontent="$this.disable_preconnect_if_0rtt"></span></li>
<li>Disable QUIC On Timeout With Open Streams: <span jscontent="$this.disable_quic_on_timeout_with_open_streams"></span></li>
<li>Race Cert Verification: <span jscontent="!!race_cert_verification"></span></li>
<li jsdisplay="$this.disabled_reason && disabled_reason.length > 0">QUIC dynamically disabled: <span jscontent="disabled_reason"></span></li>
</ul>
......
......@@ -51,7 +51,8 @@ public class QuicTest extends CronetTestBase {
.put("idle_connection_timeout_seconds", 300)
.put("close_sessions_on_ip_change", false)
.put("migrate_sessions_on_network_change", true)
.put("migrate_sessions_early", true);
.put("migrate_sessions_early", true)
.put("race_cert_verification", true);
JSONObject experimentalOptions = new JSONObject().put("QUIC", quicParams);
mBuilder.setExperimentalOptions(experimentalOptions.toString());
mBuilder.setMockCertVerifierForTesting(QuicTestServer.createMockCertVerifier());
......
......@@ -53,6 +53,7 @@ const char kQuicUserAgentId[] = "user_agent_id";
const char kQuicMigrateSessionsEarly[] = "migrate_sessions_early";
const char kQuicDisableBidirectionalStreams[] =
"quic_disable_bidirectional_streams";
const char kQuicRaceCertVerification[] = "race_cert_verification";
// AsyncDNS experiment dictionary name.
const char kAsyncDnsFieldTrialName[] = "AsyncDNS";
......@@ -187,6 +188,13 @@ void ParseAndSetExperimentalOptions(
context_builder->set_quic_disable_bidirectional_streams(
quic_disable_bidirectional_streams);
}
bool quic_race_cert_verification = false;
if (quic_args->GetBoolean(kQuicRaceCertVerification,
&quic_race_cert_verification)) {
context_builder->set_quic_race_cert_verification(
quic_race_cert_verification);
}
}
const base::DictionaryValue* async_dns_args = nullptr;
......
......@@ -46,6 +46,7 @@ TEST(URLRequestContextConfigTest, SetQuicExperimentalOptions) {
"\"packet_loss_threshold\":0.5,"
"\"idle_connection_timeout_seconds\":300,"
"\"close_sessions_on_ip_change\":true,"
"\"race_cert_verification\":true,"
"\"connection_options\":\"TIME,TBBR,REJ\"},"
"\"AsyncDNS\":{\"enable\":true}}",
// Data reduction proxy key.
......@@ -103,6 +104,9 @@ TEST(URLRequestContextConfigTest, SetQuicExperimentalOptions) {
EXPECT_TRUE(params->quic_close_sessions_on_ip_change);
EXPECT_FALSE(params->quic_migrate_sessions_on_network_change);
// Check race_cert_verification.
EXPECT_TRUE(params->quic_race_cert_verification);
// Check AsyncDNS resolver is enabled.
EXPECT_TRUE(context->host_resolver()->GetDnsConfigAsValue());
}
......
......@@ -129,6 +129,7 @@ HttpNetworkSession::Params::Params()
quic_migrate_sessions_early(false),
quic_disable_bidirectional_streams(false),
quic_force_hol_blocking(false),
quic_race_cert_verification(false),
proxy_delegate(NULL),
enable_token_binding(false) {
quic_supported_versions.push_back(QUIC_VERSION_34);
......@@ -188,6 +189,7 @@ HttpNetworkSession::HttpNetworkSession(const Params& params)
params.quic_migrate_sessions_on_network_change,
params.quic_migrate_sessions_early,
params.quic_force_hol_blocking,
params.quic_race_cert_verification,
params.quic_connection_options,
params.enable_token_binding),
spdy_session_pool_(params.host_resolver,
......@@ -340,6 +342,8 @@ std::unique_ptr<base::Value> HttpNetworkSession::QuicInfoToValue() const {
dict->SetString("disabled_reason",
quic_stream_factory_.QuicDisabledReasonString());
dict->SetBoolean("force_hol_blocking", params_.quic_force_hol_blocking);
dict->SetBoolean("race_cert_verification",
params_.quic_race_cert_verification);
return std::move(dict);
}
......
......@@ -180,6 +180,8 @@ class NET_EXPORT HttpNetworkSession
bool quic_disable_bidirectional_streams;
// If true, enable force HOL blocking. For measurement purposes.
bool quic_force_hol_blocking;
// If true, race cert verification with host resolution.
bool quic_race_cert_verification;
ProxyDelegate* proxy_delegate;
// Enable support for Token Binding.
......
......@@ -86,6 +86,26 @@ class NET_EXPORT_PRIVATE ProofVerifier {
std::string* error_details,
std::unique_ptr<ProofVerifyDetails>* details,
std::unique_ptr<ProofVerifierCallback> callback) = 0;
// VerifyCertChain checks that |certs| is a valid chain for |hostname|. On
// success, it returns QUIC_SUCCESS. On failure, it returns QUIC_FAILURE and
// sets |*error_details| to a description of the problem. In either case it
// may set |*details|, which the caller takes ownership of.
//
// |context| specifies an implementation specific struct (which may be nullptr
// for some implementations) that provides useful information for the
// verifier, e.g. logging handles.
//
// This function may also return QUIC_PENDING, in which case the ProofVerifier
// will call back, on the original thread, via |callback| when complete.
// In this case, the ProofVerifier will take ownership of |callback|.
virtual QuicAsyncStatus VerifyCertChain(
const std::string& hostname,
const std::vector<std::string>& certs,
const ProofVerifyContext* context,
std::string* error_details,
std::unique_ptr<ProofVerifyDetails>* details,
std::unique_ptr<ProofVerifierCallback> callback) = 0;
};
} // namespace net
......
......@@ -78,6 +78,16 @@ class ProofVerifierChromium::Job {
std::unique_ptr<ProofVerifyDetails>* verify_details,
std::unique_ptr<ProofVerifierCallback> callback);
// Starts the certificate chain verification of |certs|. If |QUIC_PENDING| is
// returned, then |callback| will be invoked asynchronously when the
// verification completes.
QuicAsyncStatus VerifyCertChain(
const std::string& hostname,
const std::vector<std::string>& certs,
std::string* error_details,
std::unique_ptr<ProofVerifyDetails>* verify_details,
std::unique_ptr<ProofVerifierCallback> callback);
private:
enum State {
STATE_NONE,
......@@ -85,6 +95,19 @@ class ProofVerifierChromium::Job {
STATE_VERIFY_CERT_COMPLETE,
};
// Convert |certs| to |cert_|(X509Certificate). Returns true if successful.
bool GetX509Certificate(const vector<string>& certs,
std::string* error_details,
std::unique_ptr<ProofVerifyDetails>* verify_details);
// Start the cert verification.
QuicAsyncStatus VerifyCert(
const string& hostname,
const uint16_t port,
std::string* error_details,
std::unique_ptr<ProofVerifyDetails>* verify_details,
std::unique_ptr<ProofVerifierCallback> callback);
int DoLoop(int last_io_result);
void OnIOComplete(int result);
int DoVerifyCert(int result);
......@@ -125,6 +148,9 @@ class ProofVerifierChromium::Job {
// passed to CertVerifier::Verify.
int cert_verify_flags_;
// If set to true, enforces policy checking in DoVerifyCertComplete().
bool enforce_policy_checking_;
State next_state_;
base::TimeTicks start_time_;
......@@ -148,6 +174,7 @@ ProofVerifierChromium::Job::Job(
transport_security_state_(transport_security_state),
cert_transparency_verifier_(cert_transparency_verifier),
cert_verify_flags_(cert_verify_flags),
enforce_policy_checking_(true),
next_state_(STATE_NONE),
start_time_(base::TimeTicks::Now()),
net_log_(net_log) {
......@@ -195,27 +222,9 @@ QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
verify_details_.reset(new ProofVerifyDetailsChromium);
if (certs.empty()) {
*error_details = "Failed to create certificate chain. Certs are empty.";
DLOG(WARNING) << *error_details;
verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
*verify_details = std::move(verify_details_);
return QUIC_FAILURE;
}
// Convert certs to X509Certificate.
vector<StringPiece> cert_pieces(certs.size());
for (unsigned i = 0; i < certs.size(); i++) {
cert_pieces[i] = base::StringPiece(certs[i]);
}
cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces);
if (!cert_.get()) {
*error_details = "Failed to create certificate chain";
DLOG(WARNING) << *error_details;
verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
*verify_details = std::move(verify_details_);
// Converts |certs| to |cert_|.
if (!GetX509Certificate(certs, error_details, verify_details))
return QUIC_FAILURE;
}
if (!cert_sct.empty()) {
// Note that this is a completely synchronous operation: The CT Log Verifier
......@@ -237,6 +246,75 @@ QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
return QUIC_FAILURE;
}
DCHECK(enforce_policy_checking_);
return VerifyCert(hostname, port, error_details, verify_details,
std::move(callback));
}
QuicAsyncStatus ProofVerifierChromium::Job::VerifyCertChain(
const string& hostname,
const vector<string>& certs,
std::string* error_details,
std::unique_ptr<ProofVerifyDetails>* verify_details,
std::unique_ptr<ProofVerifierCallback> callback) {
DCHECK(error_details);
DCHECK(verify_details);
DCHECK(callback);
error_details->clear();
if (STATE_NONE != next_state_) {
*error_details = "Certificate is already set and VerifyCertChain has begun";
DLOG(DFATAL) << *error_details;
return QUIC_FAILURE;
}
verify_details_.reset(new ProofVerifyDetailsChromium);
// Converts |certs| to |cert_|.
if (!GetX509Certificate(certs, error_details, verify_details))
return QUIC_FAILURE;
enforce_policy_checking_ = false;
// |port| is not needed because |enforce_policy_checking_| is false.
return VerifyCert(hostname, /*port=*/0, error_details, verify_details,
std::move(callback));
}
bool ProofVerifierChromium::Job::GetX509Certificate(
const vector<string>& certs,
std::string* error_details,
std::unique_ptr<ProofVerifyDetails>* verify_details) {
if (certs.empty()) {
*error_details = "Failed to create certificate chain. Certs are empty.";
DLOG(WARNING) << *error_details;
verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
*verify_details = std::move(verify_details_);
return false;
}
// Convert certs to X509Certificate.
vector<StringPiece> cert_pieces(certs.size());
for (unsigned i = 0; i < certs.size(); i++) {
cert_pieces[i] = base::StringPiece(certs[i]);
}
cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces);
if (!cert_.get()) {
*error_details = "Failed to create certificate chain";
DLOG(WARNING) << *error_details;
verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
*verify_details = std::move(verify_details_);
return false;
}
return true;
}
QuicAsyncStatus ProofVerifierChromium::Job::VerifyCert(
const string& hostname,
const uint16_t port,
std::string* error_details,
std::unique_ptr<ProofVerifyDetails>* verify_details,
std::unique_ptr<ProofVerifierCallback> callback) {
hostname_ = hostname;
port_ = port;
......@@ -315,7 +393,8 @@ int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) {
// If the connection was good, check HPKP and CT status simultaneously,
// but prefer to treat the HPKP error as more serious, if there was one.
if ((result == OK ||
if (enforce_policy_checking_ &&
(result == OK ||
(IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) {
if ((cert_verify_result.cert_status & CERT_STATUS_IS_EV)) {
ct::EVPolicyCompliance ev_policy_compliance =
......@@ -505,9 +584,32 @@ QuicAsyncStatus ProofVerifierChromium::VerifyProof(
QuicAsyncStatus status = job->VerifyProof(
hostname, port, server_config, quic_version, chlo_hash, certs, cert_sct,
signature, error_details, verify_details, std::move(callback));
if (status == QUIC_PENDING) {
if (status == QUIC_PENDING)
active_jobs_.insert(job.release());
return status;
}
QuicAsyncStatus ProofVerifierChromium::VerifyCertChain(
const std::string& hostname,
const std::vector<std::string>& certs,
const ProofVerifyContext* verify_context,
std::string* error_details,
std::unique_ptr<ProofVerifyDetails>* verify_details,
std::unique_ptr<ProofVerifierCallback> callback) {
if (!verify_context) {
*error_details = "Missing context";
return QUIC_FAILURE;
}
const ProofVerifyContextChromium* chromium_context =
reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
std::unique_ptr<Job> job(
new Job(this, cert_verifier_, ct_policy_enforcer_,
transport_security_state_, cert_transparency_verifier_,
chromium_context->cert_verify_flags, chromium_context->net_log));
QuicAsyncStatus status = job->VerifyCertChain(
hostname, certs, error_details, verify_details, std::move(callback));
if (status == QUIC_PENDING)
active_jobs_.insert(job.release());
return status;
}
......
......@@ -85,6 +85,13 @@ class NET_EXPORT_PRIVATE ProofVerifierChromium : public ProofVerifier {
std::string* error_details,
std::unique_ptr<ProofVerifyDetails>* verify_details,
std::unique_ptr<ProofVerifierCallback> callback) override;
QuicAsyncStatus VerifyCertChain(
const std::string& hostname,
const std::vector<std::string>& certs,
const ProofVerifyContext* verify_context,
std::string* error_details,
std::unique_ptr<ProofVerifyDetails>* verify_details,
std::unique_ptr<ProofVerifierCallback> callback) override;
private:
class Job;
......
......@@ -587,5 +587,34 @@ TEST_F(ProofVerifierChromiumTest, PKPAndCTBothTested) {
CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
}
// Tests that the VerifyCertChain verifies certificates.
TEST_F(ProofVerifierChromiumTest, VerifyCertChain) {
scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
ASSERT_TRUE(test_cert);
CertVerifyResult dummy_result;
dummy_result.verified_cert = test_cert;
dummy_result.cert_status = 0;
MockCertVerifier dummy_verifier;
dummy_verifier.AddResultForCert(test_cert.get(), dummy_result, OK);
ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
&transport_security_state_,
ct_verifier_.get());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
QuicAsyncStatus status = proof_verifier.VerifyCertChain(
kTestHostname, certs_, verify_context_.get(), &error_details_, &details_,
std::move(callback));
ASSERT_EQ(QUIC_SUCCESS, status);
ASSERT_TRUE(details_.get());
ProofVerifyDetailsChromium* verify_details =
static_cast<ProofVerifyDetailsChromium*>(details_.get());
EXPECT_EQ(0u, verify_details->cert_verify_result.cert_status);
}
} // namespace test
} // namespace net
This diff is collapsed.
......@@ -193,6 +193,7 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
bool migrate_sessions_on_network_change,
bool migrate_sessions_early,
bool force_hol_blocking,
bool race_cert_verification,
const QuicTagVector& connection_options,
bool enable_token_binding);
~QuicStreamFactory() override;
......@@ -365,6 +366,7 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
private:
class Job;
class CertVerifierJob;
friend class test::QuicStreamFactoryPeer;
FRIEND_TEST_ALL_PREFIXES(HttpStreamFactoryTest, QuicLossyProxyMarkedAsBad);
......@@ -382,6 +384,8 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
typedef std::map<QuicServerId, RequestSet> ServerIDRequestsMap;
typedef std::deque<enum QuicChromiumClientSession::QuicDisabledReason>
DisabledReasonsQueue;
typedef std::map<QuicServerId, std::unique_ptr<CertVerifierJob>>
CertVerifierJobMap;
enum FactoryStatus {
OPEN, // New streams may be created.
......@@ -401,8 +405,10 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
bool OnResolution(const QuicSessionKey& key, const AddressList& address_list);
void OnJobComplete(Job* job, int rv);
void OnCertVerifyJobComplete(CertVerifierJob* job, int rv);
bool HasActiveSession(const QuicServerId& server_id) const;
bool HasActiveJob(const QuicServerId& server_id) const;
bool HasActiveCertVerifierJob(const QuicServerId& server_id) const;
int CreateSession(const QuicSessionKey& key,
int cert_verify_flags,
std::unique_ptr<QuicServerInfo> quic_server_info,
......@@ -424,6 +430,13 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
bool CryptoConfigCacheIsEmpty(const QuicServerId& server_id);
// Starts an asynchronous job for cert verification if
// |race_cert_verification_| is enabled and if there are cached certs for the
// given |server_id|.
QuicAsyncStatus StartCertVerifyJob(const QuicServerId& server_id,
int cert_verify_flags,
const BoundNetLog& net_log);
// Initializes the cached state associated with |server_id| in
// |crypto_config_| with the information in |server_info|. Populates
// |connection_id| with the next server designated connection id,
......@@ -491,6 +504,8 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
ServerIDRequestsMap job_requests_map_;
RequestMap active_requests_;
CertVerifierJobMap active_cert_verifier_jobs_;
QuicVersionVector supported_versions_;
// Determine if we should consistently select a client UDP port. If false,
......@@ -576,6 +591,9 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
// If set, force HOL blocking. For measurement purposes.
const bool force_hol_blocking_;
// Set if cert verification is to be raced with host resolution.
bool race_cert_verification_;
// Each profile will (probably) have a unique port_seed_ value. This value
// is used to help seed a pseudo-random number generator (PortSuggester) so
// that we consistently (within this profile) suggest the same ephemeral
......
......@@ -321,16 +321,16 @@ class QuicStreamFactoryTestBase {
idle_connection_timeout_seconds_(kIdleConnectionTimeoutSeconds),
migrate_sessions_on_network_change_(false),
migrate_sessions_early_(false),
force_hol_blocking_(false) {
force_hol_blocking_(false),
race_cert_verification_(false) {
clock_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
}
~QuicStreamFactoryTestBase() {
// If |factory_| was initialized, then it took over ownership of |clock_|.
// If |factory_| was not initialized, then |clock_| needs to be destroyed.
if (!factory_) {
if (!factory_)
delete clock_;
}
}
void Initialize() {
......@@ -353,8 +353,8 @@ class QuicStreamFactoryTestBase {
close_sessions_on_ip_change_,
disable_quic_on_timeout_with_open_streams_,
idle_connection_timeout_seconds_, migrate_sessions_on_network_change_,
migrate_sessions_early_, force_hol_blocking_, QuicTagVector(),
/*enable_token_binding*/ false));
migrate_sessions_early_, force_hol_blocking_, race_cert_verification_,
QuicTagVector(), /*enable_token_binding*/ false));
factory_->set_require_confirmation(false);
EXPECT_FALSE(factory_->has_quic_server_info_factory());
factory_->set_quic_server_info_factory(new MockQuicServerInfoFactory());
......@@ -379,6 +379,11 @@ class QuicStreamFactoryTestBase {
return QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server_id);
}
bool HasActiveCertVerifierJob(const QuicServerId& server_id) {
return QuicStreamFactoryPeer::HasActiveCertVerifierJob(factory_.get(),
server_id);
}
QuicChromiumClientSession* GetActiveSession(
const HostPortPair& host_port_pair) {
QuicServerId server_id(host_port_pair, PRIVACY_MODE_DISABLED);
......@@ -547,6 +552,7 @@ class QuicStreamFactoryTestBase {
bool migrate_sessions_on_network_change_;
bool migrate_sessions_early_;
bool force_hol_blocking_;
bool race_cert_verification_;
};
class QuicStreamFactoryTest : public QuicStreamFactoryTestBase,
......@@ -4136,6 +4142,64 @@ TEST_P(QuicStreamFactoryTest, MaybeInitialize) {
EXPECT_EQ(test_cert2, cached2->certs()[0]);
}
TEST_P(QuicStreamFactoryTest, StartCertVerifyJob) {
Initialize();
MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
socket_factory_.AddSocketDataProvider(&socket_data);
// Save current state of |race_cert_verification|.
bool race_cert_verification =
QuicStreamFactoryPeer::GetRaceCertVerification(factory_.get());
// Load server config.
HostPortPair host_port_pair("test.example.com", kDefaultServerPort);
QuicServerId quic_server_id(host_port_pair_, privacy_mode_);
QuicStreamFactoryPeer::CacheDummyServerConfig(factory_.get(), quic_server_id);
QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(), true);
// Start CertVerifyJob.
QuicAsyncStatus status = QuicStreamFactoryPeer::StartCertVerifyJob(
factory_.get(), quic_server_id, /*cert_verify_flags=*/0, net_log_);
EXPECT_NE(QUIC_FAILURE, status);
if (status == QUIC_PENDING) {
// Verify CertVerifierJob has started.
EXPECT_TRUE(HasActiveCertVerifierJob(quic_server_id));
while (HasActiveCertVerifierJob(quic_server_id)) {
base::RunLoop().RunUntilIdle();
}
}
// Verify CertVerifierJob has finished.
EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
// Start a QUIC request.
QuicStreamRequest request(factory_.get());
EXPECT_EQ(ERR_IO_PENDING,
request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, url_, "GET", net_log_,
callback_.callback()));
EXPECT_EQ(OK, callback_.WaitForResult());
std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
EXPECT_TRUE(stream.get());
// Restore |race_cert_verification|.
QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(),
race_cert_verification);
EXPECT_TRUE(socket_data.AllReadDataConsumed());
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
// Verify there are no outstanding CertVerifierJobs after request has
// finished.
EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
}
TEST_P(QuicStreamFactoryTest, QuicDoingZeroRTT) {
Initialize();
......
......@@ -7,11 +7,14 @@
#include <string>
#include <vector>
#include "net/cert/x509_certificate.h"
#include "net/quic/crypto/quic_crypto_client_config.h"
#include "net/quic/quic_chromium_client_session.h"
#include "net/quic/quic_clock.h"
#include "net/quic/quic_http_stream.h"
#include "net/quic/quic_stream_factory.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
using std::string;
using std::vector;
......@@ -33,6 +36,12 @@ bool QuicStreamFactoryPeer::HasActiveSession(QuicStreamFactory* factory,
return factory->HasActiveSession(server_id);
}
bool QuicStreamFactoryPeer::HasActiveCertVerifierJob(
QuicStreamFactory* factory,
const QuicServerId& server_id) {
return factory->HasActiveCertVerifierJob(server_id);
}
QuicChromiumClientSession* QuicStreamFactoryPeer::GetActiveSession(
QuicStreamFactory* factory,
const QuicServerId& server_id) {
......@@ -82,6 +91,25 @@ void QuicStreamFactoryPeer::SetDelayTcpRace(QuicStreamFactory* factory,
factory->delay_tcp_race_ = delay_tcp_race;
}
bool QuicStreamFactoryPeer::GetRaceCertVerification(
QuicStreamFactory* factory) {
return factory->race_cert_verification_;
}
void QuicStreamFactoryPeer::SetRaceCertVerification(
QuicStreamFactory* factory,
bool race_cert_verification) {
factory->race_cert_verification_ = race_cert_verification;
}
QuicAsyncStatus QuicStreamFactoryPeer::StartCertVerifyJob(
QuicStreamFactory* factory,
const QuicServerId& server_id,
int cert_verify_flags,
const BoundNetLog& net_log) {
return factory->StartCertVerifyJob(server_id, cert_verify_flags, net_log);
}
void QuicStreamFactoryPeer::SetYieldAfterPackets(QuicStreamFactory* factory,
int yield_after_packets) {
factory->yield_after_packets_ = yield_after_packets;
......@@ -149,9 +177,15 @@ void QuicStreamFactoryPeer::CacheDummyServerConfig(
string server_config(reinterpret_cast<const char*>(&scfg), sizeof(scfg));
string source_address_token("test_source_address_token");
string signature("test_signature");
string test_cert("test_cert");
vector<string> certs;
certs.push_back(test_cert);
// Load a certificate that is valid for *.example.org
scoped_refptr<X509Certificate> cert(
ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
DCHECK(cert);
std::string der_bytes;
DCHECK(X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_bytes));
certs.push_back(der_bytes);
QuicCryptoClientConfig* crypto_config = &factory->crypto_config_;
QuicCryptoClientConfig::CachedState* cached =
......
......@@ -12,6 +12,7 @@
#include "base/task_runner.h"
#include "net/base/host_port_pair.h"
#include "net/base/privacy_mode.h"
#include "net/log/net_log.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_server_id.h"
#include "net/quic/quic_time.h"
......@@ -36,6 +37,9 @@ class QuicStreamFactoryPeer {
static bool HasActiveSession(QuicStreamFactory* factory,
const QuicServerId& server_id);
static bool HasActiveCertVerifierJob(QuicStreamFactory* factory,
const QuicServerId& server_id);
static QuicChromiumClientSession* GetActiveSession(
QuicStreamFactory* factory,
const QuicServerId& server_id);
......@@ -59,6 +63,16 @@ class QuicStreamFactoryPeer {
static void SetDelayTcpRace(QuicStreamFactory* factory, bool delay_tcp_race);
static bool GetRaceCertVerification(QuicStreamFactory* factory);
static void SetRaceCertVerification(QuicStreamFactory* factory,
bool race_cert_verification);
static QuicAsyncStatus StartCertVerifyJob(QuicStreamFactory* factory,
const QuicServerId& server_id,
int cert_verify_flags,
const BoundNetLog& net_log);
static void SetYieldAfterPackets(QuicStreamFactory* factory,
int yield_after_packets);
......
......@@ -83,6 +83,16 @@ class RecordingProofVerifier : public ProofVerifier {
return QUIC_SUCCESS;
}
QuicAsyncStatus VerifyCertChain(
const std::string& hostname,
const std::vector<std::string>& certs,
const ProofVerifyContext* verify_context,
std::string* error_details,
std::unique_ptr<ProofVerifyDetails>* verify_details,
std::unique_ptr<ProofVerifierCallback> callback) override {
return QUIC_SUCCESS;
}
const string& common_name() const { return common_name_; }
const string& cert_sct() const { return cert_sct_; }
......
......@@ -193,7 +193,8 @@ URLRequestContextBuilder::HttpNetworkSessionParams::HttpNetworkSessionParams()
quic_close_sessions_on_ip_change(false),
quic_migrate_sessions_on_network_change(false),
quic_migrate_sessions_early(false),
quic_disable_bidirectional_streams(false) {}
quic_disable_bidirectional_streams(false),
quic_race_cert_verification(false) {}
URLRequestContextBuilder::HttpNetworkSessionParams::~HttpNetworkSessionParams()
{}
......@@ -441,6 +442,8 @@ std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
http_network_session_params_.quic_migrate_sessions_early;
network_session_params.quic_disable_bidirectional_streams =
http_network_session_params_.quic_disable_bidirectional_streams;
network_session_params.quic_race_cert_verification =
http_network_session_params_.quic_race_cert_verification;
if (proxy_delegate_) {
network_session_params.proxy_delegate = proxy_delegate_.get();
storage->set_proxy_delegate(std::move(proxy_delegate_));
......
......@@ -105,6 +105,7 @@ class NET_EXPORT URLRequestContextBuilder {
bool quic_migrate_sessions_on_network_change;
bool quic_migrate_sessions_early;
bool quic_disable_bidirectional_streams;
bool quic_race_cert_verification;
};
URLRequestContextBuilder();
......@@ -283,6 +284,11 @@ class NET_EXPORT URLRequestContextBuilder {
quic_disable_bidirectional_streams;
}
void set_quic_race_cert_verification(bool quic_race_cert_verification) {
http_network_session_params_.quic_race_cert_verification =
quic_race_cert_verification;
}
void set_throttling_enabled(bool throttling_enabled) {
throttling_enabled_ = throttling_enabled;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment