Preliminary support for compressed certificates.
This change adds server-side support for compressed certificates.
(Although some definitions for client-side support are included in the
headers, there's no code behind them yet.)
Change-Id: I0f98abf0b782b7337ddd014c58e19e6b8cc5a3c2
Reviewed-on: https://boringssl-review.googlesource.com/27964
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 96cd7e5..1218a46 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -4565,6 +4565,50 @@
BORINGSSL_MAKE_DELETER(SSL_CTX, SSL_CTX_free)
BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free)
+// Certificate compression.
+//
+// Certificates in TLS 1.3 can be compressed[1]. BoringSSL supports this as both
+// a client and a server, but does not link against any specific compression
+// libraries in order to keep dependencies to a minimum. Instead, hooks for
+// compression and decompression can be installed in an |SSL_CTX| to enable
+// support.
+//
+// [1] https://tools.ietf.org/html/draft-ietf-tls-certificate-compression-03.
+
+// CertCompressFunc is a pointer to a function that performs compression. It
+// must write the compressed representation of |in| to |out|, returning one on
+// success and zero on error. The results of compressing certificates are not
+// cached internally. Implementations may wish to implement their own cache if
+// they expect it to be useful given the certificates that they serve.
+typedef bool (*CertCompressFunc)(SSL *ssl, CBB *out, Span<const uint8_t> in);
+
+// CertDecompressFunc is a pointer to a function that performs decompression.
+// The compressed data from the peer is passed as |in| and the decompressed
+// result must be exactly |uncompressed_len| bytes long. It returns one on
+// success, in which case |*out| must be set to the results of decompressing
+// |in|, or zero on error. The results of decompression are not cached
+// internally. Implementations may wish to implement their own cache if they
+// expect it to be useful.
+typedef bool (*CertDecompressFunc)(SSL *ssl,
+ bssl::UniquePtr<CRYPTO_BUFFER> *out,
+ size_t uncompressed_len,
+ Span<const uint8_t> in);
+
+// SSL_CTX_add_cert_compression_alg registers a certificate compression
+// algorithm on |ctx| with ID |alg_id|. (The value of |alg_id| should be an IANA
+// assigned value and each can only be registered once.)
+//
+// One of the function pointers may be nullptr to avoid having to implement both
+// sides of a compression algorithm if you're only going to use it in one
+// direction. In this case, the unimplemented direction acts like it was never
+// configured.
+//
+// For a server, algorithms are registered in preference order with the most
+// preferable first. It returns one on success or zero on error.
+OPENSSL_EXPORT int SSL_CTX_add_cert_compression_alg(
+ SSL_CTX *ctx, uint16_t alg_id, CertCompressFunc compress,
+ CertDecompressFunc decompress);
+
enum class OpenRecordResult {
kOK,
kDiscard,
diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h
index e32a6d7..67d06f4 100644
--- a/include/openssl/ssl3.h
+++ b/include/openssl/ssl3.h
@@ -311,6 +311,7 @@
#define SSL3_MT_CERTIFICATE_STATUS 22
#define SSL3_MT_SUPPLEMENTAL_DATA 23
#define SSL3_MT_KEY_UPDATE 24
+#define SSL3_MT_COMPRESSED_CERTIFICATE 25
#define SSL3_MT_NEXT_PROTO 67
#define SSL3_MT_CHANNEL_ID 203
#define SSL3_MT_MESSAGE_HASH 254
diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
index 4b25806..bb9a816 100644
--- a/include/openssl/tls1.h
+++ b/include/openssl/tls1.h
@@ -205,9 +205,15 @@
// ExtensionType value from draft-ietf-tokbind-negotiation-10
#define TLSEXT_TYPE_token_binding 24
-// ExtensionType value from draft-ietf-quic-tls
+// ExtensionType value from draft-ietf-quic-tls. Note that this collides with
+// TLS-LTS and, based on scans, something else too. Since it's QUIC-only, that
+// shouldn't be a problem in practice.
#define TLSEXT_TYPE_quic_transport_parameters 26
+// ExtensionType value assigned to
+// https://tools.ietf.org/html/draft-ietf-tls-certificate-compression-03
+#define TLSEXT_TYPE_cert_compression 27
+
// ExtensionType value from RFC4507
#define TLSEXT_TYPE_session_ticket 35