blob: ce94f88f48694a5e7e79f0785683baf92c45e5f8 [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"
Ryan Hamilton56b10c5d2018-05-11 13:40:169#include "net/third_party/quic/core/crypto/null_decrypter.h"
10#include "net/third_party/quic/core/crypto/null_encrypter.h"
11#include "net/third_party/quic/core/crypto/quic_decrypter.h"
12#include "net/third_party/quic/core/crypto/quic_encrypter.h"
Victor Vasilievc5b409c22018-07-24 12:23:4613#include "net/third_party/quic/core/http/quic_spdy_client_session_base.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1614#include "net/third_party/quic/platform/api/quic_ptr_util.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1615#include "net/third_party/quic/test_tools/quic_config_peer.h"
16#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;
23using quic::ENCRYPTION_INITIAL;
24using 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;
45using quic::QuicString;
Zhongyi Shi879659422018-08-02 17:58:2546using quic::QuicStringPiece;
Ryan Hamilton9835e662018-08-02 05:36:2747using quic::QuicTagVector;
48using quic::QuicTime;
49
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_) {
110 session()->connection()->SetDecrypter(
111 ENCRYPTION_INITIAL,
112 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
113 session()->connection()->SetEncrypter(
114 ENCRYPTION_INITIAL,
115 QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
116 } else {
117 session()->connection()->SetDecrypter(
118 ENCRYPTION_INITIAL,
119 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
120 session()->connection()->SetEncrypter(
121 ENCRYPTION_INITIAL,
122 QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
123 }
124 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
125 session()->OnCryptoHandshakeEvent(
126 QuicSession::ENCRYPTION_FIRST_ESTABLISHED);
127 break;
128 }
129
130 case CONFIRM_HANDSHAKE: {
131 encryption_established_ = true;
132 handshake_confirmed_ = true;
133 crypto_negotiated_params_->key_exchange = kC255;
134 crypto_negotiated_params_->aead = kAESG;
135 if (proof_verify_details_) {
136 reinterpret_cast<QuicSpdyClientSessionBase*>(session())
137 ->OnProofVerifyDetailsAvailable(*proof_verify_details_);
138 }
139 SetConfigNegotiated();
140 if (use_mock_crypter_) {
141 session()->connection()->SetDecrypter(
142 ENCRYPTION_FORWARD_SECURE,
143 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
144 session()->connection()->SetEncrypter(
145 ENCRYPTION_FORWARD_SECURE,
146 QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
147 } else {
148 session()->connection()->SetDecrypter(
149 ENCRYPTION_FORWARD_SECURE,
150 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
151 session()->connection()->SetEncrypter(
152 ENCRYPTION_FORWARD_SECURE,
153 QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
154 }
155 session()->connection()->SetDefaultEncryptionLevel(
156 ENCRYPTION_FORWARD_SECURE);
157 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
158 break;
159 }
160
161 case COLD_START: {
162 handshake_confirmed_ = false;
163 encryption_established_ = false;
164 break;
165 }
166
Zhongyi Shi879659422018-08-02 17:58:25167 case COLD_START_WITH_CHLO_SENT: {
168 handshake_confirmed_ = false;
169 encryption_established_ = false;
Zhongyi Shi5068bb02018-08-03 02:44:09170 SendHandshakeMessage(GetDummyCHLOMessage());
Ryan Hamilton56b10c5d2018-05-11 13:40:16171 break;
172 }
173 }
174
175 return session()->connection()->connected();
176}
177
178bool MockCryptoClientStream::encryption_established() const {
179 return encryption_established_;
180}
181
182bool MockCryptoClientStream::handshake_confirmed() const {
183 return handshake_confirmed_;
184}
185
186const QuicCryptoNegotiatedParameters&
187MockCryptoClientStream::crypto_negotiated_params() const {
188 return *crypto_negotiated_params_;
189}
190
191CryptoMessageParser* MockCryptoClientStream::crypto_message_parser() {
192 return &crypto_framer_;
193}
194
195void MockCryptoClientStream::SendOnCryptoHandshakeEvent(
196 QuicSession::CryptoHandshakeEvent event) {
197 encryption_established_ = true;
198 if (event == QuicSession::HANDSHAKE_CONFIRMED) {
199 handshake_confirmed_ = true;
200 SetConfigNegotiated();
201 if (use_mock_crypter_) {
202 session()->connection()->SetDecrypter(
203 ENCRYPTION_FORWARD_SECURE,
204 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
205 session()->connection()->SetEncrypter(
206 ENCRYPTION_FORWARD_SECURE,
207 QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
208 } else {
209 session()->connection()->SetDecrypter(
210 ENCRYPTION_FORWARD_SECURE,
211 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
212 session()->connection()->SetEncrypter(
213 ENCRYPTION_FORWARD_SECURE,
214 QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
215 }
216 session()->connection()->SetDefaultEncryptionLevel(
217 ENCRYPTION_FORWARD_SECURE);
218 }
219 session()->OnCryptoHandshakeEvent(event);
220}
221
Zhongyi Shi879659422018-08-02 17:58:25222// static
223CryptoHandshakeMessage MockCryptoClientStream::GetDummyCHLOMessage() {
224 CryptoHandshakeMessage message;
225 message.set_tag(quic::kCHLO);
226 return message;
227}
228
Ryan Hamilton56b10c5d2018-05-11 13:40:16229void MockCryptoClientStream::SetConfigNegotiated() {
230 ASSERT_FALSE(session()->config()->negotiated());
231 QuicTagVector cgst;
232// TODO(rtenneti): Enable the following code after BBR code is checked in.
233#if 0
234 cgst.push_back(kTBBR);
235#endif
236 cgst.push_back(kQBIC);
237 QuicConfig config(config_);
238 config.SetIdleNetworkTimeout(
239 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
240 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
Ryan Hamilton56b10c5d2018-05-11 13:40:16241 config.SetBytesForConnectionIdToSend(PACKET_8BYTE_CONNECTION_ID);
242 config.SetMaxIncomingDynamicStreamsToSend(kDefaultMaxStreamsPerConnection /
243 2);
244
245 CryptoHandshakeMessage msg;
246 config.ToHandshakeMessage(&msg);
Ryan Hamiltonccfa84a2018-07-24 00:38:08247 QuicString error_details;
Ryan Hamilton56b10c5d2018-05-11 13:40:16248 const QuicErrorCode error =
249 session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
250 ASSERT_EQ(QUIC_NO_ERROR, error);
251 ASSERT_TRUE(session()->config()->negotiated());
252 session()->OnConfigNegotiated();
253}
254
Ryan Hamilton9835e662018-08-02 05:36:27255} // namespace net