1*0Sstevel@tonic-gate #include <stdio.h> 2*0Sstevel@tonic-gate #include <stdlib.h> 3*0Sstevel@tonic-gate #include <string.h> 4*0Sstevel@tonic-gate #include <openssl/objects.h> 5*0Sstevel@tonic-gate #include <openssl/comp.h> 6*0Sstevel@tonic-gate 7*0Sstevel@tonic-gate COMP_METHOD *COMP_zlib(void ); 8*0Sstevel@tonic-gate 9*0Sstevel@tonic-gate static COMP_METHOD zlib_method_nozlib={ 10*0Sstevel@tonic-gate NID_undef, 11*0Sstevel@tonic-gate "(undef)", 12*0Sstevel@tonic-gate NULL, 13*0Sstevel@tonic-gate NULL, 14*0Sstevel@tonic-gate NULL, 15*0Sstevel@tonic-gate NULL, 16*0Sstevel@tonic-gate NULL, 17*0Sstevel@tonic-gate NULL, 18*0Sstevel@tonic-gate }; 19*0Sstevel@tonic-gate 20*0Sstevel@tonic-gate #ifndef ZLIB 21*0Sstevel@tonic-gate #undef ZLIB_SHARED 22*0Sstevel@tonic-gate #else 23*0Sstevel@tonic-gate 24*0Sstevel@tonic-gate #include <zlib.h> 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gate static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, 27*0Sstevel@tonic-gate unsigned int olen, unsigned char *in, unsigned int ilen); 28*0Sstevel@tonic-gate static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, 29*0Sstevel@tonic-gate unsigned int olen, unsigned char *in, unsigned int ilen); 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, 32*0Sstevel@tonic-gate uLong sourceLen); 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate static COMP_METHOD zlib_method={ 35*0Sstevel@tonic-gate NID_zlib_compression, 36*0Sstevel@tonic-gate LN_zlib_compression, 37*0Sstevel@tonic-gate NULL, 38*0Sstevel@tonic-gate NULL, 39*0Sstevel@tonic-gate zlib_compress_block, 40*0Sstevel@tonic-gate zlib_expand_block, 41*0Sstevel@tonic-gate NULL, 42*0Sstevel@tonic-gate NULL, 43*0Sstevel@tonic-gate }; 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gate /* 46*0Sstevel@tonic-gate * When OpenSSL is built on Windows, we do not want to require that 47*0Sstevel@tonic-gate * the ZLIB.DLL be available in order for the OpenSSL DLLs to 48*0Sstevel@tonic-gate * work. Therefore, all ZLIB routines are loaded at run time 49*0Sstevel@tonic-gate * and we do not link to a .LIB file. 50*0Sstevel@tonic-gate */ 51*0Sstevel@tonic-gate #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) 52*0Sstevel@tonic-gate # include <windows.h> 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate # define Z_CALLCONV _stdcall 55*0Sstevel@tonic-gate # define ZLIB_SHARED 56*0Sstevel@tonic-gate #else 57*0Sstevel@tonic-gate # define Z_CALLCONV 58*0Sstevel@tonic-gate #endif /* !(OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32) */ 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate #ifdef ZLIB_SHARED 61*0Sstevel@tonic-gate #include <openssl/dso.h> 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate /* Prototypes for built in stubs */ 64*0Sstevel@tonic-gate static int stub_compress(Bytef *dest,uLongf *destLen, 65*0Sstevel@tonic-gate const Bytef *source, uLong sourceLen); 66*0Sstevel@tonic-gate static int stub_inflateEnd(z_streamp strm); 67*0Sstevel@tonic-gate static int stub_inflate(z_streamp strm, int flush); 68*0Sstevel@tonic-gate static int stub_inflateInit_(z_streamp strm, const char * version, 69*0Sstevel@tonic-gate int stream_size); 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate /* Function pointers */ 72*0Sstevel@tonic-gate typedef int (Z_CALLCONV *compress_ft)(Bytef *dest,uLongf *destLen, 73*0Sstevel@tonic-gate const Bytef *source, uLong sourceLen); 74*0Sstevel@tonic-gate typedef int (Z_CALLCONV *inflateEnd_ft)(z_streamp strm); 75*0Sstevel@tonic-gate typedef int (Z_CALLCONV *inflate_ft)(z_streamp strm, int flush); 76*0Sstevel@tonic-gate typedef int (Z_CALLCONV *inflateInit__ft)(z_streamp strm, 77*0Sstevel@tonic-gate const char * version, int stream_size); 78*0Sstevel@tonic-gate static compress_ft p_compress=NULL; 79*0Sstevel@tonic-gate static inflateEnd_ft p_inflateEnd=NULL; 80*0Sstevel@tonic-gate static inflate_ft p_inflate=NULL; 81*0Sstevel@tonic-gate static inflateInit__ft p_inflateInit_=NULL; 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate static int zlib_loaded = 0; /* only attempt to init func pts once */ 84*0Sstevel@tonic-gate static DSO *zlib_dso = NULL; 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate #define compress stub_compress 87*0Sstevel@tonic-gate #define inflateEnd stub_inflateEnd 88*0Sstevel@tonic-gate #define inflate stub_inflate 89*0Sstevel@tonic-gate #define inflateInit_ stub_inflateInit_ 90*0Sstevel@tonic-gate #endif /* ZLIB_SHARED */ 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gate static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, 93*0Sstevel@tonic-gate unsigned int olen, unsigned char *in, unsigned int ilen) 94*0Sstevel@tonic-gate { 95*0Sstevel@tonic-gate unsigned long l; 96*0Sstevel@tonic-gate int i; 97*0Sstevel@tonic-gate int clear=1; 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gate if (ilen > 128) 100*0Sstevel@tonic-gate { 101*0Sstevel@tonic-gate out[0]=1; 102*0Sstevel@tonic-gate l=olen-1; 103*0Sstevel@tonic-gate i=compress(&(out[1]),&l,in,(unsigned long)ilen); 104*0Sstevel@tonic-gate if (i != Z_OK) 105*0Sstevel@tonic-gate return(-1); 106*0Sstevel@tonic-gate if (ilen > l) 107*0Sstevel@tonic-gate { 108*0Sstevel@tonic-gate clear=0; 109*0Sstevel@tonic-gate l++; 110*0Sstevel@tonic-gate } 111*0Sstevel@tonic-gate } 112*0Sstevel@tonic-gate if (clear) 113*0Sstevel@tonic-gate { 114*0Sstevel@tonic-gate out[0]=0; 115*0Sstevel@tonic-gate memcpy(&(out[1]),in,ilen); 116*0Sstevel@tonic-gate l=ilen+1; 117*0Sstevel@tonic-gate } 118*0Sstevel@tonic-gate #ifdef DEBUG_ZLIB 119*0Sstevel@tonic-gate fprintf(stderr,"compress(%4d)->%4d %s\n", 120*0Sstevel@tonic-gate ilen,(int)l,(clear)?"clear":"zlib"); 121*0Sstevel@tonic-gate #endif 122*0Sstevel@tonic-gate return((int)l); 123*0Sstevel@tonic-gate } 124*0Sstevel@tonic-gate 125*0Sstevel@tonic-gate static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, 126*0Sstevel@tonic-gate unsigned int olen, unsigned char *in, unsigned int ilen) 127*0Sstevel@tonic-gate { 128*0Sstevel@tonic-gate unsigned long l; 129*0Sstevel@tonic-gate int i; 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate if (in[0]) 132*0Sstevel@tonic-gate { 133*0Sstevel@tonic-gate l=olen; 134*0Sstevel@tonic-gate i=zz_uncompress(out,&l,&(in[1]),(unsigned long)ilen-1); 135*0Sstevel@tonic-gate if (i != Z_OK) 136*0Sstevel@tonic-gate return(-1); 137*0Sstevel@tonic-gate } 138*0Sstevel@tonic-gate else 139*0Sstevel@tonic-gate { 140*0Sstevel@tonic-gate memcpy(out,&(in[1]),ilen-1); 141*0Sstevel@tonic-gate l=ilen-1; 142*0Sstevel@tonic-gate } 143*0Sstevel@tonic-gate #ifdef DEBUG_ZLIB 144*0Sstevel@tonic-gate fprintf(stderr,"expand (%4d)->%4d %s\n", 145*0Sstevel@tonic-gate ilen,(int)l,in[0]?"zlib":"clear"); 146*0Sstevel@tonic-gate #endif 147*0Sstevel@tonic-gate return((int)l); 148*0Sstevel@tonic-gate } 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, 151*0Sstevel@tonic-gate uLong sourceLen) 152*0Sstevel@tonic-gate { 153*0Sstevel@tonic-gate z_stream stream; 154*0Sstevel@tonic-gate int err; 155*0Sstevel@tonic-gate 156*0Sstevel@tonic-gate stream.next_in = (Bytef*)source; 157*0Sstevel@tonic-gate stream.avail_in = (uInt)sourceLen; 158*0Sstevel@tonic-gate /* Check for source > 64K on 16-bit machine: */ 159*0Sstevel@tonic-gate if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate stream.next_out = dest; 162*0Sstevel@tonic-gate stream.avail_out = (uInt)*destLen; 163*0Sstevel@tonic-gate if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate stream.zalloc = (alloc_func)0; 166*0Sstevel@tonic-gate stream.zfree = (free_func)0; 167*0Sstevel@tonic-gate 168*0Sstevel@tonic-gate err = inflateInit(&stream); 169*0Sstevel@tonic-gate if (err != Z_OK) return err; 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate err = inflate(&stream, Z_FINISH); 172*0Sstevel@tonic-gate if (err != Z_STREAM_END) { 173*0Sstevel@tonic-gate inflateEnd(&stream); 174*0Sstevel@tonic-gate return err; 175*0Sstevel@tonic-gate } 176*0Sstevel@tonic-gate *destLen = stream.total_out; 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gate err = inflateEnd(&stream); 179*0Sstevel@tonic-gate return err; 180*0Sstevel@tonic-gate } 181*0Sstevel@tonic-gate 182*0Sstevel@tonic-gate #endif 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate COMP_METHOD *COMP_zlib(void) 185*0Sstevel@tonic-gate { 186*0Sstevel@tonic-gate COMP_METHOD *meth = &zlib_method_nozlib; 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate #ifdef ZLIB_SHARED 189*0Sstevel@tonic-gate if (!zlib_loaded) 190*0Sstevel@tonic-gate { 191*0Sstevel@tonic-gate #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) 192*0Sstevel@tonic-gate zlib_dso = DSO_load(NULL, "ZLIB", NULL, 0); 193*0Sstevel@tonic-gate #else 194*0Sstevel@tonic-gate zlib_dso = DSO_load(NULL, "z", NULL, 0); 195*0Sstevel@tonic-gate #endif 196*0Sstevel@tonic-gate if (zlib_dso != NULL) 197*0Sstevel@tonic-gate { 198*0Sstevel@tonic-gate p_compress 199*0Sstevel@tonic-gate = (compress_ft) DSO_bind_func(zlib_dso, 200*0Sstevel@tonic-gate "compress"); 201*0Sstevel@tonic-gate p_inflateEnd 202*0Sstevel@tonic-gate = (inflateEnd_ft) DSO_bind_func(zlib_dso, 203*0Sstevel@tonic-gate "inflateEnd"); 204*0Sstevel@tonic-gate p_inflate 205*0Sstevel@tonic-gate = (inflate_ft) DSO_bind_func(zlib_dso, 206*0Sstevel@tonic-gate "inflate"); 207*0Sstevel@tonic-gate p_inflateInit_ 208*0Sstevel@tonic-gate = (inflateInit__ft) DSO_bind_func(zlib_dso, 209*0Sstevel@tonic-gate "inflateInit_"); 210*0Sstevel@tonic-gate zlib_loaded++; 211*0Sstevel@tonic-gate } 212*0Sstevel@tonic-gate } 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate #endif 215*0Sstevel@tonic-gate #if defined(ZLIB) || defined(ZLIB_SHARED) 216*0Sstevel@tonic-gate meth = &zlib_method; 217*0Sstevel@tonic-gate #endif 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate return(meth); 220*0Sstevel@tonic-gate } 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate #ifdef ZLIB_SHARED 223*0Sstevel@tonic-gate /* Stubs for each function to be dynamicly loaded */ 224*0Sstevel@tonic-gate static int 225*0Sstevel@tonic-gate stub_compress(Bytef *dest,uLongf *destLen,const Bytef *source, uLong sourceLen) 226*0Sstevel@tonic-gate { 227*0Sstevel@tonic-gate if (p_compress) 228*0Sstevel@tonic-gate return(p_compress(dest,destLen,source,sourceLen)); 229*0Sstevel@tonic-gate else 230*0Sstevel@tonic-gate return(Z_MEM_ERROR); 231*0Sstevel@tonic-gate } 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gate static int 234*0Sstevel@tonic-gate stub_inflateEnd(z_streamp strm) 235*0Sstevel@tonic-gate { 236*0Sstevel@tonic-gate if ( p_inflateEnd ) 237*0Sstevel@tonic-gate return(p_inflateEnd(strm)); 238*0Sstevel@tonic-gate else 239*0Sstevel@tonic-gate return(Z_MEM_ERROR); 240*0Sstevel@tonic-gate } 241*0Sstevel@tonic-gate 242*0Sstevel@tonic-gate static int 243*0Sstevel@tonic-gate stub_inflate(z_streamp strm, int flush) 244*0Sstevel@tonic-gate { 245*0Sstevel@tonic-gate if ( p_inflate ) 246*0Sstevel@tonic-gate return(p_inflate(strm,flush)); 247*0Sstevel@tonic-gate else 248*0Sstevel@tonic-gate return(Z_MEM_ERROR); 249*0Sstevel@tonic-gate } 250*0Sstevel@tonic-gate 251*0Sstevel@tonic-gate static int 252*0Sstevel@tonic-gate stub_inflateInit_(z_streamp strm, const char * version, int stream_size) 253*0Sstevel@tonic-gate { 254*0Sstevel@tonic-gate if ( p_inflateInit_ ) 255*0Sstevel@tonic-gate return(p_inflateInit_(strm,version,stream_size)); 256*0Sstevel@tonic-gate else 257*0Sstevel@tonic-gate return(Z_MEM_ERROR); 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate 260*0Sstevel@tonic-gate #endif /* ZLIB_SHARED */ 261