| OLD | NEW |
| (Empty) |
| 1 /* crypto/bio/bss_bio.c -*- Mode: C; c-file-style: "eay" -*- */ | |
| 2 /* ==================================================================== | |
| 3 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. | |
| 4 * | |
| 5 * Redistribution and use in source and binary forms, with or without | |
| 6 * modification, are permitted provided that the following conditions | |
| 7 * are met: | |
| 8 * | |
| 9 * 1. Redistributions of source code must retain the above copyright | |
| 10 * notice, this list of conditions and the following disclaimer. | |
| 11 * | |
| 12 * 2. Redistributions in binary form must reproduce the above copyright | |
| 13 * notice, this list of conditions and the following disclaimer in | |
| 14 * the documentation and/or other materials provided with the | |
| 15 * distribution. | |
| 16 * | |
| 17 * 3. All advertising materials mentioning features or use of this | |
| 18 * software must display the following acknowledgment: | |
| 19 * "This product includes software developed by the OpenSSL Project | |
| 20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | |
| 21 * | |
| 22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
| 23 * endorse or promote products derived from this software without | |
| 24 * prior written permission. For written permission, please contact | |
| 25 * openssl-core@openssl.org. | |
| 26 * | |
| 27 * 5. Products derived from this software may not be called "OpenSSL" | |
| 28 * nor may "OpenSSL" appear in their names without prior written | |
| 29 * permission of the OpenSSL Project. | |
| 30 * | |
| 31 * 6. Redistributions of any form whatsoever must retain the following | |
| 32 * acknowledgment: | |
| 33 * "This product includes software developed by the OpenSSL Project | |
| 34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | |
| 35 * | |
| 36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
| 37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
| 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
| 42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
| 47 * OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 48 * ==================================================================== | |
| 49 * | |
| 50 * This product includes cryptographic software written by Eric Young | |
| 51 * (eay@cryptsoft.com). This product includes software written by Tim | |
| 52 * Hudson (tjh@cryptsoft.com). | |
| 53 * | |
| 54 */ | |
| 55 | |
| 56 /* Special method for a BIO where the other endpoint is also a BIO | |
| 57 * of this kind, handled by the same thread (i.e. the "peer" is actually | |
| 58 * ourselves, wearing a different hat). | |
| 59 * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces | |
| 60 * for which no specific BIO method is available. | |
| 61 * See ssl/ssltest.c for some hints on how this can be used. */ | |
| 62 | |
| 63 /* BIO_DEBUG implies BIO_PAIR_DEBUG */ | |
| 64 #ifdef BIO_DEBUG | |
| 65 # ifndef BIO_PAIR_DEBUG | |
| 66 # define BIO_PAIR_DEBUG | |
| 67 # endif | |
| 68 #endif | |
| 69 | |
| 70 /* disable assert() unless BIO_PAIR_DEBUG has been defined */ | |
| 71 #ifndef BIO_PAIR_DEBUG | |
| 72 # ifndef NDEBUG | |
| 73 # define NDEBUG | |
| 74 # endif | |
| 75 #endif | |
| 76 | |
| 77 #include <assert.h> | |
| 78 #include <limits.h> | |
| 79 #include <stdlib.h> | |
| 80 #include <string.h> | |
| 81 | |
| 82 #include <openssl/bio.h> | |
| 83 #include <openssl/err.h> | |
| 84 #include <openssl/crypto.h> | |
| 85 | |
| 86 #include "e_os.h" | |
| 87 | |
| 88 /* VxWorks defines SSIZE_MAX with an empty value causing compile errors */ | |
| 89 #if defined(OPENSSL_SYS_VXWORKS) | |
| 90 # undef SSIZE_MAX | |
| 91 #endif | |
| 92 #ifndef SSIZE_MAX | |
| 93 # define SSIZE_MAX INT_MAX | |
| 94 #endif | |
| 95 | |
| 96 static int bio_new(BIO *bio); | |
| 97 static int bio_free(BIO *bio); | |
| 98 static int bio_read(BIO *bio, char *buf, int size); | |
| 99 static int bio_write(BIO *bio, const char *buf, int num); | |
| 100 static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr); | |
| 101 static int bio_puts(BIO *bio, const char *str); | |
| 102 | |
| 103 static int bio_make_pair(BIO *bio1, BIO *bio2); | |
| 104 static void bio_destroy_pair(BIO *bio); | |
| 105 | |
| 106 static BIO_METHOD methods_biop = | |
| 107 { | |
| 108 BIO_TYPE_BIO, | |
| 109 "BIO pair", | |
| 110 bio_write, | |
| 111 bio_read, | |
| 112 bio_puts, | |
| 113 NULL /* no bio_gets */, | |
| 114 bio_ctrl, | |
| 115 bio_new, | |
| 116 bio_free, | |
| 117 NULL /* no bio_callback_ctrl */ | |
| 118 }; | |
| 119 | |
| 120 BIO_METHOD *BIO_s_bio(void) | |
| 121 { | |
| 122 return &methods_biop; | |
| 123 } | |
| 124 | |
| 125 struct bio_bio_st | |
| 126 { | |
| 127 BIO *peer; /* NULL if buf == NULL. | |
| 128 * If peer != NULL, then peer->ptr is also a bio_bio_st, | |
| 129 * and its "peer" member points back to us. | |
| 130 * peer != NULL iff init != 0 in the BIO. */ | |
| 131 | |
| 132 /* This is for what we write (i.e. reading uses peer's struct): */ | |
| 133 int closed; /* valid iff peer != NULL */ | |
| 134 size_t len; /* valid iff buf != NULL; 0 if peer == NULL */ | |
| 135 size_t offset; /* valid iff buf != NULL; 0 if len == 0 */ | |
| 136 size_t size; | |
| 137 char *buf; /* "size" elements (if != NULL) */ | |
| 138 | |
| 139 size_t request; /* valid iff peer != NULL; 0 if len != 0, | |
| 140 * otherwise set by peer to number of bytes | |
| 141 * it (unsuccessfully) tried to read, | |
| 142 * never more than buffer space (size-len) warrants. */ | |
| 143 }; | |
| 144 | |
| 145 static int bio_new(BIO *bio) | |
| 146 { | |
| 147 struct bio_bio_st *b; | |
| 148 | |
| 149 b = OPENSSL_malloc(sizeof *b); | |
| 150 if (b == NULL) | |
| 151 return 0; | |
| 152 | |
| 153 b->peer = NULL; | |
| 154 b->size = 17*1024; /* enough for one TLS record (just a default) */ | |
| 155 b->buf = NULL; | |
| 156 | |
| 157 bio->ptr = b; | |
| 158 return 1; | |
| 159 } | |
| 160 | |
| 161 | |
| 162 static int bio_free(BIO *bio) | |
| 163 { | |
| 164 struct bio_bio_st *b; | |
| 165 | |
| 166 if (bio == NULL) | |
| 167 return 0; | |
| 168 b = bio->ptr; | |
| 169 | |
| 170 assert(b != NULL); | |
| 171 | |
| 172 if (b->peer) | |
| 173 bio_destroy_pair(bio); | |
| 174 | |
| 175 if (b->buf != NULL) | |
| 176 { | |
| 177 OPENSSL_free(b->buf); | |
| 178 } | |
| 179 | |
| 180 OPENSSL_free(b); | |
| 181 | |
| 182 return 1; | |
| 183 } | |
| 184 | |
| 185 | |
| 186 | |
| 187 static int bio_read(BIO *bio, char *buf, int size_) | |
| 188 { | |
| 189 size_t size = size_; | |
| 190 size_t rest; | |
| 191 struct bio_bio_st *b, *peer_b; | |
| 192 | |
| 193 BIO_clear_retry_flags(bio); | |
| 194 | |
| 195 if (!bio->init) | |
| 196 return 0; | |
| 197 | |
| 198 b = bio->ptr; | |
| 199 assert(b != NULL); | |
| 200 assert(b->peer != NULL); | |
| 201 peer_b = b->peer->ptr; | |
| 202 assert(peer_b != NULL); | |
| 203 assert(peer_b->buf != NULL); | |
| 204 | |
| 205 peer_b->request = 0; /* will be set in "retry_read" situation */ | |
| 206 | |
| 207 if (buf == NULL || size == 0) | |
| 208 return 0; | |
| 209 | |
| 210 if (peer_b->len == 0) | |
| 211 { | |
| 212 if (peer_b->closed) | |
| 213 return 0; /* writer has closed, and no data is left */ | |
| 214 else | |
| 215 { | |
| 216 BIO_set_retry_read(bio); /* buffer is empty */ | |
| 217 if (size <= peer_b->size) | |
| 218 peer_b->request = size; | |
| 219 else | |
| 220 /* don't ask for more than the peer can | |
| 221 * deliver in one write */ | |
| 222 peer_b->request = peer_b->size; | |
| 223 return -1; | |
| 224 } | |
| 225 } | |
| 226 | |
| 227 /* we can read */ | |
| 228 if (peer_b->len < size) | |
| 229 size = peer_b->len; | |
| 230 | |
| 231 /* now read "size" bytes */ | |
| 232 | |
| 233 rest = size; | |
| 234 | |
| 235 assert(rest > 0); | |
| 236 do /* one or two iterations */ | |
| 237 { | |
| 238 size_t chunk; | |
| 239 | |
| 240 assert(rest <= peer_b->len); | |
| 241 if (peer_b->offset + rest <= peer_b->size) | |
| 242 chunk = rest; | |
| 243 else | |
| 244 /* wrap around ring buffer */ | |
| 245 chunk = peer_b->size - peer_b->offset; | |
| 246 assert(peer_b->offset + chunk <= peer_b->size); | |
| 247 | |
| 248 memcpy(buf, peer_b->buf + peer_b->offset, chunk); | |
| 249 | |
| 250 peer_b->len -= chunk; | |
| 251 if (peer_b->len) | |
| 252 { | |
| 253 peer_b->offset += chunk; | |
| 254 assert(peer_b->offset <= peer_b->size); | |
| 255 if (peer_b->offset == peer_b->size) | |
| 256 peer_b->offset = 0; | |
| 257 buf += chunk; | |
| 258 } | |
| 259 else | |
| 260 { | |
| 261 /* buffer now empty, no need to advance "buf" */ | |
| 262 assert(chunk == rest); | |
| 263 peer_b->offset = 0; | |
| 264 } | |
| 265 rest -= chunk; | |
| 266 } | |
| 267 while (rest); | |
| 268 | |
| 269 return size; | |
| 270 } | |
| 271 | |
| 272 /* non-copying interface: provide pointer to available data in buffer | |
| 273 * bio_nread0: return number of available bytes | |
| 274 * bio_nread: also advance index | |
| 275 * (example usage: bio_nread0(), read from buffer, bio_nread() | |
| 276 * or just bio_nread(), read from buffer) | |
| 277 */ | |
| 278 /* WARNING: The non-copying interface is largely untested as of yet | |
| 279 * and may contain bugs. */ | |
| 280 static ossl_ssize_t bio_nread0(BIO *bio, char **buf) | |
| 281 { | |
| 282 struct bio_bio_st *b, *peer_b; | |
| 283 ossl_ssize_t num; | |
| 284 | |
| 285 BIO_clear_retry_flags(bio); | |
| 286 | |
| 287 if (!bio->init) | |
| 288 return 0; | |
| 289 | |
| 290 b = bio->ptr; | |
| 291 assert(b != NULL); | |
| 292 assert(b->peer != NULL); | |
| 293 peer_b = b->peer->ptr; | |
| 294 assert(peer_b != NULL); | |
| 295 assert(peer_b->buf != NULL); | |
| 296 | |
| 297 peer_b->request = 0; | |
| 298 | |
| 299 if (peer_b->len == 0) | |
| 300 { | |
| 301 char dummy; | |
| 302 | |
| 303 /* avoid code duplication -- nothing available for reading */ | |
| 304 return bio_read(bio, &dummy, 1); /* returns 0 or -1 */ | |
| 305 } | |
| 306 | |
| 307 num = peer_b->len; | |
| 308 if (peer_b->size < peer_b->offset + num) | |
| 309 /* no ring buffer wrap-around for non-copying interface */ | |
| 310 num = peer_b->size - peer_b->offset; | |
| 311 assert(num > 0); | |
| 312 | |
| 313 if (buf != NULL) | |
| 314 *buf = peer_b->buf + peer_b->offset; | |
| 315 return num; | |
| 316 } | |
| 317 | |
| 318 static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_) | |
| 319 { | |
| 320 struct bio_bio_st *b, *peer_b; | |
| 321 ossl_ssize_t num, available; | |
| 322 | |
| 323 if (num_ > SSIZE_MAX) | |
| 324 num = SSIZE_MAX; | |
| 325 else | |
| 326 num = (ossl_ssize_t)num_; | |
| 327 | |
| 328 available = bio_nread0(bio, buf); | |
| 329 if (num > available) | |
| 330 num = available; | |
| 331 if (num <= 0) | |
| 332 return num; | |
| 333 | |
| 334 b = bio->ptr; | |
| 335 peer_b = b->peer->ptr; | |
| 336 | |
| 337 peer_b->len -= num; | |
| 338 if (peer_b->len) | |
| 339 { | |
| 340 peer_b->offset += num; | |
| 341 assert(peer_b->offset <= peer_b->size); | |
| 342 if (peer_b->offset == peer_b->size) | |
| 343 peer_b->offset = 0; | |
| 344 } | |
| 345 else | |
| 346 peer_b->offset = 0; | |
| 347 | |
| 348 return num; | |
| 349 } | |
| 350 | |
| 351 | |
| 352 static int bio_write(BIO *bio, const char *buf, int num_) | |
| 353 { | |
| 354 size_t num = num_; | |
| 355 size_t rest; | |
| 356 struct bio_bio_st *b; | |
| 357 | |
| 358 BIO_clear_retry_flags(bio); | |
| 359 | |
| 360 if (!bio->init || buf == NULL || num == 0) | |
| 361 return 0; | |
| 362 | |
| 363 b = bio->ptr; | |
| 364 assert(b != NULL); | |
| 365 assert(b->peer != NULL); | |
| 366 assert(b->buf != NULL); | |
| 367 | |
| 368 b->request = 0; | |
| 369 if (b->closed) | |
| 370 { | |
| 371 /* we already closed */ | |
| 372 BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE); | |
| 373 return -1; | |
| 374 } | |
| 375 | |
| 376 assert(b->len <= b->size); | |
| 377 | |
| 378 if (b->len == b->size) | |
| 379 { | |
| 380 BIO_set_retry_write(bio); /* buffer is full */ | |
| 381 return -1; | |
| 382 } | |
| 383 | |
| 384 /* we can write */ | |
| 385 if (num > b->size - b->len) | |
| 386 num = b->size - b->len; | |
| 387 | |
| 388 /* now write "num" bytes */ | |
| 389 | |
| 390 rest = num; | |
| 391 | |
| 392 assert(rest > 0); | |
| 393 do /* one or two iterations */ | |
| 394 { | |
| 395 size_t write_offset; | |
| 396 size_t chunk; | |
| 397 | |
| 398 assert(b->len + rest <= b->size); | |
| 399 | |
| 400 write_offset = b->offset + b->len; | |
| 401 if (write_offset >= b->size) | |
| 402 write_offset -= b->size; | |
| 403 /* b->buf[write_offset] is the first byte we can write to. */ | |
| 404 | |
| 405 if (write_offset + rest <= b->size) | |
| 406 chunk = rest; | |
| 407 else | |
| 408 /* wrap around ring buffer */ | |
| 409 chunk = b->size - write_offset; | |
| 410 | |
| 411 memcpy(b->buf + write_offset, buf, chunk); | |
| 412 | |
| 413 b->len += chunk; | |
| 414 | |
| 415 assert(b->len <= b->size); | |
| 416 | |
| 417 rest -= chunk; | |
| 418 buf += chunk; | |
| 419 } | |
| 420 while (rest); | |
| 421 | |
| 422 return num; | |
| 423 } | |
| 424 | |
| 425 /* non-copying interface: provide pointer to region to write to | |
| 426 * bio_nwrite0: check how much space is available | |
| 427 * bio_nwrite: also increase length | |
| 428 * (example usage: bio_nwrite0(), write to buffer, bio_nwrite() | |
| 429 * or just bio_nwrite(), write to buffer) | |
| 430 */ | |
| 431 static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf) | |
| 432 { | |
| 433 struct bio_bio_st *b; | |
| 434 size_t num; | |
| 435 size_t write_offset; | |
| 436 | |
| 437 BIO_clear_retry_flags(bio); | |
| 438 | |
| 439 if (!bio->init) | |
| 440 return 0; | |
| 441 | |
| 442 b = bio->ptr; | |
| 443 assert(b != NULL); | |
| 444 assert(b->peer != NULL); | |
| 445 assert(b->buf != NULL); | |
| 446 | |
| 447 b->request = 0; | |
| 448 if (b->closed) | |
| 449 { | |
| 450 BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE); | |
| 451 return -1; | |
| 452 } | |
| 453 | |
| 454 assert(b->len <= b->size); | |
| 455 | |
| 456 if (b->len == b->size) | |
| 457 { | |
| 458 BIO_set_retry_write(bio); | |
| 459 return -1; | |
| 460 } | |
| 461 | |
| 462 num = b->size - b->len; | |
| 463 write_offset = b->offset + b->len; | |
| 464 if (write_offset >= b->size) | |
| 465 write_offset -= b->size; | |
| 466 if (write_offset + num > b->size) | |
| 467 /* no ring buffer wrap-around for non-copying interface | |
| 468 * (to fulfil the promise by BIO_ctrl_get_write_guarantee, | |
| 469 * BIO_nwrite may have to be called twice) */ | |
| 470 num = b->size - write_offset; | |
| 471 | |
| 472 if (buf != NULL) | |
| 473 *buf = b->buf + write_offset; | |
| 474 assert(write_offset + num <= b->size); | |
| 475 | |
| 476 return num; | |
| 477 } | |
| 478 | |
| 479 static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_) | |
| 480 { | |
| 481 struct bio_bio_st *b; | |
| 482 ossl_ssize_t num, space; | |
| 483 | |
| 484 if (num_ > SSIZE_MAX) | |
| 485 num = SSIZE_MAX; | |
| 486 else | |
| 487 num = (ossl_ssize_t)num_; | |
| 488 | |
| 489 space = bio_nwrite0(bio, buf); | |
| 490 if (num > space) | |
| 491 num = space; | |
| 492 if (num <= 0) | |
| 493 return num; | |
| 494 b = bio->ptr; | |
| 495 assert(b != NULL); | |
| 496 b->len += num; | |
| 497 assert(b->len <= b->size); | |
| 498 | |
| 499 return num; | |
| 500 } | |
| 501 | |
| 502 | |
| 503 static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | |
| 504 { | |
| 505 long ret; | |
| 506 struct bio_bio_st *b = bio->ptr; | |
| 507 | |
| 508 assert(b != NULL); | |
| 509 | |
| 510 switch (cmd) | |
| 511 { | |
| 512 /* specific CTRL codes */ | |
| 513 | |
| 514 case BIO_C_SET_WRITE_BUF_SIZE: | |
| 515 if (b->peer) | |
| 516 { | |
| 517 BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE); | |
| 518 ret = 0; | |
| 519 } | |
| 520 else if (num == 0) | |
| 521 { | |
| 522 BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT); | |
| 523 ret = 0; | |
| 524 } | |
| 525 else | |
| 526 { | |
| 527 size_t new_size = num; | |
| 528 | |
| 529 if (b->size != new_size) | |
| 530 { | |
| 531 if (b->buf) | |
| 532 { | |
| 533 OPENSSL_free(b->buf); | |
| 534 b->buf = NULL; | |
| 535 } | |
| 536 b->size = new_size; | |
| 537 } | |
| 538 ret = 1; | |
| 539 } | |
| 540 break; | |
| 541 | |
| 542 case BIO_C_GET_WRITE_BUF_SIZE: | |
| 543 ret = (long) b->size; | |
| 544 break; | |
| 545 | |
| 546 case BIO_C_MAKE_BIO_PAIR: | |
| 547 { | |
| 548 BIO *other_bio = ptr; | |
| 549 | |
| 550 if (bio_make_pair(bio, other_bio)) | |
| 551 ret = 1; | |
| 552 else | |
| 553 ret = 0; | |
| 554 } | |
| 555 break; | |
| 556 | |
| 557 case BIO_C_DESTROY_BIO_PAIR: | |
| 558 /* Affects both BIOs in the pair -- call just once! | |
| 559 * Or let BIO_free(bio1); BIO_free(bio2); do the job. */ | |
| 560 bio_destroy_pair(bio); | |
| 561 ret = 1; | |
| 562 break; | |
| 563 | |
| 564 case BIO_C_GET_WRITE_GUARANTEE: | |
| 565 /* How many bytes can the caller feed to the next write | |
| 566 * without having to keep any? */ | |
| 567 if (b->peer == NULL || b->closed) | |
| 568 ret = 0; | |
| 569 else | |
| 570 ret = (long) b->size - b->len; | |
| 571 break; | |
| 572 | |
| 573 case BIO_C_GET_READ_REQUEST: | |
| 574 /* If the peer unsuccessfully tried to read, how many bytes | |
| 575 * were requested? (As with BIO_CTRL_PENDING, that number | |
| 576 * can usually be treated as boolean.) */ | |
| 577 ret = (long) b->request; | |
| 578 break; | |
| 579 | |
| 580 case BIO_C_RESET_READ_REQUEST: | |
| 581 /* Reset request. (Can be useful after read attempts | |
| 582 * at the other side that are meant to be non-blocking, | |
| 583 * e.g. when probing SSL_read to see if any data is | |
| 584 * available.) */ | |
| 585 b->request = 0; | |
| 586 ret = 1; | |
| 587 break; | |
| 588 | |
| 589 case BIO_C_SHUTDOWN_WR: | |
| 590 /* similar to shutdown(..., SHUT_WR) */ | |
| 591 b->closed = 1; | |
| 592 ret = 1; | |
| 593 break; | |
| 594 | |
| 595 case BIO_C_NREAD0: | |
| 596 /* prepare for non-copying read */ | |
| 597 ret = (long) bio_nread0(bio, ptr); | |
| 598 break; | |
| 599 | |
| 600 case BIO_C_NREAD: | |
| 601 /* non-copying read */ | |
| 602 ret = (long) bio_nread(bio, ptr, (size_t) num); | |
| 603 break; | |
| 604 | |
| 605 case BIO_C_NWRITE0: | |
| 606 /* prepare for non-copying write */ | |
| 607 ret = (long) bio_nwrite0(bio, ptr); | |
| 608 break; | |
| 609 | |
| 610 case BIO_C_NWRITE: | |
| 611 /* non-copying write */ | |
| 612 ret = (long) bio_nwrite(bio, ptr, (size_t) num); | |
| 613 break; | |
| 614 | |
| 615 | |
| 616 /* standard CTRL codes follow */ | |
| 617 | |
| 618 case BIO_CTRL_RESET: | |
| 619 if (b->buf != NULL) | |
| 620 { | |
| 621 b->len = 0; | |
| 622 b->offset = 0; | |
| 623 } | |
| 624 ret = 0; | |
| 625 break; | |
| 626 | |
| 627 case BIO_CTRL_GET_CLOSE: | |
| 628 ret = bio->shutdown; | |
| 629 break; | |
| 630 | |
| 631 case BIO_CTRL_SET_CLOSE: | |
| 632 bio->shutdown = (int) num; | |
| 633 ret = 1; | |
| 634 break; | |
| 635 | |
| 636 case BIO_CTRL_PENDING: | |
| 637 if (b->peer != NULL) | |
| 638 { | |
| 639 struct bio_bio_st *peer_b = b->peer->ptr; | |
| 640 | |
| 641 ret = (long) peer_b->len; | |
| 642 } | |
| 643 else | |
| 644 ret = 0; | |
| 645 break; | |
| 646 | |
| 647 case BIO_CTRL_WPENDING: | |
| 648 if (b->buf != NULL) | |
| 649 ret = (long) b->len; | |
| 650 else | |
| 651 ret = 0; | |
| 652 break; | |
| 653 | |
| 654 case BIO_CTRL_DUP: | |
| 655 /* See BIO_dup_chain for circumstances we have to expect. */ | |
| 656 { | |
| 657 BIO *other_bio = ptr; | |
| 658 struct bio_bio_st *other_b; | |
| 659 | |
| 660 assert(other_bio != NULL); | |
| 661 other_b = other_bio->ptr; | |
| 662 assert(other_b != NULL); | |
| 663 | |
| 664 assert(other_b->buf == NULL); /* other_bio is always fresh */ | |
| 665 | |
| 666 other_b->size = b->size; | |
| 667 } | |
| 668 | |
| 669 ret = 1; | |
| 670 break; | |
| 671 | |
| 672 case BIO_CTRL_FLUSH: | |
| 673 ret = 1; | |
| 674 break; | |
| 675 | |
| 676 case BIO_CTRL_EOF: | |
| 677 { | |
| 678 BIO *other_bio = ptr; | |
| 679 | |
| 680 if (other_bio) | |
| 681 { | |
| 682 struct bio_bio_st *other_b = other_bio->ptr; | |
| 683 | |
| 684 assert(other_b != NULL); | |
| 685 ret = other_b->len == 0 && other_b->closed; | |
| 686 } | |
| 687 else | |
| 688 ret = 1; | |
| 689 } | |
| 690 break; | |
| 691 | |
| 692 default: | |
| 693 ret = 0; | |
| 694 } | |
| 695 return ret; | |
| 696 } | |
| 697 | |
| 698 static int bio_puts(BIO *bio, const char *str) | |
| 699 { | |
| 700 return bio_write(bio, str, strlen(str)); | |
| 701 } | |
| 702 | |
| 703 | |
| 704 static int bio_make_pair(BIO *bio1, BIO *bio2) | |
| 705 { | |
| 706 struct bio_bio_st *b1, *b2; | |
| 707 | |
| 708 assert(bio1 != NULL); | |
| 709 assert(bio2 != NULL); | |
| 710 | |
| 711 b1 = bio1->ptr; | |
| 712 b2 = bio2->ptr; | |
| 713 | |
| 714 if (b1->peer != NULL || b2->peer != NULL) | |
| 715 { | |
| 716 BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE); | |
| 717 return 0; | |
| 718 } | |
| 719 | |
| 720 if (b1->buf == NULL) | |
| 721 { | |
| 722 b1->buf = OPENSSL_malloc(b1->size); | |
| 723 if (b1->buf == NULL) | |
| 724 { | |
| 725 BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); | |
| 726 return 0; | |
| 727 } | |
| 728 b1->len = 0; | |
| 729 b1->offset = 0; | |
| 730 } | |
| 731 | |
| 732 if (b2->buf == NULL) | |
| 733 { | |
| 734 b2->buf = OPENSSL_malloc(b2->size); | |
| 735 if (b2->buf == NULL) | |
| 736 { | |
| 737 BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); | |
| 738 return 0; | |
| 739 } | |
| 740 b2->len = 0; | |
| 741 b2->offset = 0; | |
| 742 } | |
| 743 | |
| 744 b1->peer = bio2; | |
| 745 b1->closed = 0; | |
| 746 b1->request = 0; | |
| 747 b2->peer = bio1; | |
| 748 b2->closed = 0; | |
| 749 b2->request = 0; | |
| 750 | |
| 751 bio1->init = 1; | |
| 752 bio2->init = 1; | |
| 753 | |
| 754 return 1; | |
| 755 } | |
| 756 | |
| 757 static void bio_destroy_pair(BIO *bio) | |
| 758 { | |
| 759 struct bio_bio_st *b = bio->ptr; | |
| 760 | |
| 761 if (b != NULL) | |
| 762 { | |
| 763 BIO *peer_bio = b->peer; | |
| 764 | |
| 765 if (peer_bio != NULL) | |
| 766 { | |
| 767 struct bio_bio_st *peer_b = peer_bio->ptr; | |
| 768 | |
| 769 assert(peer_b != NULL); | |
| 770 assert(peer_b->peer == bio); | |
| 771 | |
| 772 peer_b->peer = NULL; | |
| 773 peer_bio->init = 0; | |
| 774 assert(peer_b->buf != NULL); | |
| 775 peer_b->len = 0; | |
| 776 peer_b->offset = 0; | |
| 777 | |
| 778 b->peer = NULL; | |
| 779 bio->init = 0; | |
| 780 assert(b->buf != NULL); | |
| 781 b->len = 0; | |
| 782 b->offset = 0; | |
| 783 } | |
| 784 } | |
| 785 } | |
| 786 | |
| 787 | |
| 788 /* Exported convenience functions */ | |
| 789 int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, | |
| 790 BIO **bio2_p, size_t writebuf2) | |
| 791 { | |
| 792 BIO *bio1 = NULL, *bio2 = NULL; | |
| 793 long r; | |
| 794 int ret = 0; | |
| 795 | |
| 796 bio1 = BIO_new(BIO_s_bio()); | |
| 797 if (bio1 == NULL) | |
| 798 goto err; | |
| 799 bio2 = BIO_new(BIO_s_bio()); | |
| 800 if (bio2 == NULL) | |
| 801 goto err; | |
| 802 | |
| 803 if (writebuf1) | |
| 804 { | |
| 805 r = BIO_set_write_buf_size(bio1, writebuf1); | |
| 806 if (!r) | |
| 807 goto err; | |
| 808 } | |
| 809 if (writebuf2) | |
| 810 { | |
| 811 r = BIO_set_write_buf_size(bio2, writebuf2); | |
| 812 if (!r) | |
| 813 goto err; | |
| 814 } | |
| 815 | |
| 816 r = BIO_make_bio_pair(bio1, bio2); | |
| 817 if (!r) | |
| 818 goto err; | |
| 819 ret = 1; | |
| 820 | |
| 821 err: | |
| 822 if (ret == 0) | |
| 823 { | |
| 824 if (bio1) | |
| 825 { | |
| 826 BIO_free(bio1); | |
| 827 bio1 = NULL; | |
| 828 } | |
| 829 if (bio2) | |
| 830 { | |
| 831 BIO_free(bio2); | |
| 832 bio2 = NULL; | |
| 833 } | |
| 834 } | |
| 835 | |
| 836 *bio1_p = bio1; | |
| 837 *bio2_p = bio2; | |
| 838 return ret; | |
| 839 } | |
| 840 | |
| 841 size_t BIO_ctrl_get_write_guarantee(BIO *bio) | |
| 842 { | |
| 843 return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); | |
| 844 } | |
| 845 | |
| 846 size_t BIO_ctrl_get_read_request(BIO *bio) | |
| 847 { | |
| 848 return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); | |
| 849 } | |
| 850 | |
| 851 int BIO_ctrl_reset_read_request(BIO *bio) | |
| 852 { | |
| 853 return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0); | |
| 854 } | |
| 855 | |
| 856 | |
| 857 /* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now | |
| 858 * (conceivably some other BIOs could allow non-copying reads and writes too.) | |
| 859 */ | |
| 860 int BIO_nread0(BIO *bio, char **buf) | |
| 861 { | |
| 862 long ret; | |
| 863 | |
| 864 if (!bio->init) | |
| 865 { | |
| 866 BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED); | |
| 867 return -2; | |
| 868 } | |
| 869 | |
| 870 ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf); | |
| 871 if (ret > INT_MAX) | |
| 872 return INT_MAX; | |
| 873 else | |
| 874 return (int) ret; | |
| 875 } | |
| 876 | |
| 877 int BIO_nread(BIO *bio, char **buf, int num) | |
| 878 { | |
| 879 int ret; | |
| 880 | |
| 881 if (!bio->init) | |
| 882 { | |
| 883 BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED); | |
| 884 return -2; | |
| 885 } | |
| 886 | |
| 887 ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf); | |
| 888 if (ret > 0) | |
| 889 bio->num_read += ret; | |
| 890 return ret; | |
| 891 } | |
| 892 | |
| 893 int BIO_nwrite0(BIO *bio, char **buf) | |
| 894 { | |
| 895 long ret; | |
| 896 | |
| 897 if (!bio->init) | |
| 898 { | |
| 899 BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED); | |
| 900 return -2; | |
| 901 } | |
| 902 | |
| 903 ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf); | |
| 904 if (ret > INT_MAX) | |
| 905 return INT_MAX; | |
| 906 else | |
| 907 return (int) ret; | |
| 908 } | |
| 909 | |
| 910 int BIO_nwrite(BIO *bio, char **buf, int num) | |
| 911 { | |
| 912 int ret; | |
| 913 | |
| 914 if (!bio->init) | |
| 915 { | |
| 916 BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED); | |
| 917 return -2; | |
| 918 } | |
| 919 | |
| 920 ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf); | |
| 921 if (ret > 0) | |
| 922 bio->num_write += ret; | |
| 923 return ret; | |
| 924 } | |
| OLD | NEW |