summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2019-01-19 02:57:04 +0000
committerjsing <>2019-01-19 02:57:04 +0000
commit16ec5ecfb1d1645f467a9a1af970763217cd5d86 (patch)
tree54bdb7dfb4340210334119a5bbf55af58f7de817
parent6a367516df1cd7a6eb819c9bc94f4e4cb1d4f0eb (diff)
downloadopenbsd-16ec5ecfb1d1645f467a9a1af970763217cd5d86.tar.gz
openbsd-16ec5ecfb1d1645f467a9a1af970763217cd5d86.tar.bz2
openbsd-16ec5ecfb1d1645f467a9a1af970763217cd5d86.zip
Add regress for TLSv1.3 record handling.
-rw-r--r--src/regress/lib/libssl/record/Makefile10
-rw-r--r--src/regress/lib/libssl/record/recordtest.c523
2 files changed, 533 insertions, 0 deletions
diff --git a/src/regress/lib/libssl/record/Makefile b/src/regress/lib/libssl/record/Makefile
new file mode 100644
index 0000000000..f0e2bc52a8
--- /dev/null
+++ b/src/regress/lib/libssl/record/Makefile
@@ -0,0 +1,10 @@
1# $OpenBSD: Makefile,v 1.1 2019/01/19 02:57:04 jsing Exp $
2
3PROG= recordtest
4LDADD= ${SSL_INT} -lcrypto
5DPADD= ${LIBSSL} ${LIBCRYPTO}
6WARNINGS= Yes
7CFLAGS+= -DLIBRESSL_INTERNAL -Wall -Wundef -Werror
8CFLAGS+= -I${.CURDIR}/../../../../lib/libssl
9
10.include <bsd.regress.mk>
diff --git a/src/regress/lib/libssl/record/recordtest.c b/src/regress/lib/libssl/record/recordtest.c
new file mode 100644
index 0000000000..2e08c34577
--- /dev/null
+++ b/src/regress/lib/libssl/record/recordtest.c
@@ -0,0 +1,523 @@
1/*
2 * Copyright (c) 2019 Joel Sing <jsing@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <err.h>
18#include <string.h>
19
20#include <openssl/ssl.h>
21
22#include "tls13_internal.h"
23#include "tls13_record.h"
24
25/* Valid record. */
26static uint8_t test_record_1[] = {
27 0x16, 0x03, 0x03, 0x00, 0x7a, 0x02, 0x00, 0x00,
28 0x76, 0x03, 0x03, 0x14, 0xae, 0x2b, 0x6d, 0x58,
29 0xe9, 0x79, 0x9d, 0xd4, 0x90, 0x52, 0x90, 0x13,
30 0x1c, 0x08, 0xaa, 0x3f, 0x5b, 0xfb, 0x64, 0xfe,
31 0x9a, 0xca, 0x73, 0x6d, 0x87, 0x8d, 0x8b, 0x3b,
32 0x70, 0x14, 0xa3, 0x20, 0xd7, 0x50, 0xa4, 0xe5,
33 0x17, 0x42, 0x5d, 0xce, 0xe6, 0xfe, 0x1b, 0x59,
34 0x27, 0x6b, 0xff, 0xc8, 0x40, 0xc7, 0xac, 0x16,
35 0x32, 0xe6, 0x5b, 0xd2, 0xd9, 0xd4, 0xb5, 0x3f,
36 0x8f, 0x74, 0x6e, 0x7d, 0x13, 0x02, 0x00, 0x00,
37 0x2e, 0x00, 0x33, 0x00, 0x24, 0x00, 0x1d, 0x00,
38 0x20, 0x72, 0xb0, 0xaf, 0x7f, 0xf5, 0x89, 0x0f,
39 0xcd, 0x6e, 0x45, 0xb1, 0x51, 0xa0, 0xbd, 0x1e,
40 0xee, 0x7e, 0xf1, 0xa5, 0xc5, 0xc6, 0x7e, 0x5f,
41 0x6a, 0xca, 0xc9, 0xe4, 0xae, 0xb9, 0x50, 0x76,
42 0x0a, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04,
43};
44
45/* Truncated record. */
46static uint8_t test_record_2[] = {
47 0x17, 0x03, 0x03, 0xff, 0xff, 0x02, 0x00, 0x00,
48};
49
50static void
51hexdump(const unsigned char *buf, size_t len)
52{
53 size_t i;
54
55 for (i = 1; i <= len; i++)
56 fprintf(stderr, " 0x%02x,%s", buf[i - 1], i % 8 ? "" : "\n");
57 if (len % 8 != 0)
58 fprintf(stderr, "\n");
59}
60
61struct rw_state {
62 uint8_t *buf;
63 size_t len;
64 size_t offset;
65 uint8_t eof;
66};
67
68static ssize_t
69read_cb(void *buf, size_t buflen, void *cb_arg)
70{
71 struct rw_state *rs = cb_arg;
72 ssize_t n;
73
74 if (rs->eof)
75 return TLS13_IO_EOF;
76
77 if ((size_t)(n = buflen) > (rs->len - rs->offset))
78 n = rs->len - rs->offset;
79
80 if (n == 0)
81 return TLS13_IO_WANT_POLLIN;
82
83 memcpy(buf, &rs->buf[rs->offset], n);
84 rs->offset += n;
85
86 return n;
87}
88
89static ssize_t
90write_cb(const void *buf, size_t buflen, void *cb_arg)
91{
92 struct rw_state *ws = cb_arg;
93 ssize_t n;
94
95 if (ws->eof)
96 return TLS13_IO_EOF;
97
98 if ((size_t)(n = buflen) > (ws->len - ws->offset))
99 n = ws->len - ws->offset;
100
101 if (n == 0)
102 return TLS13_IO_WANT_POLLOUT;
103
104 memcpy(&ws->buf[ws->offset], buf, n);
105 ws->offset += n;
106
107 return n;
108}
109
110struct record_test {
111 size_t rw_len;
112 int eof;
113 ssize_t want_ret;
114};
115
116struct record_recv_test {
117 uint8_t *read_buf;
118 struct record_test rt[10];
119 uint8_t want_content_type;
120 uint8_t *want_data;
121 size_t want_len;
122};
123
124struct record_recv_test record_recv_tests[] = {
125 {
126 .read_buf = test_record_1,
127 .rt = {
128 {
129 .rw_len = sizeof(test_record_1),
130 .want_ret = sizeof(test_record_1),
131 },
132 },
133 .want_content_type = SSL3_RT_HANDSHAKE,
134 .want_data = test_record_1,
135 .want_len = sizeof(test_record_1),
136 },
137 {
138 .read_buf = test_record_1,
139 .rt = {
140 {
141 .rw_len = 0,
142 .want_ret = TLS13_IO_WANT_POLLIN,
143 },
144 {
145 .rw_len = sizeof(test_record_1),
146 .want_ret = sizeof(test_record_1),
147 },
148 },
149 .want_content_type = SSL3_RT_HANDSHAKE,
150 .want_data = test_record_1,
151 .want_len = sizeof(test_record_1),
152 },
153 {
154 .read_buf = test_record_1,
155 .rt = {
156 {
157 .rw_len = 0,
158 .want_ret = TLS13_IO_WANT_POLLIN,
159 },
160 {
161 .rw_len = 5,
162 .want_ret = TLS13_IO_WANT_POLLIN,
163 },
164 {
165 .rw_len = sizeof(test_record_1),
166 .want_ret = sizeof(test_record_1),
167 },
168 },
169 .want_content_type = SSL3_RT_HANDSHAKE,
170 .want_data = test_record_1,
171 .want_len = sizeof(test_record_1),
172 },
173 {
174 .read_buf = test_record_1,
175 .rt = {
176 {
177 .rw_len = 0,
178 .want_ret = TLS13_IO_WANT_POLLIN,
179 },
180 {
181 .rw_len = 2,
182 .want_ret = TLS13_IO_WANT_POLLIN,
183 },
184 {
185 .rw_len = 6,
186 .want_ret = TLS13_IO_WANT_POLLIN,
187 },
188 {
189 .rw_len = sizeof(test_record_1),
190 .want_ret = sizeof(test_record_1),
191 },
192 },
193 .want_content_type = SSL3_RT_HANDSHAKE,
194 .want_data = test_record_1,
195 .want_len = sizeof(test_record_1),
196 },
197 {
198 .read_buf = test_record_1,
199 .rt = {
200 {
201 .rw_len = 4,
202 .want_ret = TLS13_IO_WANT_POLLIN,
203 },
204 {
205 .eof = 1,
206 .want_ret = TLS13_IO_EOF,
207 },
208 },
209 },
210 {
211 .read_buf = test_record_1,
212 .rt = {
213 {
214 .eof = 1,
215 .want_ret = TLS13_IO_EOF,
216 },
217 },
218 },
219 {
220 .read_buf = test_record_2,
221 .rt = {
222 {
223 .rw_len = sizeof(test_record_2),
224 .want_ret = TLS13_IO_WANT_POLLIN,
225 },
226 {
227 .eof = 1,
228 .want_ret = TLS13_IO_EOF,
229 },
230 },
231 .want_content_type = SSL3_RT_APPLICATION_DATA,
232 },
233};
234
235#define N_RECORD_RECV_TESTS (sizeof(record_recv_tests) / sizeof(record_recv_tests[0]))
236
237struct record_send_test {
238 uint8_t *data;
239 size_t data_len;
240 struct record_test rt[10];
241 uint8_t *want_data;
242 size_t want_len;
243};
244
245struct record_send_test record_send_tests[] = {
246 {
247 .data = test_record_1,
248 .data_len = sizeof(test_record_1),
249 .rt = {
250 {
251 .rw_len = sizeof(test_record_1),
252 .want_ret = sizeof(test_record_1),
253 },
254 },
255 .want_data = test_record_1,
256 .want_len = sizeof(test_record_1),
257 },
258 {
259 .data = test_record_1,
260 .data_len = sizeof(test_record_1),
261 .rt = {
262 {
263 .rw_len = 0,
264 .want_ret = TLS13_IO_WANT_POLLOUT,
265 },
266 {
267 .rw_len = sizeof(test_record_1),
268 .want_ret = sizeof(test_record_1),
269 },
270 },
271 .want_data = test_record_1,
272 .want_len = sizeof(test_record_1),
273 },
274 {
275 .data = test_record_1,
276 .data_len = sizeof(test_record_1),
277 .rt = {
278 {
279 .rw_len = 0,
280 .want_ret = TLS13_IO_WANT_POLLOUT,
281 },
282 {
283 .rw_len = 5,
284 .want_ret = TLS13_IO_WANT_POLLOUT,
285 },
286 {
287 .rw_len = sizeof(test_record_1),
288 .want_ret = sizeof(test_record_1),
289 },
290 },
291 .want_data = test_record_1,
292 .want_len = sizeof(test_record_1),
293 },
294 {
295 .data = test_record_1,
296 .data_len = sizeof(test_record_1),
297 .rt = {
298 {
299 .rw_len = 0,
300 .want_ret = TLS13_IO_WANT_POLLOUT,
301 },
302 {
303 .rw_len = 2,
304 .want_ret = TLS13_IO_WANT_POLLOUT,
305 },
306 {
307 .rw_len = 6,
308 .want_ret = TLS13_IO_WANT_POLLOUT,
309 },
310 {
311 .rw_len = sizeof(test_record_1),
312 .want_ret = sizeof(test_record_1),
313 },
314 },
315 .want_data = test_record_1,
316 .want_len = sizeof(test_record_1),
317 },
318 {
319 .data = test_record_1,
320 .data_len = sizeof(test_record_1),
321 .rt = {
322 {
323 .rw_len = 4,
324 .want_ret = TLS13_IO_WANT_POLLOUT,
325 },
326 {
327 .eof = 1,
328 .want_ret = TLS13_IO_EOF,
329 },
330 },
331 .want_data = test_record_1,
332 .want_len = 4,
333 },
334 {
335 .data = test_record_1,
336 .data_len = sizeof(test_record_1),
337 .rt = {
338 {
339 .rw_len = 0,
340 .want_ret = TLS13_IO_WANT_POLLOUT,
341 },
342 {
343 .eof = 1,
344 .want_ret = TLS13_IO_EOF,
345 },
346 },
347 .want_data = NULL,
348 .want_len = 0,
349 },
350};
351
352#define N_RECORD_SEND_TESTS (sizeof(record_send_tests) / sizeof(record_send_tests[0]))
353
354static int
355test_record_recv(size_t test_no, struct record_recv_test *rrt)
356{
357 struct tls13_record *rec;
358 struct rw_state rs;
359 int failed = 1;
360 ssize_t ret;
361 size_t i;
362 CBS cbs;
363
364 rs.buf = rrt->read_buf;
365 rs.offset = 0;
366
367 if ((rec = tls13_record_new()) == NULL)
368 errx(1, "tls13_record_new");
369
370 for (i = 0; rrt->rt[i].rw_len != 0 || rrt->rt[i].want_ret != 0; i++) {
371 rs.eof = rrt->rt[i].eof;
372 rs.len = rrt->rt[i].rw_len;
373
374 ret = tls13_record_recv(rec, read_cb, &rs);
375 if (ret != rrt->rt[i].want_ret) {
376 fprintf(stderr, "FAIL: Test %zu/%zu - tls_record_recv "
377 "returned %zi, want %zi\n", test_no, i, ret,
378 rrt->rt[i].want_ret);
379 goto failure;
380 }
381 }
382
383 if (tls13_record_content_type(rec) != rrt->want_content_type) {
384 fprintf(stderr, "FAIL: Test %zu - got content type %u, "
385 "want %u\n", test_no, tls13_record_content_type(rec),
386 rrt->want_content_type);
387 goto failure;
388 }
389
390 tls13_record_data(rec, &cbs);
391
392 if (rrt->want_data == NULL) {
393 if (CBS_data(&cbs) != NULL || CBS_len(&cbs) != 0) {
394 fprintf(stderr, "FAIL: Test %zu - got CBS with data, "
395 "want NULL\n", test_no);
396 goto failure;
397 }
398 goto done;
399 }
400
401 if (!CBS_mem_equal(&cbs, rrt->want_data, rrt->want_len)) {
402 fprintf(stderr, "FAIL: Test %zu - data mismatch\n", test_no);
403 fprintf(stderr, "Got record data:\n");
404 hexdump(CBS_data(&cbs), CBS_len(&cbs));
405 fprintf(stderr, "Want record data:\n");
406 hexdump(rrt->want_data, rrt->want_len);
407 goto failure;
408 }
409 if (!tls13_record_content(rec, &cbs)) {
410 fprintf(stderr, "FAIL: Test %zu - fail to get record "
411 "content", test_no);
412 goto failure;
413 }
414 if (!CBS_mem_equal(&cbs, rrt->want_data + TLS13_RECORD_HEADER_LEN,
415 rrt->want_len - TLS13_RECORD_HEADER_LEN)) {
416 fprintf(stderr, "FAIL: Test %zu - content mismatch\n", test_no);
417 fprintf(stderr, "Got record data:\n");
418 hexdump(CBS_data(&cbs), CBS_len(&cbs));
419 fprintf(stderr, "Want record data:\n");
420 hexdump(rrt->want_data, rrt->want_len);
421 goto failure;
422 }
423
424 done:
425 failed = 0;
426
427 failure:
428 tls13_record_free(rec);
429
430 return failed;
431}
432
433static int
434test_record_send(size_t test_no, struct record_send_test *rst)
435{
436 uint8_t *data = NULL;
437 struct tls13_record *rec;
438 struct rw_state ws;
439 int failed = 1;
440 ssize_t ret;
441 size_t i;
442
443 if ((ws.buf = malloc(TLS13_RECORD_MAX_LEN)) == NULL)
444 errx(1, "malloc");
445
446 ws.offset = 0;
447
448 if ((rec = tls13_record_new()) == NULL)
449 errx(1, "tls13_record_new");
450
451 if ((data = malloc(rst->data_len)) == NULL)
452 errx(1, "malloc");
453 memcpy(data, rst->data, rst->data_len);
454
455 tls13_record_set_data(rec, data, rst->data_len);
456 data = NULL;
457
458 for (i = 0; rst->rt[i].rw_len != 0 || rst->rt[i].want_ret != 0; i++) {
459 ws.eof = rst->rt[i].eof;
460 ws.len = rst->rt[i].rw_len;
461
462 ret = tls13_record_send(rec, write_cb, &ws);
463 if (ret != rst->rt[i].want_ret) {
464 fprintf(stderr, "FAIL: Test %zu/%zu - tls_record_send "
465 "returned %zi, want %zi\n", test_no, i, ret,
466 rst->rt[i].want_ret);
467 goto failure;
468 }
469 }
470
471 if (rst->want_data != NULL &&
472 memcmp(ws.buf, rst->want_data, rst->want_len) != 0) {
473 fprintf(stderr, "FAIL: Test %zu - content mismatch\n", test_no);
474 fprintf(stderr, "Got record data:\n");
475 hexdump(rst->data, rst->data_len);
476 fprintf(stderr, "Want record data:\n");
477 hexdump(rst->want_data, rst->want_len);
478 goto failure;
479 }
480
481 failed = 0;
482
483 failure:
484 tls13_record_free(rec);
485 free(ws.buf);
486
487 return failed;
488}
489
490static int
491test_recv_records(void)
492{
493 int failed = 0;
494 size_t i;
495
496 for (i = 0; i < N_RECORD_RECV_TESTS; i++)
497 failed |= test_record_recv(i, &record_recv_tests[i]);
498
499 return failed;
500}
501
502static int
503test_send_records(void)
504{
505 int failed = 0;
506 size_t i;
507
508 for (i = 0; i < N_RECORD_SEND_TESTS; i++)
509 failed |= test_record_send(i, &record_send_tests[i]);
510
511 return failed;
512}
513
514int
515main(int argc, char **argv)
516{
517 int failed = 0;
518
519 failed |= test_recv_records();
520 failed |= test_send_records();
521
522 return failed;
523}