diff options
author | djm <> | 2008-09-06 12:17:54 +0000 |
---|---|---|
committer | djm <> | 2008-09-06 12:17:54 +0000 |
commit | 38ce604e3cc97706b876b0525ddff0121115456d (patch) | |
tree | 7ccc28afe1789ea3dbedf72365f955d5b8e105b5 /src/lib/libcrypto/comp/c_zlib.c | |
parent | 12867252827c8efaa8ddd1fa3b3d6e321e2bcdef (diff) | |
download | openbsd-38ce604e3cc97706b876b0525ddff0121115456d.tar.gz openbsd-38ce604e3cc97706b876b0525ddff0121115456d.tar.bz2 openbsd-38ce604e3cc97706b876b0525ddff0121115456d.zip |
resolve conflicts
Diffstat (limited to 'src/lib/libcrypto/comp/c_zlib.c')
-rw-r--r-- | src/lib/libcrypto/comp/c_zlib.c | 600 |
1 files changed, 593 insertions, 7 deletions
diff --git a/src/lib/libcrypto/comp/c_zlib.c b/src/lib/libcrypto/comp/c_zlib.c index 5fcb521ffb..0f34597e70 100644 --- a/src/lib/libcrypto/comp/c_zlib.c +++ b/src/lib/libcrypto/comp/c_zlib.c | |||
@@ -24,6 +24,32 @@ 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 | ||
27 | static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, | 53 | static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, |
28 | unsigned int olen, unsigned char *in, unsigned int ilen); | 54 | unsigned int olen, unsigned char *in, unsigned int ilen); |
29 | static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, | 55 | static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, |
@@ -32,7 +58,7 @@ static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, | |||
32 | static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, | 58 | static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, |
33 | uLong sourceLen); | 59 | uLong sourceLen); |
34 | 60 | ||
35 | static COMP_METHOD zlib_method={ | 61 | static COMP_METHOD zlib_stateless_method={ |
36 | NID_zlib_compression, | 62 | NID_zlib_compression, |
37 | LN_zlib_compression, | 63 | LN_zlib_compression, |
38 | NULL, | 64 | NULL, |
@@ -42,12 +68,24 @@ static COMP_METHOD zlib_method={ | |||
42 | NULL, | 68 | NULL, |
43 | NULL, | 69 | NULL, |
44 | }; | 70 | }; |
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 | }; | ||
45 | 83 | ||
46 | /* | 84 | /* |
47 | * When OpenSSL is built on Windows, we do not want to require that | 85 | * When OpenSSL is built on Windows, we do not want to require that |
48 | * the ZLIB.DLL be available in order for the OpenSSL DLLs to | 86 | * the ZLIB.DLL be available in order for the OpenSSL DLLs to |
49 | * work. Therefore, all ZLIB routines are loaded at run time | 87 | * work. Therefore, all ZLIB routines are loaded at run time |
50 | * and we do not link to a .LIB file. | 88 | * and we do not link to a .LIB file when ZLIB_SHARED is set. |
51 | */ | 89 | */ |
52 | #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) | 90 | #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) |
53 | # include <windows.h> | 91 | # include <windows.h> |
@@ -63,10 +101,19 @@ typedef int (*inflateEnd_ft)(z_streamp strm); | |||
63 | typedef int (*inflate_ft)(z_streamp strm, int flush); | 101 | typedef int (*inflate_ft)(z_streamp strm, int flush); |
64 | typedef int (*inflateInit__ft)(z_streamp strm, | 102 | typedef int (*inflateInit__ft)(z_streamp strm, |
65 | const char * version, int stream_size); | 103 | 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); | ||
66 | static compress_ft p_compress=NULL; | 109 | static compress_ft p_compress=NULL; |
67 | static inflateEnd_ft p_inflateEnd=NULL; | 110 | static inflateEnd_ft p_inflateEnd=NULL; |
68 | static inflate_ft p_inflate=NULL; | 111 | static inflate_ft p_inflate=NULL; |
69 | static inflateInit__ft p_inflateInit_=NULL; | 112 | 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; | ||
70 | 117 | ||
71 | static int zlib_loaded = 0; /* only attempt to init func pts once */ | 118 | static int zlib_loaded = 0; /* only attempt to init func pts once */ |
72 | static DSO *zlib_dso = NULL; | 119 | static DSO *zlib_dso = NULL; |
@@ -75,10 +122,133 @@ static DSO *zlib_dso = NULL; | |||
75 | #define inflateEnd p_inflateEnd | 122 | #define inflateEnd p_inflateEnd |
76 | #define inflate p_inflate | 123 | #define inflate p_inflate |
77 | #define inflateInit_ p_inflateInit_ | 124 | #define inflateInit_ p_inflateInit_ |
125 | #define deflateEnd p_deflateEnd | ||
126 | #define deflate p_deflate | ||
127 | #define deflateInit_ p_deflateInit_ | ||
128 | #define zError p_zError | ||
78 | #endif /* ZLIB_SHARED */ | 129 | #endif /* ZLIB_SHARED */ |
79 | 130 | ||
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 | ||
80 | static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, | 250 | static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, |
81 | unsigned int olen, unsigned char *in, unsigned int ilen) | 251 | unsigned int olen, unsigned char *in, unsigned int ilen) |
82 | { | 252 | { |
83 | unsigned long l; | 253 | unsigned long l; |
84 | int i; | 254 | int i; |
@@ -111,7 +281,7 @@ static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, | |||
111 | } | 281 | } |
112 | 282 | ||
113 | static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, | 283 | static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, |
114 | unsigned int olen, unsigned char *in, unsigned int ilen) | 284 | unsigned int olen, unsigned char *in, unsigned int ilen) |
115 | { | 285 | { |
116 | unsigned long l; | 286 | unsigned long l; |
117 | int i; | 287 | int i; |
@@ -153,7 +323,8 @@ static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, | |||
153 | stream.zalloc = (alloc_func)0; | 323 | stream.zalloc = (alloc_func)0; |
154 | stream.zfree = (free_func)0; | 324 | stream.zfree = (free_func)0; |
155 | 325 | ||
156 | err = inflateInit(&stream); | 326 | err = inflateInit_(&stream, |
327 | ZLIB_VERSION, sizeof(z_stream)); | ||
157 | if (err != Z_OK) return err; | 328 | if (err != Z_OK) return err; |
158 | 329 | ||
159 | err = inflate(&stream, Z_FINISH); | 330 | err = inflate(&stream, Z_FINISH); |
@@ -166,6 +337,7 @@ static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, | |||
166 | err = inflateEnd(&stream); | 337 | err = inflateEnd(&stream); |
167 | return err; | 338 | return err; |
168 | } | 339 | } |
340 | #endif | ||
169 | 341 | ||
170 | #endif | 342 | #endif |
171 | 343 | ||
@@ -195,9 +367,22 @@ COMP_METHOD *COMP_zlib(void) | |||
195 | p_inflateInit_ | 367 | p_inflateInit_ |
196 | = (inflateInit__ft) DSO_bind_func(zlib_dso, | 368 | = (inflateInit__ft) DSO_bind_func(zlib_dso, |
197 | "inflateInit_"); | 369 | "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"); | ||
198 | 382 | ||
199 | if (p_compress && p_inflateEnd && p_inflate | 383 | if (p_compress && p_inflateEnd && p_inflate |
200 | && p_inflateInit_) | 384 | && p_inflateInit_ && p_deflateEnd |
385 | && p_deflate && p_deflateInit_ && p_zError) | ||
201 | zlib_loaded++; | 386 | zlib_loaded++; |
202 | } | 387 | } |
203 | } | 388 | } |
@@ -207,9 +392,410 @@ COMP_METHOD *COMP_zlib(void) | |||
207 | if (zlib_loaded) | 392 | if (zlib_loaded) |
208 | #endif | 393 | #endif |
209 | #if defined(ZLIB) || defined(ZLIB_SHARED) | 394 | #if defined(ZLIB) || defined(ZLIB_SHARED) |
210 | meth = &zlib_method; | 395 | { |
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: | ||
211 | #endif | 414 | #endif |
212 | 415 | ||
213 | return(meth); | 416 | return(meth); |
214 | } | 417 | } |
215 | 418 | ||
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 | ||