1e0c4386eSCy Schubert /* 2*44096ebdSEnji Cooper * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. 3e0c4386eSCy Schubert * 4e0c4386eSCy Schubert * Licensed under the Apache License 2.0 (the "License"); 5e0c4386eSCy Schubert * you may not use this file except in compliance with the License. 6e0c4386eSCy Schubert * You may obtain a copy of the License at 7e0c4386eSCy Schubert * https://www.openssl.org/source/license.html 8e0c4386eSCy Schubert * or in the file LICENSE in the source distribution. 9e0c4386eSCy Schubert */ 10e0c4386eSCy Schubert 11*44096ebdSEnji Cooper /* 12*44096ebdSEnji Cooper * We need access to the deprecated low level Engine APIs for legacy purposes 13*44096ebdSEnji Cooper * when the deprecated calls are not hidden 14*44096ebdSEnji Cooper */ 15*44096ebdSEnji Cooper #ifndef OPENSSL_NO_DEPRECATED_3_0 16*44096ebdSEnji Cooper # define OPENSSL_SUPPRESS_DEPRECATED 17*44096ebdSEnji Cooper #endif 18*44096ebdSEnji Cooper 19e0c4386eSCy Schubert #include <string.h> 20e0c4386eSCy Schubert #include <openssl/ssl.h> 21e0c4386eSCy Schubert #include <openssl/bio.h> 22e0c4386eSCy Schubert #include <openssl/err.h> 23*44096ebdSEnji Cooper #include <openssl/engine.h> 24e0c4386eSCy Schubert 25e0c4386eSCy Schubert #include "internal/packet.h" 26e0c4386eSCy Schubert 27e0c4386eSCy Schubert #include "helpers/ssltestlib.h" 28e0c4386eSCy Schubert #include "testutil.h" 29e0c4386eSCy Schubert 30e0c4386eSCy Schubert struct async_ctrs { 31e0c4386eSCy Schubert unsigned int rctr; 32e0c4386eSCy Schubert unsigned int wctr; 33e0c4386eSCy Schubert }; 34e0c4386eSCy Schubert 35e0c4386eSCy Schubert static SSL_CTX *serverctx = NULL; 36e0c4386eSCy Schubert static SSL_CTX *clientctx = NULL; 37e0c4386eSCy Schubert 38e0c4386eSCy Schubert #define MAX_ATTEMPTS 100 39e0c4386eSCy Schubert 40e0c4386eSCy Schubert 41e0c4386eSCy Schubert /* 42e0c4386eSCy Schubert * There are 9 passes in the tests 43e0c4386eSCy Schubert * 0 = control test 44e0c4386eSCy Schubert * tests during writes 45e0c4386eSCy Schubert * 1 = free buffers 46e0c4386eSCy Schubert * 2 = + allocate buffers after free 47e0c4386eSCy Schubert * 3 = + allocate buffers again 48e0c4386eSCy Schubert * 4 = + free buffers after allocation 49e0c4386eSCy Schubert * tests during reads 50e0c4386eSCy Schubert * 5 = + free buffers 51e0c4386eSCy Schubert * 6 = + free buffers again 52e0c4386eSCy Schubert * 7 = + allocate buffers after free 53e0c4386eSCy Schubert * 8 = + free buffers after allocation 54e0c4386eSCy Schubert */ 55e0c4386eSCy Schubert static int test_func(int test) 56e0c4386eSCy Schubert { 57e0c4386eSCy Schubert int result = 0; 58e0c4386eSCy Schubert SSL *serverssl = NULL, *clientssl = NULL; 59e0c4386eSCy Schubert int ret; 60e0c4386eSCy Schubert size_t i, j; 61e0c4386eSCy Schubert const char testdata[] = "Test data"; 62e0c4386eSCy Schubert char buf[sizeof(testdata)]; 63e0c4386eSCy Schubert 64e0c4386eSCy Schubert if (!TEST_true(create_ssl_objects(serverctx, clientctx, &serverssl, &clientssl, 65e0c4386eSCy Schubert NULL, NULL))) { 66e0c4386eSCy Schubert TEST_error("Test %d failed: Create SSL objects failed\n", test); 67e0c4386eSCy Schubert goto end; 68e0c4386eSCy Schubert } 69e0c4386eSCy Schubert 70e0c4386eSCy Schubert if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) { 71e0c4386eSCy Schubert TEST_error("Test %d failed: Create SSL connection failed\n", test); 72e0c4386eSCy Schubert goto end; 73e0c4386eSCy Schubert } 74e0c4386eSCy Schubert 75e0c4386eSCy Schubert /* 76e0c4386eSCy Schubert * Send and receive some test data. Do the whole thing twice to ensure 77e0c4386eSCy Schubert * we hit at least one async event in both reading and writing 78e0c4386eSCy Schubert */ 79e0c4386eSCy Schubert for (j = 0; j < 2; j++) { 80e0c4386eSCy Schubert int len; 81e0c4386eSCy Schubert 82e0c4386eSCy Schubert /* 83e0c4386eSCy Schubert 84e0c4386eSCy Schubert * Write some test data. It should never take more than 2 attempts 85e0c4386eSCy Schubert * (the first one might be a retryable fail). 86e0c4386eSCy Schubert */ 87e0c4386eSCy Schubert for (ret = -1, i = 0, len = 0; len != sizeof(testdata) && i < 2; 88e0c4386eSCy Schubert i++) { 89e0c4386eSCy Schubert /* test == 0 mean to free/allocate = control */ 90e0c4386eSCy Schubert if (test >= 1 && !TEST_true(SSL_free_buffers(clientssl))) 91e0c4386eSCy Schubert goto end; 92e0c4386eSCy Schubert if (test >= 2 && !TEST_true(SSL_alloc_buffers(clientssl))) 93e0c4386eSCy Schubert goto end; 94e0c4386eSCy Schubert /* allocate a second time */ 95e0c4386eSCy Schubert if (test >= 3 && !TEST_true(SSL_alloc_buffers(clientssl))) 96e0c4386eSCy Schubert goto end; 97e0c4386eSCy Schubert if (test >= 4 && !TEST_true(SSL_free_buffers(clientssl))) 98e0c4386eSCy Schubert goto end; 99e0c4386eSCy Schubert 100e0c4386eSCy Schubert ret = SSL_write(clientssl, testdata + len, 101e0c4386eSCy Schubert sizeof(testdata) - len); 102e0c4386eSCy Schubert if (ret > 0) { 103e0c4386eSCy Schubert len += ret; 104e0c4386eSCy Schubert } else { 105e0c4386eSCy Schubert int ssl_error = SSL_get_error(clientssl, ret); 106e0c4386eSCy Schubert 107e0c4386eSCy Schubert if (ssl_error == SSL_ERROR_SYSCALL || 108e0c4386eSCy Schubert ssl_error == SSL_ERROR_SSL) { 109e0c4386eSCy Schubert TEST_error("Test %d failed: Failed to write app data\n", test); 110e0c4386eSCy Schubert goto end; 111e0c4386eSCy Schubert } 112e0c4386eSCy Schubert } 113e0c4386eSCy Schubert } 114e0c4386eSCy Schubert if (!TEST_size_t_eq(len, sizeof(testdata))) 115e0c4386eSCy Schubert goto end; 116e0c4386eSCy Schubert /* 117e0c4386eSCy Schubert * Now read the test data. It may take more attempts here because 118e0c4386eSCy Schubert * it could fail once for each byte read, including all overhead 119e0c4386eSCy Schubert * bytes from the record header/padding etc. 120e0c4386eSCy Schubert */ 121e0c4386eSCy Schubert for (ret = -1, i = 0, len = 0; len != sizeof(testdata) && 122e0c4386eSCy Schubert i < MAX_ATTEMPTS; i++) 123e0c4386eSCy Schubert { 124e0c4386eSCy Schubert if (test >= 5 && !TEST_true(SSL_free_buffers(serverssl))) 125e0c4386eSCy Schubert goto end; 126e0c4386eSCy Schubert /* free a second time */ 127e0c4386eSCy Schubert if (test >= 6 && !TEST_true(SSL_free_buffers(serverssl))) 128e0c4386eSCy Schubert goto end; 129e0c4386eSCy Schubert if (test >= 7 && !TEST_true(SSL_alloc_buffers(serverssl))) 130e0c4386eSCy Schubert goto end; 131e0c4386eSCy Schubert if (test >= 8 && !TEST_true(SSL_free_buffers(serverssl))) 132e0c4386eSCy Schubert goto end; 133e0c4386eSCy Schubert 134e0c4386eSCy Schubert ret = SSL_read(serverssl, buf + len, sizeof(buf) - len); 135e0c4386eSCy Schubert if (ret > 0) { 136e0c4386eSCy Schubert len += ret; 137e0c4386eSCy Schubert } else { 138e0c4386eSCy Schubert int ssl_error = SSL_get_error(serverssl, ret); 139e0c4386eSCy Schubert 140e0c4386eSCy Schubert if (ssl_error == SSL_ERROR_SYSCALL || 141e0c4386eSCy Schubert ssl_error == SSL_ERROR_SSL) { 142e0c4386eSCy Schubert TEST_error("Test %d failed: Failed to read app data\n", test); 143e0c4386eSCy Schubert goto end; 144e0c4386eSCy Schubert } 145e0c4386eSCy Schubert } 146e0c4386eSCy Schubert } 147e0c4386eSCy Schubert if (!TEST_mem_eq(buf, len, testdata, sizeof(testdata))) 148e0c4386eSCy Schubert goto end; 149e0c4386eSCy Schubert } 150e0c4386eSCy Schubert 151e0c4386eSCy Schubert result = 1; 152e0c4386eSCy Schubert end: 153e0c4386eSCy Schubert if (!result) 154e0c4386eSCy Schubert ERR_print_errors_fp(stderr); 155e0c4386eSCy Schubert 156e0c4386eSCy Schubert SSL_free(clientssl); 157e0c4386eSCy Schubert SSL_free(serverssl); 158e0c4386eSCy Schubert 159e0c4386eSCy Schubert return result; 160e0c4386eSCy Schubert } 161e0c4386eSCy Schubert 162*44096ebdSEnji Cooper /* 163*44096ebdSEnji Cooper * Test that attempting to free the buffers at points where they cannot be freed 164*44096ebdSEnji Cooper * works as expected 165*44096ebdSEnji Cooper * Test 0: Attempt to free buffers after a full record has been processed, but 166*44096ebdSEnji Cooper * the application has only performed a partial read 167*44096ebdSEnji Cooper * Test 1: Attempt to free buffers after only a partial record header has been 168*44096ebdSEnji Cooper * received 169*44096ebdSEnji Cooper * Test 2: Attempt to free buffers after a full record header but no record body 170*44096ebdSEnji Cooper * Test 3: Attempt to free buffers after a full record hedaer and partial record 171*44096ebdSEnji Cooper * body 172*44096ebdSEnji Cooper * Test 4-7: We repeat tests 0-3 but including data from a second pipelined 173*44096ebdSEnji Cooper * record 174*44096ebdSEnji Cooper */ 175*44096ebdSEnji Cooper static int test_free_buffers(int test) 176*44096ebdSEnji Cooper { 177*44096ebdSEnji Cooper int result = 0; 178*44096ebdSEnji Cooper SSL *serverssl = NULL, *clientssl = NULL; 179*44096ebdSEnji Cooper const char testdata[] = "Test data"; 180*44096ebdSEnji Cooper char buf[120]; 181*44096ebdSEnji Cooper size_t written, readbytes; 182*44096ebdSEnji Cooper int i, pipeline = test > 3; 183*44096ebdSEnji Cooper ENGINE *e = NULL; 184*44096ebdSEnji Cooper 185*44096ebdSEnji Cooper if (pipeline) { 186*44096ebdSEnji Cooper e = load_dasync(); 187*44096ebdSEnji Cooper if (e == NULL) 188*44096ebdSEnji Cooper goto end; 189*44096ebdSEnji Cooper test -= 4; 190*44096ebdSEnji Cooper } 191*44096ebdSEnji Cooper 192*44096ebdSEnji Cooper if (!TEST_true(create_ssl_objects(serverctx, clientctx, &serverssl, 193*44096ebdSEnji Cooper &clientssl, NULL, NULL))) 194*44096ebdSEnji Cooper goto end; 195*44096ebdSEnji Cooper 196*44096ebdSEnji Cooper if (pipeline) { 197*44096ebdSEnji Cooper if (!TEST_true(SSL_set_cipher_list(serverssl, "AES128-SHA")) 198*44096ebdSEnji Cooper || !TEST_true(SSL_set_max_proto_version(serverssl, 199*44096ebdSEnji Cooper TLS1_2_VERSION)) 200*44096ebdSEnji Cooper || !TEST_true(SSL_set_max_pipelines(serverssl, 2))) 201*44096ebdSEnji Cooper goto end; 202*44096ebdSEnji Cooper } 203*44096ebdSEnji Cooper 204*44096ebdSEnji Cooper if (!TEST_true(create_ssl_connection(serverssl, clientssl, 205*44096ebdSEnji Cooper SSL_ERROR_NONE))) 206*44096ebdSEnji Cooper goto end; 207*44096ebdSEnji Cooper 208*44096ebdSEnji Cooper /* 209*44096ebdSEnji Cooper * For the non-pipeline case we write one record. For pipelining we write 210*44096ebdSEnji Cooper * two records. 211*44096ebdSEnji Cooper */ 212*44096ebdSEnji Cooper for (i = 0; i <= pipeline; i++) { 213*44096ebdSEnji Cooper if (!TEST_true(SSL_write_ex(clientssl, testdata, strlen(testdata), 214*44096ebdSEnji Cooper &written))) 215*44096ebdSEnji Cooper goto end; 216*44096ebdSEnji Cooper } 217*44096ebdSEnji Cooper 218*44096ebdSEnji Cooper if (test == 0) { 219*44096ebdSEnji Cooper size_t readlen = 1; 220*44096ebdSEnji Cooper 221*44096ebdSEnji Cooper /* 222*44096ebdSEnji Cooper * Deliberately only read the first byte - so the remaining bytes are 223*44096ebdSEnji Cooper * still buffered. In the pipelining case we read as far as the first 224*44096ebdSEnji Cooper * byte from the second record. 225*44096ebdSEnji Cooper */ 226*44096ebdSEnji Cooper if (pipeline) 227*44096ebdSEnji Cooper readlen += strlen(testdata); 228*44096ebdSEnji Cooper 229*44096ebdSEnji Cooper if (!TEST_true(SSL_read_ex(serverssl, buf, readlen, &readbytes)) 230*44096ebdSEnji Cooper || !TEST_size_t_eq(readlen, readbytes)) 231*44096ebdSEnji Cooper goto end; 232*44096ebdSEnji Cooper } else { 233*44096ebdSEnji Cooper BIO *tmp; 234*44096ebdSEnji Cooper size_t partial_len; 235*44096ebdSEnji Cooper 236*44096ebdSEnji Cooper /* Remove all the data that is pending for read by the server */ 237*44096ebdSEnji Cooper tmp = SSL_get_rbio(serverssl); 238*44096ebdSEnji Cooper if (!TEST_true(BIO_read_ex(tmp, buf, sizeof(buf), &readbytes)) 239*44096ebdSEnji Cooper || !TEST_size_t_lt(readbytes, sizeof(buf)) 240*44096ebdSEnji Cooper || !TEST_size_t_gt(readbytes, SSL3_RT_HEADER_LENGTH)) 241*44096ebdSEnji Cooper goto end; 242*44096ebdSEnji Cooper 243*44096ebdSEnji Cooper switch(test) { 244*44096ebdSEnji Cooper case 1: 245*44096ebdSEnji Cooper partial_len = SSL3_RT_HEADER_LENGTH - 1; 246*44096ebdSEnji Cooper break; 247*44096ebdSEnji Cooper case 2: 248*44096ebdSEnji Cooper partial_len = SSL3_RT_HEADER_LENGTH; 249*44096ebdSEnji Cooper break; 250*44096ebdSEnji Cooper case 3: 251*44096ebdSEnji Cooper partial_len = readbytes - 1; 252*44096ebdSEnji Cooper break; 253*44096ebdSEnji Cooper default: 254*44096ebdSEnji Cooper TEST_error("Invalid test index"); 255*44096ebdSEnji Cooper goto end; 256*44096ebdSEnji Cooper } 257*44096ebdSEnji Cooper 258*44096ebdSEnji Cooper if (pipeline) { 259*44096ebdSEnji Cooper /* We happen to know the first record is 57 bytes long */ 260*44096ebdSEnji Cooper const size_t first_rec_len = 57; 261*44096ebdSEnji Cooper 262*44096ebdSEnji Cooper if (test != 3) 263*44096ebdSEnji Cooper partial_len += first_rec_len; 264*44096ebdSEnji Cooper 265*44096ebdSEnji Cooper /* 266*44096ebdSEnji Cooper * Sanity check. If we got the record len right then this should 267*44096ebdSEnji Cooper * never fail. 268*44096ebdSEnji Cooper */ 269*44096ebdSEnji Cooper if (!TEST_int_eq(buf[first_rec_len], SSL3_RT_APPLICATION_DATA)) 270*44096ebdSEnji Cooper goto end; 271*44096ebdSEnji Cooper } 272*44096ebdSEnji Cooper 273*44096ebdSEnji Cooper /* 274*44096ebdSEnji Cooper * Put back just the partial record (plus the whole initial record in 275*44096ebdSEnji Cooper * the pipelining case) 276*44096ebdSEnji Cooper */ 277*44096ebdSEnji Cooper if (!TEST_true(BIO_write_ex(tmp, buf, partial_len, &written))) 278*44096ebdSEnji Cooper goto end; 279*44096ebdSEnji Cooper 280*44096ebdSEnji Cooper if (pipeline) { 281*44096ebdSEnji Cooper /* 282*44096ebdSEnji Cooper * Attempt a read. This should pass but only return data from the 283*44096ebdSEnji Cooper * first record. Only a partial record is available for the second 284*44096ebdSEnji Cooper * record. 285*44096ebdSEnji Cooper */ 286*44096ebdSEnji Cooper if (!TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf), 287*44096ebdSEnji Cooper &readbytes)) 288*44096ebdSEnji Cooper || !TEST_size_t_eq(readbytes, strlen(testdata))) 289*44096ebdSEnji Cooper goto end; 290*44096ebdSEnji Cooper } else { 291*44096ebdSEnji Cooper /* 292*44096ebdSEnji Cooper * Attempt a read. This should fail because only a partial record is 293*44096ebdSEnji Cooper * available. 294*44096ebdSEnji Cooper */ 295*44096ebdSEnji Cooper if (!TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf), 296*44096ebdSEnji Cooper &readbytes))) 297*44096ebdSEnji Cooper goto end; 298*44096ebdSEnji Cooper } 299*44096ebdSEnji Cooper } 300*44096ebdSEnji Cooper 301*44096ebdSEnji Cooper /* 302*44096ebdSEnji Cooper * Attempting to free the buffers at this point should fail because they are 303*44096ebdSEnji Cooper * still in use 304*44096ebdSEnji Cooper */ 305*44096ebdSEnji Cooper if (!TEST_false(SSL_free_buffers(serverssl))) 306*44096ebdSEnji Cooper goto end; 307*44096ebdSEnji Cooper 308*44096ebdSEnji Cooper result = 1; 309*44096ebdSEnji Cooper end: 310*44096ebdSEnji Cooper SSL_free(clientssl); 311*44096ebdSEnji Cooper SSL_free(serverssl); 312*44096ebdSEnji Cooper #ifndef OPENSSL_NO_DYNAMIC_ENGINE 313*44096ebdSEnji Cooper if (e != NULL) { 314*44096ebdSEnji Cooper ENGINE_unregister_ciphers(e); 315*44096ebdSEnji Cooper ENGINE_finish(e); 316*44096ebdSEnji Cooper ENGINE_free(e); 317*44096ebdSEnji Cooper } 318*44096ebdSEnji Cooper #endif 319*44096ebdSEnji Cooper return result; 320*44096ebdSEnji Cooper } 321*44096ebdSEnji Cooper 322e0c4386eSCy Schubert OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n") 323e0c4386eSCy Schubert 324e0c4386eSCy Schubert int setup_tests(void) 325e0c4386eSCy Schubert { 326e0c4386eSCy Schubert char *cert, *pkey; 327e0c4386eSCy Schubert 328e0c4386eSCy Schubert if (!test_skip_common_options()) { 329e0c4386eSCy Schubert TEST_error("Error parsing test options\n"); 330e0c4386eSCy Schubert return 0; 331e0c4386eSCy Schubert } 332e0c4386eSCy Schubert 333e0c4386eSCy Schubert if (!TEST_ptr(cert = test_get_argument(0)) 334e0c4386eSCy Schubert || !TEST_ptr(pkey = test_get_argument(1))) 335e0c4386eSCy Schubert return 0; 336e0c4386eSCy Schubert 337e0c4386eSCy Schubert if (!create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), 338e0c4386eSCy Schubert TLS1_VERSION, 0, 339e0c4386eSCy Schubert &serverctx, &clientctx, cert, pkey)) { 340e0c4386eSCy Schubert TEST_error("Failed to create SSL_CTX pair\n"); 341e0c4386eSCy Schubert return 0; 342e0c4386eSCy Schubert } 343e0c4386eSCy Schubert 344e0c4386eSCy Schubert ADD_ALL_TESTS(test_func, 9); 345*44096ebdSEnji Cooper #if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE) 346*44096ebdSEnji Cooper ADD_ALL_TESTS(test_free_buffers, 8); 347*44096ebdSEnji Cooper #else 348*44096ebdSEnji Cooper ADD_ALL_TESTS(test_free_buffers, 4); 349*44096ebdSEnji Cooper #endif 350e0c4386eSCy Schubert return 1; 351e0c4386eSCy Schubert } 352e0c4386eSCy Schubert 353e0c4386eSCy Schubert void cleanup_tests(void) 354e0c4386eSCy Schubert { 355e0c4386eSCy Schubert SSL_CTX_free(clientctx); 356e0c4386eSCy Schubert SSL_CTX_free(serverctx); 357e0c4386eSCy Schubert } 358