blob: bf804711d8a4e9aa1ced4d58358ae1d0e0ffd56c [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);
181 break;
182 }
183
184 case COLD_START: {
185 handshake_confirmed_ = false;
186 encryption_established_ = false;
187 break;
188 }
189
Zhongyi Shi879659422018-08-02 17:58:25190 case COLD_START_WITH_CHLO_SENT: {
191 handshake_confirmed_ = false;
192 encryption_established_ = false;
Zhongyi Shi5068bb02018-08-03 02:44:09193 SendHandshakeMessage(GetDummyCHLOMessage());
Ryan Hamilton56b10c5d2018-05-11 13:40:16194 break;
195 }
196 }
197
198 return session()->connection()->connected();
199}
200
201bool MockCryptoClientStream::encryption_established() const {
202 return encryption_established_;
203}
204
205bool MockCryptoClientStream::handshake_confirmed() const {
206 return handshake_confirmed_;
207}
208
209const QuicCryptoNegotiatedParameters&
210MockCryptoClientStream::crypto_negotiated_params() const {
211 return *crypto_negotiated_params_;
212}
213
214CryptoMessageParser* MockCryptoClientStream::crypto_message_parser() {
215 return &crypto_framer_;
216}
217
218void MockCryptoClientStream::SendOnCryptoHandshakeEvent(
219 QuicSession::CryptoHandshakeEvent event) {
220 encryption_established_ = true;
221 if (event == QuicSession::HANDSHAKE_CONFIRMED) {
222 handshake_confirmed_ = true;
223 SetConfigNegotiated();
224 if (use_mock_crypter_) {
Zhongyi Shi2d8d8c22019-04-13 00:06:17225 if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
226 session()->connection()->InstallDecrypter(
227 ENCRYPTION_FORWARD_SECURE,
228 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
229 } else {
230 session()->connection()->SetDecrypter(
231 ENCRYPTION_FORWARD_SECURE,
232 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
233 }
Ryan Hamilton56b10c5d2018-05-11 13:40:16234 session()->connection()->SetEncrypter(
235 ENCRYPTION_FORWARD_SECURE,
236 QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
237 } else {
Zhongyi Shi2d8d8c22019-04-13 00:06:17238 if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
239 session()->connection()->InstallDecrypter(
240 ENCRYPTION_FORWARD_SECURE,
241 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
242 } else {
243 session()->connection()->SetDecrypter(
244 ENCRYPTION_FORWARD_SECURE,
245 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
246 }
Ryan Hamilton56b10c5d2018-05-11 13:40:16247 session()->connection()->SetEncrypter(
248 ENCRYPTION_FORWARD_SECURE,
249 QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
250 }
251 session()->connection()->SetDefaultEncryptionLevel(
252 ENCRYPTION_FORWARD_SECURE);
253 }
254 session()->OnCryptoHandshakeEvent(event);
255}
256
Zhongyi Shi879659422018-08-02 17:58:25257// static
258CryptoHandshakeMessage MockCryptoClientStream::GetDummyCHLOMessage() {
259 CryptoHandshakeMessage message;
260 message.set_tag(quic::kCHLO);
261 return message;
262}
263
Ryan Hamilton56b10c5d2018-05-11 13:40:16264void MockCryptoClientStream::SetConfigNegotiated() {
265 ASSERT_FALSE(session()->config()->negotiated());
266 QuicTagVector cgst;
267// TODO(rtenneti): Enable the following code after BBR code is checked in.
268#if 0
269 cgst.push_back(kTBBR);
270#endif
271 cgst.push_back(kQBIC);
272 QuicConfig config(config_);
273 config.SetIdleNetworkTimeout(
274 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
275 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
Ryan Hamilton56b10c5d2018-05-11 13:40:16276 config.SetBytesForConnectionIdToSend(PACKET_8BYTE_CONNECTION_ID);
Ryan Hamilton4aeec562019-05-17 21:22:52277 config.SetMaxIncomingBidirectionalStreamsToSend(
278 kDefaultMaxStreamsPerConnection / 2);
279 config.SetMaxIncomingUnidirectionalStreamsToSend(
280 kDefaultMaxStreamsPerConnection / 2);
Ryan Hamilton56b10c5d2018-05-11 13:40:16281
282 CryptoHandshakeMessage msg;
Ryan Hamilton4aeec562019-05-17 21:22:52283 config.ToHandshakeMessage(
284 &msg, session()->connection()->version().transport_version);
Victor Vasiliev076657c2019-03-12 02:46:43285 std::string error_details;
Ryan Hamilton56b10c5d2018-05-11 13:40:16286 const QuicErrorCode error =
287 session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
288 ASSERT_EQ(QUIC_NO_ERROR, error);
289 ASSERT_TRUE(session()->config()->negotiated());
290 session()->OnConfigNegotiated();
291}
292
Ryan Hamilton9835e662018-08-02 05:36:27293} // namespace net