diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libssl/tls13_internal.h | 6 | ||||
| -rw-r--r-- | src/lib/libssl/tls13_record_layer.c | 183 |
2 files changed, 174 insertions, 15 deletions
diff --git a/src/lib/libssl/tls13_internal.h b/src/lib/libssl/tls13_internal.h index 9ab72f4f3a..05e108952a 100644 --- a/src/lib/libssl/tls13_internal.h +++ b/src/lib/libssl/tls13_internal.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls13_internal.h,v 1.30 2019/11/17 06:35:30 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_internal.h,v 1.31 2019/11/17 17:20:16 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2018 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2018 Bob Beck <beck@openbsd.org> |
| 4 | * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> | 4 | * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> |
| @@ -120,6 +120,10 @@ int tls13_record_layer_set_read_traffic_key(struct tls13_record_layer *rl, | |||
| 120 | struct tls13_secret *read_key); | 120 | struct tls13_secret *read_key); |
| 121 | int tls13_record_layer_set_write_traffic_key(struct tls13_record_layer *rl, | 121 | int tls13_record_layer_set_write_traffic_key(struct tls13_record_layer *rl, |
| 122 | struct tls13_secret *write_key); | 122 | struct tls13_secret *write_key); |
| 123 | ssize_t tls13_record_layer_alert(struct tls13_record_layer *rl, | ||
| 124 | uint8_t alert_level, uint8_t alert_desc); | ||
| 125 | ssize_t tls13_record_layer_phh(struct tls13_record_layer *rl, uint8_t *data, | ||
| 126 | size_t len); | ||
| 123 | 127 | ||
| 124 | ssize_t tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n); | 128 | ssize_t tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n); |
| 125 | ssize_t tls13_write_handshake_data(struct tls13_record_layer *rl, const uint8_t *buf, | 129 | ssize_t tls13_write_handshake_data(struct tls13_record_layer *rl, const uint8_t *buf, |
diff --git a/src/lib/libssl/tls13_record_layer.c b/src/lib/libssl/tls13_record_layer.c index ff26b09d46..8208ae508c 100644 --- a/src/lib/libssl/tls13_record_layer.c +++ b/src/lib/libssl/tls13_record_layer.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls13_record_layer.c,v 1.10 2019/11/17 00:10:47 beck Exp $ */ | 1 | /* $OpenBSD: tls13_record_layer.c,v 1.11 2019/11/17 17:20:16 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -22,6 +22,11 @@ | |||
| 22 | #include "tls13_internal.h" | 22 | #include "tls13_internal.h" |
| 23 | #include "tls13_record.h" | 23 | #include "tls13_record.h" |
| 24 | 24 | ||
| 25 | static ssize_t tls13_record_layer_write_chunk(struct tls13_record_layer *rl, | ||
| 26 | uint8_t content_type, const uint8_t *buf, size_t n); | ||
| 27 | static ssize_t tls13_record_layer_write_record(struct tls13_record_layer *rl, | ||
| 28 | uint8_t content_type, const uint8_t *content, size_t content_len); | ||
| 29 | |||
| 25 | struct tls13_record_layer { | 30 | struct tls13_record_layer { |
| 26 | int change_cipher_spec_seen; | 31 | int change_cipher_spec_seen; |
| 27 | int handshake_completed; | 32 | int handshake_completed; |
| @@ -36,7 +41,20 @@ struct tls13_record_layer { | |||
| 36 | int write_closed; | 41 | int write_closed; |
| 37 | 42 | ||
| 38 | struct tls13_record *rrec; | 43 | struct tls13_record *rrec; |
| 44 | |||
| 39 | struct tls13_record *wrec; | 45 | struct tls13_record *wrec; |
| 46 | uint8_t wrec_content_type; | ||
| 47 | size_t wrec_appdata_len; | ||
| 48 | size_t wrec_content_len; | ||
| 49 | |||
| 50 | /* Pending alert messages. */ | ||
| 51 | uint8_t *alert_data; | ||
| 52 | size_t alert_len; | ||
| 53 | |||
| 54 | /* Pending post-handshake handshake messages. */ | ||
| 55 | CBS phh_cbs; | ||
| 56 | uint8_t *phh_data; | ||
| 57 | size_t phh_len; | ||
| 40 | 58 | ||
| 41 | /* Buffer containing plaintext from opened records. */ | 59 | /* Buffer containing plaintext from opened records. */ |
| 42 | uint8_t rbuf_content_type; | 60 | uint8_t rbuf_content_type; |
| @@ -232,7 +250,7 @@ tls13_record_layer_process_alert(struct tls13_record_layer *rl) | |||
| 232 | } else if (alert_level == SSL3_AL_FATAL) { | 250 | } else if (alert_level == SSL3_AL_FATAL) { |
| 233 | rl->read_closed = 1; | 251 | rl->read_closed = 1; |
| 234 | rl->write_closed = 1; | 252 | rl->write_closed = 1; |
| 235 | ret = TLS13_IO_EOF; | 253 | ret = TLS13_IO_FAILURE; /* XXX - ALERT? */ |
| 236 | } else { | 254 | } else { |
| 237 | /* XXX - decode error alert. */ | 255 | /* XXX - decode error alert. */ |
| 238 | return TLS13_IO_FAILURE; | 256 | return TLS13_IO_FAILURE; |
| @@ -244,12 +262,112 @@ tls13_record_layer_process_alert(struct tls13_record_layer *rl) | |||
| 244 | return ret; | 262 | return ret; |
| 245 | } | 263 | } |
| 246 | 264 | ||
| 247 | int | 265 | static ssize_t |
| 248 | tls13_record_layer_send_alert(struct tls13_record_layer *rl, | 266 | tls13_record_layer_send_alert(struct tls13_record_layer *rl) |
| 267 | { | ||
| 268 | ssize_t ret; | ||
| 269 | |||
| 270 | /* This has to fit into a single record, per RFC 8446 section 5.1. */ | ||
| 271 | if ((ret = tls13_record_layer_write_record(rl, SSL3_RT_ALERT, | ||
| 272 | rl->alert_data, rl->alert_len)) != rl->alert_len) | ||
| 273 | return ret; | ||
| 274 | |||
| 275 | freezero(rl->alert_data, rl->alert_len); | ||
| 276 | rl->alert_data = NULL; | ||
| 277 | rl->alert_len = 0; | ||
| 278 | |||
| 279 | /* XXX - only close write channel when sending close notify. */ | ||
| 280 | rl->read_closed = 1; | ||
| 281 | rl->write_closed = 1; | ||
| 282 | |||
| 283 | /* XXX - we may want a TLS13_IO_ALERT (or handle as errors). */ | ||
| 284 | return TLS13_IO_FAILURE; | ||
| 285 | } | ||
| 286 | |||
| 287 | static ssize_t | ||
| 288 | tls13_record_layer_send_phh(struct tls13_record_layer *rl) | ||
| 289 | { | ||
| 290 | ssize_t ret; | ||
| 291 | |||
| 292 | /* Push out pending post-handshake handshake messages. */ | ||
| 293 | if ((ret = tls13_record_layer_write_chunk(rl, SSL3_RT_HANDSHAKE, | ||
| 294 | CBS_data(&rl->phh_cbs), CBS_len(&rl->phh_cbs))) < 0) | ||
| 295 | return ret; | ||
| 296 | if (!CBS_skip(&rl->phh_cbs, ret)) | ||
| 297 | return TLS13_IO_FAILURE; | ||
| 298 | if (CBS_len(&rl->phh_cbs) != 0) | ||
| 299 | return TLS13_IO_WANT_POLLOUT; | ||
| 300 | |||
| 301 | freezero(rl->phh_data, rl->phh_len); | ||
| 302 | rl->phh_data = NULL; | ||
| 303 | rl->phh_len = 0; | ||
| 304 | |||
| 305 | CBS_init(&rl->phh_cbs, rl->phh_data, rl->phh_len); | ||
| 306 | |||
| 307 | return TLS13_IO_SUCCESS; | ||
| 308 | } | ||
| 309 | |||
| 310 | static ssize_t | ||
| 311 | tls13_record_layer_send_pending(struct tls13_record_layer *rl) | ||
| 312 | { | ||
| 313 | /* | ||
| 314 | * If an alert is pending, then it needs to be sent. However, | ||
| 315 | * if we're already part of the way through sending post-handshake | ||
| 316 | * handshake messages, then we need to finish that first... | ||
| 317 | */ | ||
| 318 | |||
| 319 | if (rl->phh_data != NULL && CBS_len(&rl->phh_cbs) != rl->phh_len) | ||
| 320 | return tls13_record_layer_send_phh(rl); | ||
| 321 | |||
| 322 | if (rl->alert_data != NULL) | ||
| 323 | return tls13_record_layer_send_alert(rl); | ||
| 324 | |||
| 325 | if (rl->phh_data != NULL) | ||
| 326 | return tls13_record_layer_send_phh(rl); | ||
| 327 | |||
| 328 | return TLS13_IO_SUCCESS; | ||
| 329 | } | ||
| 330 | |||
| 331 | ssize_t | ||
| 332 | tls13_record_layer_alert(struct tls13_record_layer *rl, | ||
| 249 | uint8_t alert_level, uint8_t alert_desc) | 333 | uint8_t alert_level, uint8_t alert_desc) |
| 250 | { | 334 | { |
| 251 | /* XXX - implement. */ | 335 | CBB cbb; |
| 252 | return -1; | 336 | |
| 337 | if (rl->alert_data != NULL) | ||
| 338 | return TLS13_IO_FAILURE; | ||
| 339 | |||
| 340 | if (!CBB_init(&cbb, 0)) | ||
| 341 | goto err; | ||
| 342 | |||
| 343 | if (!CBB_add_u8(&cbb, alert_level)) | ||
| 344 | goto err; | ||
| 345 | if (!CBB_add_u8(&cbb, alert_desc)) | ||
| 346 | goto err; | ||
| 347 | if (!CBB_finish(&cbb, &rl->alert_data, &rl->alert_len)) | ||
| 348 | goto err; | ||
| 349 | |||
| 350 | return tls13_record_layer_send_pending(rl); | ||
| 351 | |||
| 352 | err: | ||
| 353 | CBB_cleanup(&cbb); | ||
| 354 | |||
| 355 | return TLS13_IO_FAILURE; | ||
| 356 | } | ||
| 357 | |||
| 358 | ssize_t | ||
| 359 | tls13_record_layer_phh(struct tls13_record_layer *rl, uint8_t *data, | ||
| 360 | size_t len) | ||
| 361 | { | ||
| 362 | if (rl->phh_data != NULL) | ||
| 363 | return TLS13_IO_FAILURE; | ||
| 364 | |||
| 365 | rl->phh_data = data; | ||
| 366 | rl->phh_len = len; | ||
| 367 | |||
| 368 | CBS_init(&rl->phh_cbs, rl->phh_data, rl->phh_len); | ||
| 369 | |||
| 370 | return tls13_record_layer_send_pending(rl); | ||
| 253 | } | 371 | } |
| 254 | 372 | ||
| 255 | static int | 373 | static int |
| @@ -546,6 +664,9 @@ tls13_record_layer_seal_record_protected(struct tls13_record_layer *rl, | |||
| 546 | if (!tls13_record_set_data(rl->wrec, data, data_len)) | 664 | if (!tls13_record_set_data(rl->wrec, data, data_len)) |
| 547 | goto err; | 665 | goto err; |
| 548 | 666 | ||
| 667 | rl->wrec_content_len = content_len; | ||
| 668 | rl->wrec_content_type = content_type; | ||
| 669 | |||
| 549 | data = NULL; | 670 | data = NULL; |
| 550 | data_len = 0; | 671 | data_len = 0; |
| 551 | 672 | ||
| @@ -673,12 +794,12 @@ tls13_record_layer_read(struct tls13_record_layer *rl, uint8_t content_type, | |||
| 673 | { | 794 | { |
| 674 | ssize_t ret; | 795 | ssize_t ret; |
| 675 | 796 | ||
| 797 | if ((ret = tls13_record_layer_send_pending(rl)) != TLS13_IO_SUCCESS) | ||
| 798 | return ret; | ||
| 799 | |||
| 676 | if (rl->read_closed) | 800 | if (rl->read_closed) |
| 677 | return TLS13_IO_EOF; | 801 | return TLS13_IO_EOF; |
| 678 | 802 | ||
| 679 | /* XXX - loop here with record and byte limits. */ | ||
| 680 | /* XXX - send alert... */ | ||
| 681 | |||
| 682 | /* If necessary, pull up the next record. */ | 803 | /* If necessary, pull up the next record. */ |
| 683 | if (CBS_len(&rl->rbuf_cbs) == 0) { | 804 | if (CBS_len(&rl->rbuf_cbs) == 0) { |
| 684 | if ((ret = tls13_record_layer_read_record(rl)) <= 0) | 805 | if ((ret = tls13_record_layer_read_record(rl)) <= 0) |
| @@ -737,16 +858,38 @@ tls13_record_layer_write_record(struct tls13_record_layer *rl, | |||
| 737 | if (rl->write_closed) | 858 | if (rl->write_closed) |
| 738 | return TLS13_IO_EOF; | 859 | return TLS13_IO_EOF; |
| 739 | 860 | ||
| 861 | /* | ||
| 862 | * If we pushed out application data while handling other messages, | ||
| 863 | * we need to return content length on the next call. | ||
| 864 | */ | ||
| 865 | if (content_type == SSL3_RT_APPLICATION_DATA && | ||
| 866 | rl->wrec_appdata_len != 0) { | ||
| 867 | ret = rl->wrec_appdata_len; | ||
| 868 | rl->wrec_appdata_len = 0; | ||
| 869 | return ret; | ||
| 870 | } | ||
| 871 | |||
| 740 | /* See if there is an existing record and attempt to push it out... */ | 872 | /* See if there is an existing record and attempt to push it out... */ |
| 741 | if (rl->wrec != NULL) { | 873 | if (rl->wrec != NULL) { |
| 742 | if ((ret = tls13_record_send(rl->wrec, rl->wire_write, | 874 | if ((ret = tls13_record_send(rl->wrec, rl->wire_write, |
| 743 | rl->cb_arg)) <= 0) | 875 | rl->cb_arg)) <= 0) |
| 744 | return ret; | 876 | return ret; |
| 745 | |||
| 746 | tls13_record_layer_wrec_free(rl); | 877 | tls13_record_layer_wrec_free(rl); |
| 747 | 878 | ||
| 748 | /* XXX - could be pushing out different data... */ | 879 | if (rl->wrec_content_type == content_type) { |
| 749 | return content_len; | 880 | ret = rl->wrec_content_len; |
| 881 | rl->wrec_content_len = 0; | ||
| 882 | rl->wrec_content_type = 0; | ||
| 883 | return ret; | ||
| 884 | } | ||
| 885 | |||
| 886 | /* | ||
| 887 | * The only partial record type should be application data. | ||
| 888 | * All other cases are handled to completion. | ||
| 889 | */ | ||
| 890 | if (rl->wrec_content_type != SSL3_RT_APPLICATION_DATA) | ||
| 891 | return TLS13_IO_FAILURE; | ||
| 892 | rl->wrec_appdata_len = rl->wrec_content_len; | ||
| 750 | } | 893 | } |
| 751 | 894 | ||
| 752 | if (content_len > TLS13_RECORD_MAX_PLAINTEXT_LEN) | 895 | if (content_len > TLS13_RECORD_MAX_PLAINTEXT_LEN) |
| @@ -767,8 +910,8 @@ tls13_record_layer_write_record(struct tls13_record_layer *rl, | |||
| 767 | } | 910 | } |
| 768 | 911 | ||
| 769 | static ssize_t | 912 | static ssize_t |
| 770 | tls13_record_layer_write(struct tls13_record_layer *rl, uint8_t content_type, | 913 | tls13_record_layer_write_chunk(struct tls13_record_layer *rl, |
| 771 | const uint8_t *buf, size_t n) | 914 | uint8_t content_type, const uint8_t *buf, size_t n) |
| 772 | { | 915 | { |
| 773 | if (n > TLS13_RECORD_MAX_PLAINTEXT_LEN) | 916 | if (n > TLS13_RECORD_MAX_PLAINTEXT_LEN) |
| 774 | n = TLS13_RECORD_MAX_PLAINTEXT_LEN; | 917 | n = TLS13_RECORD_MAX_PLAINTEXT_LEN; |
| @@ -776,6 +919,18 @@ tls13_record_layer_write(struct tls13_record_layer *rl, uint8_t content_type, | |||
| 776 | return tls13_record_layer_write_record(rl, content_type, buf, n); | 919 | return tls13_record_layer_write_record(rl, content_type, buf, n); |
| 777 | } | 920 | } |
| 778 | 921 | ||
| 922 | static ssize_t | ||
| 923 | tls13_record_layer_write(struct tls13_record_layer *rl, uint8_t content_type, | ||
| 924 | const uint8_t *buf, size_t n) | ||
| 925 | { | ||
| 926 | ssize_t ret; | ||
| 927 | |||
| 928 | if ((ret = tls13_record_layer_send_pending(rl)) != TLS13_IO_SUCCESS) | ||
| 929 | return ret; | ||
| 930 | |||
| 931 | return tls13_record_layer_write_chunk(rl, content_type, buf, n); | ||
| 932 | } | ||
| 933 | |||
| 779 | ssize_t | 934 | ssize_t |
| 780 | tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n) | 935 | tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n) |
| 781 | { | 936 | { |
