RFC 8879

TLS Certificate Compression

πŸ“… published December 2020, from ietf

RFC 8879: TLS Certificate Compression πŸŽ€

Okay bestie, let's get into RFC 8879 ✨ It's TLS Certificate Compression by A. Ghedini (Cloudflare, Inc.) and V. Vasiliev (Google), published in December 2020 as a Standards Track document. It's in the IETF stream with ISSN 2070-1721. The header doesn't list anything it obsoletes or updates, so it's a standalone spec πŸ’…

Abstract 🌈

So in TLS handshakes, certificate chains are usually the biggest chunk of bytes getting sent, lowkey wild 😭 This doc explains how you can compress those chains so less data gets transmitted and you can skip some round trips. Compression glow-up πŸ’–

Status of This Memo ✨

This is an Internet Standards Track document πŸ¦‹

It's a product of the Internet Engineering Task Force (IETF), so it represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). If you want more on Internet Standards, check Section 2 of RFC 7841. For the current status, errata, and where to send feedback, go to https://www.rfc-editor.org/info/rfc8879 πŸ”—

Copyright (c) 2020 IETF Trust and the persons identified as the document authors. All rights reserved 🫢

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they were in effect on the date of publication. Please read those carefully, because they spell out your rights and restrictions for this document. Code Components pulled out of this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come without warranty, as the Simplified BSD License describes πŸ“œ


Table of Contents 🧚

   1.  Introduction
   2.  Notational Conventions
   3.  Negotiating Certificate Compression
   4.  Compressed Certificate Message
   5.  Security Considerations
   6.  Middlebox Compatibility
   7.  IANA Considerations
     7.1.  TLS ExtensionType Values
     7.2.  TLS HandshakeType
     7.3.  Compression Algorithms
   8.  References
     8.1.  Normative References
     8.2.  Informative References
   Acknowledgements
   Authors' Addresses

1. Introduction ✨

Okay so to cut latency and make things faster, it helps to shrink how much data gets swapped during a TLS handshake πŸƒβ€β™€οΈπŸ’¨

[RFC7924] covers a mechanism where a client and server skip resending certificates they already shared in an earlier handshake. Cute, but it doesn't help when you connect to a server for the very first time and have no clue what its certificate chain looks like πŸ™ˆ

So this document describes a mechanism that lets certificates get compressed in every handshake, not just the repeat ones. Main character energy πŸ‘‘

2. Notational Conventions 🌸

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this doc mean what BCP 14 [RFC2119] [RFC8174] says they mean, but only when they show up in all capitals, just like here πŸ’…

3. Negotiating Certificate Compression πŸ’œ

Quick heads up: this extension only works with TLS 1.3 [RFC8446] and newer. If TLS 1.2 [RFC5246] or older is what gets negotiated, the peers MUST ignore this extension. Not me ignoring it πŸ™…β€β™€οΈ

This document defines a new extension type, compress_certificate(27), which signals the compression formats a peer supports for the Certificate message. When a client sends it as a ClientHello message extension ([RFC8446], Section 4.1.2), that means it supports compressed server certificates. When a server sends it as a CertificateRequest extension ([RFC8446], Section 4.3.2), that means it supports compressed client certificates ✨

When you send a compress_certificate extension, you're telling the peer which certificate-compression algorithms you're willing to use for decompression. The "extension_data" field of this extension SHALL contain a CertificateCompressionAlgorithms value, and it looks like this:

       enum {
           zlib(1),
           brotli(2),
           zstd(3),
           (65535)
       } CertificateCompressionAlgorithm;

       struct {
           CertificateCompressionAlgorithm algorithms<2..2^8-2>;
       } CertificateCompressionAlgorithms;

The compress_certificate extension is a one-way vibe. It's unidirectional, so no matching response extension is needed 🫢

4. Compressed Certificate Message πŸ¦‹

If the peer has said it supports compression, the server and the client MAY compress their corresponding Certificate messages (Section 4.4.2 of [RFC8446]). Then they send the result as a CompressedCertificate message, which replaces the Certificate message 🎁

The CompressedCertificate message is built like this:

       struct {
            CertificateCompressionAlgorithm algorithm;
            uint24 uncompressed_length;
            opaque compressed_certificate_message<1..2^24-1>;
       } CompressedCertificate;

