summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/comp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/comp')
-rw-r--r--src/lib/libcrypto/comp/c_zlib.c542
-rw-r--r--src/lib/libcrypto/comp/comp.h8
2 files changed, 3 insertions, 547 deletions
diff --git a/src/lib/libcrypto/comp/c_zlib.c b/src/lib/libcrypto/comp/c_zlib.c
index 009737d59d..ec98b26f5c 100644
--- a/src/lib/libcrypto/comp/c_zlib.c
+++ b/src/lib/libcrypto/comp/c_zlib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: c_zlib.c,v 1.26 2023/04/17 13:18:00 tb Exp $ */ 1/* $OpenBSD: c_zlib.c,v 1.27 2023/06/11 05:35:43 tb Exp $ */
2/* 2/*
3 * --------------------------------------------------------------------------- 3 * ---------------------------------------------------------------------------
4 * Major patches to this file were contributed by 4 * Major patches to this file were contributed by
@@ -132,551 +132,13 @@ static COMP_METHOD zlib_method_nozlib = {
132 .name = "(undef)" 132 .name = "(undef)"
133}; 133};
134 134
135#ifdef ZLIB
136
137#include <zlib.h>
138
139static int zlib_stateful_init(COMP_CTX *ctx);
140static void zlib_stateful_finish(COMP_CTX *ctx);
141static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
142 unsigned int olen, unsigned char *in, unsigned int ilen);
143static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
144 unsigned int olen, unsigned char *in, unsigned int ilen);
145
146
147/* memory allocations functions for zlib initialization */
148static void*
149zlib_zalloc(void* opaque, unsigned int no, unsigned int size)
150{
151 return calloc(no, size);
152}
153
154static void
155zlib_zfree(void* opaque, void* address)
156{
157 free(address);
158}
159
160static COMP_METHOD zlib_stateful_method = {
161 .type = NID_zlib_compression,
162 .name = LN_zlib_compression,
163 .init = zlib_stateful_init,
164 .finish = zlib_stateful_finish,
165 .compress = zlib_stateful_compress_block,
166 .expand = zlib_stateful_expand_block
167};
168
169struct zlib_state {
170 z_stream istream;
171 z_stream ostream;
172};
173
174static int zlib_stateful_ex_idx = -1;
175
176static int
177zlib_stateful_init(COMP_CTX *ctx)
178{
179 int err;
180 struct zlib_state *state = malloc(sizeof(struct zlib_state));
181
182 if (state == NULL)
183 goto err;
184
185 state->istream.zalloc = zlib_zalloc;
186 state->istream.zfree = zlib_zfree;
187 state->istream.opaque = Z_NULL;
188 state->istream.next_in = Z_NULL;
189 state->istream.next_out = Z_NULL;
190 state->istream.avail_in = 0;
191 state->istream.avail_out = 0;
192 err = inflateInit_(&state->istream, ZLIB_VERSION, sizeof(z_stream));
193 if (err != Z_OK)
194 goto err;
195
196 state->ostream.zalloc = zlib_zalloc;
197 state->ostream.zfree = zlib_zfree;
198 state->ostream.opaque = Z_NULL;
199 state->ostream.next_in = Z_NULL;
200 state->ostream.next_out = Z_NULL;
201 state->ostream.avail_in = 0;
202 state->ostream.avail_out = 0;
203 err = deflateInit_(&state->ostream, Z_DEFAULT_COMPRESSION,
204 ZLIB_VERSION, sizeof(z_stream));
205 if (err != Z_OK)
206 goto err;
207
208 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data);
209 CRYPTO_set_ex_data(&ctx->ex_data, zlib_stateful_ex_idx, state);
210 return 1;
211
212err:
213 free(state);
214 return 0;
215}
216
217static void
218zlib_stateful_finish(COMP_CTX *ctx)
219{
220 struct zlib_state *state =
221 (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
222 zlib_stateful_ex_idx);
223
224 inflateEnd(&state->istream);
225 deflateEnd(&state->ostream);
226 free(state);
227 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data);
228}
229
230static int
231zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
232 unsigned int olen, unsigned char *in, unsigned int ilen)
233{
234 int err = Z_OK;
235 struct zlib_state *state =
236 (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
237 zlib_stateful_ex_idx);
238
239 if (state == NULL)
240 return -1;
241
242 state->ostream.next_in = in;
243 state->ostream.avail_in = ilen;
244 state->ostream.next_out = out;
245 state->ostream.avail_out = olen;
246 if (ilen > 0)
247 err = deflate(&state->ostream, Z_SYNC_FLUSH);
248 if (err != Z_OK)
249 return -1;
250
251#ifdef DEBUG_ZLIB
252 fprintf(stderr, "compress(%4d)->%4d %s\n",
253 ilen, olen - state->ostream.avail_out,
254 (ilen != olen - state->ostream.avail_out)?"zlib":"clear");
255#endif
256
257 return olen - state->ostream.avail_out;
258}
259
260static int
261zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
262 unsigned int olen, unsigned char *in, unsigned int ilen)
263{
264 int err = Z_OK;
265
266 struct zlib_state *state =
267 (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
268 zlib_stateful_ex_idx);
269
270 if (state == NULL)
271 return 0;
272
273 state->istream.next_in = in;
274 state->istream.avail_in = ilen;
275 state->istream.next_out = out;
276 state->istream.avail_out = olen;
277 if (ilen > 0)
278 err = inflate(&state->istream, Z_SYNC_FLUSH);
279 if (err != Z_OK)
280 return -1;
281
282#ifdef DEBUG_ZLIB
283 fprintf(stderr, "expand(%4d)->%4d %s\n",
284 ilen, olen - state->istream.avail_out,
285 (ilen != olen - state->istream.avail_out)?"zlib":"clear");
286#endif
287
288 return olen - state->istream.avail_out;
289}
290
291#endif
292
293COMP_METHOD * 135COMP_METHOD *
294COMP_zlib(void) 136COMP_zlib(void)
295{ 137{
296 COMP_METHOD *meth = &zlib_method_nozlib; 138 return &zlib_method_nozlib;
297
298#ifdef ZLIB
299 {
300 /* init zlib_stateful_ex_idx here so that in a multi-process
301 * application it's enough to initialize openssl before forking
302 * (idx will be inherited in all the children) */
303 if (zlib_stateful_ex_idx == -1) {
304 CRYPTO_w_lock(CRYPTO_LOCK_COMP);
305 if (zlib_stateful_ex_idx == -1)
306 zlib_stateful_ex_idx =
307 CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
308 0, NULL, NULL, NULL, NULL);
309 CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
310 if (zlib_stateful_ex_idx == -1)
311 goto err;
312 }
313 if (!OPENSSL_init_crypto(0, NULL))
314 goto err;
315
316 meth = &zlib_stateful_method;
317 }
318
319err:
320#endif
321
322 return (meth);
323} 139}
324 140
325void 141void
326COMP_zlib_cleanup(void) 142COMP_zlib_cleanup(void)
327{ 143{
328} 144}
329
330#ifdef ZLIB
331
332/* Zlib based compression/decompression filter BIO */
333
334typedef struct {
335 unsigned char *ibuf; /* Input buffer */
336 int ibufsize; /* Buffer size */
337 z_stream zin; /* Input decompress context */
338 unsigned char *obuf; /* Output buffer */
339 int obufsize; /* Output buffer size */
340 unsigned char *optr; /* Position in output buffer */
341 int ocount; /* Amount of data in output buffer */
342 int odone; /* deflate EOF */
343 int comp_level; /* Compression level to use */
344 z_stream zout; /* Output compression context */
345} BIO_ZLIB_CTX;
346
347#define ZLIB_DEFAULT_BUFSIZE 1024
348
349static int bio_zlib_new(BIO *bi);
350static int bio_zlib_free(BIO *bi);
351static int bio_zlib_read(BIO *b, char *out, int outl);
352static int bio_zlib_write(BIO *b, const char *in, int inl);
353static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);
354static long bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp);
355
356static BIO_METHOD bio_meth_zlib = {
357 .type = BIO_TYPE_COMP,
358 .name = "zlib",
359 .bwrite = bio_zlib_write,
360 .bread = bio_zlib_read,
361 .ctrl = bio_zlib_ctrl,
362 .create = bio_zlib_new,
363 .destroy = bio_zlib_free,
364 .callback_ctrl = bio_zlib_callback_ctrl
365};
366
367BIO_METHOD *
368BIO_f_zlib(void)
369{
370 return &bio_meth_zlib;
371}
372
373
374static int
375bio_zlib_new(BIO *bi)
376{
377 BIO_ZLIB_CTX *ctx;
378
379 ctx = malloc(sizeof(BIO_ZLIB_CTX));
380 if (!ctx) {
381 COMPerror(ERR_R_MALLOC_FAILURE);
382 return 0;
383 }
384 ctx->ibuf = NULL;
385 ctx->obuf = NULL;
386 ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;
387 ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;
388 ctx->zin.zalloc = Z_NULL;
389 ctx->zin.zfree = Z_NULL;
390 ctx->zin.next_in = NULL;
391 ctx->zin.avail_in = 0;
392 ctx->zin.next_out = NULL;
393 ctx->zin.avail_out = 0;
394 ctx->zout.zalloc = Z_NULL;
395 ctx->zout.zfree = Z_NULL;
396 ctx->zout.next_in = NULL;
397 ctx->zout.avail_in = 0;
398 ctx->zout.next_out = NULL;
399 ctx->zout.avail_out = 0;
400 ctx->odone = 0;
401 ctx->comp_level = Z_DEFAULT_COMPRESSION;
402 bi->init = 1;
403 bi->ptr = (char *)ctx;
404 bi->flags = 0;
405 return 1;
406}
407
408static int
409bio_zlib_free(BIO *bi)
410{
411 BIO_ZLIB_CTX *ctx;
412
413 if (!bi)
414 return 0;
415 ctx = (BIO_ZLIB_CTX *)bi->ptr;
416 if (ctx->ibuf) {
417 /* Destroy decompress context */
418 inflateEnd(&ctx->zin);
419 free(ctx->ibuf);
420 }
421 if (ctx->obuf) {
422 /* Destroy compress context */
423 deflateEnd(&ctx->zout);
424 free(ctx->obuf);
425 }
426 free(ctx);
427 bi->ptr = NULL;
428 bi->init = 0;
429 bi->flags = 0;
430 return 1;
431}
432
433static int
434bio_zlib_read(BIO *b, char *out, int outl)
435{
436 BIO_ZLIB_CTX *ctx;
437 int ret;
438 z_stream *zin;
439
440 if (!out || !outl)
441 return 0;
442 ctx = (BIO_ZLIB_CTX *)b->ptr;
443 zin = &ctx->zin;
444 BIO_clear_retry_flags(b);
445 if (!ctx->ibuf) {
446 ctx->ibuf = malloc(ctx->ibufsize);
447 if (!ctx->ibuf) {
448 COMPerror(ERR_R_MALLOC_FAILURE);
449 return 0;
450 }
451 inflateInit(zin);
452 zin->next_in = ctx->ibuf;
453 zin->avail_in = 0;
454 }
455
456 /* Copy output data directly to supplied buffer */
457 zin->next_out = (unsigned char *)out;
458 zin->avail_out = (unsigned int)outl;
459 for (;;) {
460 /* Decompress while data available */
461 while (zin->avail_in) {
462 ret = inflate(zin, 0);
463 if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
464 COMPerror(COMP_R_ZLIB_INFLATE_ERROR);
465 ERR_asprintf_error_data("zlib error:%s",
466 zError(ret));
467 return 0;
468 }
469 /* If EOF or we've read everything then return */
470 if ((ret == Z_STREAM_END) || !zin->avail_out)
471 return outl - zin->avail_out;
472 }
473
474 /* No data in input buffer try to read some in,
475 * if an error then return the total data read.
476 */
477 ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize);
478 if (ret <= 0) {
479 /* Total data read */
480 int tot = outl - zin->avail_out;
481 BIO_copy_next_retry(b);
482 if (ret < 0)
483 return (tot > 0) ? tot : ret;
484 return tot;
485 }
486 zin->avail_in = ret;
487 zin->next_in = ctx->ibuf;
488 }
489}
490
491static int
492bio_zlib_write(BIO *b, const char *in, int inl)
493{
494 BIO_ZLIB_CTX *ctx;
495 int ret;
496 z_stream *zout;
497
498 if (!in || !inl)
499 return 0;
500 ctx = (BIO_ZLIB_CTX *)b->ptr;
501 if (ctx->odone)
502 return 0;
503 zout = &ctx->zout;
504 BIO_clear_retry_flags(b);
505 if (!ctx->obuf) {
506 ctx->obuf = malloc(ctx->obufsize);
507 /* Need error here */
508 if (!ctx->obuf) {
509 COMPerror(ERR_R_MALLOC_FAILURE);
510 return 0;
511 }
512 ctx->optr = ctx->obuf;
513 ctx->ocount = 0;
514 deflateInit(zout, ctx->comp_level);
515 zout->next_out = ctx->obuf;
516 zout->avail_out = ctx->obufsize;
517 }
518 /* Obtain input data directly from supplied buffer */
519 zout->next_in = (void *)in;
520 zout->avail_in = inl;
521 for (;;) {
522 /* If data in output buffer write it first */
523 while (ctx->ocount) {
524 ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
525 if (ret <= 0) {
526 /* Total data written */
527 int tot = inl - zout->avail_in;
528 BIO_copy_next_retry(b);
529 if (ret < 0)
530 return (tot > 0) ? tot : ret;
531 return tot;
532 }
533 ctx->optr += ret;
534 ctx->ocount -= ret;
535 }
536
537 /* Have we consumed all supplied data? */
538 if (!zout->avail_in)
539 return inl;
540
541 /* Compress some more */
542
543 /* Reset buffer */
544 ctx->optr = ctx->obuf;
545 zout->next_out = ctx->obuf;
546 zout->avail_out = ctx->obufsize;
547 /* Compress some more */
548 ret = deflate(zout, 0);
549 if (ret != Z_OK) {
550 COMPerror(COMP_R_ZLIB_DEFLATE_ERROR);
551 ERR_asprintf_error_data("zlib error:%s", zError(ret));
552 return 0;
553 }
554 ctx->ocount = ctx->obufsize - zout->avail_out;
555 }
556}
557
558static int
559bio_zlib_flush(BIO *b)
560{
561 BIO_ZLIB_CTX *ctx;
562 int ret;
563 z_stream *zout;
564
565 ctx = (BIO_ZLIB_CTX *)b->ptr;
566 /* If no data written or already flush show success */
567 if (!ctx->obuf || (ctx->odone && !ctx->ocount))
568 return 1;
569 zout = &ctx->zout;
570 BIO_clear_retry_flags(b);
571 /* No more input data */
572 zout->next_in = NULL;
573 zout->avail_in = 0;
574 for (;;) {
575 /* If data in output buffer write it first */
576 while (ctx->ocount) {
577 ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
578 if (ret <= 0) {
579 BIO_copy_next_retry(b);
580 return ret;
581 }
582 ctx->optr += ret;
583 ctx->ocount -= ret;
584 }
585 if (ctx->odone)
586 return 1;
587
588 /* Compress some more */
589
590 /* Reset buffer */
591 ctx->optr = ctx->obuf;
592 zout->next_out = ctx->obuf;
593 zout->avail_out = ctx->obufsize;
594 /* Compress some more */
595 ret = deflate(zout, Z_FINISH);
596 if (ret == Z_STREAM_END)
597 ctx->odone = 1;
598 else if (ret != Z_OK) {
599 COMPerror(COMP_R_ZLIB_DEFLATE_ERROR);
600 ERR_asprintf_error_data("zlib error:%s", zError(ret));
601 return 0;
602 }
603 ctx->ocount = ctx->obufsize - zout->avail_out;
604 }
605}
606
607static long
608bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
609{
610 BIO_ZLIB_CTX *ctx;
611 int ret, *ip;
612 int ibs, obs;
613 if (!b->next_bio)
614 return 0;
615 ctx = (BIO_ZLIB_CTX *)b->ptr;
616 switch (cmd) {
617
618 case BIO_CTRL_RESET:
619 ctx->ocount = 0;
620 ctx->odone = 0;
621 ret = 1;
622 break;
623
624 case BIO_CTRL_FLUSH:
625 ret = bio_zlib_flush(b);
626 if (ret > 0)
627 ret = BIO_flush(b->next_bio);
628 break;
629
630 case BIO_C_SET_BUFF_SIZE:
631 ibs = -1;
632 obs = -1;
633 if (ptr != NULL) {
634 ip = ptr;
635 if (*ip == 0)
636 ibs = (int) num;
637 else
638 obs = (int) num;
639 } else {
640 ibs = (int)num;
641 obs = ibs;
642 }
643
644 if (ibs != -1) {
645 free(ctx->ibuf);
646 ctx->ibuf = NULL;
647 ctx->ibufsize = ibs;
648 }
649
650 if (obs != -1) {
651 free(ctx->obuf);
652 ctx->obuf = NULL;
653 ctx->obufsize = obs;
654 }
655 ret = 1;
656 break;
657
658 case BIO_C_DO_STATE_MACHINE:
659 BIO_clear_retry_flags(b);
660 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
661 BIO_copy_next_retry(b);
662 break;
663
664 default:
665 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
666 break;
667
668 }
669
670 return ret;
671}
672
673
674static long
675bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
676{
677 if (!b->next_bio)
678 return 0;
679 return BIO_callback_ctrl(b->next_bio, cmd, fp);
680}
681
682#endif
diff --git a/src/lib/libcrypto/comp/comp.h b/src/lib/libcrypto/comp/comp.h
index 58b51c6e82..8f3645f37b 100644
--- a/src/lib/libcrypto/comp/comp.h
+++ b/src/lib/libcrypto/comp/comp.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: comp.h,v 1.11 2022/12/24 07:12:09 tb Exp $ */ 1/* $OpenBSD: comp.h,v 1.12 2023/06/11 05:35:43 tb Exp $ */
2/* 2/*
3 * --------------------------------------------------------------------------- 3 * ---------------------------------------------------------------------------
4 * Patches to this file were contributed by 4 * Patches to this file were contributed by
@@ -131,12 +131,6 @@ COMP_METHOD *COMP_rle(void );
131COMP_METHOD *COMP_zlib(void ); 131COMP_METHOD *COMP_zlib(void );
132void COMP_zlib_cleanup(void); 132void COMP_zlib_cleanup(void);
133 133
134#ifdef HEADER_BIO_H
135#ifdef ZLIB
136BIO_METHOD *BIO_f_zlib(void);
137#endif
138#endif
139
140void ERR_load_COMP_strings(void); 134void ERR_load_COMP_strings(void);
141 135
142/* Error codes for the COMP functions. */ 136/* Error codes for the COMP functions. */