blob: c2046b1bdfb45a2926dd1002651bc76a61c4e9dc [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 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
5#include "net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.h"
dschinazi580d30b2019-04-26 15:05:20 -07006
QUICHE teama6ef0a62019-03-07 20:34:33 -05007#include "net/third_party/quiche/src/quic/core/proto/crypto_server_config.pb.h"
8#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
9#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h"
dschinazi580d30b2019-04-26 15:05:20 -070010#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050011#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
12
13namespace quic {
14namespace {
15
16using ::testing::Test;
17
18class TestProofHandler : public QuicCryptoClientStream::ProofHandler {
19 public:
20 ~TestProofHandler() override {}
21 void OnProofValid(
22 const QuicCryptoClientConfig::CachedState& cached) override {}
23 void OnProofVerifyDetailsAvailable(
24 const ProofVerifyDetails& verify_details) override {}
25};
26
27class InsecureProofVerifier : public ProofVerifier {
28 public:
29 InsecureProofVerifier() {}
30 ~InsecureProofVerifier() override {}
31
32 // ProofVerifier override.
33 QuicAsyncStatus VerifyProof(
vasilvvc48c8712019-03-11 13:38:16 -070034 const std::string& hostname,
QUICHE teama6ef0a62019-03-07 20:34:33 -050035 const uint16_t port,
vasilvvc48c8712019-03-11 13:38:16 -070036 const std::string& server_config,
QUICHE teama6ef0a62019-03-07 20:34:33 -050037 QuicTransportVersion transport_version,
38 QuicStringPiece chlo_hash,
vasilvvc48c8712019-03-11 13:38:16 -070039 const std::vector<std::string>& certs,
40 const std::string& cert_sct,
41 const std::string& signature,
QUICHE teama6ef0a62019-03-07 20:34:33 -050042 const ProofVerifyContext* context,
vasilvvc48c8712019-03-11 13:38:16 -070043 std::string* error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -050044 std::unique_ptr<ProofVerifyDetails>* verify_details,
45 std::unique_ptr<ProofVerifierCallback> callback) override {
46 return QUIC_SUCCESS;
47 }
48
49 QuicAsyncStatus VerifyCertChain(
vasilvvc48c8712019-03-11 13:38:16 -070050 const std::string& hostname,
51 const std::vector<std::string>& certs,
QUICHE teama6ef0a62019-03-07 20:34:33 -050052 const ProofVerifyContext* context,
vasilvvc48c8712019-03-11 13:38:16 -070053 std::string* error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -050054 std::unique_ptr<ProofVerifyDetails>* details,
55 std::unique_ptr<ProofVerifierCallback> callback) override {
56 return QUIC_SUCCESS;
57 }
58
59 std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
60 return nullptr;
61 }
62};
63
64class DummyProofSource : public ProofSource {
65 public:
66 DummyProofSource() {}
67 ~DummyProofSource() override {}
68
69 // ProofSource override.
70 void GetProof(const QuicSocketAddress& server_address,
vasilvvc48c8712019-03-11 13:38:16 -070071 const std::string& hostname,
72 const std::string& server_config,
QUICHE teama6ef0a62019-03-07 20:34:33 -050073 QuicTransportVersion transport_version,
74 QuicStringPiece chlo_hash,
75 std::unique_ptr<Callback> callback) override {
76 QuicReferenceCountedPointer<ProofSource::Chain> chain =
77 GetCertChain(server_address, hostname);
78 QuicCryptoProof proof;
79 proof.signature = "Dummy signature";
80 proof.leaf_cert_scts = "Dummy timestamp";
81 callback->Run(true, chain, proof, nullptr /* details */);
82 }
83
84 QuicReferenceCountedPointer<Chain> GetCertChain(
85 const QuicSocketAddress& server_address,
vasilvvc48c8712019-03-11 13:38:16 -070086 const std::string& hostname) override {
87 std::vector<std::string> certs;
QUICHE teama6ef0a62019-03-07 20:34:33 -050088 certs.push_back("Dummy cert");
89 return QuicReferenceCountedPointer<ProofSource::Chain>(
90 new ProofSource::Chain(certs));
91 }
92
93 void ComputeTlsSignature(
94 const QuicSocketAddress& server_address,
vasilvvc48c8712019-03-11 13:38:16 -070095 const std::string& hostname,
QUICHE teama6ef0a62019-03-07 20:34:33 -050096 uint16_t signature_algorithm,
97 QuicStringPiece in,
98 std::unique_ptr<SignatureCallback> callback) override {
99 callback->Run(true, "Dummy signature");
100 }
101};
102
103class Handshaker : public QuicCryptoClientHandshaker {
104 public:
105 Handshaker(const QuicServerId& server_id,
106 QuicCryptoClientStream* stream,
107 QuicSession* session,
108 std::unique_ptr<ProofVerifyContext> verify_context,
109 QuicCryptoClientConfig* crypto_config,
110 QuicCryptoClientStream::ProofHandler* proof_handler)
111 : QuicCryptoClientHandshaker(server_id,
112 stream,
113 session,
114 std::move(verify_context),
115 crypto_config,
116 proof_handler) {}
117
118 void DoSendCHLOTest(QuicCryptoClientConfig::CachedState* cached) {
119 QuicCryptoClientHandshaker::DoSendCHLO(cached);
120 }
121};
122
123class QuicCryptoClientHandshakerTest : public Test {
124 protected:
125 QuicCryptoClientHandshakerTest()
126 : proof_handler_(),
127 helper_(),
128 alarm_factory_(),
129 server_id_("host", 123),
130 connection_(new test::MockQuicConnection(&helper_,
131 &alarm_factory_,
132 Perspective::IS_CLIENT)),
133 session_(connection_, false),
134 crypto_client_config_(QuicMakeUnique<InsecureProofVerifier>(),
135 quic::TlsClientHandshaker::CreateSslCtx()),
136 client_stream_(new QuicCryptoClientStream(server_id_,
137 &session_,
138 nullptr,
139 &crypto_client_config_,
140 &proof_handler_)),
141 handshaker_(server_id_,
142 client_stream_,
143 &session_,
144 nullptr,
145 &crypto_client_config_,
146 &proof_handler_),
147 state_() {
148 // Session takes the ownership of the client stream! (but handshaker also
149 // takes a reference to it, but doesn't take the ownership).
150 session_.SetCryptoStream(client_stream_);
151 session_.Initialize();
152 }
153
154 void InitializeServerParametersToEnableFullHello() {
155 QuicCryptoServerConfig::ConfigOptions options;
QUICHE teambbaa8be2019-03-21 12:54:17 -0700156 QuicServerConfigProtobuf config = QuicCryptoServerConfig::GenerateConfig(
157 helper_.GetRandomGenerator(), helper_.GetClock(), options);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500158 state_.Initialize(
QUICHE teambbaa8be2019-03-21 12:54:17 -0700159 config.config(), "sourcetoken", std::vector<std::string>{"Dummy cert"},
QUICHE teama6ef0a62019-03-07 20:34:33 -0500160 "", "chlo_hash", "signature", helper_.GetClock()->WallNow(),
161 helper_.GetClock()->WallNow().Add(QuicTime::Delta::FromSeconds(30)));
162
163 state_.SetProofValid();
164 }
165
166 TestProofHandler proof_handler_;
167 test::MockQuicConnectionHelper helper_;
168 test::MockAlarmFactory alarm_factory_;
169 QuicServerId server_id_;
170 // Session takes the ownership of the connection.
171 test::MockQuicConnection* connection_;
172 test::MockQuicSession session_;
173 QuicCryptoClientConfig crypto_client_config_;
174 QuicCryptoClientStream* client_stream_;
175 Handshaker handshaker_;
176 QuicCryptoClientConfig::CachedState state_;
177};
178
179TEST_F(QuicCryptoClientHandshakerTest, TestSendFullPaddingInInchoateHello) {
180 handshaker_.DoSendCHLOTest(&state_);
181
182 EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
183}
184
185TEST_F(QuicCryptoClientHandshakerTest, TestDisabledPaddingInInchoateHello) {
186 crypto_client_config_.set_pad_inchoate_hello(false);
187 handshaker_.DoSendCHLOTest(&state_);
188 EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
189}
190
191TEST_F(QuicCryptoClientHandshakerTest,
192 TestPaddingInFullHelloEvenIfInchoateDisabled) {
193 // Disable inchoate, but full hello should still be padded.
194 crypto_client_config_.set_pad_inchoate_hello(false);
195
196 InitializeServerParametersToEnableFullHello();
197
198 handshaker_.DoSendCHLOTest(&state_);
199 EXPECT_TRUE(connection_->fully_pad_during_crypto_handshake());
200}
201
202TEST_F(QuicCryptoClientHandshakerTest, TestNoPaddingInFullHelloWhenDisabled) {
203 crypto_client_config_.set_pad_full_hello(false);
204
205 InitializeServerParametersToEnableFullHello();
206
207 handshaker_.DoSendCHLOTest(&state_);
208 EXPECT_FALSE(connection_->fully_pad_during_crypto_handshake());
209}
210
211} // namespace
212} // namespace quic