Fix coverity 1493364 & 1493375: unchecked return value
[openssl.git] / crypto / comp / c_zlib.c
1 /*
2  * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <openssl/objects.h>
14 #include "internal/comp.h"
15 #include <openssl/err.h>
16 #include "crypto/cryptlib.h"
17 #include "internal/bio.h"
18 #include "internal/thread_once.h"
19 #include "comp_local.h"
20
21 COMP_METHOD *COMP_zlib(void);
22
23 static COMP_METHOD zlib_method_nozlib = {
24     NID_undef,
25     "(undef)",
26     NULL,
27     NULL,
28     NULL,
29     NULL,
30 };
31
32 #ifndef ZLIB
33 # undef ZLIB_SHARED
34 #else
35
36 # include <zlib.h>
37
38 static int zlib_stateful_init(COMP_CTX *ctx);
39 static void zlib_stateful_finish(COMP_CTX *ctx);
40 static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
41                                         unsigned int olen, unsigned char *in,
42                                         unsigned int ilen);
43 static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
44                                       unsigned int olen, unsigned char *in,
45                                       unsigned int ilen);
46
47 /* memory allocations functions for zlib initialisation */
48 static void *zlib_zalloc(void *opaque, unsigned int no, unsigned int size)
49 {
50     void *p;
51
52     p = OPENSSL_zalloc(no * size);
53     return p;
54 }
55
56 static void zlib_zfree(void *opaque, void *address)
57 {
58     OPENSSL_free(address);
59 }
60
61
62 static COMP_METHOD zlib_stateful_method = {
63     NID_zlib_compression,
64     LN_zlib_compression,
65     zlib_stateful_init,
66     zlib_stateful_finish,
67     zlib_stateful_compress_block,
68     zlib_stateful_expand_block
69 };
70
71 /*
72  * When OpenSSL is built on Windows, we do not want to require that
73  * the ZLIB.DLL be available in order for the OpenSSL DLLs to
74  * work.  Therefore, all ZLIB routines are loaded at run time
75  * and we do not link to a .LIB file when ZLIB_SHARED is set.
76  */
77 # if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
78 #  include <windows.h>
79 # endif                         /* !(OPENSSL_SYS_WINDOWS ||
80                                  * OPENSSL_SYS_WIN32) */
81
82 # ifdef ZLIB_SHARED
83 #  include "internal/dso.h"
84
85 /* Function pointers */
86 typedef int (*compress_ft) (Bytef *dest, uLongf * destLen,
87                             const Bytef *source, uLong sourceLen);
88 typedef int (*inflateEnd_ft) (z_streamp strm);
89 typedef int (*inflate_ft) (z_streamp strm, int flush);
90 typedef int (*inflateInit__ft) (z_streamp strm,
91                                 const char *version, int stream_size);
92 typedef int (*deflateEnd_ft) (z_streamp strm);
93 typedef int (*deflate_ft) (z_streamp strm, int flush);
94 typedef int (*deflateInit__ft) (z_streamp strm, int level,
95                                 const char *version, int stream_size);
96 typedef const char *(*zError__ft) (int err);
97 static compress_ft p_compress = NULL;
98 static inflateEnd_ft p_inflateEnd = NULL;
99 static inflate_ft p_inflate = NULL;
100 static inflateInit__ft p_inflateInit_ = NULL;
101 static deflateEnd_ft p_deflateEnd = NULL;
102 static deflate_ft p_deflate = NULL;
103 static deflateInit__ft p_deflateInit_ = NULL;
104 static zError__ft p_zError = NULL;
105
106 static DSO *zlib_dso = NULL;
107
108 #  define compress                p_compress
109 #  define inflateEnd              p_inflateEnd
110 #  define inflate                 p_inflate
111 #  define inflateInit_            p_inflateInit_
112 #  define deflateEnd              p_deflateEnd
113 #  define deflate                 p_deflate
114 #  define deflateInit_            p_deflateInit_
115 #  define zError                  p_zError
116 # endif                         /* ZLIB_SHARED */
117
118 struct zlib_state {
119     z_stream istream;
120     z_stream ostream;
121 };
122
123 static int zlib_stateful_init(COMP_CTX *ctx)
124 {
125     int err;
126     struct zlib_state *state = OPENSSL_zalloc(sizeof(*state));
127
128     if (state == NULL)
129         goto err;
130
131     state->istream.zalloc = zlib_zalloc;
132     state->istream.zfree = zlib_zfree;
133     state->istream.opaque = Z_NULL;
134     state->istream.next_in = Z_NULL;
135     state->istream.next_out = Z_NULL;
136     err = inflateInit_(&state->istream, ZLIB_VERSION, sizeof(z_stream));
137     if (err != Z_OK)
138         goto err;
139
140     state->ostream.zalloc = zlib_zalloc;
141     state->ostream.zfree = zlib_zfree;
142     state->ostream.opaque = Z_NULL;
143     state->ostream.next_in = Z_NULL;
144     state->ostream.next_out = Z_NULL;
145     err = deflateInit_(&state->ostream, Z_DEFAULT_COMPRESSION,
146                        ZLIB_VERSION, sizeof(z_stream));
147     if (err != Z_OK)
148         goto err;
149
150     ctx->data = state;
151     return 1;
152  err:
153     OPENSSL_free(state);
154     return 0;
155 }
156
157 static void zlib_stateful_finish(COMP_CTX *ctx)
158 {
159     struct zlib_state *state = ctx->data;
160     inflateEnd(&state->istream);
161     deflateEnd(&state->ostream);
162     OPENSSL_free(state);
163 }
164
165 static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
166                                         unsigned int olen, unsigned char *in,
167                                         unsigned int ilen)
168 {
169     int err = Z_OK;
170     struct zlib_state *state = ctx->data;
171
172     if (state == NULL)
173         return -1;
174
175     state->ostream.next_in = in;
176     state->ostream.avail_in = ilen;
177     state->ostream.next_out = out;
178     state->ostream.avail_out = olen;
179     if (ilen > 0)
180         err = deflate(&state->ostream, Z_SYNC_FLUSH);
181     if (err != Z_OK)
182         return -1;
183     return olen - state->ostream.avail_out;
184 }
185
186 static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
187                                       unsigned int olen, unsigned char *in,
188                                       unsigned int ilen)
189 {
190     int err = Z_OK;
191     struct zlib_state *state = ctx->data;
192
193     if (state == NULL)
194         return 0;
195
196     state->istream.next_in = in;
197     state->istream.avail_in = ilen;
198     state->istream.next_out = out;
199     state->istream.avail_out = olen;
200     if (ilen > 0)
201         err = inflate(&state->istream, Z_SYNC_FLUSH);
202     if (err != Z_OK)
203         return -1;
204     return olen - state->istream.avail_out;
205 }
206
207 static CRYPTO_ONCE zlib_once = CRYPTO_ONCE_STATIC_INIT;
208 DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init)
209 {
210 # ifdef ZLIB_SHARED
211     /* LIBZ may be externally defined, and we should respect that value */
212 #  ifndef LIBZ
213 #   if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
214 #    define LIBZ "ZLIB1"
215 #   elif defined(OPENSSL_SYS_VMS)
216 #    define LIBZ "LIBZ"
217 #   else
218 #    define LIBZ "z"
219 #   endif
220 #  endif
221
222     zlib_dso = DSO_load(NULL, LIBZ, NULL, 0);
223     if (zlib_dso != NULL) {
224         p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress");
225         p_inflateEnd = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd");
226         p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate");
227         p_inflateInit_ = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_");
228         p_deflateEnd = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd");
229         p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate");
230         p_deflateInit_ = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_");
231         p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError");
232
233         if (p_compress == NULL || p_inflateEnd == NULL
234                 || p_inflate == NULL || p_inflateInit_ == NULL
235                 || p_deflateEnd == NULL || p_deflate == NULL
236                 || p_deflateInit_ == NULL || p_zError == NULL) {
237             ossl_comp_zlib_cleanup();
238             return 0;
239         }
240     }
241 # endif
242     return 1;
243 }
244 #endif
245
246 COMP_METHOD *COMP_zlib(void)
247 {
248     COMP_METHOD *meth = &zlib_method_nozlib;
249
250 #ifdef ZLIB
251     if (RUN_ONCE(&zlib_once, ossl_comp_zlib_init))
252         meth = &zlib_stateful_method;
253 #endif
254
255     return meth;
256 }
257
258 /* Also called from OPENSSL_cleanup() */
259 void ossl_comp_zlib_cleanup(void)
260 {
261 #ifdef ZLIB_SHARED
262     DSO_free(zlib_dso);
263     zlib_dso = NULL;
264 #endif
265 }
266
267 #ifdef ZLIB
268
269 /* Zlib based compression/decompression filter BIO */
270
271 typedef struct {
272     unsigned char *ibuf;        /* Input buffer */
273     int ibufsize;               /* Buffer size */
274     z_stream zin;               /* Input decompress context */
275     unsigned char *obuf;        /* Output buffer */
276     int obufsize;               /* Output buffer size */
277     unsigned char *optr;        /* Position in output buffer */
278     int ocount;                 /* Amount of data in output buffer */
279     int odone;                  /* deflate EOF */
280     int comp_level;             /* Compression level to use */
281     z_stream zout;              /* Output compression context */
282 } BIO_ZLIB_CTX;
283
284 # define ZLIB_DEFAULT_BUFSIZE 1024
285
286 static int bio_zlib_new(BIO *bi);
287 static int bio_zlib_free(BIO *bi);
288 static int bio_zlib_read(BIO *b, char *out, int outl);
289 static int bio_zlib_write(BIO *b, const char *in, int inl);
290 static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);
291 static long bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp);
292
293 static const BIO_METHOD bio_meth_zlib = {
294     BIO_TYPE_COMP,
295     "zlib",
296     bwrite_conv,
297     bio_zlib_write,
298     bread_conv,
299     bio_zlib_read,
300     NULL,                      /* bio_zlib_puts, */
301     NULL,                      /* bio_zlib_gets, */
302     bio_zlib_ctrl,
303     bio_zlib_new,
304     bio_zlib_free,
305     bio_zlib_callback_ctrl
306 };
307
308 const BIO_METHOD *BIO_f_zlib(void)
309 {
310     return &bio_meth_zlib;
311 }
312
313 static int bio_zlib_new(BIO *bi)
314 {
315     BIO_ZLIB_CTX *ctx;
316
317 # ifdef ZLIB_SHARED
318     if (!RUN_ONCE(&zlib_once, ossl_comp_zlib_init)) {
319         ERR_raise(ERR_LIB_COMP, COMP_R_ZLIB_NOT_SUPPORTED);
320         return 0;
321     }
322 # endif
323     ctx = OPENSSL_zalloc(sizeof(*ctx));
324     if (ctx == NULL) {
325         ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE);
326         return 0;
327     }
328     ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;
329     ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;
330     ctx->zin.zalloc = Z_NULL;
331     ctx->zin.zfree = Z_NULL;
332     ctx->zout.zalloc = Z_NULL;
333     ctx->zout.zfree = Z_NULL;
334     ctx->comp_level = Z_DEFAULT_COMPRESSION;
335     BIO_set_init(bi, 1);
336     BIO_set_data(bi, ctx);
337
338     return 1;
339 }
340
341 static int bio_zlib_free(BIO *bi)
342 {
343     BIO_ZLIB_CTX *ctx;
344
345     if (!bi)
346         return 0;
347     ctx = BIO_get_data(bi);
348     if (ctx->ibuf) {
349         /* Destroy decompress context */
350         inflateEnd(&ctx->zin);
351         OPENSSL_free(ctx->ibuf);
352     }
353     if (ctx->obuf) {
354         /* Destroy compress context */
355         deflateEnd(&ctx->zout);
356         OPENSSL_free(ctx->obuf);
357     }
358     OPENSSL_free(ctx);
359     BIO_set_data(bi, NULL);
360     BIO_set_init(bi, 0);
361
362     return 1;
363 }
364
365 static int bio_zlib_read(BIO *b, char *out, int outl)
366 {
367     BIO_ZLIB_CTX *ctx;
368     int ret;
369     z_stream *zin;
370     BIO *next = BIO_next(b);
371
372     if (!out || !outl)
373         return 0;
374     ctx = BIO_get_data(b);
375     zin = &ctx->zin;
376     BIO_clear_retry_flags(b);
377     if (!ctx->ibuf) {
378         ctx->ibuf = OPENSSL_malloc(ctx->ibufsize);
379         if (ctx->ibuf == NULL) {
380             ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE);
381             return 0;
382         }
383         if ((ret = inflateInit(zin)) != Z_OK) {
384             ERR_raise_data(ERR_LIB_COMP, COMP_R_ZLIB_INFLATE_ERROR,
385                            "zlib error: %s", zError(ret));
386             return 0;
387         }
388         zin->next_in = ctx->ibuf;
389         zin->avail_in = 0;
390     }
391
392     /* Copy output data directly to supplied buffer */
393     zin->next_out = (unsigned char *)out;
394     zin->avail_out = (unsigned int)outl;
395     for (;;) {
396         /* Decompress while data available */
397         while (zin->avail_in) {
398             ret = inflate(zin, 0);
399             if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
400                 ERR_raise_data(ERR_LIB_COMP, COMP_R_ZLIB_INFLATE_ERROR,
401                                "zlib error: %s", zError(ret));
402                 return 0;
403             }
404             /* If EOF or we've read everything then return */
405             if ((ret == Z_STREAM_END) || !zin->avail_out)
406                 return outl - zin->avail_out;
407         }
408
409         /*
410          * No data in input buffer try to read some in, if an error then
411          * return the total data read.
412          */
413         ret = BIO_read(next, ctx->ibuf, ctx->ibufsize);
414         if (ret <= 0) {
415             /* Total data read */
416             int tot = outl - zin->avail_out;
417             BIO_copy_next_retry(b);
418             if (ret < 0)
419                 return (tot > 0) ? tot : ret;
420             return tot;
421         }
422         zin->avail_in = ret;
423         zin->next_in = ctx->ibuf;
424     }
425 }
426
427 static int bio_zlib_write(BIO *b, const char *in, int inl)
428 {
429     BIO_ZLIB_CTX *ctx;
430     int ret;
431     z_stream *zout;
432     BIO *next = BIO_next(b);
433
434     if (!in || !inl)
435         return 0;
436     ctx = BIO_get_data(b);
437     if (ctx->odone)
438         return 0;
439     zout = &ctx->zout;
440     BIO_clear_retry_flags(b);
441     if (!ctx->obuf) {
442         ctx->obuf = OPENSSL_malloc(ctx->obufsize);
443         /* Need error here */
444         if (ctx->obuf == NULL) {
445             ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE);
446             return 0;
447         }
448         ctx->optr = ctx->obuf;
449         ctx->ocount = 0;
450         if ((ret = deflateInit(zout, ctx->comp_level)) != Z_OK) {
451             ERR_raise_data(ERR_LIB_COMP, COMP_R_ZLIB_DEFLATE_ERROR,
452                            "zlib error: %s", zError(ret));
453             return 0;
454         }
455         zout->next_out = ctx->obuf;
456         zout->avail_out = ctx->obufsize;
457     }
458     /* Obtain input data directly from supplied buffer */
459     zout->next_in = (void *)in;
460     zout->avail_in = inl;
461     for (;;) {
462         /* If data in output buffer write it first */
463         while (ctx->ocount) {
464             ret = BIO_write(next, ctx->optr, ctx->ocount);
465             if (ret <= 0) {
466                 /* Total data written */
467                 int tot = inl - zout->avail_in;
468                 BIO_copy_next_retry(b);
469                 if (ret < 0)
470                     return (tot > 0) ? tot : ret;
471                 return tot;
472             }
473             ctx->optr += ret;
474             ctx->ocount -= ret;
475         }
476
477         /* Have we consumed all supplied data? */
478         if (!zout->avail_in)
479             return inl;
480
481         /* Compress some more */
482
483         /* Reset buffer */
484         ctx->optr = ctx->obuf;
485         zout->next_out = ctx->obuf;
486         zout->avail_out = ctx->obufsize;
487         /* Compress some more */
488         ret = deflate(zout, 0);
489         if (ret != Z_OK) {
490             ERR_raise_data(ERR_LIB_COMP, COMP_R_ZLIB_DEFLATE_ERROR,
491                            "zlib error: %s", zError(ret));
492             return 0;
493         }
494         ctx->ocount = ctx->obufsize - zout->avail_out;
495     }
496 }
497
498 static int bio_zlib_flush(BIO *b)
499 {
500     BIO_ZLIB_CTX *ctx;
501     int ret;
502     z_stream *zout;
503     BIO *next = BIO_next(b);
504
505     ctx = BIO_get_data(b);
506     /* If no data written or already flush show success */
507     if (!ctx->obuf || (ctx->odone && !ctx->ocount))
508         return 1;
509     zout = &ctx->zout;
510     BIO_clear_retry_flags(b);
511     /* No more input data */
512     zout->next_in = NULL;
513     zout->avail_in = 0;
514     for (;;) {
515         /* If data in output buffer write it first */
516         while (ctx->ocount) {
517             ret = BIO_write(next, ctx->optr, ctx->ocount);
518             if (ret <= 0) {
519                 BIO_copy_next_retry(b);
520                 return ret;
521             }
522             ctx->optr += ret;
523             ctx->ocount -= ret;
524         }
525         if (ctx->odone)
526             return 1;
527
528         /* Compress some more */
529
530         /* Reset buffer */
531         ctx->optr = ctx->obuf;
532         zout->next_out = ctx->obuf;
533         zout->avail_out = ctx->obufsize;
534         /* Compress some more */
535         ret = deflate(zout, Z_FINISH);
536         if (ret == Z_STREAM_END)
537             ctx->odone = 1;
538         else if (ret != Z_OK) {
539             ERR_raise_data(ERR_LIB_COMP, COMP_R_ZLIB_DEFLATE_ERROR,
540                            "zlib error: %s", zError(ret));
541             return 0;
542         }
543         ctx->ocount = ctx->obufsize - zout->avail_out;
544     }
545 }
546
547 static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
548 {
549     BIO_ZLIB_CTX *ctx;
550     int ret, *ip;
551     int ibs, obs;
552     BIO *next = BIO_next(b);
553
554     if (next == NULL)
555         return 0;
556     ctx = BIO_get_data(b);
557     switch (cmd) {
558
559     case BIO_CTRL_RESET:
560         ctx->ocount = 0;
561         ctx->odone = 0;
562         ret = 1;
563         break;
564
565     case BIO_CTRL_FLUSH:
566         ret = bio_zlib_flush(b);
567         if (ret > 0)
568             ret = BIO_flush(next);
569         break;
570
571     case BIO_C_SET_BUFF_SIZE:
572         ibs = -1;
573         obs = -1;
574         if (ptr != NULL) {
575             ip = ptr;
576             if (*ip == 0)
577                 ibs = (int)num;
578             else
579                 obs = (int)num;
580         } else {
581             ibs = (int)num;
582             obs = ibs;
583         }
584
585         if (ibs != -1) {
586             OPENSSL_free(ctx->ibuf);
587             ctx->ibuf = NULL;
588             ctx->ibufsize = ibs;
589         }
590
591         if (obs != -1) {
592             OPENSSL_free(ctx->obuf);
593             ctx->obuf = NULL;
594             ctx->obufsize = obs;
595         }
596         ret = 1;
597         break;
598
599     case BIO_C_DO_STATE_MACHINE:
600         BIO_clear_retry_flags(b);
601         ret = BIO_ctrl(next, cmd, num, ptr);
602         BIO_copy_next_retry(b);
603         break;
604
605     case BIO_CTRL_WPENDING:
606         if (ctx->obuf == NULL)
607             return 0;
608
609         if (ctx->odone) {
610             ret = ctx->ocount;
611         } else {
612             ret = ctx->ocount;
613             if (ret == 0)
614                 /* Unknown amount pending but we are not finished */
615                 ret = 1;
616         }
617         if (ret == 0)
618             ret = BIO_ctrl(next, cmd, num, ptr);
619         break;
620
621     case BIO_CTRL_PENDING:
622         ret = ctx->zin.avail_in;
623         if (ret == 0)
624             ret = BIO_ctrl(next, cmd, num, ptr);
625         break;
626
627     default:
628         ret = BIO_ctrl(next, cmd, num, ptr);
629         break;
630
631     }
632
633     return ret;
634 }
635
636 static long bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
637 {
638     BIO *next = BIO_next(b);
639
640     if (next == NULL)
641         return 0;
642     return BIO_callback_ctrl(next, cmd, fp);
643 }
644
645 #endif