1295016Sjkim/* crypto/bio/bss_bio.c */ 2120631Snectar/* ==================================================================== 3120631Snectar * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 4120631Snectar * 5120631Snectar * Redistribution and use in source and binary forms, with or without 6120631Snectar * modification, are permitted provided that the following conditions 7120631Snectar * are met: 8120631Snectar * 9120631Snectar * 1. Redistributions of source code must retain the above copyright 10280304Sjkim * notice, this list of conditions and the following disclaimer. 11120631Snectar * 12120631Snectar * 2. Redistributions in binary form must reproduce the above copyright 13120631Snectar * notice, this list of conditions and the following disclaimer in 14120631Snectar * the documentation and/or other materials provided with the 15120631Snectar * distribution. 16120631Snectar * 17120631Snectar * 3. All advertising materials mentioning features or use of this 18120631Snectar * software must display the following acknowledgment: 19120631Snectar * "This product includes software developed by the OpenSSL Project 20120631Snectar * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21120631Snectar * 22120631Snectar * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23120631Snectar * endorse or promote products derived from this software without 24120631Snectar * prior written permission. For written permission, please contact 25120631Snectar * openssl-core@openssl.org. 26120631Snectar * 27120631Snectar * 5. Products derived from this software may not be called "OpenSSL" 28120631Snectar * nor may "OpenSSL" appear in their names without prior written 29120631Snectar * permission of the OpenSSL Project. 30120631Snectar * 31120631Snectar * 6. Redistributions of any form whatsoever must retain the following 32120631Snectar * acknowledgment: 33120631Snectar * "This product includes software developed by the OpenSSL Project 34120631Snectar * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35120631Snectar * 36120631Snectar * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37120631Snectar * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38120631Snectar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39120631Snectar * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40120631Snectar * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41120631Snectar * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42120631Snectar * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43120631Snectar * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44120631Snectar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45120631Snectar * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46120631Snectar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47120631Snectar * OF THE POSSIBILITY OF SUCH DAMAGE. 48120631Snectar * ==================================================================== 49120631Snectar * 50120631Snectar * This product includes cryptographic software written by Eric Young 51120631Snectar * (eay@cryptsoft.com). This product includes software written by Tim 52120631Snectar * Hudson (tjh@cryptsoft.com). 53120631Snectar * 54120631Snectar */ 5555714Skris 56280304Sjkim/* 57280304Sjkim * Special method for a BIO where the other endpoint is also a BIO of this 58280304Sjkim * kind, handled by the same thread (i.e. the "peer" is actually ourselves, 59280304Sjkim * wearing a different hat). Such "BIO pairs" are mainly for using the SSL 60280304Sjkim * library with I/O interfaces for which no specific BIO method is available. 61280304Sjkim * See ssl/ssltest.c for some hints on how this can be used. 62280304Sjkim */ 6355714Skris 64100936Snectar/* BIO_DEBUG implies BIO_PAIR_DEBUG */ 65100936Snectar#ifdef BIO_DEBUG 66100936Snectar# ifndef BIO_PAIR_DEBUG 67100936Snectar# define BIO_PAIR_DEBUG 68100936Snectar# endif 69100936Snectar#endif 70100936Snectar 71100936Snectar/* disable assert() unless BIO_PAIR_DEBUG has been defined */ 7255714Skris#ifndef BIO_PAIR_DEBUG 73100936Snectar# ifndef NDEBUG 74100936Snectar# define NDEBUG 75100936Snectar# endif 7655714Skris#endif 7755714Skris 7855714Skris#include <assert.h> 7959191Skris#include <limits.h> 8055714Skris#include <stdlib.h> 8155714Skris#include <string.h> 8255714Skris 8355714Skris#include <openssl/bio.h> 8455714Skris#include <openssl/err.h> 8555714Skris#include <openssl/crypto.h> 8655714Skris 87109998Smarkm#include "e_os.h" 88100928Snectar 89109998Smarkm/* VxWorks defines SSIZE_MAX with an empty value causing compile errors */ 90109998Smarkm#if defined(OPENSSL_SYS_VXWORKS) 91100928Snectar# undef SSIZE_MAX 92109998Smarkm#endif 93109998Smarkm#ifndef SSIZE_MAX 9459191Skris# define SSIZE_MAX INT_MAX 9559191Skris#endif 9659191Skris 9755714Skrisstatic int bio_new(BIO *bio); 9855714Skrisstatic int bio_free(BIO *bio); 9955714Skrisstatic int bio_read(BIO *bio, char *buf, int size); 10068651Skrisstatic int bio_write(BIO *bio, const char *buf, int num); 10155714Skrisstatic long bio_ctrl(BIO *bio, int cmd, long num, void *ptr); 10268651Skrisstatic int bio_puts(BIO *bio, const char *str); 10355714Skris 10455714Skrisstatic int bio_make_pair(BIO *bio1, BIO *bio2); 10555714Skrisstatic void bio_destroy_pair(BIO *bio); 10655714Skris 107280304Sjkimstatic BIO_METHOD methods_biop = { 108280304Sjkim BIO_TYPE_BIO, 109280304Sjkim "BIO pair", 110280304Sjkim bio_write, 111280304Sjkim bio_read, 112280304Sjkim bio_puts, 113280304Sjkim NULL /* no bio_gets */ , 114280304Sjkim bio_ctrl, 115280304Sjkim bio_new, 116280304Sjkim bio_free, 117280304Sjkim NULL /* no bio_callback_ctrl */ 11855714Skris}; 11955714Skris 12055714SkrisBIO_METHOD *BIO_s_bio(void) 12155714Skris{ 122280304Sjkim return &methods_biop; 123280304Sjkim} 12455714Skris 125280304Sjkimstruct bio_bio_st { 126280304Sjkim BIO *peer; /* NULL if buf == NULL. If peer != NULL, then 127280304Sjkim * peer->ptr is also a bio_bio_st, and its 128280304Sjkim * "peer" member points back to us. peer != 129280304Sjkim * NULL iff init != 0 in the BIO. */ 130280304Sjkim /* This is for what we write (i.e. reading uses peer's struct): */ 131280304Sjkim int closed; /* valid iff peer != NULL */ 132280304Sjkim size_t len; /* valid iff buf != NULL; 0 if peer == NULL */ 133280304Sjkim size_t offset; /* valid iff buf != NULL; 0 if len == 0 */ 134280304Sjkim size_t size; 135280304Sjkim char *buf; /* "size" elements (if != NULL) */ 136280304Sjkim size_t request; /* valid iff peer != NULL; 0 if len != 0, 137280304Sjkim * otherwise set by peer to number of bytes 138280304Sjkim * it (unsuccessfully) tried to read, never 139280304Sjkim * more than buffer space (size-len) 140280304Sjkim * warrants. */ 14155714Skris}; 14255714Skris 14355714Skrisstatic int bio_new(BIO *bio) 144280304Sjkim{ 145280304Sjkim struct bio_bio_st *b; 14655714Skris 147280304Sjkim b = OPENSSL_malloc(sizeof *b); 148280304Sjkim if (b == NULL) 149280304Sjkim return 0; 15055714Skris 151280304Sjkim b->peer = NULL; 152280304Sjkim /* enough for one TLS record (just a default) */ 153280304Sjkim b->size = 17 * 1024; 154280304Sjkim b->buf = NULL; 15555714Skris 156280304Sjkim bio->ptr = b; 157280304Sjkim return 1; 158280304Sjkim} 15955714Skris 16055714Skrisstatic int bio_free(BIO *bio) 161280304Sjkim{ 162280304Sjkim struct bio_bio_st *b; 16355714Skris 164280304Sjkim if (bio == NULL) 165280304Sjkim return 0; 166280304Sjkim b = bio->ptr; 16755714Skris 168280304Sjkim assert(b != NULL); 16955714Skris 170280304Sjkim if (b->peer) 171280304Sjkim bio_destroy_pair(bio); 17255714Skris 173280304Sjkim if (b->buf != NULL) { 174280304Sjkim OPENSSL_free(b->buf); 175280304Sjkim } 17655714Skris 177280304Sjkim OPENSSL_free(b); 17855714Skris 179280304Sjkim return 1; 180280304Sjkim} 18155714Skris 18255714Skrisstatic int bio_read(BIO *bio, char *buf, int size_) 183280304Sjkim{ 184280304Sjkim size_t size = size_; 185280304Sjkim size_t rest; 186280304Sjkim struct bio_bio_st *b, *peer_b; 18755714Skris 188280304Sjkim BIO_clear_retry_flags(bio); 18955714Skris 190280304Sjkim if (!bio->init) 191280304Sjkim return 0; 19255714Skris 193280304Sjkim b = bio->ptr; 194280304Sjkim assert(b != NULL); 195280304Sjkim assert(b->peer != NULL); 196280304Sjkim peer_b = b->peer->ptr; 197280304Sjkim assert(peer_b != NULL); 198280304Sjkim assert(peer_b->buf != NULL); 19955714Skris 200280304Sjkim peer_b->request = 0; /* will be set in "retry_read" situation */ 20155714Skris 202280304Sjkim if (buf == NULL || size == 0) 203280304Sjkim return 0; 20455714Skris 205280304Sjkim if (peer_b->len == 0) { 206280304Sjkim if (peer_b->closed) 207280304Sjkim return 0; /* writer has closed, and no data is left */ 208280304Sjkim else { 209280304Sjkim BIO_set_retry_read(bio); /* buffer is empty */ 210280304Sjkim if (size <= peer_b->size) 211280304Sjkim peer_b->request = size; 212280304Sjkim else 213280304Sjkim /* 214280304Sjkim * don't ask for more than the peer can deliver in one write 215280304Sjkim */ 216280304Sjkim peer_b->request = peer_b->size; 217280304Sjkim return -1; 218280304Sjkim } 219280304Sjkim } 22055714Skris 221280304Sjkim /* we can read */ 222280304Sjkim if (peer_b->len < size) 223280304Sjkim size = peer_b->len; 22455714Skris 225280304Sjkim /* now read "size" bytes */ 22655714Skris 227280304Sjkim rest = size; 228280304Sjkim 229280304Sjkim assert(rest > 0); 230280304Sjkim do { /* one or two iterations */ 231280304Sjkim size_t chunk; 232280304Sjkim 233280304Sjkim assert(rest <= peer_b->len); 234280304Sjkim if (peer_b->offset + rest <= peer_b->size) 235280304Sjkim chunk = rest; 236280304Sjkim else 237280304Sjkim /* wrap around ring buffer */ 238280304Sjkim chunk = peer_b->size - peer_b->offset; 239280304Sjkim assert(peer_b->offset + chunk <= peer_b->size); 240280304Sjkim 241280304Sjkim memcpy(buf, peer_b->buf + peer_b->offset, chunk); 242280304Sjkim 243280304Sjkim peer_b->len -= chunk; 244280304Sjkim if (peer_b->len) { 245280304Sjkim peer_b->offset += chunk; 246280304Sjkim assert(peer_b->offset <= peer_b->size); 247280304Sjkim if (peer_b->offset == peer_b->size) 248280304Sjkim peer_b->offset = 0; 249280304Sjkim buf += chunk; 250280304Sjkim } else { 251280304Sjkim /* buffer now empty, no need to advance "buf" */ 252280304Sjkim assert(chunk == rest); 253280304Sjkim peer_b->offset = 0; 254280304Sjkim } 255280304Sjkim rest -= chunk; 256280304Sjkim } 257280304Sjkim while (rest); 258280304Sjkim 259280304Sjkim return size; 260280304Sjkim} 261280304Sjkim 262280304Sjkim/*- 263280304Sjkim * non-copying interface: provide pointer to available data in buffer 26459191Skris * bio_nread0: return number of available bytes 26559191Skris * bio_nread: also advance index 26659191Skris * (example usage: bio_nread0(), read from buffer, bio_nread() 26759191Skris * or just bio_nread(), read from buffer) 26859191Skris */ 269280304Sjkim/* 270280304Sjkim * WARNING: The non-copying interface is largely untested as of yet and may 271280304Sjkim * contain bugs. 272280304Sjkim */ 273238405Sjkimstatic ossl_ssize_t bio_nread0(BIO *bio, char **buf) 274280304Sjkim{ 275280304Sjkim struct bio_bio_st *b, *peer_b; 276280304Sjkim ossl_ssize_t num; 27759191Skris 278280304Sjkim BIO_clear_retry_flags(bio); 27959191Skris 280280304Sjkim if (!bio->init) 281280304Sjkim return 0; 28259191Skris 283280304Sjkim b = bio->ptr; 284280304Sjkim assert(b != NULL); 285280304Sjkim assert(b->peer != NULL); 286280304Sjkim peer_b = b->peer->ptr; 287280304Sjkim assert(peer_b != NULL); 288280304Sjkim assert(peer_b->buf != NULL); 28959191Skris 290280304Sjkim peer_b->request = 0; 291280304Sjkim 292280304Sjkim if (peer_b->len == 0) { 293280304Sjkim char dummy; 294280304Sjkim 295280304Sjkim /* avoid code duplication -- nothing available for reading */ 296280304Sjkim return bio_read(bio, &dummy, 1); /* returns 0 or -1 */ 297280304Sjkim } 298280304Sjkim 299280304Sjkim num = peer_b->len; 300280304Sjkim if (peer_b->size < peer_b->offset + num) 301280304Sjkim /* no ring buffer wrap-around for non-copying interface */ 302280304Sjkim num = peer_b->size - peer_b->offset; 303280304Sjkim assert(num > 0); 304280304Sjkim 305280304Sjkim if (buf != NULL) 306280304Sjkim *buf = peer_b->buf + peer_b->offset; 307280304Sjkim return num; 308280304Sjkim} 309280304Sjkim 310238405Sjkimstatic ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_) 311280304Sjkim{ 312280304Sjkim struct bio_bio_st *b, *peer_b; 313280304Sjkim ossl_ssize_t num, available; 31459191Skris 315280304Sjkim if (num_ > SSIZE_MAX) 316280304Sjkim num = SSIZE_MAX; 317280304Sjkim else 318280304Sjkim num = (ossl_ssize_t) num_; 31959191Skris 320280304Sjkim available = bio_nread0(bio, buf); 321280304Sjkim if (num > available) 322280304Sjkim num = available; 323280304Sjkim if (num <= 0) 324280304Sjkim return num; 32559191Skris 326280304Sjkim b = bio->ptr; 327280304Sjkim peer_b = b->peer->ptr; 32859191Skris 329280304Sjkim peer_b->len -= num; 330280304Sjkim if (peer_b->len) { 331280304Sjkim peer_b->offset += num; 332280304Sjkim assert(peer_b->offset <= peer_b->size); 333280304Sjkim if (peer_b->offset == peer_b->size) 334280304Sjkim peer_b->offset = 0; 335280304Sjkim } else 336280304Sjkim peer_b->offset = 0; 33759191Skris 338280304Sjkim return num; 339280304Sjkim} 34059191Skris 34168651Skrisstatic int bio_write(BIO *bio, const char *buf, int num_) 342280304Sjkim{ 343280304Sjkim size_t num = num_; 344280304Sjkim size_t rest; 345280304Sjkim struct bio_bio_st *b; 34655714Skris 347280304Sjkim BIO_clear_retry_flags(bio); 34855714Skris 349280304Sjkim if (!bio->init || buf == NULL || num == 0) 350280304Sjkim return 0; 35155714Skris 352280304Sjkim b = bio->ptr; 353280304Sjkim assert(b != NULL); 354280304Sjkim assert(b->peer != NULL); 355280304Sjkim assert(b->buf != NULL); 35655714Skris 357280304Sjkim b->request = 0; 358280304Sjkim if (b->closed) { 359280304Sjkim /* we already closed */ 360280304Sjkim BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE); 361280304Sjkim return -1; 362280304Sjkim } 36355714Skris 364280304Sjkim assert(b->len <= b->size); 36555714Skris 366280304Sjkim if (b->len == b->size) { 367280304Sjkim BIO_set_retry_write(bio); /* buffer is full */ 368280304Sjkim return -1; 369280304Sjkim } 37055714Skris 371280304Sjkim /* we can write */ 372280304Sjkim if (num > b->size - b->len) 373280304Sjkim num = b->size - b->len; 37455714Skris 375280304Sjkim /* now write "num" bytes */ 37655714Skris 377280304Sjkim rest = num; 37855714Skris 379280304Sjkim assert(rest > 0); 380280304Sjkim do { /* one or two iterations */ 381280304Sjkim size_t write_offset; 382280304Sjkim size_t chunk; 38355714Skris 384280304Sjkim assert(b->len + rest <= b->size); 38555714Skris 386280304Sjkim write_offset = b->offset + b->len; 387280304Sjkim if (write_offset >= b->size) 388280304Sjkim write_offset -= b->size; 389280304Sjkim /* b->buf[write_offset] is the first byte we can write to. */ 39055714Skris 391280304Sjkim if (write_offset + rest <= b->size) 392280304Sjkim chunk = rest; 393280304Sjkim else 394280304Sjkim /* wrap around ring buffer */ 395280304Sjkim chunk = b->size - write_offset; 39655714Skris 397280304Sjkim memcpy(b->buf + write_offset, buf, chunk); 398280304Sjkim 399280304Sjkim b->len += chunk; 400280304Sjkim 401280304Sjkim assert(b->len <= b->size); 402280304Sjkim 403280304Sjkim rest -= chunk; 404280304Sjkim buf += chunk; 405280304Sjkim } 406280304Sjkim while (rest); 407280304Sjkim 408280304Sjkim return num; 409280304Sjkim} 410280304Sjkim 411280304Sjkim/*- 412280304Sjkim * non-copying interface: provide pointer to region to write to 41359191Skris * bio_nwrite0: check how much space is available 41459191Skris * bio_nwrite: also increase length 41559191Skris * (example usage: bio_nwrite0(), write to buffer, bio_nwrite() 41659191Skris * or just bio_nwrite(), write to buffer) 41759191Skris */ 418238405Sjkimstatic ossl_ssize_t bio_nwrite0(BIO *bio, char **buf) 419280304Sjkim{ 420280304Sjkim struct bio_bio_st *b; 421280304Sjkim size_t num; 422280304Sjkim size_t write_offset; 42355714Skris 424280304Sjkim BIO_clear_retry_flags(bio); 42559191Skris 426280304Sjkim if (!bio->init) 427280304Sjkim return 0; 42859191Skris 429280304Sjkim b = bio->ptr; 430280304Sjkim assert(b != NULL); 431280304Sjkim assert(b->peer != NULL); 432280304Sjkim assert(b->buf != NULL); 43359191Skris 434280304Sjkim b->request = 0; 435280304Sjkim if (b->closed) { 436280304Sjkim BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE); 437280304Sjkim return -1; 438280304Sjkim } 43959191Skris 440280304Sjkim assert(b->len <= b->size); 44159191Skris 442280304Sjkim if (b->len == b->size) { 443280304Sjkim BIO_set_retry_write(bio); 444280304Sjkim return -1; 445280304Sjkim } 44659191Skris 447280304Sjkim num = b->size - b->len; 448280304Sjkim write_offset = b->offset + b->len; 449280304Sjkim if (write_offset >= b->size) 450280304Sjkim write_offset -= b->size; 451280304Sjkim if (write_offset + num > b->size) 452280304Sjkim /* 453280304Sjkim * no ring buffer wrap-around for non-copying interface (to fulfil 454280304Sjkim * the promise by BIO_ctrl_get_write_guarantee, BIO_nwrite may have 455280304Sjkim * to be called twice) 456280304Sjkim */ 457280304Sjkim num = b->size - write_offset; 45859191Skris 459280304Sjkim if (buf != NULL) 460280304Sjkim *buf = b->buf + write_offset; 461280304Sjkim assert(write_offset + num <= b->size); 46259191Skris 463280304Sjkim return num; 464280304Sjkim} 46559191Skris 466238405Sjkimstatic ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_) 467280304Sjkim{ 468280304Sjkim struct bio_bio_st *b; 469280304Sjkim ossl_ssize_t num, space; 47059191Skris 471280304Sjkim if (num_ > SSIZE_MAX) 472280304Sjkim num = SSIZE_MAX; 473280304Sjkim else 474280304Sjkim num = (ossl_ssize_t) num_; 47559191Skris 476280304Sjkim space = bio_nwrite0(bio, buf); 477280304Sjkim if (num > space) 478280304Sjkim num = space; 479280304Sjkim if (num <= 0) 480280304Sjkim return num; 481280304Sjkim b = bio->ptr; 482280304Sjkim assert(b != NULL); 483280304Sjkim b->len += num; 484280304Sjkim assert(b->len <= b->size); 48559191Skris 486280304Sjkim return num; 487280304Sjkim} 48859191Skris 48955714Skrisstatic long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) 490280304Sjkim{ 491280304Sjkim long ret; 492280304Sjkim struct bio_bio_st *b = bio->ptr; 49355714Skris 494280304Sjkim assert(b != NULL); 49555714Skris 496280304Sjkim switch (cmd) { 497280304Sjkim /* specific CTRL codes */ 49855714Skris 499280304Sjkim case BIO_C_SET_WRITE_BUF_SIZE: 500280304Sjkim if (b->peer) { 501280304Sjkim BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE); 502280304Sjkim ret = 0; 503280304Sjkim } else if (num == 0) { 504280304Sjkim BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT); 505280304Sjkim ret = 0; 506280304Sjkim } else { 507280304Sjkim size_t new_size = num; 50855714Skris 509280304Sjkim if (b->size != new_size) { 510280304Sjkim if (b->buf) { 511280304Sjkim OPENSSL_free(b->buf); 512280304Sjkim b->buf = NULL; 513280304Sjkim } 514280304Sjkim b->size = new_size; 515280304Sjkim } 516280304Sjkim ret = 1; 517280304Sjkim } 518280304Sjkim break; 51955714Skris 520280304Sjkim case BIO_C_GET_WRITE_BUF_SIZE: 521280304Sjkim ret = (long)b->size; 522280304Sjkim break; 52355714Skris 524280304Sjkim case BIO_C_MAKE_BIO_PAIR: 525280304Sjkim { 526280304Sjkim BIO *other_bio = ptr; 52755714Skris 528280304Sjkim if (bio_make_pair(bio, other_bio)) 529280304Sjkim ret = 1; 530280304Sjkim else 531280304Sjkim ret = 0; 532280304Sjkim } 533280304Sjkim break; 53455714Skris 535280304Sjkim case BIO_C_DESTROY_BIO_PAIR: 536280304Sjkim /* 537280304Sjkim * Affects both BIOs in the pair -- call just once! Or let 538280304Sjkim * BIO_free(bio1); BIO_free(bio2); do the job. 539280304Sjkim */ 540280304Sjkim bio_destroy_pair(bio); 541280304Sjkim ret = 1; 542280304Sjkim break; 54359191Skris 544280304Sjkim case BIO_C_GET_WRITE_GUARANTEE: 545280304Sjkim /* 546280304Sjkim * How many bytes can the caller feed to the next write without 547280304Sjkim * having to keep any? 548280304Sjkim */ 549280304Sjkim if (b->peer == NULL || b->closed) 550280304Sjkim ret = 0; 551280304Sjkim else 552280304Sjkim ret = (long)b->size - b->len; 553280304Sjkim break; 55455714Skris 555280304Sjkim case BIO_C_GET_READ_REQUEST: 556280304Sjkim /* 557280304Sjkim * If the peer unsuccessfully tried to read, how many bytes were 558280304Sjkim * requested? (As with BIO_CTRL_PENDING, that number can usually be 559280304Sjkim * treated as boolean.) 560280304Sjkim */ 561280304Sjkim ret = (long)b->request; 562280304Sjkim break; 56355714Skris 564280304Sjkim case BIO_C_RESET_READ_REQUEST: 565280304Sjkim /* 566280304Sjkim * Reset request. (Can be useful after read attempts at the other 567280304Sjkim * side that are meant to be non-blocking, e.g. when probing SSL_read 568280304Sjkim * to see if any data is available.) 569280304Sjkim */ 570280304Sjkim b->request = 0; 571280304Sjkim ret = 1; 572280304Sjkim break; 57359191Skris 574280304Sjkim case BIO_C_SHUTDOWN_WR: 575280304Sjkim /* similar to shutdown(..., SHUT_WR) */ 576280304Sjkim b->closed = 1; 577280304Sjkim ret = 1; 578280304Sjkim break; 57955714Skris 580280304Sjkim case BIO_C_NREAD0: 581280304Sjkim /* prepare for non-copying read */ 582280304Sjkim ret = (long)bio_nread0(bio, ptr); 583280304Sjkim break; 58455714Skris 585280304Sjkim case BIO_C_NREAD: 586280304Sjkim /* non-copying read */ 587280304Sjkim ret = (long)bio_nread(bio, ptr, (size_t)num); 588280304Sjkim break; 58955714Skris 590280304Sjkim case BIO_C_NWRITE0: 591280304Sjkim /* prepare for non-copying write */ 592280304Sjkim ret = (long)bio_nwrite0(bio, ptr); 593280304Sjkim break; 59455714Skris 595280304Sjkim case BIO_C_NWRITE: 596280304Sjkim /* non-copying write */ 597280304Sjkim ret = (long)bio_nwrite(bio, ptr, (size_t)num); 598280304Sjkim break; 59955714Skris 600280304Sjkim /* standard CTRL codes follow */ 60155714Skris 602280304Sjkim case BIO_CTRL_RESET: 603280304Sjkim if (b->buf != NULL) { 604280304Sjkim b->len = 0; 605280304Sjkim b->offset = 0; 606280304Sjkim } 607280304Sjkim ret = 0; 608280304Sjkim break; 60955714Skris 610280304Sjkim case BIO_CTRL_GET_CLOSE: 611280304Sjkim ret = bio->shutdown; 612280304Sjkim break; 61355714Skris 614280304Sjkim case BIO_CTRL_SET_CLOSE: 615280304Sjkim bio->shutdown = (int)num; 616280304Sjkim ret = 1; 617280304Sjkim break; 61855714Skris 619280304Sjkim case BIO_CTRL_PENDING: 620280304Sjkim if (b->peer != NULL) { 621280304Sjkim struct bio_bio_st *peer_b = b->peer->ptr; 62255714Skris 623280304Sjkim ret = (long)peer_b->len; 624280304Sjkim } else 625280304Sjkim ret = 0; 626280304Sjkim break; 62755714Skris 628280304Sjkim case BIO_CTRL_WPENDING: 629280304Sjkim if (b->buf != NULL) 630280304Sjkim ret = (long)b->len; 631280304Sjkim else 632280304Sjkim ret = 0; 633280304Sjkim break; 63455714Skris 635280304Sjkim case BIO_CTRL_DUP: 636280304Sjkim /* See BIO_dup_chain for circumstances we have to expect. */ 637280304Sjkim { 638280304Sjkim BIO *other_bio = ptr; 639280304Sjkim struct bio_bio_st *other_b; 640280304Sjkim 641280304Sjkim assert(other_bio != NULL); 642280304Sjkim other_b = other_bio->ptr; 643280304Sjkim assert(other_b != NULL); 644280304Sjkim 645280304Sjkim assert(other_b->buf == NULL); /* other_bio is always fresh */ 646280304Sjkim 647280304Sjkim other_b->size = b->size; 648280304Sjkim } 649280304Sjkim 650280304Sjkim ret = 1; 651280304Sjkim break; 652280304Sjkim 653280304Sjkim case BIO_CTRL_FLUSH: 654280304Sjkim ret = 1; 655280304Sjkim break; 656280304Sjkim 657280304Sjkim case BIO_CTRL_EOF: 658280304Sjkim { 659280304Sjkim BIO *other_bio = ptr; 660280304Sjkim 661280304Sjkim if (other_bio) { 662280304Sjkim struct bio_bio_st *other_b = other_bio->ptr; 663280304Sjkim 664280304Sjkim assert(other_b != NULL); 665280304Sjkim ret = other_b->len == 0 && other_b->closed; 666280304Sjkim } else 667280304Sjkim ret = 1; 668280304Sjkim } 669280304Sjkim break; 670280304Sjkim 671280304Sjkim default: 672280304Sjkim ret = 0; 673280304Sjkim } 674280304Sjkim return ret; 675280304Sjkim} 676280304Sjkim 67768651Skrisstatic int bio_puts(BIO *bio, const char *str) 678280304Sjkim{ 679280304Sjkim return bio_write(bio, str, strlen(str)); 680280304Sjkim} 68155714Skris 68255714Skrisstatic int bio_make_pair(BIO *bio1, BIO *bio2) 683280304Sjkim{ 684280304Sjkim struct bio_bio_st *b1, *b2; 68555714Skris 686280304Sjkim assert(bio1 != NULL); 687280304Sjkim assert(bio2 != NULL); 68855714Skris 689280304Sjkim b1 = bio1->ptr; 690280304Sjkim b2 = bio2->ptr; 69155714Skris 692280304Sjkim if (b1->peer != NULL || b2->peer != NULL) { 693280304Sjkim BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE); 694280304Sjkim return 0; 695280304Sjkim } 69655714Skris 697280304Sjkim if (b1->buf == NULL) { 698280304Sjkim b1->buf = OPENSSL_malloc(b1->size); 699280304Sjkim if (b1->buf == NULL) { 700280304Sjkim BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); 701280304Sjkim return 0; 702280304Sjkim } 703280304Sjkim b1->len = 0; 704280304Sjkim b1->offset = 0; 705280304Sjkim } 70655714Skris 707280304Sjkim if (b2->buf == NULL) { 708280304Sjkim b2->buf = OPENSSL_malloc(b2->size); 709280304Sjkim if (b2->buf == NULL) { 710280304Sjkim BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); 711280304Sjkim return 0; 712280304Sjkim } 713280304Sjkim b2->len = 0; 714280304Sjkim b2->offset = 0; 715280304Sjkim } 716280304Sjkim 717280304Sjkim b1->peer = bio2; 718280304Sjkim b1->closed = 0; 719280304Sjkim b1->request = 0; 720280304Sjkim b2->peer = bio1; 721280304Sjkim b2->closed = 0; 722280304Sjkim b2->request = 0; 723280304Sjkim 724280304Sjkim bio1->init = 1; 725280304Sjkim bio2->init = 1; 726280304Sjkim 727280304Sjkim return 1; 728280304Sjkim} 729280304Sjkim 73055714Skrisstatic void bio_destroy_pair(BIO *bio) 731280304Sjkim{ 732280304Sjkim struct bio_bio_st *b = bio->ptr; 73355714Skris 734280304Sjkim if (b != NULL) { 735280304Sjkim BIO *peer_bio = b->peer; 73655714Skris 737280304Sjkim if (peer_bio != NULL) { 738280304Sjkim struct bio_bio_st *peer_b = peer_bio->ptr; 73955714Skris 740280304Sjkim assert(peer_b != NULL); 741280304Sjkim assert(peer_b->peer == bio); 74255714Skris 743280304Sjkim peer_b->peer = NULL; 744280304Sjkim peer_bio->init = 0; 745280304Sjkim assert(peer_b->buf != NULL); 746280304Sjkim peer_b->len = 0; 747280304Sjkim peer_b->offset = 0; 74855714Skris 749280304Sjkim b->peer = NULL; 750280304Sjkim bio->init = 0; 751280304Sjkim assert(b->buf != NULL); 752280304Sjkim b->len = 0; 753280304Sjkim b->offset = 0; 754280304Sjkim } 755280304Sjkim } 756280304Sjkim} 757280304Sjkim 75855714Skris/* Exported convenience functions */ 75955714Skrisint BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, 760280304Sjkim BIO **bio2_p, size_t writebuf2) 761280304Sjkim{ 762280304Sjkim BIO *bio1 = NULL, *bio2 = NULL; 763280304Sjkim long r; 764280304Sjkim int ret = 0; 76555714Skris 766280304Sjkim bio1 = BIO_new(BIO_s_bio()); 767280304Sjkim if (bio1 == NULL) 768280304Sjkim goto err; 769280304Sjkim bio2 = BIO_new(BIO_s_bio()); 770280304Sjkim if (bio2 == NULL) 771280304Sjkim goto err; 77255714Skris 773280304Sjkim if (writebuf1) { 774280304Sjkim r = BIO_set_write_buf_size(bio1, writebuf1); 775280304Sjkim if (!r) 776280304Sjkim goto err; 777280304Sjkim } 778280304Sjkim if (writebuf2) { 779280304Sjkim r = BIO_set_write_buf_size(bio2, writebuf2); 780280304Sjkim if (!r) 781280304Sjkim goto err; 782280304Sjkim } 78355714Skris 784280304Sjkim r = BIO_make_bio_pair(bio1, bio2); 785280304Sjkim if (!r) 786280304Sjkim goto err; 787280304Sjkim ret = 1; 78855714Skris 78955714Skris err: 790280304Sjkim if (ret == 0) { 791280304Sjkim if (bio1) { 792280304Sjkim BIO_free(bio1); 793280304Sjkim bio1 = NULL; 794280304Sjkim } 795280304Sjkim if (bio2) { 796280304Sjkim BIO_free(bio2); 797280304Sjkim bio2 = NULL; 798280304Sjkim } 799280304Sjkim } 80055714Skris 801280304Sjkim *bio1_p = bio1; 802280304Sjkim *bio2_p = bio2; 803280304Sjkim return ret; 804280304Sjkim} 80555714Skris 80655714Skrissize_t BIO_ctrl_get_write_guarantee(BIO *bio) 807280304Sjkim{ 808280304Sjkim return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); 809280304Sjkim} 81055714Skris 81155714Skrissize_t BIO_ctrl_get_read_request(BIO *bio) 812280304Sjkim{ 813280304Sjkim return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); 814280304Sjkim} 81559191Skris 81659191Skrisint BIO_ctrl_reset_read_request(BIO *bio) 817280304Sjkim{ 818280304Sjkim return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0); 819280304Sjkim} 82059191Skris 821280304Sjkim/* 822280304Sjkim * BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now 823280304Sjkim * (conceivably some other BIOs could allow non-copying reads and writes 824280304Sjkim * too.) 82559191Skris */ 82659191Skrisint BIO_nread0(BIO *bio, char **buf) 827280304Sjkim{ 828280304Sjkim long ret; 82959191Skris 830280304Sjkim if (!bio->init) { 831280304Sjkim BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED); 832280304Sjkim return -2; 833280304Sjkim } 83459191Skris 835280304Sjkim ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf); 836280304Sjkim if (ret > INT_MAX) 837280304Sjkim return INT_MAX; 838280304Sjkim else 839280304Sjkim return (int)ret; 840280304Sjkim} 84159191Skris 84259191Skrisint BIO_nread(BIO *bio, char **buf, int num) 843280304Sjkim{ 844280304Sjkim int ret; 84559191Skris 846280304Sjkim if (!bio->init) { 847280304Sjkim BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED); 848280304Sjkim return -2; 849280304Sjkim } 85059191Skris 851280304Sjkim ret = (int)BIO_ctrl(bio, BIO_C_NREAD, num, buf); 852280304Sjkim if (ret > 0) 853280304Sjkim bio->num_read += ret; 854280304Sjkim return ret; 855280304Sjkim} 85659191Skris 85759191Skrisint BIO_nwrite0(BIO *bio, char **buf) 858280304Sjkim{ 859280304Sjkim long ret; 86059191Skris 861280304Sjkim if (!bio->init) { 862280304Sjkim BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED); 863280304Sjkim return -2; 864280304Sjkim } 86559191Skris 866280304Sjkim ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf); 867280304Sjkim if (ret > INT_MAX) 868280304Sjkim return INT_MAX; 869280304Sjkim else 870280304Sjkim return (int)ret; 871280304Sjkim} 87259191Skris 87359191Skrisint BIO_nwrite(BIO *bio, char **buf, int num) 874280304Sjkim{ 875280304Sjkim int ret; 87659191Skris 877280304Sjkim if (!bio->init) { 878280304Sjkim BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED); 879280304Sjkim return -2; 880280304Sjkim } 88159191Skris 882280304Sjkim ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf); 883280304Sjkim if (ret > 0) 884280304Sjkim bio->num_write += ret; 885280304Sjkim return ret; 886280304Sjkim} 887