summaryrefslogtreecommitdiff
path: root/usr/src/common/openssl/crypto/comp/c_zlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/common/openssl/crypto/comp/c_zlib.c')
-rw-r--r--usr/src/common/openssl/crypto/comp/c_zlib.c234
1 files changed, 227 insertions, 7 deletions
diff --git a/usr/src/common/openssl/crypto/comp/c_zlib.c b/usr/src/common/openssl/crypto/comp/c_zlib.c
index 8c0876151a..8263f7315d 100644
--- a/usr/src/common/openssl/crypto/comp/c_zlib.c
+++ b/usr/src/common/openssl/crypto/comp/c_zlib.c
@@ -3,6 +3,7 @@
#include <string.h>
#include <openssl/objects.h>
#include <openssl/comp.h>
+#include <openssl/err.h>
COMP_METHOD *COMP_zlib(void );
@@ -23,6 +24,14 @@ static COMP_METHOD zlib_method_nozlib={
#include <zlib.h>
+static int zlib_stateful_init(COMP_CTX *ctx);
+static void zlib_stateful_finish(COMP_CTX *ctx);
+static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in, unsigned int ilen);
+static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in, unsigned int ilen);
+
+#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,
@@ -31,7 +40,7 @@ static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
uLong sourceLen);
-static COMP_METHOD zlib_method={
+static COMP_METHOD zlib_stateless_method={
NID_zlib_compression,
LN_zlib_compression,
NULL,
@@ -41,6 +50,18 @@ static COMP_METHOD zlib_method={
NULL,
NULL,
};
+#endif
+
+static COMP_METHOD zlib_stateful_method={
+ NID_zlib_compression,
+ LN_zlib_compression,
+ zlib_stateful_init,
+ zlib_stateful_finish,
+ zlib_stateful_compress_block,
+ zlib_stateful_expand_block,
+ NULL,
+ NULL,
+ };
/*
* When OpenSSL is built on Windows, we do not want to require that
@@ -52,7 +73,9 @@ static COMP_METHOD zlib_method={
# include <windows.h>
# define Z_CALLCONV _stdcall
-# define ZLIB_SHARED
+# ifndef ZLIB_SHARED
+# define ZLIB_SHARED
+# endif
#else
# define Z_CALLCONV
#endif /* !(OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32) */
@@ -61,12 +84,18 @@ static COMP_METHOD zlib_method={
#include <openssl/dso.h>
/* Prototypes for built in stubs */
+#if 0
static int stub_compress(Bytef *dest,uLongf *destLen,
const Bytef *source, uLong sourceLen);
+#endif
static int stub_inflateEnd(z_streamp strm);
static int stub_inflate(z_streamp strm, int flush);
static int stub_inflateInit_(z_streamp strm, const char * version,
int stream_size);
+static int stub_deflateEnd(z_streamp strm);
+static int stub_deflate(z_streamp strm, int flush);
+static int stub_deflateInit_(z_streamp strm, int level,
+ const char * version, int stream_size);
/* Function pointers */
typedef int (Z_CALLCONV *compress_ft)(Bytef *dest,uLongf *destLen,
@@ -75,10 +104,17 @@ typedef int (Z_CALLCONV *inflateEnd_ft)(z_streamp strm);
typedef int (Z_CALLCONV *inflate_ft)(z_streamp strm, int flush);
typedef int (Z_CALLCONV *inflateInit__ft)(z_streamp strm,
const char * version, int stream_size);
+typedef int (Z_CALLCONV *deflateEnd_ft)(z_streamp strm);
+typedef int (Z_CALLCONV *deflate_ft)(z_streamp strm, int flush);
+typedef int (Z_CALLCONV *deflateInit__ft)(z_streamp strm, int level,
+ const char * version, int stream_size);
static compress_ft p_compress=NULL;
static inflateEnd_ft p_inflateEnd=NULL;
static inflate_ft p_inflate=NULL;
static inflateInit__ft p_inflateInit_=NULL;
+static deflateEnd_ft p_deflateEnd=NULL;
+static deflate_ft p_deflate=NULL;
+static deflateInit__ft p_deflateInit_=NULL;
static int zlib_loaded = 0; /* only attempt to init func pts once */
static DSO *zlib_dso = NULL;
@@ -87,10 +123,143 @@ static DSO *zlib_dso = NULL;
#define inflateEnd stub_inflateEnd
#define inflate stub_inflate
#define inflateInit_ stub_inflateInit_
+#define deflateEnd stub_deflateEnd
+#define deflate stub_deflate
+#define deflateInit_ stub_deflateInit_
#endif /* ZLIB_SHARED */
+struct zlib_state
+ {
+ z_stream istream;
+ z_stream ostream;
+ };
+
+static int zlib_stateful_ex_idx = -1;
+
+static void zlib_stateful_free_ex_data(void *obj, void *item,
+ CRYPTO_EX_DATA *ad, int ind,long argl, void *argp)
+ {
+ struct zlib_state *state = (struct zlib_state *)item;
+ inflateEnd(&state->istream);
+ deflateEnd(&state->ostream);
+ OPENSSL_free(state);
+ }
+
+static int zlib_stateful_init(COMP_CTX *ctx)
+ {
+ int err;
+ struct zlib_state *state =
+ (struct zlib_state *)OPENSSL_malloc(sizeof(struct zlib_state));
+
+ if (state == NULL)
+ goto err;
+
+ state->istream.zalloc = Z_NULL;
+ state->istream.zfree = Z_NULL;
+ 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;
+
+ state->ostream.zalloc = Z_NULL;
+ state->ostream.zfree = Z_NULL;
+ 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;
+
+ CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
+ 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,zlib_stateful_free_ex_data);
+ CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
+ if (zlib_stateful_ex_idx == -1)
+ goto err;
+ }
+ CRYPTO_set_ex_data(&ctx->ex_data,zlib_stateful_ex_idx,state);
+ return 1;
+ err:
+ if (state) OPENSSL_free(state);
+ return 0;
+ }
+
+static void zlib_stateful_finish(COMP_CTX *ctx)
+ {
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
+ }
+
+static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in, unsigned int ilen)
+ {
+ int err = Z_OK;
+ struct zlib_state *state =
+ (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
+ zlib_stateful_ex_idx);
+
+ if (state == NULL)
+ return -1;
+
+ state->ostream.next_in = in;
+ state->ostream.avail_in = ilen;
+ state->ostream.next_out = out;
+ state->ostream.avail_out = olen;
+ if (ilen > 0)
+ 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;
+ }
+
+static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in, unsigned int ilen)
+ {
+ int err = Z_OK;
+
+ struct zlib_state *state =
+ (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
+ zlib_stateful_ex_idx);
+
+ if (state == NULL)
+ return 0;
+
+ state->istream.next_in = in;
+ state->istream.avail_in = ilen;
+ state->istream.next_out = out;
+ state->istream.avail_out = olen;
+ if (ilen > 0)
+ 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 int olen, unsigned char *in, unsigned int ilen)
{
unsigned long l;
int i;
@@ -123,7 +292,7 @@ static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
}
static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
- unsigned int olen, unsigned char *in, unsigned int ilen)
+ unsigned int olen, unsigned char *in, unsigned int ilen)
{
unsigned long l;
int i;
@@ -165,7 +334,8 @@ static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source,
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
- err = inflateInit(&stream);
+ err = inflateInit_(&stream,
+ ZLIB_VERSION, sizeof(z_stream));
if (err != Z_OK) return err;
err = inflate(&stream, Z_FINISH);
@@ -178,6 +348,7 @@ static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source,
err = inflateEnd(&stream);
return err;
}
+#endif
#endif
@@ -189,7 +360,17 @@ COMP_METHOD *COMP_zlib(void)
if (!zlib_loaded)
{
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
- zlib_dso = DSO_load(NULL, "ZLIB", NULL, 0);
+ zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0);
+ if (!zlib_dso)
+ {
+ zlib_dso = DSO_load(NULL, "ZLIB", NULL, 0);
+ if (zlib_dso)
+ {
+ /* Clear the errors from the first failed
+ DSO_load() */
+ ERR_clear_error();
+ }
+ }
#else
zlib_dso = DSO_load(NULL, "z", NULL, 0);
#endif
@@ -207,19 +388,29 @@ COMP_METHOD *COMP_zlib(void)
p_inflateInit_
= (inflateInit__ft) DSO_bind_func(zlib_dso,
"inflateInit_");
+ p_deflateEnd
+ = (deflateEnd_ft) DSO_bind_func(zlib_dso,
+ "deflateEnd");
+ p_deflate
+ = (deflate_ft) DSO_bind_func(zlib_dso,
+ "deflate");
+ p_deflateInit_
+ = (deflateInit__ft) DSO_bind_func(zlib_dso,
+ "deflateInit_");
zlib_loaded++;
}
}
#endif
#if defined(ZLIB) || defined(ZLIB_SHARED)
- meth = &zlib_method;
+ meth = &zlib_stateful_method;
#endif
return(meth);
}
#ifdef ZLIB_SHARED
+#if 0
/* Stubs for each function to be dynamicly loaded */
static int
stub_compress(Bytef *dest,uLongf *destLen,const Bytef *source, uLong sourceLen)
@@ -229,6 +420,7 @@ stub_compress(Bytef *dest,uLongf *destLen,const Bytef *source, uLong sourceLen)
else
return(Z_MEM_ERROR);
}
+#endif
static int
stub_inflateEnd(z_streamp strm)
@@ -257,4 +449,32 @@ stub_inflateInit_(z_streamp strm, const char * version, int stream_size)
return(Z_MEM_ERROR);
}
+static int
+stub_deflateEnd(z_streamp strm)
+ {
+ if ( p_deflateEnd )
+ return(p_deflateEnd(strm));
+ else
+ return(Z_MEM_ERROR);
+ }
+
+static int
+stub_deflate(z_streamp strm, int flush)
+ {
+ if ( p_deflate )
+ return(p_deflate(strm,flush));
+ else
+ return(Z_MEM_ERROR);
+ }
+
+static int
+stub_deflateInit_(z_streamp strm, int level,
+ const char * version, int stream_size)
+ {
+ if ( p_deflateInit_ )
+ return(p_deflateInit_(strm,level,version,stream_size));
+ else
+ return(Z_MEM_ERROR);
+ }
+
#endif /* ZLIB_SHARED */