c_zlib.c 18 KB

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