1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/bio/bss_bio.c -*- Mode: C; c-file-style: "eay" -*- */ 2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ==================================================================== 3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without 6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions 7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met: 8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright 10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer. 11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer in 14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the documentation and/or other materials provided with the 15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * distribution. 16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this 18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * software must display the following acknowledgment: 19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * endorse or promote products derived from this software without 24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * prior written permission. For written permission, please contact 25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * openssl-core@openssl.org. 26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL" 28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * nor may "OpenSSL" appear in their names without prior written 29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * permission of the OpenSSL Project. 30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following 32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * acknowledgment: 33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE. 48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ==================================================================== 49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young 51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com). This product includes software written by Tim 52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com). 53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Special method for a BIO where the other endpoint is also a BIO 57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * of this kind, handled by the same thread (i.e. the "peer" is actually 58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ourselves, wearing a different hat). 59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces 60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for which no specific BIO method is available. 61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * See ssl/ssltest.c for some hints on how this can be used. */ 62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* BIO_DEBUG implies BIO_PAIR_DEBUG */ 64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef BIO_DEBUG 65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# ifndef BIO_PAIR_DEBUG 66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# define BIO_PAIR_DEBUG 67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# endif 68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* disable assert() unless BIO_PAIR_DEBUG has been defined */ 71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef BIO_PAIR_DEBUG 72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# ifndef NDEBUG 73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# define NDEBUG 74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# endif 75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <assert.h> 78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <limits.h> 79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdlib.h> 80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <string.h> 81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/bio.h> 83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/err.h> 84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/crypto.h> 85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "e_os.h" 87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* VxWorks defines SSIZE_MAX with an empty value causing compile errors */ 89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if defined(OPENSSL_SYS_VXWORKS) 90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# undef SSIZE_MAX 91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef SSIZE_MAX 93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# define SSIZE_MAX INT_MAX 94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_new(BIO *bio); 97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_free(BIO *bio); 98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_read(BIO *bio, char *buf, int size); 99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_write(BIO *bio, const char *buf, int num); 100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long bio_ctrl(BIO *bio, int cmd, long num, void *ptr); 101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_puts(BIO *bio, const char *str); 102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_make_pair(BIO *bio1, BIO *bio2); 104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void bio_destroy_pair(BIO *bio); 105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic BIO_METHOD methods_biop = 107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_TYPE_BIO, 109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project "BIO pair", 110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio_write, 111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio_read, 112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio_puts, 113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NULL /* no bio_gets */, 114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio_ctrl, 115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio_new, 116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio_free, 117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NULL /* no bio_callback_ctrl */ 118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}; 119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO_METHOD *BIO_s_bio(void) 121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return &methods_biop; 123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstruct bio_bio_st 126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *peer; /* NULL if buf == NULL. 128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If peer != NULL, then peer->ptr is also a bio_bio_st, 129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * and its "peer" member points back to us. 130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * peer != NULL iff init != 0 in the BIO. */ 131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* This is for what we write (i.e. reading uses peer's struct): */ 133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int closed; /* valid iff peer != NULL */ 134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t len; /* valid iff buf != NULL; 0 if peer == NULL */ 135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t offset; /* valid iff buf != NULL; 0 if len == 0 */ 136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t size; 137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project char *buf; /* "size" elements (if != NULL) */ 138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t request; /* valid iff peer != NULL; 0 if len != 0, 140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * otherwise set by peer to number of bytes 141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * it (unsuccessfully) tried to read, 142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * never more than buffer space (size-len) warrants. */ 143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}; 144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_new(BIO *bio) 146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *b; 148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b = OPENSSL_malloc(sizeof *b); 150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b == NULL) 151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->peer = NULL; 154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->size = 17*1024; /* enough for one TLS record (just a default) */ 155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->buf = NULL; 156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio->ptr = b; 158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_free(BIO *bio) 163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *b; 165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bio == NULL) 167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b = bio->ptr; 169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b != NULL); 171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->peer) 173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio_destroy_pair(bio); 174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->buf != NULL) 176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(b->buf); 178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(b); 181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_read(BIO *bio, char *buf, int size_) 188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t size = size_; 190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t rest; 191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *b, *peer_b; 192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_clear_retry_flags(bio); 194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!bio->init) 196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b = bio->ptr; 199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b != NULL); 200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b->peer != NULL); 201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b = b->peer->ptr; 202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(peer_b != NULL); 203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(peer_b->buf != NULL); 204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->request = 0; /* will be set in "retry_read" situation */ 206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (buf == NULL || size == 0) 208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (peer_b->len == 0) 211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (peer_b->closed) 213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; /* writer has closed, and no data is left */ 214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_retry_read(bio); /* buffer is empty */ 217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (size <= peer_b->size) 218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->request = size; 219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* don't ask for more than the peer can 221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * deliver in one write */ 222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->request = peer_b->size; 223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; 224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* we can read */ 228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (peer_b->len < size) 229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size = peer_b->len; 230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* now read "size" bytes */ 232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project rest = size; 234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(rest > 0); 236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project do /* one or two iterations */ 237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t chunk; 239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(rest <= peer_b->len); 241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (peer_b->offset + rest <= peer_b->size) 242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project chunk = rest; 243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* wrap around ring buffer */ 245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project chunk = peer_b->size - peer_b->offset; 246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(peer_b->offset + chunk <= peer_b->size); 247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memcpy(buf, peer_b->buf + peer_b->offset, chunk); 249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->len -= chunk; 251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (peer_b->len) 252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->offset += chunk; 254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(peer_b->offset <= peer_b->size); 255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (peer_b->offset == peer_b->size) 256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->offset = 0; 257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project buf += chunk; 258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* buffer now empty, no need to advance "buf" */ 262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(chunk == rest); 263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->offset = 0; 264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project rest -= chunk; 266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project while (rest); 268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return size; 270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* non-copying interface: provide pointer to available data in buffer 273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * bio_nread0: return number of available bytes 274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * bio_nread: also advance index 275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (example usage: bio_nread0(), read from buffer, bio_nread() 276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * or just bio_nread(), read from buffer) 277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* WARNING: The non-copying interface is largely untested as of yet 279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * and may contain bugs. */ 280392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic ossl_ssize_t bio_nread0(BIO *bio, char **buf) 281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *b, *peer_b; 283392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ossl_ssize_t num; 284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_clear_retry_flags(bio); 286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!bio->init) 288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b = bio->ptr; 291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b != NULL); 292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b->peer != NULL); 293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b = b->peer->ptr; 294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(peer_b != NULL); 295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(peer_b->buf != NULL); 296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->request = 0; 298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (peer_b->len == 0) 300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project char dummy; 302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* avoid code duplication -- nothing available for reading */ 304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return bio_read(bio, &dummy, 1); /* returns 0 or -1 */ 305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project num = peer_b->len; 308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (peer_b->size < peer_b->offset + num) 309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* no ring buffer wrap-around for non-copying interface */ 310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project num = peer_b->size - peer_b->offset; 311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(num > 0); 312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (buf != NULL) 314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *buf = peer_b->buf + peer_b->offset; 315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return num; 316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 318392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_) 319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *b, *peer_b; 321392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ossl_ssize_t num, available; 322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (num_ > SSIZE_MAX) 324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project num = SSIZE_MAX; 325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 326392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom num = (ossl_ssize_t)num_; 327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project available = bio_nread0(bio, buf); 329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (num > available) 330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project num = available; 331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (num <= 0) 332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return num; 333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b = bio->ptr; 335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b = b->peer->ptr; 336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->len -= num; 338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (peer_b->len) 339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->offset += num; 341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(peer_b->offset <= peer_b->size); 342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (peer_b->offset == peer_b->size) 343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->offset = 0; 344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->offset = 0; 347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return num; 349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_write(BIO *bio, const char *buf, int num_) 353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t num = num_; 355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t rest; 356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *b; 357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_clear_retry_flags(bio); 359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!bio->init || buf == NULL || num == 0) 361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b = bio->ptr; 364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b != NULL); 365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b->peer != NULL); 366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b->buf != NULL); 367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->request = 0; 369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->closed) 370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* we already closed */ 372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE); 373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; 374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b->len <= b->size); 377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->len == b->size) 379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_retry_write(bio); /* buffer is full */ 381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; 382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* we can write */ 385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (num > b->size - b->len) 386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project num = b->size - b->len; 387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* now write "num" bytes */ 389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project rest = num; 391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(rest > 0); 393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project do /* one or two iterations */ 394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t write_offset; 396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t chunk; 397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b->len + rest <= b->size); 399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project write_offset = b->offset + b->len; 401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (write_offset >= b->size) 402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project write_offset -= b->size; 403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* b->buf[write_offset] is the first byte we can write to. */ 404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (write_offset + rest <= b->size) 406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project chunk = rest; 407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* wrap around ring buffer */ 409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project chunk = b->size - write_offset; 410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memcpy(b->buf + write_offset, buf, chunk); 412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->len += chunk; 414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b->len <= b->size); 416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project rest -= chunk; 418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project buf += chunk; 419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project while (rest); 421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return num; 423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* non-copying interface: provide pointer to region to write to 426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * bio_nwrite0: check how much space is available 427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * bio_nwrite: also increase length 428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (example usage: bio_nwrite0(), write to buffer, bio_nwrite() 429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * or just bio_nwrite(), write to buffer) 430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 431392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic ossl_ssize_t bio_nwrite0(BIO *bio, char **buf) 432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *b; 434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t num; 435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t write_offset; 436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_clear_retry_flags(bio); 438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!bio->init) 440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b = bio->ptr; 443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b != NULL); 444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b->peer != NULL); 445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b->buf != NULL); 446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->request = 0; 448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->closed) 449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE); 451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; 452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b->len <= b->size); 455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->len == b->size) 457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_retry_write(bio); 459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; 460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project num = b->size - b->len; 463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project write_offset = b->offset + b->len; 464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (write_offset >= b->size) 465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project write_offset -= b->size; 466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (write_offset + num > b->size) 467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* no ring buffer wrap-around for non-copying interface 468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (to fulfil the promise by BIO_ctrl_get_write_guarantee, 469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * BIO_nwrite may have to be called twice) */ 470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project num = b->size - write_offset; 471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (buf != NULL) 473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *buf = b->buf + write_offset; 474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(write_offset + num <= b->size); 475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return num; 477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 479392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_) 480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *b; 482392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ossl_ssize_t num, space; 483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (num_ > SSIZE_MAX) 485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project num = SSIZE_MAX; 486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 487392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom num = (ossl_ssize_t)num_; 488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project space = bio_nwrite0(bio, buf); 490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (num > space) 491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project num = space; 492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (num <= 0) 493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return num; 494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b = bio->ptr; 495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b != NULL); 496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->len += num; 497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b->len <= b->size); 498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return num; 500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) 504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project long ret; 506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *b = bio->ptr; 507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b != NULL); 509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (cmd) 511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* specific CTRL codes */ 513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_SET_WRITE_BUF_SIZE: 515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->peer) 516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE); 518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 0; 519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else if (num == 0) 521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT); 523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 0; 524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t new_size = num; 528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->size != new_size) 530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->buf) 532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(b->buf); 534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->buf = NULL; 535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->size = new_size; 537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_GET_WRITE_BUF_SIZE: 543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = (long) b->size; 544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_MAKE_BIO_PAIR: 547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *other_bio = ptr; 549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bio_make_pair(bio, other_bio)) 551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 0; 554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_DESTROY_BIO_PAIR: 558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Affects both BIOs in the pair -- call just once! 559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Or let BIO_free(bio1); BIO_free(bio2); do the job. */ 560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio_destroy_pair(bio); 561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_GET_WRITE_GUARANTEE: 565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* How many bytes can the caller feed to the next write 566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * without having to keep any? */ 567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->peer == NULL || b->closed) 568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 0; 569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = (long) b->size - b->len; 571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_GET_READ_REQUEST: 574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* If the peer unsuccessfully tried to read, how many bytes 575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * were requested? (As with BIO_CTRL_PENDING, that number 576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * can usually be treated as boolean.) */ 577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = (long) b->request; 578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_RESET_READ_REQUEST: 581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Reset request. (Can be useful after read attempts 582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * at the other side that are meant to be non-blocking, 583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * e.g. when probing SSL_read to see if any data is 584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * available.) */ 585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->request = 0; 586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_SHUTDOWN_WR: 590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* similar to shutdown(..., SHUT_WR) */ 591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->closed = 1; 592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 595656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_NREAD0: 596656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* prepare for non-copying read */ 597656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = (long) bio_nread0(bio, ptr); 598656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 599656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 600656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_NREAD: 601656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* non-copying read */ 602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = (long) bio_nread(bio, ptr, (size_t) num); 603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_NWRITE0: 606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* prepare for non-copying write */ 607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = (long) bio_nwrite0(bio, ptr); 608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_NWRITE: 611656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* non-copying write */ 612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = (long) bio_nwrite(bio, ptr, (size_t) num); 613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* standard CTRL codes follow */ 617656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_RESET: 619656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->buf != NULL) 620656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 621656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->len = 0; 622656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->offset = 0; 623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 0; 625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_GET_CLOSE: 628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = bio->shutdown; 629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_SET_CLOSE: 632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio->shutdown = (int) num; 633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_PENDING: 637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->peer != NULL) 638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *peer_b = b->peer->ptr; 640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = (long) peer_b->len; 642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 644656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 0; 645656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 646656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 647656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_WPENDING: 648656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->buf != NULL) 649656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = (long) b->len; 650656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 651656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 0; 652656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 653656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 654656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_DUP: 655656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* See BIO_dup_chain for circumstances we have to expect. */ 656656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 657656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *other_bio = ptr; 658656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *other_b; 659656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 660656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(other_bio != NULL); 661656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project other_b = other_bio->ptr; 662656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(other_b != NULL); 663656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 664656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(other_b->buf == NULL); /* other_bio is always fresh */ 665656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 666656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project other_b->size = b->size; 667656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 668656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 669656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 670656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 671656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 672656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_FLUSH: 673656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 674656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 675656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 676656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_EOF: 677656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *other_bio = ptr; 679656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 680656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (other_bio) 681656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 682656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *other_b = other_bio->ptr; 683656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 684656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(other_b != NULL); 685656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = other_b->len == 0 && other_b->closed; 686656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 687656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 688656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 689656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 690656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 691656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 692656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: 693656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 0; 694656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 695656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 696656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 697656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 698656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_puts(BIO *bio, const char *str) 699656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 700656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return bio_write(bio, str, strlen(str)); 701656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 702656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 703656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 704656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_make_pair(BIO *bio1, BIO *bio2) 705656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *b1, *b2; 707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(bio1 != NULL); 709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(bio2 != NULL); 710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 711656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b1 = bio1->ptr; 712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b2 = bio2->ptr; 713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b1->peer != NULL || b2->peer != NULL) 715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE); 717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 718656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 719656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b1->buf == NULL) 721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b1->buf = OPENSSL_malloc(b1->size); 723656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b1->buf == NULL) 724656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 725656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); 726656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 727656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 728656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b1->len = 0; 729656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b1->offset = 0; 730656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 731656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 732656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b2->buf == NULL) 733656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 734656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b2->buf = OPENSSL_malloc(b2->size); 735656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b2->buf == NULL) 736656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 737656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); 738656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 739656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 740656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b2->len = 0; 741656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b2->offset = 0; 742656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 743656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 744656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b1->peer = bio2; 745656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b1->closed = 0; 746656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b1->request = 0; 747656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b2->peer = bio1; 748656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b2->closed = 0; 749656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b2->request = 0; 750656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 751656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio1->init = 1; 752656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio2->init = 1; 753656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 754656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 755656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 756656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 757656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void bio_destroy_pair(BIO *bio) 758656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 759656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *b = bio->ptr; 760656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 761656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b != NULL) 762656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 763656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *peer_bio = b->peer; 764656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 765656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (peer_bio != NULL) 766656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 767656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct bio_bio_st *peer_b = peer_bio->ptr; 768656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 769656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(peer_b != NULL); 770656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(peer_b->peer == bio); 771656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 772656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->peer = NULL; 773656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_bio->init = 0; 774656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(peer_b->buf != NULL); 775656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->len = 0; 776656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project peer_b->offset = 0; 777656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 778656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->peer = NULL; 779656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio->init = 0; 780656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(b->buf != NULL); 781656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->len = 0; 782656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->offset = 0; 783656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 784656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 785656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 786656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 787656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 788656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Exported convenience functions */ 789656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, 790656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO **bio2_p, size_t writebuf2) 791656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 792656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *bio1 = NULL, *bio2 = NULL; 793656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project long r; 794656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret = 0; 795656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 796656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio1 = BIO_new(BIO_s_bio()); 797656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bio1 == NULL) 798656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 799656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio2 = BIO_new(BIO_s_bio()); 800656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bio2 == NULL) 801656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 802656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 803656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (writebuf1) 804656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 805656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project r = BIO_set_write_buf_size(bio1, writebuf1); 806656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!r) 807656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 808656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 809656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (writebuf2) 810656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 811656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project r = BIO_set_write_buf_size(bio2, writebuf2); 812656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!r) 813656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 814656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 815656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 816656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project r = BIO_make_bio_pair(bio1, bio2); 817656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!r) 818656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 819656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 820656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 821656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 822656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret == 0) 823656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 824656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bio1) 825656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 826656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_free(bio1); 827656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio1 = NULL; 828656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 829656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bio2) 830656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 831656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_free(bio2); 832656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio2 = NULL; 833656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 834656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 835656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 836656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *bio1_p = bio1; 837656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *bio2_p = bio2; 838656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 839656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 840656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 841656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectsize_t BIO_ctrl_get_write_guarantee(BIO *bio) 842656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 843656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); 844656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 845656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 846656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectsize_t BIO_ctrl_get_read_request(BIO *bio) 847656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 848656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); 849656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 850656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 851656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BIO_ctrl_reset_read_request(BIO *bio) 852656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 853656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0); 854656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 855656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 856656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 857656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now 858656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (conceivably some other BIOs could allow non-copying reads and writes too.) 859656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 860656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BIO_nread0(BIO *bio, char **buf) 861656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 862656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project long ret; 863656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 864656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!bio->init) 865656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 866656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED); 867656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -2; 868656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 869656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 870656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf); 871656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret > INT_MAX) 872656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return INT_MAX; 873656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 874656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return (int) ret; 875656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 876656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 877656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BIO_nread(BIO *bio, char **buf, int num) 878656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 879656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret; 880656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 881656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!bio->init) 882656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 883656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED); 884656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -2; 885656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 886656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 887656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf); 888656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret > 0) 889656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio->num_read += ret; 890656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 891656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 892656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 893656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BIO_nwrite0(BIO *bio, char **buf) 894656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 895656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project long ret; 896656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 897656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!bio->init) 898656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 899656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED); 900656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -2; 901656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 902656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 903656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf); 904656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret > INT_MAX) 905656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return INT_MAX; 906656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 907656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return (int) ret; 908656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 909656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 910656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BIO_nwrite(BIO *bio, char **buf, int num) 911656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 912656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret; 913656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 914656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!bio->init) 915656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 916656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED); 917656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -2; 918656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 919656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 920656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf); 921656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret > 0) 922e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu bio->num_write += ret; 923656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 924656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 925