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 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 619