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