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