Skip to content

Certificate compression #788

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Certificate compression #788

wants to merge 3 commits into from

Conversation

pluknet
Copy link
Contributor

@pluknet pluknet commented Jul 16, 2025

See also trac ticket #2546 for the previous patch series discussion and some numbers linked from there.

pluknet added 3 commits July 16, 2025 22:50
Certificate compression is supported since OpenSSL 3.2, it is enabled
automatically as negotiated in a TLSv1.3 handshake.

Using certificate compression and decompression in runtime may be
suboptimal in terms of CPU and memory consumption in certain typical
scenarios, hence it is disabled by default on both server and client
sides.  It can be enabled with ssl_conf_command and similar directives
in upstream as appropriate, for example:

    ssl_conf_command Options RxCertificateCompression;
    ssl_conf_command Options TxCertificateCompression;

Compressing server certificates requires additional support, this is
addressed separately.
The ssl_certificate_compression directive allows to send compressed
server certificates, which are pre-compressed on on nginx startup.
To simplify configuration, the SSL_OP_NO_TX_CERTIFICATE_COMPRESSION
option is automatically cleared if certificates were pre-compressed.

SSL_CTX_compress_certs() may return an error in legitimate cases,
e.g., when none of compression algorithms is available or if the
resulting compressed size is larger than the original one, thus it
is silently ignored.

Certificate compression is supported in Chrome with brotli only,
in Safari with zlib only, and in Firefox with all listed algorithms.
It is supported since Ubuntu 24.10, which has OpenSSL with enabled
zlib and zstd support.

The actual list of algorithms supported in OpenSSL depends on how
the library was configured; it can be brotli, zlib, zstd as listed
in RFC 8879.
BoringSSL provides two callbacks to register on SSL context for each
compression algorithm, which is used to send and receive compressed
server certificates, as appropriate.  This change adds support for
compression with zlib, enabled with the ssl_certificate_compression
directive.  Compressed certificates are cached in SSL context on the
first callback invocation.
@pluknet pluknet requested a review from arut July 16, 2025 18:53
@pluknet pluknet self-assigned this Jul 16, 2025
@Maryna-f5 Maryna-f5 added this to the nginx-1.29.1 milestone Jul 16, 2025
zstream.next_out = tmp.data;
zstream.avail_out = tmp.len;

rc = deflateInit(&zstream, Z_DEFAULT_COMPRESSION);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the result of compression is cached and certificates are usually small (few kb), I think it would be better to use Z_BEST_COMPRESSION.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Z_DEFAULT_COMPRESSION - is a compromise between two evils: non-efficient and slow compression.
If proven useful, a separate directive can be introduced, similar to gzip_comp_level.

Comment on lines +683 to +684
ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
"\"ssl_certificate_compression\" ignored, not supported");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A similar function ngx_ssl_early_data() has different text:

    ngx_log_error(NGX_LOG_WARN, ssl->log, 0,                                     
                  "\"ssl_early_data\" is not supported on this platform, "       
                  "ignored"); 

The same text exists in ngx_ssl_session_ticket_keys(), but the example above looks more relevant.

#ifdef SSL_OP_NO_RX_CERTIFICATE_COMPRESSION

if (SSL_CTX_compress_certs(ssl->ctx, 0) != 0) {
SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TX_CERTIFICATE_COMPRESSION);
Copy link
Contributor

@arut arut Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not disable tx compression in the if (!enable) {...} block above instead of disabling it for all new ssl context and enabling it back here. Also, seems like enabling tx compression is completely safe anyway.

@arut
Copy link
Contributor

arut commented Jul 29, 2025

server certificates, which are pre-compressed on on nginx startup.

double "on"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants