blob: 57ae56af3f0f27bd9f5ddab36dab068ebb54698c [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;
46using quic::QuicTagVector;
47using quic::QuicTime;
48
49namespace net {
Ryan Hamilton56b10c5d2018-05-11 13:40:1650
51MockCryptoClientStream::MockCryptoClientStream(
52 const QuicServerId& server_id,
53 QuicSpdyClientSessionBase* session,
Ryan Hamiltonf044c1b2018-07-24 00:00:1454 std::unique_ptr<ProofVerifyContext> verify_context,
Ryan Hamilton56b10c5d2018-05-11 13:40:1655 const QuicConfig& config,
56 QuicCryptoClientConfig* crypto_config,
57 HandshakeMode handshake_mode,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5258 const net::ProofVerifyDetailsChromium* proof_verify_details,
Ryan Hamilton56b10c5d2018-05-11 13:40:1659 bool use_mock_crypter)
60 : QuicCryptoClientStream(server_id,
61 session,
Ryan Hamiltonf044c1b2018-07-24 00:00:1462 std::move(verify_context),
Ryan Hamilton56b10c5d2018-05-11 13:40:1663 crypto_config,
64 session),
65 QuicCryptoHandshaker(this, session),
66 handshake_mode_(handshake_mode),
67 encryption_established_(false),
68 handshake_confirmed_(false),
69 crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
70 use_mock_crypter_(use_mock_crypter),
71 server_id_(server_id),
72 proof_verify_details_(proof_verify_details),
73 config_(config) {
74 crypto_framer_.set_visitor(this);
75}
76
77MockCryptoClientStream::~MockCryptoClientStream() {}
78
79void MockCryptoClientStream::OnHandshakeMessage(
80 const CryptoHandshakeMessage& message) {
81 CloseConnectionWithDetails(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
82 "Forced mock failure");
83}
84
85bool MockCryptoClientStream::CryptoConnect() {
86 if (proof_verify_details_) {
87 if (!proof_verify_details_->cert_verify_result.verified_cert
88 ->VerifyNameMatch(server_id_.host())) {
89 handshake_confirmed_ = false;
90 encryption_established_ = false;
91 session()->connection()->CloseConnection(
92 QUIC_PROOF_INVALID, "proof invalid",
93 ConnectionCloseBehavior::SILENT_CLOSE);
94 return false;
95 }
96 }
97
98 switch (handshake_mode_) {
99 case ZERO_RTT: {
100 encryption_established_ = true;
101 handshake_confirmed_ = false;
102 crypto_negotiated_params_->key_exchange = kC255;
103 crypto_negotiated_params_->aead = kAESG;
104 if (proof_verify_details_) {
105 reinterpret_cast<QuicSpdyClientSessionBase*>(session())
106 ->OnProofVerifyDetailsAvailable(*proof_verify_details_);
107 }
108 if (use_mock_crypter_) {
109 session()->connection()->SetDecrypter(
110 ENCRYPTION_INITIAL,
111 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
112 session()->connection()->SetEncrypter(
113 ENCRYPTION_INITIAL,
114 QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
115 } else {
116 session()->connection()->SetDecrypter(
117 ENCRYPTION_INITIAL,
118 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
119 session()->connection()->SetEncrypter(
120 ENCRYPTION_INITIAL,
121 QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
122 }
123 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
124 session()->OnCryptoHandshakeEvent(
125 QuicSession::ENCRYPTION_FIRST_ESTABLISHED);
126 break;
127 }
128
129 case CONFIRM_HANDSHAKE: {
130 encryption_established_ = true;
131 handshake_confirmed_ = true;
132 crypto_negotiated_params_->key_exchange = kC255;
133 crypto_negotiated_params_->aead = kAESG;
134 if (proof_verify_details_) {
135 reinterpret_cast<QuicSpdyClientSessionBase*>(session())
136 ->OnProofVerifyDetailsAvailable(*proof_verify_details_);
137 }
138 SetConfigNegotiated();
139 if (use_mock_crypter_) {
140 session()->connection()->SetDecrypter(
141 ENCRYPTION_FORWARD_SECURE,
142 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
143 session()->connection()->SetEncrypter(
144 ENCRYPTION_FORWARD_SECURE,
145 QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
146 } else {
147 session()->connection()->SetDecrypter(
148 ENCRYPTION_FORWARD_SECURE,
149 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
150 session()->connection()->SetEncrypter(
151 ENCRYPTION_FORWARD_SECURE,
152 QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
153 }
154 session()->connection()->SetDefaultEncryptionLevel(
155 ENCRYPTION_FORWARD_SECURE);
156 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
157 break;
158 }
159
160 case COLD_START: {
161 handshake_confirmed_ = false;
162 encryption_established_ = false;
163 break;
164 }
165
166 case USE_DEFAULT_CRYPTO_STREAM: {
167 NOTREACHED();
168 break;
169 }
170 }
171
172 return session()->connection()->connected();
173}
174
175bool MockCryptoClientStream::encryption_established() const {
176 return encryption_established_;
177}
178
179bool MockCryptoClientStream::handshake_confirmed() const {
180 return handshake_confirmed_;
181}
182
183const QuicCryptoNegotiatedParameters&
184MockCryptoClientStream::crypto_negotiated_params() const {
185 return *crypto_negotiated_params_;
186}
187
188CryptoMessageParser* MockCryptoClientStream::crypto_message_parser() {
189 return &crypto_framer_;
190}
191
192void MockCryptoClientStream::SendOnCryptoHandshakeEvent(
193 QuicSession::CryptoHandshakeEvent event) {
194 encryption_established_ = true;
195 if (event == QuicSession::HANDSHAKE_CONFIRMED) {
196 handshake_confirmed_ = true;
197 SetConfigNegotiated();
198 if (use_mock_crypter_) {
199 session()->connection()->SetDecrypter(
200 ENCRYPTION_FORWARD_SECURE,
201 QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
202 session()->connection()->SetEncrypter(
203 ENCRYPTION_FORWARD_SECURE,
204 QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
205 } else {
206 session()->connection()->SetDecrypter(
207 ENCRYPTION_FORWARD_SECURE,
208 QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
209 session()->connection()->SetEncrypter(
210 ENCRYPTION_FORWARD_SECURE,
211 QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
212 }
213 session()->connection()->SetDefaultEncryptionLevel(
214 ENCRYPTION_FORWARD_SECURE);
215 }
216 session()->OnCryptoHandshakeEvent(event);
217}
218
219void MockCryptoClientStream::SetConfigNegotiated() {
220 ASSERT_FALSE(session()->config()->negotiated());
221 QuicTagVector cgst;
222// TODO(rtenneti): Enable the following code after BBR code is checked in.
223#if 0
224 cgst.push_back(kTBBR);
225#endif
226 cgst.push_back(kQBIC);
227 QuicConfig config(config_);
228 config.SetIdleNetworkTimeout(
229 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
230 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
Ryan Hamilton56b10c5d2018-05-11 13:40:16231 config.SetBytesForConnectionIdToSend(PACKET_8BYTE_CONNECTION_ID);
232 config.SetMaxIncomingDynamicStreamsToSend(kDefaultMaxStreamsPerConnection /
233 2);
234
235 CryptoHandshakeMessage msg;
236 config.ToHandshakeMessage(&msg);
Ryan Hamiltonccfa84a2018-07-24 00:38:08237 QuicString error_details;
Ryan Hamilton56b10c5d2018-05-11 13:40:16238 const QuicErrorCode error =
239 session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
240 ASSERT_EQ(QUIC_NO_ERROR, error);
241 ASSERT_TRUE(session()->config()->negotiated());
242 session()->OnConfigNegotiated();
243}
244
Ryan Hamilton9835e662018-08-02 05:36:27245} // namespace net