diff options
author | jsing <> | 2021-09-16 19:25:30 +0000 |
---|---|---|
committer | jsing <> | 2021-09-16 19:25:30 +0000 |
commit | 2d955253865a6015861bd8fe88e65001b0fcf007 (patch) | |
tree | 721c70e4e05fb8482881613ba81112e77e594f1e | |
parent | a490f30feab724ed170f288710f349bf893262b4 (diff) | |
download | openbsd-2d955253865a6015861bd8fe88e65001b0fcf007.tar.gz openbsd-2d955253865a6015861bd8fe88e65001b0fcf007.tar.bz2 openbsd-2d955253865a6015861bd8fe88e65001b0fcf007.zip |
Implement flushing for TLSv1.3 handshakes.
When we finish sending a flight of records, flush the record layer output.
This effectively means calling BIO_flush() on the wbio.
Some things (such as apache2) have custom BIOs that perform buffering and
do not actually send on BIO_write(). Without BIO_flush() the server thinks
it has sent data and starts receiving records, however the client never
sends records since it never received those that the server should have
sent.
Joint work with tb@
ok tb@
-rw-r--r-- | src/lib/libssl/tls13_handshake.c | 32 | ||||
-rw-r--r-- | src/lib/libssl/tls13_internal.h | 7 | ||||
-rw-r--r-- | src/lib/libssl/tls13_legacy.c | 26 | ||||
-rw-r--r-- | src/lib/libssl/tls13_lib.c | 3 | ||||
-rw-r--r-- | src/lib/libssl/tls13_record_layer.c | 8 |
5 files changed, 69 insertions, 7 deletions
diff --git a/src/lib/libssl/tls13_handshake.c b/src/lib/libssl/tls13_handshake.c index 310a2116b8..cca8560fc2 100644 --- a/src/lib/libssl/tls13_handshake.c +++ b/src/lib/libssl/tls13_handshake.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls13_handshake.c,v 1.69 2021/07/01 17:53:39 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_handshake.c,v 1.70 2021/09/16 19:25:30 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2018-2021 Theo Buehler <tb@openbsd.org> | 3 | * Copyright (c) 2018-2021 Theo Buehler <tb@openbsd.org> |
4 | * Copyright (c) 2019 Joel Sing <jsing@openbsd.org> | 4 | * Copyright (c) 2019 Joel Sing <jsing@openbsd.org> |
@@ -331,6 +331,18 @@ tls13_handshake_advance_state_machine(struct tls13_ctx *ctx) | |||
331 | return 1; | 331 | return 1; |
332 | } | 332 | } |
333 | 333 | ||
334 | static int | ||
335 | tls13_handshake_end_of_flight(struct tls13_ctx *ctx, | ||
336 | const struct tls13_handshake_action *previous) | ||
337 | { | ||
338 | const struct tls13_handshake_action *current; | ||
339 | |||
340 | if ((current = tls13_handshake_active_action(ctx)) == NULL) | ||
341 | return 1; | ||
342 | |||
343 | return current->sender != previous->sender; | ||
344 | } | ||
345 | |||
334 | int | 346 | int |
335 | tls13_handshake_msg_record(struct tls13_ctx *ctx) | 347 | tls13_handshake_msg_record(struct tls13_ctx *ctx) |
336 | { | 348 | { |
@@ -344,6 +356,7 @@ int | |||
344 | tls13_handshake_perform(struct tls13_ctx *ctx) | 356 | tls13_handshake_perform(struct tls13_ctx *ctx) |
345 | { | 357 | { |
346 | const struct tls13_handshake_action *action; | 358 | const struct tls13_handshake_action *action; |
359 | int sending; | ||
347 | int ret; | 360 | int ret; |
348 | 361 | ||
349 | if (!ctx->handshake_started) { | 362 | if (!ctx->handshake_started) { |
@@ -367,6 +380,13 @@ tls13_handshake_perform(struct tls13_ctx *ctx) | |||
367 | if ((action = tls13_handshake_active_action(ctx)) == NULL) | 380 | if ((action = tls13_handshake_active_action(ctx)) == NULL) |
368 | return TLS13_IO_FAILURE; | 381 | return TLS13_IO_FAILURE; |
369 | 382 | ||
383 | if (ctx->need_flush) { | ||
384 | if ((ret = tls13_record_layer_flush(ctx->rl)) != | ||
385 | TLS13_IO_SUCCESS) | ||
386 | return ret; | ||
387 | ctx->need_flush = 0; | ||
388 | } | ||
389 | |||
370 | if (action->handshake_complete) { | 390 | if (action->handshake_complete) { |
371 | ctx->handshake_completed = 1; | 391 | ctx->handshake_completed = 1; |
372 | tls13_record_layer_handshake_completed(ctx->rl); | 392 | tls13_record_layer_handshake_completed(ctx->rl); |
@@ -379,14 +399,16 @@ tls13_handshake_perform(struct tls13_ctx *ctx) | |||
379 | return TLS13_IO_SUCCESS; | 399 | return TLS13_IO_SUCCESS; |
380 | } | 400 | } |
381 | 401 | ||
402 | sending = action->sender == ctx->mode; | ||
403 | |||
382 | DEBUGF("%s %s %s\n", tls13_handshake_mode_name(ctx->mode), | 404 | DEBUGF("%s %s %s\n", tls13_handshake_mode_name(ctx->mode), |
383 | (action->sender == ctx->mode) ? "sending" : "receiving", | 405 | sending ? "sending" : "receiving", |
384 | tls13_handshake_message_name(action->handshake_type)); | 406 | tls13_handshake_message_name(action->handshake_type)); |
385 | 407 | ||
386 | if (ctx->alert != 0) | 408 | if (ctx->alert != 0) |
387 | return tls13_send_alert(ctx->rl, ctx->alert); | 409 | return tls13_send_alert(ctx->rl, ctx->alert); |
388 | 410 | ||
389 | if (action->sender == ctx->mode) | 411 | if (sending) |
390 | ret = tls13_handshake_send_action(ctx, action); | 412 | ret = tls13_handshake_send_action(ctx, action); |
391 | else | 413 | else |
392 | ret = tls13_handshake_recv_action(ctx, action); | 414 | ret = tls13_handshake_recv_action(ctx, action); |
@@ -408,6 +430,10 @@ tls13_handshake_perform(struct tls13_ctx *ctx) | |||
408 | if (!tls13_handshake_advance_state_machine(ctx)) | 430 | if (!tls13_handshake_advance_state_machine(ctx)) |
409 | return TLS13_IO_FAILURE; | 431 | return TLS13_IO_FAILURE; |
410 | 432 | ||
433 | if (sending) | ||
434 | ctx->need_flush = tls13_handshake_end_of_flight(ctx, | ||
435 | action); | ||
436 | |||
411 | if (!tls13_handshake_set_legacy_state(ctx)) | 437 | if (!tls13_handshake_set_legacy_state(ctx)) |
412 | return TLS13_IO_FAILURE; | 438 | return TLS13_IO_FAILURE; |
413 | } | 439 | } |
diff --git a/src/lib/libssl/tls13_internal.h b/src/lib/libssl/tls13_internal.h index cb59634edc..20cb52ebdd 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.93 2021/09/14 14:35:09 tb Exp $ */ | 1 | /* $OpenBSD: tls13_internal.h,v 1.94 2021/09/16 19:25:30 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> |
@@ -92,6 +92,7 @@ typedef void (*tls13_phh_sent_cb)(void *_cb_arg); | |||
92 | typedef ssize_t (*tls13_read_cb)(void *_buf, size_t _buflen, void *_cb_arg); | 92 | typedef ssize_t (*tls13_read_cb)(void *_buf, size_t _buflen, void *_cb_arg); |
93 | typedef ssize_t (*tls13_write_cb)(const void *_buf, size_t _buflen, | 93 | typedef ssize_t (*tls13_write_cb)(const void *_buf, size_t _buflen, |
94 | void *_cb_arg); | 94 | void *_cb_arg); |
95 | typedef ssize_t (*tls13_flush_cb)(void *_cb_arg); | ||
95 | typedef void (*tls13_handshake_message_cb)(void *_cb_arg); | 96 | typedef void (*tls13_handshake_message_cb)(void *_cb_arg); |
96 | typedef void (*tls13_info_cb)(void *_cb_arg, int _state, int _ret); | 97 | typedef void (*tls13_info_cb)(void *_cb_arg, int _state, int _ret); |
97 | typedef int (*tls13_ocsp_status_cb)(void *_cb_arg); | 98 | typedef int (*tls13_ocsp_status_cb)(void *_cb_arg); |
@@ -200,6 +201,7 @@ struct tls13_record_layer; | |||
200 | struct tls13_record_layer_callbacks { | 201 | struct tls13_record_layer_callbacks { |
201 | tls13_read_cb wire_read; | 202 | tls13_read_cb wire_read; |
202 | tls13_write_cb wire_write; | 203 | tls13_write_cb wire_write; |
204 | tls13_flush_cb wire_flush; | ||
203 | tls13_alert_cb alert_recv; | 205 | tls13_alert_cb alert_recv; |
204 | tls13_alert_cb alert_sent; | 206 | tls13_alert_cb alert_sent; |
205 | tls13_phh_recv_cb phh_recv; | 207 | tls13_phh_recv_cb phh_recv; |
@@ -226,6 +228,7 @@ int tls13_record_layer_set_write_traffic_key(struct tls13_record_layer *rl, | |||
226 | struct tls13_secret *write_key); | 228 | struct tls13_secret *write_key); |
227 | ssize_t tls13_record_layer_send_pending(struct tls13_record_layer *rl); | 229 | ssize_t tls13_record_layer_send_pending(struct tls13_record_layer *rl); |
228 | ssize_t tls13_record_layer_phh(struct tls13_record_layer *rl, CBS *cbs); | 230 | ssize_t tls13_record_layer_phh(struct tls13_record_layer *rl, CBS *cbs); |
231 | ssize_t tls13_record_layer_flush(struct tls13_record_layer *rl); | ||
229 | 232 | ||
230 | ssize_t tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n); | 233 | ssize_t tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n); |
231 | ssize_t tls13_write_handshake_data(struct tls13_record_layer *rl, const uint8_t *buf, | 234 | ssize_t tls13_write_handshake_data(struct tls13_record_layer *rl, const uint8_t *buf, |
@@ -283,6 +286,7 @@ struct tls13_ctx { | |||
283 | struct tls13_handshake_stage handshake_stage; | 286 | struct tls13_handshake_stage handshake_stage; |
284 | int handshake_started; | 287 | int handshake_started; |
285 | int handshake_completed; | 288 | int handshake_completed; |
289 | int need_flush; | ||
286 | int middlebox_compat; | 290 | int middlebox_compat; |
287 | int send_dummy_ccs; | 291 | int send_dummy_ccs; |
288 | int send_dummy_ccs_after; | 292 | int send_dummy_ccs_after; |
@@ -328,6 +332,7 @@ int tls13_legacy_connect(SSL *ssl); | |||
328 | int tls13_legacy_return_code(SSL *ssl, ssize_t ret); | 332 | int tls13_legacy_return_code(SSL *ssl, ssize_t ret); |
329 | ssize_t tls13_legacy_wire_read_cb(void *buf, size_t n, void *arg); | 333 | ssize_t tls13_legacy_wire_read_cb(void *buf, size_t n, void *arg); |
330 | ssize_t tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg); | 334 | ssize_t tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg); |
335 | ssize_t tls13_legacy_wire_flush_cb(void *arg); | ||
331 | int tls13_legacy_pending(const SSL *ssl); | 336 | int tls13_legacy_pending(const SSL *ssl); |
332 | int tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, | 337 | int tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, |
333 | int peek); | 338 | int peek); |
diff --git a/src/lib/libssl/tls13_legacy.c b/src/lib/libssl/tls13_legacy.c index 3368600c60..f668dd4ea3 100644 --- a/src/lib/libssl/tls13_legacy.c +++ b/src/lib/libssl/tls13_legacy.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls13_legacy.c,v 1.30 2021/09/14 14:31:21 tb Exp $ */ | 1 | /* $OpenBSD: tls13_legacy.c,v 1.31 2021/09/16 19:25:30 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 | * |
@@ -96,6 +96,30 @@ tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg) | |||
96 | return tls13_legacy_wire_write(ctx->ssl, buf, n); | 96 | return tls13_legacy_wire_write(ctx->ssl, buf, n); |
97 | } | 97 | } |
98 | 98 | ||
99 | static ssize_t | ||
100 | tls13_legacy_wire_flush(SSL *ssl) | ||
101 | { | ||
102 | if (BIO_flush(ssl->wbio) <= 0) { | ||
103 | if (BIO_should_write(ssl->wbio)) | ||
104 | return TLS13_IO_WANT_POLLOUT; | ||
105 | |||
106 | if (ERR_peek_error() == 0 && errno != 0) | ||
107 | SYSerror(errno); | ||
108 | |||
109 | return TLS13_IO_FAILURE; | ||
110 | } | ||
111 | |||
112 | return TLS13_IO_SUCCESS; | ||
113 | } | ||
114 | |||
115 | ssize_t | ||
116 | tls13_legacy_wire_flush_cb(void *arg) | ||
117 | { | ||
118 | struct tls13_ctx *ctx = arg; | ||
119 | |||
120 | return tls13_legacy_wire_flush(ctx->ssl); | ||
121 | } | ||
122 | |||
99 | static void | 123 | static void |
100 | tls13_legacy_error(SSL *ssl) | 124 | tls13_legacy_error(SSL *ssl) |
101 | { | 125 | { |
diff --git a/src/lib/libssl/tls13_lib.c b/src/lib/libssl/tls13_lib.c index 6615efc4d2..1a9596adca 100644 --- a/src/lib/libssl/tls13_lib.c +++ b/src/lib/libssl/tls13_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls13_lib.c,v 1.61 2021/09/02 11:58:30 beck Exp $ */ | 1 | /* $OpenBSD: tls13_lib.c,v 1.62 2021/09/16 19:25:30 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 | * Copyright (c) 2019 Bob Beck <beck@openbsd.org> | 4 | * Copyright (c) 2019 Bob Beck <beck@openbsd.org> |
@@ -374,6 +374,7 @@ tls13_phh_received_cb(void *cb_arg, CBS *cbs) | |||
374 | static const struct tls13_record_layer_callbacks rl_callbacks = { | 374 | static const struct tls13_record_layer_callbacks rl_callbacks = { |
375 | .wire_read = tls13_legacy_wire_read_cb, | 375 | .wire_read = tls13_legacy_wire_read_cb, |
376 | .wire_write = tls13_legacy_wire_write_cb, | 376 | .wire_write = tls13_legacy_wire_write_cb, |
377 | .wire_flush = tls13_legacy_wire_flush_cb, | ||
377 | .alert_recv = tls13_alert_received_cb, | 378 | .alert_recv = tls13_alert_received_cb, |
378 | .alert_sent = tls13_alert_sent_cb, | 379 | .alert_sent = tls13_alert_sent_cb, |
379 | .phh_recv = tls13_phh_received_cb, | 380 | .phh_recv = tls13_phh_received_cb, |
diff --git a/src/lib/libssl/tls13_record_layer.c b/src/lib/libssl/tls13_record_layer.c index 2e32cb8a37..6b9f5d1419 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.63 2021/09/04 16:26:12 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_record_layer.c,v 1.64 2021/09/16 19:25:30 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 | * |
@@ -1096,6 +1096,12 @@ tls13_record_layer_write(struct tls13_record_layer *rl, uint8_t content_type, | |||
1096 | return ret; | 1096 | return ret; |
1097 | } | 1097 | } |
1098 | 1098 | ||
1099 | ssize_t | ||
1100 | tls13_record_layer_flush(struct tls13_record_layer *rl) | ||
1101 | { | ||
1102 | return rl->cb.wire_flush(rl->cb_arg); | ||
1103 | } | ||
1104 | |||
1099 | static const uint8_t tls13_dummy_ccs[] = { 0x01 }; | 1105 | static const uint8_t tls13_dummy_ccs[] = { 0x01 }; |
1100 | 1106 | ||
1101 | ssize_t | 1107 | ssize_t |