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))
114 || !TEST_true(checkbuffers(clientssl, 0))))
115 goto end;
116 if (test >= 2 && (!TEST_true(SSL_alloc_buffers(clientssl))
117 || !TEST_true(checkbuffers(clientssl, 1))))
118 goto end;
119 /* allocate a second time */
120 if (test >= 3 && (!TEST_true(SSL_alloc_buffers(clientssl))
121 || !TEST_true(checkbuffers(clientssl, 1))))
122 goto end;
123 if (test >= 4 && (!TEST_true(SSL_free_buffers(clientssl))
124 || !TEST_true(checkbuffers(clientssl, 0))))
125 goto end;
126
127 ret = SSL_write(clientssl, testdata + len,
128 sizeof(testdata) - len);
129 if (ret > 0) {
130 len += ret;
131 } else {
132 int ssl_error = SSL_get_error(clientssl, ret);
133
134 if (ssl_error == SSL_ERROR_SYSCALL ||
135 ssl_error == SSL_ERROR_SSL) {
136 TEST_error("Test %d failed: Failed to write app data\n", test);
137 goto end;
138 }
139 }
140 }
141 if (!TEST_size_t_eq(len, sizeof(testdata)))
142 goto end;
143 /*
144 * Now read the test data. It may take more attempts here because
145 * it could fail once for each byte read, including all overhead
146 * bytes from the record header/padding etc.
147 */
148 for (ret = -1, i = 0, len = 0; len != sizeof(testdata) &&
149 i < MAX_ATTEMPTS; i++) {
150 if (test >= 5 && (!TEST_true(SSL_free_buffers(serverssl))
151 || !TEST_true(checkbuffers(serverssl, 0))))
152 goto end;
153 /* free a second time */
154 if (test >= 6 && (!TEST_true(SSL_free_buffers(serverssl))
155 || !TEST_true(checkbuffers(serverssl, 0))))
156 goto end;
157 if (test >= 7 && (!TEST_true(SSL_alloc_buffers(serverssl))
158 || !TEST_true(checkbuffers(serverssl, 1))))
159 goto end;
160 if (test >= 8 && (!TEST_true(SSL_free_buffers(serverssl))
161 || !TEST_true(checkbuffers(serverssl, 0))))
162 goto end;
163
164 ret = SSL_read(serverssl, buf + len, sizeof(buf) - len);
165 if (ret > 0) {
166 len += ret;
167 } else {
168 int ssl_error = SSL_get_error(serverssl, ret);
169
170 if (ssl_error == SSL_ERROR_SYSCALL ||
171 ssl_error == SSL_ERROR_SSL) {
172 TEST_error("Test %d failed: Failed to read app data\n", test);
173 goto end;
174 }
175 }
176 }
177 if (!TEST_mem_eq(buf, len, testdata, sizeof(testdata)))
178 goto end;
179 }
180
181 result = 1;
182 end:
183 if (!result)
184 ERR_print_errors_fp(stderr);
185
186 SSL_free(clientssl);
187 SSL_free(serverssl);
188
189 return result;
190 }
191
192 /*
193 * Test that attempting to free the buffers at points where they cannot be freed
194 * works as expected
195 * Test 0: Attempt to free buffers after a full record has been processed, but
196 * the application has only performed a partial read
197 * Test 1: Attempt to free buffers after only a partial record header has been
198 * received
199 * Test 2: Attempt to free buffers after a full record header but no record body
200 * Test 3: Attempt to free buffers after a full record hedaer and partial record
201 * body
202 * Test 4-7: We repeat tests 0-3 but including data from a second pipelined
203 * record
204 */
test_free_buffers(int test)205 static int test_free_buffers(int test)
206 {
207 int result = 0;
208 SSL *serverssl = NULL, *clientssl = NULL;
209 const char testdata[] = "Test data";
210 char buf[120];
211 size_t written, readbytes;
212 int i, pipeline = test > 3;
213 ENGINE *e = NULL;
214
215 if (pipeline) {
216 e = load_dasync();
217 if (e == NULL)
218 goto end;
219 test -= 4;
220 }
221
222 if (!TEST_true(create_ssl_objects(serverctx, clientctx, &serverssl,
223 &clientssl, NULL, NULL)))
224 goto end;
225
226 if (pipeline) {
227 if (!TEST_true(SSL_set_cipher_list(serverssl, "AES128-SHA"))
228 || !TEST_true(SSL_set_max_proto_version(serverssl,
229 TLS1_2_VERSION))
230 || !TEST_true(SSL_set_max_pipelines(serverssl, 2)))
231 goto end;
232 }
233
234 if (!TEST_true(create_ssl_connection(serverssl, clientssl,
235 SSL_ERROR_NONE)))
236 goto end;
237
238 /*
239 * For the non-pipeline case we write one record. For pipelining we write
240 * two records.
241 */
242 for (i = 0; i <= pipeline; i++) {
243 if (!TEST_true(SSL_write_ex(clientssl, testdata, strlen(testdata),
244 &written)))
245 goto end;
246 }
247
248 if (test == 0) {
249 size_t readlen = 1;
250
251 /*
252 * Deliberately only read the first byte - so the remaining bytes are
253 * still buffered. In the pipelining case we read as far as the first
254 * byte from the second record.
255 */
256 if (pipeline)
257 readlen += strlen(testdata);
258
259 if (!TEST_true(SSL_read_ex(serverssl, buf, readlen, &readbytes))
260 || !TEST_size_t_eq(readlen, readbytes))
261 goto end;
262 } else {
263 BIO *tmp;
264 size_t partial_len;
265
266 /* Remove all the data that is pending for read by the server */
267 tmp = SSL_get_rbio(serverssl);
268 if (!TEST_true(BIO_read_ex(tmp, buf, sizeof(buf), &readbytes))
269 || !TEST_size_t_lt(readbytes, sizeof(buf))
270 || !TEST_size_t_gt(readbytes, SSL3_RT_HEADER_LENGTH))
271 goto end;
272
273 switch(test) {
274 case 1:
275 partial_len = SSL3_RT_HEADER_LENGTH - 1;
276 break;
277 case 2:
278 partial_len = SSL3_RT_HEADER_LENGTH;
279 break;
280 case 3:
281 partial_len = readbytes - 1;
282 break;
283 default:
284 TEST_error("Invalid test index");
285 goto end;
286 }
287
288 if (pipeline) {
289 /* We happen to know the first record is 57 bytes long */
290 const size_t first_rec_len = 57;
291
292 if (test != 3)
293 partial_len += first_rec_len;
294
295 /*
296 * Sanity check. If we got the record len right then this should
297 * never fail.
298 */
299 if (!TEST_int_eq(buf[first_rec_len], SSL3_RT_APPLICATION_DATA))
300 goto end;
301 }
302
303 /*
304 * Put back just the partial record (plus the whole initial record in
305 * the pipelining case)
306 */
307 if (!TEST_true(BIO_write_ex(tmp, buf, partial_len, &written)))
308 goto end;
309
310 if (pipeline) {
311 /*
312 * Attempt a read. This should pass but only return data from the
313 * first record. Only a partial record is available for the second
314 * record.
315 */
316 if (!TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf),
317 &readbytes))
318 || !TEST_size_t_eq(readbytes, strlen(testdata)))
319 goto end;
320 } else {
321 /*
322 * Attempt a read. This should fail because only a partial record is
323 * available.
324 */
325 if (!TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf),
326 &readbytes)))
327 goto end;
328 }
329 }
330
331 /*
332 * Attempting to free the buffers at this point should fail because they are
333 * still in use
334 */
335 if (!TEST_false(SSL_free_buffers(serverssl)))
336 goto end;
337
338 result = 1;
339 end:
340 SSL_free(clientssl);
341 SSL_free(serverssl);
342 #ifndef OPENSSL_NO_DYNAMIC_ENGINE
343 if (e != NULL) {
344 ENGINE_unregister_ciphers(e);
345 ENGINE_finish(e);
346 ENGINE_free(e);
347 }
348 #endif
349 return result;
350 }
351
352 OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n")
353
setup_tests(void)354 int setup_tests(void)
355 {
356 char *cert, *pkey;
357
358 if (!test_skip_common_options()) {
359 TEST_error("Error parsing test options\n");
360 return 0;
361 }
362
363 if (!TEST_ptr(cert = test_get_argument(0))
364 || !TEST_ptr(pkey = test_get_argument(1)))
365 return 0;
366
367 if (!create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(),
368 TLS1_VERSION, 0,
369 &serverctx, &clientctx, cert, pkey)) {
370 TEST_error("Failed to create SSL_CTX pair\n");
371 return 0;
372 }
373
374 ADD_ALL_TESTS(test_func, 9);
375 #if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE)
376 ADD_ALL_TESTS(test_free_buffers, 8);
377 #else
378 ADD_ALL_TESTS(test_free_buffers, 4);
379 #endif
380 return 1;
381 }
382
cleanup_tests(void)383 void cleanup_tests(void)
384 {
385 SSL_CTX_free(clientctx);
386 SSL_CTX_free(serverctx);
387 }
388