diff options
Diffstat (limited to 'Cryptlib/OpenSSL/crypto/comp/c_zlib.c')
-rw-r--r-- | Cryptlib/OpenSSL/crypto/comp/c_zlib.c | 316 |
1 files changed, 232 insertions, 84 deletions
diff --git a/Cryptlib/OpenSSL/crypto/comp/c_zlib.c b/Cryptlib/OpenSSL/crypto/comp/c_zlib.c index 2f38c2e9..9c32614d 100644 --- a/Cryptlib/OpenSSL/crypto/comp/c_zlib.c +++ b/Cryptlib/OpenSSL/crypto/comp/c_zlib.c @@ -1,21 +1,9 @@ -/* - * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/objects.h> -#include "internal/comp.h" +#include <openssl/comp.h> #include <openssl/err.h> -#include "internal/cryptlib_int.h" -#include "internal/bio.h" -#include "comp_lcl.h" COMP_METHOD *COMP_zlib(void); @@ -26,6 +14,8 @@ static COMP_METHOD zlib_method_nozlib = { NULL, NULL, NULL, + NULL, + NULL, }; #ifndef ZLIB @@ -43,12 +33,14 @@ static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, unsigned int olen, unsigned char *in, unsigned int ilen); -/* memory allocations functions for zlib initialisation */ +/* memory allocations functions for zlib intialization */ static void *zlib_zalloc(void *opaque, unsigned int no, unsigned int size) { void *p; - p = OPENSSL_zalloc(no * size); + p = OPENSSL_malloc(no * size); + if (p) + memset(p, 0, no * size); return p; } @@ -57,6 +49,28 @@ static void zlib_zfree(void *opaque, void *address) OPENSSL_free(address); } +# if 0 +static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen); +static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen); + +static int zz_uncompress(Bytef *dest, uLongf * destLen, const Bytef *source, + uLong sourceLen); + +static COMP_METHOD zlib_stateless_method = { + NID_zlib_compression, + LN_zlib_compression, + NULL, + NULL, + zlib_compress_block, + zlib_expand_block, + NULL, + NULL, +}; +# endif static COMP_METHOD zlib_stateful_method = { NID_zlib_compression, @@ -64,7 +78,9 @@ static COMP_METHOD zlib_stateful_method = { zlib_stateful_init, zlib_stateful_finish, zlib_stateful_compress_block, - zlib_stateful_expand_block + zlib_stateful_expand_block, + NULL, + NULL, }; /* @@ -79,7 +95,7 @@ static COMP_METHOD zlib_stateful_method = { * OPENSSL_SYS_WIN32) */ # ifdef ZLIB_SHARED -# include "internal/dso.h" +# include <openssl/dso.h> /* Function pointers */ typedef int (*compress_ft) (Bytef *dest, uLongf * destLen, @@ -120,10 +136,13 @@ struct zlib_state { z_stream ostream; }; +static int zlib_stateful_ex_idx = -1; + static int zlib_stateful_init(COMP_CTX *ctx) { int err; - struct zlib_state *state = OPENSSL_zalloc(sizeof(*state)); + struct zlib_state *state = + (struct zlib_state *)OPENSSL_malloc(sizeof(struct zlib_state)); if (state == NULL) goto err; @@ -133,6 +152,8 @@ static int zlib_stateful_init(COMP_CTX *ctx) state->istream.opaque = Z_NULL; state->istream.next_in = Z_NULL; state->istream.next_out = Z_NULL; + state->istream.avail_in = 0; + state->istream.avail_out = 0; err = inflateInit_(&state->istream, ZLIB_VERSION, sizeof(z_stream)); if (err != Z_OK) goto err; @@ -142,24 +163,31 @@ static int zlib_stateful_init(COMP_CTX *ctx) state->ostream.opaque = Z_NULL; state->ostream.next_in = Z_NULL; state->ostream.next_out = Z_NULL; + state->ostream.avail_in = 0; + state->ostream.avail_out = 0; err = deflateInit_(&state->ostream, Z_DEFAULT_COMPRESSION, ZLIB_VERSION, sizeof(z_stream)); if (err != Z_OK) goto err; - ctx->data = state; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data); + CRYPTO_set_ex_data(&ctx->ex_data, zlib_stateful_ex_idx, state); return 1; err: - OPENSSL_free(state); + if (state) + OPENSSL_free(state); return 0; } static void zlib_stateful_finish(COMP_CTX *ctx) { - struct zlib_state *state = ctx->data; + struct zlib_state *state = + (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, + zlib_stateful_ex_idx); inflateEnd(&state->istream); deflateEnd(&state->ostream); OPENSSL_free(state); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data); } static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, @@ -167,7 +195,9 @@ static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, unsigned int ilen) { int err = Z_OK; - struct zlib_state *state = ctx->data; + struct zlib_state *state = + (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, + zlib_stateful_ex_idx); if (state == NULL) return -1; @@ -180,6 +210,11 @@ static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, err = deflate(&state->ostream, Z_SYNC_FLUSH); if (err != Z_OK) return -1; +# ifdef DEBUG_ZLIB + fprintf(stderr, "compress(%4d)->%4d %s\n", + ilen, olen - state->ostream.avail_out, + (ilen != olen - state->ostream.avail_out) ? "zlib" : "clear"); +# endif return olen - state->ostream.avail_out; } @@ -188,7 +223,10 @@ static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, unsigned int ilen) { int err = Z_OK; - struct zlib_state *state = ctx->data; + + struct zlib_state *state = + (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, + zlib_stateful_ex_idx); if (state == NULL) return 0; @@ -201,9 +239,105 @@ static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, err = inflate(&state->istream, Z_SYNC_FLUSH); if (err != Z_OK) return -1; +# ifdef DEBUG_ZLIB + fprintf(stderr, "expand(%4d)->%4d %s\n", + ilen, olen - state->istream.avail_out, + (ilen != olen - state->istream.avail_out) ? "zlib" : "clear"); +# endif return olen - state->istream.avail_out; } +# if 0 +static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen) +{ + unsigned long l; + int i; + int clear = 1; + + if (ilen > 128) { + out[0] = 1; + l = olen - 1; + i = compress(&(out[1]), &l, in, (unsigned long)ilen); + if (i != Z_OK) + return (-1); + if (ilen > l) { + clear = 0; + l++; + } + } + if (clear) { + out[0] = 0; + memcpy(&(out[1]), in, ilen); + l = ilen + 1; + } +# ifdef DEBUG_ZLIB + fprintf(stderr, "compress(%4d)->%4d %s\n", + ilen, (int)l, (clear) ? "clear" : "zlib"); +# endif + return ((int)l); +} + +static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen) +{ + unsigned long l; + int i; + + if (in[0]) { + l = olen; + i = zz_uncompress(out, &l, &(in[1]), (unsigned long)ilen - 1); + if (i != Z_OK) + return (-1); + } else { + memcpy(out, &(in[1]), ilen - 1); + l = ilen - 1; + } +# ifdef DEBUG_ZLIB + fprintf(stderr, "expand (%4d)->%4d %s\n", + ilen, (int)l, in[0] ? "zlib" : "clear"); +# endif + return ((int)l); +} + +static int zz_uncompress(Bytef *dest, uLongf * destLen, const Bytef *source, + uLong sourceLen) +{ + z_stream stream; + int err; + + stream.next_in = (Bytef *)source; + stream.avail_in = (uInt) sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong) stream.avail_in != sourceLen) + return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt) * destLen; + if ((uLong) stream.avail_out != *destLen) + return Z_BUF_ERROR; + + stream.zalloc = (alloc_func) 0; + stream.zfree = (free_func) 0; + + err = inflateInit_(&stream, ZLIB_VERSION, sizeof(z_stream)); + if (err != Z_OK) + return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} +# endif + #endif COMP_METHOD *COMP_zlib(void) @@ -211,19 +345,12 @@ COMP_METHOD *COMP_zlib(void) COMP_METHOD *meth = &zlib_method_nozlib; #ifdef ZLIB_SHARED - /* LIBZ may be externally defined, and we should respect that value */ -# ifndef LIBZ -# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) -# define LIBZ "ZLIB1" -# elif defined(OPENSSL_SYS_VMS) -# define LIBZ "LIBZ" -# else -# define LIBZ "z" -# endif -# endif - if (!zlib_loaded) { - zlib_dso = DSO_load(NULL, LIBZ, NULL, 0); +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) + zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0); +# else + zlib_dso = DSO_load(NULL, "z", NULL, 0); +# endif if (zlib_dso != NULL) { p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress"); p_inflateEnd @@ -242,24 +369,39 @@ COMP_METHOD *COMP_zlib(void) && p_inflateInit_ && p_deflateEnd && p_deflate && p_deflateInit_ && p_zError) zlib_loaded++; - - if (!OPENSSL_init_crypto(OPENSSL_INIT_ZLIB, NULL)) { - comp_zlib_cleanup_int(); - return meth; - } - if (zlib_loaded) - meth = &zlib_stateful_method; } } #endif -#if defined(ZLIB) - meth = &zlib_stateful_method; +#ifdef ZLIB_SHARED + if (zlib_loaded) +#endif +#if defined(ZLIB) || defined(ZLIB_SHARED) + { + /* + * init zlib_stateful_ex_idx here so that in a multi-process + * application it's enough to intialize openssl before forking (idx + * will be inherited in all the children) + */ + if (zlib_stateful_ex_idx == -1) { + CRYPTO_w_lock(CRYPTO_LOCK_COMP); + if (zlib_stateful_ex_idx == -1) + zlib_stateful_ex_idx = + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP, + 0, NULL, NULL, NULL, NULL); + CRYPTO_w_unlock(CRYPTO_LOCK_COMP); + if (zlib_stateful_ex_idx == -1) + goto err; + } + + meth = &zlib_stateful_method; + } + err: #endif return (meth); } -void comp_zlib_cleanup_int(void) +void COMP_zlib_cleanup(void) { #ifdef ZLIB_SHARED if (zlib_dso != NULL) @@ -294,7 +436,7 @@ static int bio_zlib_write(BIO *b, const char *in, int inl); static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr); static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp); -static const BIO_METHOD bio_meth_zlib = { +static BIO_METHOD bio_meth_zlib = { BIO_TYPE_COMP, "zlib", bio_zlib_write, @@ -307,7 +449,7 @@ static const BIO_METHOD bio_meth_zlib = { bio_zlib_callback_ctrl }; -const BIO_METHOD *BIO_f_zlib(void) +BIO_METHOD *BIO_f_zlib(void) { return &bio_meth_zlib; } @@ -322,21 +464,32 @@ static int bio_zlib_new(BIO *bi) return 0; } # endif - ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) { + ctx = OPENSSL_malloc(sizeof(BIO_ZLIB_CTX)); + if (!ctx) { COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE); return 0; } + ctx->ibuf = NULL; + ctx->obuf = NULL; ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE; ctx->obufsize = ZLIB_DEFAULT_BUFSIZE; ctx->zin.zalloc = Z_NULL; ctx->zin.zfree = Z_NULL; + ctx->zin.next_in = NULL; + ctx->zin.avail_in = 0; + ctx->zin.next_out = NULL; + ctx->zin.avail_out = 0; ctx->zout.zalloc = Z_NULL; ctx->zout.zfree = Z_NULL; + ctx->zout.next_in = NULL; + ctx->zout.avail_in = 0; + ctx->zout.next_out = NULL; + ctx->zout.avail_out = 0; + ctx->odone = 0; ctx->comp_level = Z_DEFAULT_COMPRESSION; - BIO_set_init(bi, 1); - BIO_set_data(bi, ctx); - + bi->init = 1; + bi->ptr = (char *)ctx; + bi->flags = 0; return 1; } @@ -345,7 +498,7 @@ static int bio_zlib_free(BIO *bi) BIO_ZLIB_CTX *ctx; if (!bi) return 0; - ctx = BIO_get_data(bi); + ctx = (BIO_ZLIB_CTX *) bi->ptr; if (ctx->ibuf) { /* Destroy decompress context */ inflateEnd(&ctx->zin); @@ -357,9 +510,9 @@ static int bio_zlib_free(BIO *bi) OPENSSL_free(ctx->obuf); } OPENSSL_free(ctx); - BIO_set_data(bi, NULL); - BIO_set_init(bi, 0); - + bi->ptr = NULL; + bi->init = 0; + bi->flags = 0; return 1; } @@ -368,16 +521,14 @@ static int bio_zlib_read(BIO *b, char *out, int outl) BIO_ZLIB_CTX *ctx; int ret; z_stream *zin; - BIO *next = BIO_next(b); - if (!out || !outl) return 0; - ctx = BIO_get_data(b); + ctx = (BIO_ZLIB_CTX *) b->ptr; zin = &ctx->zin; BIO_clear_retry_flags(b); if (!ctx->ibuf) { ctx->ibuf = OPENSSL_malloc(ctx->ibufsize); - if (ctx->ibuf == NULL) { + if (!ctx->ibuf) { COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE); return 0; } @@ -407,7 +558,7 @@ static int bio_zlib_read(BIO *b, char *out, int outl) * No data in input buffer try to read some in, if an error then * return the total data read. */ - ret = BIO_read(next, ctx->ibuf, ctx->ibufsize); + ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize); if (ret <= 0) { /* Total data read */ int tot = outl - zin->avail_out; @@ -426,11 +577,9 @@ static int bio_zlib_write(BIO *b, const char *in, int inl) BIO_ZLIB_CTX *ctx; int ret; z_stream *zout; - BIO *next = BIO_next(b); - if (!in || !inl) return 0; - ctx = BIO_get_data(b); + ctx = (BIO_ZLIB_CTX *) b->ptr; if (ctx->odone) return 0; zout = &ctx->zout; @@ -438,7 +587,7 @@ static int bio_zlib_write(BIO *b, const char *in, int inl) if (!ctx->obuf) { ctx->obuf = OPENSSL_malloc(ctx->obufsize); /* Need error here */ - if (ctx->obuf == NULL) { + if (!ctx->obuf) { COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE); return 0; } @@ -454,7 +603,7 @@ static int bio_zlib_write(BIO *b, const char *in, int inl) for (;;) { /* If data in output buffer write it first */ while (ctx->ocount) { - ret = BIO_write(next, ctx->optr, ctx->ocount); + ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount); if (ret <= 0) { /* Total data written */ int tot = inl - zout->avail_in; @@ -493,9 +642,7 @@ static int bio_zlib_flush(BIO *b) BIO_ZLIB_CTX *ctx; int ret; z_stream *zout; - BIO *next = BIO_next(b); - - ctx = BIO_get_data(b); + ctx = (BIO_ZLIB_CTX *) b->ptr; /* If no data written or already flush show success */ if (!ctx->obuf || (ctx->odone && !ctx->ocount)) return 1; @@ -507,7 +654,7 @@ static int bio_zlib_flush(BIO *b) for (;;) { /* If data in output buffer write it first */ while (ctx->ocount) { - ret = BIO_write(next, ctx->optr, ctx->ocount); + ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount); if (ret <= 0) { BIO_copy_next_retry(b); return ret; @@ -542,11 +689,9 @@ static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) BIO_ZLIB_CTX *ctx; int ret, *ip; int ibs, obs; - BIO *next = BIO_next(b); - - if (next == NULL) + if (!b->next_bio) return 0; - ctx = BIO_get_data(b); + ctx = (BIO_ZLIB_CTX *) b->ptr; switch (cmd) { case BIO_CTRL_RESET: @@ -558,7 +703,7 @@ static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_FLUSH: ret = bio_zlib_flush(b); if (ret > 0) - ret = BIO_flush(next); + ret = BIO_flush(b->next_bio); break; case BIO_C_SET_BUFF_SIZE: @@ -576,14 +721,18 @@ static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) } if (ibs != -1) { - OPENSSL_free(ctx->ibuf); - ctx->ibuf = NULL; + if (ctx->ibuf) { + OPENSSL_free(ctx->ibuf); + ctx->ibuf = NULL; + } ctx->ibufsize = ibs; } if (obs != -1) { - OPENSSL_free(ctx->obuf); - ctx->obuf = NULL; + if (ctx->obuf) { + OPENSSL_free(ctx->obuf); + ctx->obuf = NULL; + } ctx->obufsize = obs; } ret = 1; @@ -591,12 +740,12 @@ static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_C_DO_STATE_MACHINE: BIO_clear_retry_flags(b); - ret = BIO_ctrl(next, cmd, num, ptr); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); BIO_copy_next_retry(b); break; default: - ret = BIO_ctrl(next, cmd, num, ptr); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); break; } @@ -606,10 +755,9 @@ static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) { - BIO *next = BIO_next(b); - if (next == NULL) + if (!b->next_bio) return 0; - return BIO_callback_ctrl(next, cmd, fp); + return BIO_callback_ctrl(b->next_bio, cmd, fp); } #endif |