1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ssl/bio_ssl.c */ 2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * All rights reserved. 4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This package is an SSL implementation written 6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * by Eric Young (eay@cryptsoft.com). 7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The implementation was written so as to conform with Netscapes SSL. 8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This library is free for commercial and non-commercial use as long as 10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the following conditions are aheared to. The following conditions 11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * apply to all code found in this distribution, be it the RC4, RSA, 12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * included with this distribution is covered by the same copyright terms 14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright remains Eric Young's, and as such any Copyright notices in 17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the code are not to be removed. 18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If this package is used in a product, Eric Young should be given attribution 19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * as the author of the parts of the library used. 20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This can be in the form of a textual message at program startup or 21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * in documentation (online or textual) provided with the package. 22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without 24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions 25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met: 26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the copyright 27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer. 28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer in the 30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * documentation and/or other materials provided with the distribution. 31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this software 32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * must display the following acknowledgement: 33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes cryptographic software written by 34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Eric Young (eay@cryptsoft.com)" 35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The word 'cryptographic' can be left out if the rouines from the library 36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * being used are not cryptographic related :-). 37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. If you include any Windows specific code (or a derivative thereof) from 38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the apps directory (application code) you must include an acknowledgement: 39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SUCH DAMAGE. 52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The licence and distribution terms for any publically available version or 54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * derivative of this code cannot be changed. i.e. this code cannot simply be 55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * copied and put under another distribution licence 56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * [including the GNU Public Licence.] 57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h> 60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdlib.h> 61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <string.h> 62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <errno.h> 63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/crypto.h> 64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/bio.h> 65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/err.h> 66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/ssl.h> 67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ssl_write(BIO *h, const char *buf, int num); 69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ssl_read(BIO *h, char *buf, int size); 70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ssl_puts(BIO *h, const char *str); 71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2); 72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ssl_new(BIO *h); 73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ssl_free(BIO *data); 74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); 75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct bio_ssl_st 76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL *ssl; /* The ssl handle :-) */ 78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* re-negotiate every time the total number of bytes is this size */ 79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int num_renegotiates; 80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned long renegotiate_count; 81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned long byte_count; 82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned long renegotiate_timeout; 83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned long last_time; 84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } BIO_SSL; 85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic BIO_METHOD methods_sslp= 87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_TYPE_SSL,"ssl", 89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ssl_write, 90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ssl_read, 91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ssl_puts, 92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NULL, /* ssl_gets, */ 93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ssl_ctrl, 94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ssl_new, 95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ssl_free, 96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ssl_callback_ctrl, 97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project }; 98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO_METHOD *BIO_f_ssl(void) 100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(&methods_sslp); 102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ssl_new(BIO *bi) 105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_SSL *bs; 107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bs=(BIO_SSL *)OPENSSL_malloc(sizeof(BIO_SSL)); 109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bs == NULL) 110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIOerr(BIO_F_SSL_NEW,ERR_R_MALLOC_FAILURE); 112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(0); 113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memset(bs,0,sizeof(BIO_SSL)); 115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bi->init=0; 116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bi->ptr=(char *)bs; 117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bi->flags=0; 118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(1); 119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ssl_free(BIO *a) 122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_SSL *bs; 124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a == NULL) return(0); 126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bs=(BIO_SSL *)a->ptr; 127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bs->ssl != NULL) SSL_shutdown(bs->ssl); 128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->shutdown) 129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->init && (bs->ssl != NULL)) 131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_free(bs->ssl); 132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->init=0; 133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->flags=0; 134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->ptr != NULL) 136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(a->ptr); 137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(1); 138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ssl_read(BIO *b, char *out, int outl) 141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret=1; 143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_SSL *sb; 144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL *ssl; 145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int retry_reason=0; 146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int r=0; 147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (out == NULL) return(0); 149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sb=(BIO_SSL *)b->ptr; 150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ssl=sb->ssl; 151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_clear_retry_flags(b); 153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0 155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!SSL_is_init_finished(ssl)) 156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ret=SSL_do_handshake(ssl); */ 158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret > 0) 159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project outflags=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY); 162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret= -1; 163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto end; 164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* if (ret > 0) */ 168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=SSL_read(ssl,out,outl); 169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (SSL_get_error(ssl,ret)) 171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_NONE: 173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret <= 0) break; 174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (sb->renegotiate_count > 0) 175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sb->byte_count+=ret; 177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (sb->byte_count > sb->renegotiate_count) 178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sb->byte_count=0; 180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sb->num_renegotiates++; 181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_renegotiate(ssl); 182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project r=1; 183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((sb->renegotiate_timeout > 0) && (!r)) 186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned long tm; 188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project tm=(unsigned long)time(NULL); 190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (tm > sb->last_time+sb->renegotiate_timeout) 191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sb->last_time=tm; 193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sb->num_renegotiates++; 194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_renegotiate(ssl); 195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_WANT_READ: 200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_retry_read(b); 201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_WANT_WRITE: 203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_retry_write(b); 204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_WANT_X509_LOOKUP: 206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_retry_special(b); 207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project retry_reason=BIO_RR_SSL_X509_LOOKUP; 208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_WANT_ACCEPT: 210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_retry_special(b); 211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project retry_reason=BIO_RR_ACCEPT; 212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_WANT_CONNECT: 214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_retry_special(b); 215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project retry_reason=BIO_RR_CONNECT; 216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_SYSCALL: 218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_SSL: 219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_ZERO_RETURN: 220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: 221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->retry_reason=retry_reason; 225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ret); 226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ssl_write(BIO *b, const char *out, int outl) 229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret,r=0; 231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int retry_reason=0; 232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL *ssl; 233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_SSL *bs; 234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (out == NULL) return(0); 236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bs=(BIO_SSL *)b->ptr; 237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ssl=bs->ssl; 238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_clear_retry_flags(b); 240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ret=SSL_do_handshake(ssl); 242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret > 0) */ 243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=SSL_write(ssl,out,outl); 244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (SSL_get_error(ssl,ret)) 246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_NONE: 248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret <= 0) break; 249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bs->renegotiate_count > 0) 250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bs->byte_count+=ret; 252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bs->byte_count > bs->renegotiate_count) 253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bs->byte_count=0; 255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bs->num_renegotiates++; 256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_renegotiate(ssl); 257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project r=1; 258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((bs->renegotiate_timeout > 0) && (!r)) 261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned long tm; 263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project tm=(unsigned long)time(NULL); 265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (tm > bs->last_time+bs->renegotiate_timeout) 266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bs->last_time=tm; 268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bs->num_renegotiates++; 269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_renegotiate(ssl); 270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_WANT_WRITE: 274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_retry_write(b); 275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_WANT_READ: 277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_retry_read(b); 278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_WANT_X509_LOOKUP: 280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_retry_special(b); 281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project retry_reason=BIO_RR_SSL_X509_LOOKUP; 282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_WANT_CONNECT: 284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_retry_special(b); 285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project retry_reason=BIO_RR_CONNECT; 286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_SYSCALL: 287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_SSL: 288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: 289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->retry_reason=retry_reason; 293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ret); 294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long ssl_ctrl(BIO *b, int cmd, long num, void *ptr) 297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL **sslp,*ssl; 299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_SSL *bs; 300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *dbio,*bio; 301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project long ret=1; 302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bs=(BIO_SSL *)b->ptr; 304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ssl=bs->ssl; 305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ssl == NULL) && (cmd != BIO_C_SET_SSL)) 306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(0); 307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (cmd) 308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_RESET: 310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_shutdown(ssl); 311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ssl->handshake_func == ssl->method->ssl_connect) 313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_set_connect_state(ssl); 314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else if (ssl->handshake_func == ssl->method->ssl_accept) 315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_set_accept_state(ssl); 316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_clear(ssl); 318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->next_bio != NULL) 320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=BIO_ctrl(b->next_bio,cmd,num,ptr); 321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else if (ssl->rbio != NULL) 322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=BIO_ctrl(ssl->rbio,cmd,num,ptr); 323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=1; 325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_INFO: 327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=0; 328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_SSL_MODE: 330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (num) /* client mode */ 331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_set_connect_state(ssl); 332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_set_accept_state(ssl); 334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT: 336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=bs->renegotiate_timeout; 337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (num < 60) num=5; 338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bs->renegotiate_timeout=(unsigned long)num; 339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bs->last_time=(unsigned long)time(NULL); 340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_SET_SSL_RENEGOTIATE_BYTES: 342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=bs->renegotiate_count; 343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((long)num >=512) 344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bs->renegotiate_count=(unsigned long)num; 345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_GET_SSL_NUM_RENEGOTIATES: 347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=bs->num_renegotiates; 348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_SET_SSL: 350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ssl != NULL) 351ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom { 352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ssl_free(b); 353ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom if (!ssl_new(b)) 354ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom return 0; 355ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom } 356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->shutdown=(int)num; 357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ssl=(SSL *)ptr; 358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ((BIO_SSL *)b->ptr)->ssl=ssl; 359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bio=SSL_get_rbio(ssl); 360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bio != NULL) 361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->next_bio != NULL) 363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_push(bio,b->next_bio); 364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->next_bio=bio; 365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO); 366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->init=1; 368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_GET_SSL: 370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ptr != NULL) 371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sslp=(SSL **)ptr; 373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *sslp=ssl; 374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=0; 377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_GET_CLOSE: 379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=b->shutdown; 380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_SET_CLOSE: 382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->shutdown=(int)num; 383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_WPENDING: 385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=BIO_ctrl(ssl->wbio,cmd,num,ptr); 386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_PENDING: 388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=SSL_pending(ssl); 389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret == 0) 390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=BIO_pending(ssl->rbio); 391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_FLUSH: 393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_clear_retry_flags(b); 394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=BIO_ctrl(ssl->wbio,cmd,num,ptr); 395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_copy_next_retry(b); 396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_PUSH: 398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio)) 399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_set_bio(ssl,b->next_bio,b->next_bio); 401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project CRYPTO_add(&b->next_bio->references,1,CRYPTO_LOCK_BIO); 402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_POP: 405221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* Only detach if we are the BIO explicitly being popped */ 406221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (b == ptr) 407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 408221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* Shouldn't happen in practice because the 409221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * rbio and wbio are the same when pushed. 410221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */ 411221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (ssl->rbio != ssl->wbio) 412221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom BIO_free_all(ssl->wbio); 413221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (b->next_bio != NULL) 414221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom CRYPTO_add(&b->next_bio->references,-1,CRYPTO_LOCK_BIO); 415221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ssl->wbio=NULL; 416221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ssl->rbio=NULL; 417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_DO_STATE_MACHINE: 420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_clear_retry_flags(b); 421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->retry_reason=0; 423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=(int)SSL_do_handshake(ssl); 424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (SSL_get_error(ssl,(int)ret)) 426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_WANT_READ: 428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_flags(b, 429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY); 430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_WANT_WRITE: 432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_flags(b, 433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY); 434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case SSL_ERROR_WANT_CONNECT: 436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_flags(b, 437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY); 438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->retry_reason=b->next_bio->retry_reason; 439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: 441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_DUP: 445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project dbio=(BIO *)ptr; 446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (((BIO_SSL *)dbio->ptr)->ssl != NULL) 447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_free(((BIO_SSL *)dbio->ptr)->ssl); 448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ((BIO_SSL *)dbio->ptr)->ssl=SSL_dup(ssl); 449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ((BIO_SSL *)dbio->ptr)->renegotiate_count= 450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ((BIO_SSL *)b->ptr)->renegotiate_count; 451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ((BIO_SSL *)dbio->ptr)->byte_count= 452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ((BIO_SSL *)b->ptr)->byte_count; 453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ((BIO_SSL *)dbio->ptr)->renegotiate_timeout= 454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ((BIO_SSL *)b->ptr)->renegotiate_timeout; 455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ((BIO_SSL *)dbio->ptr)->last_time= 456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ((BIO_SSL *)b->ptr)->last_time; 457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=(((BIO_SSL *)dbio->ptr)->ssl != NULL); 458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_C_GET_FD: 460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=BIO_ctrl(ssl->rbio,cmd,num,ptr); 461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_SET_CALLBACK: 463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0 /* FIXME: Should this be used? -- Richard Levitte */ 465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSLerr(SSL_F_SSL_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = -1; 467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else 468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=0; 469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_GET_CALLBACK: 473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project void (**fptr)(const SSL *xssl,int type,int val); 475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project fptr=(void (**)(const SSL *xssl,int type,int val))ptr; 477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *fptr=SSL_get_info_callback(ssl); 478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: 481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=BIO_ctrl(ssl->rbio,cmd,num,ptr); 482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ret); 485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) 488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL *ssl; 490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_SSL *bs; 491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project long ret=1; 492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bs=(BIO_SSL *)b->ptr; 494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ssl=bs->ssl; 495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (cmd) 496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case BIO_CTRL_SET_CALLBACK: 498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* FIXME: setting this via a completely different prototype 500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project seems like a crap idea */ 501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_set_info_callback(ssl,(void (*)(const SSL *,int,int))fp); 502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: 505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=BIO_callback_ctrl(ssl->rbio,cmd,fp); 506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ret); 509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ssl_puts(BIO *bp, const char *str) 512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int n,ret; 514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project n=strlen(str); 516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=BIO_write(bp,str,n); 517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ret); 518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx) 521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_SOCK 523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *ret=NULL,*buf=NULL,*ssl=NULL; 524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((buf=BIO_new(BIO_f_buffer())) == NULL) 526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(NULL); 527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ssl=BIO_new_ssl_connect(ctx)) == NULL) 528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ret=BIO_push(buf,ssl)) == NULL) 530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ret); 532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr: 533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (buf != NULL) BIO_free(buf); 534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ssl != NULL) BIO_free(ssl); 535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(NULL); 537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO *BIO_new_ssl_connect(SSL_CTX *ctx) 540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 541a1a5710c055e139ea00e785f9eb55b3af3e4dab1Brian Carlstrom#ifndef OPENSSL_NO_SOCK 542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *ret=NULL,*con=NULL,*ssl=NULL; 543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((con=BIO_new(BIO_s_connect())) == NULL) 545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(NULL); 546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ssl=BIO_new_ssl(ctx,1)) == NULL) 547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ret=BIO_push(ssl,con)) == NULL) 549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ret); 551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr: 552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (con != NULL) BIO_free(con); 553a1a5710c055e139ea00e785f9eb55b3af3e4dab1Brian Carlstrom#endif 554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(NULL); 555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO *BIO_new_ssl(SSL_CTX *ctx, int client) 558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO *ret; 560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL *ssl; 561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ret=BIO_new(BIO_f_ssl())) == NULL) 563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(NULL); 564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ssl=SSL_new(ctx)) == NULL) 565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_free(ret); 567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(NULL); 568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (client) 570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_set_connect_state(ssl); 571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_set_accept_state(ssl); 573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIO_set_ssl(ret,ssl,BIO_CLOSE); 575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ret); 576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BIO_ssl_copy_session_id(BIO *t, BIO *f) 579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project t=BIO_find_type(t,BIO_TYPE_SSL); 581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project f=BIO_find_type(f,BIO_TYPE_SSL); 582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((t == NULL) || (f == NULL)) 583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(0); 584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ( (((BIO_SSL *)t->ptr)->ssl == NULL) || 585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (((BIO_SSL *)f->ptr)->ssl == NULL)) 586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(0); 587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl,((BIO_SSL *)f->ptr)->ssl); 588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(1); 589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid BIO_ssl_shutdown(BIO *b) 592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL *s; 594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 595656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project while (b != NULL) 596656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 597656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->method->type == BIO_TYPE_SSL) 598656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 599656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project s=((BIO_SSL *)b->ptr)->ssl; 600656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project SSL_shutdown(s); 601656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b=b->next_bio; 604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 606