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