Add tests for SSL_set_fd and friends.
Their implementations expose a lot of really weird SSL_set_bio behavior. Note
that one test must be disabled as it doesn't even work. The subsequent commit
will re-enable it.
Change-Id: I4b7acadd710b3be056951886fc3e073a5aa816de
Reviewed-on: https://boringssl-review.googlesource.com/8272
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc
index ef38902..619b4b2 100644
--- a/ssl/ssl_test.cc
+++ b/ssl/ssl_test.cc
@@ -1251,6 +1251,109 @@
return true;
}
+static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
+ if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
+ fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
+ SSL_get_wfd(ssl), rfd, wfd);
+ return false;
+ }
+
+ // The wrapper BIOs are always equal when fds are equal, even if set
+ // individually.
+ if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
+ fprintf(stderr, "rbio and wbio did not match.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestSetFD() {
+ ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ if (!ctx) {
+ return false;
+ }
+
+ // Test setting different read and write FDs.
+ ScopedSSL ssl(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_rfd(ssl.get(), 1) ||
+ !SSL_set_wfd(ssl.get(), 2) ||
+ !ExpectFDs(ssl.get(), 1, 2)) {
+ return false;
+ }
+
+ // Test setting the same FD.
+ ssl.reset(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_fd(ssl.get(), 1) ||
+ !ExpectFDs(ssl.get(), 1, 1)) {
+ return false;
+ }
+
+ // Test setting the same FD one side at a time.
+ ssl.reset(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_rfd(ssl.get(), 1) ||
+ !SSL_set_wfd(ssl.get(), 1) ||
+ !ExpectFDs(ssl.get(), 1, 1)) {
+ return false;
+ }
+
+ // Test setting the same FD in the other order.
+ ssl.reset(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_wfd(ssl.get(), 1) ||
+ !SSL_set_rfd(ssl.get(), 1) ||
+ !ExpectFDs(ssl.get(), 1, 1)) {
+ return false;
+ }
+
+ // TODO(davidben): This one is broken.
+#if 0
+ // Test changing the read FD partway through.
+ ssl.reset(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_fd(ssl.get(), 1) ||
+ !SSL_set_rfd(ssl.get(), 2) ||
+ !ExpectFDs(ssl.get(), 2, 1)) {
+ return false;
+ }
+#endif
+
+ // Test changing the write FD partway through.
+ ssl.reset(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_fd(ssl.get(), 1) ||
+ !SSL_set_wfd(ssl.get(), 2) ||
+ !ExpectFDs(ssl.get(), 1, 2)) {
+ return false;
+ }
+
+ // Test a no-op change to the read FD partway through.
+ ssl.reset(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_fd(ssl.get(), 1) ||
+ !SSL_set_rfd(ssl.get(), 1) ||
+ !ExpectFDs(ssl.get(), 1, 1)) {
+ return false;
+ }
+
+ // Test a no-op change to the write FD partway through.
+ ssl.reset(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_fd(ssl.get(), 1) ||
+ !SSL_set_wfd(ssl.get(), 1) ||
+ !ExpectFDs(ssl.get(), 1, 1)) {
+ return false;
+ }
+
+ // ASan builds will implicitly test that the internal |BIO| reference-counting
+ // is correct.
+
+ return true;
+}
+
int main() {
CRYPTO_library_init();
@@ -1275,7 +1378,8 @@
!TestInternalSessionCache() ||
!TestSequenceNumber(false /* TLS */) ||
!TestSequenceNumber(true /* DTLS */) ||
- !TestOneSidedShutdown()) {
+ !TestOneSidedShutdown() ||
+ !TestSetFD()) {
ERR_print_errors_fp(stderr);
return 1;
}