Internet-Draft Extended Extensions in TLS 1.3 July 2026
Smyslov Expires 7 January 2027 [Page]
Workgroup:
Network Working Group
Internet-Draft:
draft-smyslov-tls-ext-ext-00
Published:
Intended Status:
Informational
Expires:
Author:
V. Smyslov
ELVIS-PLUS

Extending Limit on Extensions Size in TLS 1.3

Abstract

Protocol TLS 1.3 is widely used to protect traffic in the Internet. However, the format of the TLS 1.3 ClientHello, ServerHello, and EncryptedExtensions handshake messages limits the size of extensions to 64 Kbytes.

This specification extends TLS 1.3 to allow extensions in ClientHello, ServerHello, and EncryptedExtensions have size larget than 64 Kbytes.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 7 January 2027.

Table of Contents

1. Introduction

TLS 1.3 [RFC8446] was standardized in 2018 and since then has become a widely used security protocol for protecting Internet traffic.

During TLS 1.3 handshake the client first sends the ClientHello message and the server responds with the ServerHello message followed by the EncryptedExtensions message ([RFC8446], Section 2). These messages contain various data needed to establish security connection, e.g., key shares for ephemeral key exchange. The ClientHello and ServerHello messages have few mandatory fields followed by the optional extensions ([RFC8446], Sections 4.1.2 and 4.1.3) and the EncryptedExtensions message contains only optional extensions ([RFC8446], Sections 4.3.1). Which extensions are included is situation-dependant, so whether a particular extension is sent or not depends on the protocol variant.

While the size of TLS 1.3 handshake messages can be up to 2^24 -1 bytes, the total size of extensions is limited to 2^16 - 1 bytes. This makes it impossible to use TLS 1.3 if the data needed to be transferred in an extension exceeds this limitation. One of possible example of such situation is using postquantum KEMS with large public keys or ciphertexts (like Classic MCEliece [I-D.josefsson-mceliece]).

This specification extends TLS 1.3 in to allow transferring extension data larget than 64 Kbytes.

Due to increased message size and additional round trip, this extension, when used, will lead to longer TLS handshake that might not be appropriate for some use cases, like interactive web surfing. For this reason, it is mostly aimed for long-lived TLS connections, when the longer handshake is amortized by the longevity of the connection.

2. Requirements Notation

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

It is assumed that readers are familiar with TLS 1.3 [RFC8446].

3. Protocol Overview

This document introduces a variable-size length encoding of extensions blocks and individual extensions, as well as the content of each extension that contains data limited to 2^16 bytes. The idea is inspired by QUIC [RFC9000] and MLS [RFC9420].

Unlike encodings in QUIC and MLS, this document allocates only one most significant bit to indicate what is the size of the length field, so that the length field occupies either 2 or 3 bytes. There is no need to have TLS extensions larger than 2^24, since this is the hard limit on the size of the TLS messages. The encoding is summarized in Table 1.

Table 1: Length Encoding
MSB Length Usable Bits Range
0 2 15 0-32767
1 3 23 0-8388607

As in QUIC, there is no requirement that length is encoded on the minimum number of bytes.

When this specification is in use by TLS 1.3 endpoints, the encoding of extensions blocks and individual extensions, as well as the content of any extension inside the handshake messages that contain the "extensions" field is modified as shown in Appendix A, where the variable-size length encoding is defined as <V>.

3.1. Use of Extended Extensions

If there is a need for a client to send TLS extension that do not fit into the existing TLS 1.3 handshake messages extensions block in ClienHello (e.g. in case PQ KEM with large public keys, like Classic NcEliece) then the client indicates this with new extension of type extended_extensions (Figure 1) in the ClientHello message. This extension contains no data.

        enum {
                ...
                extended_extensions(TBD),
                (65535)
            } ExtensionType;
Figure 1

If the server supports this extension, it replies with the HelloRetryRequest that also includes the extended_extensions extension.

Once HelloRetryRequest has been received, the client repeats ClienHello re-formatting it in such a way, that the extensions block with the variable-size length encoding as per Appendix A. Note that unless the extension exceeds 32767 bytes in size, no changes of the bits on the wire occured with new encoding.

