diff options
author | jsing <> | 2019-11-17 17:20:16 +0000 |
---|---|---|
committer | jsing <> | 2019-11-17 17:20:16 +0000 |
commit | 516efe2f49b299dbcb3e0e96afba993c37476db8 (patch) | |
tree | 35f5e41f42031e9a4701b5932269f219de6d35ba | |
parent | 1730c597e084e59232a8f9c312ac29a78c60a98a (diff) | |
download | openbsd-516efe2f49b299dbcb3e0e96afba993c37476db8.tar.gz openbsd-516efe2f49b299dbcb3e0e96afba993c37476db8.tar.bz2 openbsd-516efe2f49b299dbcb3e0e96afba993c37476db8.zip |
Provide framework for sending alerts and post-handshake handshake messages.
Discussed at length with beck@
ok beck@ tb@
-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 | { |