1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <openssl/objects.h> 5 #include <openssl/comp.h> 6 #include <openssl/err.h> 7 8 COMP_METHOD *COMP_zlib(void ); 9 10 static COMP_METHOD zlib_method_nozlib={ 11 NID_undef, 12 "(undef)", 13 NULL, 14 NULL, 15 NULL, 16 NULL, 17 NULL, 18 NULL, 19 }; 20 21 #ifndef ZLIB 22 #undef ZLIB_SHARED 23 #else 24 25 #include <zlib.h> 26 27 static int zlib_stateful_init(COMP_CTX *ctx); 28 static void zlib_stateful_finish(COMP_CTX *ctx); 29 static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, 30 unsigned int olen, unsigned char *in, unsigned int ilen); 31 static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, 32 unsigned int olen, unsigned char *in, unsigned int ilen); 33 34 35 /* memory allocations functions for zlib intialization */ 36 static void* zlib_zalloc(void* opaque, unsigned int no, unsigned int size) 37 { 38 void *p; 39 40 p=OPENSSL_malloc(no*size); 41 if (p) 42 memset(p, 0, no*size); 43 return p; 44 } 45 46 47 static void zlib_zfree(void* opaque, void* address) 48 { 49 OPENSSL_free(address); 50 } 51 52 #if 0 53 static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, 54 unsigned int olen, unsigned char *in, unsigned int ilen); 55 static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, 56 unsigned int olen, unsigned char *in, unsigned int ilen); 57 58 static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, 59 uLong sourceLen); 60 61 static COMP_METHOD zlib_stateless_method={ 62 NID_zlib_compression, 63 LN_zlib_compression, 64 NULL, 65 NULL, 66 zlib_compress_block, 67 zlib_expand_block, 68 NULL, 69 NULL, 70 }; 71 #endif 72 73 static COMP_METHOD zlib_stateful_method={ 74 NID_zlib_compression, 75 LN_zlib_compression, 76 zlib_stateful_init, 77 zlib_stateful_finish, 78 zlib_stateful_compress_block, 79 zlib_stateful_expand_block, 80 NULL, 81 NULL, 82 }; 83 84 /* 85 * When OpenSSL is built on Windows, we do not want to require that 86 * the ZLIB.DLL be available in order for the OpenSSL DLLs to 87 * work. Therefore, all ZLIB routines are loaded at run time 88 * and we do not link to a .LIB file when ZLIB_SHARED is set. 89 */ 90 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) 91 # include <windows.h> 92 #endif /* !(OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32) */ 93 94 #ifdef ZLIB_SHARED 95 #include <openssl/dso.h> 96 97 /* Function pointers */ 98 typedef int (*compress_ft)(Bytef *dest,uLongf *destLen, 99 const Bytef *source, uLong sourceLen); 100 typedef int (*inflateEnd_ft)(z_streamp strm); 101 typedef int (*inflate_ft)(z_streamp strm, int flush); 102 typedef int (*inflateInit__ft)(z_streamp strm, 103 const char * version, int stream_size); 104 typedef int (*deflateEnd_ft)(z_streamp strm); 105 typedef int (*deflate_ft)(z_streamp strm, int flush); 106 typedef int (*deflateInit__ft)(z_streamp strm, int level, 107 const char * version, int stream_size); 108 typedef const char * (*zError__ft)(int err); 109 static compress_ft p_compress=NULL; 110 static inflateEnd_ft p_inflateEnd=NULL; 111 static inflate_ft p_inflate=NULL; 112 static inflateInit__ft p_inflateInit_=NULL; 113 static deflateEnd_ft p_deflateEnd=NULL; 114 static deflate_ft p_deflate=NULL; 115 static deflateInit__ft p_deflateInit_=NULL; 116 static zError__ft p_zError=NULL; 117 118 static int zlib_loaded = 0; /* only attempt to init func pts once */ 119 static DSO *zlib_dso = NULL; 120 121 #define compress p_compress 122 #define inflateEnd p_inflateEnd 123 #define inflate p_inflate 124 #define inflateInit_ p_inflateInit_ 125 #define deflateEnd p_deflateEnd 126 #define deflate p_deflate 127 #define deflateInit_ p_deflateInit_ 128 #define zError p_zError 129 #endif /* ZLIB_SHARED */ 130 131 struct zlib_state 132 { 133 z_stream istream; 134 z_stream ostream; 135 }; 136 137 static int zlib_stateful_ex_idx = -1; 138 139 static int zlib_stateful_init(COMP_CTX *ctx) 140 { 141 int err; 142 struct zlib_state *state = 143 (struct zlib_state *)OPENSSL_malloc(sizeof(struct zlib_state)); 144 145 if (state == NULL) 146 goto err; 147 148 state->istream.zalloc = zlib_zalloc; 149 state->istream.zfree = zlib_zfree; 150 state->istream.opaque = Z_NULL; 151 state->istream.next_in = Z_NULL; 152 state->istream.next_out = Z_NULL; 153 state->istream.avail_in = 0; 154 state->istream.avail_out = 0; 155 err = inflateInit_(&state->istream, 156 ZLIB_VERSION, sizeof(z_stream)); 157 if (err != Z_OK) 158 goto err; 159 160 state->ostream.zalloc = zlib_zalloc; 161 state->ostream.zfree = zlib_zfree; 162 state->ostream.opaque = Z_NULL; 163 state->ostream.next_in = Z_NULL; 164 state->ostream.next_out = Z_NULL; 165 state->ostream.avail_in = 0; 166 state->ostream.avail_out = 0; 167 err = deflateInit_(&state->ostream,Z_DEFAULT_COMPRESSION, 168 ZLIB_VERSION, sizeof(z_stream)); 169 if (err != Z_OK) 170 goto err; 171 172 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data); 173 CRYPTO_set_ex_data(&ctx->ex_data,zlib_stateful_ex_idx,state); 174 return 1; 175 err: 176 if (state) OPENSSL_free(state); 177 return 0; 178 } 179 180 static void zlib_stateful_finish(COMP_CTX *ctx) 181 { 182 struct zlib_state *state = 183 (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, 184 zlib_stateful_ex_idx); 185 inflateEnd(&state->istream); 186 deflateEnd(&state->ostream); 187 OPENSSL_free(state); 188 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data); 189 } 190 191 static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, 192 unsigned int olen, unsigned char *in, unsigned int ilen) 193 { 194 int err = Z_OK; 195 struct zlib_state *state = 196 (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, 197 zlib_stateful_ex_idx); 198 199 if (state == NULL) 200 return -1; 201 202 state->ostream.next_in = in; 203 state->ostream.avail_in = ilen; 204 state->ostream.next_out = out; 205 state->ostream.avail_out = olen; 206 if (ilen > 0) 207 err = deflate(&state->ostream, Z_SYNC_FLUSH); 208 if (err != Z_OK) 209 return -1; 210 #ifdef DEBUG_ZLIB 211 fprintf(stderr,"compress(%4d)->%4d %s\n", 212 ilen,olen - state->ostream.avail_out, 213 (ilen != olen - state->ostream.avail_out)?"zlib":"clear"); 214 #endif 215 return olen - state->ostream.avail_out; 216 } 217 218 static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, 219 unsigned int olen, unsigned char *in, unsigned int ilen) 220 { 221 int err = Z_OK; 222 223 struct zlib_state *state = 224 (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, 225 zlib_stateful_ex_idx); 226 227 if (state == NULL) 228 return 0; 229 230 state->istream.next_in = in; 231 state->istream.avail_in = ilen; 232 state->istream.next_out = out; 233 state->istream.avail_out = olen; 234 if (ilen > 0) 235 err = inflate(&state->istream, Z_SYNC_FLUSH); 236 if (err != Z_OK) 237 return -1; 238 #ifdef DEBUG_ZLIB 239 fprintf(stderr,"expand(%4d)->%4d %s\n", 240 ilen,olen - state->istream.avail_out, 241 (ilen != olen - state->istream.avail_out)?"zlib":"clear"); 242 #endif 243 return olen - state->istream.avail_out; 244 } 245 246 #if 0 247 static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, 248 unsigned int olen, unsigned char *in, unsigned int ilen) 249 { 250 unsigned long l; 251 int i; 252 int clear=1; 253 254 if (ilen > 128) 255 { 256 out[0]=1; 257 l=olen-1; 258 i=compress(&(out[1]),&l,in,(unsigned long)ilen); 259 if (i != Z_OK) 260 return(-1); 261 if (ilen > l) 262 { 263 clear=0; 264 l++; 265 } 266 } 267 if (clear) 268 { 269 out[0]=0; 270 memcpy(&(out[1]),in,ilen); 271 l=ilen+1; 272 } 273 #ifdef DEBUG_ZLIB 274 fprintf(stderr,"compress(%4d)->%4d %s\n", 275 ilen,(int)l,(clear)?"clear":"zlib"); 276 #endif 277 return((int)l); 278 } 279 280 static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, 281 unsigned int olen, unsigned char *in, unsigned int ilen) 282 { 283 unsigned long l; 284 int i; 285 286 if (in[0]) 287 { 288 l=olen; 289 i=zz_uncompress(out,&l,&(in[1]),(unsigned long)ilen-1); 290 if (i != Z_OK) 291 return(-1); 292 } 293 else 294 { 295 memcpy(out,&(in[1]),ilen-1); 296 l=ilen-1; 297 } 298 #ifdef DEBUG_ZLIB 299 fprintf(stderr,"expand (%4d)->%4d %s\n", 300 ilen,(int)l,in[0]?"zlib":"clear"); 301 #endif 302 return((int)l); 303 } 304 305 static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, 306 uLong sourceLen) 307 { 308 z_stream stream; 309 int err; 310 311 stream.next_in = (Bytef*)source; 312 stream.avail_in = (uInt)sourceLen; 313 /* Check for source > 64K on 16-bit machine: */ 314 if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; 315 316 stream.next_out = dest; 317 stream.avail_out = (uInt)*destLen; 318 if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; 319 320 stream.zalloc = (alloc_func)0; 321 stream.zfree = (free_func)0; 322 323 err = inflateInit_(&stream, 324 ZLIB_VERSION, sizeof(z_stream)); 325 if (err != Z_OK) return err; 326 327 err = inflate(&stream, Z_FINISH); 328 if (err != Z_STREAM_END) { 329 inflateEnd(&stream); 330 return err; 331 } 332 *destLen = stream.total_out; 333 334 err = inflateEnd(&stream); 335 return err; 336 } 337 #endif 338 339 #endif 340 341 COMP_METHOD *COMP_zlib(void) 342 { 343 COMP_METHOD *meth = &zlib_method_nozlib; 344 345 #ifdef ZLIB_SHARED 346 if (!zlib_loaded) 347 { 348 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) 349 zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0); 350 #else 351 zlib_dso = DSO_load(NULL, "z", NULL, 0); 352 #endif 353 if (zlib_dso != NULL) 354 { 355 p_compress 356 = (compress_ft) DSO_bind_func(zlib_dso, 357 "compress"); 358 p_inflateEnd 359 = (inflateEnd_ft) DSO_bind_func(zlib_dso, 360 "inflateEnd"); 361 p_inflate 362 = (inflate_ft) DSO_bind_func(zlib_dso, 363 "inflate"); 364 p_inflateInit_ 365 = (inflateInit__ft) DSO_bind_func(zlib_dso, 366 "inflateInit_"); 367 p_deflateEnd 368 = (deflateEnd_ft) DSO_bind_func(zlib_dso, 369 "deflateEnd"); 370 p_deflate 371 = (deflate_ft) DSO_bind_func(zlib_dso, 372 "deflate"); 373 p_deflateInit_ 374 = (deflateInit__ft) DSO_bind_func(zlib_dso, 375 "deflateInit_"); 376 p_zError 377 = (zError__ft) DSO_bind_func(zlib_dso, 378 "zError"); 379 380 if (p_compress && p_inflateEnd && p_inflate 381 && p_inflateInit_ && p_deflateEnd 382 && p_deflate && p_deflateInit_ && p_zError) 383 zlib_loaded++; 384 } 385 } 386 387 #endif 388 #ifdef ZLIB_SHARED 389 if (zlib_loaded) 390 #endif 391 #if defined(ZLIB) || defined(ZLIB_SHARED) 392 { 393 /* init zlib_stateful_ex_idx here so that in a multi-process 394 * application it's enough to intialize openssl before forking 395 * (idx will be inherited in all the children) */ 396 if (zlib_stateful_ex_idx == -1) 397 { 398 CRYPTO_w_lock(CRYPTO_LOCK_COMP); 399 if (zlib_stateful_ex_idx == -1) 400 zlib_stateful_ex_idx = 401 CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP, 402 0,NULL,NULL,NULL,NULL); 403 CRYPTO_w_unlock(CRYPTO_LOCK_COMP); 404 if (zlib_stateful_ex_idx == -1) 405 goto err; 406 } 407 408 meth = &zlib_stateful_method; 409 } 410 err: 411 #endif 412 413 return(meth); 414 } 415 416 void COMP_zlib_cleanup(void) 417 { 418 #ifdef ZLIB_SHARED 419 if (zlib_dso) 420 DSO_free(zlib_dso); 421 #endif 422 } 423 424 #ifdef ZLIB 425 426 /* Zlib based compression/decompression filter BIO */ 427 428 typedef struct 429 { 430 unsigned char *ibuf; /* Input buffer */ 431 int ibufsize; /* Buffer size */ 432 z_stream zin; /* Input decompress context */ 433 unsigned char *obuf; /* Output buffer */ 434 int obufsize; /* Output buffer size */ 435 unsigned char *optr; /* Position in output buffer */ 436 int ocount; /* Amount of data in output buffer */ 437 int odone; /* deflate EOF */ 438 int comp_level; /* Compression level to use */ 439 z_stream zout; /* Output compression context */ 440 } BIO_ZLIB_CTX; 441 442 #define ZLIB_DEFAULT_BUFSIZE 1024 443 444 static int bio_zlib_new(BIO *bi); 445 static int bio_zlib_free(BIO *bi); 446 static int bio_zlib_read(BIO *b, char *out, int outl); 447 static int bio_zlib_write(BIO *b, const char *in, int inl); 448 static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr); 449 static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp); 450 451 static BIO_METHOD bio_meth_zlib = 452 { 453 BIO_TYPE_COMP, 454 "zlib", 455 bio_zlib_write, 456 bio_zlib_read, 457 NULL, 458 NULL, 459 bio_zlib_ctrl, 460 bio_zlib_new, 461 bio_zlib_free, 462 bio_zlib_callback_ctrl 463 }; 464 465 BIO_METHOD *BIO_f_zlib(void) 466 { 467 return &bio_meth_zlib; 468 } 469 470 471 static int bio_zlib_new(BIO *bi) 472 { 473 BIO_ZLIB_CTX *ctx; 474 #ifdef ZLIB_SHARED 475 (void)COMP_zlib(); 476 if (!zlib_loaded) 477 { 478 COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED); 479 return 0; 480 } 481 #endif 482 ctx = OPENSSL_malloc(sizeof(BIO_ZLIB_CTX)); 483 if(!ctx) 484 { 485 COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE); 486 return 0; 487 } 488 ctx->ibuf = NULL; 489 ctx->obuf = NULL; 490 ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE; 491 ctx->obufsize = ZLIB_DEFAULT_BUFSIZE; 492 ctx->zin.zalloc = Z_NULL; 493 ctx->zin.zfree = Z_NULL; 494 ctx->zin.next_in = NULL; 495 ctx->zin.avail_in = 0; 496 ctx->zin.next_out = NULL; 497 ctx->zin.avail_out = 0; 498 ctx->zout.zalloc = Z_NULL; 499 ctx->zout.zfree = Z_NULL; 500 ctx->zout.next_in = NULL; 501 ctx->zout.avail_in = 0; 502 ctx->zout.next_out = NULL; 503 ctx->zout.avail_out = 0; 504 ctx->odone = 0; 505 ctx->comp_level = Z_DEFAULT_COMPRESSION; 506 bi->init = 1; 507 bi->ptr = (char *)ctx; 508 bi->flags = 0; 509 return 1; 510 } 511 512 static int bio_zlib_free(BIO *bi) 513 { 514 BIO_ZLIB_CTX *ctx; 515 if(!bi) return 0; 516 ctx = (BIO_ZLIB_CTX *)bi->ptr; 517 if(ctx->ibuf) 518 { 519 /* Destroy decompress context */ 520 inflateEnd(&ctx->zin); 521 OPENSSL_free(ctx->ibuf); 522 } 523 if(ctx->obuf) 524 { 525 /* Destroy compress context */ 526 deflateEnd(&ctx->zout); 527 OPENSSL_free(ctx->obuf); 528 } 529 OPENSSL_free(ctx); 530 bi->ptr = NULL; 531 bi->init = 0; 532 bi->flags = 0; 533 return 1; 534 } 535 536 static int bio_zlib_read(BIO *b, char *out, int outl) 537 { 538 BIO_ZLIB_CTX *ctx; 539 int ret; 540 z_stream *zin; 541 if(!out || !outl) return 0; 542 ctx = (BIO_ZLIB_CTX *)b->ptr; 543 zin = &ctx->zin; 544 BIO_clear_retry_flags(b); 545 if(!ctx->ibuf) 546 { 547 ctx->ibuf = OPENSSL_malloc(ctx->ibufsize); 548 if(!ctx->ibuf) 549 { 550 COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE); 551 return 0; 552 } 553 inflateInit(zin); 554 zin->next_in = ctx->ibuf; 555 zin->avail_in = 0; 556 } 557 558 /* Copy output data directly to supplied buffer */ 559 zin->next_out = (unsigned char *)out; 560 zin->avail_out = (unsigned int)outl; 561 for(;;) 562 { 563 /* Decompress while data available */ 564 while(zin->avail_in) 565 { 566 ret = inflate(zin, 0); 567 if((ret != Z_OK) && (ret != Z_STREAM_END)) 568 { 569 COMPerr(COMP_F_BIO_ZLIB_READ, 570 COMP_R_ZLIB_INFLATE_ERROR); 571 ERR_add_error_data(2, "zlib error:", 572 zError(ret)); 573 return 0; 574 } 575 /* If EOF or we've read everything then return */ 576 if((ret == Z_STREAM_END) || !zin->avail_out) 577 return outl - zin->avail_out; 578 } 579 580 /* No data in input buffer try to read some in, 581 * if an error then return the total data read. 582 */ 583 ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize); 584 if(ret <= 0) 585 { 586 /* Total data read */ 587 int tot = outl - zin->avail_out; 588 BIO_copy_next_retry(b); 589 if(ret < 0) return (tot > 0) ? tot : ret; 590 return tot; 591 } 592 zin->avail_in = ret; 593 zin->next_in = ctx->ibuf; 594 } 595 } 596 597 static int bio_zlib_write(BIO *b, const char *in, int inl) 598 { 599 BIO_ZLIB_CTX *ctx; 600 int ret; 601 z_stream *zout; 602 if(!in || !inl) return 0; 603 ctx = (BIO_ZLIB_CTX *)b->ptr; 604 if(ctx->odone) return 0; 605 zout = &ctx->zout; 606 BIO_clear_retry_flags(b); 607 if(!ctx->obuf) 608 { 609 ctx->obuf = OPENSSL_malloc(ctx->obufsize); 610 /* Need error here */ 611 if(!ctx->obuf) 612 { 613 COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE); 614 return 0; 615 } 616 ctx->optr = ctx->obuf; 617 ctx->ocount = 0; 618 deflateInit(zout, ctx->comp_level); 619 zout->next_out = ctx->obuf; 620 zout->avail_out = ctx->obufsize; 621 } 622 /* Obtain input data directly from supplied buffer */ 623 zout->next_in = (void *)in; 624 zout->avail_in = inl; 625 for(;;) 626 { 627 /* If data in output buffer write it first */ 628 while(ctx->ocount) { 629 ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount); 630 if(ret <= 0) 631 { 632 /* Total data written */ 633 int tot = inl - zout->avail_in; 634 BIO_copy_next_retry(b); 635 if(ret < 0) return (tot > 0) ? tot : ret; 636 return tot; 637 } 638 ctx->optr += ret; 639 ctx->ocount -= ret; 640 } 641 642 /* Have we consumed all supplied data? */ 643 if(!zout->avail_in) 644 return inl; 645 646 /* Compress some more */ 647 648 /* Reset buffer */ 649 ctx->optr = ctx->obuf; 650 zout->next_out = ctx->obuf; 651 zout->avail_out = ctx->obufsize; 652 /* Compress some more */ 653 ret = deflate(zout, 0); 654 if(ret != Z_OK) 655 { 656 COMPerr(COMP_F_BIO_ZLIB_WRITE, 657 COMP_R_ZLIB_DEFLATE_ERROR); 658 ERR_add_error_data(2, "zlib error:", zError(ret)); 659 return 0; 660 } 661 ctx->ocount = ctx->obufsize - zout->avail_out; 662 } 663 } 664 665 static int bio_zlib_flush(BIO *b) 666 { 667 BIO_ZLIB_CTX *ctx; 668 int ret; 669 z_stream *zout; 670 ctx = (BIO_ZLIB_CTX *)b->ptr; 671 /* If no data written or already flush show success */ 672 if(!ctx->obuf || (ctx->odone && !ctx->ocount)) return 1; 673 zout = &ctx->zout; 674 BIO_clear_retry_flags(b); 675 /* No more input data */ 676 zout->next_in = NULL; 677 zout->avail_in = 0; 678 for(;;) 679 { 680 /* If data in output buffer write it first */ 681 while(ctx->ocount) 682 { 683 ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount); 684 if(ret <= 0) 685 { 686 BIO_copy_next_retry(b); 687 return ret; 688 } 689 ctx->optr += ret; 690 ctx->ocount -= ret; 691 } 692 if(ctx->odone) return 1; 693 694 /* Compress some more */ 695 696 /* Reset buffer */ 697 ctx->optr = ctx->obuf; 698 zout->next_out = ctx->obuf; 699 zout->avail_out = ctx->obufsize; 700 /* Compress some more */ 701 ret = deflate(zout, Z_FINISH); 702 if(ret == Z_STREAM_END) ctx->odone = 1; 703 else if(ret != Z_OK) 704 { 705 COMPerr(COMP_F_BIO_ZLIB_FLUSH, 706 COMP_R_ZLIB_DEFLATE_ERROR); 707 ERR_add_error_data(2, "zlib error:", zError(ret)); 708 return 0; 709 } 710 ctx->ocount = ctx->obufsize - zout->avail_out; 711 } 712 } 713 714 static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) 715 { 716 BIO_ZLIB_CTX *ctx; 717 int ret, *ip; 718 int ibs, obs; 719 if(!b->next_bio) return 0; 720 ctx = (BIO_ZLIB_CTX *)b->ptr; 721 switch (cmd) 722 { 723 724 case BIO_CTRL_RESET: 725 ctx->ocount = 0; 726 ctx->odone = 0; 727 ret = 1; 728 break; 729 730 case BIO_CTRL_FLUSH: 731 ret = bio_zlib_flush(b); 732 if (ret > 0) 733 ret = BIO_flush(b->next_bio); 734 break; 735 736 case BIO_C_SET_BUFF_SIZE: 737 ibs = -1; 738 obs = -1; 739 if (ptr != NULL) 740 { 741 ip = ptr; 742 if (*ip == 0) 743 ibs = (int) num; 744 else 745 obs = (int) num; 746 } 747 else 748 { 749 ibs = (int)num; 750 obs = ibs; 751 } 752 753 if (ibs != -1) 754 { 755 if (ctx->ibuf) 756 { 757 OPENSSL_free(ctx->ibuf); 758 ctx->ibuf = NULL; 759 } 760 ctx->ibufsize = ibs; 761 } 762 763 if (obs != -1) 764 { 765 if (ctx->obuf) 766 { 767 OPENSSL_free(ctx->obuf); 768 ctx->obuf = NULL; 769 } 770 ctx->obufsize = obs; 771 } 772 ret = 1; 773 break; 774 775 case BIO_C_DO_STATE_MACHINE: 776 BIO_clear_retry_flags(b); 777 ret = BIO_ctrl(b->next_bio, cmd, num, ptr); 778 BIO_copy_next_retry(b); 779 break; 780 781 default: 782 ret = BIO_ctrl(b->next_bio, cmd, num, ptr); 783 break; 784 785 } 786 787 return ret; 788 } 789 790 791 static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) 792 { 793 if(!b->next_bio) 794 return 0; 795 return 796 BIO_callback_ctrl(b->next_bio, cmd, fp); 797 } 798 799 #endif 800