blob: db6b181638542d402dc583a32e1397456d503522 [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
dschinazi56fb53e2019-06-21 15:30:04 -07007#include "net/third_party/quiche/src/quic/core/proto/crypto_server_config_proto.h"
dschinazi580d30b2019-04-26 15:05:20 -07008#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -05009#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
10
11namespace quic {
12namespace {
13
14using ::testing::Test;
15
16class TestProofHandler : public QuicCryptoClientStream::ProofHandler {
17 public:
18 ~TestProofHandler() override {}
19 void OnProofValid(
dschinazi17d42422019-06-18 16:35:07 -070020 const QuicCryptoClientConfig::CachedState& /*cached*/) override {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050021 void OnProofVerifyDetailsAvailable(
dschinazi17d42422019-06-18 16:35:07 -070022 const ProofVerifyDetails& /*verify_details*/) override {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050023};
24
25class InsecureProofVerifier : public ProofVerifier {
26 public:
27 InsecureProofVerifier() {}
28 ~InsecureProofVerifier() override {}
29
30 // ProofVerifier override.
31 QuicAsyncStatus VerifyProof(
dschinazi17d42422019-06-18 16:35:07 -070032 const std::string& /*hostname*/,
33 const uint16_t /*port*/,
34 const std::string& /*server_config*/,
35 QuicTransportVersion /*transport_version*/,
36 QuicStringPiece /*chlo_hash*/,
37 const std::vector<std::string>& /*certs*/,
38 const std::string& /*cert_sct*/,
39 const std::string& /*signature*/,
40 const ProofVerifyContext* /*context*/,
41 std::string* /*error_details*/,
42 std::unique_ptr<ProofVerifyDetails>* /*verify_details*/,
43 std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -050044 return QUIC_SUCCESS;
45 }
46
47 QuicAsyncStatus VerifyCertChain(
dschinazi17d42422019-06-18 16:35:07 -070048 const std::string& /*hostname*/,
49 const std::vector<std::string>& /*certs*/,
50 const std::string& /*ocsp_response*/,
51 const std::string& /*cert_sct*/,
52 const ProofVerifyContext* /*context*/,
53 std::string* /*error_details*/,
54 std::unique_ptr<ProofVerifyDetails>* /*details*/,
55 std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -050056 return QUIC_SUCCESS;
57 }
58
59 std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
60 return nullptr;
61 }
62};
63
64class DummyProofSource : public ProofSource {
65 public:
66 DummyProofSource() {}
67 ~DummyProofSource() override {}
68
69 // ProofSource override.
70 void GetProof(const QuicSocketAddress& server_address,
vasilvvc48c8712019-03-11 13:38:16 -070071 const std::string& hostname,
dschinazi17d42422019-06-18 16:35:07 -070072 const std::string& /*server_config*/,
73 QuicTransportVersion /*transport_version*/,
74 QuicStringPiece /*chlo_hash*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -050075 std::unique_ptr<Callback> callback) override {
76 QuicReferenceCountedPointer<ProofSource::Chain> chain =
77 GetCertChain(server_address, hostname);
78 QuicCryptoProof proof;
79 proof.signature = "Dummy signature";
80 proof.leaf_cert_scts = "Dummy timestamp";
dschinazi17d42422019-06-18 16:35:07 -070081 callback->Run(true, chain, proof, /*details=*/nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -050082 }
83
84 QuicReferenceCountedPointer<Chain> GetCertChain(
dschinazi17d42422019-06-18 16:35:07 -070085 const QuicSocketAddress& /*server_address*/,
86 const std::string& /*hostname*/) override {
vasilvvc48c8712019-03-11 13:38:16 -070087 std::vector<std::string> certs;
QUICHE teama6ef0a62019-03-07 20:34:33 -050088 certs.push_back("Dummy cert");
89 return QuicReferenceCountedPointer<ProofSource::Chain>(
90 new ProofSource::Chain(certs));
91 }
92
93 void ComputeTlsSignature(
dschinazi17d42422019-06-18 16:35:07 -070094 const QuicSocketAddress& /*server_address*/,
95 const std::string& /*hostname*/,
96 uint16_t /*signature_algorit*/,
97 QuicStringPiece /*in*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -050098 std::unique_ptr<SignatureCallback> callback) override {
99 callback->Run(true, "Dummy signature");
100 }
101};
102
103class Handshaker : public QuicCryptoClientHandshaker {
104 public:
105 Handshaker(const QuicServerId& server_id,
106 QuicCryptoClientStream* stream,
107 QuicSession* session,
108 std::unique_ptr<ProofVerifyContext> verify_context,
109 QuicCryptoClientConfig* crypto_config,
110 QuicCryptoClientStream::ProofHandler* proof_handler)
111 : QuicCryptoClientHandshaker(server_id,
112 stream,
113 session,
114 std::move(verify_context),
115 crypto_config,
116 proof_handler) {}
117
118 void DoSendCHLOTest(QuicCryptoClientConfig::CachedState* cached) {
119 QuicCryptoClientHandshaker::DoSendCHLO(cached);
120 }
121};
122
123class QuicCryptoClientHandshakerTest : public Test {
124 protected:
125 QuicCryptoClientHandshakerTest()
126 : proof_handler_(),
127 helper_(),
128 alarm_factory_(),
129 server_id_("host", 123),
130 connection_(new test::MockQuicConnection(&helper_,
131 &alarm_factory_,
132 Perspective::IS_CLIENT)),
133 session_(connection_, false),
nharper6ebe83b2019-06-13 17:43:52 -0700134 crypto_client_config_(QuicMakeUnique<InsecureProofVerifier>()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500135 client_stream_(new QuicCryptoClientStream(server_id_,
136 &session_,
137 nullptr,
138 &crypto_client_config_,
139 &proof_handler_)),
140 handshaker_(server_id_,
141 client_stream_,
142 &session_,
143 nullptr,
144 &crypto_client_config_,
145 &proof_handler_),
146 state_() {
147 // Session takes the ownership of the client stream! (but handshaker also
148 // takes a reference to it, but doesn't take the ownership).
149 session_.SetCryptoStream(client_stream_);
150 session_.Initialize();
151 }
152
153 void InitializeServerParametersToEnableFullHello() {
154 QuicCryptoServerConfig::ConfigOptions options;
QUICHE teambbaa8be2019-03-21 12:54:17 -0700155 QuicServerConfigProtobuf config = QuicCryptoServerConfig::GenerateConfig(
156 helper_.GetRandomGenerator(), helper_.GetClock(), options);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500157 state_.Initialize(
QUICHE teambbaa8be2019-03-21 12:54:17 -0700158 config.config(), "sourcetoken", std::vector<std::string>{"Dummy cert"},
QUICHE teama6ef0a62019-03-07 20:34:33 -0500159 "", "chlo_hash", "signature", helper_.GetClock()->WallNow(),
160 helper_.GetClock()->WallNow().Add(QuicTime::Delta::FromSeconds(30)));
161
162 state_.SetProofValid();
163 }
164
165 TestProofHandler proof_handler_;
166 test::MockQuicConnectionHelper helper_;
167 test::MockAlarmFactory alarm_factory_;
168 QuicServerId server_id_;
169 // Session takes the ownership of the connection.
170 test::MockQuicConnection* connection_;
171 test::MockQuicSession session_;
172 QuicCryptoClientConfig crypto_client_config_;
173 QuicCryptoClientStream* client_stream_;
174 Handshaker handshaker_;
175 QuicCryptoClientConfig::CachedState state_;
176};
177
178TEST_F(QuicCryptoClientHandshakerTest, TestSendFullPaddingInInchoateHello) {
179 handshaker_.DoSendCHLOTest(&state_);
180
181 EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
182}
183
184TEST_F(QuicCryptoClientHandshakerTest, TestDisabledPaddingInInchoateHello) {
185 crypto_client_config_.set_pad_inchoate_hello(false);
186 handshaker_.DoSendCHLOTest(&state_);
187 EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
188}
189
190TEST_F(QuicCryptoClientHandshakerTest,
191 TestPaddingInFullHelloEvenIfInchoateDisabled) {
192 // Disable inchoate, but full hello should still be padded.
193 crypto_client_config_.set_pad_inchoate_hello(false);
194
195 InitializeServerParametersToEnableFullHello();
196
197 handshaker_.DoSendCHLOTest(&state_);
198 EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
199}
200
201TEST_F(QuicCryptoClientHandshakerTest, TestNoPaddingInFullHelloWhenDisabled) {
202 crypto_client_config_.set_pad_full_hello(false);
203
204 InitializeServerParametersToEnableFullHello();
205
206 handshaker_.DoSendCHLOTest(&state_);
207 EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
208}
209
210} // namespace
211} // namespace quic