Coverage Report

Created: 2018-08-29 13:53

/src/openssl/crypto/comp/c_zlib.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the OpenSSL license (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 "internal/cryptlib_int.h"
17
#include "internal/bio.h"
18
#include "comp_lcl.h"
19
20
COMP_METHOD *COMP_zlib(void);
21
22
static COMP_METHOD zlib_method_nozlib = {
23
    NID_undef,
24
    "(undef)",
25
    NULL,
26
    NULL,
27
    NULL,
28
    NULL,
29
};
30
31
#ifndef ZLIB
32
# undef ZLIB_SHARED
33
#else
34
35
# include <zlib.h>
36
37
static int zlib_stateful_init(COMP_CTX *ctx);
38
static void zlib_stateful_finish(COMP_CTX *ctx);
39
static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
40
                                        unsigned int olen, unsigned char *in,
41
                                        unsigned int ilen);
42
static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
43
                                      unsigned int olen, unsigned char *in,
44
                                      unsigned int ilen);
45
46
/* memory allocations functions for zlib initialisation */
47
static void *zlib_zalloc(void *opaque, unsigned int no, unsigned int size)
48
{
49
    void *p;
50
51
    p = OPENSSL_zalloc(no * size);
52
    return p;
53
}
54
55
static void zlib_zfree(void *opaque, void *address)
56
{
57
    OPENSSL_free(address);
58
}
59
60
61
static COMP_METHOD zlib_stateful_method = {
62
    NID_zlib_compression,
63
    LN_zlib_compression,
64
    zlib_stateful_init,
65
    zlib_stateful_finish,
66
    zlib_stateful_compress_block,
67
    zlib_stateful_expand_block
68
};
69
70
/*
71
 * When OpenSSL is built on Windows, we do not want to require that
72
 * the ZLIB.DLL be available in order for the OpenSSL DLLs to
73
 * work.  Therefore, all ZLIB routines are loaded at run time
74
 * and we do not link to a .LIB file when ZLIB_SHARED is set.
75
 */
76
# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
77
#  include <windows.h>
78
# endif                         /* !(OPENSSL_SYS_WINDOWS ||
79
                                 * OPENSSL_SYS_WIN32) */
80
81
# ifdef ZLIB_SHARED
82
#  include "internal/dso.h"
83
84
/* Function pointers */
85
typedef int (*compress_ft) (Bytef *dest, uLongf * destLen,
86
                            const Bytef *source, uLong sourceLen);
87
typedef int (*inflateEnd_ft) (z_streamp strm);
88
typedef int (*inflate_ft) (z_streamp strm, int flush);
89
typedef int (*inflateInit__ft) (z_streamp strm,
90
                                const char *version, int stream_size);
91
typedef int (*deflateEnd_ft) (z_streamp strm);
92
typedef int (*deflate_ft) (z_streamp strm, int flush);
93
typedef int (*deflateInit__ft) (z_streamp strm, int level,
94
                                const char *version, int stream_size);