Here's what each field does:

  • algorithm: the algorithm used to compress the certificate. It MUST be one of the algorithms listed in the peer's compress_certificate extension.
  • uncompressed_length: the length of the Certificate message once it's uncompressed. If the specified length doesn't match the actual length after decompression, the party receiving the invalid message MUST abort the connection with the "bad_certificate" alert. This field is the secret sauce that lets the receiver preallocate the buffer for the uncompressed Certificate message and enforce limits on the message size before it starts decompressing 🧠
  • compressed_certificate_message: the result of applying the indicated compression algorithm to the encoded Certificate message that would have been sent if certificate compression wasn't in use. The compression algorithm defines how the bytes in this field get converted back into the Certificate message πŸ”„

Now the algorithm-specific rules, which are a whole vibe πŸ’–

  • If the algorithm is zlib, the Certificate message MUST be compressed with the ZLIB compression algorithm, as defined in [RFC1950].
  • If the algorithm is brotli, the Certificate message MUST be compressed with the Brotli compression algorithm, as defined in [RFC7932].
  • If the algorithm is zstd, the Certificate message MUST be compressed with the Zstandard compression algorithm, as defined in [RFC8478].

It's possible to define a certificate compression algorithm that uses a preshared dictionary to get a higher compression ratio. This document doesn't define any of those, but extra codepoints can be allocated for them under the policy in Section 7.3 🌟

If the received CompressedCertificate message can't be decompressed, the connection MUST be terminated with the "bad_certificate" alert 🚫

Last bit for this section: if the format of the Certificate message gets altered using the server_certificate_type or client_certificate_type extensions [RFC7250], then the altered message is what gets compressed instead πŸ“

Part 1 wraps up here. Part 2 picks up at Section 5 (Security Considerations) and keeps the glow going πŸŒˆπŸ’–

7.3. Compression Algorithms ✨

okay so this section sets up a brand new registry πŸ—‚οΈ called "TLS Certificate Compression Algorithm IDs", and it lives inside the existing "Transport Layer Security (TLS) Extensions" registry. the whole point is to keep track of which compression algorithms can squish the Certificate message πŸ€πŸ’–

here's the lineup:

+==================+===============================+===========+
| Algorithm Number | Description                   | Reference |
+==================+===============================+===========+
| 0                | Reserved                      | RFC 8879  |
+------------------+-------------------------------+-----------+
| 1                | zlib                          | RFC 8879  |
+------------------+-------------------------------+-----------+
| 2                | brotli                        | RFC 8879  |
+------------------+-------------------------------+-----------+
| 3                | zstd                          | RFC 8879  |
+------------------+-------------------------------+-----------+
| 16384 to 65535   | Reserved for Experimental Use |           |
+------------------+-------------------------------+-----------+

Table 1: TLS Certificate Compression Algorithm IDs πŸŽ€

ngl the way the ID ranges are split up is so organized it's giving librarian energy πŸ“šπŸ§š new values under 256 get handed out through IETF Review πŸ‘€, values from 256 up to 16383 need Specification Required πŸ“, and anything above that is for Experimental Use πŸ§ͺ. and the experimental stuff? totally fair game for both private networks and the open Internet 🌈🫢

if you want the nitty gritty on how those policies actually work, you can check out [RFC8126] πŸ’… and the procedures for asking for values in the Specification Required space are in Section 17 of [RFC8447] πŸ¦‹


8. References πŸ“š

8.1. Normative References πŸ’œ

8.2. Informative References 🌷


Acknowledgements 🫢

certificate compression first showed up in the QUIC Crypto protocol, designed by Adam Langley and Wan-Teh Chang. iconic origin story πŸ‘‘

this document got so much help from contributions and suggestions by David Benjamin, Ryan Hamilton, Christian Huitema, Benjamin Kaduk, Ilari Liusvaara, Piotr Sikora, Ian Swett, Martin Thomson, Sean Turner, and many others. the squad is literally the best πŸ’–πŸŒˆ


Authors' Addresses πŸ’Œ

Alessandro Ghedini Cloudflare, Inc.

Email: alessandro@cloudflare.com

Victor Vasiliev Google

Email: vasilvv@google.com

πŸ“¦ where this page comes from