diff options
author | jsing <> | 2020-01-22 01:02:28 +0000 |
---|---|---|
committer | jsing <> | 2020-01-22 01:02:28 +0000 |
commit | d2535f6d6c56956061dc8da2a8a2bfdd6b98a0a4 (patch) | |
tree | 8f321cdd5e9030d317130115bbb253896e4ea0f2 /src | |
parent | 6e568c664abbc564bc3a97d549d37155632d79a5 (diff) | |
download | openbsd-d2535f6d6c56956061dc8da2a8a2bfdd6b98a0a4.tar.gz openbsd-d2535f6d6c56956061dc8da2a8a2bfdd6b98a0a4.tar.bz2 openbsd-d2535f6d6c56956061dc8da2a8a2bfdd6b98a0a4.zip |
Implement close-notify and SSL_shutdown() handling for the TLSv1.3 client.
ok beck@ inoguchi@ tb@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/tls13_internal.h | 7 | ||||
-rw-r--r-- | src/lib/libssl/tls13_lib.c | 52 | ||||
-rw-r--r-- | src/lib/libssl/tls13_record_layer.c | 26 |
3 files changed, 76 insertions, 9 deletions
diff --git a/src/lib/libssl/tls13_internal.h b/src/lib/libssl/tls13_internal.h index 3ee73782ec..7fee37f5dd 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.39 2020/01/21 12:08:04 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_internal.h,v 1.40 2020/01/22 01:02:28 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> |
@@ -126,6 +126,7 @@ int tls13_record_layer_set_read_traffic_key(struct tls13_record_layer *rl, | |||
126 | struct tls13_secret *read_key); | 126 | struct tls13_secret *read_key); |
127 | int tls13_record_layer_set_write_traffic_key(struct tls13_record_layer *rl, | 127 | int tls13_record_layer_set_write_traffic_key(struct tls13_record_layer *rl, |
128 | struct tls13_secret *write_key); | 128 | struct tls13_secret *write_key); |
129 | ssize_t tls13_record_layer_send_pending(struct tls13_record_layer *rl); | ||
129 | ssize_t tls13_record_layer_phh(struct tls13_record_layer *rl, CBS *cbs); | 130 | ssize_t tls13_record_layer_phh(struct tls13_record_layer *rl, CBS *cbs); |
130 | 131 | ||
131 | ssize_t tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n); | 132 | ssize_t tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n); |
@@ -181,6 +182,9 @@ struct tls13_ctx { | |||
181 | struct tls13_handshake_stage handshake_stage; | 182 | struct tls13_handshake_stage handshake_stage; |
182 | int handshake_completed; | 183 | int handshake_completed; |
183 | 184 | ||
185 | int close_notify_sent; | ||
186 | int close_notify_recv; | ||
187 | |||
184 | const EVP_AEAD *aead; | 188 | const EVP_AEAD *aead; |
185 | const EVP_MD *hash; | 189 | const EVP_MD *hash; |
186 | 190 | ||
@@ -215,6 +219,7 @@ ssize_t tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg); | |||
215 | int tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, | 219 | int tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, |
216 | int peek); | 220 | int peek); |
217 | int tls13_legacy_write_bytes(SSL *ssl, int type, const void *buf, int len); | 221 | int tls13_legacy_write_bytes(SSL *ssl, int type, const void *buf, int len); |
222 | int tls13_legacy_shutdown(SSL *ssl); | ||
218 | 223 | ||
219 | /* | 224 | /* |
220 | * Message Types - RFC 8446, Section B.3. | 225 | * Message Types - RFC 8446, Section B.3. |
diff --git a/src/lib/libssl/tls13_lib.c b/src/lib/libssl/tls13_lib.c index 451e798cb8..bb749a9b68 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.16 2020/01/21 05:19:02 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_lib.c,v 1.17 2020/01/22 01:02:28 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> |
@@ -69,6 +69,7 @@ tls13_alert_received_cb(uint8_t alert_desc, void *arg) | |||
69 | SSL *s = ctx->ssl; | 69 | SSL *s = ctx->ssl; |
70 | 70 | ||
71 | if (alert_desc == SSL_AD_CLOSE_NOTIFY) { | 71 | if (alert_desc == SSL_AD_CLOSE_NOTIFY) { |
72 | ctx->close_notify_recv = 1; | ||
72 | ctx->ssl->internal->shutdown |= SSL_RECEIVED_SHUTDOWN; | 73 | ctx->ssl->internal->shutdown |= SSL_RECEIVED_SHUTDOWN; |
73 | S3I(ctx->ssl)->warn_alert = alert_desc; | 74 | S3I(ctx->ssl)->warn_alert = alert_desc; |
74 | return; | 75 | return; |
@@ -482,3 +483,52 @@ tls13_legacy_write_bytes(SSL *ssl, int type, const void *vbuf, int len) | |||
482 | n -= ret; | 483 | n -= ret; |
483 | } | 484 | } |
484 | } | 485 | } |
486 | |||
487 | int | ||
488 | tls13_legacy_shutdown(SSL *ssl) | ||
489 | { | ||
490 | struct tls13_ctx *ctx = ssl->internal->tls13; | ||
491 | uint8_t buf[512]; /* XXX */ | ||
492 | ssize_t ret; | ||
493 | |||
494 | /* | ||
495 | * We need to return 0 when we have sent a close-notify but have not | ||
496 | * yet received one. We return 1 only once we have sent and received | ||
497 | * close-notify alerts. All other cases return -1 and set internal | ||
498 | * state appropriately. | ||
499 | */ | ||
500 | if (ctx == NULL || ssl->internal->quiet_shutdown) { | ||
501 | ssl->internal->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN; | ||
502 | return 1; | ||
503 | } | ||
504 | |||
505 | /* Send close notify. */ | ||
506 | if (!ctx->close_notify_sent) { | ||
507 | ctx->close_notify_sent = 1; | ||
508 | if ((ret = tls13_send_alert(ctx->rl, SSL_AD_CLOSE_NOTIFY)) < 0) | ||
509 | return tls13_legacy_return_code(ssl, ret); | ||
510 | } | ||
511 | |||
512 | /* Ensure close notify has been sent. */ | ||
513 | if ((ret = tls13_record_layer_send_pending(ctx->rl)) != TLS13_IO_SUCCESS) | ||
514 | return tls13_legacy_return_code(ssl, ret); | ||
515 | |||
516 | /* Receive close notify. */ | ||
517 | if (!ctx->close_notify_recv) { | ||
518 | /* | ||
519 | * If there is still application data pending then we have no | ||
520 | * option but to discard it here. The application should have | ||
521 | * continued to call SSL_read() instead of SSL_shutdown(). | ||
522 | */ | ||
523 | /* XXX - tls13_drain_application_data()? */ | ||
524 | if ((ret = tls13_read_application_data(ctx->rl, buf, sizeof(buf))) > 0) | ||
525 | ret = TLS13_IO_WANT_POLLIN; | ||
526 | if (ret != TLS13_IO_EOF) | ||
527 | return tls13_legacy_return_code(ssl, ret); | ||
528 | } | ||
529 | |||
530 | if (ctx->close_notify_recv) | ||
531 | return 1; | ||
532 | |||
533 | return 0; | ||
534 | } | ||
diff --git a/src/lib/libssl/tls13_record_layer.c b/src/lib/libssl/tls13_record_layer.c index a6b00a83b3..dff5cd2bbe 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.18 2020/01/21 12:08:04 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_record_layer.c,v 1.19 2020/01/22 01:02:28 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 | * |
@@ -51,6 +51,8 @@ struct tls13_record_layer { | |||
51 | /* Pending alert messages. */ | 51 | /* Pending alert messages. */ |
52 | uint8_t *alert_data; | 52 | uint8_t *alert_data; |
53 | size_t alert_len; | 53 | size_t alert_len; |
54 | uint8_t alert_level; | ||
55 | uint8_t alert_desc; | ||
54 | 56 | ||
55 | /* Pending post-handshake handshake messages (RFC 8446, section 4.6). */ | 57 | /* Pending post-handshake handshake messages (RFC 8446, section 4.6). */ |
56 | CBS phh_cbs; | 58 | CBS phh_cbs; |
@@ -281,12 +283,19 @@ tls13_record_layer_send_alert(struct tls13_record_layer *rl) | |||
281 | rl->alert_data = NULL; | 283 | rl->alert_data = NULL; |
282 | rl->alert_len = 0; | 284 | rl->alert_len = 0; |
283 | 285 | ||
284 | /* XXX - only close write channel when sending close notify. */ | 286 | if (rl->alert_desc == SSL_AD_CLOSE_NOTIFY) { |
285 | rl->read_closed = 1; | 287 | rl->write_closed = 1; |
286 | rl->write_closed = 1; | 288 | ret = TLS13_IO_SUCCESS; |
289 | } else if (rl->alert_desc == SSL_AD_USER_CANCELLED) { | ||
290 | /* Ignored at the record layer. */ | ||
291 | ret = TLS13_IO_SUCCESS; | ||
292 | } else { | ||
293 | rl->read_closed = 1; | ||
294 | rl->write_closed = 1; | ||
295 | ret = TLS13_IO_SUCCESS; /* XXX - ALERT? */ | ||
296 | } | ||
287 | 297 | ||
288 | /* XXX - we may want a TLS13_IO_ALERT (or handle as errors). */ | 298 | return ret; |
289 | return TLS13_IO_FAILURE; | ||
290 | } | 299 | } |
291 | 300 | ||
292 | static ssize_t | 301 | static ssize_t |
@@ -314,7 +323,7 @@ tls13_record_layer_send_phh(struct tls13_record_layer *rl) | |||
314 | return TLS13_IO_SUCCESS; | 323 | return TLS13_IO_SUCCESS; |
315 | } | 324 | } |
316 | 325 | ||
317 | static ssize_t | 326 | ssize_t |
318 | tls13_record_layer_send_pending(struct tls13_record_layer *rl) | 327 | tls13_record_layer_send_pending(struct tls13_record_layer *rl) |
319 | { | 328 | { |
320 | /* | 329 | /* |
@@ -354,6 +363,9 @@ tls13_record_layer_alert(struct tls13_record_layer *rl, | |||
354 | if (!CBB_finish(&cbb, &rl->alert_data, &rl->alert_len)) | 363 | if (!CBB_finish(&cbb, &rl->alert_data, &rl->alert_len)) |
355 | goto err; | 364 | goto err; |
356 | 365 | ||
366 | rl->alert_level = alert_level; | ||
367 | rl->alert_desc = alert_desc; | ||
368 | |||
357 | return tls13_record_layer_send_pending(rl); | 369 | return tls13_record_layer_send_pending(rl); |
358 | 370 | ||
359 | err: | 371 | err: |