static int bio_zlib_new(BIO *bi) { BIO_ZLIB_CTX *ctx; # ifdef ZLIB_SHARED (void)COMP_zlib(); if (!zlib_loaded) { COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED); return 0; } # endif ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx == NULL) { COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE); return 0; } ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE; ctx->obufsize = ZLIB_DEFAULT_BUFSIZE; ctx->zin.zalloc = Z_NULL; ctx->zin.zfree = Z_NULL; ctx->zout.zalloc = Z_NULL; ctx->zout.zfree = Z_NULL; ctx->comp_level = Z_DEFAULT_COMPRESSION; BIO_set_init(bi, 1); BIO_set_data(bi, ctx); return 1; }
static int bio_zlib_read(BIO *b, char *out, int outl) { BIO_ZLIB_CTX *ctx; int ret; z_stream *zin; if(!out || !outl) return 0; ctx = (BIO_ZLIB_CTX *)b->ptr; zin = &ctx->zin; BIO_clear_retry_flags(b); if(!ctx->ibuf) { ctx->ibuf = OPENSSL_malloc(ctx->ibufsize); if(!ctx->ibuf) { COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE); return 0; } inflateInit(zin); zin->next_in = ctx->ibuf; zin->avail_in = 0; } /* Copy output data directly to supplied buffer */ zin->next_out = (unsigned char *)out; zin->avail_out = (unsigned int)outl; for(;;) { /* Decompress while data available */ while(zin->avail_in) { ret = inflate(zin, 0); if((ret != Z_OK) && (ret != Z_STREAM_END)) { COMPerr(COMP_F_BIO_ZLIB_READ, COMP_R_ZLIB_INFLATE_ERROR); ERR_add_error_data(2, "zlib error:", zError(ret)); return 0; } /* If EOF or we've read everything then return */ if((ret == Z_STREAM_END) || !zin->avail_out) return outl - zin->avail_out; } /* No data in input buffer try to read some in, * if an error then return the total data read. */ ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize); if(ret <= 0) { /* Total data read */ int tot = outl - zin->avail_out; BIO_copy_next_retry(b); if(ret < 0) return (tot > 0) ? tot : ret; return tot; } zin->avail_in = ret; zin->next_in = ctx->ibuf; } }
static int bio_zlib_new (BIO * bi) { BIO_ZLIB_CTX *ctx; #ifdef ZLIB_SHARED (void) COMP_zlib (); if (!zlib_loaded) { COMPerr (COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED); return 0; } #endif ctx = OPENSSL_malloc (sizeof (BIO_ZLIB_CTX)); if (!ctx) { COMPerr (COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE); return 0; } ctx->ibuf = NULL; ctx->obuf = NULL; ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE; ctx->obufsize = ZLIB_DEFAULT_BUFSIZE; ctx->zin.zalloc = Z_NULL; ctx->zin.zfree = Z_NULL; ctx->zin.next_in = NULL; ctx->zin.avail_in = 0; ctx->zin.next_out = NULL; ctx->zin.avail_out = 0; ctx->zout.zalloc = Z_NULL; ctx->zout.zfree = Z_NULL; ctx->zout.next_in = NULL; ctx->zout.avail_in = 0; ctx->zout.next_out = NULL; ctx->zout.avail_out = 0; ctx->odone = 0; ctx->comp_level = Z_DEFAULT_COMPRESSION; bi->init = 1; bi->ptr = (char *) ctx; bi->flags = 0; return 1; }
static int bio_zlib_flush (BIO * b) { BIO_ZLIB_CTX *ctx; int ret; z_stream *zout; ctx = (BIO_ZLIB_CTX *) b->ptr; /* If no data written or already flush show success */ if (!ctx->obuf || (ctx->odone && !ctx->ocount)) return 1; zout = &ctx->zout; BIO_clear_retry_flags (b); /* No more input data */ zout->next_in = NULL; zout->avail_in = 0; for (;;) { /* If data in output buffer write it first */ while (ctx->ocount) { ret = BIO_write (b->next_bio, ctx->optr, ctx->ocount); if (ret <= 0) { BIO_copy_next_retry (b); return ret; } ctx->optr += ret; ctx->ocount -= ret; } if (ctx->odone) return 1; /* Compress some more */ /* Reset buffer */ ctx->optr = ctx->obuf; zout->next_out = ctx->obuf; zout->avail_out = ctx->obufsize; /* Compress some more */ ret = deflate (zout, Z_FINISH); if (ret == Z_STREAM_END) ctx->odone = 1; else if (ret != Z_OK) { COMPerr (COMP_F_BIO_ZLIB_FLUSH, COMP_R_ZLIB_DEFLATE_ERROR); ERR_add_error_data (2, "zlib error:", zError (ret)); return 0; } ctx->ocount = ctx->obufsize - zout->avail_out; } }
static int bio_zlib_write(BIO *b, const char *in, int inl) { BIO_ZLIB_CTX *ctx; int ret; z_stream *zout; if (!in || !inl) return 0; ctx = (BIO_ZLIB_CTX *) b->ptr; if (ctx->odone) return 0; zout = &ctx->zout; BIO_clear_retry_flags(b); if (!ctx->obuf) { ctx->obuf = OPENSSL_malloc(ctx->obufsize); /* Need error here */ if (!ctx->obuf) { COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE); return 0; } ctx->optr = ctx->obuf; ctx->ocount = 0; deflateInit(zout, ctx->comp_level); zout->next_out = ctx->obuf; zout->avail_out = ctx->obufsize; } /* Obtain input data directly from supplied buffer */ zout->next_in = (void *)in; zout->avail_in = inl; for (;;) { /* If data in output buffer write it first */ while (ctx->ocount) { ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount); if (ret <= 0) { /* Total data written */ int tot = inl - zout->avail_in; BIO_copy_next_retry(b); if (ret < 0) return (tot > 0) ? tot : ret; return tot; } ctx->optr += ret; ctx->ocount -= ret; } /* Have we consumed all supplied data? */ if (!zout->avail_in) return inl; /* Compress some more */ /* Reset buffer */ ctx->optr = ctx->obuf; zout->next_out = ctx->obuf; zout->avail_out = ctx->obufsize; /* Compress some more */ ret = deflate(zout, 0); if (ret != Z_OK) { COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR); ERR_add_error_data(2, "zlib error:", zError(ret)); return 0; } ctx->ocount = ctx->obufsize - zout->avail_out; } }