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 { 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 262 void comp_zlib_cleanup_int(void) 263 { 264 #ifdef ZLIB_SHARED 265 if (zlib_dso != NULL) 266 DSO_free(zlib_dso); 267 zlib_dso = NULL; 268 #endif 269 } 270 271 #ifdef ZLIB 272 273 /* Zlib based compression/decompression filter BIO */ 274 275 typedef struct { 276 unsigned char *ibuf; /* Input buffer */ 277 int ibufsize; /* Buffer size */ 278 z_stream zin; /* Input decompress context */ 279 unsigned char *obuf; /* Output buffer */ 280 int obufsize; /* Output buffer size */ 281 unsigned char *optr; /* Position in output buffer */ 282 int ocount; /* Amount of data in output buffer */ 283 int odone; /* deflate EOF */ 284 int comp_level; /* Compression level to use */ 285 z_stream zout; /* Output compression context */ 286 } BIO_ZLIB_CTX; 287 288 # define ZLIB_DEFAULT_BUFSIZE 1024 289 290 static int bio_zlib_new(BIO *bi); 291 static int bio_zlib_free(BIO *bi); 292 static int bio_zlib_read(BIO *b, char *out, int outl); 293 static int bio_zlib_write(BIO *b, const char *in, int inl); 294 static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr); 295 static long bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp); 296 297 static const BIO_METHOD bio_meth_zlib = { 298 BIO_TYPE_COMP, 299 "zlib", 300 bio_zlib_write, 301 bio_zlib_read, 302 NULL, /* bio_zlib_puts, */ 303 NULL, /* bio_zlib_gets, */ 304 bio_zlib_ctrl, 305 bio_zlib_new, 306 bio_zlib_free, 307 bio_zlib_callback_ctrl 308 }; 309 310 const BIO_METHOD *BIO_f_zlib(void) 311 { 312 return &bio_meth_zlib; 313 } 314 315 static int bio_zlib_new(BIO *bi) 316 { 317 BIO_ZLIB_CTX *ctx; 318 # ifdef ZLIB_SHARED 319 (void)COMP_zlib(); 320 if (!zlib_loaded) { 321 COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED); 322 return 0; 323 } 324 # endif 325 ctx = OPENSSL_zalloc(sizeof(*ctx)); 326 if (ctx == NULL) { 327 COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE); 328 return 0; 329 } 330 ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE; 331 ctx->obufsize = ZLIB_DEFAULT_BUFSIZE; 332 ctx->zin.zalloc = Z_NULL; 333 ctx->zin.zfree = Z_NULL; 334 ctx->zout.zalloc = Z_NULL; 335 ctx->zout.zfree = Z_NULL; 336 ctx->comp_level = Z_DEFAULT_COMPRESSION; 337 BIO_set_init(bi, 1); 338 BIO_set_data(bi, ctx); 339 340 return 1; 341 } 342 343 static int bio_zlib_free(BIO *bi) 344 { 345 BIO_ZLIB_CTX *ctx; 346 if (!bi) 347 return 0; 348 ctx = BIO_get_data(bi); 349 if (ctx->ibuf) { 350 /* Destroy decompress context */ 351 inflateEnd(&ctx->zin); 352 OPENSSL_free(ctx->ibuf); 353 } 354 if (ctx->obuf) { 355 /* Destroy compress context */ 356 deflateEnd(&ctx->zout); 357 OPENSSL_free(ctx->obuf); 358 } 359 OPENSSL_free(ctx); 360 BIO_set_data(bi, NULL); 361 BIO_set_init(bi, 0); 362 363 return 1; 364 } 365 366 static int bio_zlib_read(BIO *b, char *out, int outl) 367 { 368 BIO_ZLIB_CTX *ctx; 369 int ret; 370 z_stream *zin; 371 BIO *next = BIO_next(b); 372 373 if (!out || !outl) 374 return 0; 375 ctx = BIO_get_data(b); 376 zin = &ctx->zin; 377 BIO_clear_retry_flags(b); 378 if (!ctx->ibuf) { 379 ctx->ibuf = OPENSSL_malloc(ctx->ibufsize); 380 if (ctx->ibuf == NULL) { 381 COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE); 382 return 0; 383 } 384 inflateInit(zin); 385 zin->next_in = ctx->ibuf; 386 zin->avail_in = 0; 387 } 388 389 /* Copy output data directly to supplied buffer */ 390 zin->next_out = (unsigned char *)out; 391 zin->avail_out = (unsigned int)outl; 392 for (;;) { 393 /* Decompress while data available */ 394 while (zin->avail_in) { 395 ret = inflate(zin, 0); 396 if ((ret != Z_OK) && (ret != Z_STREAM_END)) { 397 COMPerr(COMP_F_BIO_ZLIB_READ, COMP_R_ZLIB_INFLATE_ERROR); 398 ERR_add_error_data(2, "zlib error:", zError(ret)); 399 return 0; 400 } 401 /* If EOF or we've read everything then return */ 402 if ((ret == Z_STREAM_END) || !zin->avail_out) 403 return outl - zin->avail_out; 404 } 405 406 /* 407 * No data in input buffer try to read some in, if an error then 408 * return the total data read. 409 */ 410 ret = BIO_read(next, ctx->ibuf, ctx->ibufsize); 411 if (ret <= 0) { 412 /* Total data read */ 413 int tot = outl - zin->avail_out; 414 BIO_copy_next_retry(b); 415 if (ret < 0) 416 return (tot > 0) ? tot : ret; 417 return tot; 418 } 419 zin->avail_in = ret; 420 zin->next_in = ctx->ibuf; 421 } 422 } 423 424 static int bio_zlib_write(BIO *b, const char *in, int inl) 425 { 426 BIO_ZLIB_CTX *ctx; 427 int ret; 428 z_stream *zout; 429 BIO *next = BIO_next(b); 430 431 if (!in || !inl) 432 return 0; 433 ctx = BIO_get_data(b); 434 if (ctx->odone) 435 return 0; 436 zout = &ctx->zout; 437 BIO_clear_retry_flags(b); 438 if (!ctx->obuf) { 439 ctx->obuf = OPENSSL_malloc(ctx->obufsize); 440 /* Need error here */ 441 if (ctx->obuf == NULL) { 442 COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE); 443 return 0; 444 } 445 ctx->optr = ctx->obuf; 446 ctx->ocount = 0; 447 deflateInit(zout, ctx->comp_level); 448 zout->next_out = ctx->obuf; 449 zout->avail_out = ctx->obufsize; 450 } 451 /* Obtain input data directly from supplied buffer */ 452 zout->next_in = (void *)in; 453 zout->avail_in = inl; 454 for (;;) { 455 /* If data in output buffer write it first */ 456 while (ctx->ocount) { 457 ret = BIO_write(next, ctx->optr, ctx->ocount); 458 if (ret <= 0) { 459 /* Total data written */ 460 int tot = inl - zout->avail_in; 461 BIO_copy_next_retry(b); 462 if (ret < 0) 463 return (tot > 0) ? tot : ret; 464 return tot; 465 } 466 ctx->optr += ret; 467 ctx->ocount -= ret; 468 } 469 470 /* Have we consumed all supplied data? */ 471 if (!zout->avail_in) 472 return inl; 473 474 /* Compress some more */ 475 476 /* Reset buffer */ 477 ctx->optr = ctx->obuf; 478 zout->next_out = ctx->obuf; 479 zout->avail_out = ctx->obufsize; 480 /* Compress some more */ 481 ret = deflate(zout, 0); 482 if (ret != Z_OK) { 483 COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR); 484 ERR_add_error_data(2, "zlib error:", zError(ret)); 485 return 0; 486 } 487 ctx->ocount = ctx->obufsize - zout->avail_out; 488 } 489 } 490 491 static int bio_zlib_flush(BIO *b) 492 { 493 BIO_ZLIB_CTX *ctx; 494 int ret; 495 z_stream *zout; 496 BIO *next = BIO_next(b); 497 498 ctx = BIO_get_data(b); 499 /* If no data written or already flush show success */ 500 if (!ctx->obuf || (ctx->odone && !ctx->ocount)) 501 return 1; 502 zout = &ctx->zout; 503 BIO_clear_retry_flags(b); 504 /* No more input data */ 505 zout->next_in = NULL; 506 zout->avail_in = 0; 507 for (;;) { 508 /* If data in output buffer write it first */ 509 while (ctx->ocount) { 510 ret = BIO_write(next, ctx->optr, ctx->ocount); 511 if (ret <= 0) { 512 BIO_copy_next_retry(b); 513 return ret; 514 } 515 ctx->optr += ret; 516 ctx->ocount -= ret; 517 } 518 if (ctx->odone) 519 return 1; 520 521 /* Compress some more */ 522 523 /* Reset buffer */ 524 ctx->optr = ctx->obuf; 525 zout->next_out = ctx->obuf; 526 zout->avail_out = ctx->obufsize; 527 /* Compress some more */ 528 ret = deflate(zout, Z_FINISH); 529 if (ret == Z_STREAM_END) 530 ctx->odone = 1; 531 else if (ret != Z_OK) { 532 COMPerr(COMP_F_BIO_ZLIB_FLUSH, COMP_R_ZLIB_DEFLATE_ERROR); 533 ERR_add_error_data(2, "zlib error:", zError(ret)); 534 return 0; 535 } 536 ctx->ocount = ctx->obufsize - zout->avail_out; 537 } 538 } 539 540 static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) 541 { 542 BIO_ZLIB_CTX *ctx; 543 int ret, *ip; 544 int ibs, obs; 545 BIO *next = BIO_next(b); 546 547 if (next == NULL) 548 return 0; 549 ctx = BIO_get_data(b); 550 switch (cmd) { 551 552 case BIO_CTRL_RESET: 553 ctx->ocount = 0; 554 ctx->odone = 0; 555 ret = 1; 556 break; 557 558 case BIO_CTRL_FLUSH: 559 ret = bio_zlib_flush(b); 560 if (ret > 0) 561 ret = BIO_flush(next); 562 break; 563 564 case BIO_C_SET_BUFF_SIZE: 565 ibs = -1; 566 obs = -1; 567 if (ptr != NULL) { 568 ip = ptr; 569 if (*ip == 0) 570 ibs = (int)num; 571 else 572 obs = (int)num; 573 } else { 574 ibs = (int)num; 575 obs = ibs; 576 } 577 578 if (ibs != -1) { 579 OPENSSL_free(ctx->ibuf); 580 ctx->ibuf = NULL; 581 ctx->ibufsize = ibs; 582 } 583 584 if (obs != -1) { 585 OPENSSL_free(ctx->obuf); 586 ctx->obuf = NULL; 587 ctx->obufsize = obs; 588 } 589 ret = 1; 590 break; 591 592 case BIO_C_DO_STATE_MACHINE: 593 BIO_clear_retry_flags(b); 594 ret = BIO_ctrl(next, cmd, num, ptr); 595 BIO_copy_next_retry(b); 596 break; 597 598 default: 599 ret = BIO_ctrl(next, cmd, num, ptr); 600 break; 601 602 } 603 604 return ret; 605 } 606 607 static long bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) 608 { 609 BIO *next = BIO_next(b); 610 if (next == NULL) 611 return 0; 612 return BIO_callback_ctrl(next, cmd, fp); 613 } 614 615 #endif 616