Align with OpenSSL on SSL_set_bio behavior. SSL_set_bio is a nightmare. In f715c423224a292d79ba0e3df373c828fbae29f7, we noticed that, among other problems, SSL_set_bio's actual behavior did not match how SSL_set_rfd was calling it due to an asymmetry in the rbio/wbio handling. This resulted in SSL_set_fd/SSL_set_rfd calls to crash. We decided that SSL_set_rfd's believed semantics were definitive and changed SSL_set_bio. Upstream, in 65e2d672548e7c4bcb28f1c5c835362830b1745b, decided that SSL_set_bio's behavior, asymmetry and all, was definitive and that the SSL_set_rfd crash was a bug in SSL_set_rfd. Accordingly, they switched the fd callers to use the side-specific setters, new in 1.1.0. Align with upstream's behavior and add tests for all of SSL_set_bio's insanity. Also export the new side-specific setters in anticipation of wanting to be mostly compatible with OpenSSL 1.1.0. Change-Id: Iceac9508711f79750a3cc2ded081b2bb2cbf54d8 Reviewed-on: https://boringssl-review.googlesource.com/9064 Reviewed-by: Adam Langley <agl@google.com> Commit-Queue: Adam Langley <agl@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 6fd5b3b..8a1eb4c 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h
@@ -240,12 +240,33 @@ * In DTLS, if |rbio| is blocking, it must handle * |BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT| control requests to set read timeouts. * - * If |rbio| (respectively, |wbio|) is the same as the currently configured - * |BIO| for reading (respectively, writing), that side is left untouched and is - * not freed. Using this behavior and calling this function if |ssl| already has - * |BIO|s configured is deprecated. */ + * If |rbio| is the same as the currently configured |BIO| for reading, that + * side is left untouched and is not freed. + * + * If |wbio| is the same as the currently configured |BIO| for writing AND |ssl| + * is not currently configured to read from and write to the same |BIO|, that + * side is left untouched and is not freed. This asymmetry is present for + * historical reasons. + * + * Due to the very complex historical behavior of this function, calling this + * function if |ssl| already has |BIO|s configured is deprecated. Prefer + * |SSL_set0_rbio| and |SSL_set0_wbio| instead. */ OPENSSL_EXPORT void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); +/* SSL_set0_rbio configures |ssl| to write to |rbio|. It takes ownership of + * |rbio|. + * + * Note that, although this function and |SSL_set0_wbio| may be called on the + * same |BIO|, each call takes a reference. Use |BIO_up_ref| to balance this. */ +OPENSSL_EXPORT void SSL_set0_rbio(SSL *ssl, BIO *rbio); + +/* SSL_set0_wbio configures |ssl| to write to |wbio|. It takes ownership of + * |wbio|. + * + * Note that, although this function and |SSL_set0_rbio| may be called on the + * same |BIO|, each call takes a reference. Use |BIO_up_ref| to balance this. */ +OPENSSL_EXPORT void SSL_set0_wbio(SSL *ssl, BIO *wbio); + /* SSL_get_rbio returns the |BIO| that |ssl| reads from. */ OPENSSL_EXPORT BIO *SSL_get_rbio(const SSL *ssl);