blob: 582568c174466cd505a71f65621fa497fb89fa48 [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/test_tools/crypto_test_utils.h"
6
bnc463f2352019-10-10 04:49:34 -07007#include <utility>
8
dschinazi56fb53e2019-06-21 15:30:04 -07009#include "net/third_party/quiche/src/quic/core/proto/crypto_server_config_proto.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050010#include "net/third_party/quiche/src/quic/core/quic_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050011#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050012#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
QUICHE team6dcf6ab2019-12-11 10:10:51 -080013#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
14#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050015
16namespace quic {
17namespace test {
18
19class ShloVerifier {
20 public:
21 ShloVerifier(
22 QuicCryptoServerConfig* crypto_config,
23 QuicSocketAddress server_addr,
24 QuicSocketAddress client_addr,
25 const QuicClock* clock,
26 QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config,
27 QuicCompressedCertsCache* compressed_certs_cache)
28 : crypto_config_(crypto_config),
29 server_addr_(server_addr),
30 client_addr_(client_addr),
31 clock_(clock),
32 signed_config_(signed_config),
33 compressed_certs_cache_(compressed_certs_cache),
34 params_(new QuicCryptoNegotiatedParameters) {}
35
36 class ValidateClientHelloCallback : public ValidateClientHelloResultCallback {
37 public:
38 explicit ValidateClientHelloCallback(ShloVerifier* shlo_verifier)
39 : shlo_verifier_(shlo_verifier) {}
40 void Run(QuicReferenceCountedPointer<
41 ValidateClientHelloResultCallback::Result> result,
42 std::unique_ptr<ProofSource::Details> /* details */) override {
43 shlo_verifier_->ValidateClientHelloDone(result);
44 }
45
46 private:
47 ShloVerifier* shlo_verifier_;
48 };
49
50 std::unique_ptr<ValidateClientHelloCallback>
51 GetValidateClientHelloCallback() {
vasilvv0fc587f2019-09-06 13:33:08 -070052 return std::make_unique<ValidateClientHelloCallback>(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -050053 }
54
55 private:
56 void ValidateClientHelloDone(
57 const QuicReferenceCountedPointer<
58 ValidateClientHelloResultCallback::Result>& result) {
59 result_ = result;
60 crypto_config_->ProcessClientHello(
61 result_, /*reject_only=*/false,
62 /*connection_id=*/TestConnectionId(1), server_addr_, client_addr_,
wubecf9bd82019-06-05 04:57:02 -070063 AllSupportedVersions().front(), AllSupportedVersions(), clock_,
QUICHE teama6ef0a62019-03-07 20:34:33 -050064 QuicRandom::GetInstance(), compressed_certs_cache_, params_,
65 signed_config_, /*total_framing_overhead=*/50, kDefaultMaxPacketSize,
66 GetProcessClientHelloCallback());
67 }
68
69 class ProcessClientHelloCallback : public ProcessClientHelloResultCallback {
70 public:
71 explicit ProcessClientHelloCallback(ShloVerifier* shlo_verifier)
72 : shlo_verifier_(shlo_verifier) {}
dschinazi17d42422019-06-18 16:35:07 -070073 void Run(QuicErrorCode /*error*/,
74 const std::string& /*error_details*/,
75 std::unique_ptr<CryptoHandshakeMessage> message,
76 std::unique_ptr<DiversificationNonce> /*diversification_nonce*/,
77 std::unique_ptr<ProofSource::Details> /*proof_source_details*/)
78 override {
QUICHE teama6ef0a62019-03-07 20:34:33 -050079 shlo_verifier_->ProcessClientHelloDone(std::move(message));
80 }
81
82 private:
83 ShloVerifier* shlo_verifier_;
84 };
85
86 std::unique_ptr<ProcessClientHelloCallback> GetProcessClientHelloCallback() {
vasilvv0fc587f2019-09-06 13:33:08 -070087 return std::make_unique<ProcessClientHelloCallback>(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -050088 }
89
90 void ProcessClientHelloDone(std::unique_ptr<CryptoHandshakeMessage> message) {
91 // Verify output is a SHLO.
92 EXPECT_EQ(message->tag(), kSHLO)
93 << "Fail to pass validation. Get " << message->DebugString();
94 }
95
96 QuicCryptoServerConfig* crypto_config_;
97 QuicSocketAddress server_addr_;
98 QuicSocketAddress client_addr_;
99 const QuicClock* clock_;
100 QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
101 QuicCompressedCertsCache* compressed_certs_cache_;
102
103 QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
104 QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
105 result_;
106};
107
108class CryptoTestUtilsTest : public QuicTest {};
109
110TEST_F(CryptoTestUtilsTest, TestGenerateFullCHLO) {
111 MockClock clock;
112 QuicCryptoServerConfig crypto_config(
113 QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
nharper6ebe83b2019-06-13 17:43:52 -0700114 crypto_test_utils::ProofSourceForTesting(), KeyExchangeSource::Default());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500115 QuicSocketAddress server_addr(QuicIpAddress::Any4(), 5);
116 QuicSocketAddress client_addr(QuicIpAddress::Loopback4(), 1);
117 QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config(
118 new QuicSignedServerConfig);
119 QuicCompressedCertsCache compressed_certs_cache(
120 QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
121 CryptoHandshakeMessage full_chlo;
122
123 QuicCryptoServerConfig::ConfigOptions old_config_options;
124 old_config_options.id = "old-config-id";
QUICHE teamd5af58a2019-03-14 20:35:50 -0700125 crypto_config.AddDefaultConfig(QuicRandom::GetInstance(), &clock,
126 old_config_options);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500127 QuicCryptoServerConfig::ConfigOptions new_config_options;
QUICHE teambbaa8be2019-03-21 12:54:17 -0700128 QuicServerConfigProtobuf primary_config = crypto_config.GenerateConfig(
129 QuicRandom::GetInstance(), &clock, new_config_options);
130 primary_config.set_primary_time(clock.WallNow().ToUNIXSeconds());
QUICHE teamd5af58a2019-03-14 20:35:50 -0700131 std::unique_ptr<CryptoHandshakeMessage> msg =
wub76855422019-10-24 08:53:04 -0700132 crypto_config.AddConfig(primary_config, clock.WallNow());
QUICHE team6dcf6ab2019-12-11 10:10:51 -0800133 quiche::QuicheStringPiece orbit;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500134 ASSERT_TRUE(msg->GetStringPiece(kORBT, &orbit));
vasilvvc48c8712019-03-11 13:38:16 -0700135 std::string nonce;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500136 CryptoUtils::GenerateNonce(clock.WallNow(), QuicRandom::GetInstance(), orbit,
137 &nonce);
QUICHE team6dcf6ab2019-12-11 10:10:51 -0800138 std::string nonce_hex = "#" + quiche::QuicheTextUtils::HexEncode(nonce);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500139
140 char public_value[32];
141 memset(public_value, 42, sizeof(public_value));
QUICHE team6dcf6ab2019-12-11 10:10:51 -0800142 std::string pub_hex = "#" + quiche::QuicheTextUtils::HexEncode(
143 public_value, sizeof(public_value));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500144
dschinazi41616842020-01-21 15:46:11 -0800145 // The methods below use a PROTOCOL_QUIC_CRYPTO version so we pick the
146 // first one from the list of supported versions.
147 QuicTransportVersion transport_version = QUIC_VERSION_UNSUPPORTED;
148 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
149 if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
150 transport_version = version.transport_version;
151 break;
152 }
153 }
154 ASSERT_NE(QUIC_VERSION_UNSUPPORTED, transport_version);
155
QUICHE teama6ef0a62019-03-07 20:34:33 -0500156 CryptoHandshakeMessage inchoate_chlo = crypto_test_utils::CreateCHLO(
157 {{"PDMD", "X509"},
158 {"AEAD", "AESG"},
159 {"KEXS", "C255"},
160 {"COPT", "SREJ"},
161 {"PUBS", pub_hex},
162 {"NONC", nonce_hex},
dschinazi41616842020-01-21 15:46:11 -0800163 {"VER\0", QuicVersionLabelToString(
164 QuicVersionToQuicVersionLabel(transport_version))}},
QUICHE teama6ef0a62019-03-07 20:34:33 -0500165 kClientHelloMinimumSize);
166
dschinazi41616842020-01-21 15:46:11 -0800167 crypto_test_utils::GenerateFullCHLO(inchoate_chlo, &crypto_config,
168 server_addr, client_addr,
169 transport_version, &clock, signed_config,
170 &compressed_certs_cache, &full_chlo);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500171 // Verify that full_chlo can pass crypto_config's verification.
172 ShloVerifier shlo_verifier(&crypto_config, server_addr, client_addr, &clock,
173 signed_config, &compressed_certs_cache);
174 crypto_config.ValidateClientHello(
dschinazi41616842020-01-21 15:46:11 -0800175 full_chlo, client_addr.host(), server_addr, transport_version, &clock,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500176 signed_config, shlo_verifier.GetValidateClientHelloCallback());
177}
178
179} // namespace test
180} // namespace quic