95
typedef const char *(*zError__ft) (int err);
96
static compress_ft p_compress = NULL;
97
static inflateEnd_ft p_inflateEnd = NULL;
98
static inflate_ft p_inflate = NULL;
99
static inflateInit__ft p_inflateInit_ = NULL;
100
static deflateEnd_ft p_deflateEnd = NULL;
101
static deflate_ft p_deflate = NULL;
102
static deflateInit__ft p_deflateInit_ = NULL;
103
static zError__ft p_zError = NULL;
104
105
static int zlib_loaded = 0;     /* only attempt to init func pts once */
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
#endif
208
209
COMP_METHOD *COMP_zlib(void)
210
0
{
211
0
    COMP_METHOD *meth = &zlib_method_nozlib;
212
0
213
#ifdef ZLIB_SHARED
214
    /* LIBZ may be externally defined, and we should respect that value */
215
# ifndef LIBZ
216
#  if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
217
#   define LIBZ "ZLIB1"
218
#  elif defined(OPENSSL_SYS_VMS)
219
#   define LIBZ "LIBZ"
220
#  else
221
#   define LIBZ "z"
222
#  endif
223
# endif
224
225
    if (!zlib_loaded) {
226
        zlib_dso = DSO_load(NULL, LIBZ, NULL, 0);
227
        if (zlib_dso != NULL) {
228
            p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress");
229
            p_inflateEnd
230
                = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd");
231
            p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate");
232
            p_inflateInit_
233
                = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_");
234
            p_deflateEnd
235
                = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd");
236
            p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate");
237
            p_deflateInit_
238
                = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_");
239
            p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError");
240
241
            if (p_compress && p_inflateEnd && p_inflate
242
                && p_inflateInit_ && p_deflateEnd
243
                && p_deflate && p_deflateInit_ && p_zError)
244
                zlib_loaded++;
245
246
            if (!OPENSSL_init_crypto(OPENSSL_INIT_ZLIB, NULL)) {
247
                comp_zlib_cleanup_int();
248
                return meth;
249
            }
250
            if (zlib_loaded)
251
                meth = &zlib_stateful_method;
252
        }
253
    }
254
#endif
255
#if defined(ZLIB)
256
    meth = &zlib_stateful_method;
257
#endif
258
259
0
    return meth;
260
0
}
261
262
void comp_zlib_cleanup_int(void)
263
0
{
264
#ifdef ZLIB_SHARED
265
    DSO_free(zlib_dso);
266
    zlib_dso = NULL;
267
#endif
268
}
269
270
#ifdef ZLIB
271
272
/* Zlib based compression/decompression filter BIO */
273
274
typedef struct {
275
    unsigned char *ibuf;        /* Input buffer */
276
    int ibufsize;               /* Buffer size */
277
    z_stream zin;               /* Input decompress context */
278
    unsigned char *obuf;        /* Output buffer */
279
    int obufsize;               /* Output buffer size */
280
    unsigned char *optr;        /* Position in output buffer */
281
    int ocount;                 /* Amount of data in output buffer */
282
    int odone;                  /* deflate EOF */
283
    int comp_level;             /* Compression level to use */
284
    z_stream zout;              /* Output compression context */
285
} BIO_ZLIB_CTX;
286
287
# define ZLIB_DEFAULT_BUFSIZE 1024
288
289
static int bio_zlib_new(BIO *bi);
290
static int bio_zlib_free(BIO *bi);
291
static int bio_zlib_read(BIO *b, char *out, int outl);
292
static int bio_zlib_write(BIO *b, const char *in, int inl);
293
static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);
294
static long bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp);
295
296
static const BIO_METHOD bio_meth_zlib = {
297
    BIO_TYPE_COMP,
298
    "zlib",
299
    /* TODO: Convert to new style write function */
300
    bwrite_conv,
301
    bio_zlib_write,
302
    /* TODO: Convert to new style read function */
303
    bread_conv,
304
    bio_zlib_read,
305
    NULL,                      /* bio_zlib_puts, */
306
    NULL,                      /* bio_zlib_gets, */
307
    bio_zlib_ctrl,
308
    bio_zlib_new,
309
    bio_zlib_free,
310
    bio_zlib_callback_ctrl
311
};
312
313
const BIO_METHOD *BIO_f_zlib(void)
314
{
315
    return &bio_meth_zlib;
316
}
317
318
static int bio_zlib_new(BIO *bi)
319
{
320
    BIO_ZLIB_CTX *ctx;
321
# ifdef ZLIB_SHARED
322
    (void)COMP_zlib();
323
    if (!zlib_loaded) {
324
        COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED);
325
        return 0;
326
    }
327
# endif
328
    ctx = OPENSSL_zalloc(sizeof(*ctx));
