diff options
Diffstat (limited to 'src/lib/libcrypto/comp/c_zlib.c')
-rw-r--r-- | src/lib/libcrypto/comp/c_zlib.c | 600 |
1 files changed, 7 insertions, 593 deletions
diff --git a/src/lib/libcrypto/comp/c_zlib.c b/src/lib/libcrypto/comp/c_zlib.c index 0f34597e70..5fcb521ffb 100644 --- a/src/lib/libcrypto/comp/c_zlib.c +++ b/src/lib/libcrypto/comp/c_zlib.c | |||
@@ -24,32 +24,6 @@ static COMP_METHOD zlib_method_nozlib={ | |||
24 | 24 | ||
25 | #include <zlib.h> | 25 | #include <zlib.h> |
26 | 26 | ||
27 | static int zlib_stateful_init(COMP_CTX *ctx); | ||
28 | static void zlib_stateful_finish(COMP_CTX *ctx); | ||
29 | static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, | ||
30 | unsigned int olen, unsigned char *in, unsigned int ilen); | ||
31 | static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, | ||
32 | unsigned int olen, unsigned char *in, unsigned int ilen); | ||
33 | |||
34 | |||
35 | /* memory allocations functions for zlib intialization */ | ||
36 | static void* zlib_zalloc(void* opaque, unsigned int no, unsigned int size) | ||
37 | { | ||
38 | void *p; | ||
39 | |||
40 | p=OPENSSL_malloc(no*size); | ||
41 | if (p) | ||
42 | memset(p, 0, no*size); | ||
43 | return p; | ||
44 | } | ||
45 | |||
46 | |||
47 | static void zlib_zfree(void* opaque, void* address) | ||
48 | { | ||
49 | OPENSSL_free(address); | ||
50 | } | ||
51 | |||
52 | #if 0 | ||
53 | static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, | 27 | static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, |
54 | unsigned int olen, unsigned char *in, unsigned int ilen); | 28 | unsigned int olen, unsigned char *in, unsigned int ilen); |
55 | static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, | 29 | static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, |
@@ -58,7 +32,7 @@ static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, | |||
58 | static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, | 32 | static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, |
59 | uLong sourceLen); | 33 | uLong sourceLen); |
60 | 34 | ||
61 | static COMP_METHOD zlib_stateless_method={ | 35 | static COMP_METHOD zlib_method={ |
62 | NID_zlib_compression, | 36 | NID_zlib_compression, |
63 | LN_zlib_compression, | 37 | LN_zlib_compression, |
64 | NULL, | 38 | NULL, |
@@ -68,24 +42,12 @@ static COMP_METHOD zlib_stateless_method={ | |||
68 | NULL, | 42 | NULL, |
69 | NULL, | 43 | NULL, |
70 | }; | 44 | }; |
71 | #endif | ||
72 | |||
73 | static COMP_METHOD zlib_stateful_method={ | ||
74 | NID_zlib_compression, | ||
75 | LN_zlib_compression, | ||
76 | zlib_stateful_init, | ||
77 | zlib_stateful_finish, | ||
78 | zlib_stateful_compress_block, | ||
79 | zlib_stateful_expand_block, | ||
80 | NULL, | ||
81 | NULL, | ||
82 | }; | ||
83 | 45 | ||
84 | /* | 46 | /* |
85 | * When OpenSSL is built on Windows, we do not want to require that | 47 | * When OpenSSL is built on Windows, we do not want to require that |
86 | * the ZLIB.DLL be available in order for the OpenSSL DLLs to | 48 | * the ZLIB.DLL be available in order for the OpenSSL DLLs to |
87 | * work. Therefore, all ZLIB routines are loaded at run time | 49 | * work. Therefore, all ZLIB routines are loaded at run time |
88 | * and we do not link to a .LIB file when ZLIB_SHARED is set. | 50 | * and we do not link to a .LIB file. |
89 | */ | 51 | */ |
90 | #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) | 52 | #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) |
91 | # include <windows.h> | 53 | # include <windows.h> |
@@ -101,19 +63,10 @@ typedef int (*inflateEnd_ft)(z_streamp strm); | |||
101 | typedef int (*inflate_ft)(z_streamp strm, int flush); | 63 | typedef int (*inflate_ft)(z_streamp strm, int flush); |
102 | typedef int (*inflateInit__ft)(z_streamp strm, | 64 | typedef int (*inflateInit__ft)(z_streamp strm, |
103 | const char * version, int stream_size); | 65 | const char * version, int stream_size); |
104 | typedef int (*deflateEnd_ft)(z_streamp strm); | ||
105 | typedef int (*deflate_ft)(z_streamp strm, int flush); | ||
106 | typedef int (*deflateInit__ft)(z_streamp strm, int level, | ||
107 | const char * version, int stream_size); | ||
108 | typedef const char * (*zError__ft)(int err); | ||
109 | static compress_ft p_compress=NULL; | 66 | static compress_ft p_compress=NULL; |
110 | static inflateEnd_ft p_inflateEnd=NULL; | 67 | static inflateEnd_ft p_inflateEnd=NULL; |
111 | static inflate_ft p_inflate=NULL; | 68 | static inflate_ft p_inflate=NULL; |
112 | static inflateInit__ft p_inflateInit_=NULL; | 69 | static inflateInit__ft p_inflateInit_=NULL; |
113 | static deflateEnd_ft p_deflateEnd=NULL; | ||
114 | static deflate_ft p_deflate=NULL; | ||
115 | static deflateInit__ft p_deflateInit_=NULL; | ||
116 | static zError__ft p_zError=NULL; | ||
117 | 70 | ||
118 | static int zlib_loaded = 0; /* only attempt to init func pts once */ | 71 | static int zlib_loaded = 0; /* only attempt to init func pts once */ |
119 | static DSO *zlib_dso = NULL; | 72 | static DSO *zlib_dso = NULL; |
@@ -122,133 +75,10 @@ static DSO *zlib_dso = NULL; | |||
122 | #define inflateEnd p_inflateEnd | 75 | #define inflateEnd p_inflateEnd |
123 | #define inflate p_inflate | 76 | #define inflate p_inflate |
124 | #define inflateInit_ p_inflateInit_ | 77 | #define inflateInit_ p_inflateInit_ |
125 | #define deflateEnd p_deflateEnd | ||
126 | #define deflate p_deflate | ||
127 | #define deflateInit_ p_deflateInit_ | ||
128 | #define zError p_zError | ||
129 | #endif /* ZLIB_SHARED */ | 78 | #endif /* ZLIB_SHARED */ |
130 | 79 | ||
131 | struct zlib_state | ||
132 | { | ||
133 | z_stream istream; | ||
134 | z_stream ostream; | ||
135 | }; | ||
136 | |||
137 | static int zlib_stateful_ex_idx = -1; | ||
138 | |||
139 | static void zlib_stateful_free_ex_data(void *obj, void *item, | ||
140 | CRYPTO_EX_DATA *ad, int ind,long argl, void *argp) | ||
141 | { | ||
142 | struct zlib_state *state = (struct zlib_state *)item; | ||
143 | inflateEnd(&state->istream); | ||
144 | deflateEnd(&state->ostream); | ||
145 | OPENSSL_free(state); | ||
146 | } | ||
147 | |||
148 | static int zlib_stateful_init(COMP_CTX *ctx) | ||
149 | { | ||
150 | int err; | ||
151 | struct zlib_state *state = | ||
152 | (struct zlib_state *)OPENSSL_malloc(sizeof(struct zlib_state)); | ||
153 | |||
154 | if (state == NULL) | ||
155 | goto err; | ||
156 | |||
157 | state->istream.zalloc = zlib_zalloc; | ||
158 | state->istream.zfree = zlib_zfree; | ||
159 | state->istream.opaque = Z_NULL; | ||
160 | state->istream.next_in = Z_NULL; | ||
161 | state->istream.next_out = Z_NULL; | ||
162 | state->istream.avail_in = 0; | ||
163 | state->istream.avail_out = 0; | ||
164 | err = inflateInit_(&state->istream, | ||
165 | ZLIB_VERSION, sizeof(z_stream)); | ||
166 | if (err != Z_OK) | ||
167 | goto err; | ||
168 | |||
169 | state->ostream.zalloc = zlib_zalloc; | ||
170 | state->ostream.zfree = zlib_zfree; | ||
171 | state->ostream.opaque = Z_NULL; | ||
172 | state->ostream.next_in = Z_NULL; | ||
173 | state->ostream.next_out = Z_NULL; | ||
174 | state->ostream.avail_in = 0; | ||
175 | state->ostream.avail_out = 0; | ||
176 | err = deflateInit_(&state->ostream,Z_DEFAULT_COMPRESSION, | ||
177 | ZLIB_VERSION, sizeof(z_stream)); | ||
178 | if (err != Z_OK) | ||
179 | goto err; | ||
180 | |||
181 | CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data); | ||
182 | CRYPTO_set_ex_data(&ctx->ex_data,zlib_stateful_ex_idx,state); | ||
183 | return 1; | ||
184 | err: | ||
185 | if (state) OPENSSL_free(state); | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static void zlib_stateful_finish(COMP_CTX *ctx) | ||
190 | { | ||
191 | CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data); | ||
192 | } | ||
193 | |||
194 | static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, | ||
195 | unsigned int olen, unsigned char *in, unsigned int ilen) | ||
196 | { | ||
197 | int err = Z_OK; | ||
198 | struct zlib_state *state = | ||
199 | (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, | ||
200 | zlib_stateful_ex_idx); | ||
201 | |||
202 | if (state == NULL) | ||
203 | return -1; | ||
204 | |||
205 | state->ostream.next_in = in; | ||
206 | state->ostream.avail_in = ilen; | ||
207 | state->ostream.next_out = out; | ||
208 | state->ostream.avail_out = olen; | ||
209 | if (ilen > 0) | ||
210 | err = deflate(&state->ostream, Z_SYNC_FLUSH); | ||
211 | if (err != Z_OK) | ||
212 | return -1; | ||
213 | #ifdef DEBUG_ZLIB | ||
214 | fprintf(stderr,"compress(%4d)->%4d %s\n", | ||
215 | ilen,olen - state->ostream.avail_out, | ||
216 | (ilen != olen - state->ostream.avail_out)?"zlib":"clear"); | ||
217 | #endif | ||
218 | return olen - state->ostream.avail_out; | ||
219 | } | ||
220 | |||
221 | static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, | ||
222 | unsigned int olen, unsigned char *in, unsigned int ilen) | ||
223 | { | ||
224 | int err = Z_OK; | ||
225 | |||
226 | struct zlib_state *state = | ||
227 | (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, | ||
228 | zlib_stateful_ex_idx); | ||
229 | |||
230 | if (state == NULL) | ||
231 | return 0; | ||
232 | |||
233 | state->istream.next_in = in; | ||
234 | state->istream.avail_in = ilen; | ||
235 | state->istream.next_out = out; | ||
236 | state->istream.avail_out = olen; | ||
237 | if (ilen > 0) | ||
238 | err = inflate(&state->istream, Z_SYNC_FLUSH); | ||
239 | if (err != Z_OK) | ||
240 | return -1; | ||
241 | #ifdef DEBUG_ZLIB | ||
242 | fprintf(stderr,"expand(%4d)->%4d %s\n", | ||
243 | ilen,olen - state->istream.avail_out, | ||
244 | (ilen != olen - state->istream.avail_out)?"zlib":"clear"); | ||
245 | #endif | ||
246 | return olen - state->istream.avail_out; | ||
247 | } | ||
248 | |||
249 | #if 0 | ||
250 | static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, | 80 | static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, |
251 | unsigned int olen, unsigned char *in, unsigned int ilen) | 81 | unsigned int olen, unsigned char *in, unsigned int ilen) |
252 | { | 82 | { |
253 | unsigned long l; | 83 | unsigned long l; |
254 | int i; | 84 | int i; |
@@ -281,7 +111,7 @@ static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, | |||
281 | } | 111 | } |
282 | 112 | ||
283 | static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, | 113 | static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, |
284 | unsigned int olen, unsigned char *in, unsigned int ilen) | 114 | unsigned int olen, unsigned char *in, unsigned int ilen) |
285 | { | 115 | { |
286 | unsigned long l; | 116 | unsigned long l; |
287 | int i; | 117 | int i; |
@@ -323,8 +153,7 @@ static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, | |||
323 | stream.zalloc = (alloc_func)0; | 153 | stream.zalloc = (alloc_func)0; |
324 | stream.zfree = (free_func)0; | 154 | stream.zfree = (free_func)0; |
325 | 155 | ||
326 | err = inflateInit_(&stream, | 156 | err = inflateInit(&stream); |
327 | ZLIB_VERSION, sizeof(z_stream)); | ||
328 | if (err != Z_OK) return err; | 157 | if (err != Z_OK) return err; |
329 | 158 | ||
330 | err = inflate(&stream, Z_FINISH); | 159 | err = inflate(&stream, Z_FINISH); |
@@ -337,7 +166,6 @@ static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, | |||
337 | err = inflateEnd(&stream); | 166 | err = inflateEnd(&stream); |
338 | return err; | 167 | return err; |
339 | } | 168 | } |
340 | #endif | ||
341 | 169 | ||
342 | #endif | 170 | #endif |
343 | 171 | ||
@@ -367,22 +195,9 @@ COMP_METHOD *COMP_zlib(void) | |||
367 | p_inflateInit_ | 195 | p_inflateInit_ |
368 | = (inflateInit__ft) DSO_bind_func(zlib_dso, | 196 | = (inflateInit__ft) DSO_bind_func(zlib_dso, |
369 | "inflateInit_"); | 197 | "inflateInit_"); |
370 | p_deflateEnd | ||
371 | = (deflateEnd_ft) DSO_bind_func(zlib_dso, | ||
372 | "deflateEnd"); | ||
373 | p_deflate | ||
374 | = (deflate_ft) DSO_bind_func(zlib_dso, | ||
375 | "deflate"); | ||
376 | p_deflateInit_ | ||
377 | = (deflateInit__ft) DSO_bind_func(zlib_dso, | ||
378 | "deflateInit_"); | ||
379 | p_zError | ||
380 | = (zError__ft) DSO_bind_func(zlib_dso, | ||
381 | "zError"); | ||
382 | 198 | ||
383 | if (p_compress && p_inflateEnd && p_inflate | 199 | if (p_compress && p_inflateEnd && p_inflate |
384 | && p_inflateInit_ && p_deflateEnd | 200 | && p_inflateInit_) |
385 | && p_deflate && p_deflateInit_ && p_zError) | ||
386 | zlib_loaded++; | 201 | zlib_loaded++; |
387 | } | 202 | } |
388 | } | 203 | } |
@@ -392,410 +207,9 @@ COMP_METHOD *COMP_zlib(void) | |||
392 | if (zlib_loaded) | 207 | if (zlib_loaded) |
393 | #endif | 208 | #endif |
394 | #if defined(ZLIB) || defined(ZLIB_SHARED) | 209 | #if defined(ZLIB) || defined(ZLIB_SHARED) |
395 | { | 210 | meth = &zlib_method; |
396 | /* init zlib_stateful_ex_idx here so that in a multi-process | ||
397 | * application it's enough to intialize openssl before forking | ||
398 | * (idx will be inherited in all the children) */ | ||
399 | if (zlib_stateful_ex_idx == -1) | ||
400 | { | ||
401 | CRYPTO_w_lock(CRYPTO_LOCK_COMP); | ||
402 | if (zlib_stateful_ex_idx == -1) | ||
403 | zlib_stateful_ex_idx = | ||
404 | CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP, | ||
405 | 0,NULL,NULL,NULL,zlib_stateful_free_ex_data); | ||
406 | CRYPTO_w_unlock(CRYPTO_LOCK_COMP); | ||
407 | if (zlib_stateful_ex_idx == -1) | ||
408 | goto err; | ||
409 | } | ||
410 | |||
411 | meth = &zlib_stateful_method; | ||
412 | } | ||
413 | err: | ||
414 | #endif | 211 | #endif |
415 | 212 | ||
416 | return(meth); | 213 | return(meth); |
417 | } | 214 | } |
418 | 215 | ||
419 | void COMP_zlib_cleanup(void) | ||
420 | { | ||
421 | #ifdef ZLIB_SHARED | ||
422 | if (zlib_dso) | ||
423 | DSO_free(zlib_dso); | ||
424 | #endif | ||
425 | } | ||
426 | |||
427 | #ifdef ZLIB | ||
428 | |||
429 | /* Zlib based compression/decompression filter BIO */ | ||
430 | |||
431 | typedef struct | ||
432 | { | ||
433 | unsigned char *ibuf; /* Input buffer */ | ||
434 | int ibufsize; /* Buffer size */ | ||
435 | z_stream zin; /* Input decompress context */ | ||
436 | unsigned char *obuf; /* Output buffer */ | ||
437 | int obufsize; /* Output buffer size */ | ||
438 | unsigned char *optr; /* Position in output buffer */ | ||
439 | int ocount; /* Amount of data in output buffer */ | ||
440 | int odone; /* deflate EOF */ | ||
441 | int comp_level; /* Compression level to use */ | ||
442 | z_stream zout; /* Output compression context */ | ||
443 | } BIO_ZLIB_CTX; | ||
444 | |||
445 | #define ZLIB_DEFAULT_BUFSIZE 1024 | ||
446 | |||
447 | static int bio_zlib_new(BIO *bi); | ||
448 | static int bio_zlib_free(BIO *bi); | ||
449 | static int bio_zlib_read(BIO *b, char *out, int outl); | ||
450 | static int bio_zlib_write(BIO *b, const char *in, int inl); | ||
451 | static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr); | ||
452 | static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp); | ||
453 | |||
454 | static BIO_METHOD bio_meth_zlib = | ||
455 | { | ||
456 | BIO_TYPE_COMP, | ||
457 | "zlib", | ||
458 | bio_zlib_write, | ||
459 | bio_zlib_read, | ||
460 | NULL, | ||
461 | NULL, | ||
462 | bio_zlib_ctrl, | ||
463 | bio_zlib_new, | ||
464 | bio_zlib_free, | ||
465 | bio_zlib_callback_ctrl | ||
466 | }; | ||
467 | |||
468 | BIO_METHOD *BIO_f_zlib(void) | ||
469 | { | ||
470 | return &bio_meth_zlib; | ||
471 | } | ||
472 | |||
473 | |||
474 | static int bio_zlib_new(BIO *bi) | ||
475 | { | ||
476 | BIO_ZLIB_CTX *ctx; | ||
477 | #ifdef ZLIB_SHARED | ||
478 | (void)COMP_zlib(); | ||
479 | if (!zlib_loaded) | ||
480 | { | ||
481 | COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED); | ||
482 | return 0; | ||
483 | } | ||
484 | #endif | ||
485 | ctx = OPENSSL_malloc(sizeof(BIO_ZLIB_CTX)); | ||
486 | if(!ctx) | ||
487 | { | ||
488 | COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE); | ||
489 | return 0; | ||
490 | } | ||
491 | ctx->ibuf = NULL; | ||
492 | ctx->obuf = NULL; | ||
493 | ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE; | ||
494 | ctx->obufsize = ZLIB_DEFAULT_BUFSIZE; | ||
495 | ctx->zin.zalloc = Z_NULL; | ||
496 | ctx->zin.zfree = Z_NULL; | ||
497 | ctx->zin.next_in = NULL; | ||
498 | ctx->zin.avail_in = 0; | ||
499 | ctx->zin.next_out = NULL; | ||
500 | ctx->zin.avail_out = 0; | ||
501 | ctx->zout.zalloc = Z_NULL; | ||
502 | ctx->zout.zfree = Z_NULL; | ||
503 | ctx->zout.next_in = NULL; | ||
504 | ctx->zout.avail_in = 0; | ||
505 | ctx->zout.next_out = NULL; | ||
506 | ctx->zout.avail_out = 0; | ||
507 | ctx->odone = 0; | ||
508 | ctx->comp_level = Z_DEFAULT_COMPRESSION; | ||
509 | bi->init = 1; | ||
510 | bi->ptr = (char *)ctx; | ||
511 | bi->flags = 0; | ||
512 | return 1; | ||
513 | } | ||
514 | |||
515 | static int bio_zlib_free(BIO *bi) | ||
516 | { | ||
517 | BIO_ZLIB_CTX *ctx; | ||
518 | if(!bi) return 0; | ||
519 | ctx = (BIO_ZLIB_CTX *)bi->ptr; | ||
520 | if(ctx->ibuf) | ||
521 | { | ||
522 | /* Destroy decompress context */ | ||
523 | inflateEnd(&ctx->zin); | ||
524 | OPENSSL_free(ctx->ibuf); | ||
525 | } | ||
526 | if(ctx->obuf) | ||
527 | { | ||
528 | /* Destroy compress context */ | ||
529 | deflateEnd(&ctx->zout); | ||
530 | OPENSSL_free(ctx->obuf); | ||
531 | } | ||
532 | OPENSSL_free(ctx); | ||
533 | bi->ptr = NULL; | ||
534 | bi->init = 0; | ||
535 | bi->flags = 0; | ||
536 | return 1; | ||
537 | } | ||
538 | |||
539 | static int bio_zlib_read(BIO *b, char *out, int outl) | ||
540 | { | ||
541 | BIO_ZLIB_CTX *ctx; | ||
542 | int ret; | ||
543 | z_stream *zin; | ||
544 | if(!out || !outl) return 0; | ||
545 | ctx = (BIO_ZLIB_CTX *)b->ptr; | ||
546 | zin = &ctx->zin; | ||
547 | BIO_clear_retry_flags(b); | ||
548 | if(!ctx->ibuf) | ||
549 | { | ||
550 | ctx->ibuf = OPENSSL_malloc(ctx->ibufsize); | ||
551 | if(!ctx->ibuf) | ||
552 | { | ||
553 | COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE); | ||
554 | return 0; | ||
555 | } | ||
556 | inflateInit(zin); | ||
557 | zin->next_in = ctx->ibuf; | ||
558 | zin->avail_in = 0; | ||
559 | } | ||
560 | |||
561 | /* Copy output data directly to supplied buffer */ | ||
562 | zin->next_out = (unsigned char *)out; | ||
563 | zin->avail_out = (unsigned int)outl; | ||
564 | for(;;) | ||
565 | { | ||
566 | /* Decompress while data available */ | ||
567 | while(zin->avail_in) | ||
568 | { | ||
569 | ret = inflate(zin, 0); | ||
570 | if((ret != Z_OK) && (ret != Z_STREAM_END)) | ||
571 | { | ||
572 | COMPerr(COMP_F_BIO_ZLIB_READ, | ||
573 | COMP_R_ZLIB_INFLATE_ERROR); | ||
574 | ERR_add_error_data(2, "zlib error:", | ||
575 | zError(ret)); | ||
576 | return 0; | ||
577 | } | ||
578 | /* If EOF or we've read everything then return */ | ||
579 | if((ret == Z_STREAM_END) || !zin->avail_out) | ||
580 | return outl - zin->avail_out; | ||
581 | } | ||
582 | |||
583 | /* No data in input buffer try to read some in, | ||
584 | * if an error then return the total data read. | ||
585 | */ | ||
586 | ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize); | ||
587 | if(ret <= 0) | ||
588 | { | ||
589 | /* Total data read */ | ||
590 | int tot = outl - zin->avail_out; | ||
591 | BIO_copy_next_retry(b); | ||
592 | if(ret < 0) return (tot > 0) ? tot : ret; | ||
593 | return tot; | ||
594 | } | ||
595 | zin->avail_in = ret; | ||
596 | zin->next_in = ctx->ibuf; | ||
597 | } | ||
598 | } | ||
599 | |||
600 | static int bio_zlib_write(BIO *b, const char *in, int inl) | ||
601 | { | ||
602 | BIO_ZLIB_CTX *ctx; | ||
603 | int ret; | ||
604 | z_stream *zout; | ||
605 | if(!in || !inl) return 0; | ||
606 | ctx = (BIO_ZLIB_CTX *)b->ptr; | ||
607 | if(ctx->odone) return 0; | ||
608 | zout = &ctx->zout; | ||
609 | BIO_clear_retry_flags(b); | ||
610 | if(!ctx->obuf) | ||
611 | { | ||
612 | ctx->obuf = OPENSSL_malloc(ctx->obufsize); | ||
613 | /* Need error here */ | ||
614 | if(!ctx->obuf) | ||
615 | { | ||
616 | COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE); | ||
617 | return 0; | ||
618 | } | ||
619 | ctx->optr = ctx->obuf; | ||
620 | ctx->ocount = 0; | ||
621 | deflateInit(zout, ctx->comp_level); | ||
622 | zout->next_out = ctx->obuf; | ||
623 | zout->avail_out = ctx->obufsize; | ||
624 | } | ||
625 | /* Obtain input data directly from supplied buffer */ | ||
626 | zout->next_in = (void *)in; | ||
627 | zout->avail_in = inl; | ||
628 | for(;;) | ||
629 | { | ||
630 | /* If data in output buffer write it first */ | ||
631 | while(ctx->ocount) { | ||
632 | ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount); | ||
633 | if(ret <= 0) | ||
634 | { | ||
635 | /* Total data written */ | ||
636 | int tot = inl - zout->avail_in; | ||
637 | BIO_copy_next_retry(b); | ||
638 | if(ret < 0) return (tot > 0) ? tot : ret; | ||
639 | return tot; | ||
640 | } | ||
641 | ctx->optr += ret; | ||
642 | ctx->ocount -= ret; | ||
643 | } | ||
644 | |||
645 | /* Have we consumed all supplied data? */ | ||
646 | if(!zout->avail_in) | ||
647 | return inl; | ||
648 | |||
649 | /* Compress some more */ | ||
650 | |||
651 | /* Reset buffer */ | ||
652 | ctx->optr = ctx->obuf; | ||
653 | zout->next_out = ctx->obuf; | ||
654 | zout->avail_out = ctx->obufsize; | ||
655 | /* Compress some more */ | ||
656 | ret = deflate(zout, 0); | ||
657 | if(ret != Z_OK) | ||
658 | { | ||
659 | COMPerr(COMP_F_BIO_ZLIB_WRITE, | ||
660 | COMP_R_ZLIB_DEFLATE_ERROR); | ||
661 | ERR_add_error_data(2, "zlib error:", zError(ret)); | ||
662 | return 0; | ||
663 | } | ||
664 | ctx->ocount = ctx->obufsize - zout->avail_out; | ||
665 | } | ||
666 | } | ||
667 | |||
668 | static int bio_zlib_flush(BIO *b) | ||
669 | { | ||
670 | BIO_ZLIB_CTX *ctx; | ||
671 | int ret; | ||
672 | z_stream *zout; | ||
673 | ctx = (BIO_ZLIB_CTX *)b->ptr; | ||
674 | /* If no data written or already flush show success */ | ||
675 | if(!ctx->obuf || (ctx->odone && !ctx->ocount)) return 1; | ||
676 | zout = &ctx->zout; | ||
677 | BIO_clear_retry_flags(b); | ||
678 | /* No more input data */ | ||
679 | zout->next_in = NULL; | ||
680 | zout->avail_in = 0; | ||
681 | for(;;) | ||
682 | { | ||
683 | /* If data in output buffer write it first */ | ||
684 | while(ctx->ocount) | ||
685 | { | ||
686 | ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount); | ||
687 | if(ret <= 0) | ||
688 | { | ||
689 | BIO_copy_next_retry(b); | ||
690 | return ret; | ||
691 | } | ||
692 | ctx->optr += ret; | ||
693 | ctx->ocount -= ret; | ||
694 | } | ||
695 | if(ctx->odone) return 1; | ||
696 | |||
697 | /* Compress some more */ | ||
698 | |||
699 | /* Reset buffer */ | ||
700 | ctx->optr = ctx->obuf; | ||
701 | zout->next_out = ctx->obuf; | ||
702 | zout->avail_out = ctx->obufsize; | ||
703 | /* Compress some more */ | ||
704 | ret = deflate(zout, Z_FINISH); | ||
705 | if(ret == Z_STREAM_END) ctx->odone = 1; | ||
706 | else if(ret != Z_OK) | ||
707 | { | ||
708 | COMPerr(COMP_F_BIO_ZLIB_FLUSH, | ||
709 | COMP_R_ZLIB_DEFLATE_ERROR); | ||
710 | ERR_add_error_data(2, "zlib error:", zError(ret)); | ||
711 | return 0; | ||
712 | } | ||
713 | ctx->ocount = ctx->obufsize - zout->avail_out; | ||
714 | } | ||
715 | } | ||
716 | |||
717 | static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) | ||
718 | { | ||
719 | BIO_ZLIB_CTX *ctx; | ||
720 | int ret, *ip; | ||
721 | int ibs, obs; | ||
722 | if(!b->next_bio) return 0; | ||
723 | ctx = (BIO_ZLIB_CTX *)b->ptr; | ||
724 | switch (cmd) | ||
725 | { | ||
726 | |||
727 | case BIO_CTRL_RESET: | ||
728 | ctx->ocount = 0; | ||
729 | ctx->odone = 0; | ||
730 | break; | ||
731 | |||
732 | case BIO_CTRL_FLUSH: | ||
733 | ret = bio_zlib_flush(b); | ||
734 | if (ret > 0) | ||
735 | ret = BIO_flush(b->next_bio); | ||
736 | break; | ||
737 | |||
738 | case BIO_C_SET_BUFF_SIZE: | ||
739 | ibs = -1; | ||
740 | obs = -1; | ||
741 | if (ptr != NULL) | ||
742 | { | ||
743 | ip = ptr; | ||
744 | if (*ip == 0) | ||
745 | ibs = (int) num; | ||
746 | else | ||
747 | obs = (int) num; | ||
748 | } | ||
749 | else | ||
750 | { | ||
751 | ibs = (int)num; | ||
752 | obs = ibs; | ||
753 | } | ||
754 | |||
755 | if (ibs != -1) | ||
756 | { | ||
757 | if (ctx->ibuf) | ||
758 | { | ||
759 | OPENSSL_free(ctx->ibuf); | ||
760 | ctx->ibuf = NULL; | ||
761 | } | ||
762 | ctx->ibufsize = ibs; | ||
763 | } | ||
764 | |||
765 | if (obs != -1) | ||
766 | { | ||
767 | if (ctx->obuf) | ||
768 | { | ||
769 | OPENSSL_free(ctx->obuf); | ||
770 | ctx->obuf = NULL; | ||
771 | } | ||
772 | ctx->obufsize = obs; | ||
773 | } | ||
774 | |||
775 | break; | ||
776 | |||
777 | case BIO_C_DO_STATE_MACHINE: | ||
778 | BIO_clear_retry_flags(b); | ||
779 | ret = BIO_ctrl(b->next_bio, cmd, num, ptr); | ||
780 | BIO_copy_next_retry(b); | ||
781 | break; | ||
782 | |||
783 | default: | ||
784 | ret = BIO_ctrl(b->next_bio, cmd, num, ptr); | ||
785 | break; | ||
786 | |||
787 | } | ||
788 | |||
789 | return ret; | ||
790 | } | ||
791 | |||
792 | |||
793 | static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) | ||
794 | { | ||
795 | if(!b->next_bio) | ||
796 | return 0; | ||
797 | return | ||
798 | BIO_callback_ctrl(b->next_bio, cmd, fp); | ||
799 | } | ||
800 | |||
801 | #endif | ||