The server then responds with ServerHello that also includes the extensions block encoded in accordance with Appendix A.

            Client                                               Server

            ClientHello
            + key_share
            + extended_extensions  -------->
                                                      HelloRetryRequest
                                                            + key_share
                                   <--------      + extended_extensions
            <ClientHello>
            + key_share
            + extended_extensions  -------->
                                                          <ServerHello>
                                                            + key_share
                                                  + extended_extensions
                                                      AuxHandshakeData*
                                                {<EncryptedExtensions>}
                                                  {CertificateRequest*}
                                                       {<Certificate>*}
                                                   {CertificateVerify*}
                                                             {Finished}
                                    <--------       [Application Data*]
            {<Certificate>*}
            {CertificateVerify*}
            {Finished}              -------->
            [Application Data]      <------->        [Application Data]


            <> Indicates messages that contain extension
               blocks encoded with variable-size length encoding.

Figure 2: Message Flow

Note that once the extended extensions are negotiated, all susequent TLS handshake messages for this TLS session that include the extensions blocks MUST use the variable-size length encodings for them.

4. IANA Considerations

IANA is requested to assign a new value from the TLS ExtensionType Values registry:

        *  The Extension Name should be extended_extensions

        *  The TLS 1.3 value should be CH,SH,HRR

        *  The DTLS-Only value should be N

        *  The Recommended value should be Y

5. Security Considerations

The extended extensions mechanism defined in this document only affects the encoding of TLS 1.3 messages. It does not change security properties of TLS 1.3 defined in [RFC8446].

6. References

6.1. Normative References

[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8446]
Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, , <https://www.rfc-editor.org/info/rfc8446>.

6.2. Informative References

[I-D.josefsson-mceliece]
Josefsson, S., "Classic McEliece", Work in Progress, Internet-Draft, draft-josefsson-mceliece-05, , <https://datatracker.ietf.org/doc/html/draft-josefsson-mceliece-05>.
[RFC9000]
Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based Multiplexed and Secure Transport", RFC 9000, DOI 10.17487/RFC9000, , <https://www.rfc-editor.org/info/rfc9000>.
[RFC9420]
Barnes, R., Beurdouche, B., Robert, R., Millican, J., Omara, E., and K. Cohn-Gordon, "The Messaging Layer Security (MLS) Protocol", RFC 9420, DOI 10.17487/RFC9420, , <https://www.rfc-editor.org/info/rfc9420>.

Appendix A. Extended Extensions

This appendix contains an excerpt from Appendix B.3 of [RFC8446], with the changes in encoding that this specification defines. The numeration of subsections from [RFC8446] is preserved and for convenience numbers are quoted.


