Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/crypto/transport_parameters_test.cc b/quic/core/crypto/transport_parameters_test.cc
new file mode 100644
index 0000000..8a81841
--- /dev/null
+++ b/quic/core/crypto/transport_parameters_test.cc
@@ -0,0 +1,440 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h"
+
+#include "third_party/boringssl/src/include/openssl/mem.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class TransportParametersTest : public QuicTest {};
+
+TEST_F(TransportParametersTest, RoundTripClient) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_CLIENT;
+  orig_params.initial_max_stream_data = 12;
+  orig_params.initial_max_data = 34;
+  orig_params.idle_timeout = 56;
+  orig_params.initial_max_bidi_streams.present = true;
+  orig_params.initial_max_bidi_streams.value = 2000;
+  orig_params.initial_max_uni_streams.present = true;
+  orig_params.initial_max_uni_streams.value = 3000;
+  orig_params.max_packet_size.present = true;
+  orig_params.max_packet_size.value = 9001;
+  orig_params.ack_delay_exponent.present = true;
+  orig_params.ack_delay_exponent.value = 10;
+  orig_params.version = 0xff000005;
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParameters(orig_params, &serialized));
+
+  TransportParameters new_params;
+  ASSERT_TRUE(ParseTransportParameters(serialized.data(), serialized.size(),
+                                       Perspective::IS_CLIENT, &new_params));
+
+  EXPECT_EQ(new_params.initial_max_stream_data,
+            orig_params.initial_max_stream_data);
+  EXPECT_EQ(new_params.initial_max_data, orig_params.initial_max_data);
+  EXPECT_EQ(new_params.idle_timeout, orig_params.idle_timeout);
+  EXPECT_EQ(new_params.version, orig_params.version);
+  EXPECT_TRUE(new_params.initial_max_bidi_streams.present);
+  EXPECT_EQ(new_params.initial_max_bidi_streams.value,
+            orig_params.initial_max_bidi_streams.value);
+  EXPECT_TRUE(new_params.initial_max_uni_streams.present);
+  EXPECT_EQ(new_params.initial_max_uni_streams.value,
+            orig_params.initial_max_uni_streams.value);
+  EXPECT_TRUE(new_params.max_packet_size.present);
+  EXPECT_EQ(new_params.max_packet_size.value,
+            orig_params.max_packet_size.value);
+  EXPECT_TRUE(new_params.ack_delay_exponent.present);
+  EXPECT_EQ(new_params.ack_delay_exponent.value,
+            orig_params.ack_delay_exponent.value);
+}
+
+TEST_F(TransportParametersTest, RoundTripServer) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_SERVER;
+  orig_params.initial_max_stream_data = 12;
+  orig_params.initial_max_data = 34;
+  orig_params.idle_timeout = 56;
+  orig_params.stateless_reset_token.resize(16);
+  orig_params.version = 0xff000005;
+  orig_params.supported_versions.push_back(0xff000005);
+  orig_params.supported_versions.push_back(0xff000004);
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParameters(orig_params, &serialized));
+
+  TransportParameters new_params;
+  ASSERT_TRUE(ParseTransportParameters(serialized.data(), serialized.size(),
+                                       Perspective::IS_SERVER, &new_params));
+
+  EXPECT_EQ(new_params.initial_max_stream_data,
+            orig_params.initial_max_stream_data);
+  EXPECT_EQ(new_params.initial_max_data, orig_params.initial_max_data);
+  EXPECT_EQ(new_params.idle_timeout, orig_params.idle_timeout);
+  EXPECT_EQ(new_params.stateless_reset_token,
+            orig_params.stateless_reset_token);
+  EXPECT_EQ(new_params.version, orig_params.version);
+  ASSERT_EQ(new_params.supported_versions, orig_params.supported_versions);
+}
+
+TEST_F(TransportParametersTest, IsValid) {
+  TransportParameters empty_params;
+  empty_params.perspective = Perspective::IS_CLIENT;
+  EXPECT_TRUE(empty_params.is_valid());
+
+  {
+    TransportParameters params;
+    params.perspective = Perspective::IS_CLIENT;
+    EXPECT_TRUE(params.is_valid());
+    params.idle_timeout = 600;
+    EXPECT_TRUE(params.is_valid());
+    params.idle_timeout = 601;
+    EXPECT_FALSE(params.is_valid());
+  }
+  {
+    TransportParameters params;
+    params.perspective = Perspective::IS_CLIENT;
+    EXPECT_TRUE(params.is_valid());
+    params.max_packet_size.present = true;
+    params.max_packet_size.value = 0;
+    EXPECT_FALSE(params.is_valid());
+    params.max_packet_size.value = 1200;
+    EXPECT_TRUE(params.is_valid());
+    params.max_packet_size.value = 65527;
+    EXPECT_TRUE(params.is_valid());
+    params.max_packet_size.value = 65535;
+    EXPECT_FALSE(params.is_valid());
+  }
+  {
+    TransportParameters params;
+    params.perspective = Perspective::IS_CLIENT;
+    EXPECT_TRUE(params.is_valid());
+    params.ack_delay_exponent.present = true;
+    params.ack_delay_exponent.value = 0;
+    EXPECT_TRUE(params.is_valid());
+    params.ack_delay_exponent.value = 20;
+    EXPECT_TRUE(params.is_valid());
+    params.ack_delay_exponent.value = 21;
+    EXPECT_FALSE(params.is_valid());
+  }
+}
+
+TEST_F(TransportParametersTest, NoServerParamsWithoutStatelessResetToken) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_SERVER;
+  orig_params.initial_max_stream_data = 12;
+  orig_params.initial_max_data = 34;
+  orig_params.idle_timeout = 56;
+  orig_params.version = 0xff000005;
+  orig_params.supported_versions.push_back(0xff000005);
+  orig_params.supported_versions.push_back(0xff000004);
+
+  std::vector<uint8_t> out;
+  ASSERT_FALSE(SerializeTransportParameters(orig_params, &out));
+}
+
+TEST_F(TransportParametersTest, NoClientParamsWithStatelessResetToken) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_CLIENT;
+  orig_params.initial_max_stream_data = 12;
+  orig_params.initial_max_data = 34;
+  orig_params.idle_timeout = 56;
+  orig_params.stateless_reset_token.resize(16);
+  orig_params.version = 0xff000005;
+
+  std::vector<uint8_t> out;
+  ASSERT_FALSE(SerializeTransportParameters(orig_params, &out));
+}
+
+TEST_F(TransportParametersTest, ParseClientParams) {
+  const uint8_t kClientParams[] = {
+      0xff, 0x00, 0x00, 0x05,  // initial version
+      0x00, 0x16,              // length parameters array that follows
+      // initial_max_stream_data
+      0x00, 0x00,              // parameter id
+      0x00, 0x04,              // length
+      0x00, 0x00, 0x00, 0x0c,  // value
+      // initial_max_data
+      0x00, 0x01,              // parameter id
+      0x00, 0x04,              // length
+      0x00, 0x00, 0x00, 0x22,  // value
+      // idle_timeout
+      0x00, 0x03,  // parameter id
+      0x00, 0x02,  // length
+      0x00, 0x38,  // value
+  };
+
+  TransportParameters out_params;
+  ASSERT_TRUE(ParseTransportParameters(kClientParams,
+                                       QUIC_ARRAYSIZE(kClientParams),
+                                       Perspective::IS_CLIENT, &out_params));
+}
+
+TEST_F(TransportParametersTest, ParseClientParamsFailsWithStatelessResetToken) {
+  TransportParameters out_params;
+
+  // clang-format off
+  const uint8_t kClientParamsWithFullToken[] = {
+      0xff, 0x00, 0x00, 0x05,  // initial version
+      0x00, 0x2a,  // length parameters array that follows
+      // initial_max_stream_data
+      0x00, 0x00,              // parameter id
+      0x00, 0x04,              // length
+      0x00, 0x00, 0x00, 0x0c,  // value
+      // initial_max_data
+      0x00, 0x01,              // parameter id
+      0x00, 0x04,              // length
+      0x00, 0x00, 0x00, 0x22,  // value
+      // idle_timeout
+      0x00, 0x03,  // parameter id
+      0x00, 0x02,  // length
+      0x00, 0x38,  // value
+      // stateless_reset_token
+      0x00, 0x06,  // parameter id
+      0x00, 0x10,  // length
+      0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+  };
+  // clang-format on
+
+  ASSERT_FALSE(ParseTransportParameters(
+      kClientParamsWithFullToken, QUIC_ARRAYSIZE(kClientParamsWithFullToken),
+      Perspective::IS_CLIENT, &out_params));
+
+  const uint8_t kClientParamsWithEmptyToken[] = {
+      0xff, 0x00, 0x00, 0x05,  // initial version
+      0x00, 0x1a,              // length parameters array that follows
+      // initial_max_stream_data
+      0x00, 0x00,              // parameter id
+      0x00, 0x04,              // length
+      0x00, 0x00, 0x00, 0x0c,  // value
+      // initial_max_data
+      0x00, 0x01,              // parameter id
+      0x00, 0x04,              // length
+      0x00, 0x00, 0x00, 0x22,  // value
+      // idle_timeout
+      0x00, 0x03,  // parameter id
+      0x00, 0x02,  // length
+      0x00, 0x38,  // value
+      // stateless_reset_token
+      0x00, 0x06,  // parameter id
+      0x00, 0x00,  // length
+  };
+
+  ASSERT_FALSE(ParseTransportParameters(
+      kClientParamsWithEmptyToken, QUIC_ARRAYSIZE(kClientParamsWithEmptyToken),
+      Perspective::IS_CLIENT, &out_params));
+}
+
+TEST_F(TransportParametersTest, ParseClientParametersWithInvalidParams) {
+  TransportParameters out_params;
+
+  const uint8_t kClientParamsRepeated[] = {
+      0xff, 0x00, 0x00, 0x05,  // initial version
+      0x00, 0x1c,              // length parameters array that follows
+      // initial_max_stream_data
+      0x00, 0x00,              // parameter id
+      0x00, 0x04,              // length
+      0x00, 0x00, 0x00, 0x0c,  // value
+      // initial_max_data
+      0x00, 0x01,              // parameter id
+      0x00, 0x04,              // length
+      0x00, 0x00, 0x00, 0x22,  // value
+      // idle_timeout
+      0x00, 0x03,  // parameter id
+      0x00, 0x02,  // length
+      0x00, 0x38,  // value
+      // idle_timeout (repeat)
+      0x00, 0x03,  // parameter id
+      0x00, 0x02,  // length
+      0x00, 0x38,  // value
+  };
+  ASSERT_FALSE(ParseTransportParameters(kClientParamsRepeated,
+                                        QUIC_ARRAYSIZE(kClientParamsRepeated),
+                                        Perspective::IS_CLIENT, &out_params));
+
+  const uint8_t kClientParamsMissing[] = {
+      0xff, 0x00, 0x00, 0x05,  // initial version
+      0x00, 0x10,              // length parameters array that follows
+      // initial_max_stream_data
+      0x00, 0x00,              // parameter id
+      0x00, 0x04,              // length
+      0x00, 0x00, 0x00, 0x0c,  // value
+      // initial_max_data
+      0x00, 0x01,              // parameter id
+      0x00, 0x04,              // length
+      0x00, 0x00, 0x00, 0x22,  // value
+  };
+  ASSERT_FALSE(ParseTransportParameters(kClientParamsMissing,
+                                        QUIC_ARRAYSIZE(kClientParamsMissing),
+                                        Perspective::IS_CLIENT, &out_params));
+}
+
+TEST_F(TransportParametersTest, ParseServerParams) {
+  // clang-format off
+  const uint8_t kServerParams[] = {
+      0xff, 0x00, 0x00, 0x05,  // negotiated_version
+      0x08,  // length of supported versions array
+      0xff, 0x00, 0x00, 0x05,
+      0xff, 0x00, 0x00, 0x04,
+      0x00, 0x2a,  // length of parameters array that follows
+      // initial_max_stream_data
+      0x00, 0x00,
+      0x00, 0x04,
+      0x00, 0x00, 0x00, 0x0c,
+      // initial_max_data
+      0x00, 0x01,
+      0x00, 0x04,
+      0x00, 0x00, 0x00, 0x22,
+      // idle_timeout
+      0x00, 0x03,
+      0x00, 0x02,
+      0x00, 0x38,
+      // stateless_reset_token
+      0x00, 0x06,
+      0x00, 0x10,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  // clang-format on
+
+  TransportParameters out_params;
+  ASSERT_TRUE(ParseTransportParameters(kServerParams,
+                                       QUIC_ARRAYSIZE(kServerParams),
+                                       Perspective::IS_SERVER, &out_params));
+}
+
+TEST_F(TransportParametersTest, ParseServerParamsWithoutToken) {
+  // clang-format off
+  const uint8_t kServerParams[] = {
+      0xff, 0x00, 0x00, 0x05,  // negotiated_version
+      0x08,  // length of supported versions array
+      0xff, 0x00, 0x00, 0x05,
+      0xff, 0x00, 0x00, 0x04,
+      0x00, 0x16,  // length of parameters array that follows
+      // initial_max_stream_data
+      0x00, 0x00,
+      0x00, 0x04,
+      0x00, 0x00, 0x00, 0x0c,
+      // initial_max_data
+      0x00, 0x01,
+      0x00, 0x04,
+      0x00, 0x00, 0x00, 0x22,
+      // idle_timeout
+      0x00, 0x03,
+      0x00, 0x02,
+      0x00, 0x38,
+  };
+  // clang-format on
+
+  TransportParameters out_params;
+  ASSERT_FALSE(ParseTransportParameters(kServerParams,
+                                        QUIC_ARRAYSIZE(kServerParams),
+                                        Perspective::IS_SERVER, &out_params));
+}
+
+TEST_F(TransportParametersTest, ParseServerParametersWithInvalidParams) {
+  TransportParameters out_params;
+
+  // clang-format off
+  const uint8_t kServerParamsRepeated[] = {
+      0xff, 0x00, 0x00, 0x05,  // negotiated_version
+      0x08,  // length of supported versions array
+      0xff, 0x00, 0x00, 0x05,
+      0xff, 0x00, 0x00, 0x04,
+      0x00, 0x30,  // length of parameters array that follows
+      // initial_max_stream_data
+      0x00, 0x00,
+      0x00, 0x04,
+      0x00, 0x00, 0x00, 0x0c,
+      // initial_max_data
+      0x00, 0x01,
+      0x00, 0x04,
+      0x00, 0x00, 0x00, 0x22,
+      // idle_timeout
+      0x00, 0x03,
+      0x00, 0x02,
+      0x00, 0x38,
+      // idle_timeout (repeat)
+      0x00, 0x03,
+      0x00, 0x02,
+      0x00, 0x38,
+      // stateless_reset_token
+      0x00, 0x06,
+      0x00, 0x10,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  // clang-format on
+  ASSERT_FALSE(ParseTransportParameters(kServerParamsRepeated,
+                                        QUIC_ARRAYSIZE(kServerParamsRepeated),
+                                        Perspective::IS_SERVER, &out_params));
+
+  // clang-format off
+  const uint8_t kServerParamsMissing[] = {
+      0xff, 0x00, 0x00, 0x05,  // negotiated_version
+      0x08,  // length of supported versions array
+      0xff, 0x00, 0x00, 0x05,
+      0xff, 0x00, 0x00, 0x04,
+      0x00, 0x24,  // length of parameters array that follows
+      // initial_max_stream_data
+      0x00, 0x00,
+      0x00, 0x04,
+      0x00, 0x00, 0x00, 0x0c,
+      // initial_max_data
+      0x00, 0x01,
+      0x00, 0x04,
+      0x00, 0x00, 0x00, 0x22,
+      // stateless_reset_token
+      0x00, 0x06,
+      0x00, 0x10,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+  // clang-format on
+  ASSERT_FALSE(ParseTransportParameters(kServerParamsMissing,
+                                        QUIC_ARRAYSIZE(kServerParamsMissing),
+                                        Perspective::IS_SERVER, &out_params));
+}
+
+TEST_F(TransportParametersTest, CryptoHandshakeMessageRoundtrip) {
+  TransportParameters orig_params;
+  orig_params.perspective = Perspective::IS_CLIENT;
+  orig_params.initial_max_stream_data = 12;
+  orig_params.initial_max_data = 34;
+  orig_params.idle_timeout = 56;
+
+  orig_params.google_quic_params = QuicMakeUnique<CryptoHandshakeMessage>();
+  const QuicString kTestString = "test string";
+  orig_params.google_quic_params->SetStringPiece(42, kTestString);
+  const uint32_t kTestValue = 12;
+  orig_params.google_quic_params->SetValue(1337, kTestValue);
+
+  std::vector<uint8_t> serialized;
+  ASSERT_TRUE(SerializeTransportParameters(orig_params, &serialized));
+
+  TransportParameters new_params;
+  ASSERT_TRUE(ParseTransportParameters(serialized.data(), serialized.size(),
+                                       Perspective::IS_CLIENT, &new_params));
+
+  ASSERT_NE(new_params.google_quic_params.get(), nullptr);
+  EXPECT_EQ(new_params.google_quic_params->tag(),
+            orig_params.google_quic_params->tag());
+  QuicStringPiece test_string;
+  EXPECT_TRUE(new_params.google_quic_params->GetStringPiece(42, &test_string));
+  EXPECT_EQ(test_string, kTestString);
+  uint32_t test_value;
+  EXPECT_EQ(new_params.google_quic_params->GetUint32(1337, &test_value),
+            QUIC_NO_ERROR);
+  EXPECT_EQ(test_value, kTestValue);
+}
+
+}  // namespace test
+}  // namespace quic