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