c_zlib.c 20 KB

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