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 "crypto/cryptlib.h" 17#include "internal/bio.h" 18#include "comp_local.h" 19 20COMP_METHOD *COMP_zlib(void); 21 22static 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 37static int zlib_stateful_init(COMP_CTX *ctx); 38static void zlib_stateful_finish(COMP_CTX *ctx); 39static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, 40 unsigned int olen, unsigned char *in, 41 unsigned int ilen); 42static 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 */ 47static 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 55static void zlib_zfree(void *opaque, void *address) 56{ 57 OPENSSL_free(address); 58} 59 60 61static 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 */ 85typedef int (*compress_ft) (Bytef *dest, uLongf * destLen, 86 const Bytef *source, uLong sourceLen); 87typedef int (*inflateEnd_ft) (z_streamp strm); 88typedef int (*inflate_ft) (z_streamp strm, int flush); 89typedef int (*inflateInit__ft) (z_streamp strm, 90 const char *version, int stream_size); 91typedef int (*deflateEnd_ft) (z_streamp strm); 92typedef int (*deflate_ft) (z_streamp strm, int flush); 93typedef int (*deflateInit__ft) (z_streamp strm, int level, 94 const char *version, int stream_size); 95typedef const char *(*zError__ft) (int err); 96static compress_ft p_compress = NULL; 97static inflateEnd_ft p_inflateEnd = NULL; 98static inflate_ft p_inflate = NULL; 99static inflateInit__ft p_inflateInit_ = NULL; 100static deflateEnd_ft p_deflateEnd = NULL; 101static deflate_ft p_deflate = NULL; 102static deflateInit__ft p_deflateInit_ = NULL; 103static zError__ft p_zError = NULL; 104 105static int zlib_loaded = 0; /* only attempt to init func pts once */ 106static 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 118struct zlib_state { 119 z_stream istream; 120 z_stream ostream; 121}; 122 123static 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 157static 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 165static 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 186static 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 209COMP_METHOD *COMP_zlib(void) 210{ 211 COMP_METHOD *meth = &zlib_method_nozlib; 212 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 return meth; 260} 261 262void comp_zlib_cleanup_int(void) 263{ 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 274typedef 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 289static int bio_zlib_new(BIO *bi); 290static int bio_zlib_free(BIO *bi); 291static int bio_zlib_read(BIO *b, char *out, int outl); 292static int bio_zlib_write(BIO *b, const char *in, int inl); 293static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr); 294static long bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp); 295 296static 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 313const BIO_METHOD *BIO_f_zlib(void) 314{ 315 return &bio_meth_zlib; 316} 317 318static 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 346static 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 369static 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 427static 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 494static 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 543static 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 case BIO_CTRL_WPENDING: 602 if (ctx->obuf == NULL) 603 return 0; 604 605 if (ctx->odone) { 606 ret = ctx->ocount; 607 } else { 608 ret = ctx->ocount; 609 if (ret == 0) 610 /* Unknown amount pending but we are not finished */ 611 ret = 1; 612 } 613 if (ret == 0) 614 ret = BIO_ctrl(next, cmd, num, ptr); 615 break; 616 617 case BIO_CTRL_PENDING: 618 ret = ctx->zin.avail_in; 619 if (ret == 0) 620 ret = BIO_ctrl(next, cmd, num, ptr); 621 break; 622 623 default: 624 ret = BIO_ctrl(next, cmd, num, ptr); 625 break; 626 627 } 628 629 return ret; 630} 631 632static long bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) 633{ 634 BIO *next = BIO_next(b); 635 if (next == NULL) 636 return 0; 637 return BIO_callback_ctrl(next, cmd, fp); 638} 639 640#endif 641