summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/core/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/third_party/quiche/src/quic/core/crypto')
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/boring_utils.h6
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.cc280
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util.h46
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_util_test.cc49
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc34
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h13
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_message_printer_bin.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.cc10
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h8
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer_test.cc8
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc116
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.h33
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils_test.cc92
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc7
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h12
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc20
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h40
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc110
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h7
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc38
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;