diff --git a/ChangeLog b/ChangeLog index 0f9ccf0b5..c7bda6bf7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ Features API Changes * net_connect() and net_bind() have a new 'proto' argument to choose between TCP and UDP, using the macros NET_PROTO_TCP or NET_PROTO_UDP. + * ssl_set_bio() now requires that p_send == p_recv. = PolarSSL 1.3.9 released 2014-10-20 Security diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index 1cfb606c9..29c8dc0d1 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -725,8 +725,7 @@ struct _ssl_context void *p_rng; /*!< context for the RNG function */ void *p_dbg; /*!< context for the debug function */ - void *p_recv; /*!< context for reading operations */ - void *p_send; /*!< context for writing operations */ + void *p_bio; /*!< context for I/O operations */ void *p_get_cache; /*!< context for cache retrieval */ void *p_set_cache; /*!< context for cache store */ void *p_hw_data; /*!< context for HW acceleration */ @@ -1069,9 +1068,13 @@ void ssl_set_dbg( ssl_context *ssl, * * \param ssl SSL context * \param f_recv read callback - * \param p_recv read parameter + * \param p_recv read parameter (must be equal to write parameter) * \param f_send write callback - * \param p_send write parameter + * \param p_send write parameter (must be equal to read parameter) + * + * \warning It is required that p_recv == p_send. Otherwise, the first + * attempt at sending or receiving will result in a + * POLARSSL_ERR_SSL_BAD_INPUT_DATA error. */ void ssl_set_bio( ssl_context *ssl, int (*f_recv)(void *, unsigned char *, size_t), void *p_recv, diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 51a0ac7f0..126fbae41 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1842,6 +1842,13 @@ int ssl_fetch_input( ssl_context *ssl, size_t nb_want ) SSL_DEBUG_MSG( 2, ( "=> fetch input" ) ); + if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL ) + { + SSL_DEBUG_MSG( 1, ( "Bad usage of ssl_set_bio() " + "or ssl_set_bio_timeout()" ) ); + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + if( nb_want > SSL_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) ) { SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) ); @@ -1907,7 +1914,7 @@ int ssl_fetch_input( ssl_context *ssl, size_t nb_want ) } len = SSL_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf ); - ret = ssl->f_recv( ssl->p_recv, ssl->in_hdr, len ); + ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len ); SSL_DEBUG_RET( 2, "ssl->f_recv", ret ); @@ -1928,7 +1935,7 @@ int ssl_fetch_input( ssl_context *ssl, size_t nb_want ) while( ssl->in_left < nb_want ) { len = nb_want - ssl->in_left; - ret = ssl->f_recv( ssl->p_recv, ssl->in_hdr + ssl->in_left, len ); + ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr + ssl->in_left, len ); SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", ssl->in_left, nb_want ) ); @@ -1959,6 +1966,13 @@ int ssl_flush_output( ssl_context *ssl ) SSL_DEBUG_MSG( 2, ( "=> flush output" ) ); + if( ssl->f_send == NULL ) + { + SSL_DEBUG_MSG( 1, ( "Bad usage of ssl_set_bio() " + "or ssl_set_bio_timeout()" ) ); + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + /* Avoid incrementing counter if data is flushed */ if( ssl->out_left == 0 ) { @@ -1973,7 +1987,7 @@ int ssl_flush_output( ssl_context *ssl ) buf = ssl->out_hdr + ssl_hdr_len( ssl ) + ssl->out_msglen - ssl->out_left; - ret = ssl->f_send( ssl->p_send, buf, ssl->out_left ); + ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left ); SSL_DEBUG_RET( 2, "ssl->f_send", ret ); @@ -4299,10 +4313,17 @@ void ssl_set_bio( ssl_context *ssl, int (*f_recv)(void *, unsigned char *, size_t), void *p_recv, int (*f_send)(void *, const unsigned char *, size_t), void *p_send ) { + if( p_recv != p_send ) + { + ssl->f_recv = NULL; + ssl->f_send = NULL; + ssl->p_bio = NULL; + return; + } + ssl->f_recv = f_recv; ssl->f_send = f_send; - ssl->p_recv = p_recv; - ssl->p_send = p_send; + ssl->p_bio = p_send; } void ssl_set_session_cache( ssl_context *ssl,