"B.3.1."  Key Exchange Messages

    uint16 ProtocolVersion;
    opaque Random[32];

    uint8 CipherSuite[2];    /* Cryptographic suite selector */

    struct {
        ProtocolVersion legacy_version = 0x0303;    /* TLS v1.2 */
        Random random;
        opaque legacy_session_id<0..32>;
        CipherSuite cipher_suites<2..2^16-2>;
        opaque legacy_compression_methods<1..2^8-1>;
        Extension extensions<V>;                    /* 8..2^23-1 */
    } ClientHello;

    struct {
        ProtocolVersion legacy_version = 0x0303;    /* TLS v1.2 */
        Random random;
        opaque legacy_session_id_echo<0..32>;
        CipherSuite cipher_suite;
        uint8 legacy_compression_method = 0;
        Extension extensions<V>;                    /* 6..2^23-1 */
    } ServerHello;

    struct {
        ExtensionType extension_type;
        opaque extension_data<V>;                   /* 0..2^23-1 */
    } Extension;

    enum {
        server_name(0),                             /* RFC 6066 */
        max_fragment_length(1),                     /* RFC 6066 */
        status_request(5),                          /* RFC 6066 */
        supported_groups(10),                       /* RFC 8422, 7919 */
        signature_algorithms(13),                   /* RFC 8446 */
        use_srtp(14),                               /* RFC 5764 */
        heartbeat(15),                              /* RFC 6520 */
        application_layer_protocol_negotiation(16), /* RFC 7301 */
        signed_certificate_timestamp(18),           /* RFC 6962 */
        client_certificate_type(19),                /* RFC 7250 */
        server_certificate_type(20),                /* RFC 7250 */
        padding(21),                                /* RFC 7685 */
        RESERVED(40),                               /* Used but never
                                                       assigned */
        pre_shared_key(41),                         /* RFC 8446 */
        early_data(42),                             /* RFC 8446 */
        supported_versions(43),                     /* RFC 8446 */
        cookie(44),                                 /* RFC 8446 */
        psk_key_exchange_modes(45),                 /* RFC 8446 */
        RESERVED(46),                               /* Used but never
                                                       assigned */
        certificate_authorities(47),                /* RFC 8446 */
        oid_filters(48),                            /* RFC 8446 */
        post_handshake_auth(49),                    /* RFC 8446 */
        signature_algorithms_cert(50),              /* RFC 8446 */
        key_share(51),                              /* RFC 8446 */
        (65535)
    } ExtensionType;

    struct {
        NamedGroup group;
        opaque key_exchange<V>;                     /* 1..2^23-1 */
    } KeyShareEntry;

    struct {
        KeyShareEntry client_shares<V>;             /* 0..2^23-1 */
    } KeyShareClientHello;

    struct {
        NamedGroup selected_group;
    } KeyShareHelloRetryRequest;

    struct {
        KeyShareEntry server_share;
    } KeyShareServerHello;

    struct {
        uint8 legacy_form = 4;
        opaque X[coordinate_length];
        opaque Y[coordinate_length];
    } UncompressedPointRepresentation;

    enum { psk_ke(0), psk_dhe_ke(1), (255) } PskKeyExchangeMode;

    struct {
        PskKeyExchangeMode ke_modes<1..255>;
    } PskKeyExchangeModes;

    struct {} Empty;

    struct {
        select (Handshake.msg_type) {
            case new_session_ticket:   uint32 max_early_data_size;
            case client_hello:         Empty;
            case encrypted_extensions: Empty;
        };
    } EarlyDataIndication;

    struct {
        opaque identity<V>;                         /* 1..2^23-1 */
        uint32 obfuscated_ticket_age;
    } PskIdentity;

    opaque PskBinderEntry<32..255>;

    struct {
        PskIdentity identities<V>;                  /* 7..2^23-1 */
        PskBinderEntry binders<V>;                  /* 33..2^23-1 */
    } OfferedPsks;

    struct {
        select (Handshake.msg_type) {
            case client_hello: OfferedPsks;
            case server_hello: uint16 selected_identity;
        };
    } PreSharedKeyExtension;

"B.3.1.1."  Version Extension

      struct {
          select (Handshake.msg_type) {
              case client_hello:
                   ProtocolVersion versions<2..254>;

              case server_hello: /* and HelloRetryRequest */
                   ProtocolVersion selected_version;
          };
      } SupportedVersions;

"B.3.1.2."  Cookie Extension

      struct {
          opaque cookie<V>;                         /* 1..2^23-1 */
      } Cookie;

"B.3.1.3."  Signature Algorithm Extension

      enum {
          /* RSASSA-PKCS1-v1_5 algorithms */
          rsa_pkcs1_sha256(0x0401),
          rsa_pkcs1_sha384(0x0501),
          rsa_pkcs1_sha512(0x0601),

          /* ECDSA algorithms */
          ecdsa_secp256r1_sha256(0x0403),
          ecdsa_secp384r1_sha384(0x0503),
          ecdsa_secp521r1_sha512(0x0603),

          /* RSASSA-PSS algorithms with public key OID rsaEncryption */
          rsa_pss_rsae_sha256(0x0804),
          rsa_pss_rsae_sha384(0x0805),
          rsa_pss_rsae_sha512(0x0806),

          /* EdDSA algorithms */
          ed25519(0x0807),
          ed448(0x0808),

          /* RSASSA-PSS algorithms with public key OID RSASSA-PSS */
          rsa_pss_pss_sha256(0x0809),
          rsa_pss_pss_sha384(0x080a),
          rsa_pss_pss_sha512(0x080b),

          /* Legacy algorithms */
          rsa_pkcs1_sha1(0x0201),
          ecdsa_sha1(0x0203),

          /* Reserved Code Points */
          obsolete_RESERVED(0x0000..0x0200),
          dsa_sha1_RESERVED(0x0202),
          obsolete_RESERVED(0x0204..0x0400),
          dsa_sha256_RESERVED(0x0402),
          obsolete_RESERVED(0x0404..0x0500),
          dsa_sha384_RESERVED(0x0502),
          obsolete_RESERVED(0x0504..0x0600),
          dsa_sha512_RESERVED(0x0602),
          obsolete_RESERVED(0x0604..0x06FF),
          private_use(0xFE00..0xFFFF),
          (0xFFFF)
      } SignatureScheme;

      struct {
          SignatureScheme supported_signature_algorithms<V>;
                                                    /* 2..2^23-2 */
      } SignatureSchemeList;

