sslbuffertest.c 12 KB

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