Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4317,6 +4317,20 @@ if(WOLFSSL_LIBZ)
list(APPEND WOLFSSL_INCLUDE_DIRS ${ZLIB_INCLUDE_DIRS})
endif()

# TLS 1.3 Certificate Compression (RFC 8879)
add_option("WOLFSSL_CERT_COMPRESSION"
"Enable TLS 1.3 Certificate Compression, RFC 8879 (requires WOLFSSL_LIBZ) (default: disabled)"
"no" "yes;no")
if(WOLFSSL_CERT_COMPRESSION)
if(NOT WOLFSSL_LIBZ)
message(FATAL_ERROR "WOLFSSL_CERT_COMPRESSION requires zlib. Add -DWOLFSSL_LIBZ=yes.")
endif()
if(NOT WOLFSSL_TLS13)
message(FATAL_ERROR "WOLFSSL_CERT_COMPRESSION requires TLS 1.3. Do not disable WOLFSSL_TLS13.")
endif()
list(APPEND WOLFSSL_DEFINITIONS "-DHAVE_TLS_EXTENSIONS" "-DWOLFSSL_CERT_COMPRESSION")
endif()


####################################################
# Maximum key size options (parity with configure.ac)
Expand Down Expand Up @@ -4876,6 +4890,7 @@ if(WOLFSSL_EXAMPLES)
tests/api/test_evp_pkey.c
tests/api/test_certman.c
tests/api/test_tls13.c
tests/api/test_tls13_cert_compression.c
tests/api/test_tls13_bounds.c
tests/api/test_tls13_features.c
tests/srp.c
Expand Down
2 changes: 2 additions & 0 deletions cmake/options.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,8 @@ extern "C" {
#cmakedefine WOLFSSL_CHECK_ALERT_ON_ERR
#undef HAVE_LIBZ
#cmakedefine HAVE_LIBZ
#undef WOLFSSL_CERT_COMPRESSION
#cmakedefine WOLFSSL_CERT_COMPRESSION
#undef WOLFSSL_HARDEN_TLS
#cmakedefine WOLFSSL_HARDEN_TLS @WOLFSSL_HARDEN_TLS@

Expand Down
21 changes: 21 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -11190,6 +11190,26 @@ AC_ARG_WITH([libz],
]
)

# TLS 1.3 Certificate Compression (RFC 8879)
AC_ARG_ENABLE([cert-compression],
[AS_HELP_STRING([--enable-cert-compression],[Enable TLS 1.3 Certificate Compression, RFC 8879 (requires --with-libz) (default: disabled)])],
[ ENABLED_CERT_COMPRESSION=$enableval ],
[ ENABLED_CERT_COMPRESSION=no ]
)

if test "x$ENABLED_CERT_COMPRESSION" = "xyes"
then
if test "x$ENABLED_LIBZ" = "xno"
then
AC_MSG_ERROR([--enable-cert-compression requires zlib. Add --with-libz.])
fi
if test "x$ENABLED_TLS13" = "xno"
then
AC_MSG_ERROR([--enable-cert-compression requires TLS 1.3. Do not disable TLS 1.3.])
fi
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DWOLFSSL_CERT_COMPRESSION"
fi