"B.3.1.4."  Supported Groups Extension

      enum {
          unallocated_RESERVED(0x0000),

          /* Elliptic Curve Groups (ECDHE) */
          obsolete_RESERVED(0x0001..0x0016),
          secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019),
          obsolete_RESERVED(0x001A..0x001C),
          x25519(0x001D), x448(0x001E),

          /* Finite Field Groups (DHE) */
          ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102),
          ffdhe6144(0x0103), ffdhe8192(0x0104),

          /* Reserved Code Points */
          ffdhe_private_use(0x01FC..0x01FF),
          ecdhe_private_use(0xFE00..0xFEFF),
          obsolete_RESERVED(0xFF01..0xFF02),
          (0xFFFF)
      } NamedGroup;

      struct {
          NamedGroup named_group_list<V>;           /* 2..2^23-1 */
      } NamedGroupList;

"B.3.2."  Server Parameters Messages

      opaque DistinguishedName<V>;                  /* 1..2^23-1 */

      struct {
          DistinguishedName authorities<V>;         /* 3..2^23-1 */
      } CertificateAuthoritiesExtension;

      struct {
          opaque certificate_extension_oid<1..2^8-1>;
          opaque certificate_extension_values<V>;   /* 0..2^23-1 */
      } OIDFilter;

      struct {
          OIDFilter filters<V>;                     /* 0..2^23-1 */
      } OIDFilterExtension;

      struct {} PostHandshakeAuth;

      struct {
          Extension extensions<V>;                  /* 0..2^23-1 */
      } EncryptedExtensions;

      struct {
          opaque certificate_request_context<0..2^8-1>;
          Extension extensions<V>;                  /* 2..2^23-1 */
      } CertificateRequest;

"B.3.3."  Authentication Messages

      enum {
          X509(0),
          OpenPGP_RESERVED(1),
          RawPublicKey(2),
          (255)
      } CertificateType;

      struct {
          select (certificate_type) {
              case RawPublicKey:
                /* From RFC 7250 ASN.1_subjectPublicKeyInfo */
                opaque ASN1_subjectPublicKeyInfo<1..2^24-1>;

              case X509:
                opaque cert_data<1..2^24-1>;
          };
          Extension extensions<V>;                  /* 0..2^23-1 */
      } CertificateEntry;

      struct {
          opaque certificate_request_context<0..2^8-1>;
          CertificateEntry certificate_list<0..2^24-1>;
      } Certificate;

      struct {
          SignatureScheme algorithm;
          opaque signature<0..2^16-1>;
      } CertificateVerify;

      struct {
          opaque verify_data[Hash.length];
      } Finished;

"B.3.4."  Ticket Establishment

      struct {
          uint32 ticket_lifetime;
          uint32 ticket_age_add;
          opaque ticket_nonce<0..255>;
          opaque ticket<1..2^16-1>;
          Extension extensions<V>;                  /* 0..2^23-2 */
      } NewSessionTicket;

"B.3.5."  Updating Keys

      struct {} EndOfEarlyData;

      enum {
          update_not_requested(0), update_requested(1), (255)
      } KeyUpdateRequest;

      struct {
          KeyUpdateRequest request_update;
      } KeyUpdate;

Acknowledgements

Eric Rescorla proposed the idea to use QUIC- and MLS-like variable-size length encoding in TLS 1.3.

Author's Address

Valery Smyslov
ELVIS-PLUS
Russian Federation