Add zlib oneshot compression
Fixes #19520 Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/19603)
This commit is contained in:
parent
f5a10d5cc1
commit
3840271e98
@ -74,8 +74,10 @@ static COMP_METHOD zlib_stateful_method = {
|
||||
# include "internal/dso.h"
|
||||
|
||||
/* Function pointers */
|
||||
typedef int (*compress_ft) (Bytef *dest, uLongf * destLen,
|
||||
typedef int (*compress_ft) (Bytef *dest, uLongf *destLen,
|
||||
const Bytef *source, uLong sourceLen);
|
||||
typedef int (*uncompress_ft) (Bytef *dest, uLongf *destLen,
|
||||
const Bytef *source, uLong sourceLen);
|
||||
typedef int (*inflateEnd_ft) (z_streamp strm);
|
||||
typedef int (*inflate_ft) (z_streamp strm, int flush);
|
||||
typedef int (*inflateInit__ft) (z_streamp strm,
|
||||
@ -86,6 +88,7 @@ typedef int (*deflateInit__ft) (z_streamp strm, int level,
|
||||
const char *version, int stream_size);
|
||||
typedef const char *(*zError__ft) (int err);
|
||||
static compress_ft p_compress = NULL;
|
||||
static uncompress_ft p_uncompress = NULL;
|
||||
static inflateEnd_ft p_inflateEnd = NULL;
|
||||
static inflate_ft p_inflate = NULL;
|
||||
static inflateInit__ft p_inflateInit_ = NULL;
|
||||
@ -97,6 +100,7 @@ static zError__ft p_zError = NULL;
|
||||
static DSO *zlib_dso = NULL;
|
||||
|
||||
# define compress p_compress
|
||||
# define uncompress p_uncompress
|
||||
# define inflateEnd p_inflateEnd
|
||||
# define inflate p_inflate
|
||||
# define inflateInit_ p_inflateInit_
|
||||
@ -199,6 +203,70 @@ static ossl_ssize_t zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out
|
||||
return (ossl_ssize_t)(olen - state->istream.avail_out);
|
||||
}
|
||||
|
||||
/* ONESHOT COMPRESSION/DECOMPRESSION */
|
||||
|
||||
static int zlib_oneshot_init(COMP_CTX *ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void zlib_oneshot_finish(COMP_CTX *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static ossl_ssize_t zlib_oneshot_compress_block(COMP_CTX *ctx, unsigned char *out,
|
||||
size_t olen, unsigned char *in,
|
||||
size_t ilen)
|
||||
{
|
||||
uLongf out_size;
|
||||
|
||||
if (ilen == 0)
|
||||
return 0;
|
||||
|
||||
/* zlib's uLongf defined as unsigned long FAR */
|
||||
if (olen > ULONG_MAX)
|
||||
return -1;
|
||||
out_size = (uLongf)olen;
|
||||
|
||||
if (compress(out, &out_size, in, ilen) != Z_OK)
|
||||
return -1;
|
||||
|
||||
if (out_size > OSSL_SSIZE_MAX)
|
||||
return -1;
|
||||
return (ossl_ssize_t)out_size;
|
||||
}
|
||||
|
||||
static ossl_ssize_t zlib_oneshot_expand_block(COMP_CTX *ctx, unsigned char *out,
|
||||
size_t olen, unsigned char *in,
|
||||
size_t ilen)
|
||||
{
|
||||
uLongf out_size;
|
||||
|
||||
if (ilen == 0)
|
||||
return 0;
|
||||
|
||||
/* zlib's uLongf defined as unsigned long FAR */
|
||||
if (olen > ULONG_MAX)
|
||||
return -1;
|
||||
out_size = (uLongf)olen;
|
||||
|
||||
if (uncompress(out, &out_size, in, ilen) != Z_OK)
|
||||
return -1;
|
||||
|
||||
if (out_size > OSSL_SSIZE_MAX)
|
||||
return -1;
|
||||
return (ossl_ssize_t)out_size;
|
||||
}
|
||||
|
||||
static COMP_METHOD zlib_oneshot_method = {
|
||||
NID_zlib_compression,
|
||||
LN_zlib_compression,
|
||||
zlib_oneshot_init,
|
||||
zlib_oneshot_finish,
|
||||
zlib_oneshot_compress_block,
|
||||
zlib_oneshot_expand_block
|
||||
};
|
||||
|
||||
static CRYPTO_ONCE zlib_once = CRYPTO_ONCE_STATIC_INIT;
|
||||
DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init)
|
||||
{
|
||||
@ -217,6 +285,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init)
|
||||
zlib_dso = DSO_load(NULL, LIBZ, NULL, 0);
|
||||
if (zlib_dso != NULL) {
|
||||
p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress");
|
||||
p_uncompress = (compress_ft) DSO_bind_func(zlib_dso, "uncompress");
|
||||
p_inflateEnd = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd");
|
||||
p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate");
|
||||
p_inflateInit_ = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_");
|
||||
@ -225,7 +294,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init)
|
||||
p_deflateInit_ = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_");
|
||||
p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError");
|
||||
|
||||
if (p_compress == NULL || p_inflateEnd == NULL
|
||||
if (p_compress == NULL || p_uncompress == NULL || p_inflateEnd == NULL
|
||||
|| p_inflate == NULL || p_inflateInit_ == NULL
|
||||
|| p_deflateEnd == NULL || p_deflate == NULL
|
||||
|| p_deflateInit_ == NULL || p_zError == NULL) {
|
||||
@ -250,6 +319,18 @@ COMP_METHOD *COMP_zlib(void)
|
||||
return meth;
|
||||
}
|
||||
|
||||
COMP_METHOD *COMP_zlib_oneshot(void)
|
||||
{
|
||||
COMP_METHOD *meth = NULL;
|
||||
|
||||
#ifndef OPENSSL_NO_ZLIB
|
||||
if (RUN_ONCE(&zlib_once, ossl_comp_zlib_init))
|
||||
meth = &zlib_oneshot_method;
|
||||
#endif
|
||||
|
||||
return meth;
|
||||
}
|
||||
|
||||
/* Also called from OPENSSL_cleanup() */
|
||||
void ossl_comp_zlib_cleanup(void)
|
||||
{
|
||||
|
@ -11,6 +11,7 @@ COMP_CTX_free,
|
||||
COMP_compress_block,
|
||||
COMP_expand_block,
|
||||
COMP_zlib,
|
||||
COMP_zlib_oneshot,
|
||||
COMP_brotli,
|
||||
COMP_brotli_oneshot,
|
||||
COMP_zstd,
|
||||
@ -37,6 +38,7 @@ BIO_f_zstd
|
||||
unsigned char *in, int ilen);
|
||||
|
||||
COMP_METHOD *COMP_zlib(void);
|
||||
COMP_METHOD *COMP_zlib_oneshot(void);
|
||||
COMP_METHOD *COMP_brotli(void);
|
||||
COMP_METHOD *COMP_brotli_oneshot(void);
|
||||
COMP_METHOD *COMP_zstd(void);
|
||||
@ -78,6 +80,10 @@ COMP_zlib() returns a B<COMP_METHOD> for stream-based ZLIB compression.
|
||||
|
||||
=item *
|
||||
|
||||
COMP_zlib_oneshot() returns a B<COMP_METHOD> for one-shot ZLIB compression.
|
||||
|
||||
=item *
|
||||
|
||||
COMP_brotli() returns a B<COMP_METHOD> for stream-based Brotli compression.
|
||||
|
||||
=item *
|
||||
@ -130,7 +136,7 @@ COMP_zlib(), COMP_brotli() and COMP_zstd() are stream-based compression methods.
|
||||
Internal state (including compression dictionary) is maintained between calls.
|
||||
If an error is returned, the stream is corrupted, and should be closed.
|
||||
|
||||
COMP_brotli_oneshot() and COMP_zstd_oneshot() are not stream-based. These
|
||||
COMP_zlib_oneshot(), COMP_brotli_oneshot() and COMP_zstd_oneshot() are not stream-based. These
|
||||
methods do not maintain state between calls. An error in one call does not affect
|
||||
future calls.
|
||||
|
||||
@ -138,7 +144,7 @@ future calls.
|
||||
|
||||
COMP_CTX_new() returns a B<COMP_CTX> on success, or NULL on failure.
|
||||
|
||||
COMP_CTX_get_method(), COMP_zlib(), COMP_brotli(), COMP_brotli_oneshot(),
|
||||
COMP_CTX_get_method(), COMP_zlib(), COMP_zlib_oneshot(), COMP_brotli(), COMP_brotli_oneshot(),
|
||||
COMP_zstd(), and COMP_zstd_oneshot() return a B<COMP_METHOD> on success,
|
||||
or NULL on failure.
|
||||
|
||||
|
@ -40,6 +40,7 @@ int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
|
||||
unsigned char *in, int ilen);
|
||||
|
||||
COMP_METHOD *COMP_zlib(void);
|
||||
COMP_METHOD *COMP_zlib_oneshot(void);
|
||||
COMP_METHOD *COMP_brotli(void);
|
||||
COMP_METHOD *COMP_brotli_oneshot(void);
|
||||
COMP_METHOD *COMP_zstd(void);
|
||||
|
@ -101,7 +101,7 @@ __owur static OSSL_COMP_CERT *OSSL_COMP_CERT_from_uncompressed_data(unsigned cha
|
||||
method = COMP_brotli_oneshot();
|
||||
break;
|
||||
case TLSEXT_comp_cert_zlib:
|
||||
method = COMP_zlib();
|
||||
method = COMP_zlib_oneshot();
|
||||
break;
|
||||
case TLSEXT_comp_cert_zstd:
|
||||
method = COMP_zstd_oneshot();
|
||||
|
@ -3689,7 +3689,7 @@ CON_FUNC_RETURN tls_construct_client_compressed_certificate(SSL_CONNECTION *sc,
|
||||
|
||||
switch (alg) {
|
||||
case TLSEXT_comp_cert_zlib:
|
||||
method = COMP_zlib();
|
||||
method = COMP_zlib_oneshot();
|
||||
break;
|
||||
case TLSEXT_comp_cert_brotli:
|
||||
method = COMP_brotli_oneshot();
|
||||
|
@ -2520,7 +2520,7 @@ MSG_PROCESS_RETURN tls13_process_compressed_certificate(SSL_CONNECTION *sc,
|
||||
}
|
||||
switch (comp_alg) {
|
||||
case TLSEXT_comp_cert_zlib:
|
||||
method = COMP_zlib();
|
||||
method = COMP_zlib_oneshot();
|
||||
break;
|
||||
case TLSEXT_comp_cert_brotli:
|
||||
method = COMP_brotli_oneshot();
|
||||
|
@ -5480,3 +5480,4 @@ COMP_zstd_oneshot ? 3_2_0 EXIST::FUNCTION:COMP
|
||||
BIO_f_zstd ? 3_2_0 EXIST::FUNCTION:COMP
|
||||
d2i_PUBKEY_ex_fp ? 3_2_0 EXIST::FUNCTION:STDIO
|
||||
d2i_PUBKEY_ex_bio ? 3_2_0 EXIST::FUNCTION:
|
||||
COMP_zlib_oneshot ? 3_2_0 EXIST::FUNCTION:COMP
|
||||
|
Loading…
x
Reference in New Issue
Block a user