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