summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/comp/c_zlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/comp/c_zlib.c')
-rw-r--r--src/lib/libcrypto/comp/c_zlib.c564
1 files changed, 0 insertions, 564 deletions
diff --git a/src/lib/libcrypto/comp/c_zlib.c b/src/lib/libcrypto/comp/c_zlib.c
deleted file mode 100644
index d9a3359313..0000000000
--- a/src/lib/libcrypto/comp/c_zlib.c
+++ /dev/null
@@ -1,564 +0,0 @@
1/* $OpenBSD: c_zlib.c,v 1.18 2015/12/23 20:37:23 mmcc Exp $ */
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <openssl/objects.h>
6#include <openssl/comp.h>
7#include <openssl/err.h>
8
9COMP_METHOD *COMP_zlib(void );
10
11static COMP_METHOD zlib_method_nozlib = {
12 .type = NID_undef,
13 .name = "(undef)"
14};
15
16#ifdef ZLIB
17
18#include <zlib.h>
19
20static int zlib_stateful_init(COMP_CTX *ctx);
21static void zlib_stateful_finish(COMP_CTX *ctx);
22static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
23 unsigned int olen, unsigned char *in, unsigned int ilen);
24static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
25 unsigned int olen, unsigned char *in, unsigned int ilen);
26
27
28/* memory allocations functions for zlib intialization */
29static void*
30zlib_zalloc(void* opaque, unsigned int no, unsigned int size)
31{
32 return calloc(no, size);
33}
34
35static void
36zlib_zfree(void* opaque, void* address)
37{
38 free(address);
39}
40
41static COMP_METHOD zlib_stateful_method = {
42 .type = NID_zlib_compression,
43 .name = LN_zlib_compression,
44 .init = zlib_stateful_init,
45 .finish = zlib_stateful_finish,
46 .compress = zlib_stateful_compress_block,
47 .expand = zlib_stateful_expand_block
48};
49
50struct zlib_state {
51 z_stream istream;
52 z_stream ostream;
53};
54
55static int zlib_stateful_ex_idx = -1;
56
57static int
58zlib_stateful_init(COMP_CTX *ctx)
59{
60 int err;
61 struct zlib_state *state = malloc(sizeof(struct zlib_state));
62
63 if (state == NULL)
64 goto err;
65
66 state->istream.zalloc = zlib_zalloc;
67 state->istream.zfree = zlib_zfree;
68 state->istream.opaque = Z_NULL;
69 state->istream.next_in = Z_NULL;
70 state->istream.next_out = Z_NULL;
71 state->istream.avail_in = 0;
72 state->istream.avail_out = 0;
73 err = inflateInit_(&state->istream, ZLIB_VERSION, sizeof(z_stream));
74 if (err != Z_OK)
75 goto err;
76
77 state->ostream.zalloc = zlib_zalloc;
78 state->ostream.zfree = zlib_zfree;
79 state->ostream.opaque = Z_NULL;
80 state->ostream.next_in = Z_NULL;
81 state->ostream.next_out = Z_NULL;
82 state->ostream.avail_in = 0;
83 state->ostream.avail_out = 0;
84 err = deflateInit_(&state->ostream, Z_DEFAULT_COMPRESSION,
85 ZLIB_VERSION, sizeof(z_stream));
86 if (err != Z_OK)
87 goto err;
88
89 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data);
90 CRYPTO_set_ex_data(&ctx->ex_data, zlib_stateful_ex_idx, state);
91 return 1;
92
93err:
94 free(state);
95 return 0;
96}
97
98static void
99zlib_stateful_finish(COMP_CTX *ctx)
100{
101 struct zlib_state *state =
102 (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
103 zlib_stateful_ex_idx);
104
105 inflateEnd(&state->istream);
106 deflateEnd(&state->ostream);
107 free(state);
108 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data);
109}
110
111static int
112zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
113 unsigned int olen, unsigned char *in, unsigned int ilen)
114{
115 int err = Z_OK;
116 struct zlib_state *state =
117 (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
118 zlib_stateful_ex_idx);
119
120 if (state == NULL)
121 return -1;
122
123 state->ostream.next_in = in;
124 state->ostream.avail_in = ilen;
125 state->ostream.next_out = out;
126 state->ostream.avail_out = olen;
127 if (ilen > 0)
128 err = deflate(&state->ostream, Z_SYNC_FLUSH);
129 if (err != Z_OK)
130 return -1;
131
132#ifdef DEBUG_ZLIB
133 fprintf(stderr, "compress(%4d)->%4d %s\n",
134 ilen, olen - state->ostream.avail_out,
135 (ilen != olen - state->ostream.avail_out)?"zlib":"clear");
136#endif
137
138 return olen - state->ostream.avail_out;
139}
140
141static int
142zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
143 unsigned int olen, unsigned char *in, unsigned int ilen)
144{
145 int err = Z_OK;
146
147 struct zlib_state *state =
148 (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
149 zlib_stateful_ex_idx);
150
151 if (state == NULL)
152 return 0;
153
154 state->istream.next_in = in;
155 state->istream.avail_in = ilen;
156 state->istream.next_out = out;
157 state->istream.avail_out = olen;
158 if (ilen > 0)
159 err = inflate(&state->istream, Z_SYNC_FLUSH);
160 if (err != Z_OK)
161 return -1;
162
163#ifdef DEBUG_ZLIB
164 fprintf(stderr, "expand(%4d)->%4d %s\n",
165 ilen, olen - state->istream.avail_out,
166 (ilen != olen - state->istream.avail_out)?"zlib":"clear");
167#endif
168
169 return olen - state->istream.avail_out;
170}
171
172#endif
173
174COMP_METHOD *
175COMP_zlib(void)
176{
177 COMP_METHOD *meth = &zlib_method_nozlib;
178
179#ifdef ZLIB
180 {
181 /* init zlib_stateful_ex_idx here so that in a multi-process
182 * application it's enough to intialize openssl before forking
183 * (idx will be inherited in all the children) */
184 if (zlib_stateful_ex_idx == -1) {
185 CRYPTO_w_lock(CRYPTO_LOCK_COMP);
186 if (zlib_stateful_ex_idx == -1)
187 zlib_stateful_ex_idx =
188 CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
189 0, NULL, NULL, NULL, NULL);
190 CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
191 if (zlib_stateful_ex_idx == -1)
192 goto err;
193 }
194
195 meth = &zlib_stateful_method;
196 }
197
198err:
199#endif
200
201 return (meth);
202}
203
204void
205COMP_zlib_cleanup(void)
206{
207}
208
209#ifdef ZLIB
210
211/* Zlib based compression/decompression filter BIO */
212
213typedef struct {
214 unsigned char *ibuf; /* Input buffer */
215 int ibufsize; /* Buffer size */
216 z_stream zin; /* Input decompress context */
217 unsigned char *obuf; /* Output buffer */
218 int obufsize; /* Output buffer size */
219 unsigned char *optr; /* Position in output buffer */
220 int ocount; /* Amount of data in output buffer */
221 int odone; /* deflate EOF */
222 int comp_level; /* Compression level to use */
223 z_stream zout; /* Output compression context */
224} BIO_ZLIB_CTX;
225
226#define ZLIB_DEFAULT_BUFSIZE 1024
227
228static int bio_zlib_new(BIO *bi);
229static int bio_zlib_free(BIO *bi);
230static int bio_zlib_read(BIO *b, char *out, int outl);
231static int bio_zlib_write(BIO *b, const char *in, int inl);
232static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);
233static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp);
234
235static BIO_METHOD bio_meth_zlib = {
236 .type = BIO_TYPE_COMP,
237 .name = "zlib",
238 .bwrite = bio_zlib_write,
239 .bread = bio_zlib_read,
240 .ctrl = bio_zlib_ctrl,
241 .create = bio_zlib_new,
242 .destroy = bio_zlib_free,
243 .callback_ctrl = bio_zlib_callback_ctrl
244};
245
246BIO_METHOD *
247BIO_f_zlib(void)
248{
249 return &bio_meth_zlib;
250}
251
252
253static int
254bio_zlib_new(BIO *bi)
255{
256 BIO_ZLIB_CTX *ctx;
257
258 ctx = malloc(sizeof(BIO_ZLIB_CTX));
259 if (!ctx) {
260 COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE);
261 return 0;
262 }
263 ctx->ibuf = NULL;
264 ctx->obuf = NULL;
265 ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;
266 ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;
267 ctx->zin.zalloc = Z_NULL;
268 ctx->zin.zfree = Z_NULL;
269 ctx->zin.next_in = NULL;
270 ctx->zin.avail_in = 0;
271 ctx->zin.next_out = NULL;
272 ctx->zin.avail_out = 0;
273 ctx->zout.zalloc = Z_NULL;
274 ctx->zout.zfree = Z_NULL;
275 ctx->zout.next_in = NULL;
276 ctx->zout.avail_in = 0;
277 ctx->zout.next_out = NULL;
278 ctx->zout.avail_out = 0;
279 ctx->odone = 0;
280 ctx->comp_level = Z_DEFAULT_COMPRESSION;
281 bi->init = 1;
282 bi->ptr = (char *)ctx;
283 bi->flags = 0;
284 return 1;
285}
286
287static int
288bio_zlib_free(BIO *bi)
289{
290 BIO_ZLIB_CTX *ctx;
291
292 if (!bi)
293 return 0;
294 ctx = (BIO_ZLIB_CTX *)bi->ptr;
295 if (ctx->ibuf) {
296 /* Destroy decompress context */
297 inflateEnd(&ctx->zin);
298 free(ctx->ibuf);
299 }
300 if (ctx->obuf) {
301 /* Destroy compress context */
302 deflateEnd(&ctx->zout);
303 free(ctx->obuf);
304 }
305 free(ctx);
306 bi->ptr = NULL;
307 bi->init = 0;
308 bi->flags = 0;
309 return 1;
310}
311
312static int
313bio_zlib_read(BIO *b, char *out, int outl)
314{
315 BIO_ZLIB_CTX *ctx;
316 int ret;
317 z_stream *zin;
318
319 if (!out || !outl)
320 return 0;
321 ctx = (BIO_ZLIB_CTX *)b->ptr;
322 zin = &ctx->zin;
323 BIO_clear_retry_flags(b);
324 if (!ctx->ibuf) {
325 ctx->ibuf = malloc(ctx->ibufsize);
326 if (!ctx->ibuf) {
327 COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE);
328 return 0;
329 }
330 inflateInit(zin);
331 zin->next_in = ctx->ibuf;
332 zin->avail_in = 0;
333 }
334
335 /* Copy output data directly to supplied buffer */
336 zin->next_out = (unsigned char *)out;
337 zin->avail_out = (unsigned int)outl;
338 for (;;) {
339 /* Decompress while data available */
340 while (zin->avail_in) {
341 ret = inflate(zin, 0);
342 if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
343 COMPerr(COMP_F_BIO_ZLIB_READ,
344 COMP_R_ZLIB_INFLATE_ERROR);
345 ERR_asprintf_error_data("zlib error:%s",
346 zError(ret));
347 return 0;
348 }
349 /* If EOF or we've read everything then return */
350 if ((ret == Z_STREAM_END) || !zin->avail_out)
351 return outl - zin->avail_out;
352 }
353
354 /* No data in input buffer try to read some in,
355 * if an error then return the total data read.
356 */
357 ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize);
358 if (ret <= 0) {
359 /* Total data read */
360 int tot = outl - zin->avail_out;
361 BIO_copy_next_retry(b);
362 if (ret < 0)
363 return (tot > 0) ? tot : ret;
364 return tot;
365 }
366 zin->avail_in = ret;
367 zin->next_in = ctx->ibuf;
368 }
369}
370
371static int
372bio_zlib_write(BIO *b, const char *in, int inl)
373{
374 BIO_ZLIB_CTX *ctx;
375 int ret;
376 z_stream *zout;
377
378 if (!in || !inl)
379 return 0;
380 ctx = (BIO_ZLIB_CTX *)b->ptr;
381 if (ctx->odone)
382 return 0;
383 zout = &ctx->zout;
384 BIO_clear_retry_flags(b);
385 if (!ctx->obuf) {
386 ctx->obuf = malloc(ctx->obufsize);
387 /* Need error here */
388 if (!ctx->obuf) {
389 COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE);
390 return 0;
391 }
392 ctx->optr = ctx->obuf;
393 ctx->ocount = 0;
394 deflateInit(zout, ctx->comp_level);
395 zout->next_out = ctx->obuf;
396 zout->avail_out = ctx->obufsize;
397 }
398 /* Obtain input data directly from supplied buffer */
399 zout->next_in = (void *)in;
400 zout->avail_in = inl;
401 for (;;) {
402 /* If data in output buffer write it first */
403 while (ctx->ocount) {
404 ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
405 if (ret <= 0) {
406 /* Total data written */
407 int tot = inl - zout->avail_in;
408 BIO_copy_next_retry(b);
409 if (ret < 0)
410 return (tot > 0) ? tot : ret;
411 return tot;
412 }
413 ctx->optr += ret;
414 ctx->ocount -= ret;
415 }
416
417 /* Have we consumed all supplied data? */
418 if (!zout->avail_in)
419 return inl;
420
421 /* Compress some more */
422
423 /* Reset buffer */
424 ctx->optr = ctx->obuf;
425 zout->next_out = ctx->obuf;
426 zout->avail_out = ctx->obufsize;
427 /* Compress some more */
428 ret = deflate(zout, 0);
429 if (ret != Z_OK) {
430 COMPerr(COMP_F_BIO_ZLIB_WRITE,
431 COMP_R_ZLIB_DEFLATE_ERROR);
432 ERR_asprintf_error_data("zlib error:%s", zError(ret));
433 return 0;
434 }
435 ctx->ocount = ctx->obufsize - zout->avail_out;
436 }
437}
438
439static int
440bio_zlib_flush(BIO *b)
441{
442 BIO_ZLIB_CTX *ctx;
443 int ret;
444 z_stream *zout;
445
446 ctx = (BIO_ZLIB_CTX *)b->ptr;
447 /* If no data written or already flush show success */
448 if (!ctx->obuf || (ctx->odone && !ctx->ocount))
449 return 1;
450 zout = &ctx->zout;
451 BIO_clear_retry_flags(b);
452 /* No more input data */
453 zout->next_in = NULL;
454 zout->avail_in = 0;
455 for (;;) {
456 /* If data in output buffer write it first */
457 while (ctx->ocount) {
458 ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
459 if (ret <= 0) {
460 BIO_copy_next_retry(b);
461 return ret;
462 }
463 ctx->optr += ret;
464 ctx->ocount -= ret;
465 }
466 if (ctx->odone)
467 return 1;
468
469 /* Compress some more */
470
471 /* Reset buffer */
472 ctx->optr = ctx->obuf;
473 zout->next_out = ctx->obuf;
474 zout->avail_out = ctx->obufsize;
475 /* Compress some more */
476 ret = deflate(zout, Z_FINISH);
477 if (ret == Z_STREAM_END)
478 ctx->odone = 1;
479 else if (ret != Z_OK) {
480 COMPerr(COMP_F_BIO_ZLIB_FLUSH,
481 COMP_R_ZLIB_DEFLATE_ERROR);
482 ERR_asprintf_error_data("zlib error:%s", zError(ret));
483 return 0;
484 }
485 ctx->ocount = ctx->obufsize - zout->avail_out;
486 }
487}
488
489static long
490bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
491{
492 BIO_ZLIB_CTX *ctx;
493 int ret, *ip;
494 int ibs, obs;
495 if (!b->next_bio)
496 return 0;
497 ctx = (BIO_ZLIB_CTX *)b->ptr;
498 switch (cmd) {
499
500 case BIO_CTRL_RESET:
501 ctx->ocount = 0;
502 ctx->odone = 0;
503 ret = 1;
504 break;
505
506 case BIO_CTRL_FLUSH:
507 ret = bio_zlib_flush(b);
508 if (ret > 0)
509 ret = BIO_flush(b->next_bio);
510 break;
511
512 case BIO_C_SET_BUFF_SIZE:
513 ibs = -1;
514 obs = -1;
515 if (ptr != NULL) {
516 ip = ptr;
517 if (*ip == 0)
518 ibs = (int) num;
519 else
520 obs = (int) num;
521 } else {
522 ibs = (int)num;
523 obs = ibs;
524 }
525
526 if (ibs != -1) {
527 free(ctx->ibuf);
528 ctx->ibuf = NULL;
529 ctx->ibufsize = ibs;
530 }
531
532 if (obs != -1) {
533 free(ctx->obuf);
534 ctx->obuf = NULL;
535 ctx->obufsize = obs;
536 }
537 ret = 1;
538 break;
539
540 case BIO_C_DO_STATE_MACHINE:
541 BIO_clear_retry_flags(b);
542 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
543 BIO_copy_next_retry(b);
544 break;
545
546 default:
547 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
548 break;
549
550 }
551
552 return ret;
553}
554
555
556static long
557bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
558{
559 if (!b->next_bio)
560 return 0;
561 return BIO_callback_ctrl(b->next_bio, cmd, fp);
562}
563
564#endif