329
    if (ctx == NULL) {
330
        COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE);
331
        return 0;
332
    }
333
    ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;
334
    ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;
335
    ctx->zin.zalloc = Z_NULL;
336
    ctx->zin.zfree = Z_NULL;
337
    ctx->zout.zalloc = Z_NULL;
338
    ctx->zout.zfree = Z_NULL;
339
    ctx->comp_level = Z_DEFAULT_COMPRESSION;
340
    BIO_set_init(bi, 1);
341
    BIO_set_data(bi, ctx);
342
343
    return 1;
344
}
345
346
static int bio_zlib_free(BIO *bi)
347
{
348
    BIO_ZLIB_CTX *ctx;
349
    if (!bi)
350
        return 0;
351
    ctx = BIO_get_data(bi);
352
    if (ctx->ibuf) {
353
        /* Destroy decompress context */
354
        inflateEnd(&ctx->zin);
355
        OPENSSL_free(ctx->ibuf);
356
    }
357
    if (ctx->obuf) {
358
        /* Destroy compress context */
359
        deflateEnd(&ctx->zout);
360
        OPENSSL_free(ctx->obuf);
361
    }
362
    OPENSSL_free(ctx);
363
    BIO_set_data(bi, NULL);
364
    BIO_set_init(bi, 0);
365
366
    return 1;
367
}
368
369
static int bio_zlib_read(BIO *b, char *out, int outl)
370
{
371
    BIO_ZLIB_CTX *ctx;
372
    int ret;
373
    z_stream *zin;
374
    BIO *next = BIO_next(b);
375
376
    if (!out || !outl)
377
        return 0;
378
    ctx = BIO_get_data(b);
379
    zin = &ctx->zin;
380
    BIO_clear_retry_flags(b);
381
    if (!ctx->ibuf) {
382
        ctx->ibuf = OPENSSL_malloc(ctx->ibufsize);
383
        if (ctx->ibuf == NULL) {
384
            COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE);
385
            return 0;
386
        }
387
        inflateInit(zin);
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
                COMPerr(COMP_F_BIO_ZLIB_READ, COMP_R_ZLIB_INFLATE_ERROR);
401
                ERR_add_error_data(2, "zlib error:", 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
            COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE);
446
            return 0;
447
        }
448
        ctx->optr = ctx->obuf;
449
        ctx->ocount = 0;
450
        deflateInit(zout, ctx->comp_level);
451
        zout->next_out = ctx->obuf;
452
        zout->avail_out = ctx->obufsize;
453
    }
454
    /* Obtain input data directly from supplied buffer */
455
    zout->next_in = (void *)in;
456
    zout->avail_in = inl;
457
    for (;;) {
458
        /* If data in output buffer write it first */
459
        while (ctx->ocount) {
460
            ret = BIO_write(next, ctx->optr, ctx->ocount);
461
            if (ret <= 0) {
462
                /* Total data written */
463
                int tot = inl - zout->avail_in;
464
                BIO_copy_next_retry(b);
465
                if (ret < 0)
466
                    return (tot > 0) ? tot : ret;
467
                return tot;
468
            }
469
            ctx->optr += ret;
470
            ctx->ocount -= ret;
471
        }
472
473
        /* Have we consumed all supplied data? */
474
        if (!zout->avail_in)
475
            return inl;
476
477
        /* Compress some more */
478
479
        /* Reset buffer */
480
        ctx->optr = ctx->obuf;
481
        zout->next_out = ctx->obuf;
482
        zout->avail_out = ctx->obufsize;
483
        /* Compress some more */
484
        ret = deflate(zout, 0);
485
        if (ret != Z_OK) {
486
            COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR);
487
            ERR_add_error_data(2, "zlib error:", zError(ret));
488
            return 0;
489
        }
490
        ctx->ocount = ctx->obufsize - zout->avail_out;
491
    }
