From a34ac5b8b9c1a3281b4ee545c46177f485fb4949 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Thu, 27 Oct 2016 13:46:57 +0100 Subject: [PATCH] Add a test for BIO_read() returning 0 in SSL_read() (and also for write) A BIO_read() 0 return indicates that a failure occurred that may be retryable. An SSL_read() 0 return indicates a non-retryable failure. Check that if BIO_read() returns 0, SSL_read() returns <0. Same for SSL_write(). The asyncio test filter BIO already returns 0 on a retryable failure so we build on that. Reviewed-by: Richard Levitte --- test/asynciotest.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/test/asynciotest.c b/test/asynciotest.c index 720cc7c662..23d0907dc9 100644 --- a/test/asynciotest.c +++ b/test/asynciotest.c @@ -234,12 +234,17 @@ static int async_puts(BIO *bio, const char *str) return async_write(bio, str, strlen(str)); } +#define MAX_ATTEMPTS 100 + int main(int argc, char *argv[]) { SSL_CTX *serverctx = NULL, *clientctx = NULL; SSL *serverssl = NULL, *clientssl = NULL; BIO *s_to_c_fbio = NULL, *c_to_s_fbio = NULL; - int test, err = 1; + int test, err = 1, ret; + size_t i, j; + const char testdata[] = "Test data"; + char buf[sizeof(testdata)]; CRYPTO_set_mem_debug(1); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); @@ -287,6 +292,42 @@ int main(int argc, char *argv[]) goto end; } + /* + * Send and receive some test data. Do the whole thing twice to ensure + * we hit at least one async event in both reading and writing + */ + for (j = 0; j < 2; j++) { + /* + * Write some test data. It should never take more than 2 attempts + * (the first one might be a retryable fail). A zero return from + * SSL_write() is a non-retryable failure, so fail immediately if + * we get that. + */ + for (ret = -1, i = 0; ret < 0 && i < 2 * sizeof(testdata); i++) + ret = SSL_write(clientssl, testdata, sizeof(testdata)); + if (ret <= 0) { + printf("Test %d failed: Failed to write app data\n", test); + goto end; + } + /* + * Now read the test data. It may take more attemps here because + * it could fail once for each byte read, including all overhead + * bytes from the record header/padding etc. Fail immediately if we + * get a zero return from SSL_read(). + */ + for (ret = -1, i = 0; ret < 0 && i < MAX_ATTEMPTS; i++) + ret = SSL_read(serverssl, buf, sizeof(buf)); + if (ret <= 0) { + printf("Test %d failed: Failed to read app data\n", test); + goto end; + } + if (ret != sizeof(testdata) + || memcmp(buf, testdata, sizeof(testdata)) != 0) { + printf("Test %d failed: Unexpected app data received\n", test); + goto end; + } + } + /* Also frees the BIOs */ SSL_free(clientssl); SSL_free(serverssl); -- 2.34.1