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 646