blob: 660663a9acd98168f0a88470cab9b03e87a75683 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 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
QUICHE team5be974e2020-12-29 18:35:24 -05005#include "quic/core/quic_crypto_client_handshaker.h"
dschinazi580d30b2019-04-26 15:05:20 -07006
bnc463f2352019-10-10 04:49:34 -07007#include <utility>
8
vasilvvc872ee42020-10-07 19:50:22 -07009#include "absl/strings/string_view.h"
QUICHE team5be974e2020-12-29 18:35:24 -050010#include "quic/core/proto/crypto_server_config_proto.h"
11#include "quic/platform/api/quic_test.h"
12#include "quic/test_tools/quic_test_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050013
14namespace quic {
15namespace {
16
QUICHE teama6ef0a62019-03-07 20:34:33 -050017class TestProofHandler : public QuicCryptoClientStream::ProofHandler {
18 public:
19 ~TestProofHandler() override {}
20 void OnProofValid(
dschinazi17d42422019-06-18 16:35:07 -070021 const QuicCryptoClientConfig::CachedState& /*cached*/) override {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050022 void OnProofVerifyDetailsAvailable(
dschinazi17d42422019-06-18 16:35:07 -070023 const ProofVerifyDetails& /*verify_details*/) override {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050024};
25
26class InsecureProofVerifier : public ProofVerifier {
27 public:
28 InsecureProofVerifier() {}
29 ~InsecureProofVerifier() override {}
30
31 // ProofVerifier override.
32 QuicAsyncStatus VerifyProof(
dschinazi17d42422019-06-18 16:35:07 -070033 const std::string& /*hostname*/,
34 const uint16_t /*port*/,
35 const std::string& /*server_config*/,
36 QuicTransportVersion /*transport_version*/,
vasilvvc872ee42020-10-07 19:50:22 -070037 absl::string_view /*chlo_hash*/,
dschinazi17d42422019-06-18 16:35:07 -070038 const std::vector<std::string>& /*certs*/,
39 const std::string& /*cert_sct*/,
40 const std::string& /*signature*/,
41 const ProofVerifyContext* /*context*/,
42 std::string* /*error_details*/,
43 std::unique_ptr<ProofVerifyDetails>* /*verify_details*/,
44 std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -050045 return QUIC_SUCCESS;
46 }
47
48 QuicAsyncStatus VerifyCertChain(
dschinazi17d42422019-06-18 16:35:07 -070049 const std::string& /*hostname*/,
nharper5ab78c82020-06-05 15:03:44 -070050 const uint16_t /*port*/,
dschinazi17d42422019-06-18 16:35:07 -070051 const std::vector<std::string>& /*certs*/,
52 const std::string& /*ocsp_response*/,
53 const std::string& /*cert_sct*/,
54 const ProofVerifyContext* /*context*/,
55 std::string* /*error_details*/,
56 std::unique_ptr<ProofVerifyDetails>* /*details*/,
nharper54fc9ab2020-11-12 11:07:39 -080057 uint8_t* /*out_alert*/,
dschinazi17d42422019-06-18 16:35:07 -070058 std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -050059 return QUIC_SUCCESS;
60 }
61
62 std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
63 return nullptr;
64 }
65};
66
67class DummyProofSource : public ProofSource {
68 public:
69 DummyProofSource() {}
70 ~DummyProofSource() override {}
71
72 // ProofSource override.
73 void GetProof(const QuicSocketAddress& server_address,
danzhd1fc5912020-05-01 15:29:04 -070074 const QuicSocketAddress& client_address,
vasilvvc48c8712019-03-11 13:38:16 -070075 const std::string& hostname,
dschinazi17d42422019-06-18 16:35:07 -070076 const std::string& /*server_config*/,
77 QuicTransportVersion /*transport_version*/,
vasilvvc872ee42020-10-07 19:50:22 -070078 absl::string_view /*chlo_hash*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -050079 std::unique_ptr<Callback> callback) override {
80 QuicReferenceCountedPointer<ProofSource::Chain> chain =
danzhd1fc5912020-05-01 15:29:04 -070081 GetCertChain(server_address, client_address, hostname);
QUICHE teama6ef0a62019-03-07 20:34:33 -050082 QuicCryptoProof proof;
83 proof.signature = "Dummy signature";
84 proof.leaf_cert_scts = "Dummy timestamp";
dschinazi17d42422019-06-18 16:35:07 -070085 callback->Run(true, chain, proof, /*details=*/nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -050086 }
87
88 QuicReferenceCountedPointer<Chain> GetCertChain(
dschinazi17d42422019-06-18 16:35:07 -070089 const QuicSocketAddress& /*server_address*/,
danzhd1fc5912020-05-01 15:29:04 -070090 const QuicSocketAddress& /*client_address*/,
dschinazi17d42422019-06-18 16:35:07 -070091 const std::string& /*hostname*/) override {
vasilvvc48c8712019-03-11 13:38:16 -070092 std::vector<std::string> certs;
QUICHE teama6ef0a62019-03-07 20:34:33 -050093 certs.push_back("Dummy cert");
94 return QuicReferenceCountedPointer<ProofSource::Chain>(
95 new ProofSource::Chain(certs));
96 }
97
98 void ComputeTlsSignature(
dschinazi17d42422019-06-18 16:35:07 -070099 const QuicSocketAddress& /*server_address*/,
danzhd1fc5912020-05-01 15:29:04 -0700100 const QuicSocketAddress& /*client_address*/,
dschinazi17d42422019-06-18 16:35:07 -0700101 const std::string& /*hostname*/,
102 uint16_t /*signature_algorit*/,
vasilvvc872ee42020-10-07 19:50:22 -0700103 absl::string_view /*in*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500104 std::unique_ptr<SignatureCallback> callback) override {
nharper35d60192020-03-26 12:15:47 -0700105 callback->Run(true, "Dummy signature", /*details=*/nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500106 }
nharper037c21b2020-04-23 14:41:35 -0700107
nharper1f8289a2020-04-27 11:57:28 -0700108 TicketCrypter* GetTicketCrypter() override { return nullptr; }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500109};
110
111class Handshaker : public QuicCryptoClientHandshaker {
112 public:
113 Handshaker(const QuicServerId& server_id,
114 QuicCryptoClientStream* stream,
115 QuicSession* session,
116 std::unique_ptr<ProofVerifyContext> verify_context,
117 QuicCryptoClientConfig* crypto_config,
118 QuicCryptoClientStream::ProofHandler* proof_handler)
119 : QuicCryptoClientHandshaker(server_id,
120 stream,
121 session,
122 std::move(verify_context),
123 crypto_config,
124 proof_handler) {}
125
126 void DoSendCHLOTest(QuicCryptoClientConfig::CachedState* cached) {
127 QuicCryptoClientHandshaker::DoSendCHLO(cached);
128 }
129};
130
dschinazie7b5ae42020-03-31 14:34:45 -0700131class QuicCryptoClientHandshakerTest
132 : public QuicTestWithParam<ParsedQuicVersion> {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500133 protected:
134 QuicCryptoClientHandshakerTest()
dschinazie7b5ae42020-03-31 14:34:45 -0700135 : version_(GetParam()),
136 proof_handler_(),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500137 helper_(),
138 alarm_factory_(),
139 server_id_("host", 123),
140 connection_(new test::MockQuicConnection(&helper_,
141 &alarm_factory_,
dschinazie7b5ae42020-03-31 14:34:45 -0700142 Perspective::IS_CLIENT,
143 {version_})),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500144 session_(connection_, false),
vasilvv0fc587f2019-09-06 13:33:08 -0700145 crypto_client_config_(std::make_unique<InsecureProofVerifier>()),
renjietangbcc066a2020-04-21 18:05:57 -0700146 client_stream_(
147 new QuicCryptoClientStream(server_id_,
148 &session_,
149 nullptr,
150 &crypto_client_config_,
151 &proof_handler_,
152 /*has_application_state = */ false)),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500153 handshaker_(server_id_,
154 client_stream_,
155 &session_,
156 nullptr,
157 &crypto_client_config_,
158 &proof_handler_),
159 state_() {
160 // Session takes the ownership of the client stream! (but handshaker also
161 // takes a reference to it, but doesn't take the ownership).
162 session_.SetCryptoStream(client_stream_);
163 session_.Initialize();
164 }
165
166 void InitializeServerParametersToEnableFullHello() {
167 QuicCryptoServerConfig::ConfigOptions options;
QUICHE teambbaa8be2019-03-21 12:54:17 -0700168 QuicServerConfigProtobuf config = QuicCryptoServerConfig::GenerateConfig(
169 helper_.GetRandomGenerator(), helper_.GetClock(), options);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500170 state_.Initialize(
QUICHE teambbaa8be2019-03-21 12:54:17 -0700171 config.config(), "sourcetoken", std::vector<std::string>{"Dummy cert"},
QUICHE teama6ef0a62019-03-07 20:34:33 -0500172 "", "chlo_hash", "signature", helper_.GetClock()->WallNow(),
173 helper_.GetClock()->WallNow().Add(QuicTime::Delta::FromSeconds(30)));
174
175 state_.SetProofValid();
176 }
177
dschinazie7b5ae42020-03-31 14:34:45 -0700178 ParsedQuicVersion version_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500179 TestProofHandler proof_handler_;
180 test::MockQuicConnectionHelper helper_;
181 test::MockAlarmFactory alarm_factory_;
182 QuicServerId server_id_;
183 // Session takes the ownership of the connection.
184 test::MockQuicConnection* connection_;
185 test::MockQuicSession session_;
186 QuicCryptoClientConfig crypto_client_config_;
187 QuicCryptoClientStream* client_stream_;
188 Handshaker handshaker_;
189 QuicCryptoClientConfig::CachedState state_;
190};
191
dschinazie7b5ae42020-03-31 14:34:45 -0700192INSTANTIATE_TEST_SUITE_P(
193 QuicCryptoClientHandshakerTests,
194 QuicCryptoClientHandshakerTest,
195 ::testing::ValuesIn(AllSupportedVersionsWithQuicCrypto()),
196 ::testing::PrintToStringParamName());
197
198TEST_P(QuicCryptoClientHandshakerTest, TestSendFullPaddingInInchoateHello) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500199 handshaker_.DoSendCHLOTest(&state_);
200
201 EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
202}
203
dschinazie7b5ae42020-03-31 14:34:45 -0700204TEST_P(QuicCryptoClientHandshakerTest, TestDisabledPaddingInInchoateHello) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500205 crypto_client_config_.set_pad_inchoate_hello(false);
206 handshaker_.DoSendCHLOTest(&state_);
207 EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
208}
209
dschinazie7b5ae42020-03-31 14:34:45 -0700210TEST_P(QuicCryptoClientHandshakerTest,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500211 TestPaddingInFullHelloEvenIfInchoateDisabled) {
212 // Disable inchoate, but full hello should still be padded.
213 crypto_client_config_.set_pad_inchoate_hello(false);
214
215 InitializeServerParametersToEnableFullHello();
216
217 handshaker_.DoSendCHLOTest(&state_);
218 EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
219}
220
dschinazie7b5ae42020-03-31 14:34:45 -0700221TEST_P(QuicCryptoClientHandshakerTest, TestNoPaddingInFullHelloWhenDisabled) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500222 crypto_client_config_.set_pad_full_hello(false);
223
224 InitializeServerParametersToEnableFullHello();
225
226 handshaker_.DoSendCHLOTest(&state_);
227 EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
228}
229
230} // namespace
231} // namespace quic