diff options
Diffstat (limited to 'chromium/net/third_party/quiche/src/quic/core/crypto')
38 files changed, 236 insertions, 102 deletions
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.cc index 405292ea083..a3173f54456 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aead_base_encrypter.cc @@ -168,7 +168,7 @@ size_t AeadBaseEncrypter::GetIVSize() const { } size_t AeadBaseEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const { - return ciphertext_size - auth_tag_size_; + return ciphertext_size - std::min(ciphertext_size, auth_tag_size_); } size_t AeadBaseEncrypter::GetCiphertextSize(size_t plaintext_size) const { diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc index dd8a680ec32..9ce4bda19ba 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc @@ -269,7 +269,7 @@ TEST_F(Aes128Gcm12DecrypterTest, Decrypt) { // handle an AAD that is set to nullptr, as opposed // to a zero-length, non-nullptr pointer. aad.length() ? aad : QuicStringPiece(), ciphertext)); - if (!decrypted.get()) { + if (!decrypted) { EXPECT_FALSE(has_pt); continue; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc index 5ccc44da3c6..d529d5d60d4 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc @@ -228,6 +228,7 @@ TEST_F(Aes128Gcm12EncrypterTest, GetMaxPlaintextSize) { EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012)); EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112)); EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22)); + EXPECT_EQ(0u, encrypter.GetMaxPlaintextSize(11)); } TEST_F(Aes128Gcm12EncrypterTest, GetCiphertextSize) { diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter_test.cc index 54793f8c6e2..579f76d498d 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_decrypter_test.cc @@ -258,7 +258,7 @@ TEST_F(Aes128GcmDecrypterTest, Decrypt) { // handle an AAD that is set to nullptr, as opposed // to a zero-length, non-nullptr pointer. aad.length() ? aad : QuicStringPiece(), ciphertext)); - if (!decrypted.get()) { + if (!decrypted) { EXPECT_FALSE(has_pt); continue; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter_test.cc index 73a3b3deec4..b3d61c7798f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/aes_256_gcm_decrypter_test.cc @@ -262,7 +262,7 @@ TEST_F(Aes256GcmDecrypterTest, Decrypt) { // handle an AAD that is set to nullptr, as opposed // to a zero-length, non-nullptr pointer. aad.length() ? aad : QuicStringPiece(), ciphertext)); - if (!decrypted.get()) { + if (!decrypted) { EXPECT_FALSE(has_pt); continue; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter_test.cc index a9c4999683b..930af24a3b3 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_decrypter_test.cc @@ -159,7 +159,7 @@ TEST_F(ChaCha20Poly1305DecrypterTest, Decrypt) { // is set to nullptr, as opposed to a zero-length, non-nullptr pointer. QuicStringPiece(aad.length() ? aad.data() : nullptr, aad.length()), ct)); - if (!decrypted.get()) { + if (!decrypted) { EXPECT_FALSE(has_pt); continue; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc index ce4dea9f385..90052d60520 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc @@ -154,7 +154,7 @@ TEST_F(ChaCha20Poly1305TlsDecrypterTest, Decrypt) { // is set to nullptr, as opposed to a zero-length, non-nullptr pointer. QuicStringPiece(aad.length() ? aad.data() : nullptr, aad.length()), ct)); - if (!decrypted.get()) { + if (!decrypted) { EXPECT_FALSE(has_pt); continue; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.cc index eb1e95fb98c..c67fd89d4ef 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_decrypter.cc @@ -10,6 +10,7 @@ #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" #include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" namespace quic { @@ -30,7 +31,7 @@ std::string ChaChaBaseDecrypter::GenerateHeaderProtectionMask( } const uint8_t* nonce = reinterpret_cast<const uint8_t*>(sample.data()) + 4; uint32_t counter; - QuicDataReader(sample.data(), 4, Endianness::HOST_BYTE_ORDER) + QuicDataReader(sample.data(), 4, quiche::HOST_BYTE_ORDER) .ReadUInt32(&counter); const uint8_t zeroes[] = {0, 0, 0, 0, 0}; std::string out(QUIC_ARRAYSIZE(zeroes), 0); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.cc index 04d902f4b4c..9c465a944c9 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/chacha_base_encrypter.cc @@ -8,6 +8,7 @@ #include "net/third_party/quiche/src/quic/core/quic_data_reader.h" #include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" namespace quic { @@ -27,7 +28,7 @@ std::string ChaChaBaseEncrypter::GenerateHeaderProtectionMask( } const uint8_t* nonce = reinterpret_cast<const uint8_t*>(sample.data()) + 4; uint32_t counter; - QuicDataReader(sample.data(), 4, Endianness::HOST_BYTE_ORDER) + QuicDataReader(sample.data(), 4, quiche::HOST_BYTE_ORDER) .ReadUInt32(&counter); const uint8_t zeroes[] = {0, 0, 0, 0, 0}; std::string out(QUIC_ARRAYSIZE(zeroes), 0); diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.cc index 6feaa8a0e9d..c3dd2aa142b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_framer.cc @@ -15,6 +15,7 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h" #include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" namespace quic { @@ -117,7 +118,8 @@ bool CryptoFramer::HasTag(QuicTag tag) const { } void CryptoFramer::ForceHandshake() { - QuicDataReader reader(buffer_.data(), buffer_.length(), HOST_BYTE_ORDER); + QuicDataReader reader(buffer_.data(), buffer_.length(), + quiche::HOST_BYTE_ORDER); for (const std::pair<QuicTag, size_t>& item : tags_and_lengths_) { QuicStringPiece value; if (reader.BytesRemaining() < item.second) { @@ -156,7 +158,7 @@ std::unique_ptr<QuicData> CryptoFramer::ConstructHandshakeMessage( } std::unique_ptr<char[]> buffer(new char[len]); - QuicDataWriter writer(len, buffer.get(), HOST_BYTE_ORDER); + QuicDataWriter writer(len, buffer.get(), quiche::HOST_BYTE_ORDER); if (!writer.WriteTag(message.tag())) { DCHECK(false) << "Failed to write message tag."; return nullptr; @@ -244,7 +246,8 @@ void CryptoFramer::Clear() { QuicErrorCode CryptoFramer::Process(QuicStringPiece input) { // Add this data to the buffer. buffer_.append(input.data(), input.length()); - QuicDataReader reader(buffer_.data(), buffer_.length(), HOST_BYTE_ORDER); + QuicDataReader reader(buffer_.data(), buffer_.length(), + quiche::HOST_BYTE_ORDER); switch (state_) { case STATE_READING_TAG: diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.cc index 022a86b9227..56f0bd62a1f 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.cc @@ -12,10 +12,10 @@ #include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.h" #include "net/third_party/quiche/src/quic/core/quic_socket_address_coder.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_endian.h" #include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h" #include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h" #include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" namespace quic { @@ -57,7 +57,7 @@ void CryptoHandshakeMessage::Clear() { } const QuicData& CryptoHandshakeMessage::GetSerialized() const { - if (!serialized_.get()) { + if (!serialized_) { serialized_ = CryptoFramer::ConstructHandshakeMessage(*this); } return *serialized_; @@ -73,14 +73,15 @@ void CryptoHandshakeMessage::SetVersionVector( QuicVersionLabelVector version_labels; for (ParsedQuicVersion version : versions) { version_labels.push_back( - QuicEndian::HostToNet32(CreateQuicVersionLabel(version))); + quiche::QuicheEndian::HostToNet32(CreateQuicVersionLabel(version))); } SetVector(tag, version_labels); } void CryptoHandshakeMessage::SetVersion(QuicTag tag, ParsedQuicVersion version) { - SetValue(tag, QuicEndian::HostToNet32(CreateQuicVersionLabel(version))); + SetValue(tag, + quiche::QuicheEndian::HostToNet32(CreateQuicVersionLabel(version))); } void CryptoHandshakeMessage::SetStringPiece(QuicTag tag, @@ -128,7 +129,7 @@ QuicErrorCode CryptoHandshakeMessage::GetVersionLabelList( } for (size_t i = 0; i < out->size(); ++i) { - (*out)[i] = QuicEndian::HostToNet32((*out)[i]); + (*out)[i] = quiche::QuicheEndian::HostToNet32((*out)[i]); } return QUIC_NO_ERROR; @@ -142,7 +143,7 @@ QuicErrorCode CryptoHandshakeMessage::GetVersionLabel( return error; } - *out = QuicEndian::HostToNet32(*out); + *out = quiche::QuicheEndian::HostToNet32(*out); return QUIC_NO_ERROR; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message_test.cc index f595581601f..b6dfdd4cdaa 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message_test.cc @@ -6,8 +6,8 @@ #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_endian.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" namespace quic { namespace test { 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 ecbcab82e53..67cd531dd72 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 @@ -14,7 +14,6 @@ #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h" -using quic::Perspective; using std::cerr; using std::cout; using std::endl; 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 4d5a890bba2..9707fb5b0ca 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 @@ -176,6 +176,11 @@ const QuicTag kILD3 = TAG('I', 'L', 'D', '3'); // IETF style loss detection // with 1/4 RTT time threshold // and adaptive packet // threshold +const QuicTag kILD4 = TAG('I', 'L', 'D', '4'); // IETF style loss detection + // with both adaptive time + // threshold (default 1/4 RTT) + // and adaptive packet + // threshold // TODO(fayang): Remove this connection option when QUIC_VERSION_35, is removed // Since MAX_HEADER_LIST_SIZE settings frame is supported instead. const QuicTag kSMHL = TAG('S', 'M', 'H', 'L'); // Support MAX_HEADER_LIST_SIZE @@ -194,6 +199,16 @@ const QuicTag k8PTO = TAG('8', 'P', 'T', 'O'); // Closes connection on 8 // consecutive PTOs. const QuicTag kPTOS = TAG('P', 'T', 'O', 'S'); // Skip packet number before // sending the last PTO. +const QuicTag kPTOA = TAG('P', 'T', 'O', 'A'); // Do not add max ack delay + // when computing PTO timeout + // if an immediate ACK is + // expected. +const QuicTag kPEB1 = TAG('P', 'E', 'B', '1'); // Start exponential backoff + // since 1st PTO. +const QuicTag kPEB2 = TAG('P', 'E', 'B', '2'); // Start exponential backoff + // since 2nd PTO. +const QuicTag kPVS1 = TAG('P', 'V', 'S', '1'); // Use 2 * rttvar when + // calculating PTO timeout. // Optional support of truncated Connection IDs. If sent by a peer, the value // is the minimum number of bytes allowed for the connection ID sent to the @@ -217,6 +232,12 @@ const QuicTag kBWS2 = TAG('B', 'W', 'S', '2'); // Server bw resumption v2. const QuicTag kBWS3 = TAG('B', 'W', 'S', '3'); // QUIC Initial CWND - Control. const QuicTag kBWS4 = TAG('B', 'W', 'S', '4'); // QUIC Initial CWND - Enabled. const QuicTag kBWS5 = TAG('B', 'W', 'S', '5'); // QUIC Initial CWND up and down +const QuicTag kBWS6 = TAG('B', 'W', 'S', '6'); // QUIC Initial CWND - Enabled + // with 0.5 * default + // multiplier. +const QuicTag kBWS7 = TAG('B', 'W', 'S', '7'); // QUIC Initial CWND - Enabled + // with 0.75 * default + // multiplier. // Enable path MTU discovery experiment. const QuicTag kMTUH = TAG('M', 'T', 'U', 'H'); // High-target MTU discovery. diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_server_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_server_test.cc index b869f8bdeea..2db49d22a42 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_server_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/crypto_server_test.cc @@ -22,7 +22,6 @@ #include "net/third_party/quiche/src/quic/core/quic_socket_address_coder.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_endian.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" @@ -33,6 +32,7 @@ #include "net/third_party/quiche/src/quic/test_tools/mock_random.h" #include "net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" namespace quic { namespace test { @@ -125,7 +125,7 @@ class CryptoServerTest : public QuicTestWithParam<TestParams> { config_.GenerateConfig(rand_, &clock_, config_options_); primary_config.set_primary_time(clock_.WallNow().ToUNIXSeconds()); std::unique_ptr<CryptoHandshakeMessage> msg( - config_.AddConfig(std::move(primary_config), clock_.WallNow())); + config_.AddConfig(primary_config, clock_.WallNow())); QuicStringPiece orbit; CHECK(msg->GetStringPiece(kORBT, &orbit)); 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 59cc9673653..037990ae797 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 @@ -30,6 +30,7 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" namespace quic { @@ -109,8 +110,8 @@ void CryptoUtils::SetKeyAndIV(const EVP_MD* prf, namespace { -static_assert(kQuicIetfDraftVersion == 23, "Salts do not match draft version"); -// Salt from https://tools.ietf.org/html/draft-ietf-quic-tls-23#section-5.2 +static_assert(kQuicIetfDraftVersion == 24, "Salts do not match draft version"); +// Salt from https://tools.ietf.org/html/draft-ietf-quic-tls-24#section-5.2 const uint8_t kDraft23InitialSalt[] = {0xc3, 0xee, 0xf7, 0x12, 0xc7, 0x2e, 0xbb, 0x5a, 0x11, 0xa7, 0xd2, 0x43, 0x2b, 0xb4, 0x63, 0x65, 0xbe, 0xf9, 0xf5, 0x02}; @@ -141,7 +142,7 @@ const uint8_t kQ099Salt[] = {0xc0, 0xa2, 0xee, 0x20, 0xc7, 0xe1, 0x83, const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version, size_t* out_len) { - static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 8u, + static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 6u, "Supported versions out of sync with initial encryption salts"); switch (version.handshake_protocol) { case PROTOCOL_QUIC_CRYPTO: @@ -299,7 +300,7 @@ bool CryptoUtils::DeriveKeys(const ParsedQuicVersion& version, psk_premaster_secret = std::make_unique<char[]>(psk_premaster_secret_size); QuicDataWriter writer(psk_premaster_secret_size, psk_premaster_secret.get(), - HOST_BYTE_ORDER); + quiche::HOST_BYTE_ORDER); if (!writer.WriteStringPiece(label) || !writer.WriteUInt8(0) || !writer.WriteStringPiece(pre_shared_key) || 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 cb02dd79542..da746e3d63c 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 @@ -32,7 +32,7 @@ class QUIC_EXPORT_PRIVATE CryptoUtils { // Diversification is a utility class that's used to act like a union type. // Values can be created by calling the functions like |NoDiversification|, // below. - class Diversification { + class QUIC_EXPORT_PRIVATE Diversification { public: enum Mode { NEVER, // Key diversification will never be used. Forward secure diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.h b/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.h index c695523ef32..127dc62ea14 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/key_exchange.h @@ -25,7 +25,7 @@ class QUIC_EXPORT_PRIVATE AsynchronousKeyExchange { // Callback base class for receiving the results of an async call to // CalculateSharedKeys. - class Callback { + class QUIC_EXPORT_PRIVATE Callback { public: Callback() = default; virtual ~Callback() = default; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.cc index af0a8868cb5..51d8b11695b 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/null_decrypter.cc @@ -10,6 +10,7 @@ #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h" +#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" namespace quic { @@ -50,7 +51,7 @@ bool NullDecrypter::DecryptPacket(uint64_t /*packet_number*/, size_t* output_length, size_t max_output_length) { QuicDataReader reader(ciphertext.data(), ciphertext.length(), - HOST_BYTE_ORDER); + quiche::HOST_BYTE_ORDER); QuicUint128 hash; if (!ReadHash(&reader, &hash)) { diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.cc index 4ad9b2ad382..1fe0fdfc8bf 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter.cc @@ -75,7 +75,7 @@ size_t NullEncrypter::GetIVSize() const { } size_t NullEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const { - return ciphertext_size - GetHashLength(); + return ciphertext_size - std::min(ciphertext_size, GetHashLength()); } size_t NullEncrypter::GetCiphertextSize(size_t plaintext_size) const { diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter_test.cc index fd95cc6fb76..c6a89efbf29 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/null_encrypter_test.cc @@ -87,6 +87,7 @@ TEST_F(NullEncrypterTest, GetMaxPlaintextSize) { EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012)); EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112)); EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22)); + EXPECT_EQ(0u, encrypter.GetMaxPlaintextSize(11)); } TEST_F(NullEncrypterTest, GetCiphertextSize) { diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.h b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.h index fd890987d5d..f774efc3f22 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.h @@ -37,13 +37,13 @@ class QUIC_EXPORT_PRIVATE ProofSource { // Details is an abstract class which acts as a container for any // implementation-specific details that a ProofSource wants to return. - class Details { + class QUIC_EXPORT_PRIVATE Details { public: virtual ~Details() {} }; // Callback base class for receiving the results of an async call to GetProof. - class Callback { + class QUIC_EXPORT_PRIVATE Callback { public: Callback() {} virtual ~Callback() {} @@ -74,7 +74,7 @@ class QUIC_EXPORT_PRIVATE ProofSource { }; // Base class for signalling the completion of a call to ComputeTlsSignature. - class SignatureCallback { + class QUIC_EXPORT_PRIVATE SignatureCallback { public: SignatureCallback() {} virtual ~SignatureCallback() = default; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h index 20031874c83..586ea88f676 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h @@ -52,7 +52,7 @@ class QUIC_EXPORT_PRIVATE QuicCompressedCertsCache { // A wrapper of the tuple: // |chain, client_common_set_hashes, client_cached_cert_hashes| // to identify uncompressed representation of certs. - struct UncompressedCerts { + struct QUIC_EXPORT_PRIVATE UncompressedCerts { UncompressedCerts(); UncompressedCerts( const QuicReferenceCountedPointer<ProofSource::Chain>& chain, @@ -68,7 +68,7 @@ class QUIC_EXPORT_PRIVATE QuicCompressedCertsCache { // Certs stored by QuicCompressedCertsCache where uncompressed certs data is // used to identify the uncompressed representation of certs and // |compressed_cert| is the cached compressed representation. - class CachedCerts { + class QUIC_EXPORT_PRIVATE CachedCerts { public: CachedCerts(); CachedCerts(const UncompressedCerts& uncompressed_certs, 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 75b2e6a2884..d674126b6df 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 @@ -28,7 +28,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_client_stats.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_endian.h" #include "net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" #include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h" @@ -61,7 +60,13 @@ void RecordDiskCacheServerConfigState( QuicCryptoClientConfig::QuicCryptoClientConfig( std::unique_ptr<ProofVerifier> proof_verifier) + : QuicCryptoClientConfig(std::move(proof_verifier), nullptr) {} + +QuicCryptoClientConfig::QuicCryptoClientConfig( + std::unique_ptr<ProofVerifier> proof_verifier, + std::unique_ptr<SessionCache> session_cache) : proof_verifier_(std::move(proof_verifier)), + session_cache_(std::move(session_cache)), ssl_ctx_(TlsClientConnection::CreateSslCtx()) { DCHECK(proof_verifier_.get()); SetDefaults(); @@ -120,7 +125,7 @@ QuicCryptoClientConfig::CachedState::GetServerConfig() const { return nullptr; } - if (!scfg_.get()) { + if (!scfg_) { scfg_ = CryptoFramer::ParseMessage(server_config_); DCHECK(scfg_.get()); } @@ -850,6 +855,10 @@ ProofVerifier* QuicCryptoClientConfig::proof_verifier() const { return proof_verifier_.get(); } +SessionCache* QuicCryptoClientConfig::session_cache() const { + return session_cache_.get(); +} + SSL_CTX* QuicCryptoClientConfig::ssl_ctx() const { return ssl_ctx_.get(); } 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 838b2eef010..a3e1bcd18b2 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 @@ -12,8 +12,10 @@ #include <vector> #include "third_party/boringssl/src/include/openssl/base.h" +#include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" +#include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_server_id.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" @@ -27,6 +29,53 @@ class ProofVerifier; class ProofVerifyDetails; class QuicRandom; +// QuicResumptionState stores the state a client needs for performing connection +// resumption. +struct QUIC_EXPORT_PRIVATE QuicResumptionState { + // |tls_session| holds the cryptographic state necessary for a resumption. It + // includes the ALPN negotiated on the connection where the ticket was + // received. + bssl::UniquePtr<SSL_SESSION> tls_session; + + // If the application using QUIC doesn't support 0-RTT handshakes or the + // client didn't receive a 0-RTT capable session ticket from the server, + // |transport_params| will be null. Otherwise, it will contain the transport + // parameters received from the server on the original connection. + std::unique_ptr<TransportParameters> transport_params; + + // If |transport_params| is null, then |application_state| is ignored and + // should be empty. |application_state| contains serialized state that the + // client received from the server at the application layer that the client + // needs to remember when performing a 0-RTT handshake. + std::vector<uint8_t> application_state; +}; + +// SessionCache is an interface for managing storing and retrieving +// QuicResumptionState structs. +class QUIC_EXPORT_PRIVATE SessionCache { + public: + virtual ~SessionCache() {} + + // Inserts |state| into the cache, keyed by |server_id|. Insert is called + // after a session ticket is received. If the session ticket is valid for + // 0-RTT, there may be a delay between its receipt and the call to Insert + // while waiting for application state for |state|. + // + // Insert may be called multiple times per connection. SessionCache + // implementations should support storing multiple entries per server ID. + virtual void Insert(const QuicServerId& server_id, + std::unique_ptr<QuicResumptionState> state) = 0; + + // Lookup is called once at the beginning of each TLS handshake to potentially + // provide the saved state both for the TLS handshake and for sending 0-RTT + // data (if supported). Lookup may return a nullptr. Implementations should + // delete cache entries after returning them in Lookup so that session tickets + // are used only once. + virtual std::unique_ptr<QuicResumptionState> Lookup( + const QuicServerId& server_id, + const SSL_CTX* ctx) = 0; +}; + // QuicCryptoClientConfig contains crypto-related configuration settings for a // client. Note that this object isn't thread-safe. It's designed to be used on // a single thread at a time. @@ -195,7 +244,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { }; // Used to filter server ids for partial config deletion. - class ServerIdFilter { + class QUIC_EXPORT_PRIVATE ServerIdFilter { public: virtual ~ServerIdFilter() {} @@ -203,8 +252,11 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { virtual bool Matches(const QuicServerId& server_id) const = 0; }; + // DEPRECATED: Use the constructor below instead. explicit QuicCryptoClientConfig( std::unique_ptr<ProofVerifier> proof_verifier); + QuicCryptoClientConfig(std::unique_ptr<ProofVerifier> proof_verifier, + std::unique_ptr<SessionCache> session_cache); QuicCryptoClientConfig(const QuicCryptoClientConfig&) = delete; QuicCryptoClientConfig& operator=(const QuicCryptoClientConfig&) = delete; ~QuicCryptoClientConfig(); @@ -309,7 +361,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { std::string* error_details); ProofVerifier* proof_verifier() const; - + SessionCache* session_cache() const; SSL_CTX* ssl_ctx() const; // Initialize the CachedState from |canonical_crypto_config| for the @@ -388,6 +440,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { std::vector<std::string> canonical_suffixes_; std::unique_ptr<ProofVerifier> proof_verifier_; + std::unique_ptr<SessionCache> session_cache_; bssl::UniquePtr<SSL_CTX> ssl_ctx_; // The |user_agent_id_| passed in QUIC's CHLO message. diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config_test.cc index 683180bf030..8b5f116d107 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config_test.cc @@ -10,7 +10,6 @@ #include "net/third_party/quiche/src/quic/core/quic_server_id.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_endian.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/mock_random.h" @@ -115,11 +114,9 @@ TEST_F(QuicCryptoClientConfigTest, CachedState_ServerDesignatedConnectionId) { TEST_F(QuicCryptoClientConfigTest, CachedState_ServerIdConsumedBeforeSet) { QuicCryptoClientConfig::CachedState state; EXPECT_FALSE(state.has_server_designated_connection_id()); -#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG) - EXPECT_DEBUG_DEATH(state.GetNextServerDesignatedConnectionId(), - "Attempting to consume a connection id " - "that was never designated."); -#endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG) + EXPECT_QUIC_DEBUG_DEATH(state.GetNextServerDesignatedConnectionId(), + "Attempting to consume a connection id " + "that was never designated."); } TEST_F(QuicCryptoClientConfigTest, CachedState_ServerNonce) { @@ -156,11 +153,9 @@ TEST_F(QuicCryptoClientConfigTest, CachedState_ServerNonce) { TEST_F(QuicCryptoClientConfigTest, CachedState_ServerNonceConsumedBeforeSet) { QuicCryptoClientConfig::CachedState state; EXPECT_FALSE(state.has_server_nonce()); -#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG) - EXPECT_DEBUG_DEATH(state.GetNextServerNonce(), - "Attempting to consume a server nonce " - "that was never designated."); -#endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG) + EXPECT_QUIC_DEBUG_DEATH(state.GetNextServerNonce(), + "Attempting to consume a server nonce " + "that was never designated."); } TEST_F(QuicCryptoClientConfigTest, CachedState_InitializeFrom) { 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 c211cdb3345..d5689862fcf 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 @@ -38,7 +38,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" #include "net/third_party/quiche/src/quic/platform/api/quic_cert_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_clock.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_endian.h" #include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" @@ -385,14 +384,14 @@ std::unique_ptr<CryptoHandshakeMessage> QuicCryptoServerConfig::AddConfig( std::unique_ptr<CryptoHandshakeMessage> msg = CryptoFramer::ParseMessage(protobuf.config()); - if (!msg.get()) { + if (!msg) { QUIC_LOG(WARNING) << "Failed to parse server config message"; return nullptr; } QuicReferenceCountedPointer<Config> config = ParseConfigProtobuf(protobuf, /* is_fallback = */ false); - if (!config.get()) { + if (!config) { QUIC_LOG(WARNING) << "Failed to parse server config message"; return nullptr; } @@ -896,7 +895,7 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterCalculateSharedKeys( } std::unique_ptr<CryptoHandshakeMessage> cetv(CryptoFramer::ParseMessage( QuicStringPiece(plaintext, plaintext_length))); - if (!cetv.get()) { + if (!cetv) { context->Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "CETV parse error"); return; } @@ -1281,7 +1280,6 @@ void QuicCryptoServerConfig::EvaluateClientHello( // Server nonce is optional, and used for key derivation if present. client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); - QUIC_DVLOG(1) << "No 0-RTT replay protection in QUIC_VERSION_33 and higher."; // If the server nonce is empty and we're requiring handshake confirmation // for DoS reasons then we must reject the CHLO. if (GetQuicReloadableFlag(quic_require_handshake_confirmation) && 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 3fb424d4022..809ebaec575 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 @@ -41,7 +41,7 @@ struct QuicSignedServerConfig; // ClientHelloInfo contains information about a client hello message that is // only kept for as long as it's being processed. -struct ClientHelloInfo { +struct QUIC_EXPORT_PRIVATE ClientHelloInfo { ClientHelloInfo(const QuicIpAddress& in_client_ip, QuicWallTime in_now); ClientHelloInfo(const ClientHelloInfo& other); ~ClientHelloInfo(); @@ -68,7 +68,7 @@ class QuicCryptoServerConfigPeer; } // namespace test // Hook that allows application code to subscribe to primary config changes. -class PrimaryConfigChangedCallback { +class QUIC_EXPORT_PRIVATE PrimaryConfigChangedCallback { public: PrimaryConfigChangedCallback(); PrimaryConfigChangedCallback(const PrimaryConfigChangedCallback&) = delete; @@ -128,7 +128,7 @@ class QUIC_EXPORT_PRIVATE ProcessClientHelloResultCallback { // Callback used to receive the results of a call to // BuildServerConfigUpdateMessage. -class BuildServerConfigUpdateMessageResultCallback { +class QUIC_EXPORT_PRIVATE BuildServerConfigUpdateMessageResultCallback { public: BuildServerConfigUpdateMessageResultCallback() = default; virtual ~BuildServerConfigUpdateMessageResultCallback() {} @@ -141,7 +141,7 @@ class BuildServerConfigUpdateMessageResultCallback { // Object that is interested in built rejections (which include REJ, SREJ and // cheap SREJ). -class RejectionObserver { +class QUIC_EXPORT_PRIVATE RejectionObserver { public: RejectionObserver() = default; virtual ~RejectionObserver() {} @@ -511,7 +511,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { QUIC_SHARED_LOCKS_REQUIRED(configs_lock_); // A snapshot of the configs associated with an in-progress handshake. - struct Configs { + struct QUIC_EXPORT_PRIVATE Configs { QuicReferenceCountedPointer<Config> requested; QuicReferenceCountedPointer<Config> primary; QuicReferenceCountedPointer<Config> fallback; @@ -552,7 +552,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { // Convenience class which carries the arguments passed to // |ProcessClientHellp| along. - class ProcessClientHelloContext { + class QUIC_EXPORT_PRIVATE ProcessClientHelloContext { public: ProcessClientHelloContext( QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config_test.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config_test.cc index bc9b2efe200..8f9e4ba776a 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config_test.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config_test.cc @@ -18,6 +18,7 @@ #include "net/third_party/quiche/src/quic/core/quic_time.h" #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h" #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/mock_clock.h" #include "net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h" @@ -351,7 +352,7 @@ class CryptoServerConfigsTest : public QuicTest { QuicCryptoServerConfig::GenerateConfig(rand_, &clock_, options); protobuf.set_primary_time(primary_time); protobuf.set_priority(priority); - if (std::string(server_config_id).find("INVALID") == 0) { + if (QuicTextUtils::StartsWith(std::string(server_config_id), "INVALID")) { protobuf.clear_key(); has_invalid = true; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.h b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.h index 09006eef4db..94d45bc91a6 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/quic_hkdf.h @@ -15,7 +15,7 @@ namespace quic { // QuicHKDF implements the key derivation function specified in RFC 5869 // (using SHA-256) and outputs key material, as needed by QUIC. // See https://tools.ietf.org/html/rfc5869 for details. -class QUIC_EXPORT QuicHKDF { +class QUIC_EXPORT_PRIVATE QuicHKDF { public: // |secret|: the input shared secret (or, from RFC 5869, the IKM). // |salt|: an (optional) public salt / non-secret random value. While diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.cc index f28af660e90..7d112245b3c 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.cc @@ -14,11 +14,14 @@ TlsClientConnection::TlsClientConnection(SSL_CTX* ssl_ctx, Delegate* delegate) bssl::UniquePtr<SSL_CTX> TlsClientConnection::CreateSslCtx() { bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx(); // Configure certificate verification. - // TODO(nharper): This only verifies certs on initial connection, not on - // resumption. Chromium has this callback be a no-op and verifies the - // certificate after the connection is complete. We need to re-verify on - // resumption in case of expiration or revocation/distrust. SSL_CTX_set_custom_verify(ssl_ctx.get(), SSL_VERIFY_PEER, &VerifyCallback); + int reverify_on_resume_enabled = 1; + SSL_CTX_set_reverify_on_resume(ssl_ctx.get(), reverify_on_resume_enabled); + + // Configure session caching. + SSL_CTX_set_session_cache_mode( + ssl_ctx.get(), SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL); + SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback); return ssl_ctx; } @@ -30,4 +33,11 @@ enum ssl_verify_result_t TlsClientConnection::VerifyCallback( ->delegate_->VerifyCert(out_alert); } +// static +int TlsClientConnection::NewSessionCallback(SSL* ssl, SSL_SESSION* session) { + static_cast<TlsClientConnection*>(ConnectionFromSsl(ssl)) + ->delegate_->InsertSession(bssl::UniquePtr<SSL_SESSION>(session)); + return 1; +} + } // namespace quic diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h index a9212ff2a72..035f420a835 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h @@ -15,7 +15,7 @@ class QUIC_EXPORT_PRIVATE TlsClientConnection : public TlsConnection { public: // A TlsClientConnection::Delegate implements the client-specific methods that // are set as callbacks for an SSL object. - class Delegate { + class QUIC_EXPORT_PRIVATE Delegate { public: virtual ~Delegate() {} @@ -26,6 +26,9 @@ class QUIC_EXPORT_PRIVATE TlsClientConnection : public TlsConnection { // or ssl_verify_retry if verification is happening asynchronously. virtual enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) = 0; + // Called when a NewSessionTicket is received from the server. + virtual void InsertSession(bssl::UniquePtr<SSL_SESSION> session) = 0; + // Provides the delegate for callbacks that are shared between client and // server. virtual TlsConnection::Delegate* ConnectionDelegate() = 0; @@ -43,6 +46,10 @@ class QUIC_EXPORT_PRIVATE TlsClientConnection : public TlsConnection { // implementation is delegated to Delegate::VerifyCert. static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert); + // Registered as the callback for SSL_CTX_sess_set_new_cb, which calls + // Delegate::InsertSession. + static int NewSessionCallback(SSL* ssl, SSL_SESSION* session); + Delegate* delegate_; }; diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.h b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.h index 4774ba6924d..fd4f64b1978 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.h @@ -26,7 +26,7 @@ class QUIC_EXPORT_PRIVATE TlsConnection { public: // A TlsConnection::Delegate implements the methods that are set as callbacks // of TlsConnection. - class Delegate { + class QUIC_EXPORT_PRIVATE Delegate { public: virtual ~Delegate() {} diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.cc index 927c75af318..f539a089d2c 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.cc +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.cc @@ -16,6 +16,7 @@ bssl::UniquePtr<SSL_CTX> TlsServerConnection::CreateSslCtx() { SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(), &SelectCertificateCallback); SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), &SelectAlpnCallback, nullptr); + SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_NO_TICKET); return ssl_ctx; } diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h index 0e78d1bf015..96d71e2bef1 100644 --- a/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h +++ b/chromium/net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h @@ -15,7 +15,7 @@ class QUIC_EXPORT_PRIVATE TlsServerConnection : public TlsConnection { public: // A TlsServerConnection::Delegate implement the server-specific methods that // are set as callbacks for an SSL object. - class Delegate { + class QUIC_EXPORT_PRIVATE Delegate { public: virtual ~Delegate() {} 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 ce6cc2005c3..a870017b0b3 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 @@ -44,6 +44,8 @@ enum TransportParameters::TransportParameterId : uint16_t { kPreferredAddress = 0xd, kActiveConnectionIdLimit = 0xe, + kMaxDatagramFrameSize = 0x20, + kGoogleQuicParam = 18257, // Used for non-standard Google-specific params. kGoogleQuicVersion = 18258, // Used to transmit version and supported_versions. @@ -95,6 +97,8 @@ std::string TransportParameterIdToString( return "preferred_address"; case TransportParameters::kActiveConnectionIdLimit: return "active_connection_id_limit"; + case TransportParameters::kMaxDatagramFrameSize: + return "max_datagram_frame_size"; case TransportParameters::kGoogleQuicParam: return "google"; case TransportParameters::kGoogleQuicVersion: @@ -279,6 +283,7 @@ std::string TransportParameters::ToString() const { preferred_address->ToString(); } rv += active_connection_id_limit.ToString(/*for_use_in_list=*/true); + rv += max_datagram_frame_size.ToString(/*for_use_in_list=*/true); if (google_quic_params) { rv += " " + TransportParameterIdToString(kGoogleQuicParam); } @@ -313,7 +318,8 @@ TransportParameters::TransportParameters() 0, kMaxMaxAckDelayTransportParam), disable_migration(false), - active_connection_id_limit(kActiveConnectionIdLimit) + active_connection_id_limit(kActiveConnectionIdLimit), + max_datagram_frame_size(kMaxDatagramFrameSize) // Important note: any new transport parameters must be added // to TransportParameters::AreValid, SerializeTransportParameters and // ParseTransportParameters. @@ -354,15 +360,15 @@ bool TransportParameters::AreValid() const { QUIC_BUG << "Preferred address family failure"; return false; } - const bool ok = idle_timeout_milliseconds.IsValid() && - max_packet_size.IsValid() && initial_max_data.IsValid() && - initial_max_stream_data_bidi_local.IsValid() && - initial_max_stream_data_bidi_remote.IsValid() && - initial_max_stream_data_uni.IsValid() && - initial_max_streams_bidi.IsValid() && - initial_max_streams_uni.IsValid() && - ack_delay_exponent.IsValid() && max_ack_delay.IsValid() && - active_connection_id_limit.IsValid(); + const bool ok = + idle_timeout_milliseconds.IsValid() && max_packet_size.IsValid() && + initial_max_data.IsValid() && + initial_max_stream_data_bidi_local.IsValid() && + initial_max_stream_data_bidi_remote.IsValid() && + initial_max_stream_data_uni.IsValid() && + initial_max_streams_bidi.IsValid() && initial_max_streams_uni.IsValid() && + ack_delay_exponent.IsValid() && max_ack_delay.IsValid() && + active_connection_id_limit.IsValid() && max_datagram_frame_size.IsValid(); if (!ok) { QUIC_DLOG(ERROR) << "Invalid transport parameters " << *this; } @@ -445,7 +451,8 @@ bool SerializeTransportParameters(ParsedQuicVersion /*version*/, !in.initial_max_streams_uni.WriteToCbb(¶ms) || !in.ack_delay_exponent.WriteToCbb(¶ms) || !in.max_ack_delay.WriteToCbb(¶ms) || - !in.active_connection_id_limit.WriteToCbb(¶ms)) { + !in.active_connection_id_limit.WriteToCbb(¶ms) || + !in.max_datagram_frame_size.WriteToCbb(¶ms)) { QUIC_BUG << "Failed to write integers for " << in; return false; } @@ -734,6 +741,9 @@ bool ParseTransportParameters(ParsedQuicVersion version, case TransportParameters::kActiveConnectionIdLimit: parse_success = out->active_connection_id_limit.ReadFromCbs(&value); break; + case TransportParameters::kMaxDatagramFrameSize: + parse_success = out->max_datagram_frame_size.ReadFromCbs(&value); + break; case TransportParameters::kGoogleQuicParam: { if (out->google_quic_params) { QUIC_DLOG(ERROR) << "Received a second Google parameter"; 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 22dc252405c..c5ec1a4f71b 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 @@ -168,6 +168,10 @@ struct QUIC_EXPORT_PRIVATE TransportParameters { // to store. IntegerParameter active_connection_id_limit; + // Indicates support for the DATAGRAM frame and the maximum frame size that + // the sender accepts. See draft-pauly-quic-datagram. + IntegerParameter max_datagram_frame_size; + // Transport parameters used by Google QUIC but not IETF QUIC. This is // serialized into a TransportParameter struct with a TransportParameterId of // kGoogleQuicParamId. 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 90afe221bd7..61a6e0d4d6b 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 @@ -24,14 +24,10 @@ using testing::UnorderedElementsAre; const ParsedQuicVersion kVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99); const QuicVersionLabel kFakeVersionLabel = 0x01234567; const QuicVersionLabel kFakeVersionLabel2 = 0x89ABCDEF; -const QuicConnectionId kFakeOriginalConnectionId = TestConnectionId(0x1337); const uint64_t kFakeIdleTimeoutMilliseconds = 12012; const uint8_t kFakeStatelessResetTokenData[16] = { 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F}; -const std::vector<uint8_t> kFakeStatelessResetToken( - kFakeStatelessResetTokenData, - kFakeStatelessResetTokenData + sizeof(kFakeStatelessResetTokenData)); const uint64_t kFakeMaxPacketSize = 9001; const uint64_t kFakeInitialMaxData = 101; const uint64_t kFakeInitialMaxStreamDataBidiLocal = 2001; @@ -43,14 +39,10 @@ const uint64_t kFakeAckDelayExponent = 10; const uint64_t kFakeMaxAckDelay = 51; const bool kFakeDisableMigration = true; const uint64_t kFakeActiveConnectionIdLimit = 52; -const QuicConnectionId kFakePreferredConnectionId = TestConnectionId(0xBEEF); const uint8_t kFakePreferredStatelessResetTokenData[16] = { 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F}; -const std::vector<uint8_t> kFakePreferredStatelessResetToken( - kFakePreferredStatelessResetTokenData, - kFakePreferredStatelessResetTokenData + - sizeof(kFakeStatelessResetTokenData)); + const auto kCustomParameter1 = static_cast<TransportParameters::TransportParameterId>(0xffcd); const char* kCustomParameter1Value = "foo"; @@ -58,6 +50,27 @@ const auto kCustomParameter2 = static_cast<TransportParameters::TransportParameterId>(0xff34); const char* kCustomParameter2Value = "bar"; +QuicConnectionId CreateFakeOriginalConnectionId() { + return TestConnectionId(0x1337); +} + +QuicConnectionId CreateFakePreferredConnectionId() { + return TestConnectionId(0xBEEF); +} + +std::vector<uint8_t> CreateFakeStatelessResetToken() { + return std::vector<uint8_t>( + kFakeStatelessResetTokenData, + kFakeStatelessResetTokenData + sizeof(kFakeStatelessResetTokenData)); +} + +std::vector<uint8_t> CreateFakePreferredStatelessResetToken() { + return std::vector<uint8_t>( + kFakePreferredStatelessResetTokenData, + kFakePreferredStatelessResetTokenData + + sizeof(kFakePreferredStatelessResetTokenData)); +} + QuicSocketAddress CreateFakeV4SocketAddress() { QuicIpAddress ipv4_address; if (!ipv4_address.FromString("65.66.67.68")) { // 0x41, 0x42, 0x43, 0x44 @@ -81,8 +94,9 @@ CreateFakePreferredAddress() { TransportParameters::PreferredAddress preferred_address; preferred_address.ipv4_socket_address = CreateFakeV4SocketAddress(); preferred_address.ipv6_socket_address = CreateFakeV6SocketAddress(); - preferred_address.connection_id = kFakePreferredConnectionId; - preferred_address.stateless_reset_token = kFakePreferredStatelessResetToken; + preferred_address.connection_id = CreateFakePreferredConnectionId(); + preferred_address.stateless_reset_token = + CreateFakePreferredStatelessResetToken(); return std::make_unique<TransportParameters::PreferredAddress>( preferred_address); } @@ -158,9 +172,9 @@ TEST_F(TransportParametersTest, RoundTripServer) { orig_params.version = kFakeVersionLabel; orig_params.supported_versions.push_back(kFakeVersionLabel); orig_params.supported_versions.push_back(kFakeVersionLabel2); - orig_params.original_connection_id = kFakeOriginalConnectionId; + orig_params.original_connection_id = CreateFakeOriginalConnectionId(); orig_params.idle_timeout_milliseconds.set_value(kFakeIdleTimeoutMilliseconds); - orig_params.stateless_reset_token = kFakeStatelessResetToken; + orig_params.stateless_reset_token = CreateFakeStatelessResetToken(); orig_params.max_packet_size.set_value(kFakeMaxPacketSize); orig_params.initial_max_data.set_value(kFakeInitialMaxData); orig_params.initial_max_stream_data_bidi_local.set_value( @@ -191,10 +205,11 @@ TEST_F(TransportParametersTest, RoundTripServer) { EXPECT_EQ(2u, new_params.supported_versions.size()); EXPECT_EQ(kFakeVersionLabel, new_params.supported_versions[0]); EXPECT_EQ(kFakeVersionLabel2, new_params.supported_versions[1]); - EXPECT_EQ(kFakeOriginalConnectionId, new_params.original_connection_id); + EXPECT_EQ(CreateFakeOriginalConnectionId(), + new_params.original_connection_id); EXPECT_EQ(kFakeIdleTimeoutMilliseconds, new_params.idle_timeout_milliseconds.value()); - EXPECT_EQ(kFakeStatelessResetToken, new_params.stateless_reset_token); + EXPECT_EQ(CreateFakeStatelessResetToken(), new_params.stateless_reset_token); EXPECT_EQ(kFakeMaxPacketSize, new_params.max_packet_size.value()); EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value()); EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal, @@ -215,9 +230,9 @@ TEST_F(TransportParametersTest, RoundTripServer) { new_params.preferred_address->ipv4_socket_address); EXPECT_EQ(CreateFakeV6SocketAddress(), new_params.preferred_address->ipv6_socket_address); - EXPECT_EQ(kFakePreferredConnectionId, + EXPECT_EQ(CreateFakePreferredConnectionId(), new_params.preferred_address->connection_id); - EXPECT_EQ(kFakePreferredStatelessResetToken, + EXPECT_EQ(CreateFakePreferredStatelessResetToken(), new_params.preferred_address->stateless_reset_token); EXPECT_EQ(kFakeActiveConnectionIdLimit, new_params.active_connection_id_limit.value()); @@ -272,7 +287,7 @@ TEST_F(TransportParametersTest, NoClientParamsWithStatelessResetToken) { orig_params.perspective = Perspective::IS_CLIENT; orig_params.version = kFakeVersionLabel; orig_params.idle_timeout_milliseconds.set_value(kFakeIdleTimeoutMilliseconds); - orig_params.stateless_reset_token = kFakeStatelessResetToken; + orig_params.stateless_reset_token = CreateFakeStatelessResetToken(); orig_params.max_packet_size.set_value(kFakeMaxPacketSize); std::vector<uint8_t> out; @@ -543,10 +558,11 @@ TEST_F(TransportParametersTest, ParseServerParams) { EXPECT_EQ(2u, new_params.supported_versions.size()); EXPECT_EQ(kFakeVersionLabel, new_params.supported_versions[0]); EXPECT_EQ(kFakeVersionLabel2, new_params.supported_versions[1]); - EXPECT_EQ(kFakeOriginalConnectionId, new_params.original_connection_id); + EXPECT_EQ(CreateFakeOriginalConnectionId(), + new_params.original_connection_id); EXPECT_EQ(kFakeIdleTimeoutMilliseconds, new_params.idle_timeout_milliseconds.value()); - EXPECT_EQ(kFakeStatelessResetToken, new_params.stateless_reset_token); + EXPECT_EQ(CreateFakeStatelessResetToken(), new_params.stateless_reset_token); EXPECT_EQ(kFakeMaxPacketSize, new_params.max_packet_size.value()); EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value()); EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal, @@ -567,9 +583,9 @@ TEST_F(TransportParametersTest, ParseServerParams) { new_params.preferred_address->ipv4_socket_address); EXPECT_EQ(CreateFakeV6SocketAddress(), new_params.preferred_address->ipv6_socket_address); - EXPECT_EQ(kFakePreferredConnectionId, + EXPECT_EQ(CreateFakePreferredConnectionId(), new_params.preferred_address->connection_id); - EXPECT_EQ(kFakePreferredStatelessResetToken, + EXPECT_EQ(CreateFakePreferredStatelessResetToken(), new_params.preferred_address->stateless_reset_token); EXPECT_EQ(kFakeActiveConnectionIdLimit, new_params.active_connection_id_limit.value()); |