summaryrefslogtreecommitdiff
path: root/Cryptlib/OpenSSL/crypto/comp/c_zlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'Cryptlib/OpenSSL/crypto/comp/c_zlib.c')
-rw-r--r--Cryptlib/OpenSSL/crypto/comp/c_zlib.c316
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