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. */ 26 static 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. */ 46 static uint8_t test_record_2[] = { 47 0x17, 0x03, 0x03, 0x41, 0x00, 0x02, 0x00, 0x00, 48 }; 49 50 /* Oversized and truncated record. */ 51 static uint8_t test_record_3[] = { 52 0x17, 0x03, 0x03, 0x41, 0x01, 0x02, 0x00, 0x00, 53 }; 54 55 static void 56 hexdump(const unsigned char *buf, size_t len) 57 { 58 size_t i; 59 60 for (i = 1; i <= len; i++) 61 fprintf(stderr, " 0x%02x,%s", buf[i - 1], i % 8 ? "" : "\n"); 62 if (len % 8 != 0) 63 fprintf(stderr, "\n"); 64 } 65 66 struct rw_state { 67 uint8_t *buf; 68 size_t len; 69 size_t offset; 70 uint8_t eof; 71 }; 72 73 static ssize_t 74 read_cb(void *buf, size_t buflen, void *cb_arg) 75 { 76 struct rw_state *rs = cb_arg; 77 ssize_t n; 78 79 if (rs->eof) 80 return TLS13_IO_EOF; 81 82 if ((size_t)(n = buflen) > (rs->len - rs->offset)) 83 n = rs->len - rs->offset; 84 85 if (n == 0) 86 return TLS13_IO_WANT_POLLIN; 87 88 memcpy(buf, &rs->buf[rs->offset], n); 89 rs->offset += n; 90 91 return n; 92 } 93 94 static ssize_t 95 write_cb(const void *buf, size_t buflen, void *cb_arg) 96 { 97 struct rw_state *ws = cb_arg; 98 ssize_t n; 99 100 if (ws->eof) 101 return TLS13_IO_EOF; 102 103 if ((size_t)(n = buflen) > (ws->len - ws->offset)) 104 n = ws->len - ws->offset; 105 106 if (n == 0) 107 return TLS13_IO_WANT_POLLOUT; 108 109 memcpy(&ws->buf[ws->offset], buf, n); 110 ws->offset += n; 111 112 return n; 113 } 114 115 struct record_test { 116 size_t rw_len; 117 int eof; 118 ssize_t want_ret; 119 }; 120 121 struct record_recv_test { 122 uint8_t *read_buf; 123 struct record_test rt[10]; 124 uint8_t want_content_type; 125 uint8_t *want_data; 126 size_t want_len; 127 }; 128 129 struct record_recv_test record_recv_tests[] = { 130 { 131 .read_buf = test_record_1, 132 .rt = { 133 { 134 .rw_len = sizeof(test_record_1), 135 .want_ret = sizeof(test_record_1), 136 }, 137 }, 138 .want_content_type = SSL3_RT_HANDSHAKE, 139 .want_data = test_record_1, 140 .want_len = sizeof(test_record_1), 141 }, 142 { 143 .read_buf = test_record_1, 144 .rt = { 145 { 146 .rw_len = 0, 147 .want_ret = TLS13_IO_WANT_POLLIN, 148 }, 149 { 150 .rw_len = sizeof(test_record_1), 151 .want_ret = sizeof(test_record_1), 152 }, 153 }, 154 .want_content_type = SSL3_RT_HANDSHAKE, 155 .want_data = test_record_1, 156 .want_len = sizeof(test_record_1), 157 }, 158 { 159 .read_buf = test_record_1, 160 .rt = { 161 { 162 .rw_len = 0, 163 .want_ret = TLS13_IO_WANT_POLLIN, 164 }, 165 { 166 .rw_len = 5, 167 .want_ret = TLS13_IO_WANT_POLLIN, 168 }, 169 { 170 .rw_len = sizeof(test_record_1), 171 .want_ret = sizeof(test_record_1), 172 }, 173 }, 174 .want_content_type = SSL3_RT_HANDSHAKE, 175 .want_data = test_record_1, 176 .want_len = sizeof(test_record_1), 177 }, 178 { 179 .read_buf = test_record_1, 180 .rt = { 181 { 182 .rw_len = 0, 183 .want_ret = TLS13_IO_WANT_POLLIN, 184 }, 185 { 186 .rw_len = 2, 187 .want_ret = TLS13_IO_WANT_POLLIN, 188 }, 189 { 190 .rw_len = 6, 191 .want_ret = TLS13_IO_WANT_POLLIN, 192 }, 193 { 194 .rw_len = sizeof(test_record_1), 195 .want_ret = sizeof(test_record_1), 196 }, 197 }, 198 .want_content_type = SSL3_RT_HANDSHAKE, 199 .want_data = test_record_1, 200 .want_len = sizeof(test_record_1), 201 }, 202 { 203 .read_buf = test_record_1, 204 .rt = { 205 { 206 .rw_len = 4, 207 .want_ret = TLS13_IO_WANT_POLLIN, 208 }, 209 { 210 .eof = 1, 211 .want_ret = TLS13_IO_EOF, 212 }, 213 }, 214 }, 215 { 216 .read_buf = test_record_1, 217 .rt = { 218 { 219 .eof = 1, 220 .want_ret = TLS13_IO_EOF, 221 }, 222 }, 223 }, 224 { 225 .read_buf = test_record_2, 226 .rt = { 227 { 228 .rw_len = sizeof(test_record_2), 229 .want_ret = TLS13_IO_WANT_POLLIN, 230 }, 231 { 232 .eof = 1, 233 .want_ret = TLS13_IO_EOF, 234 }, 235 }, 236 .want_content_type = SSL3_RT_APPLICATION_DATA, 237 }, 238 { 239 .read_buf = test_record_3, 240 .rt = { 241 { 242 .rw_len = sizeof(test_record_3), 243 .want_ret = TLS13_IO_FAILURE, 244 }, 245 }, 246 }, 247 }; 248 249 #define N_RECORD_RECV_TESTS (sizeof(record_recv_tests) / sizeof(record_recv_tests[0])) 250 251 struct record_send_test { 252 uint8_t *data; 253 size_t data_len; 254 struct record_test rt[10]; 255 uint8_t *want_data; 256 size_t want_len; 257 }; 258 259 struct record_send_test record_send_tests[] = { 260 { 261 .data = test_record_1, 262 .data_len = sizeof(test_record_1), 263 .rt = { 264 { 265 .rw_len = sizeof(test_record_1), 266 .want_ret = sizeof(test_record_1), 267 }, 268 }, 269 .want_data = test_record_1, 270 .want_len = sizeof(test_record_1), 271 }, 272 { 273 .data = test_record_1, 274 .data_len = sizeof(test_record_1), 275 .rt = { 276 { 277 .rw_len = 0, 278 .want_ret = TLS13_IO_WANT_POLLOUT, 279 }, 280 { 281 .rw_len = sizeof(test_record_1), 282 .want_ret = sizeof(test_record_1), 283 }, 284 }, 285 .want_data = test_record_1, 286 .want_len = sizeof(test_record_1), 287 }, 288 { 289 .data = test_record_1, 290 .data_len = sizeof(test_record_1), 291 .rt = { 292 { 293 .rw_len = 0, 294 .want_ret = TLS13_IO_WANT_POLLOUT, 295 }, 296 { 297 .rw_len = 5, 298 .want_ret = TLS13_IO_WANT_POLLOUT, 299 }, 300 { 301 .rw_len = sizeof(test_record_1), 302 .want_ret = sizeof(test_record_1), 303 }, 304 }, 305 .want_data = test_record_1, 306 .want_len = sizeof(test_record_1), 307 }, 308 { 309 .data = test_record_1, 310 .data_len = sizeof(test_record_1), 311 .rt = { 312 { 313 .rw_len = 0, 314 .want_ret = TLS13_IO_WANT_POLLOUT, 315 }, 316 { 317 .rw_len = 2, 318 .want_ret = TLS13_IO_WANT_POLLOUT, 319 }, 320 { 321 .rw_len = 6, 322 .want_ret = TLS13_IO_WANT_POLLOUT, 323 }, 324 { 325 .rw_len = sizeof(test_record_1), 326 .want_ret = sizeof(test_record_1), 327 }, 328 }, 329 .want_data = test_record_1, 330 .want_len = sizeof(test_record_1), 331 }, 332 { 333 .data = test_record_1, 334 .data_len = sizeof(test_record_1), 335 .rt = { 336 { 337 .rw_len = 4, 338 .want_ret = TLS13_IO_WANT_POLLOUT, 339 }, 340 { 341 .eof = 1, 342 .want_ret = TLS13_IO_EOF, 343 }, 344 }, 345 .want_data = test_record_1, 346 .want_len = 4, 347 }, 348 { 349 .data = test_record_1, 350 .data_len = sizeof(test_record_1), 351 .rt = { 352 { 353 .rw_len = 0, 354 .want_ret = TLS13_IO_WANT_POLLOUT, 355 }, 356 { 357 .eof = 1, 358 .want_ret = TLS13_IO_EOF, 359 }, 360 }, 361 .want_data = NULL, 362 .want_len = 0, 363 }, 364 }; 365 366 #define N_RECORD_SEND_TESTS (sizeof(record_send_tests) / sizeof(record_send_tests[0])) 367 368 static int 369 test_record_recv(size_t test_no, struct record_recv_test *rrt) 370 { 371 struct tls13_record *rec; 372 struct rw_state rs; 373 int failed = 1; 374 ssize_t ret; 375 size_t i; 376 CBS cbs; 377 378 rs.buf = rrt->read_buf; 379 rs.offset = 0; 380 381 if ((rec = tls13_record_new()) == NULL) 382 errx(1, "tls13_record_new"); 383 384 for (i = 0; rrt->rt[i].rw_len != 0 || rrt->rt[i].want_ret != 0; i++) { 385 rs.eof = rrt->rt[i].eof; 386 rs.len = rrt->rt[i].rw_len; 387 388 ret = tls13_record_recv(rec, read_cb, &rs); 389 if (ret != rrt->rt[i].want_ret) { 390 fprintf(stderr, "FAIL: Test %zu/%zu - tls_record_recv " 391 "returned %zi, want %zi\n", test_no, i, ret, 392 rrt->rt[i].want_ret); 393 goto failure; 394 } 395 } 396 397 if (tls13_record_content_type(rec) != rrt->want_content_type) { 398 fprintf(stderr, "FAIL: Test %zu - got content type %u, " 399 "want %u\n", test_no, tls13_record_content_type(rec), 400 rrt->want_content_type); 401 goto failure; 402 } 403 404 tls13_record_data(rec, &cbs); 405 if (rrt->want_data == NULL) { 406 if (CBS_data(&cbs) != NULL || CBS_len(&cbs) != 0) { 407 fprintf(stderr, "FAIL: Test %zu - got CBS with data, " 408 "want NULL\n", test_no); 409 goto failure; 410 } 411 goto done; 412 } 413 if (!CBS_mem_equal(&cbs, rrt->want_data, rrt->want_len)) { 414 fprintf(stderr, "FAIL: Test %zu - data mismatch\n", test_no); 415 fprintf(stderr, "Got record data:\n"); 416 hexdump(CBS_data(&cbs), CBS_len(&cbs)); 417 fprintf(stderr, "Want record data:\n"); 418 hexdump(rrt->want_data, rrt->want_len); 419 goto failure; 420 } 421 422 if (!tls13_record_header(rec, &cbs)) { 423 fprintf(stderr, "FAIL: Test %zu - fail to get record " 424 "header", test_no); 425 goto failure; 426 } 427 if (!CBS_mem_equal(&cbs, rrt->want_data, TLS13_RECORD_HEADER_LEN)) { 428 fprintf(stderr, "FAIL: Test %zu - header mismatch\n", test_no); 429 fprintf(stderr, "Got record header:\n"); 430 hexdump(CBS_data(&cbs), CBS_len(&cbs)); 431 fprintf(stderr, "Want record header:\n"); 432 hexdump(rrt->want_data, rrt->want_len); 433 goto failure; 434 } 435 436 if (!tls13_record_content(rec, &cbs)) { 437 fprintf(stderr, "FAIL: Test %zu - fail to get record " 438 "content", test_no); 439 goto failure; 440 } 441 if (!CBS_mem_equal(&cbs, rrt->want_data + TLS13_RECORD_HEADER_LEN, 442 rrt->want_len - TLS13_RECORD_HEADER_LEN)) { 443 fprintf(stderr, "FAIL: Test %zu - content mismatch\n", test_no); 444 fprintf(stderr, "Got record content:\n"); 445 hexdump(CBS_data(&cbs), CBS_len(&cbs)); 446 fprintf(stderr, "Want record content:\n"); 447 hexdump(rrt->want_data, rrt->want_len); 448 goto failure; 449 } 450 451 done: 452 failed = 0; 453 454 failure: 455 tls13_record_free(rec); 456 457 return failed; 458 } 459 460 static int 461 test_record_send(size_t test_no, struct record_send_test *rst) 462 { 463 uint8_t *data = NULL; 464 struct tls13_record *rec; 465 struct rw_state ws; 466 int failed = 1; 467 ssize_t ret; 468 size_t i; 469 470 if ((ws.buf = malloc(TLS13_RECORD_MAX_LEN)) == NULL) 471 errx(1, "malloc"); 472 473 ws.offset = 0; 474 475 if ((rec = tls13_record_new()) == NULL) 476 errx(1, "tls13_record_new"); 477 478 if ((data = malloc(rst->data_len)) == NULL) 479 errx(1, "malloc"); 480 memcpy(data, rst->data, rst->data_len); 481 482 if (!tls13_record_set_data(rec, data, rst->data_len)) { 483 fprintf(stderr, "FAIL: Test %zu - failed to set record data\n", 484 test_no); 485 goto failure; 486 } 487 data = NULL; 488 489 for (i = 0; rst->rt[i].rw_len != 0 || rst->rt[i].want_ret != 0; i++) { 490 ws.eof = rst->rt[i].eof; 491 ws.len = rst->rt[i].rw_len; 492 493 ret = tls13_record_send(rec, write_cb, &ws); 494 if (ret != rst->rt[i].want_ret) { 495 fprintf(stderr, "FAIL: Test %zu/%zu - tls_record_send " 496 "returned %zi, want %zi\n", test_no, i, ret, 497 rst->rt[i].want_ret); 498 goto failure; 499 } 500 } 501 502 if (rst->want_data != NULL && 503 memcmp(ws.buf, rst->want_data, rst->want_len) != 0) { 504 fprintf(stderr, "FAIL: Test %zu - content mismatch\n", test_no); 505 fprintf(stderr, "Got record data:\n"); 506 hexdump(rst->data, rst->data_len); 507 fprintf(stderr, "Want record data:\n"); 508 hexdump(rst->want_data, rst->want_len); 509 goto failure; 510 } 511 512 failed = 0; 513 514 failure: 515 tls13_record_free(rec); 516 free(ws.buf); 517 518 return failed; 519 } 520 521 static int 522 test_recv_records(void) 523 { 524 int failed = 0; 525 size_t i; 526 527 for (i = 0; i < N_RECORD_RECV_TESTS; i++) 528 failed |= test_record_recv(i, &record_recv_tests[i]); 529 530 return failed; 531 } 532 533 static int 534 test_send_records(void) 535 { 536 int failed = 0; 537 size_t i; 538 539 for (i = 0; i < N_RECORD_SEND_TESTS; i++) 540 failed |= test_record_send(i, &record_send_tests[i]); 541 542 return failed; 543 } 544 545 int 546 main(int argc, char **argv) 547 { 548 int failed = 0; 549 550 failed |= test_recv_records(); 551 failed |= test_send_records(); 552 553 return failed; 554 } 555