c_zlib.c 18 KB

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