From 30c6bedc4d90b3cb03bf34f4730d7677b819a32d Mon Sep 17 00:00:00 2001 From: 0x676e67 Date: Sun, 2 Feb 2025 19:29:29 +0800 Subject: [PATCH] feat: Add ALPS use new endpoint (#39) --- ...df6f03d85c901767250329c571db405122d5.patch | 293 ++++++++++++++++-- boring/src/ssl/mod.rs | 8 +- 2 files changed, 280 insertions(+), 21 deletions(-) diff --git a/boring-sys/patches/boringssl-44b3df6f03d85c901767250329c571db405122d5.patch b/boring-sys/patches/boringssl-44b3df6f03d85c901767250329c571db405122d5.patch index e2fa92f6..116f16e4 100644 --- a/boring-sys/patches/boringssl-44b3df6f03d85c901767250329c571db405122d5.patch +++ b/boring-sys/patches/boringssl-44b3df6f03d85c901767250329c571db405122d5.patch @@ -4270,7 +4270,7 @@ index 4dd8841b1..23ffcd446 100644 #if defined(__cplusplus) } /* extern C */ diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h -index 53aa9b453..eebfb7c8a 100644 +index 53aa9b453..1e93efda3 100644 --- a/src/include/openssl/ssl.h +++ b/src/include/openssl/ssl.h @@ -718,6 +718,12 @@ OPENSSL_EXPORT int SSL_version(const SSL *ssl); @@ -4300,7 +4300,17 @@ index 53aa9b453..eebfb7c8a 100644 // SSL_get_curve_id returns the ID of the curve used by |ssl|'s most recently // completed handshake or 0 if not applicable. -@@ -4570,6 +4583,27 @@ OPENSSL_EXPORT void SSL_CTX_set_permute_extensions(SSL_CTX *ctx, int enabled); +@@ -3022,6 +3035,9 @@ OPENSSL_EXPORT void SSL_get0_peer_application_settings(const SSL *ssl, + // connection and zero otherwise. + OPENSSL_EXPORT int SSL_has_application_settings(const SSL *ssl); + ++// SSL_set_alps_use_new_codepoint configures whether to use the new ALPS ++// codepoint. By default, the old codepoint is used. ++OPENSSL_EXPORT void SSL_set_alps_use_new_codepoint(SSL *ssl, int use_new); + + // Certificate compression. + // +@@ -4570,6 +4586,27 @@ OPENSSL_EXPORT void SSL_CTX_set_permute_extensions(SSL_CTX *ctx, int enabled); // permute extensions. For now, this is only implemented for the ClientHello. OPENSSL_EXPORT void SSL_set_permute_extensions(SSL *ssl, int enabled); @@ -4328,7 +4338,7 @@ index 53aa9b453..eebfb7c8a 100644 // SSL_max_seal_overhead returns the maximum overhead, in bytes, of sealing a // record with |ssl|. OPENSSL_EXPORT size_t SSL_max_seal_overhead(const SSL *ssl); -@@ -4874,6 +4908,10 @@ OPENSSL_EXPORT int SSL_CTX_set1_sigalgs_list(SSL_CTX *ctx, const char *str); +@@ -4874,6 +4911,10 @@ OPENSSL_EXPORT int SSL_CTX_set1_sigalgs_list(SSL_CTX *ctx, const char *str); // more convenient to codesearch for specific algorithm values. OPENSSL_EXPORT int SSL_set1_sigalgs_list(SSL *ssl, const char *str); @@ -4339,7 +4349,7 @@ index 53aa9b453..eebfb7c8a 100644 #define SSL_set_app_data(s, arg) (SSL_set_ex_data(s, 0, (char *)(arg))) #define SSL_get_app_data(s) (SSL_get_ex_data(s, 0)) #define SSL_SESSION_set_app_data(s, a) \ -@@ -4926,7 +4964,6 @@ DEFINE_STACK_OF(SSL_COMP) +@@ -4926,7 +4967,6 @@ DEFINE_STACK_OF(SSL_COMP) #define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0 #define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0 #define SSL_OP_NO_COMPRESSION 0 @@ -4348,7 +4358,7 @@ index 53aa9b453..eebfb7c8a 100644 #define SSL_OP_NO_SSLv2 0 #define SSL_OP_NO_SSLv3 0 diff --git a/src/include/openssl/tls1.h b/src/include/openssl/tls1.h -index 772fb87a3..511793068 100644 +index 772fb87a3..955126a7a 100644 --- a/src/include/openssl/tls1.h +++ b/src/include/openssl/tls1.h @@ -181,6 +181,8 @@ extern "C" { @@ -4360,7 +4370,15 @@ index 772fb87a3..511793068 100644 // ExtensionType values from RFC 6066 #define TLSEXT_TYPE_server_name 0 #define TLSEXT_TYPE_status_request 5 -@@ -286,6 +288,7 @@ extern "C" { +@@ -245,6 +247,7 @@ extern "C" { + // ExtensionType value from draft-vvv-tls-alps. This is not an IANA defined + // extension number. + #define TLSEXT_TYPE_application_settings 17513 ++#define TLSEXT_TYPE_application_settings_new 17613 + + // ExtensionType values from draft-ietf-tls-esni-13. This is not an IANA defined + // extension number. +@@ -286,6 +289,7 @@ extern "C" { // From https://www.rfc-editor.org/rfc/rfc8879.html#section-3 #define TLSEXT_cert_compression_zlib 1 #define TLSEXT_cert_compression_brotli 2 @@ -4382,7 +4400,7 @@ index 5c7e881bf..3c0770cf3 100644 crypto/pkcs8/test/no_encryption.p12 crypto/pkcs8/test/nss.p12 diff --git a/src/ssl/extensions.cc b/src/ssl/extensions.cc -index 5ee280221..3eba40c13 100644 +index 5ee280221..b42f332a1 100644 --- a/src/ssl/extensions.cc +++ b/src/ssl/extensions.cc @@ -207,6 +207,10 @@ static bool tls1_check_duplicate_extensions(const CBS *cbs) { @@ -4512,7 +4530,134 @@ index 5ee280221..3eba40c13 100644 static bool ext_delegated_credential_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents) { -@@ -3094,6 +3142,39 @@ bool ssl_negotiate_alps(SSL_HANDSHAKE *hs, uint8_t *out_alert, +@@ -2957,9 +3005,10 @@ bool ssl_get_local_application_settings(const SSL_HANDSHAKE *hs, + return false; + } + +-static bool ext_alps_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, +- CBB *out_compressible, +- ssl_client_hello_type_t type) { ++static bool ext_alps_add_clienthello_impl(const SSL_HANDSHAKE *hs, CBB *out, ++ CBB *out_compressible, ++ ssl_client_hello_type_t type, ++ bool use_new_codepoint) { + const SSL *const ssl = hs->ssl; + if (// ALPS requires TLS 1.3. + hs->max_version < TLS1_3_VERSION || +@@ -2972,8 +3021,18 @@ static bool ext_alps_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + return true; + } + ++ if (use_new_codepoint != hs->config->alps_use_new_codepoint) { ++ // Do nothing, we'll send the other codepoint. ++ return true; ++ } ++ ++ uint16_t extension_type = TLSEXT_TYPE_application_settings; ++ if (hs->config->alps_use_new_codepoint) { ++ extension_type = TLSEXT_TYPE_application_settings_new; ++ } ++ + CBB contents, proto_list, proto; +- if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_application_settings) || ++ if (!CBB_add_u16(out_compressible, extension_type) || + !CBB_add_u16_length_prefixed(out_compressible, &contents) || + !CBB_add_u16_length_prefixed(&contents, &proto_list)) { + return false; +@@ -2990,8 +3049,24 @@ static bool ext_alps_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, + return CBB_flush(out_compressible); + } + +-static bool ext_alps_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, +- CBS *contents) { ++static bool ext_alps_add_clienthello_new(const SSL_HANDSHAKE *hs, CBB *out, ++ CBB *out_compressible, ++ ssl_client_hello_type_t type) { ++ return ext_alps_add_clienthello_impl(hs, out, out_compressible, type, ++ /*use_new_codepoint=*/true); ++} ++ ++static bool ext_alps_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, ++ CBB *out_compressible, ++ ssl_client_hello_type_t type) { ++ return ext_alps_add_clienthello_impl(hs, out, out_compressible, type, ++ /*use_new_codepoint=*/false); ++} ++ ++static bool ext_alps_parse_serverhello_impl(SSL_HANDSHAKE *hs, ++ uint8_t *out_alert, ++ CBS *contents, ++ bool use_new_codepoint) { + SSL *const ssl = hs->ssl; + if (contents == nullptr) { + return true; +@@ -3000,6 +3075,7 @@ static bool ext_alps_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + assert(!ssl->s3->initial_handshake_complete); + assert(!hs->config->alpn_client_proto_list.empty()); + assert(!hs->config->alps_configs.empty()); ++ assert(use_new_codepoint == hs->config->alps_use_new_codepoint); + + // ALPS requires TLS 1.3. + if (ssl_protocol_version(ssl) < TLS1_3_VERSION) { +@@ -3019,7 +3095,21 @@ static bool ext_alps_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + return true; + } + +-static bool ext_alps_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { ++static bool ext_alps_parse_serverhello_new(SSL_HANDSHAKE *hs, ++ uint8_t *out_alert, ++ CBS *contents) { ++ return ext_alps_parse_serverhello_impl(hs, out_alert, contents, ++ /*use_new_codepoint=*/true); ++} ++ ++static bool ext_alps_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, ++ CBS *contents) { ++ return ext_alps_parse_serverhello_impl(hs, out_alert, contents, ++ /*use_new_codepoint=*/false); ++} ++ ++static bool ext_alps_add_serverhello_impl(SSL_HANDSHAKE *hs, CBB *out, ++ bool use_new_codepoint) { + SSL *const ssl = hs->ssl; + // If early data is accepted, we omit the ALPS extension. It is implicitly + // carried over from the previous connection. +@@ -3029,8 +3119,18 @@ static bool ext_alps_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + return true; + } + ++ if (use_new_codepoint != hs->config->alps_use_new_codepoint) { ++ // Do nothing, we'll send the other codepoint. ++ return true; ++ } ++ ++ uint16_t extension_type = TLSEXT_TYPE_application_settings; ++ if (hs->config->alps_use_new_codepoint) { ++ extension_type = TLSEXT_TYPE_application_settings_new; ++ } ++ + CBB contents; +- if (!CBB_add_u16(out, TLSEXT_TYPE_application_settings) || ++ if (!CBB_add_u16(out, extension_type) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_bytes(&contents, + hs->new_session->local_application_settings.data(), +@@ -3042,6 +3142,14 @@ static bool ext_alps_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + return true; + } + ++static bool ext_alps_add_serverhello_new(SSL_HANDSHAKE *hs, CBB *out) { ++ return ext_alps_add_serverhello_impl(hs, out, /*use_new_codepoint=*/true); ++} ++ ++static bool ext_alps_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { ++ return ext_alps_add_serverhello_impl(hs, out, /*use_new_codepoint=*/false); ++} ++ + bool ssl_negotiate_alps(SSL_HANDSHAKE *hs, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; +@@ -3094,6 +3202,39 @@ bool ssl_negotiate_alps(SSL_HANDSHAKE *hs, uint8_t *out_alert, return true; } @@ -4552,11 +4697,19 @@ index 5ee280221..3eba40c13 100644 // kExtensions contains all the supported extensions. static const struct tls_extension kExtensions[] = { { -@@ -3267,6 +3348,13 @@ static const struct tls_extension kExtensions[] = { +@@ -3267,6 +3408,21 @@ static const struct tls_extension kExtensions[] = { ignore_parse_clienthello, ext_alps_add_serverhello, }, + { ++ TLSEXT_TYPE_application_settings_new, ++ ext_alps_add_clienthello_new, ++ ext_alps_parse_serverhello_new, ++ // ALPS is negotiated late in |ssl_negotiate_alpn|. ++ ignore_parse_clienthello, ++ ext_alps_add_serverhello_new, ++ }, ++ { + TLSEXT_TYPE_record_size_limit, + record_size_limit_add_clienthello, + record_size_limit_parse_serverhello, @@ -4566,7 +4719,7 @@ index 5ee280221..3eba40c13 100644 }; #define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension)) -@@ -3280,6 +3368,12 @@ static_assert(kNumExtensions <= +@@ -3280,6 +3436,12 @@ static_assert(kNumExtensions <= bool ssl_setup_extension_permutation(SSL_HANDSHAKE *hs) { if (!hs->config->permute_extensions) { @@ -4579,7 +4732,7 @@ index 5ee280221..3eba40c13 100644 return true; } -@@ -3357,10 +3451,16 @@ static bool ssl_add_clienthello_tlsext_inner(SSL_HANDSHAKE *hs, CBB *out, +@@ -3357,10 +3519,16 @@ static bool ssl_add_clienthello_tlsext_inner(SSL_HANDSHAKE *hs, CBB *out, } } @@ -4597,7 +4750,7 @@ index 5ee280221..3eba40c13 100644 const size_t len_before = CBB_len(&extensions); const size_t len_compressed_before = CBB_len(compressed.get()); if (!kExtensions[i].add_clienthello(hs, &extensions, compressed.get(), -@@ -3466,10 +3566,16 @@ bool ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, CBB *out_encoded, +@@ -3466,10 +3634,16 @@ bool ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, CBB *out_encoded, } bool last_was_empty = false; @@ -4615,6 +4768,90 @@ index 5ee280221..3eba40c13 100644 const size_t len_before = CBB_len(&extensions); if (!kExtensions[i].add_clienthello(hs, &extensions, &extensions, type)) { OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION); +diff --git a/src/ssl/handoff.cc b/src/ssl/handoff.cc +index 6e5cc2da1..6cd3ca430 100644 +--- a/src/ssl/handoff.cc ++++ b/src/ssl/handoff.cc +@@ -169,46 +169,46 @@ static bool apply_remote_features(SSL *ssl, CBS *in) { + return false; + } + +- CBS curves; +- if (!CBS_get_asn1(in, &curves, CBS_ASN1_OCTETSTRING)) { ++ CBS groups; ++ if (!CBS_get_asn1(in, &groups, CBS_ASN1_OCTETSTRING)) { + return false; + } +- Array supported_curves; +- if (!supported_curves.Init(CBS_len(&curves) / 2)) { ++ Array supported_groups; ++ if (!supported_groups.Init(CBS_len(&groups) / 2)) { + return false; + } + size_t idx = 0; +- while (CBS_len(&curves)) { +- uint16_t curve; +- if (!CBS_get_u16(&curves, &curve)) { ++ while (CBS_len(&groups)) { ++ uint16_t group; ++ if (!CBS_get_u16(&groups, &group)) { + return false; + } +- supported_curves[idx++] = curve; ++ supported_groups[idx++] = group; + } +- Span configured_curves = ++ Span configured_groups = + tls1_get_grouplist(ssl->s3->hs.get()); +- Array new_configured_curves; +- if (!new_configured_curves.Init(configured_curves.size())) { ++ Array new_configured_groups; ++ if (!new_configured_groups.Init(configured_groups.size())) { + return false; + } + idx = 0; +- for (uint16_t configured_curve : configured_curves) { ++ for (uint16_t configured_group : configured_groups) { + bool ok = false; +- for (uint16_t supported_curve : supported_curves) { +- if (supported_curve == configured_curve) { ++ for (uint16_t supported_group : supported_groups) { ++ if (supported_group == configured_group) { + ok = true; + break; + } + } + if (ok) { +- new_configured_curves[idx++] = configured_curve; ++ new_configured_groups[idx++] = configured_group; + } + } + if (idx == 0) { + return false; + } +- new_configured_curves.Shrink(idx); +- ssl->config->supported_group_list = std::move(new_configured_curves); ++ new_configured_groups.Shrink(idx); ++ ssl->config->supported_group_list = std::move(new_configured_groups); + + CBS alps; + CBS_init(&alps, nullptr, 0); +@@ -222,9 +222,12 @@ static bool apply_remote_features(SSL *ssl, CBS *in) { + if (!CBS_get_u16(&alps, &id)) { + return false; + } +- // For now, we only support one ALPS code point, so we only need to extract +- // a boolean signal from the feature list. +- if (id == TLSEXT_TYPE_application_settings) { ++ // For now, we support two ALPS codepoints, so we need to extract both ++ // codepoints, and then filter what the handshaker might try to send. ++ if ((id == TLSEXT_TYPE_application_settings_new && ++ ssl->config->alps_use_new_codepoint) || ++ (id == TLSEXT_TYPE_application_settings && ++ !ssl->config->alps_use_new_codepoint)) { + supports_alps = true; + break; + } diff --git a/src/ssl/handshake_client.cc b/src/ssl/handshake_client.cc index 971ebd0b1..348fb93dc 100644 --- a/src/ssl/handshake_client.cc @@ -4788,7 +5025,7 @@ index 971ebd0b1..348fb93dc 100644 CBB child; if (!CBB_add_u8_length_prefixed(&body, &child)) { diff --git a/src/ssl/internal.h b/src/ssl/internal.h -index 1e6da2153..f3150a114 100644 +index 1e6da2153..2a342d768 100644 --- a/src/ssl/internal.h +++ b/src/ssl/internal.h @@ -323,6 +323,19 @@ class Array { @@ -4899,11 +5136,15 @@ index 1e6da2153..f3150a114 100644 // srtp_profiles is the list of configured SRTP protection profiles for // DTLS-SRTP. -@@ -3128,6 +3175,12 @@ struct SSL_CONFIG { +@@ -3128,6 +3175,16 @@ struct SSL_CONFIG { // of support for AES hw. The value is only considered if |aes_hw_override| is // true. bool aes_hw_override_value : 1; + ++ // alps_use_new_codepoint if set indicates we use new ALPS extension codepoint ++ // to negotiate and convey application settings. ++ bool alps_use_new_codepoint : 1; ++ + // record_size_limit is whether to send record size limit extension. + uint16_t record_size_limit = 0; + @@ -4912,7 +5153,7 @@ index 1e6da2153..f3150a114 100644 }; // From RFC 8446, used in determining PSK modes. -@@ -3696,6 +3749,10 @@ struct ssl_ctx_st { +@@ -3696,6 +3753,10 @@ struct ssl_ctx_st { // accepted from the peer in decreasing order of preference. bssl::Array verify_sigalgs; @@ -4923,7 +5164,7 @@ index 1e6da2153..f3150a114 100644 // retain_only_sha256_of_client_certs is true if we should compute the SHA256 // hash of the peer's certificate and then discard it to save memory and // session space. Only effective on the server side. -@@ -3748,6 +3805,15 @@ struct ssl_ctx_st { +@@ -3748,6 +3809,15 @@ struct ssl_ctx_st { // |aes_hw_override| is true. bool aes_hw_override_value : 1; @@ -5963,7 +6204,7 @@ index 09a9ad380..9c583b5ec 100644 return nullptr; } diff --git a/src/ssl/ssl_lib.cc b/src/ssl/ssl_lib.cc -index 838761af5..93447106f 100644 +index 838761af5..9c4a340d0 100644 --- a/src/ssl/ssl_lib.cc +++ b/src/ssl/ssl_lib.cc @@ -537,7 +537,8 @@ ssl_ctx_st::ssl_ctx_st(const SSL_METHOD *ssl_method) @@ -6038,7 +6279,21 @@ index 838761af5..93447106f 100644 void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out, size_t *out_len) { SSL_SESSION *session = SSL_get_session(ssl); -@@ -2939,6 +2966,24 @@ void SSL_set_permute_extensions(SSL *ssl, int enabled) { +@@ -2327,6 +2354,13 @@ int SSL_has_application_settings(const SSL *ssl) { + return session && session->has_application_settings; + } + ++void SSL_set_alps_use_new_codepoint(SSL *ssl, int use_new) { ++ if (!ssl->config) { ++ return; ++ } ++ ssl->config->alps_use_new_codepoint = !!use_new; ++} ++ + int SSL_CTX_add_cert_compression_alg(SSL_CTX *ctx, uint16_t alg_id, + ssl_cert_compression_func_t compress, + ssl_cert_decompression_func_t decompress) { +@@ -2939,6 +2973,24 @@ void SSL_set_permute_extensions(SSL *ssl, int enabled) { ssl->config->permute_extensions = !!enabled; } @@ -6063,7 +6318,7 @@ index 838761af5..93447106f 100644 int32_t SSL_get_ticket_age_skew(const SSL *ssl) { return ssl->s3->ticket_age_skew; } -@@ -3151,7 +3196,7 @@ namespace fips202205 { +@@ -3151,7 +3203,7 @@ namespace fips202205 { // Section 3.3.1 // "The server shall be configured to only use cipher suites that are // composed entirely of NIST approved algorithms" diff --git a/boring/src/ssl/mod.rs b/boring/src/ssl/mod.rs index 3ab6b324..c68a58d7 100644 --- a/boring/src/ssl/mod.rs +++ b/boring/src/ssl/mod.rs @@ -568,6 +568,8 @@ impl ExtensionType { pub const RENEGOTIATE: Self = Self(ffi::TLSEXT_TYPE_renegotiate as u16); pub const DELEGATED_CREDENTIAL: Self = Self(ffi::TLSEXT_TYPE_delegated_credential as u16); pub const APPLICATION_SETTINGS: Self = Self(ffi::TLSEXT_TYPE_application_settings as u16); + pub const APPLICATION_SETTINGS_NEW: Self = + Self(ffi::TLSEXT_TYPE_application_settings_new as u16); pub const ENCRYPTED_CLIENT_HELLO: Self = Self(ffi::TLSEXT_TYPE_encrypted_client_hello as u16); pub const CERTIFICATE_TIMESTAMP: Self = Self(ffi::TLSEXT_TYPE_certificate_timestamp as u16); pub const NEXT_PROTO_NEG: Self = Self(ffi::TLSEXT_TYPE_next_proto_neg as u16); @@ -575,7 +577,7 @@ impl ExtensionType { pub const RECORD_SIZE_LIMIT: Self = Self(ffi::TLSEXT_TYPE_record_size_limit as u16); /// The permutation of extension types used by BoringSSL. - pub const BORING_SSLEXTENSION_PERMUTATION: [ExtensionType; 25] = [ + pub const BORING_SSLEXTENSION_PERMUTATION: &[ExtensionType] = &[ ExtensionType::SERVER_NAME, ExtensionType::ENCRYPTED_CLIENT_HELLO, ExtensionType::EXTENDED_MASTER_SECRET, @@ -600,6 +602,7 @@ impl ExtensionType { ExtensionType::CERT_COMPRESSION, ExtensionType::DELEGATED_CREDENTIAL, ExtensionType::APPLICATION_SETTINGS, + ExtensionType::APPLICATION_SETTINGS_NEW, ExtensionType::RECORD_SIZE_LIMIT, ]; @@ -630,7 +633,8 @@ impl ExtensionType { ExtensionType::CERT_COMPRESSION => Some(21), ExtensionType::DELEGATED_CREDENTIAL => Some(22), ExtensionType::APPLICATION_SETTINGS => Some(23), - ExtensionType::RECORD_SIZE_LIMIT => Some(24), + ExtensionType::APPLICATION_SETTINGS_NEW => Some(24), + ExtensionType::RECORD_SIZE_LIMIT => Some(25), _ => None, } }