1 // Copyright (c) 2022 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 "quiche/quic/load_balancer/load_balancer_decoder.h"
6 
7 #include <cstdint>
8 
9 #include "absl/strings/string_view.h"
10 #include "absl/types/span.h"
11 #include "quiche/quic/core/quic_connection_id.h"
12 #include "quiche/quic/load_balancer/load_balancer_config.h"
13 #include "quiche/quic/load_balancer/load_balancer_server_id.h"
14 #include "quiche/quic/platform/api/quic_expect_bug.h"
15 #include "quiche/quic/platform/api/quic_test.h"
16 
17 namespace quic {
18 
19 namespace test {
20 
21 namespace {
22 
23 class LoadBalancerDecoderTest : public QuicTest {};
24 
25 // Convenience function to shorten the code. Does not check if |array| is long
26 // enough or |length| is valid for a server ID.
MakeServerId(const uint8_t array[],const uint8_t length)27 inline LoadBalancerServerId MakeServerId(const uint8_t array[],
28                                          const uint8_t length) {
29   return LoadBalancerServerId(absl::Span<const uint8_t>(array, length));
30 }
31 
32 constexpr char kRawKey[] = {0x8f, 0x95, 0xf0, 0x92, 0x45, 0x76, 0x5f, 0x80,
33                             0x25, 0x69, 0x34, 0xe5, 0x0c, 0x66, 0x20, 0x7f};
34 constexpr absl::string_view kKey(kRawKey, kLoadBalancerKeyLen);
35 constexpr uint8_t kServerId[] = {0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f, 0x5f,
36                                  0xab, 0x65, 0xba, 0x04, 0xc3, 0x33, 0x0a};
37 
38 struct LoadBalancerDecoderTestCase {
39   LoadBalancerConfig config;
40   QuicConnectionId connection_id;
41   LoadBalancerServerId server_id;
42 };
43 
TEST_F(LoadBalancerDecoderTest,UnencryptedConnectionIdTestVectors)44 TEST_F(LoadBalancerDecoderTest, UnencryptedConnectionIdTestVectors) {
45   const struct LoadBalancerDecoderTestCase test_vectors[2] = {
46       {
47           *LoadBalancerConfig::CreateUnencrypted(0, 3, 4),
48           QuicConnectionId({0x07, 0xed, 0x79, 0x3a, 0x80, 0x49, 0x71, 0x8a}),
49           MakeServerId(kServerId, 3),
50       },
51       {
52           *LoadBalancerConfig::CreateUnencrypted(1, 8, 5),
53           QuicConnectionId({0x2d, 0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f,
54                             0x5f, 0xee, 0x15, 0xda, 0x27, 0xc4}),
55           MakeServerId(kServerId, 8),
56       }};
57   for (const auto& test : test_vectors) {
58     LoadBalancerDecoder decoder;
59     LoadBalancerServerId answer;
60     EXPECT_TRUE(decoder.AddConfig(test.config));
61     EXPECT_TRUE(decoder.GetServerId(test.connection_id, answer));
62     EXPECT_EQ(answer, test.server_id);
63   }
64 }
65 
66 // Compare test vectors from Appendix B of draft-ietf-quic-load-balancers-19.
TEST_F(LoadBalancerDecoderTest,DecoderTestVectors)67 TEST_F(LoadBalancerDecoderTest, DecoderTestVectors) {
68   // Try (1) the "standard" CID length of 8
69   // (2) server_id_len > nonce_len, so there is a fourth decryption pass
70   // (3) the single-pass encryption case
71   // (4) An even total length.
72   const struct LoadBalancerDecoderTestCase test_vectors[4] = {
73       {
74           *LoadBalancerConfig::Create(0, 3, 4, kKey),
75           QuicConnectionId({0x07, 0x20, 0xb1, 0xd0, 0x7b, 0x35, 0x9d, 0x3c}),
76           MakeServerId(kServerId, 3),
77       },
78       {
79           *LoadBalancerConfig::Create(1, 10, 5, kKey),
80           QuicConnectionId({0x2f, 0xcc, 0x38, 0x1b, 0xc7, 0x4c, 0xb4, 0xfb,
81                             0xad, 0x28, 0x23, 0xa3, 0xd1, 0xf8, 0xfe, 0xd2}),
82           MakeServerId(kServerId, 10),
83       },
84       {
85           *LoadBalancerConfig::Create(2, 8, 8, kKey),
86           QuicConnectionId({0x50, 0x4d, 0xd2, 0xd0, 0x5a, 0x7b, 0x0d, 0xe9,
87                             0xb2, 0xb9, 0x90, 0x7a, 0xfb, 0x5e, 0xcf, 0x8c,
88                             0xc3}),
89           MakeServerId(kServerId, 8),
90       },
91       {
92           *LoadBalancerConfig::Create(0, 9, 9, kKey),
93           QuicConnectionId({0x12, 0x57, 0x79, 0xc9, 0xcc, 0x86, 0xbe, 0xb3,
94                             0xa3, 0xa4, 0xa3, 0xca, 0x96, 0xfc, 0xe4, 0xbf,
95                             0xe0, 0xcd, 0xbc}),
96           MakeServerId(kServerId, 9),
97       },
98   };
99   for (const auto& test : test_vectors) {
100     LoadBalancerDecoder decoder;
101     EXPECT_TRUE(decoder.AddConfig(test.config));
102     LoadBalancerServerId answer;
103     EXPECT_TRUE(decoder.GetServerId(test.connection_id, answer));
104     EXPECT_EQ(answer, test.server_id);
105   }
106 }
107 
TEST_F(LoadBalancerDecoderTest,InvalidConfigId)108 TEST_F(LoadBalancerDecoderTest, InvalidConfigId) {
109   LoadBalancerServerId server_id({0x01, 0x02, 0x03});
110   EXPECT_TRUE(server_id.IsValid());
111   LoadBalancerDecoder decoder;
112   EXPECT_TRUE(
113       decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(1, 3, 4)));
114   QuicConnectionId wrong_config_id(
115       {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07});
116   LoadBalancerServerId answer;
117   EXPECT_FALSE(decoder.GetServerId(
118       QuicConnectionId({0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}),
119       answer));
120 }
121 
TEST_F(LoadBalancerDecoderTest,UnroutableCodepoint)122 TEST_F(LoadBalancerDecoderTest, UnroutableCodepoint) {
123   LoadBalancerServerId server_id({0x01, 0x02, 0x03});
124   EXPECT_TRUE(server_id.IsValid());
125   LoadBalancerDecoder decoder;
126   EXPECT_TRUE(
127       decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(1, 3, 4)));
128   LoadBalancerServerId answer;
129   EXPECT_FALSE(decoder.GetServerId(
130       QuicConnectionId({0xe0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}),
131       answer));
132 }
133 
TEST_F(LoadBalancerDecoderTest,UnroutableCodepointAnyLength)134 TEST_F(LoadBalancerDecoderTest, UnroutableCodepointAnyLength) {
135   LoadBalancerServerId server_id({0x01, 0x02, 0x03});
136   EXPECT_TRUE(server_id.IsValid());
137   LoadBalancerDecoder decoder;
138   EXPECT_TRUE(
139       decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(1, 3, 4)));
140   LoadBalancerServerId answer;
141   EXPECT_FALSE(decoder.GetServerId(QuicConnectionId({0xff}), answer));
142 }
143 
TEST_F(LoadBalancerDecoderTest,ConnectionIdTooShort)144 TEST_F(LoadBalancerDecoderTest, ConnectionIdTooShort) {
145   LoadBalancerServerId server_id({0x01, 0x02, 0x03});
146   EXPECT_TRUE(server_id.IsValid());
147   LoadBalancerDecoder decoder;
148   EXPECT_TRUE(
149       decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(0, 3, 4)));
150   LoadBalancerServerId answer;
151   EXPECT_FALSE(decoder.GetServerId(
152       QuicConnectionId({0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}), answer));
153 }
154 
TEST_F(LoadBalancerDecoderTest,ConnectionIdTooLongIsOK)155 TEST_F(LoadBalancerDecoderTest, ConnectionIdTooLongIsOK) {
156   LoadBalancerServerId server_id({0x01, 0x02, 0x03});
157   LoadBalancerDecoder decoder;
158   EXPECT_TRUE(
159       decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(0, 3, 4)));
160   LoadBalancerServerId answer;
161   EXPECT_TRUE(decoder.GetServerId(
162       QuicConnectionId({0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}),
163       answer));
164   EXPECT_EQ(answer, server_id);
165 }
166 
TEST_F(LoadBalancerDecoderTest,DeleteConfigBadId)167 TEST_F(LoadBalancerDecoderTest, DeleteConfigBadId) {
168   LoadBalancerDecoder decoder;
169   decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(2, 3, 4));
170   decoder.DeleteConfig(0);
171   EXPECT_QUIC_BUG(decoder.DeleteConfig(7),
172                   "Decoder deleting config with invalid config_id 7");
173   LoadBalancerServerId answer;
174   EXPECT_TRUE(decoder.GetServerId(
175       QuicConnectionId({0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}),
176       answer));
177 }
178 
TEST_F(LoadBalancerDecoderTest,DeleteConfigGoodId)179 TEST_F(LoadBalancerDecoderTest, DeleteConfigGoodId) {
180   LoadBalancerDecoder decoder;
181   decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(2, 3, 4));
182   decoder.DeleteConfig(2);
183   LoadBalancerServerId answer;
184   EXPECT_FALSE(decoder.GetServerId(
185       QuicConnectionId({0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}),
186       answer));
187 }
188 
189 // Create two server IDs and make sure the decoder decodes the correct one.
TEST_F(LoadBalancerDecoderTest,TwoServerIds)190 TEST_F(LoadBalancerDecoderTest, TwoServerIds) {
191   LoadBalancerServerId server_id1({0x01, 0x02, 0x03});
192   EXPECT_TRUE(server_id1.IsValid());
193   LoadBalancerServerId server_id2({0x04, 0x05, 0x06});
194   LoadBalancerDecoder decoder;
195   EXPECT_TRUE(
196       decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(0, 3, 4)));
197   LoadBalancerServerId answer;
198   EXPECT_TRUE(decoder.GetServerId(
199       QuicConnectionId({0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}),
200       answer));
201   EXPECT_EQ(answer, server_id1);
202   EXPECT_TRUE(decoder.GetServerId(
203       QuicConnectionId({0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a}),
204       answer));
205   EXPECT_EQ(answer, server_id2);
206 }
207 
TEST_F(LoadBalancerDecoderTest,GetConfigId)208 TEST_F(LoadBalancerDecoderTest, GetConfigId) {
209   EXPECT_FALSE(
210       LoadBalancerDecoder::GetConfigId(QuicConnectionId()).has_value());
211   for (uint8_t i = 0; i < kNumLoadBalancerConfigs; i++) {
212     const QuicConnectionId connection_id(
213         {static_cast<unsigned char>(i << kConnectionIdLengthBits)});
214     auto config_id = LoadBalancerDecoder::GetConfigId(connection_id);
215     EXPECT_EQ(config_id,
216               LoadBalancerDecoder::GetConfigId(connection_id.data()[0]));
217     EXPECT_TRUE(config_id.has_value());
218     EXPECT_EQ(*config_id, i);
219   }
220   EXPECT_FALSE(
221       LoadBalancerDecoder::GetConfigId(QuicConnectionId({0xe0})).has_value());
222 }
223 
TEST_F(LoadBalancerDecoderTest,GetConfig)224 TEST_F(LoadBalancerDecoderTest, GetConfig) {
225   LoadBalancerDecoder decoder;
226   decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(2, 3, 4));
227 
228   EXPECT_EQ(decoder.GetConfig(0), nullptr);
229   EXPECT_EQ(decoder.GetConfig(1), nullptr);
230   EXPECT_EQ(decoder.GetConfig(3), nullptr);
231   EXPECT_EQ(decoder.GetConfig(4), nullptr);
232 
233   const LoadBalancerConfig* config = decoder.GetConfig(2);
234   ASSERT_NE(config, nullptr);
235   EXPECT_EQ(config->server_id_len(), 3);
236   EXPECT_EQ(config->nonce_len(), 4);
237   EXPECT_FALSE(config->IsEncrypted());
238 }
239 
TEST_F(LoadBalancerDecoderTest,OnePassIgnoreAdditionalBytes)240 TEST_F(LoadBalancerDecoderTest, OnePassIgnoreAdditionalBytes) {
241   uint8_t ptext[] = {0x00, 0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f, 0x5f, 0xee,
242                      0x08, 0x0d, 0xbf, 0x48, 0xc0, 0xd1, 0xe5, 0xda, 0x41};
243   uint8_t ctext[] = {0x00, 0x4d, 0xd2, 0xd0, 0x5a, 0x7b, 0x0d, 0xe9, 0xb2, 0xb9,
244                      0x90, 0x7a, 0xfb, 0x5e, 0xcf, 0x8c, 0xc3, 0xda, 0x41};
245   LoadBalancerDecoder decoder;
246   decoder.AddConfig(
247       *LoadBalancerConfig::Create(0, 8, 8, absl::string_view(kRawKey, 16)));
248   LoadBalancerServerId original_server_id(absl::Span<uint8_t>(&ptext[1], 8));
249   QuicConnectionId cid(absl::Span<uint8_t>(ctext, sizeof(ctext)));
250   LoadBalancerServerId answer;
251   EXPECT_TRUE(decoder.GetServerId(cid, answer));
252   EXPECT_EQ(answer, original_server_id);
253 }
254 
255 }  // namespace
256 
257 }  // namespace test
258 
259 }  // namespace quic
260