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