blob: 52e4756d5b1a719cfbc904331b538cbd79d9ad0f [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;
Michael Warres167db3e2019-03-01 21:38:0323using quic::ENCRYPTION_ZERO_RTT;
Ryan Hamilton9835e662018-08-02 05:36:2724using quic::kAESG;
25using quic::kC255;
26using quic::kDefaultMaxStreamsPerConnection;
27using quic::kMaximumIdleTimeoutSecs;
28using quic::kQBIC;
29using quic::NullDecrypter;
30using quic::NullEncrypter;
31using quic::PACKET_8BYTE_CONNECTION_ID;
32using quic::Perspective;
33using quic::ProofVerifyContext;
34using quic::QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE;
35using quic::QUIC_NO_ERROR;
36using quic::QUIC_PROOF_INVALID;
37using quic::QuicConfig;
38using quic::QuicCryptoClientConfig;
39using quic::QuicCryptoNegotiatedParameters;
40using quic::QuicErrorCode;
41using quic::QuicMakeUnique;
42using quic::QuicServerId;
43using quic::QuicSession;
44using quic::QuicSpdyClientSessionBase;
Zhongyi Shi879659422018-08-02 17:58:2545using quic::QuicStringPiece;
Ryan Hamilton9835e662018-08-02 05:36:2746using quic::QuicTagVector;
47using quic::QuicTime;
Victor Vasiliev076657c2019-03-12 02:46:4348using std::string;
Ryan Hamilton9835e662018-08-02 05:36:2749
50namespace net {
Ryan Hamilton56b10c5d2018-05-11 13:40:1651
52MockCryptoClientStream::MockCryptoClientStream(
53 const QuicServerId& server_id,
54 QuicSpdyClientSessionBase* session,
Ryan Hamiltonf044c1b2018-07-24 00:00:1455 std::unique_ptr<ProofVerifyContext> verify_context,
Ryan Hamilton56b10c5d2018-05-11 13:40:1656 const QuicConfig& config,
57 QuicCryptoClientConfig* crypto_config,
58 HandshakeMode handshake_mode,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5259 const net::ProofVerifyDetailsChromium* proof_verify_details,
Ryan Hamilton56b10c5d2018-05-11 13:40:1660 bool use_mock_crypter)
61 : QuicCryptoClientStream(server_id,
62 session,
Ryan Hamiltonf044c1b2018-07-24 00:00:1463 std::move(verify_context),
Ryan Hamilton56b10c5d2018-05-11 13:40:1664 crypto_config,
65 session),
66 QuicCryptoHandshaker(this, session),
67 handshake_mode_(handshake_mode),
68 encryption_established_(false),
69 handshake_confirmed_(false),
70 crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
71 use_mock_crypter_(use_mock_crypter),
72 server_id_(server_id),
73 proof_verify_details_(proof_verify_details),
74 config_(config) {
75 crypto_framer_.set_visitor(this);
76}
77
78MockCryptoClientStream::~MockCryptoClientStream() {}
79
80void MockCryptoClientStream::OnHandshakeMessage(
81 const CryptoHandshakeMessage& message) {
82 CloseConnectionWithDetails(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
83 "Forced mock failure");
84}
85
86bool MockCryptoClientStream::CryptoConnect() {
87 if (proof_verify_details_) {
88 if (!proof_verify_details_->cert_verify_result.verified_cert
89 ->VerifyNameMatch(server_id_.host())) {
90 handshake_confirmed_ = false;
91 encryption_established_ = false;
92 session()->connection()->CloseConnection(
93 QUIC_PROOF_INVALID, "proof invalid",
94 ConnectionCloseBehavior::SILENT_CLOSE);
95 return false;
96 }
97 }
98
99 switch (handshake_mode_) {
100 case ZERO_RTT: {
101 encryption_established_ = true;
102 handshake_confirmed_ = false;
103 crypto_negotiated_params_->key_exchange = kC255;
104 crypto_negotiated_params_->aead = kAESG;
105 if (proof_verify_details_) {
106 reinterpret_cast<QuicSpdyClientSessionBase*>(session())
107 ->OnProofVerifyDetailsAvailable(*proof_verify_details_);
108 }
109 if (use_mock_crypter_) {
Zhongyi Shi2d8d8c22019-04-13 00:06:17110 if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
111 session()->connection()->InstallDecrypter(
112 ENCRYPTION_ZERO_RTT,
113 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
114 } else {
115 session()->connection()->SetDecrypter(
116 ENCRYPTION_ZERO_RTT,
117 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
118 }
Ryan Hamilton56b10c5d2018-05-11 13:40:16119 session()->connection()->SetEncrypter(
Michael Warres167db3e2019-03-01 21:38:03120 ENCRYPTION_ZERO_RTT,
Ryan Hamilton56b10c5d2018-05-11 13:40:16121 QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
122 } else {
Zhongyi Shi2d8d8c22019-04-13 00:06:17123 if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
124 session()->connection()->InstallDecrypter(
125 ENCRYPTION_ZERO_RTT,
126 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
127 } else {
128 session()->connection()->SetDecrypter(
129 ENCRYPTION_ZERO_RTT,
130 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
131 }
Ryan Hamilton56b10c5d2018-05-11 13:40:16132 session()->connection()->SetEncrypter(
Michael Warres167db3e2019-03-01 21:38:03133 ENCRYPTION_ZERO_RTT,
Ryan Hamilton56b10c5d2018-05-11 13:40:16134 QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
135 }
Michael Warres167db3e2019-03-01 21:38:03136 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
Ryan Hamilton05c0f592019-08-21 19:53:16137 session()->OnCryptoHandshakeEvent(QuicSession::ENCRYPTION_ESTABLISHED);
Ryan Hamilton56b10c5d2018-05-11 13:40:16138 break;
139 }
140
141 case CONFIRM_HANDSHAKE: {
142 encryption_established_ = true;
143 handshake_confirmed_ = true;
144 crypto_negotiated_params_->key_exchange = kC255;
145 crypto_negotiated_params_->aead = kAESG;
146 if (proof_verify_details_) {
147 reinterpret_cast<QuicSpdyClientSessionBase*>(session())
148 ->OnProofVerifyDetailsAvailable(*proof_verify_details_);
149 }
150 SetConfigNegotiated();
151 if (use_mock_crypter_) {
Zhongyi Shi2d8d8c22019-04-13 00:06:17152 if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
153 session()->connection()->InstallDecrypter(
154 ENCRYPTION_FORWARD_SECURE,
155 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
156 } else {
157 session()->connection()->SetDecrypter(
158 ENCRYPTION_FORWARD_SECURE,
159 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
160 }
Ryan Hamilton56b10c5d2018-05-11 13:40:16161 session()->connection()->SetEncrypter(
162 ENCRYPTION_FORWARD_SECURE,
163 QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
164 } else {
Zhongyi Shi2d8d8c22019-04-13 00:06:17165 if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
166 session()->connection()->InstallDecrypter(
167 ENCRYPTION_FORWARD_SECURE,
168 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
169 } else {
170 session()->connection()->SetDecrypter(
171 ENCRYPTION_FORWARD_SECURE,
172 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
173 }
Ryan Hamilton56b10c5d2018-05-11 13:40:16174 session()->connection()->SetEncrypter(
175 ENCRYPTION_FORWARD_SECURE,
176 QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
177 }
178 session()->connection()->SetDefaultEncryptionLevel(
179 ENCRYPTION_FORWARD_SECURE);
180 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
Fan Yang928cb042019-08-26 21:53:37181 session()->connection()->OnHandshakeComplete();
Ryan Hamilton56b10c5d2018-05-11 13:40:16182 break;
183 }
184
185 case COLD_START: {
186 handshake_confirmed_ = false;
187 encryption_established_ = false;
188 break;
189 }
190
Zhongyi Shi879659422018-08-02 17:58:25191 case COLD_START_WITH_CHLO_SENT: {
192 handshake_confirmed_ = false;
193 encryption_established_ = false;
Zhongyi Shi5068bb02018-08-03 02:44:09194 SendHandshakeMessage(GetDummyCHLOMessage());
Ryan Hamilton56b10c5d2018-05-11 13:40:16195 break;
196 }
197 }
198
199 return session()->connection()->connected();
200}
201
202bool MockCryptoClientStream::encryption_established() const {
203 return encryption_established_;
204}
205
206bool MockCryptoClientStream::handshake_confirmed() const {
207 return handshake_confirmed_;
208}
209
210const QuicCryptoNegotiatedParameters&
211MockCryptoClientStream::crypto_negotiated_params() const {
212 return *crypto_negotiated_params_;
213}
214
215CryptoMessageParser* MockCryptoClientStream::crypto_message_parser() {
216 return &crypto_framer_;
217}
218
219void MockCryptoClientStream::SendOnCryptoHandshakeEvent(
220 QuicSession::CryptoHandshakeEvent event) {
221 encryption_established_ = true;
222 if (event == QuicSession::HANDSHAKE_CONFIRMED) {
223 handshake_confirmed_ = true;
224 SetConfigNegotiated();
225 if (use_mock_crypter_) {
Zhongyi Shi2d8d8c22019-04-13 00:06:17226 if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
227 session()->connection()->InstallDecrypter(
228 ENCRYPTION_FORWARD_SECURE,
229 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
230 } else {
231 session()->connection()->SetDecrypter(
232 ENCRYPTION_FORWARD_SECURE,
233 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
234 }
Ryan Hamilton56b10c5d2018-05-11 13:40:16235 session()->connection()->SetEncrypter(
236 ENCRYPTION_FORWARD_SECURE,
237 QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
238 } else {
Zhongyi Shi2d8d8c22019-04-13 00:06:17239 if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
240 session()->connection()->InstallDecrypter(
241 ENCRYPTION_FORWARD_SECURE,
242 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
243 } else {
244 session()->connection()->SetDecrypter(
245 ENCRYPTION_FORWARD_SECURE,
246 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
247 }
Ryan Hamilton56b10c5d2018-05-11 13:40:16248 session()->connection()->SetEncrypter(
249 ENCRYPTION_FORWARD_SECURE,
250 QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
251 }
252 session()->connection()->SetDefaultEncryptionLevel(
253 ENCRYPTION_FORWARD_SECURE);
254 }
255 session()->OnCryptoHandshakeEvent(event);
256}
257
Zhongyi Shi879659422018-08-02 17:58:25258// static
259CryptoHandshakeMessage MockCryptoClientStream::GetDummyCHLOMessage() {
260 CryptoHandshakeMessage message;
261 message.set_tag(quic::kCHLO);
262 return message;
263}
264
Ryan Hamilton56b10c5d2018-05-11 13:40:16265void MockCryptoClientStream::SetConfigNegotiated() {
266 ASSERT_FALSE(session()->config()->negotiated());
267 QuicTagVector cgst;
268// TODO(rtenneti): Enable the following code after BBR code is checked in.
269#if 0
270 cgst.push_back(kTBBR);
271#endif
272 cgst.push_back(kQBIC);
273 QuicConfig config(config_);
274 config.SetIdleNetworkTimeout(
275 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
276 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
Ryan Hamilton56b10c5d2018-05-11 13:40:16277 config.SetBytesForConnectionIdToSend(PACKET_8BYTE_CONNECTION_ID);
Ryan Hamilton4aeec562019-05-17 21:22:52278 config.SetMaxIncomingBidirectionalStreamsToSend(
279 kDefaultMaxStreamsPerConnection / 2);
280 config.SetMaxIncomingUnidirectionalStreamsToSend(
281 kDefaultMaxStreamsPerConnection / 2);
Ryan Hamilton56b10c5d2018-05-11 13:40:16282
283 CryptoHandshakeMessage msg;
Ryan Hamilton4aeec562019-05-17 21:22:52284 config.ToHandshakeMessage(
285 &msg, session()->connection()->version().transport_version);
Victor Vasiliev076657c2019-03-12 02:46:43286 std::string error_details;
Ryan Hamilton56b10c5d2018-05-11 13:40:16287 const QuicErrorCode error =
288 session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
289 ASSERT_EQ(QUIC_NO_ERROR, error);
290 ASSERT_TRUE(session()->config()->negotiated());
291 session()->OnConfigNegotiated();
292}
293
Ryan Hamilton9835e662018-08-02 05:36:27294} // namespace net