blob: 60d828be79320786a807f06647e747c16ad93f13 [file] [log] [blame]
Ned Williamson3d55bbb2017-11-07 22:58:131// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ryan Hamiltona3ee93a72018-08-01 22:03:085#include "net/quic/quic_stream_factory.h"
Ned Williamson3d55bbb2017-11-07 22:58:136
7#include "base/test/fuzzed_data_provider.h"
8
Avi Drissman4365a4782018-12-28 19:26:249#include "base/stl_util.h"
Ned Williamson3d55bbb2017-11-07 22:58:1310#include "net/base/test_completion_callback.h"
Ryan Sleevi8a9c9c12018-05-09 02:36:2311#include "net/cert/ct_policy_enforcer.h"
Ryan Sleevi987d2d92017-12-19 19:22:1412#include "net/cert/do_nothing_ct_verifier.h"
13#include "net/cert/mock_cert_verifier.h"
Ryan Hamiltone3e592e2017-11-16 04:49:0914#include "net/cert/x509_certificate.h"
Eric Orth4e55b362019-05-07 22:00:0315#include "net/dns/context_host_resolver.h"
16#include "net/dns/fuzzed_host_resolver_util.h"
Ned Williamson3d55bbb2017-11-07 22:58:1317#include "net/http/http_server_properties_impl.h"
18#include "net/http/transport_security_state.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0819#include "net/quic/mock_crypto_client_stream_factory.h"
20#include "net/quic/quic_http_stream.h"
21#include "net/quic/test_task_runner.h"
Ned Williamson3d55bbb2017-11-07 22:58:1322#include "net/socket/fuzzed_datagram_client_socket.h"
23#include "net/socket/fuzzed_socket_factory.h"
Paul Jensen8e3c5d32018-02-19 17:06:3324#include "net/socket/socket_tag.h"
Ryan Sleevi987d2d92017-12-19 19:22:1425#include "net/ssl/ssl_config_service_defaults.h"
Ryan Hamilton0a9f01462017-11-14 01:27:3026#include "net/test/gtest_util.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5127#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
28#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
Ramin Halavatia1256c82018-02-21 06:18:2129#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Ned Williamson3d55bbb2017-11-07 22:58:1330
31namespace net {
32
33namespace {
34
Ryan Hamiltone3e592e2017-11-16 04:49:0935const char kCertData[] = {
36#include "net/data/ssl/certificates/wildcard.inc"
37};
38
Ned Williamson3d55bbb2017-11-07 22:58:1339} // namespace
40
41namespace test {
42
43const char kServerHostName[] = "www.example.org";
44const int kServerPort = 443;
45const char kUrl[] = "https://www.example.org/";
46// TODO(nedwilliamson): Add POST here after testing
47// whether that can lead blocking while waiting for
48// the callbacks.
49const char kMethod[] = "GET";
50const size_t kBufferSize = 4096;
51const int kCertVerifyFlags = 0;
52
53// Static initialization for persistent factory data
54struct Env {
55 Env() : host_port_pair(kServerHostName, kServerPort), random_generator(0) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:5256 clock.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
Ryan Sleevib8449e02018-07-15 04:31:0757 ssl_config_service = std::make_unique<SSLConfigServiceDefaults>();
Ned Williamson3d55bbb2017-11-07 22:58:1358 crypto_client_stream_factory.set_use_mock_crypter(true);
Ryan Sleevi987d2d92017-12-19 19:22:1459 cert_verifier = std::make_unique<MockCertVerifier>();
Ryan Sleevi987d2d92017-12-19 19:22:1460 cert_transparency_verifier = std::make_unique<DoNothingCTVerifier>();
Ryan Hamilton0a9f01462017-11-14 01:27:3061 verify_details.cert_verify_result.verified_cert =
Avi Drissman4365a4782018-12-28 19:26:2462 X509Certificate::CreateFromBytes(kCertData, base::size(kCertData));
Ryan Hamiltone3e592e2017-11-16 04:49:0963 CHECK(verify_details.cert_verify_result.verified_cert);
Ryan Hamilton0a9f01462017-11-14 01:27:3064 verify_details.cert_verify_result.is_issued_by_known_root = true;
Ned Williamson3d55bbb2017-11-07 22:58:1365 }
66
Ryan Hamilton8d9ee76e2018-05-29 23:52:5267 quic::MockClock clock;
Ryan Sleevib8449e02018-07-15 04:31:0768 std::unique_ptr<SSLConfigService> ssl_config_service;
Ryan Hamilton0a9f01462017-11-14 01:27:3069 ProofVerifyDetailsChromium verify_details;
Ned Williamson3d55bbb2017-11-07 22:58:1370 MockCryptoClientStreamFactory crypto_client_stream_factory;
71 HostPortPair host_port_pair;
Ryan Hamilton8d9ee76e2018-05-29 23:52:5272 quic::test::MockRandom random_generator;
Ned Williamson3d55bbb2017-11-07 22:58:1373 NetLogWithSource net_log;
74 std::unique_ptr<CertVerifier> cert_verifier;
Ned Williamson3d55bbb2017-11-07 22:58:1375 TransportSecurityState transport_security_state;
Ryan Hamilton8d9ee76e2018-05-29 23:52:5276 quic::QuicTagVector connection_options;
77 quic::QuicTagVector client_connection_options;
Ned Williamson3d55bbb2017-11-07 22:58:1378 std::unique_ptr<CTVerifier> cert_transparency_verifier;
Ryan Sleevi8a9c9c12018-05-09 02:36:2379 DefaultCTPolicyEnforcer ct_policy_enforcer;
Ned Williamson3d55bbb2017-11-07 22:58:1380};
81
82static struct Env* env = new Env();
83
84extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
85 base::FuzzedDataProvider data_provider(data, size);
86
Eric Orth4e55b362019-05-07 22:00:0387 std::unique_ptr<ContextHostResolver> host_resolver =
88 CreateFuzzedContextHostResolver(HostResolver::ManagerOptions(), nullptr,
89 &data_provider,
90 true /* enable_caching */);
Ned Williamson3d55bbb2017-11-07 22:58:1391 FuzzedSocketFactory socket_factory(&data_provider);
92
93 // Initialize this on each loop since some options mutate this.
94 HttpServerPropertiesImpl http_server_properties;
95
Ned Williamson1000a492017-11-09 20:40:1496 bool store_server_configs_in_properties = data_provider.ConsumeBool();
Jana Iyengar903dec22017-11-28 00:44:2397 bool close_sessions_on_ip_change = data_provider.ConsumeBool();
Ned Williamson1000a492017-11-09 20:40:1498 bool mark_quic_broken_when_network_blackholes = data_provider.ConsumeBool();
Ned Williamson1000a492017-11-09 20:40:1499 bool allow_server_migration = data_provider.ConsumeBool();
100 bool race_cert_verification = data_provider.ConsumeBool();
101 bool estimate_initial_rtt = data_provider.ConsumeBool();
Yixin Wang079ad542018-01-11 04:06:05102 bool headers_include_h2_stream_dependency = data_provider.ConsumeBool();
kapishnikov7f8dd1e122018-01-24 06:10:49103 bool enable_socket_recv_optimization = data_provider.ConsumeBool();
Renjiea0cb4a2c2018-09-26 23:37:30104 bool race_stale_dns_on_connection = data_provider.ConsumeBool();
Ned Williamson1000a492017-11-09 20:40:14105
Ryan Hamilton0a9f01462017-11-14 01:27:30106 env->crypto_client_stream_factory.AddProofVerifyDetails(&env->verify_details);
107
Zhongyi Shi63574b7f2018-06-01 20:22:25108 bool goaway_sessions_on_ip_change = false;
Zhongyi Shif4683a32017-12-01 00:03:28109 bool migrate_sessions_early_v2 = false;
Zhongyi Shi56e44b22017-12-02 00:06:33110 bool migrate_sessions_on_network_change_v2 = false;
Zhongyi Shi8de43832018-08-15 23:40:00111 bool retry_on_alternate_network_before_handshake = false;
Zhongyi Shi32fe14d42019-02-28 00:25:36112 bool migrate_idle_sessions = false;
Renjiea5722ccf2018-08-10 00:18:49113 bool go_away_on_path_degrading = false;
Zhongyi Shif4683a32017-12-01 00:03:28114
Zhongyi Shi56e44b22017-12-02 00:06:33115 if (!close_sessions_on_ip_change) {
Zhongyi Shi63574b7f2018-06-01 20:22:25116 goaway_sessions_on_ip_change = data_provider.ConsumeBool();
117 if (!goaway_sessions_on_ip_change) {
118 migrate_sessions_on_network_change_v2 = data_provider.ConsumeBool();
119 if (migrate_sessions_on_network_change_v2) {
120 migrate_sessions_early_v2 = data_provider.ConsumeBool();
Zhongyi Shi8de43832018-08-15 23:40:00121 retry_on_alternate_network_before_handshake =
122 data_provider.ConsumeBool();
Zhongyi Shi32fe14d42019-02-28 00:25:36123 migrate_idle_sessions = data_provider.ConsumeBool();
Zhongyi Shi63574b7f2018-06-01 20:22:25124 }
Zhongyi Shi56e44b22017-12-02 00:06:33125 }
Zhongyi Shif4683a32017-12-01 00:03:28126 }
Ned Williamson1000a492017-11-09 20:40:14127
Renjiea5722ccf2018-08-10 00:18:49128 if (!migrate_sessions_early_v2)
129 go_away_on_path_degrading = data_provider.ConsumeBool();
130
Ned Williamson3d55bbb2017-11-07 22:58:13131 std::unique_ptr<QuicStreamFactory> factory =
132 std::make_unique<QuicStreamFactory>(
Eric Orth4e55b362019-05-07 22:00:03133 env->net_log.net_log(), host_resolver.get(),
134 env->ssl_config_service.get(), &socket_factory,
135 &http_server_properties, env->cert_verifier.get(),
Nick Harperecf319d2018-10-16 07:58:54136 &env->ct_policy_enforcer, &env->transport_security_state,
137 env->cert_transparency_verifier.get(), nullptr,
138 &env->crypto_client_stream_factory, &env->random_generator,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52139 &env->clock, quic::kDefaultMaxPacketSize, std::string(),
Jana Iyengar903dec22017-11-28 00:44:23140 store_server_configs_in_properties, close_sessions_on_ip_change,
Zhongyi Shi63574b7f2018-06-01 20:22:25141 goaway_sessions_on_ip_change,
Ned Williamson1000a492017-11-09 20:40:14142 mark_quic_broken_when_network_blackholes,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52143 kIdleConnectionTimeoutSeconds, quic::kPingTimeoutSecs,
Zhongyi Shie01f2db2019-02-22 19:53:23144 kDefaultRetransmittableOnWireTimeoutMillisecs,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52145 quic::kMaxTimeForCryptoHandshakeSecs, quic::kInitialIdleTimeoutSecs,
Zhongyi Shi6ec9d232018-05-18 02:20:39146 migrate_sessions_on_network_change_v2, migrate_sessions_early_v2,
Zhongyi Shi32fe14d42019-02-28 00:25:36147 retry_on_alternate_network_before_handshake, migrate_idle_sessions,
Zhongyi Shic16b4102019-02-12 00:37:40148 base::TimeDelta::FromSeconds(
149 kDefaultIdleSessionMigrationPeriodSeconds),
Zhongyi Shi73f23ca872017-12-13 18:37:13150 base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
Zhongyi Shiee760762018-08-01 00:54:29151 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30152 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shidbce7f412019-02-01 23:16:29153 allow_server_migration, race_stale_dns_on_connection,
154 go_away_on_path_degrading, race_cert_verification,
155 estimate_initial_rtt, headers_include_h2_stream_dependency,
156 env->connection_options, env->client_connection_options,
Renjiea0522f062019-04-29 18:52:21157 enable_socket_recv_optimization, 0);
Ned Williamson3d55bbb2017-11-07 22:58:13158
159 QuicStreamRequest request(factory.get());
160 TestCompletionCallback callback;
161 NetErrorDetails net_error_details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52162 request.Request(
163 env->host_port_pair,
164 data_provider.PickValueInArray(quic::kSupportedTransportVersions),
165 PRIVACY_MODE_DISABLED, DEFAULT_PRIORITY, SocketTag(), kCertVerifyFlags,
Zhongyi Shia6b68d112018-09-24 07:49:03166 GURL(kUrl), env->net_log, &net_error_details,
167 /*failed_on_default_network_callback=*/CompletionOnceCallback(),
168 callback.callback());
Ned Williamson3d55bbb2017-11-07 22:58:13169
170 callback.WaitForResult();
Yixin Wang7891a39d2017-11-08 20:59:24171 std::unique_ptr<QuicChromiumClientSession::Handle> session =
172 request.ReleaseSessionHandle();
173 if (!session)
Ned Williamson3d55bbb2017-11-07 22:58:13174 return 0;
Yixin Wang7891a39d2017-11-08 20:59:24175 std::unique_ptr<HttpStream> stream(new QuicHttpStream(std::move(session)));
Ned Williamson3d55bbb2017-11-07 22:58:13176
177 HttpRequestInfo request_info;
178 request_info.method = kMethod;
179 request_info.url = GURL(kUrl);
Ramin Halavatia1256c82018-02-21 06:18:21180 request_info.traffic_annotation =
181 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:27182 stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY, env->net_log,
Bence Békya25e3f72018-02-13 21:13:39183 CompletionOnceCallback());
Ned Williamson3d55bbb2017-11-07 22:58:13184
185 HttpResponseInfo response;
186 HttpRequestHeaders request_headers;
187 if (OK !=
188 stream->SendRequest(request_headers, &response, callback.callback()))
189 return 0;
190
191 // TODO(nedwilliamson): attempt connection migration here
Nick Harper7ac20cc2018-05-08 18:06:04192 int rv = stream->ReadResponseHeaders(callback.callback());
193 if (rv != OK && rv != ERR_IO_PENDING) {
194 return 0;
195 }
Ned Williamson3d55bbb2017-11-07 22:58:13196 callback.WaitForResult();
197
Victor Costan9c7302b2018-08-27 16:39:44198 scoped_refptr<net::IOBuffer> buffer =
199 base::MakeRefCounted<net::IOBuffer>(kBufferSize);
Nick Harper7ac20cc2018-05-08 18:06:04200 rv = stream->ReadResponseBody(buffer.get(), kBufferSize, callback.callback());
Ned Williamson3d55bbb2017-11-07 22:58:13201 if (rv == ERR_IO_PENDING)
202 callback.WaitForResult();
203
204 return 0;
205}
206
207} // namespace test
208} // namespace net