diff -r 000000000000 -r bde4ae8d615e os/ossrv/ssl/libcrypto/src/crypto/comp/c_zlib.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/ossrv/ssl/libcrypto/src/crypto/comp/c_zlib.c Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,646 @@ +/* +Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +* Neither the name of Nokia Corporation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Description: +*/ + +#include +#include +#include +#include +#include +#include +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__))) +#include "libcrypto_wsd_macros.h" +#include "libcrypto_wsd.h" +#endif + + +COMP_METHOD *COMP_zlib(void ); +#ifndef EMULATOR +static COMP_METHOD zlib_method_nozlib={ + NID_undef, + "(undef)", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }; +#else//EMULATOR + GET_STATIC_VAR_FROM_TLS(zlib_method_nozlib,c_zlib,COMP_METHOD) + #define zlib_method_nozlib (*GET_WSD_VAR_NAME(zlib_method_nozlib,c_zlib, s)()) + const COMP_METHOD temp_s_zlib_method_nozlib={ + NID_undef, + "(undef)", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }; +#endif//EMULATOR + +#ifndef ZLIB +#undef ZLIB_SHARED +#else + +#include + +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, + 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 +#ifndef EMULATOR +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, + }; +#else//EMULATOR + GET_STATIC_VAR_FROM_TLS(zlib_stateful_method,c_zlib,COMP_METHOD) + #define zlib_stateful_method (*GET_WSD_VAR_NAME(zlib_stateful_method,c_zlib, s)()) + const COMP_METHOD temp_s_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, + }; +#endif//EMULATOR + +/* + * When OpenSSL is built on Windows, we do not want to require that + * the ZLIB.DLL be available in order for the OpenSSL DLLs to + * work. Therefore, all ZLIB routines are loaded at run time + * and we do not link to a .LIB file. + */ +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +# include + +# define Z_CALLCONV _stdcall +# ifndef ZLIB_SHARED +# define ZLIB_SHARED +# endif +#else +# define Z_CALLCONV +#endif /* !(OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32) */ + +#ifdef ZLIB_SHARED +#include + +/* 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); + +#ifndef EMULATOR +/* Function pointers */ +typedef int (Z_CALLCONV *compress_ft)(Bytef *dest,uLongf *destLen, + const Bytef *source, uLong sourceLen); +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); +#endif + +#ifndef EMULATOR +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; +#else +GET_STATIC_VAR_FROM_TLS(p_compress,c_zlib,compress_ft) +#define p_compress (*GET_WSD_VAR_NAME(p_compress,c_zlib, s)()) + +GET_STATIC_VAR_FROM_TLS(p_inflateEnd,c_zlib,inflateEnd_ft) +#define p_inflateEnd (*GET_WSD_VAR_NAME(p_inflateEnd,c_zlib, s)()) + + +GET_STATIC_VAR_FROM_TLS(p_inflate,c_zlib,inflate_ft) +#define p_inflate (*GET_WSD_VAR_NAME(p_inflate,c_zlib, s)()) + +GET_STATIC_VAR_FROM_TLS(p_inflateInit_,c_zlib,inflateInit__ft) +#define p_inflateInit_ (*GET_WSD_VAR_NAME(p_inflateInit_,c_zlib, s)()) + +GET_STATIC_VAR_FROM_TLS(p_deflateEnd,c_zlib,deflateEnd_ft) +#define p_deflateEnd (*GET_WSD_VAR_NAME(p_deflateEnd,c_zlib, s)()) + +GET_STATIC_VAR_FROM_TLS(p_deflate,c_zlib,deflate_ft) +#define p_deflate (*GET_WSD_VAR_NAME(p_deflate,c_zlib, s)()) + +GET_STATIC_VAR_FROM_TLS(p_deflateInit_,c_zlib,deflateInit__ft) +#define p_deflateInit_ (*GET_WSD_VAR_NAME(p_deflateInit_,c_zlib, s)()) + + +GET_STATIC_VAR_FROM_TLS(zlib_loaded ,c_zlib,int) +#define zlib_loaded (*GET_WSD_VAR_NAME(zlib_loaded ,c_zlib, s)()) + +GET_STATIC_VAR_FROM_TLS(zlib_dso ,c_zlib,DSO *) +#define zlib_dso (*GET_WSD_VAR_NAME(zlib_dso ,c_zlib, s)()) + +#endif + +#define compress stub_compress +#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; + }; + +#ifndef EMULATOR +static int zlib_stateful_ex_idx = -1; +#else +GET_STATIC_VAR_FROM_TLS(zlib_stateful_ex_idx,c_zlib,int) +#define zlib_stateful_ex_idx (*GET_WSD_VAR_NAME(zlib_stateful_ex_idx,c_zlib, s)()) +#endif + +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 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 + +EXPORT_C COMP_METHOD *COMP_zlib(void) + { + COMP_METHOD *meth = &zlib_method_nozlib; + +#ifdef ZLIB_SHARED + if (!zlib_loaded) + { +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) + 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 +#ifndef SYMBIAN + if (zlib_dso != NULL) + { + p_compress + = (compress_ft) DSO_bind_func(zlib_dso, + "compress"); + 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_"); + 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++; + } +#else +#ifdef LIBDL_ONLY_ORDINALS +#define zlib_compress "2" +#define zlib_inflateEnd "34" +#define zlib_inflate "33" +#define zlib_inflateInit_ "36" +#define zlib_deflateEnd "9" +#define zlib_deflate "6" +#define zlib_deflateInit_ "11" +#else +#define zlib_compress compress +#define zlib_inflateEnd inflateEnd +#define zlib_inflate inflate +#define zlib_inflateInit_ inflateInit_ +#define zlib_deflateEnd deflateEnd +#define zlib_deflate deflate +#define zlib_deflateInit_ deflateInit_ +#endif + if (zlib_dso != NULL) + { + p_compress + = (compress_ft) DSO_bind_func(zlib_dso, + (const char*)zlib_compress); + p_inflateEnd + = (inflateEnd_ft) DSO_bind_func(zlib_dso, + (const char*)zlib_inflateEnd); + p_inflate + = (inflate_ft) DSO_bind_func(zlib_dso, + (const char*)zlib_inflate); + p_inflateInit_ + = (inflateInit__ft) DSO_bind_func(zlib_dso, + (const char*)zlib_inflateInit_); + p_deflateEnd + = (deflateEnd_ft) DSO_bind_func(zlib_dso, + (const char*)zlib_deflateEnd); + p_deflate + = (deflate_ft) DSO_bind_func(zlib_dso, + (const char*)zlib_deflate); + p_deflateInit_ + = (deflateInit__ft) DSO_bind_func(zlib_dso, + (const char*)zlib_deflateInit_); + zlib_loaded++; + } + +#endif + } + +#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,zlib_stateful_free_ex_data); + CRYPTO_w_unlock(CRYPTO_LOCK_COMP); + if (zlib_stateful_ex_idx == -1) + goto err; + } + + meth = &zlib_stateful_method; + } +err: +#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) + { + if (p_compress) + return(p_compress(dest,destLen,source,sourceLen)); + else + return(Z_MEM_ERROR); + } +#endif + +static int +stub_inflateEnd(z_streamp strm) + { + if ( p_inflateEnd ) + return(p_inflateEnd(strm)); + else + return(Z_MEM_ERROR); + } + +static int +stub_inflate(z_streamp strm, int flush) + { + if ( p_inflate ) + return(p_inflate(strm,flush)); + else + return(Z_MEM_ERROR); + } + +static int +stub_inflateInit_(z_streamp strm, const char * version, int stream_size) + { + if ( p_inflateInit_ ) + return(p_inflateInit_(strm,version,stream_size)); + else + 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 */