blob: 58515668dbb681a5fd2ca40754bcdda357debb13 [file] [log] [blame]
Ryan Hamilton56b10c5d2018-05-11 13:40:161// Copyright (c) 2013 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 Hamilton7582d2652018-08-01 22:35:325#include "net/quic/mock_crypto_client_stream.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:166
Ryan Hamilton7582d2652018-08-01 22:35:327#include "net/quic/mock_decrypter.h"
8#include "net/quic/mock_encrypter.h"
Victor Vasiliev6bb59d22019-03-08 21:34:519#include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h"
10#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
11#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
12#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
13#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h"
14#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
15#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1616#include "testing/gtest/include/gtest/gtest.h"
17
Ryan Hamilton9835e662018-08-02 05:36:2718using quic::CLIENT;
19using quic::ConnectionCloseBehavior;
20using quic::CryptoHandshakeMessage;
21using quic::CryptoMessageParser;
22using quic::ENCRYPTION_FORWARD_SECURE;
David Schinazi09e9a6012019-10-03 17:37:5723using quic::ENCRYPTION_INITIAL;
Michael Warres167db3e2019-03-01 21:38:0324using quic::ENCRYPTION_ZERO_RTT;
Ryan Hamilton9835e662018-08-02 05:36:2725using quic::kAESG;
26using quic::kC255;
27using quic::kDefaultMaxStreamsPerConnection;
28using quic::kMaximumIdleTimeoutSecs;
29using quic::kQBIC;
30using quic::NullDecrypter;
31using quic::NullEncrypter;
32using quic::PACKET_8BYTE_CONNECTION_ID;
33using quic::Perspective;
34using quic::ProofVerifyContext;
35using quic::QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE;
36using quic::QUIC_NO_ERROR;
37using quic::QUIC_PROOF_INVALID;
38using quic::QuicConfig;
39using quic::QuicCryptoClientConfig;
40using quic::QuicCryptoNegotiatedParameters;
41using quic::QuicErrorCode;
42using quic::QuicMakeUnique;
43using quic::QuicServerId;
44using quic::QuicSession;
45using quic::QuicSpdyClientSessionBase;
Zhongyi Shi879659422018-08-02 17:58:2546using quic::QuicStringPiece;
Ryan Hamilton9835e662018-08-02 05:36:2747using quic::QuicTagVector;
48using quic::QuicTime;
Victor Vasiliev076657c2019-03-12 02:46:4349using std::string;
Ryan Hamilton9835e662018-08-02 05:36:2750
51namespace net {
Ryan Hamilton56b10c5d2018-05-11 13:40:1652
53MockCryptoClientStream::MockCryptoClientStream(
54 const QuicServerId& server_id,
55 QuicSpdyClientSessionBase* session,
Ryan Hamiltonf044c1b2018-07-24 00:00:1456 std::unique_ptr<ProofVerifyContext> verify_context,
Ryan Hamilton56b10c5d2018-05-11 13:40:1657 const QuicConfig& config,
58 QuicCryptoClientConfig* crypto_config,
59 HandshakeMode handshake_mode,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5260 const net::ProofVerifyDetailsChromium* proof_verify_details,
Ryan Hamilton56b10c5d2018-05-11 13:40:1661 bool use_mock_crypter)
62 : QuicCryptoClientStream(server_id,
63 session,
Ryan Hamiltonf044c1b2018-07-24 00:00:1464 std::move(verify_context),
Ryan Hamilton56b10c5d2018-05-11 13:40:1665 crypto_config,
66 session),
67 QuicCryptoHandshaker(this, session),
68 handshake_mode_(handshake_mode),
69 encryption_established_(false),
70 handshake_confirmed_(false),
71 crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
72 use_mock_crypter_(use_mock_crypter),
73 server_id_(server_id),
74 proof_verify_details_(proof_verify_details),
75 config_(config) {
76 crypto_framer_.set_visitor(this);
77}
78
79MockCryptoClientStream::~MockCryptoClientStream() {}
80
81void MockCryptoClientStream::OnHandshakeMessage(
82 const CryptoHandshakeMessage& message) {
83 CloseConnectionWithDetails(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
84 "Forced mock failure");
85}
86
87bool MockCryptoClientStream::CryptoConnect() {
88 if (proof_verify_details_) {
89 if (!proof_verify_details_->cert_verify_result.verified_cert
90 ->VerifyNameMatch(server_id_.host())) {
91 handshake_confirmed_ = false;
92 encryption_established_ = false;
93 session()->connection()->CloseConnection(
94 QUIC_PROOF_INVALID, "proof invalid",
95 ConnectionCloseBehavior::SILENT_CLOSE);
96 return false;
97 }
98 }
99
100 switch (handshake_mode_) {
101 case ZERO_RTT: {
102 encryption_established_ = true;
103 handshake_confirmed_ = false;
104 crypto_negotiated_params_->key_exchange = kC255;
105 crypto_negotiated_params_->aead = kAESG;
106 if (proof_verify_details_) {
107 reinterpret_cast<QuicSpdyClientSessionBase*>(session())
108 ->OnProofVerifyDetailsAvailable(*proof_verify_details_);
109 }
110 if (use_mock_crypter_) {
Zhongyi Shi2d8d8c22019-04-13 00:06:17111 if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
112 session()->connection()->InstallDecrypter(
113 ENCRYPTION_ZERO_RTT,
114 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
115 } else {
116 session()->connection()->SetDecrypter(
117 ENCRYPTION_ZERO_RTT,
118 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
119 }
Ryan Hamilton56b10c5d2018-05-11 13:40:16120 session()->connection()->SetEncrypter(
Michael Warres167db3e2019-03-01 21:38:03121 ENCRYPTION_ZERO_RTT,
Ryan Hamilton56b10c5d2018-05-11 13:40:16122 QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
123 } else {
Zhongyi Shi2d8d8c22019-04-13 00:06:17124 if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
125 session()->connection()->InstallDecrypter(
126 ENCRYPTION_ZERO_RTT,
127 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
128 } else {
129 session()->connection()->SetDecrypter(
130 ENCRYPTION_ZERO_RTT,
131 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
132 }
Ryan Hamilton56b10c5d2018-05-11 13:40:16133 session()->connection()->SetEncrypter(
Michael Warres167db3e2019-03-01 21:38:03134 ENCRYPTION_ZERO_RTT,
Ryan Hamilton56b10c5d2018-05-11 13:40:16135 QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
136 }
Michael Warres167db3e2019-03-01 21:38:03137 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
Ryan Hamilton05c0f592019-08-21 19:53:16138 session()->OnCryptoHandshakeEvent(QuicSession::ENCRYPTION_ESTABLISHED);
Ryan Hamilton56b10c5d2018-05-11 13:40:16139 break;
140 }
141
142 case CONFIRM_HANDSHAKE: {
143 encryption_established_ = true;
144 handshake_confirmed_ = true;
145 crypto_negotiated_params_->key_exchange = kC255;
146 crypto_negotiated_params_->aead = kAESG;
147 if (proof_verify_details_) {
148 reinterpret_cast<QuicSpdyClientSessionBase*>(session())
149 ->OnProofVerifyDetailsAvailable(*proof_verify_details_);
150 }
151 SetConfigNegotiated();
152 if (use_mock_crypter_) {
Zhongyi Shi2d8d8c22019-04-13 00:06:17153 if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
154 session()->connection()->InstallDecrypter(
155 ENCRYPTION_FORWARD_SECURE,
156 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
157 } else {
158 session()->connection()->SetDecrypter(
159 ENCRYPTION_FORWARD_SECURE,
160 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
161 }
Ryan Hamilton56b10c5d2018-05-11 13:40:16162 session()->connection()->SetEncrypter(
163 ENCRYPTION_FORWARD_SECURE,
164 QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
165 } else {
Zhongyi Shi2d8d8c22019-04-13 00:06:17166 if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
167 session()->connection()->InstallDecrypter(
168 ENCRYPTION_FORWARD_SECURE,
169 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
170 } else {
171 session()->connection()->SetDecrypter(
172 ENCRYPTION_FORWARD_SECURE,
173 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
174 }
David Schinazi09e9a6012019-10-03 17:37:57175 session()->connection()->SetEncrypter(ENCRYPTION_INITIAL, nullptr);
Ryan Hamilton56b10c5d2018-05-11 13:40:16176 session()->connection()->SetEncrypter(
177 ENCRYPTION_FORWARD_SECURE,
178 QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
179 }
180 session()->connection()->SetDefaultEncryptionLevel(
181 ENCRYPTION_FORWARD_SECURE);
182 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
Fan Yang928cb042019-08-26 21:53:37183 session()->connection()->OnHandshakeComplete();
Ryan Hamilton56b10c5d2018-05-11 13:40:16184 break;
185 }
186
187 case COLD_START: {
188 handshake_confirmed_ = false;
189 encryption_established_ = false;
190 break;
191 }
192
Zhongyi Shi879659422018-08-02 17:58:25193 case COLD_START_WITH_CHLO_SENT: {
194 handshake_confirmed_ = false;
195 encryption_established_ = false;
Zhongyi Shi5068bb02018-08-03 02:44:09196 SendHandshakeMessage(GetDummyCHLOMessage());
Ryan Hamilton56b10c5d2018-05-11 13:40:16197 break;
198 }
199 }
200
201 return session()->connection()->connected();
202}
203
204bool MockCryptoClientStream::encryption_established() const {
205 return encryption_established_;
206}
207
208bool MockCryptoClientStream::handshake_confirmed() const {
209 return handshake_confirmed_;
210}
211
212const QuicCryptoNegotiatedParameters&
213MockCryptoClientStream::crypto_negotiated_params() const {
214 return *crypto_negotiated_params_;
215}
216
217CryptoMessageParser* MockCryptoClientStream::crypto_message_parser() {
218 return &crypto_framer_;
219}
220
221void MockCryptoClientStream::SendOnCryptoHandshakeEvent(
222 QuicSession::CryptoHandshakeEvent event) {
223 encryption_established_ = true;
224 if (event == QuicSession::HANDSHAKE_CONFIRMED) {
225 handshake_confirmed_ = true;
226 SetConfigNegotiated();
227 if (use_mock_crypter_) {
Zhongyi Shi2d8d8c22019-04-13 00:06:17228 if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
229 session()->connection()->InstallDecrypter(
230 ENCRYPTION_FORWARD_SECURE,
231 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
232 } else {
233 session()->connection()->SetDecrypter(
234 ENCRYPTION_FORWARD_SECURE,
235 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
236 }
Ryan Hamilton56b10c5d2018-05-11 13:40:16237 session()->connection()->SetEncrypter(
238 ENCRYPTION_FORWARD_SECURE,
239 QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
240 } else {
Zhongyi Shi2d8d8c22019-04-13 00:06:17241 if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
242 session()->connection()->InstallDecrypter(
243 ENCRYPTION_FORWARD_SECURE,
244 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
245 } else {
246 session()->connection()->SetDecrypter(
247 ENCRYPTION_FORWARD_SECURE,
248 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
249 }
David Schinazi09e9a6012019-10-03 17:37:57250 session()->connection()->SetEncrypter(ENCRYPTION_INITIAL, nullptr);
Ryan Hamilton56b10c5d2018-05-11 13:40:16251 session()->connection()->SetEncrypter(
252 ENCRYPTION_FORWARD_SECURE,
253 QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
254 }
255 session()->connection()->SetDefaultEncryptionLevel(
256 ENCRYPTION_FORWARD_SECURE);
257 }
258 session()->OnCryptoHandshakeEvent(event);
259}
260
Zhongyi Shi879659422018-08-02 17:58:25261// static
262CryptoHandshakeMessage MockCryptoClientStream::GetDummyCHLOMessage() {
263 CryptoHandshakeMessage message;
264 message.set_tag(quic::kCHLO);
265 return message;
266}
267
Ryan Hamilton56b10c5d2018-05-11 13:40:16268void MockCryptoClientStream::SetConfigNegotiated() {
269 ASSERT_FALSE(session()->config()->negotiated());
270 QuicTagVector cgst;
271// TODO(rtenneti): Enable the following code after BBR code is checked in.
272#if 0
273 cgst.push_back(kTBBR);
274#endif
275 cgst.push_back(kQBIC);
276 QuicConfig config(config_);
277 config.SetIdleNetworkTimeout(
278 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
279 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
Ryan Hamilton56b10c5d2018-05-11 13:40:16280 config.SetBytesForConnectionIdToSend(PACKET_8BYTE_CONNECTION_ID);
Ryan Hamilton4aeec562019-05-17 21:22:52281 config.SetMaxIncomingBidirectionalStreamsToSend(
282 kDefaultMaxStreamsPerConnection / 2);
283 config.SetMaxIncomingUnidirectionalStreamsToSend(
284 kDefaultMaxStreamsPerConnection / 2);
Ryan Hamilton56b10c5d2018-05-11 13:40:16285
286 CryptoHandshakeMessage msg;
Ryan Hamilton4aeec562019-05-17 21:22:52287 config.ToHandshakeMessage(
288 &msg, session()->connection()->version().transport_version);
Victor Vasiliev076657c2019-03-12 02:46:43289 std::string error_details;
Ryan Hamilton56b10c5d2018-05-11 13:40:16290 const QuicErrorCode error =
291 session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
292 ASSERT_EQ(QUIC_NO_ERROR, error);
293 ASSERT_TRUE(session()->config()->negotiated());
294 session()->OnConfigNegotiated();
295}
296
Ryan Hamilton9835e662018-08-02 05:36:27297} // namespace net