blob: 30dcbfce7a2120195f4a5955f3bdfb1f411f60c3 [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"
dmcardlecf0bfcf2019-12-13 08:08:21 -080012#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050013
14namespace quic {
15namespace {
16
17using ::testing::Test;
18
19class TestProofHandler : public QuicCryptoClientStream::ProofHandler {
20 public:
21 ~TestProofHandler() override {}
22 void OnProofValid(
dschinazi17d42422019-06-18 16:35:07 -070023 const QuicCryptoClientConfig::CachedState& /*cached*/) override {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050024 void OnProofVerifyDetailsAvailable(
dschinazi17d42422019-06-18 16:35:07 -070025 const ProofVerifyDetails& /*verify_details*/) override {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050026};
27
28class InsecureProofVerifier : public ProofVerifier {
29 public:
30 InsecureProofVerifier() {}
31 ~InsecureProofVerifier() override {}
32
33 // ProofVerifier override.
34 QuicAsyncStatus VerifyProof(
dschinazi17d42422019-06-18 16:35:07 -070035 const std::string& /*hostname*/,
36 const uint16_t /*port*/,
37 const std::string& /*server_config*/,
38 QuicTransportVersion /*transport_version*/,
dmcardlecf0bfcf2019-12-13 08:08:21 -080039 quiche::QuicheStringPiece /*chlo_hash*/,
dschinazi17d42422019-06-18 16:35:07 -070040 const std::vector<std::string>& /*certs*/,
41 const std::string& /*cert_sct*/,
42 const std::string& /*signature*/,
43 const ProofVerifyContext* /*context*/,
44 std::string* /*error_details*/,
45 std::unique_ptr<ProofVerifyDetails>* /*verify_details*/,
46 std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -050047 return QUIC_SUCCESS;
48 }
49
50 QuicAsyncStatus VerifyCertChain(
dschinazi17d42422019-06-18 16:35:07 -070051 const std::string& /*hostname*/,
52 const std::vector<std::string>& /*certs*/,
53 const std::string& /*ocsp_response*/,
54 const std::string& /*cert_sct*/,
55 const ProofVerifyContext* /*context*/,
56 std::string* /*error_details*/,
57 std::unique_ptr<ProofVerifyDetails>* /*details*/,
58 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,
vasilvvc48c8712019-03-11 13:38:16 -070074 const std::string& hostname,
dschinazi17d42422019-06-18 16:35:07 -070075 const std::string& /*server_config*/,
76 QuicTransportVersion /*transport_version*/,
dmcardlecf0bfcf2019-12-13 08:08:21 -080077 quiche::QuicheStringPiece /*chlo_hash*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -050078 std::unique_ptr<Callback> callback) override {
79 QuicReferenceCountedPointer<ProofSource::Chain> chain =
80 GetCertChain(server_address, hostname);
81 QuicCryptoProof proof;
82 proof.signature = "Dummy signature";
83 proof.leaf_cert_scts = "Dummy timestamp";
dschinazi17d42422019-06-18 16:35:07 -070084 callback->Run(true, chain, proof, /*details=*/nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -050085 }
86
87 QuicReferenceCountedPointer<Chain> GetCertChain(
dschinazi17d42422019-06-18 16:35:07 -070088 const QuicSocketAddress& /*server_address*/,
89 const std::string& /*hostname*/) override {
vasilvvc48c8712019-03-11 13:38:16 -070090 std::vector<std::string> certs;
QUICHE teama6ef0a62019-03-07 20:34:33 -050091 certs.push_back("Dummy cert");
92 return QuicReferenceCountedPointer<ProofSource::Chain>(
93 new ProofSource::Chain(certs));
94 }
95
96 void ComputeTlsSignature(
dschinazi17d42422019-06-18 16:35:07 -070097 const QuicSocketAddress& /*server_address*/,
98 const std::string& /*hostname*/,
99 uint16_t /*signature_algorit*/,
dmcardlecf0bfcf2019-12-13 08:08:21 -0800100 quiche::QuicheStringPiece /*in*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500101 std::unique_ptr<SignatureCallback> callback) override {
102 callback->Run(true, "Dummy signature");
103 }
104};
105
106class Handshaker : public QuicCryptoClientHandshaker {
107 public:
108 Handshaker(const QuicServerId& server_id,
109 QuicCryptoClientStream* stream,
110 QuicSession* session,
111 std::unique_ptr<ProofVerifyContext> verify_context,
112 QuicCryptoClientConfig* crypto_config,
113 QuicCryptoClientStream::ProofHandler* proof_handler)
114 : QuicCryptoClientHandshaker(server_id,
115 stream,
116 session,
117 std::move(verify_context),
118 crypto_config,
119 proof_handler) {}
120
121 void DoSendCHLOTest(QuicCryptoClientConfig::CachedState* cached) {
122 QuicCryptoClientHandshaker::DoSendCHLO(cached);
123 }
124};
125
126class QuicCryptoClientHandshakerTest : public Test {
127 protected:
128 QuicCryptoClientHandshakerTest()
129 : proof_handler_(),
130 helper_(),
131 alarm_factory_(),
132 server_id_("host", 123),
133 connection_(new test::MockQuicConnection(&helper_,
134 &alarm_factory_,
135 Perspective::IS_CLIENT)),
136 session_(connection_, false),
vasilvv0fc587f2019-09-06 13:33:08 -0700137 crypto_client_config_(std::make_unique<InsecureProofVerifier>()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500138 client_stream_(new QuicCryptoClientStream(server_id_,
139 &session_,
140 nullptr,
141 &crypto_client_config_,
142 &proof_handler_)),
143 handshaker_(server_id_,
144 client_stream_,
145 &session_,
146 nullptr,
147 &crypto_client_config_,
148 &proof_handler_),
149 state_() {
150 // Session takes the ownership of the client stream! (but handshaker also
151 // takes a reference to it, but doesn't take the ownership).
152 session_.SetCryptoStream(client_stream_);
153 session_.Initialize();
154 }
155
156 void InitializeServerParametersToEnableFullHello() {
157 QuicCryptoServerConfig::ConfigOptions options;
QUICHE teambbaa8be2019-03-21 12:54:17 -0700158 QuicServerConfigProtobuf config = QuicCryptoServerConfig::GenerateConfig(
159 helper_.GetRandomGenerator(), helper_.GetClock(), options);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500160 state_.Initialize(
QUICHE teambbaa8be2019-03-21 12:54:17 -0700161 config.config(), "sourcetoken", std::vector<std::string>{"Dummy cert"},
QUICHE teama6ef0a62019-03-07 20:34:33 -0500162 "", "chlo_hash", "signature", helper_.GetClock()->WallNow(),
163 helper_.GetClock()->WallNow().Add(QuicTime::Delta::FromSeconds(30)));
164
165 state_.SetProofValid();
166 }
167
168 TestProofHandler proof_handler_;
169 test::MockQuicConnectionHelper helper_;
170 test::MockAlarmFactory alarm_factory_;
171 QuicServerId server_id_;
172 // Session takes the ownership of the connection.
173 test::MockQuicConnection* connection_;
174 test::MockQuicSession session_;
175 QuicCryptoClientConfig crypto_client_config_;
176 QuicCryptoClientStream* client_stream_;
177 Handshaker handshaker_;
178 QuicCryptoClientConfig::CachedState state_;
179};
180
181TEST_F(QuicCryptoClientHandshakerTest, TestSendFullPaddingInInchoateHello) {
182 handshaker_.DoSendCHLOTest(&state_);
183
184 EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
185}
186
187TEST_F(QuicCryptoClientHandshakerTest, TestDisabledPaddingInInchoateHello) {
188 crypto_client_config_.set_pad_inchoate_hello(false);
189 handshaker_.DoSendCHLOTest(&state_);
190 EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
191}
192
193TEST_F(QuicCryptoClientHandshakerTest,
194 TestPaddingInFullHelloEvenIfInchoateDisabled) {
195 // Disable inchoate, but full hello should still be padded.
196 crypto_client_config_.set_pad_inchoate_hello(false);
197
198 InitializeServerParametersToEnableFullHello();
199
200 handshaker_.DoSendCHLOTest(&state_);
201 EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
202}
203
204TEST_F(QuicCryptoClientHandshakerTest, TestNoPaddingInFullHelloWhenDisabled) {
205 crypto_client_config_.set_pad_full_hello(false);
206
207 InitializeServerParametersToEnableFullHello();
208
209 handshaker_.DoSendCHLOTest(&state_);
210 EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
211}
212
213} // namespace
214} // namespace quic