diff options
Diffstat (limited to 'chromium/net/third_party/quiche/src/quic/core/crypto')
23 files changed, 660 insertions, 283 deletions
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/boring_utils.h b/chromium/net/third_party/quiche/src/quic/core/crypto/boring_utils.h index 2927b891f98..d623fa25af5 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/boring_utils.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/boring_utils.h @@ -23,6 +23,12 @@ inline QUIC_EXPORT_PRIVATE CBS StringPieceToCbs(absl::string_view piece) { return result; } +inline QUIC_EXPORT_PRIVATE bool AddStringToCbb(CBB* cbb, + absl::string_view piece) { + return 1 == CBB_add_bytes(cbb, reinterpret_cast<const uint8_t*>(piece.data()), + piece.size()); +} + } // namespace quic #endif // QUICHE_QUIC_CORE_CRYPTO_BORING_UTILS_H_ diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.cc new file mode 100644 index 00000000000..550adffa582 --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.cc @@ -0,0 +1,280 @@ +// Copyright 2021 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 "quic/core/crypto/certificate_util.h" + +#include "absl/strings/str_format.h" +#include "absl/strings/str_split.h" +#include "absl/strings/string_view.h" +#include "third_party/boringssl/src/include/openssl/bn.h" +#include "third_party/boringssl/src/include/openssl/bytestring.h" +#include "third_party/boringssl/src/include/openssl/digest.h" +#include "third_party/boringssl/src/include/openssl/ec_key.h" +#include "third_party/boringssl/src/include/openssl/mem.h" +#include "third_party/boringssl/src/include/openssl/pkcs7.h" +#include "third_party/boringssl/src/include/openssl/pool.h" +#include "third_party/boringssl/src/include/openssl/rsa.h" +#include "third_party/boringssl/src/include/openssl/stack.h" +#include "quic/core/crypto/boring_utils.h" +#include "quic/platform/api/quic_logging.h" + +namespace quic { +namespace { +bool AddEcdsa256SignatureAlgorithm(CBB* cbb) { + // See RFC 5758. This is the encoding of OID 1.2.840.10045.4.3.2. + static const uint8_t kEcdsaWithSha256[] = {0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x04, 0x03, 0x02}; + + // An AlgorithmIdentifier is described in RFC 5280, 4.1.1.2. + CBB sequence, oid; + if (!CBB_add_asn1(cbb, &sequence, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&sequence, &oid, CBS_ASN1_OBJECT)) { + return false; + } + + if (!CBB_add_bytes(&oid, kEcdsaWithSha256, sizeof(kEcdsaWithSha256))) { + return false; + } + + // RFC 5758, section 3.2: ecdsa-with-sha256 MUST omit the parameters field. + return CBB_flush(cbb); +} + +// Adds an X.509 Name with the specified distinguished name to |cbb|. +bool AddName(CBB* cbb, absl::string_view name) { + // See RFC 4519. + static const uint8_t kCommonName[] = {0x55, 0x04, 0x03}; + static const uint8_t kCountryName[] = {0x55, 0x04, 0x06}; + static const uint8_t kOrganizationName[] = {0x55, 0x04, 0x0a}; + static const uint8_t kOrganizationalUnitName[] = {0x55, 0x04, 0x0b}; + + std::vector<std::string> attributes = + absl::StrSplit(name, ',', absl::SkipEmpty()); + + if (attributes.empty()) { + QUIC_LOG(ERROR) << "Missing DN or wrong format"; + return false; + } + + // See RFC 5280, section 4.1.2.4. + CBB rdns; + if (!CBB_add_asn1(cbb, &rdns, CBS_ASN1_SEQUENCE)) { + return false; + } + + for (const std::string& attribute : attributes) { + std::vector<std::string> parts = + absl::StrSplit(absl::StripAsciiWhitespace(attribute), '='); + if (parts.size() != 2) { + QUIC_LOG(ERROR) << "Wrong DN format at " + attribute; + return false; + } + + const std::string& type_string = parts[0]; + const std::string& value_string = parts[1]; + absl::Span<const uint8_t> type_bytes; + if (type_string == "CN") { + type_bytes = kCommonName; + } else if (type_string == "C") { + type_bytes = kCountryName; + } else if (type_string == "O") { + type_bytes = kOrganizationName; + } else if (type_string == "OU") { + type_bytes = kOrganizationalUnitName; + } else { + QUIC_LOG(ERROR) << "Unrecognized type " + type_string; + return false; + } + + CBB rdn, attr, type, value; + if (!CBB_add_asn1(&rdns, &rdn, CBS_ASN1_SET) || + !CBB_add_asn1(&rdn, &attr, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&attr, &type, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&type, type_bytes.data(), type_bytes.size()) || + !CBB_add_asn1(&attr, &value, + type_string == "C" ? CBS_ASN1_PRINTABLESTRING + : CBS_ASN1_UTF8STRING) || + !AddStringToCbb(&value, value_string) || !CBB_flush(&rdns)) { + return false; + } + } + if (!CBB_flush(cbb)) { + return false; + } + return true; +} + +bool CBBAddTime(CBB* cbb, const CertificateTimestamp& timestamp) { + CBB child; + std::string formatted_time; + + // Per RFC 5280, 4.1.2.5, times which fit in UTCTime must be encoded as + // UTCTime rather than GeneralizedTime. + const bool is_utc_time = (1950 <= timestamp.year && timestamp.year < 2050); + if (is_utc_time) { + uint16_t year = timestamp.year - 1900; + if (year >= 100) { + year -= 100; + } + formatted_time = absl::StrFormat("%02d", year); + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_UTCTIME)) { + return false; + } + } else { + formatted_time = absl::StrFormat("%04d", timestamp.year); + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_GENERALIZEDTIME)) { + return false; + } + } + + absl::StrAppendFormat(&formatted_time, "%02d%02d%02d%02d%02dZ", + timestamp.month, timestamp.day, timestamp.hour, + timestamp.minute, timestamp.second); + + static const size_t kGeneralizedTimeLength = 15; + static const size_t kUTCTimeLength = 13; + QUICHE_DCHECK_EQ(formatted_time.size(), + is_utc_time ? kUTCTimeLength : kGeneralizedTimeLength); + + return AddStringToCbb(&child, formatted_time) && CBB_flush(cbb); +} + +bool CBBAddExtension(CBB* extensions, absl::Span<const uint8_t> oid, + bool critical, absl::Span<const uint8_t> contents) { + CBB extension, cbb_oid, cbb_contents; + if (!CBB_add_asn1(extensions, &extension, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&extension, &cbb_oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&cbb_oid, oid.data(), oid.size()) || + (critical && !CBB_add_asn1_bool(&extension, 1)) || + !CBB_add_asn1(&extension, &cbb_contents, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&cbb_contents, contents.data(), contents.size()) || + !CBB_flush(extensions)) { + return false; + } + + return true; +} + +bool IsEcdsa256Key(const EVP_PKEY& evp_key) { + if (EVP_PKEY_id(&evp_key) != EVP_PKEY_EC) { + return false; + } + const EC_KEY* key = EVP_PKEY_get0_EC_KEY(&evp_key); + if (key == nullptr) { + return false; + } + const EC_GROUP* group = EC_KEY_get0_group(key); + if (group == nullptr) { + return false; + } + return EC_GROUP_get_curve_name(group) == NID_X9_62_prime256v1; +} + +} // namespace + +bssl::UniquePtr<EVP_PKEY> MakeKeyPairForSelfSignedCertificate() { + bssl::UniquePtr<EVP_PKEY_CTX> context( + EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr)); + if (!context) { + return nullptr; + } + if (EVP_PKEY_keygen_init(context.get()) != 1) { + return nullptr; + } + if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(context.get(), + NID_X9_62_prime256v1) != 1) { + return nullptr; + } + EVP_PKEY* raw_key = nullptr; + if (EVP_PKEY_keygen(context.get(), &raw_key) != 1) { + return nullptr; + } + return bssl::UniquePtr<EVP_PKEY>(raw_key); +} + +std::string CreateSelfSignedCertificate(EVP_PKEY& key, + const CertificateOptions& options) { + std::string error; + if (!IsEcdsa256Key(key)) { + QUIC_LOG(ERROR) << "CreateSelfSignedCert only accepts ECDSA P-256 keys"; + return error; + } + + // See RFC 5280, section 4.1. First, construct the TBSCertificate. + bssl::ScopedCBB cbb; + CBB tbs_cert, version, validity; + uint8_t* tbs_cert_bytes; + size_t tbs_cert_len; + + if (!CBB_init(cbb.get(), 64) || + !CBB_add_asn1(cbb.get(), &tbs_cert, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&tbs_cert, &version, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || + !CBB_add_asn1_uint64(&version, 2) || // X.509 version 3 + !CBB_add_asn1_uint64(&tbs_cert, options.serial_number) || + !AddEcdsa256SignatureAlgorithm(&tbs_cert) || // signature algorithm + !AddName(&tbs_cert, options.subject) || // issuer + !CBB_add_asn1(&tbs_cert, &validity, CBS_ASN1_SEQUENCE) || + !CBBAddTime(&validity, options.validity_start) || + !CBBAddTime(&validity, options.validity_end) || + !AddName(&tbs_cert, options.subject) || // subject + !EVP_marshal_public_key(&tbs_cert, &key)) { // subjectPublicKeyInfo + return error; + } + + CBB outer_extensions, extensions; + if (!CBB_add_asn1(&tbs_cert, &outer_extensions, + 3 | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED) || + !CBB_add_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) { + return error; + } + + // Key Usage + constexpr uint8_t kKeyUsageOid[] = {0x55, 0x1d, 0x0f}; + constexpr uint8_t kKeyUsageContent[] = { + 0x3, // BIT STRING + 0x2, // Length + 0x0, // Unused bits + 0x80, // bit(0): digitalSignature + }; + CBBAddExtension(&extensions, kKeyUsageOid, true, kKeyUsageContent); + + // TODO(wub): Add more extensions here if needed. + + if (!CBB_finish(cbb.get(), &tbs_cert_bytes, &tbs_cert_len)) { + return error; + } + + bssl::UniquePtr<uint8_t> delete_tbs_cert_bytes(tbs_cert_bytes); + + // Sign the TBSCertificate and write the entire certificate. + CBB cert, signature; + bssl::ScopedEVP_MD_CTX ctx; + uint8_t* sig_out; + size_t sig_len; + uint8_t* cert_bytes; + size_t cert_len; + if (!CBB_init(cbb.get(), tbs_cert_len) || + !CBB_add_asn1(cbb.get(), &cert, CBS_ASN1_SEQUENCE) || + !CBB_add_bytes(&cert, tbs_cert_bytes, tbs_cert_len) || + !AddEcdsa256SignatureAlgorithm(&cert) || + !CBB_add_asn1(&cert, &signature, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&signature, 0 /* no unused bits */) || + !EVP_DigestSignInit(ctx.get(), nullptr, EVP_sha256(), nullptr, &key) || + // Compute the maximum signature length. + !EVP_DigestSign(ctx.get(), nullptr, &sig_len, tbs_cert_bytes, + tbs_cert_len) || + !CBB_reserve(&signature, &sig_out, sig_len) || + // Actually sign the TBSCertificate. + !EVP_DigestSign(ctx.get(), sig_out, &sig_len, tbs_cert_bytes, + tbs_cert_len) || + !CBB_did_write(&signature, sig_len) || + !CBB_finish(cbb.get(), &cert_bytes, &cert_len)) { + return error; + } + bssl::UniquePtr<uint8_t> delete_cert_bytes(cert_bytes); + return std::string(reinterpret_cast<char*>(cert_bytes), cert_len); +} + +} // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.h b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.h new file mode 100644 index 00000000000..ebc1cf48d6e --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.h @@ -0,0 +1,46 @@ +// Copyright 2021 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. + +#ifndef QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_ +#define QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_ + +#include <string> + +#include "absl/strings/string_view.h" +#include "third_party/boringssl/src/include/openssl/evp.h" +#include "quic/core/quic_time.h" +#include "quic/platform/api/quic_export.h" + +namespace quic { + +struct QUIC_NO_EXPORT CertificateTimestamp { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t minute; + uint8_t second; +}; + +struct QUIC_NO_EXPORT CertificateOptions { + absl::string_view subject; + uint64_t serial_number; + CertificateTimestamp validity_start; // a.k.a not_valid_before + CertificateTimestamp validity_end; // a.k.a not_valid_after +}; + +// Creates a ECDSA P-256 key pair. +QUIC_EXPORT_PRIVATE bssl::UniquePtr<EVP_PKEY> +MakeKeyPairForSelfSignedCertificate(); + +// Creates a self-signed, DER-encoded X.509 certificate. +// |key| must be a ECDSA P-256 key. +// This is mostly stolen from Chromium's net/cert/x509_util.h, with +// modifications to make it work in QUICHE. +QUIC_EXPORT_PRIVATE std::string CreateSelfSignedCertificate( + EVP_PKEY& key, const CertificateOptions& options); + +} // namespace quic + +#endif // QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_UTIL_H_ diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util_test.cc new file mode 100644 index 00000000000..1ffe6f551ee --- /dev/null +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util_test.cc @@ -0,0 +1,49 @@ +// Copyright 2021 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 "quic/core/crypto/certificate_util.h" + +#include "third_party/boringssl/src/include/openssl/ssl.h" +#include "quic/core/crypto/certificate_view.h" +#include "quic/platform/api/quic_test.h" +#include "quic/platform/api/quic_test_output.h" + +namespace quic { +namespace test { +namespace { + +TEST(CertificateUtilTest, CreateSelfSignedCertificate) { + bssl::UniquePtr<EVP_PKEY> key = MakeKeyPairForSelfSignedCertificate(); + ASSERT_NE(key, nullptr); + + CertificatePrivateKey cert_key(std::move(key)); + + CertificateOptions options; + options.subject = "CN=subject"; + options.serial_number = 0x12345678; + options.validity_start = {2020, 1, 1, 0, 0, 0}; + options.validity_end = {2049, 12, 31, 0, 0, 0}; + std::string der_cert = + CreateSelfSignedCertificate(*cert_key.private_key(), options); + ASSERT_FALSE(der_cert.empty()); + + QuicSaveTestOutput("CertificateUtilTest_CreateSelfSignedCert.crt", der_cert); + + std::unique_ptr<CertificateView> cert_view = + CertificateView::ParseSingleCertificate(der_cert); + ASSERT_NE(cert_view, nullptr); + EXPECT_EQ(cert_view->public_key_type(), PublicKeyType::kP256); + + absl::optional<std::string> subject = cert_view->GetHumanReadableSubject(); + ASSERT_TRUE(subject.has_value()); + EXPECT_EQ(*subject, options.subject); + + EXPECT_TRUE( + cert_key.ValidForSignatureAlgorithm(SSL_SIGN_ECDSA_SECP256R1_SHA256)); + EXPECT_TRUE(cert_key.MatchesPublicKey(*cert_view)); +} + +} // namespace +} // namespace test +} // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc index f0b1c18a195..12866670783 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc @@ -49,14 +49,6 @@ constexpr uint8_t kX509Version[] = {0x02, 0x01, 0x02}; // 2.5.29.17 constexpr uint8_t kSubjectAltNameOid[] = {0x55, 0x1d, 0x11}; -enum class PublicKeyType { - kRsa, - kP256, - kP384, - kEd25519, - kUnknown, -}; - PublicKeyType PublicKeyTypeFromKey(EVP_PKEY* public_key) { switch (EVP_PKEY_id(public_key)) { case EVP_PKEY_RSA: @@ -176,6 +168,22 @@ absl::optional<std::string> DistinguishedNameToString(CBS input) { } // namespace +std::string PublicKeyTypeToString(PublicKeyType type) { + switch (type) { + case PublicKeyType::kRsa: + return "RSA"; + case PublicKeyType::kP256: + return "ECDSA P-256"; + case PublicKeyType::kP384: + return "ECDSA P-384"; + case PublicKeyType::kEd25519: + return "Ed25519"; + case PublicKeyType::kUnknown: + return "unknown"; + } + return ""; +} + absl::optional<quic::QuicWallTime> ParseDerTime(unsigned tag, absl::string_view payload) { if (tag != CBS_ASN1_GENERALIZEDTIME && tag != CBS_ASN1_UTCTIME) { @@ -469,11 +477,13 @@ std::vector<std::string> CertificateView::LoadPemFromStream( } } +PublicKeyType CertificateView::public_key_type() const { + return PublicKeyTypeFromKey(public_key_.get()); +} + bool CertificateView::ValidatePublicKeyParameters() { - // The profile here affects what certificates can be used: - // (1) when QUIC is used as a server library without any custom certificate - // provider logic, - // (2) when QuicTransport is handling self-signed certificates. + // The profile here affects what certificates can be used when QUIC is used as + // a server library without any custom certificate provider logic. // The goal is to allow at minimum any certificate that would be allowed on a // regular Web session over TLS 1.3 while ensuring we do not expose any // algorithms we don't want to support long-term. diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h index f2826cdd668..5b3c8c762c6 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h @@ -34,6 +34,16 @@ struct QUIC_EXPORT_PRIVATE PemReadResult { // Reads |input| line-by-line and returns the next available PEM message. QUIC_EXPORT_PRIVATE PemReadResult ReadNextPemMessage(std::istream* input); +// Cryptograhpic algorithms recognized in X.509. +enum class PublicKeyType { + kRsa, + kP256, + kP384, + kEd25519, + kUnknown, +}; +QUIC_EXPORT_PRIVATE std::string PublicKeyTypeToString(PublicKeyType type); + // CertificateView represents a parsed version of a single X.509 certificate. As // the word "view" implies, it does not take ownership of the underlying strings // and consists primarily of pointers into the certificate that is passed into @@ -69,6 +79,9 @@ class QUIC_EXPORT_PRIVATE CertificateView { absl::string_view signature, uint16_t signature_algorithm) const; + // Returns the type of the key used in the certificate's SPKI. + PublicKeyType public_key_type() const; + private: CertificateView() = default; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc index 5d743b2114c..fbca9159c82 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc @@ -58,6 +58,8 @@ TEST(CertificateViewTest, Parse) { const QuicWallTime validity_end = QuicWallTime::FromUNIXSeconds( *quiche::QuicheUtcDateTimeToUnixSeconds(2020, 2, 2, 18, 13, 59)); EXPECT_EQ(view->validity_end(), validity_end); + EXPECT_EQ(view->public_key_type(), PublicKeyType::kRsa); + EXPECT_EQ(PublicKeyTypeToString(view->public_key_type()), "RSA"); EXPECT_EQ("C=US,ST=California,L=Mountain View,O=QUIC Server,CN=127.0.0.1", view->GetHumanReadableSubject()); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_printer_bin.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_printer_bin.cc index 68e3d9cbe19..0159e3004e5 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_printer_bin.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_printer_bin.cc @@ -13,6 +13,7 @@ #include "absl/strings/escaping.h" #include "quic/core/crypto/crypto_framer.h" #include "quic/core/quic_utils.h" +#include "common/platform/api/quiche_command_line_flags.h" using std::cerr; using std::cout; @@ -37,9 +38,9 @@ class CryptoMessagePrinter : public ::quic::CryptoFramerVisitorInterface { int main(int argc, char* argv[]) { const char* usage = "Usage: crypto_message_printer <hex>"; std::vector<std::string> messages = - quic::QuicParseCommandLineFlags(usage, argc, argv); + quiche::QuicheParseCommandLineFlags(usage, argc, argv); if (messages.size() != 1) { - quic::QuicPrintCommandLineFlagHelp(usage); + quiche::QuichePrintCommandLineFlagHelp(usage); exit(0); } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h index 5a3003861e1..0ebe0e430b8 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h @@ -121,9 +121,9 @@ const QuicTag kBBQ7 = TAG('B', 'B', 'Q', '7'); // Reduce bw_lo by const QuicTag kBBQ8 = TAG('B', 'B', 'Q', '8'); // Reduce bw_lo by // bw_lo * bytes_lost/inflight const QuicTag kBBQ9 = TAG('B', 'B', 'Q', '9'); // Reduce bw_lo by + // bw_lo * bytes_lost/cwnd const QuicTag kBBQ0 = TAG('B', 'B', 'Q', '0'); // Increase bytes_acked in // PROBE_UP when app limited. - // bw_lo * bytes_lost/cwnd const QuicTag kRENO = TAG('R', 'E', 'N', 'O'); // Reno Congestion Control const QuicTag kTPCC = TAG('P', 'C', 'C', '\0'); // Performance-Oriented // Congestion Control @@ -434,6 +434,7 @@ const QuicTag kSRWP = TAG('S', 'R', 'W', 'P'); // Enable retransmittable on // Client Hints triggers. const QuicTag kGWCH = TAG('G', 'W', 'C', 'H'); const QuicTag kYTCH = TAG('Y', 'T', 'C', 'H'); +const QuicTag kACH0 = TAG('A', 'C', 'H', '0'); // Rejection tags const QuicTag kRREJ = TAG('R', 'R', 'E', 'J'); // Reasons for server sending diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.cc index 1826212d83c..a4a7a2a615d 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.cc @@ -44,8 +44,11 @@ size_t CryptoSecretBoxer::GetKeySize() { // kAEAD is the AEAD used for boxing: AES-256-GCM-SIV. static const EVP_AEAD* (*const kAEAD)() = EVP_aead_aes_256_gcm_siv; -void CryptoSecretBoxer::SetKeys(const std::vector<std::string>& keys) { - QUICHE_DCHECK(!keys.empty()); +bool CryptoSecretBoxer::SetKeys(const std::vector<std::string>& keys) { + if (keys.empty()) { + QUIC_LOG(DFATAL) << "No keys supplied!"; + return false; + } const EVP_AEAD* const aead = kAEAD(); std::unique_ptr<State> new_state(new State); @@ -57,7 +60,7 @@ void CryptoSecretBoxer::SetKeys(const std::vector<std::string>& keys) { if (!ctx) { ERR_clear_error(); QUIC_LOG(DFATAL) << "EVP_AEAD_CTX_init failed"; - return; + return false; } new_state->ctxs.push_back(std::move(ctx)); @@ -65,6 +68,7 @@ void CryptoSecretBoxer::SetKeys(const std::vector<std::string>& keys) { QuicWriterMutexLock l(&lock_); state_ = std::move(new_state); + return true; } std::string CryptoSecretBoxer::Box(QuicRandom* rand, diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h index 5dd5cb24985..e2cd0377786 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h @@ -34,13 +34,15 @@ class QUIC_EXPORT_PRIVATE CryptoSecretBoxer { // SetKeys sets a list of encryption keys. The first key in the list will be // used by |Box|, but all supplied keys will be tried by |Unbox|, to handle // key skew across the fleet. This must be called before |Box| or |Unbox|. - // Keys must be |GetKeySize()| bytes long. - void SetKeys(const std::vector<std::string>& keys); + // Keys must be |GetKeySize()| bytes long. No change is made if any key is + // invalid, or if there are no keys supplied. + bool SetKeys(const std::vector<std::string>& keys); // Box encrypts |plaintext| using a random nonce generated from |rand| and // returns the resulting ciphertext. Since an authenticator and nonce are // included, the result will be slightly larger than |plaintext|. The first - // key in the vector supplied to |SetKeys| will be used. + // key in the vector supplied to |SetKeys| will be used. |SetKeys| must be + // called before calling this method. std::string Box(QuicRandom* rand, absl::string_view plaintext) const; // Unbox takes the result of a previous call to |Box| in |ciphertext| and diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer_test.cc index 225bfc8b14e..7b07d96d11d 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer_test.cc @@ -56,9 +56,9 @@ TEST_F(CryptoSecretBoxerTest, MultipleKeys) { std::string key_12(CryptoSecretBoxer::GetKeySize(), 0x12); CryptoSecretBoxer boxer_11, boxer_12, boxer; - boxer_11.SetKeys({key_11}); - boxer_12.SetKeys({key_12}); - boxer.SetKeys({key_12, key_11}); + EXPECT_TRUE(boxer_11.SetKeys({key_11})); + EXPECT_TRUE(boxer_12.SetKeys({key_12})); + EXPECT_TRUE(boxer.SetKeys({key_12, key_11})); // Neither single-key boxer can decode the other's tokens. EXPECT_FALSE(CanDecode(boxer_11, boxer_12)); @@ -74,7 +74,7 @@ TEST_F(CryptoSecretBoxerTest, MultipleKeys) { // After we flush key_11 from |boxer|, it can no longer decode tokens from // |boxer_11|. - boxer.SetKeys({key_12}); + EXPECT_TRUE(boxer.SetKeys({key_12})); EXPECT_FALSE(CanDecode(boxer, boxer_11)); } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc index 50bbfefa4dc..05bbdfe6321 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc @@ -57,8 +57,7 @@ namespace { // |out_len|, respectively. The resulting expanded secret is returned. std::vector<uint8_t> HkdfExpandLabel(const EVP_MD* prf, const std::vector<uint8_t>& secret, - const std::string& label, - size_t out_len) { + const std::string& label, size_t out_len) { bssl::ScopedCBB quic_hkdf_label; CBB inner_label; const char label_prefix[] = "tls13 "; @@ -91,13 +90,23 @@ std::vector<uint8_t> HkdfExpandLabel(const EVP_MD* prf, } // namespace +const std::string getLabelForVersion(const ParsedQuicVersion& version, + const absl::string_view& predicate) { + static_assert(SupportedVersions().size() == 6u, + "Supported versions out of sync with HKDF labels"); + if (version == ParsedQuicVersion::V2Draft01()) { + return absl::StrCat("quicv2 ", predicate); + } else { + return absl::StrCat("quic ", predicate); + } +} + void CryptoUtils::InitializeCrypterSecrets( - const EVP_MD* prf, - const std::vector<uint8_t>& pp_secret, - QuicCrypter* crypter) { - SetKeyAndIV(prf, pp_secret, crypter); - std::vector<uint8_t> header_protection_key = - GenerateHeaderProtectionKey(prf, pp_secret, crypter->GetKeySize()); + const EVP_MD* prf, const std::vector<uint8_t>& pp_secret, + const ParsedQuicVersion& version, QuicCrypter* crypter) { + SetKeyAndIV(prf, pp_secret, version, crypter); + std::vector<uint8_t> header_protection_key = GenerateHeaderProtectionKey( + prf, pp_secret, version, crypter->GetKeySize()); crypter->SetHeaderProtectionKey( absl::string_view(reinterpret_cast<char*>(header_protection_key.data()), header_protection_key.size())); @@ -105,11 +114,13 @@ void CryptoUtils::InitializeCrypterSecrets( void CryptoUtils::SetKeyAndIV(const EVP_MD* prf, const std::vector<uint8_t>& pp_secret, + const ParsedQuicVersion& version, QuicCrypter* crypter) { std::vector<uint8_t> key = - HkdfExpandLabel(prf, pp_secret, "quic key", crypter->GetKeySize()); - std::vector<uint8_t> iv = - HkdfExpandLabel(prf, pp_secret, "quic iv", crypter->GetIVSize()); + HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "key"), + crypter->GetKeySize()); + std::vector<uint8_t> iv = HkdfExpandLabel( + prf, pp_secret, getLabelForVersion(version, "iv"), crypter->GetIVSize()); crypter->SetKey( absl::string_view(reinterpret_cast<char*>(key.data()), key.size())); crypter->SetIV( @@ -117,16 +128,17 @@ void CryptoUtils::SetKeyAndIV(const EVP_MD* prf, } std::vector<uint8_t> CryptoUtils::GenerateHeaderProtectionKey( - const EVP_MD* prf, - const std::vector<uint8_t>& pp_secret, - size_t out_len) { - return HkdfExpandLabel(prf, pp_secret, "quic hp", out_len); + const EVP_MD* prf, const std::vector<uint8_t>& pp_secret, + const ParsedQuicVersion& version, size_t out_len) { + return HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "hp"), + out_len); } std::vector<uint8_t> CryptoUtils::GenerateNextKeyPhaseSecret( - const EVP_MD* prf, + const EVP_MD* prf, const ParsedQuicVersion& version, const std::vector<uint8_t>& current_secret) { - return HkdfExpandLabel(prf, current_secret, "quic ku", current_secret.size()); + return HkdfExpandLabel(prf, current_secret, getLabelForVersion(version, "ku"), + current_secret.size()); } namespace { @@ -138,6 +150,9 @@ const uint8_t kDraft29InitialSalt[] = {0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, const uint8_t kRFCv1InitialSalt[] = {0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a}; +const uint8_t kV2Draft01InitialSalt[] = { + 0xa7, 0x07, 0xc2, 0x03, 0xa5, 0x9b, 0x47, 0x18, 0x4a, 0x1d, + 0x62, 0xca, 0x57, 0x04, 0x06, 0xea, 0x7a, 0xe3, 0xe5, 0xd3}; // Salts used by deployed versions of QUIC. When introducing a new version, // generate a new salt by running `openssl rand -hex 20`. @@ -154,9 +169,12 @@ const uint8_t kReservedForNegotiationSalt[] = { const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version, size_t* out_len) { - static_assert(SupportedVersions().size() == 5u, + static_assert(SupportedVersions().size() == 6u, "Supported versions out of sync with initial encryption salts"); - if (version == ParsedQuicVersion::RFCv1()) { + if (version == ParsedQuicVersion::V2Draft01()) { + *out_len = ABSL_ARRAYSIZE(kV2Draft01InitialSalt); + return kV2Draft01InitialSalt; + } else if (version == ParsedQuicVersion::RFCv1()) { *out_len = ABSL_ARRAYSIZE(kRFCv1InitialSalt); return kRFCv1InitialSalt; } else if (version == ParsedQuicVersion::Draft29()) { @@ -191,6 +209,11 @@ const uint8_t kRFCv1RetryIntegrityKey[] = {0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0xe3, 0x68, 0xc8, 0x4e}; const uint8_t kRFCv1RetryIntegrityNonce[] = { 0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb}; +const uint8_t kV2Draft01RetryIntegrityKey[] = { + 0xba, 0x85, 0x8d, 0xc7, 0xb4, 0x3d, 0xe5, 0xdb, + 0xf8, 0x76, 0x17, 0xff, 0x4a, 0xb2, 0x53, 0xdb}; +const uint8_t kV2Draft01RetryIntegrityNonce[] = { + 0x14, 0x1b, 0x99, 0xc2, 0x39, 0xb0, 0x3e, 0x78, 0x5d, 0x6a, 0x2e, 0x9f}; // Retry integrity key used by ParsedQuicVersion::ReservedForNegotiation(). const uint8_t kReservedForNegotiationRetryIntegrityKey[] = { 0xf2, 0xcd, 0x8f, 0xe0, 0x36, 0xd0, 0x25, 0x35, @@ -204,13 +227,21 @@ const uint8_t kReservedForNegotiationRetryIntegrityNonce[] = { bool RetryIntegrityKeysForVersion(const ParsedQuicVersion& version, absl::string_view* key, absl::string_view* nonce) { - static_assert(SupportedVersions().size() == 5u, + static_assert(SupportedVersions().size() == 6u, "Supported versions out of sync with retry integrity keys"); if (!version.UsesTls()) { QUIC_BUG(quic_bug_10699_2) << "Attempted to get retry integrity keys for invalid version " << version; return false; + } else if (version == ParsedQuicVersion::V2Draft01()) { + *key = absl::string_view( + reinterpret_cast<const char*>(kV2Draft01RetryIntegrityKey), + ABSL_ARRAYSIZE(kV2Draft01RetryIntegrityKey)); + *nonce = absl::string_view( + reinterpret_cast<const char*>(kV2Draft01RetryIntegrityNonce), + ABSL_ARRAYSIZE(kV2Draft01RetryIntegrityNonce)); + return true; } else if (version == ParsedQuicVersion::RFCv1()) { *key = absl::string_view( reinterpret_cast<const char*>(kRFCv1RetryIntegrityKey), @@ -291,20 +322,20 @@ void CryptoUtils::CreateInitialObfuscators(Perspective perspective, std::vector<uint8_t> encryption_secret = HkdfExpandLabel( hash, handshake_secret, encryption_label, EVP_MD_size(hash)); crypters->encrypter = std::make_unique<Aes128GcmEncrypter>(); - InitializeCrypterSecrets(hash, encryption_secret, crypters->encrypter.get()); + InitializeCrypterSecrets(hash, encryption_secret, version, + crypters->encrypter.get()); std::vector<uint8_t> decryption_secret = HkdfExpandLabel( hash, handshake_secret, decryption_label, EVP_MD_size(hash)); crypters->decrypter = std::make_unique<Aes128GcmDecrypter>(); - InitializeCrypterSecrets(hash, decryption_secret, crypters->decrypter.get()); + InitializeCrypterSecrets(hash, decryption_secret, version, + crypters->decrypter.get()); } // static bool CryptoUtils::ValidateRetryIntegrityTag( - ParsedQuicVersion version, - QuicConnectionId original_connection_id, - absl::string_view retry_without_tag, - absl::string_view integrity_tag) { + ParsedQuicVersion version, QuicConnectionId original_connection_id, + absl::string_view retry_without_tag, absl::string_view integrity_tag) { unsigned char computed_integrity_tag[kRetryIntegrityTagLength]; if (integrity_tag.length() != ABSL_ARRAYSIZE(computed_integrity_tag)) { QUIC_BUG(quic_bug_10699_4) @@ -348,10 +379,8 @@ bool CryptoUtils::ValidateRetryIntegrityTag( } // static -void CryptoUtils::GenerateNonce(QuicWallTime now, - QuicRandom* random_generator, - absl::string_view orbit, - std::string* nonce) { +void CryptoUtils::GenerateNonce(QuicWallTime now, QuicRandom* random_generator, + absl::string_view orbit, std::string* nonce) { // a 4-byte timestamp + 28 random bytes. nonce->reserve(kNonceSize); nonce->resize(kNonceSize); @@ -375,17 +404,13 @@ void CryptoUtils::GenerateNonce(QuicWallTime now, } // static -bool CryptoUtils::DeriveKeys(const ParsedQuicVersion& version, - absl::string_view premaster_secret, - QuicTag aead, - absl::string_view client_nonce, - absl::string_view server_nonce, - absl::string_view pre_shared_key, - const std::string& hkdf_input, - Perspective perspective, - Diversification diversification, - CrypterPair* crypters, - std::string* subkey_secret) { +bool CryptoUtils::DeriveKeys( + const ParsedQuicVersion& version, absl::string_view premaster_secret, + QuicTag aead, absl::string_view client_nonce, + absl::string_view server_nonce, absl::string_view pre_shared_key, + const std::string& hkdf_input, Perspective perspective, + Diversification diversification, CrypterPair* crypters, + std::string* subkey_secret) { // If the connection is using PSK, concatenate it with the pre-master secret. std::unique_ptr<char[]> psk_premaster_secret; if (!pre_shared_key.empty()) { @@ -573,8 +598,7 @@ QuicErrorCode CryptoUtils::ValidateServerHelloVersions( } QuicErrorCode CryptoUtils::ValidateClientHello( - const CryptoHandshakeMessage& client_hello, - ParsedQuicVersion version, + const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version, const ParsedQuicVersionVector& supported_versions, std::string* error_details) { if (client_hello.tag() != kCHLO) { @@ -597,8 +621,7 @@ QuicErrorCode CryptoUtils::ValidateClientHello( } QuicErrorCode CryptoUtils::ValidateClientHelloVersion( - QuicVersionLabel client_version, - ParsedQuicVersion connection_version, + QuicVersionLabel client_version, ParsedQuicVersion connection_version, const ParsedQuicVersionVector& supported_versions, std::string* error_details) { if (client_version != CreateQuicVersionLabel(connection_version)) { @@ -736,8 +759,7 @@ std::string CryptoUtils::EarlyDataReasonToString( // static std::string CryptoUtils::HashHandshakeMessage( - const CryptoHandshakeMessage& message, - Perspective /*perspective*/) { + const CryptoHandshakeMessage& message, Perspective /*perspective*/) { std::string output; const QuicData& serialized = message.GetSerialized(); uint8_t digest[SHA256_DIGEST_LENGTH]; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.h b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.h index 8884f6fa096..fce62018823 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.h @@ -79,9 +79,11 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { // on the given QuicCrypter |*crypter|. // This follows the derivation described in section 7.3 of RFC 8446, except // with the label prefix in HKDF-Expand-Label changed from "tls13 " to "quic " - // as described in draft-ietf-quic-tls-14, section 5.1. + // as described in draft-ietf-quic-tls-14, section 5.1, or "quicv2 " as + // described in draft-ietf-quic-v2-01. static void InitializeCrypterSecrets(const EVP_MD* prf, const std::vector<uint8_t>& pp_secret, + const ParsedQuicVersion& version, QuicCrypter* crypter); // Derives the key and IV from the packet protection secret and sets those @@ -90,17 +92,17 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { // called before using |crypter|. static void SetKeyAndIV(const EVP_MD* prf, const std::vector<uint8_t>& pp_secret, + const ParsedQuicVersion& version, QuicCrypter* crypter); // Derives the header protection key from the packet protection secret. static std::vector<uint8_t> GenerateHeaderProtectionKey( - const EVP_MD* prf, - const std::vector<uint8_t>& pp_secret, - size_t out_len); + const EVP_MD* prf, const std::vector<uint8_t>& pp_secret, + const ParsedQuicVersion& version, size_t out_len); // Given a secret for key phase n, return the secret for phase n+1. static std::vector<uint8_t> GenerateNextKeyPhaseSecret( - const EVP_MD* prf, + const EVP_MD* prf, const ParsedQuicVersion& version, const std::vector<uint8_t>& current_secret); // IETF QUIC encrypts ENCRYPTION_INITIAL messages with a version-specific key @@ -130,10 +132,8 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { // <4 bytes> current time // <8 bytes> |orbit| (or random if |orbit| is empty) // <20 bytes> random - static void GenerateNonce(QuicWallTime now, - QuicRandom* random_generator, - absl::string_view orbit, - std::string* nonce); + static void GenerateNonce(QuicWallTime now, QuicRandom* random_generator, + absl::string_view orbit, std::string* nonce); // DeriveKeys populates |crypters->encrypter|, |crypters->decrypter|, and // |subkey_secret| (optional -- may be null) given the contents of @@ -155,15 +155,12 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { // |SetDiversificationNonce| with a diversification nonce will be needed to // complete keying. static bool DeriveKeys(const ParsedQuicVersion& version, - absl::string_view premaster_secret, - QuicTag aead, + absl::string_view premaster_secret, QuicTag aead, absl::string_view client_nonce, absl::string_view server_nonce, absl::string_view pre_shared_key, - const std::string& hkdf_input, - Perspective perspective, - Diversification diversification, - CrypterPair* crypters, + const std::string& hkdf_input, Perspective perspective, + Diversification diversification, CrypterPair* crypters, std::string* subkey_secret); // Computes the FNV-1a hash of the provided DER-encoded cert for use in the @@ -199,8 +196,7 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error // code and sets |error_details|. static QuicErrorCode ValidateClientHello( - const CryptoHandshakeMessage& client_hello, - ParsedQuicVersion version, + const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version, const ParsedQuicVersionVector& supported_versions, std::string* error_details); @@ -212,8 +208,7 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { // Returns QUIC_NO_ERROR if this is the case or returns the appropriate error // code and sets |error_details|. static QuicErrorCode ValidateClientHelloVersion( - QuicVersionLabel client_version, - ParsedQuicVersion connection_version, + QuicVersionLabel client_version, ParsedQuicVersion connection_version, const ParsedQuicVersionVector& supported_versions, std::string* error_details); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils_test.cc index 251f136ec5d..f0d944b4fea 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils_test.cc @@ -8,6 +8,7 @@ #include "absl/base/macros.h" #include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" #include "quic/core/quic_utils.h" #include "quic/platform/api/quic_test.h" #include "quic/test_tools/quic_test_utils.h" @@ -165,6 +166,97 @@ TEST_F(CryptoUtilsTest, ValidateServerVersionsWithDowngrade) { EXPECT_FALSE(error_details.empty()); } +// Test that the library is using the correct labels for each version, and +// therefore generating correct obfuscators, using the test vectors in appendix +// A of each RFC or internet-draft. +TEST_F(CryptoUtilsTest, ValidateCryptoLabels) { + // if the number of HTTP/3 QUIC versions has changed, we need to change the + // expected_keys hardcoded into this test. Regrettably, this is not a + // compile-time constant. + EXPECT_EQ(AllSupportedVersionsWithTls().size(), 3u); + const char draft_29_key[] = {// test vector from draft-ietf-quic-tls-29, A.1 + 0x14, + static_cast<char>(0x9d), + 0x0b, + 0x16, + 0x62, + static_cast<char>(0xab), + static_cast<char>(0x87), + 0x1f, + static_cast<char>(0xbe), + 0x63, + static_cast<char>(0xc4), + static_cast<char>(0x9b), + 0x5e, + 0x65, + 0x5a, + 0x5d}; + const char v1_key[] = {// test vector from RFC 9001, A.1 + static_cast<char>(0xcf), + 0x3a, + 0x53, + 0x31, + 0x65, + 0x3c, + 0x36, + 0x4c, + static_cast<char>(0x88), + static_cast<char>(0xf0), + static_cast<char>(0xf3), + 0x79, + static_cast<char>(0xb6), + 0x06, + 0x7e, + 0x37}; + const char v2_01_key[] = {// test vector from draft-ietf-quic-v2-01 + 0x15, + static_cast<char>(0xd5), + static_cast<char>(0xb4), + static_cast<char>(0xd9), + static_cast<char>(0xa2), + static_cast<char>(0xb8), + static_cast<char>(0x91), + 0x6a, + static_cast<char>(0xa3), + static_cast<char>(0x9b), + 0x1b, + static_cast<char>(0xfe), + 0x57, + 0x4d, + 0x2a, + static_cast<char>(0xad)}; + const char connection_id[] = // test vector from both docs + {static_cast<char>(0x83), + static_cast<char>(0x94), + static_cast<char>(0xc8), + static_cast<char>(0xf0), + 0x3e, + 0x51, + 0x57, + 0x08}; + const QuicConnectionId cid(connection_id, sizeof(connection_id)); + const char* key_str; + size_t key_size; + for (const ParsedQuicVersion& version : AllSupportedVersionsWithTls()) { + if (version == ParsedQuicVersion::Draft29()) { + key_str = draft_29_key; + key_size = sizeof(draft_29_key); + } else if (version == ParsedQuicVersion::RFCv1()) { + key_str = v1_key; + key_size = sizeof(v1_key); + } else { // draft-ietf-quic-v2-01 + key_str = v2_01_key; + key_size = sizeof(v2_01_key); + } + const absl::string_view expected_key{key_str, key_size}; + + CrypterPair crypters; + CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER, version, cid, + &crypters); + EXPECT_EQ(crypters.encrypter->GetKey(), expected_key); + } +} + } // namespace } // namespace test } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc index e4989bc302a..1b1790adc75 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc @@ -834,9 +834,8 @@ void QuicCryptoClientConfig::AddCanonicalSuffix(const std::string& suffix) { } bool QuicCryptoClientConfig::PopulateFromCanonicalConfig( - const QuicServerId& server_id, - CachedState* server_state) { - QUICHE_DCHECK(server_state->IsEmpty()); + const QuicServerId& server_id, CachedState* cached) { + QUICHE_DCHECK(cached->IsEmpty()); size_t i = 0; for (; i < canonical_suffixes_.size(); ++i) { if (absl::EndsWithIgnoreCase(server_id.host(), canonical_suffixes_[i])) { @@ -867,7 +866,7 @@ bool QuicCryptoClientConfig::PopulateFromCanonicalConfig( // Update canonical version to point at the "most recent" entry. it->second = server_id; - server_state->InitializeFrom(*canonical_state); + cached->InitializeFrom(*canonical_state); return true; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h index 13517299087..9c71acafa08 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h @@ -332,16 +332,14 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params, std::string* error_details); - // Processes the message in |server_update|, updating the cached source + // Processes the message in |server_config_update|, updating the cached source // address token, and server config. - // If |server_update| is invalid then |error_details| will contain an error - // message, and an error code will be returned. If all has gone well + // If |server_config_update| is invalid then |error_details| will contain an + // error message, and an error code will be returned. If all has gone well // QUIC_NO_ERROR is returned. QuicErrorCode ProcessServerConfigUpdate( - const CryptoHandshakeMessage& server_update, - QuicWallTime now, - const QuicTransportVersion version, - absl::string_view chlo_hash, + const CryptoHandshakeMessage& server_config_update, QuicWallTime now, + const QuicTransportVersion version, absl::string_view chlo_hash, CachedState* cached, QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params, std::string* error_details); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc index 16a53fa920c..71c177552a0 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc @@ -512,15 +512,17 @@ bool QuicCryptoServerConfig::SetConfigs( void QuicCryptoServerConfig::SetSourceAddressTokenKeys( const std::vector<std::string>& keys) { + // TODO(b/208866709) source_address_token_boxer_.SetKeys(keys); } -void QuicCryptoServerConfig::GetConfigIds( - std::vector<std::string>* scids) const { +std::vector<std::string> QuicCryptoServerConfig::GetConfigIds() const { QuicReaderMutexLock locked(&configs_lock_); + std::vector<std::string> scids; for (auto it = configs_.begin(); it != configs_.end(); ++it) { - scids->push_back(it->first); + scids.push_back(it->first); } + return scids; } void QuicCryptoServerConfig::ValidateClientHello( @@ -538,6 +540,10 @@ void QuicCryptoServerConfig::ValidateClientHello( client_hello, client_address.host(), now)); absl::string_view requested_scid; + // We ignore here the return value from GetStringPiece. If there is no SCID + // tag, EvaluateClientHello will discover that because GetCurrentConfigs will + // not have found the requested config (i.e. because none of the configs will + // have an empty string as its id). client_hello.GetStringPiece(kSCID, &requested_scid); Configs configs; if (!GetCurrentConfigs(now, requested_scid, @@ -1575,9 +1581,14 @@ QuicCryptoServerConfig::ParseConfigProtobuf( std::unique_ptr<CryptoHandshakeMessage> msg = CryptoFramer::ParseMessage(protobuf.config()); + if (!msg) { + QUIC_LOG(WARNING) << "Failed to parse server config message"; + return nullptr; + } + if (msg->tag() != kSCFG) { QUIC_LOG(WARNING) << "Server config message has tag " << msg->tag() - << " expected " << kSCFG; + << ", but expected " << kSCFG; return nullptr; } @@ -1597,6 +1608,7 @@ QuicCryptoServerConfig::ParseConfigProtobuf( QUIC_LOG(WARNING) << "Server config message is missing SCID"; return nullptr; } + QUICHE_DCHECK(!scid.empty()); config->id = std::string(scid); if (msg->GetTaglist(kAEAD, &config->aead) != QUIC_NO_ERROR) { diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h index ca6dbe5e32f..799058d70ff 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h @@ -200,7 +200,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { // p256 determines whether a P-256 public key will be included in the // server config. Note that this breaks deterministic server-config // generation since P-256 key generation doesn't use the QuicRandom given - // to DefaultConfig(). + // to GenerateConfig(). bool p256; }; @@ -238,8 +238,8 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { const QuicServerConfigProtobuf& protobuf, QuicWallTime now); - // AddDefaultConfig calls DefaultConfig to create a config and then calls - // AddConfig to add it. See the comment for |DefaultConfig| for details of + // AddDefaultConfig calls GenerateConfig to create a config and then calls + // AddConfig to add it. See the comment for |GenerateConfig| for details of // the arguments. std::unique_ptr<CryptoHandshakeMessage> AddDefaultConfig( QuicRandom* rand, @@ -264,7 +264,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { void SetSourceAddressTokenKeys(const std::vector<std::string>& keys); // Get the server config ids for all known configs. - void GetConfigIds(std::vector<std::string>* scids) const; + std::vector<std::string> GetConfigIds() const; // Checks |client_hello| for gross errors and determines whether it can be // shown to be fresh (i.e. not a replay). The result of the validation step @@ -282,9 +282,9 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { // port may be used for certificate selection. // version: protocol version used for this connection. // clock: used to validate client nonces and ephemeral keys. - // crypto_proof: in/out parameter to which will be written the crypto proof - // used in reply to a proof demand. The pointed-to-object must - // live until the callback is invoked. + // signed_config: in/out parameter to which will be written the crypto proof + // used in reply to a proof demand. The pointed-to-object must live until + // the callback is invoked. // done_cb: single-use callback that accepts an opaque // ValidatedClientHelloMsg token that holds information about // the client hello. The callback will always be called exactly @@ -293,10 +293,9 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { void ValidateClientHello( const CryptoHandshakeMessage& client_hello, const QuicSocketAddress& client_address, - const QuicSocketAddress& server_address, - QuicTransportVersion version, + const QuicSocketAddress& server_address, QuicTransportVersion version, const QuicClock* clock, - QuicReferenceCountedPointer<QuicSignedServerConfig> crypto_proof, + QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config, std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const; // ProcessClientHello processes |client_hello| and decides whether to accept @@ -323,27 +322,22 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { // certs. Owned by QuicDispatcher. // params: the state of the handshake. This may be updated with a server // nonce when we send a rejection. - // crypto_proof: output structure containing the crypto proof used in reply to - // a proof demand. + // signed_config: output structure containing the crypto proof used in reply + // to a proof demand. // total_framing_overhead: the total per-packet overhead for a stream frame // chlo_packet_size: the size, in bytes, of the CHLO packet // done_cb: the callback invoked on completion void ProcessClientHello( QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> validate_chlo_result, - bool reject_only, - QuicConnectionId connection_id, + bool reject_only, QuicConnectionId connection_id, const QuicSocketAddress& server_address, - const QuicSocketAddress& client_address, - ParsedQuicVersion version, - const ParsedQuicVersionVector& supported_versions, - const QuicClock* clock, - QuicRandom* rand, - QuicCompressedCertsCache* compressed_certs_cache, + const QuicSocketAddress& client_address, ParsedQuicVersion version, + const ParsedQuicVersionVector& supported_versions, const QuicClock* clock, + QuicRandom* rand, QuicCompressedCertsCache* compressed_certs_cache, QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params, - QuicReferenceCountedPointer<QuicSignedServerConfig> crypto_proof, - QuicByteCount total_framing_overhead, - QuicByteCount chlo_packet_size, + QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config, + QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size, std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const; // BuildServerConfigUpdateMessage invokes |cb| with a SCUP message containing diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc index fa9be976f69..901ae66e3c1 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc @@ -106,8 +106,8 @@ TlsConnection::TlsConnection(SSL_CTX* ssl_ctx, ssl(), ssl_config_.signing_algorithm_prefs->data(), ssl_config_.signing_algorithm_prefs->size()); } - if (ssl_config.disable_ticket_support.has_value()) { - if (*ssl_config.disable_ticket_support) { + if (ssl_config_.disable_ticket_support.has_value()) { + if (*ssl_config_.disable_ticket_support) { SSL_set_options(ssl(), SSL_OP_NO_TICKET); } } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc index 61e8f7c8720..0d828db2d2b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc @@ -54,9 +54,9 @@ enum TransportParameters::TransportParameterId : uint64_t { kInitialRoundTripTime = 0x3127, kGoogleConnectionOptions = 0x3128, - kGoogleUserAgentId = 0x3129, + // 0x3129 was used to convey the user agent string. // 0x312A was used only in T050 to indicate support for HANDSHAKE_DONE. - kGoogleKeyUpdateNotYetSupported = 0x312B, + // 0x312B was used to indicate that QUIC+TLS key updates were not supported. // 0x4751 was used for non-standard Google-specific parameters encoded as a // Google QUIC_CRYPTO CHLO, it has been replaced by individual parameters. kGoogleQuicVersion = @@ -122,10 +122,6 @@ std::string TransportParameterIdToString( return "initial_round_trip_time"; case TransportParameters::kGoogleConnectionOptions: return "google_connection_options"; - case TransportParameters::kGoogleUserAgentId: - return "user_agent_id"; - case TransportParameters::kGoogleKeyUpdateNotYetSupported: - return "key_update_not_yet_supported"; case TransportParameters::kGoogleQuicVersion: return "google-version"; case TransportParameters::kMinAckDelay: @@ -164,10 +160,6 @@ bool TransportParameterIdIsKnown( return true; case TransportParameters::kVersionInformation: return GetQuicReloadableFlag(quic_version_information); - case TransportParameters::kGoogleUserAgentId: - return !GetQuicReloadableFlag(quic_ignore_user_agent_transport_parameter); - case TransportParameters::kGoogleKeyUpdateNotYetSupported: - return !GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported); } return false; } @@ -447,13 +439,6 @@ std::string TransportParameters::ToString() const { rv += QuicTagToString(connection_option); } } - if (user_agent_id.has_value()) { - rv += " " + TransportParameterIdToString(kGoogleUserAgentId) + " \"" + - user_agent_id.value() + "\""; - } - if (key_update_not_yet_supported) { - rv += " " + TransportParameterIdToString(kGoogleKeyUpdateNotYetSupported); - } for (const auto& kv : custom_parameters) { absl::StrAppend(&rv, " 0x", absl::Hex(static_cast<uint32_t>(kv.first)), "="); @@ -493,8 +478,7 @@ TransportParameters::TransportParameters() kMinActiveConnectionIdLimitTransportParam, kVarInt62MaxValue), max_datagram_frame_size(kMaxDatagramFrameSize), - initial_round_trip_time_us(kInitialRoundTripTime), - key_update_not_yet_supported(false) + initial_round_trip_time_us(kInitialRoundTripTime) // Important note: any new transport parameters must be added // to TransportParameters::AreValid, SerializeTransportParameters and // ParseTransportParameters, TransportParameters's custom copy constructor, the @@ -528,8 +512,6 @@ TransportParameters::TransportParameters(const TransportParameters& other) max_datagram_frame_size(other.max_datagram_frame_size), initial_round_trip_time_us(other.initial_round_trip_time_us), google_connection_options(other.google_connection_options), - user_agent_id(other.user_agent_id), - key_update_not_yet_supported(other.key_update_not_yet_supported), custom_parameters(other.custom_parameters) { if (other.preferred_address) { preferred_address = std::make_unique<TransportParameters::PreferredAddress>( @@ -570,8 +552,6 @@ bool TransportParameters::operator==(const TransportParameters& rhs) const { initial_round_trip_time_us.value() == rhs.initial_round_trip_time_us.value() && google_connection_options == rhs.google_connection_options && - user_agent_id == rhs.user_agent_id && - key_update_not_yet_supported == rhs.key_update_not_yet_supported && custom_parameters == rhs.custom_parameters)) { return false; } @@ -646,10 +626,6 @@ bool TransportParameters::AreValid(std::string* error_details) const { *error_details = "Server cannot send initial round trip time"; return false; } - if (perspective == Perspective::IS_SERVER && user_agent_id.has_value()) { - *error_details = "Server cannot send user agent ID"; - return false; - } if (version_information.has_value()) { const QuicVersionLabel& chosen_version = version_information.value().chosen_version; @@ -758,8 +734,6 @@ bool SerializeTransportParameters(ParsedQuicVersion /*version*/, kIntegerParameterLength + // max_datagram_frame_size kIntegerParameterLength + // initial_round_trip_time_us kTypeAndValueLength + // google_connection_options - kTypeAndValueLength + // user_agent_id - kTypeAndValueLength + // key_update_not_yet_supported kTypeAndValueLength; // google-version std::vector<TransportParameters::TransportParameterId> parameter_ids = { @@ -784,8 +758,6 @@ bool SerializeTransportParameters(ParsedQuicVersion /*version*/, TransportParameters::kInitialSourceConnectionId, TransportParameters::kRetrySourceConnectionId, TransportParameters::kGoogleConnectionOptions, - TransportParameters::kGoogleUserAgentId, - TransportParameters::kGoogleKeyUpdateNotYetSupported, TransportParameters::kGoogleQuicVersion, TransportParameters::kVersionInformation, }; @@ -796,10 +768,6 @@ bool SerializeTransportParameters(ParsedQuicVersion /*version*/, max_transport_param_length += in.google_connection_options.value().size() * sizeof(QuicTag); } - // user_agent_id. - if (in.user_agent_id.has_value()) { - max_transport_param_length += in.user_agent_id.value().length(); - } // Google-specific version extension. if (in.legacy_version_information.has_value()) { max_transport_param_length += @@ -1124,30 +1092,6 @@ bool SerializeTransportParameters(ParsedQuicVersion /*version*/, } } } break; - // Google-specific user agent identifier. - case TransportParameters::kGoogleUserAgentId: { - if (in.user_agent_id.has_value()) { - if (!writer.WriteVarInt62(TransportParameters::kGoogleUserAgentId) || - !writer.WriteStringPieceVarInt62(in.user_agent_id.value())) { - QUIC_BUG(Failed to write Google user agent ID) - << "Failed to write Google user agent ID \"" - << in.user_agent_id.value() << "\" for " << in; - return false; - } - } - } break; - // Google-specific indicator for key update not yet supported. - case TransportParameters::kGoogleKeyUpdateNotYetSupported: { - if (in.key_update_not_yet_supported) { - if (!writer.WriteVarInt62( - TransportParameters::kGoogleKeyUpdateNotYetSupported) || - !writer.WriteVarInt62(/* transport parameter length */ 0)) { - QUIC_BUG(Failed to write key_update_not_yet_supported) - << "Failed to write key_update_not_yet_supported for " << in; - return false; - } - } - } break; // Google-specific version extension. case TransportParameters::kGoogleQuicVersion: { if (!in.legacy_version_information.has_value()) { @@ -1470,54 +1414,6 @@ bool ParseTransportParameters(ParsedQuicVersion version, out->google_connection_options.value().push_back(connection_option); } } break; - case TransportParameters::kGoogleUserAgentId: - if (GetQuicReloadableFlag(quic_ignore_user_agent_transport_parameter)) { - QUIC_RELOADABLE_FLAG_COUNT( - quic_ignore_user_agent_transport_parameter); - // This is a copy of the default switch statement below. - // TODO(dschinazi) remove this case entirely when deprecating the - // quic_ignore_user_agent_transport_parameter flag. - if (out->custom_parameters.find(param_id) != - out->custom_parameters.end()) { - *error_details = "Received a second unknown parameter" + - TransportParameterIdToString(param_id); - return false; - } - out->custom_parameters[param_id] = - std::string(value_reader.ReadRemainingPayload()); - break; - } - if (out->user_agent_id.has_value()) { - *error_details = "Received a second user_agent_id"; - return false; - } - out->user_agent_id = std::string(value_reader.ReadRemainingPayload()); - break; - case TransportParameters::kGoogleKeyUpdateNotYetSupported: - if (GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported)) { - QUIC_RELOADABLE_FLAG_COUNT_N(quic_ignore_key_update_not_yet_supported, - 1, 2); - QUIC_CODE_COUNT(quic_ignore_key_update_not_yet_supported_ignored); - // This is a copy of the default switch statement below. - // TODO(dschinazi) remove this case entirely when deprecating the - // quic_ignore_key_update_not_yet_supported flag. - if (out->custom_parameters.find(param_id) != - out->custom_parameters.end()) { - *error_details = "Received a second unknown parameter" + - TransportParameterIdToString(param_id); - return false; - } - out->custom_parameters[param_id] = - std::string(value_reader.ReadRemainingPayload()); - break; - } - QUIC_CODE_COUNT(quic_ignore_key_update_not_yet_supported_received); - if (out->key_update_not_yet_supported) { - *error_details = "Received a second key_update_not_yet_supported"; - return false; - } - out->key_update_not_yet_supported = true; - break; case TransportParameters::kGoogleQuicVersion: { if (!out->legacy_version_information.has_value()) { out->legacy_version_information = diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h index fa349359571..1b6f51684fa 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h @@ -260,13 +260,6 @@ struct QUIC_EXPORT_PRIVATE TransportParameters { // Google-specific connection options. absl::optional<QuicTagVector> google_connection_options; - // Google-specific user agent identifier. - absl::optional<std::string> user_agent_id; - - // Google-specific mechanism to indicate that IETF QUIC Key Update has not - // yet been implemented. This will be removed once we implement it. - bool key_update_not_yet_supported; - // Validates whether transport parameters are valid according to // the specification. If the transport parameters are not valid, this method // will write a human-readable error message to |error_details|. diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc index d9b55730454..c9df18a3d8a 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc @@ -37,7 +37,6 @@ const uint64_t kFakeInitialRoundTripTime = 53; const uint8_t kFakePreferredStatelessResetTokenData[16] = { 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F}; -const bool kFakeKeyUpdateNotYetSupported = true; const auto kCustomParameter1 = static_cast<TransportParameters::TransportParameterId>(0xffcd); @@ -128,10 +127,6 @@ QuicTagVector CreateFakeGoogleConnectionOptions() { MakeQuicTag('H', 'I', 'J', 0xff)}; } -std::string CreateFakeUserAgentId() { - return "FakeUAID"; -} - void RemoveGreaseParameters(TransportParameters* params) { std::vector<TransportParameters::TransportParameterId> grease_params; for (const auto& kv : params->custom_parameters) { @@ -291,8 +286,6 @@ TEST_P(TransportParametersTest, CopyConstructor) { orig_params.retry_source_connection_id = CreateFakeRetrySourceConnectionId(); orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime); orig_params.google_connection_options = CreateFakeGoogleConnectionOptions(); - orig_params.user_agent_id = CreateFakeUserAgentId(); - orig_params.key_update_not_yet_supported = kFakeKeyUpdateNotYetSupported; orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value; orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value; @@ -329,12 +322,6 @@ TEST_P(TransportParametersTest, RoundTripClient) { CreateFakeInitialSourceConnectionId(); orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime); orig_params.google_connection_options = CreateFakeGoogleConnectionOptions(); - if (!GetQuicReloadableFlag(quic_ignore_user_agent_transport_parameter)) { - orig_params.user_agent_id = CreateFakeUserAgentId(); - } - if (!GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported)) { - orig_params.key_update_not_yet_supported = kFakeKeyUpdateNotYetSupported; - } orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value; orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value; @@ -578,13 +565,6 @@ TEST_P(TransportParametersTest, ParseClientParams) { 'A', 'L', 'P', 'N', // value 'E', 'F', 'G', 0x00, 'H', 'I', 'J', 0xff, - // user_agent_id - 0x71, 0x29, // parameter id - 0x08, // length - 'F', 'a', 'k', 'e', 'U', 'A', 'I', 'D', // value - // key_update_not_yet_supported - 0x71, 0x2B, // parameter id - 0x00, // length // Google version extension 0x80, 0x00, 0x47, 0x52, // parameter id 0x04, // length @@ -649,15 +629,6 @@ TEST_P(TransportParametersTest, ParseClientParams) { ASSERT_TRUE(new_params.google_connection_options.has_value()); EXPECT_EQ(CreateFakeGoogleConnectionOptions(), new_params.google_connection_options.value()); - if (!GetQuicReloadableFlag(quic_ignore_user_agent_transport_parameter)) { - ASSERT_TRUE(new_params.user_agent_id.has_value()); - EXPECT_EQ(CreateFakeUserAgentId(), new_params.user_agent_id.value()); - } else { - EXPECT_FALSE(new_params.user_agent_id.has_value()); - } - if (!GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported)) { - EXPECT_TRUE(new_params.key_update_not_yet_supported); - } } TEST_P(TransportParametersTest, @@ -844,9 +815,6 @@ TEST_P(TransportParametersTest, ParseServerParams) { 'A', 'L', 'P', 'N', // value 'E', 'F', 'G', 0x00, 'H', 'I', 'J', 0xff, - // key_update_not_yet_supported - 0x71, 0x2B, // parameter id - 0x00, // length // Google version extension 0x80, 0x00, 0x47, 0x52, // parameter id 0x0d, // length @@ -933,10 +901,6 @@ TEST_P(TransportParametersTest, ParseServerParams) { ASSERT_TRUE(new_params.google_connection_options.has_value()); EXPECT_EQ(CreateFakeGoogleConnectionOptions(), new_params.google_connection_options.value()); - EXPECT_FALSE(new_params.user_agent_id.has_value()); - if (!GetQuicReloadableFlag(quic_ignore_key_update_not_yet_supported)) { - EXPECT_TRUE(new_params.key_update_not_yet_supported); - } } TEST_P(TransportParametersTest, ParseServerParametersRepeated) { @@ -1054,8 +1018,6 @@ TEST_P(TransportParametersTest, SerializationOrderIsRandom) { CreateFakeInitialSourceConnectionId(); orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime); orig_params.google_connection_options = CreateFakeGoogleConnectionOptions(); - orig_params.user_agent_id = CreateFakeUserAgentId(); - orig_params.key_update_not_yet_supported = kFakeKeyUpdateNotYetSupported; orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value; orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value; |