# PKCS#11
AC_ARG_ENABLE([pkcs11],
Expand Down Expand Up @@ -14779,6 +14799,7 @@ echo " * Supported Elliptic Curves: $ENABLED_SUPPORTED_CURVES"
echo " * FFDHE only in client: $ENABLED_FFDHE_ONLY"
echo " * Session Ticket: $ENABLED_SESSION_TICKET"
echo " * Session cache ref (deprec): $ENABLED_SESSION_CACHE_REF"
echo " * Certificate Compression: $ENABLED_CERT_COMPRESSION"
echo " * Extended Master Secret: $ENABLED_EXTENDED_MASTER"
echo " * Renegotiation Indication: $ENABLED_RENEGOTIATION_INDICATION"
echo " * Secure Renegotiation: $ENABLED_SECURE_RENEGOTIATION"
Expand Down
221 changes: 221 additions & 0 deletions doc/dox_comments/header_files/compress.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,224 @@ int wc_DeCompress_ex(byte* out, word32 outSz, const byte* in, word32 inSz,
int wc_DeCompressDynamic(byte** out, int max, int memoryType,
const byte* in, word32 inSz, int windowBits,
void* heap);

/*!
\ingroup Compression

\brief Checks whether a compression algorithm is compiled into this build
and usable with the wc_CompressionData functions. The algorithm ids are
the TLS CertificateCompressionAlgorithm code points (RFC 8879), e.g.
WC_ZLIB.

\return 1 if the algorithm is supported
\return 0 if the algorithm is not supported, or is WC_NO_COMPRESSION

\param alg compression algorithm id to check

_Example_
\code
if (wc_IsCompressionAlgSupported(WC_ZLIB)) {
// zlib can be used
}
\endcode

\sa wc_CompressionData_InitComp
\sa wc_CompressionData_InitDeComp
*/
byte wc_IsCompressionAlgSupported(word16 alg);

/*!
\ingroup Compression

\brief Initializes a wc_CompressionData object to decompress the given
compressed data. The object does not take ownership of data; it is only
read from and must stay valid until the object is decompressed or freed.
If reusing an object, call wc_CompressionData_Free on it first.

\return 0 on success
\return BAD_FUNC_ARG if cd or data is NULL, uncompSz is 0, or alg is not
supported

\param cd object to initialize
\param data buffer holding the compressed data
\param compSz size of the compressed data in bytes
\param uncompSz exact size of the data once decompressed
\param alg compression algorithm used to compress data

_Example_
\code
wc_CompressionData cd;
byte compressed[] = { // compressed data };
word32 uncompSz = // exact decompressed size;

if (wc_CompressionData_InitDeComp(&cd, compressed, sizeof(compressed),
uncompSz, WC_ZLIB) == 0 &&
wc_CompressionData_DeCompress(&cd) == 0) {
// cd.data holds cd.uncompressedSz bytes of decompressed data
}
wc_CompressionData_Free(&cd);
\endcode

\sa wc_CompressionData_DeCompress
\sa wc_CompressionData_DeCompToBuf
\sa wc_CompressionData_Free
*/
int wc_CompressionData_InitDeComp(wc_CompressionData* cd,
const byte* data, word32 compSz, word32 uncompSz,
word16 alg);

/*!
\ingroup Compression

\brief Initializes a wc_CompressionData object to compress the given data.
The object does not take ownership of data; it is only read from and must
stay valid until the object is compressed or freed. If reusing an object,
call wc_CompressionData_Free on it first.

\return 0 on success
\return BAD_FUNC_ARG if cd or data is NULL, uncompSz is 0, or alg is not
supported

\param cd object to initialize
\param data buffer holding the data to compress
\param uncompSz size of data in bytes
\param alg compression algorithm to use

_Example_
\code
wc_CompressionData cd;
byte msg[] = { // data to compress };

if (wc_CompressionData_InitComp(&cd, msg, sizeof(msg), WC_ZLIB) == 0 &&
wc_CompressionData_Compress(&cd) == 0) {
// cd.data holds cd.compressedSz bytes of compressed data
}
wc_CompressionData_Free(&cd);
\endcode

\sa wc_CompressionData_Compress
\sa wc_CompressionData_CompToBuf
\sa wc_CompressionData_Free
*/
int wc_CompressionData_InitComp(wc_CompressionData* cd,
const byte* data, word32 uncompSz, word16 alg);

/*!
\ingroup Compression

\brief Sets the heap hint used for buffers that
wc_CompressionData_Compress and wc_CompressionData_DeCompress allocate.
Call after the Init function, since Init clears the object.

\return 0 on success
\return BAD_FUNC_ARG if cd is NULL

\param cd initialized object
\param heap heap hint (can be NULL)

\sa wc_CompressionData_Compress
\sa wc_CompressionData_DeCompress
*/
int wc_CompressionData_SetHeap(wc_CompressionData* cd, void* heap);

/*!
\ingroup Compression

\brief Releases the buffer owned by the object (the output of a previous
Compress or DeCompress call), zeroizing it first, and clears the object.
A buffer passed to an Init function is not freed. Safe to call with NULL.

\return none No returns.

\param cd object to free

\sa wc_CompressionData_InitComp
\sa wc_CompressionData_InitDeComp
*/
void wc_CompressionData_Free(wc_CompressionData* cd);

/*!
\ingroup Compression

\brief Compresses the object's data into a newly allocated buffer, which
the object then owns. On success cd->data points at the compressed data
and cd->compressedSz holds its size. Compression fails when the output
does not fit in the uncompressed size.

\return 0 on success
\return BAD_FUNC_ARG if data is NULL, not initialized for compression, or
the algorithm is not supported
\return MEMORY_E if allocation fails
\return COMPRESS_E or another negative value if compression fails

\param data object initialized with wc_CompressionData_InitComp

\sa wc_CompressionData_InitComp
\sa wc_CompressionData_CompToBuf
*/
int wc_CompressionData_Compress(wc_CompressionData* data);

/*!
\ingroup Compression

\brief Compresses the object's data into a caller-supplied buffer. The
object is not modified.

\return the number of compressed bytes written to out on success
\return BAD_FUNC_ARG if data or out is NULL or the algorithm is not
supported
\return COMPRESS_E or another negative value if compression fails,
including when out is too small

\param data object initialized with wc_CompressionData_InitComp
\param out buffer to write the compressed data to
\param outSz size of out in bytes

\sa wc_CompressionData_Compress
*/
int wc_CompressionData_CompToBuf(const wc_CompressionData* data,
byte* out, word32 outSz);

/*!
\ingroup Compression

\brief Decompresses the object's data into a newly allocated buffer of
cd->uncompressedSz bytes, which the object then owns. On success cd->data
points at the decompressed data. Decompression fails unless the output is
exactly the uncompressed size given to wc_CompressionData_InitDeComp.

\return 0 on success
\return BAD_FUNC_ARG if data is NULL, not initialized for decompression,
or the algorithm is not supported
\return MEMORY_E if allocation fails
\return BUFFER_E if the decompressed size is too small
\return other negative values if decompression fails

\param data object initialized with wc_CompressionData_InitDeComp

\sa wc_CompressionData_InitDeComp
\sa wc_CompressionData_DeCompToBuf
*/
int wc_CompressionData_DeCompress(wc_CompressionData* data);

/*!
\ingroup Compression

\brief Decompresses the object's data into a caller-supplied buffer. The
object is not modified.

\return the number of decompressed bytes written to out on success
\return BAD_FUNC_ARG if data or out is NULL or the algorithm is not
supported
\return BUFFER_E if outSz is smaller than the uncompressed size, or the
decompressed size does not match it
\return other negative values if decompression fails

\param data object initialized with wc_CompressionData_InitDeComp
\param out buffer to write the decompressed data to
\param outSz size of out in bytes

\sa wc_CompressionData_DeCompress
*/
int wc_CompressionData_DeCompToBuf(const wc_CompressionData* data,
byte* out, word32 outSz);
89 changes: 89 additions & 0 deletions doc/dox_comments/header_files/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -14871,6 +14871,95 @@ int wolfSSL_CTX_no_ticket_TLSv13(WOLFSSL_CTX* ctx);
*/
int wolfSSL_no_ticket_TLSv13(WOLFSSL* ssl);

/*!
\ingroup Setup

\brief This function sets the certificate compression algorithms
(RFC 8879) that WOLFSSL objects created from this context will offer, in
order of preference. Defaults to negotiate all supported compression
algorithms by the build (see wc_IsCompressionAlgSupported()).
Passing an empty alg list turns off certificate compression.

Available when wolfSSL is built with --enable-cert-compression and
--with-libz. Certificate compression is available with (D)TLS 1.3.

\param [in,out] ctx a pointer to a WOLFSSL_CTX Object.
\param [in] algs array of RFC 8879 algorithm IDs, most preferred first.
Every entry must be supported by this build (see
wc_IsCompressionAlgSupported()). May be NULL only when count is 0.
\param [in] count number of entries in algs, from 0 to 127. A count of 0
turns off certificate compression.

\return WOLFSSL_SUCCESS if successful.
\return BAD_FUNC_ARG if ctx is NULL, algs is NULL while count is not 0,
count is negative or greater than 127, or an entry in algs is not a
supported algorithm.
\return MEMORY_E if the copy of the list could not be allocated.

_Example_
\code
int ret;
WOLFSSL_CTX* ctx;
const word16 algs[] = { WC_ZLIB };
...
ret = wolfSSL_CTX_set_cert_compression_algs(ctx, algs,
(int)(sizeof(algs) / sizeof(algs[0])));
if (ret != WOLFSSL_SUCCESS) {
// failed to set compression algorithms
}
\endcode

\sa wolfSSL_set_cert_compression_algs
\sa wc_IsCompressionAlgSupported
*/
int wolfSSL_CTX_set_cert_compression_algs(WOLFSSL_CTX* ctx,
const word16* algs, int count);

/*!
\ingroup Setup

\brief This function sets the certificate compression algorithms
(RFC 8879) that the wolfSSL object will negotiate. Defaults to negotiate
all supported compression algorithms by the build (see
wc_IsCompressionAlgSupported()). Passing an empty alg list turns off
certificate compression.

Available when wolfSSL is built with --enable-cert-compression and
--with-libz. Certificate compression is available with (D)TLS 1.3.

\param [in,out] ssl a pointer to a WOLFSSL structure, created using
wolfSSL_new().
\param [in] algs array of RFC 8879 algorithm IDs, most preferred first.
Every entry must be supported by this build (see
wc_IsCompressionAlgSupported()). May be NULL only when count is 0.
\param [in] count number of entries in algs, from 0 to 127. A count of 0
turns off certificate compression.

\return WOLFSSL_SUCCESS if successful.
\return BAD_FUNC_ARG if ssl is NULL, algs is NULL while count is not 0,
count is negative or greater than 127, or an entry in algs is not a
supported algorithm.
\return MEMORY_E if the copy of the list could not be allocated.

_Example_
\code
int ret;
WOLFSSL* ssl;
const word16 algs[] = { WC_ZLIB };
...
ret = wolfSSL_set_cert_compression_algs(ssl, algs,
(int)(sizeof(algs) / sizeof(algs[0])));
if (ret != WOLFSSL_SUCCESS) {
// failed to set compression algorithms
}
\endcode

\sa wolfSSL_CTX_set_cert_compression_algs
\sa wc_IsCompressionAlgSupported
*/
int wolfSSL_set_cert_compression_algs(WOLFSSL* ssl,
const word16* algs, int count);

/*!
\ingroup Setup

Expand Down
Loading
Loading