c_zlib.c 21 KB

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