blob: 43c7efa11db00b61c0246dd34a13f9374bbba9ea [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
5#include "net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.h"
dschinazi580d30b2019-04-26 15:05:20 -07006
bnc463f2352019-10-10 04:49:34 -07007#include <utility>
8
dschinazi56fb53e2019-06-21 15:30:04 -07009#include "net/third_party/quiche/src/quic/core/proto/crypto_server_config_proto.h"
dschinazi580d30b2019-04-26 15:05:20 -070010#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050011#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
12
13namespace quic {
14namespace {
15
16using ::testing::Test;
17
18class TestProofHandler : public QuicCryptoClientStream::ProofHandler {
19 public:
20 ~TestProofHandler() override {}
21 void OnProofValid(
dschinazi17d42422019-06-18 16:35:07 -070022 const QuicCryptoClientConfig::CachedState& /*cached*/) override {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050023 void OnProofVerifyDetailsAvailable(
dschinazi17d42422019-06-18 16:35:07 -070024 const ProofVerifyDetails& /*verify_details*/) override {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050025};
26
27class InsecureProofVerifier : public ProofVerifier {
28 public:
29 InsecureProofVerifier() {}
30 ~InsecureProofVerifier() override {}
31
32 // ProofVerifier override.
33 QuicAsyncStatus VerifyProof(
dschinazi17d42422019-06-18 16:35:07 -070034 const std::string& /*hostname*/,
35 const uint16_t /*port*/,
36 const std::string& /*server_config*/,
37 QuicTransportVersion /*transport_version*/,
38 QuicStringPiece /*chlo_hash*/,
39 const std::vector<std::string>& /*certs*/,
40 const std::string& /*cert_sct*/,
41 const std::string& /*signature*/,
42 const ProofVerifyContext* /*context*/,
43 std::string* /*error_details*/,
44 std::unique_ptr<ProofVerifyDetails>* /*verify_details*/,
45 std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -050046 return QUIC_SUCCESS;
47 }
48
49 QuicAsyncStatus VerifyCertChain(
dschinazi17d42422019-06-18 16:35:07 -070050 const std::string& /*hostname*/,
51 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*/,
57 std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -050058 return QUIC_SUCCESS;
59 }
60
61 std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
62 return nullptr;
63 }
64};
65
66class DummyProofSource : public ProofSource {
67 public:
68 DummyProofSource() {}
69 ~DummyProofSource() override {}
70
71 // ProofSource override.
72 void GetProof(const QuicSocketAddress& server_address,
vasilvvc48c8712019-03-11 13:38:16 -070073 const std::string& hostname,
dschinazi17d42422019-06-18 16:35:07 -070074 const std::string& /*server_config*/,
75 QuicTransportVersion /*transport_version*/,
76 QuicStringPiece /*chlo_hash*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -050077 std::unique_ptr<Callback> callback) override {
78 QuicReferenceCountedPointer<ProofSource::Chain> chain =
79 GetCertChain(server_address, hostname);
80 QuicCryptoProof proof;
81 proof.signature = "Dummy signature";
82 proof.leaf_cert_scts = "Dummy timestamp";
dschinazi17d42422019-06-18 16:35:07 -070083 callback->Run(true, chain, proof, /*details=*/nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -050084 }
85
86 QuicReferenceCountedPointer<Chain> GetCertChain(
dschinazi17d42422019-06-18 16:35:07 -070087 const QuicSocketAddress& /*server_address*/,
88 const std::string& /*hostname*/) override {
vasilvvc48c8712019-03-11 13:38:16 -070089 std::vector<std::string> certs;
QUICHE teama6ef0a62019-03-07 20:34:33 -050090 certs.push_back("Dummy cert");
91 return QuicReferenceCountedPointer<ProofSource::Chain>(
92 new ProofSource::Chain(certs));
93 }
94
95 void ComputeTlsSignature(
dschinazi17d42422019-06-18 16:35:07 -070096 const QuicSocketAddress& /*server_address*/,
97 const std::string& /*hostname*/,
98 uint16_t /*signature_algorit*/,
99 QuicStringPiece /*in*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500100 std::unique_ptr<SignatureCallback> callback) override {
101 callback->Run(true, "Dummy signature");
102 }
103};
104
105class Handshaker : public QuicCryptoClientHandshaker {
106 public:
107 Handshaker(const QuicServerId& server_id,
108 QuicCryptoClientStream* stream,
109 QuicSession* session,
110 std::unique_ptr<ProofVerifyContext> verify_context,
111 QuicCryptoClientConfig* crypto_config,
112 QuicCryptoClientStream::ProofHandler* proof_handler)
113 : QuicCryptoClientHandshaker(server_id,
114 stream,
115 session,
116 std::move(verify_context),
117 crypto_config,
118 proof_handler) {}
119
120 void DoSendCHLOTest(QuicCryptoClientConfig::CachedState* cached) {
121 QuicCryptoClientHandshaker::DoSendCHLO(cached);
122 }
123};
124
125class QuicCryptoClientHandshakerTest : public Test {
126 protected:
127 QuicCryptoClientHandshakerTest()
128 : proof_handler_(),
129 helper_(),
130 alarm_factory_(),
131 server_id_("host", 123),
132 connection_(new test::MockQuicConnection(&helper_,
133 &alarm_factory_,
134 Perspective::IS_CLIENT)),
135 session_(connection_, false),
vasilvv0fc587f2019-09-06 13:33:08 -0700136 crypto_client_config_(std::make_unique<InsecureProofVerifier>()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500137 client_stream_(new QuicCryptoClientStream(server_id_,
138 &session_,
139 nullptr,
140 &crypto_client_config_,
141 &proof_handler_)),
142 handshaker_(server_id_,
143 client_stream_,
144 &session_,
145 nullptr,
146 &crypto_client_config_,
147 &proof_handler_),
148 state_() {
149 // Session takes the ownership of the client stream! (but handshaker also
150 // takes a reference to it, but doesn't take the ownership).
151 session_.SetCryptoStream(client_stream_);
152 session_.Initialize();
153 }
154
155 void InitializeServerParametersToEnableFullHello() {
156 QuicCryptoServerConfig::ConfigOptions options;
QUICHE teambbaa8be2019-03-21 12:54:17 -0700157 QuicServerConfigProtobuf config = QuicCryptoServerConfig::GenerateConfig(
158 helper_.GetRandomGenerator(), helper_.GetClock(), options);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500159 state_.Initialize(
QUICHE teambbaa8be2019-03-21 12:54:17 -0700160 config.config(), "sourcetoken", std::vector<std::string>{"Dummy cert"},
QUICHE teama6ef0a62019-03-07 20:34:33 -0500161 "", "chlo_hash", "signature", helper_.GetClock()->WallNow(),
162 helper_.GetClock()->WallNow().Add(QuicTime::Delta::FromSeconds(30)));
163
164 state_.SetProofValid();
165 }
166
167 TestProofHandler proof_handler_;
168 test::MockQuicConnectionHelper helper_;
169 test::MockAlarmFactory alarm_factory_;
170 QuicServerId server_id_;
171 // Session takes the ownership of the connection.
172 test::MockQuicConnection* connection_;
173 test::MockQuicSession session_;
174 QuicCryptoClientConfig crypto_client_config_;
175 QuicCryptoClientStream* client_stream_;
176 Handshaker handshaker_;
177 QuicCryptoClientConfig::CachedState state_;
178};
179
180TEST_F(QuicCryptoClientHandshakerTest, TestSendFullPaddingInInchoateHello) {
181 handshaker_.DoSendCHLOTest(&state_);
182
183 EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
184}
185
186TEST_F(QuicCryptoClientHandshakerTest, TestDisabledPaddingInInchoateHello) {
187 crypto_client_config_.set_pad_inchoate_hello(false);
188 handshaker_.DoSendCHLOTest(&state_);
189 EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
190}
191
192TEST_F(QuicCryptoClientHandshakerTest,
193 TestPaddingInFullHelloEvenIfInchoateDisabled) {
194 // Disable inchoate, but full hello should still be padded.
195 crypto_client_config_.set_pad_inchoate_hello(false);
196
197 InitializeServerParametersToEnableFullHello();
198
199 handshaker_.DoSendCHLOTest(&state_);
200 EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
201}
202
203TEST_F(QuicCryptoClientHandshakerTest, TestNoPaddingInFullHelloWhenDisabled) {
204 crypto_client_config_.set_pad_full_hello(false);
205
206 InitializeServerParametersToEnableFullHello();
207
208 handshaker_.DoSendCHLOTest(&state_);
209 EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
210}
211
212} // namespace
213} // namespace quic