492
}
493
494
static int bio_zlib_flush(BIO *b)
495
{
496
    BIO_ZLIB_CTX *ctx;
497
    int ret;
498
    z_stream *zout;
499
    BIO *next = BIO_next(b);
500
501
    ctx = BIO_get_data(b);
502
    /* If no data written or already flush show success */
503
    if (!ctx->obuf || (ctx->odone && !ctx->ocount))
504
        return 1;
505
    zout = &ctx->zout;
506
    BIO_clear_retry_flags(b);
507
    /* No more input data */
508
    zout->next_in = NULL;
509
    zout->avail_in = 0;
510
    for (;;) {
511
        /* If data in output buffer write it first */
512
        while (ctx->ocount) {
513
            ret = BIO_write(next, ctx->optr, ctx->ocount);
514
            if (ret <= 0) {
515
                BIO_copy_next_retry(b);
516
                return ret;
517
            }
518
            ctx->optr += ret;
519
            ctx->ocount -= ret;
520
        }
521
        if (ctx->odone)
522
            return 1;
523
524
        /* Compress some more */
525
526
        /* Reset buffer */
527
        ctx->optr = ctx->obuf;
528
        zout->next_out = ctx->obuf;
529
        zout->avail_out = ctx->obufsize;
530
        /* Compress some more */
531
        ret = deflate(zout, Z_FINISH);
532
        if (ret == Z_STREAM_END)
533
            ctx->odone = 1;
534
        else if (ret != Z_OK) {
535
            COMPerr(COMP_F_BIO_ZLIB_FLUSH, COMP_R_ZLIB_DEFLATE_ERROR);
536
            ERR_add_error_data(2, "zlib error:", zError(ret));
537
            return 0;
538
        }
539
        ctx->ocount = ctx->obufsize - zout->avail_out;
540
    }
541
}
542
543
static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
544
{
545
    BIO_ZLIB_CTX *ctx;
546
    int ret, *ip;
547
    int ibs, obs;
548
    BIO *next = BIO_next(b);
549
550
    if (next == NULL)
551
        return 0;
552
    ctx = BIO_get_data(b);
553
    switch (cmd) {
554
555
    case BIO_CTRL_RESET:
556
        ctx->ocount = 0;
557
        ctx->odone = 0;
558
        ret = 1;
559
        break;
560
561
    case BIO_CTRL_FLUSH:
562
        ret = bio_zlib_flush(b);
563
        if (ret > 0)
564
            ret = BIO_flush(next);
565
        break;
566
567
    case BIO_C_SET_BUFF_SIZE:
568
        ibs = -1;
569
        obs = -1;
570
        if (ptr != NULL) {
571
            ip = ptr;
572
            if (*ip == 0)
573
                ibs = (int)num;
574
            else
575
                obs = (int)num;
576
        } else {
577
            ibs = (int)num;
578
            obs = ibs;
579
        }
580
581
        if (ibs != -1) {
582
            OPENSSL_free(ctx->ibuf);
583
            ctx->ibuf = NULL;
584
            ctx->ibufsize = ibs;
585
        }
586
587
        if (obs != -1) {
588
            OPENSSL_free(ctx->obuf);
589
            ctx->obuf = NULL;
590
            ctx->obufsize = obs;
591
        }
592
        ret = 1;
593
        break;
594
595
    case BIO_C_DO_STATE_MACHINE:
596
        BIO_clear_retry_flags(b);
597
        ret = BIO_ctrl(next, cmd, num, ptr);
598
        BIO_copy_next_retry(b);
599
        break;
600
601
    default:
602
        ret = BIO_ctrl(next, cmd, num, ptr);
603
        break;
604
605
    }
606
607
    return ret;
608
}
609
610
static long bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
611
{
612
    BIO *next = BIO_next(b);
613
    if (next == NULL)
614
        return 0;
615
    return BIO_callback_ctrl(next, cmd, fp);
616
}
617
618
#endif