diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c25dba04..7d8150a12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,6 +144,14 @@ IF (OPENSSL_FOUND AND LIBC_RESOLV_LIB) TARGET_LINK_LIBRARIES(cli ${LIBC_RESOLV_LIB}) ENDIF () +FIND_LIBRARY(LibZSTD "zstd") +IF (LibZSTD) + MESSAGE(STATUS " Enabling ZSTD support") + ADD_DEFINITIONS(-DPTLS_HAVE_ZSTD) + LIST(APPEND CORE_EXTRA_LIBS ${LibZSTD}) + TARGET_LINK_LIBRARIES(cli ${LibZSTD}) +ENDIF () + IF (BUILD_FUZZER) IF (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") MESSAGE(FATAL ERROR "The fuzzer needs clang as a compiler") diff --git a/include/picotls/certificate_compression.h b/include/picotls/certificate_compression.h index 30a73c465..9b2cc313d 100644 --- a/include/picotls/certificate_compression.h +++ b/include/picotls/certificate_compression.h @@ -30,6 +30,7 @@ extern "C" { #define PTLS_CERTIFICATE_COMPRESSION_ALGORITHM_GZIP 1 #define PTLS_CERTIFICATE_COMPRESSION_ALGORITHM_BROTLI 2 +#define PTLS_CERTIFICATE_COMPRESSION_ALGORITHM_ZSTD 3 typedef struct st_ptls_emit_compressed_certificate_t { ptls_emit_certificate_t super; diff --git a/lib/certificate_compression.c b/lib/certificate_compression.c index 36e77fdca..abe120489 100644 --- a/lib/certificate_compression.c +++ b/lib/certificate_compression.c @@ -24,26 +24,43 @@ #include "brotli/decode.h" #include "brotli/encode.h" #include "picotls/certificate_compression.h" +#ifdef PTLS_HAVE_ZSTD +#include "zstd.h" +#endif static inline int decompress_certificate(ptls_decompress_certificate_t *self, ptls_t *tls, uint16_t algorithm, ptls_iovec_t output, ptls_iovec_t input) { - if (algorithm != PTLS_CERTIFICATE_COMPRESSION_ALGORITHM_BROTLI) - goto Fail; - - size_t decoded_size = output.len; - if (BrotliDecoderDecompress(input.len, input.base, &decoded_size, output.base) != BROTLI_DECODER_RESULT_SUCCESS) - goto Fail; - - if (decoded_size != output.len) - goto Fail; - - return 0; + if (algorithm == PTLS_CERTIFICATE_COMPRESSION_ALGORITHM_BROTLI) { + + size_t decoded_size = output.len; + if (BrotliDecoderDecompress(input.len, input.base, &decoded_size, output.base) != BROTLI_DECODER_RESULT_SUCCESS) + goto Fail; + + if (decoded_size != output.len) + goto Fail; + + return 0; +#if PTLS_HAVE_ZSTD + } else if (algorithm == PTLS_CERTIFICATE_COMPRESSION_ALGORITHM_ZSTD) { + size_t res = ZSTD_decompress(output.base, output.len, input.base, input.len); + if (ZSTD_isError(res)) + goto Fail; + if (res != output.len) + goto Fail; + return 0; +#endif + } Fail: return PTLS_ALERT_BAD_CERTIFICATE; } -static const uint16_t algorithms[] = {PTLS_CERTIFICATE_COMPRESSION_ALGORITHM_BROTLI, UINT16_MAX}; +static const uint16_t algorithms[] = { + PTLS_CERTIFICATE_COMPRESSION_ALGORITHM_BROTLI, +#if PTLS_HAVE_ZSTD + PTLS_CERTIFICATE_COMPRESSION_ALGORITHM_ZSTD, +#endif + UINT16_MAX}; ptls_decompress_certificate_t ptls_decompress_certificate = {algorithms, decompress_certificate};