xref: /third_party/openssl/test/sslbuffertest.c (revision e1051a39)
1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License");
5e1051a39Sopenharmony_ci * you may not use this file except in compliance with the License.
6e1051a39Sopenharmony_ci * You may obtain a copy of the License at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci * or in the file LICENSE in the source distribution.
9e1051a39Sopenharmony_ci */
10e1051a39Sopenharmony_ci
11e1051a39Sopenharmony_ci#include <string.h>
12e1051a39Sopenharmony_ci#include <openssl/ssl.h>
13e1051a39Sopenharmony_ci#include <openssl/bio.h>
14e1051a39Sopenharmony_ci#include <openssl/err.h>
15e1051a39Sopenharmony_ci
16e1051a39Sopenharmony_ci#include "internal/packet.h"
17e1051a39Sopenharmony_ci
18e1051a39Sopenharmony_ci#include "helpers/ssltestlib.h"
19e1051a39Sopenharmony_ci#include "testutil.h"
20e1051a39Sopenharmony_ci
21e1051a39Sopenharmony_cistruct async_ctrs {
22e1051a39Sopenharmony_ci    unsigned int rctr;
23e1051a39Sopenharmony_ci    unsigned int wctr;
24e1051a39Sopenharmony_ci};
25e1051a39Sopenharmony_ci
26e1051a39Sopenharmony_cistatic SSL_CTX *serverctx = NULL;
27e1051a39Sopenharmony_cistatic SSL_CTX *clientctx = NULL;
28e1051a39Sopenharmony_ci
29e1051a39Sopenharmony_ci#define MAX_ATTEMPTS    100
30e1051a39Sopenharmony_ci
31e1051a39Sopenharmony_ci
32e1051a39Sopenharmony_ci/*
33e1051a39Sopenharmony_ci * There are 9 passes in the tests
34e1051a39Sopenharmony_ci * 0 = control test
35e1051a39Sopenharmony_ci * tests during writes
36e1051a39Sopenharmony_ci * 1 = free buffers
37e1051a39Sopenharmony_ci * 2 = + allocate buffers after free
38e1051a39Sopenharmony_ci * 3 = + allocate buffers again
39e1051a39Sopenharmony_ci * 4 = + free buffers after allocation
40e1051a39Sopenharmony_ci * tests during reads
41e1051a39Sopenharmony_ci * 5 = + free buffers
42e1051a39Sopenharmony_ci * 6 = + free buffers again
43e1051a39Sopenharmony_ci * 7 = + allocate buffers after free
44e1051a39Sopenharmony_ci * 8 = + free buffers after allocation
45e1051a39Sopenharmony_ci */
46e1051a39Sopenharmony_cistatic int test_func(int test)
47e1051a39Sopenharmony_ci{
48e1051a39Sopenharmony_ci    int result = 0;
49e1051a39Sopenharmony_ci    SSL *serverssl = NULL, *clientssl = NULL;
50e1051a39Sopenharmony_ci    int ret;
51e1051a39Sopenharmony_ci    size_t i, j;
52e1051a39Sopenharmony_ci    const char testdata[] = "Test data";
53e1051a39Sopenharmony_ci    char buf[sizeof(testdata)];
54e1051a39Sopenharmony_ci
55e1051a39Sopenharmony_ci    if (!TEST_true(create_ssl_objects(serverctx, clientctx, &serverssl, &clientssl,
56e1051a39Sopenharmony_ci                                      NULL, NULL))) {
57e1051a39Sopenharmony_ci        TEST_error("Test %d failed: Create SSL objects failed\n", test);
58e1051a39Sopenharmony_ci        goto end;
59e1051a39Sopenharmony_ci    }
60e1051a39Sopenharmony_ci
61e1051a39Sopenharmony_ci    if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) {
62e1051a39Sopenharmony_ci        TEST_error("Test %d failed: Create SSL connection failed\n", test);
63e1051a39Sopenharmony_ci        goto end;
64e1051a39Sopenharmony_ci    }
65e1051a39Sopenharmony_ci
66e1051a39Sopenharmony_ci    /*
67e1051a39Sopenharmony_ci     * Send and receive some test data. Do the whole thing twice to ensure
68e1051a39Sopenharmony_ci     * we hit at least one async event in both reading and writing
69e1051a39Sopenharmony_ci     */
70e1051a39Sopenharmony_ci    for (j = 0; j < 2; j++) {
71e1051a39Sopenharmony_ci        int len;
72e1051a39Sopenharmony_ci
73e1051a39Sopenharmony_ci        /*
74e1051a39Sopenharmony_ci
75e1051a39Sopenharmony_ci         * Write some test data. It should never take more than 2 attempts
76e1051a39Sopenharmony_ci         * (the first one might be a retryable fail).
77e1051a39Sopenharmony_ci         */
78e1051a39Sopenharmony_ci        for (ret = -1, i = 0, len = 0; len != sizeof(testdata) && i < 2;
79e1051a39Sopenharmony_ci             i++) {
80e1051a39Sopenharmony_ci            /* test == 0 mean to free/allocate = control */
81e1051a39Sopenharmony_ci            if (test >= 1 && !TEST_true(SSL_free_buffers(clientssl)))
82e1051a39Sopenharmony_ci                goto end;
83e1051a39Sopenharmony_ci            if (test >= 2 && !TEST_true(SSL_alloc_buffers(clientssl)))
84e1051a39Sopenharmony_ci                goto end;
85e1051a39Sopenharmony_ci            /* allocate a second time */
86e1051a39Sopenharmony_ci            if (test >= 3 && !TEST_true(SSL_alloc_buffers(clientssl)))
87e1051a39Sopenharmony_ci                goto end;
88e1051a39Sopenharmony_ci            if (test >= 4 && !TEST_true(SSL_free_buffers(clientssl)))
89e1051a39Sopenharmony_ci                goto end;
90e1051a39Sopenharmony_ci
91e1051a39Sopenharmony_ci            ret = SSL_write(clientssl, testdata + len,
92e1051a39Sopenharmony_ci                            sizeof(testdata) - len);
93e1051a39Sopenharmony_ci            if (ret > 0) {
94e1051a39Sopenharmony_ci                len += ret;
95e1051a39Sopenharmony_ci            } else {
96e1051a39Sopenharmony_ci                int ssl_error = SSL_get_error(clientssl, ret);
97e1051a39Sopenharmony_ci
98e1051a39Sopenharmony_ci                if (ssl_error == SSL_ERROR_SYSCALL ||
99e1051a39Sopenharmony_ci                    ssl_error == SSL_ERROR_SSL) {
100e1051a39Sopenharmony_ci                    TEST_error("Test %d failed: Failed to write app data\n", test);
101e1051a39Sopenharmony_ci                    goto end;
102e1051a39Sopenharmony_ci                }
103e1051a39Sopenharmony_ci            }
104e1051a39Sopenharmony_ci        }
105e1051a39Sopenharmony_ci        if (!TEST_size_t_eq(len, sizeof(testdata)))
106e1051a39Sopenharmony_ci            goto end;
107e1051a39Sopenharmony_ci        /*
108e1051a39Sopenharmony_ci         * Now read the test data. It may take more attempts here because
109e1051a39Sopenharmony_ci         * it could fail once for each byte read, including all overhead
110e1051a39Sopenharmony_ci         * bytes from the record header/padding etc.
111e1051a39Sopenharmony_ci         */
112e1051a39Sopenharmony_ci        for (ret = -1, i = 0, len = 0; len != sizeof(testdata) &&
113e1051a39Sopenharmony_ci                 i < MAX_ATTEMPTS; i++)
114e1051a39Sopenharmony_ci        {
115e1051a39Sopenharmony_ci            if (test >= 5 && !TEST_true(SSL_free_buffers(serverssl)))
116e1051a39Sopenharmony_ci                goto end;
117e1051a39Sopenharmony_ci            /* free a second time */
118e1051a39Sopenharmony_ci            if (test >= 6 && !TEST_true(SSL_free_buffers(serverssl)))
119e1051a39Sopenharmony_ci                goto end;
120e1051a39Sopenharmony_ci            if (test >= 7 && !TEST_true(SSL_alloc_buffers(serverssl)))
121e1051a39Sopenharmony_ci                goto end;
122e1051a39Sopenharmony_ci            if (test >= 8 && !TEST_true(SSL_free_buffers(serverssl)))
123e1051a39Sopenharmony_ci                goto end;
124e1051a39Sopenharmony_ci
125e1051a39Sopenharmony_ci            ret = SSL_read(serverssl, buf + len, sizeof(buf) - len);
126e1051a39Sopenharmony_ci            if (ret > 0) {
127e1051a39Sopenharmony_ci                len += ret;
128e1051a39Sopenharmony_ci            } else {
129e1051a39Sopenharmony_ci                int ssl_error = SSL_get_error(serverssl, ret);
130e1051a39Sopenharmony_ci
131e1051a39Sopenharmony_ci                if (ssl_error == SSL_ERROR_SYSCALL ||
132e1051a39Sopenharmony_ci                    ssl_error == SSL_ERROR_SSL) {
133e1051a39Sopenharmony_ci                    TEST_error("Test %d failed: Failed to read app data\n", test);
134e1051a39Sopenharmony_ci                    goto end;
135e1051a39Sopenharmony_ci                }
136e1051a39Sopenharmony_ci            }
137e1051a39Sopenharmony_ci        }
138e1051a39Sopenharmony_ci        if (!TEST_mem_eq(buf, len, testdata, sizeof(testdata)))
139e1051a39Sopenharmony_ci            goto end;
140e1051a39Sopenharmony_ci    }
141e1051a39Sopenharmony_ci
142e1051a39Sopenharmony_ci    result = 1;
143e1051a39Sopenharmony_ci end:
144e1051a39Sopenharmony_ci    if (!result)
145e1051a39Sopenharmony_ci        ERR_print_errors_fp(stderr);
146e1051a39Sopenharmony_ci
147e1051a39Sopenharmony_ci    SSL_free(clientssl);
148e1051a39Sopenharmony_ci    SSL_free(serverssl);
149e1051a39Sopenharmony_ci
150e1051a39Sopenharmony_ci    return result;
151e1051a39Sopenharmony_ci}
152e1051a39Sopenharmony_ci
153e1051a39Sopenharmony_ciOPT_TEST_DECLARE_USAGE("certfile privkeyfile\n")
154e1051a39Sopenharmony_ci
155e1051a39Sopenharmony_ciint setup_tests(void)
156e1051a39Sopenharmony_ci{
157e1051a39Sopenharmony_ci    char *cert, *pkey;
158e1051a39Sopenharmony_ci
159e1051a39Sopenharmony_ci    if (!test_skip_common_options()) {
160e1051a39Sopenharmony_ci        TEST_error("Error parsing test options\n");
161e1051a39Sopenharmony_ci        return 0;
162e1051a39Sopenharmony_ci    }
163e1051a39Sopenharmony_ci
164e1051a39Sopenharmony_ci    if (!TEST_ptr(cert = test_get_argument(0))
165e1051a39Sopenharmony_ci            || !TEST_ptr(pkey = test_get_argument(1)))
166e1051a39Sopenharmony_ci        return 0;
167e1051a39Sopenharmony_ci
168e1051a39Sopenharmony_ci    if (!create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(),
169e1051a39Sopenharmony_ci                             TLS1_VERSION, 0,
170e1051a39Sopenharmony_ci                             &serverctx, &clientctx, cert, pkey)) {
171e1051a39Sopenharmony_ci        TEST_error("Failed to create SSL_CTX pair\n");
172e1051a39Sopenharmony_ci        return 0;
173e1051a39Sopenharmony_ci    }
174e1051a39Sopenharmony_ci
175e1051a39Sopenharmony_ci    ADD_ALL_TESTS(test_func, 9);
176e1051a39Sopenharmony_ci    return 1;
177e1051a39Sopenharmony_ci}
178e1051a39Sopenharmony_ci
179e1051a39Sopenharmony_civoid cleanup_tests(void)
180e1051a39Sopenharmony_ci{
181e1051a39Sopenharmony_ci    SSL_CTX_free(clientctx);
182e1051a39Sopenharmony_ci    SSL_CTX_free(serverctx);
183e1051a39Sopenharmony_ci}
184