diff options
author | jsing <> | 2019-02-21 17:15:00 +0000 |
---|---|---|
committer | jsing <> | 2019-02-21 17:15:00 +0000 |
commit | e28bdf4c51aff3424107287d352cee238c14031c (patch) | |
tree | f4e2ad27f67cef2b56e97df4dc75aa1ffb23c1a0 /src | |
parent | c2747c010f47d9ef1447b26470fa7fb033c543c3 (diff) | |
download | openbsd-e28bdf4c51aff3424107287d352cee238c14031c.tar.gz openbsd-e28bdf4c51aff3424107287d352cee238c14031c.tar.bz2 openbsd-e28bdf4c51aff3424107287d352cee238c14031c.zip |
Wire up alert handling for TLSv1.3.
In TLSv1.3 there are two types of alerts "closure alerts" and
"error alerts". This makes the record layer more strict and handles closure
of the read and write channels. The callback then handles the record layer to
SSL mapping/behaviour.
ok tb@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/tls13_lib.c | 34 | ||||
-rw-r--r-- | src/lib/libssl/tls13_record_layer.c | 53 |
2 files changed, 78 insertions, 9 deletions
diff --git a/src/lib/libssl/tls13_lib.c b/src/lib/libssl/tls13_lib.c index 3860ddefef..f9505fa438 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.3 2019/01/21 13:45:57 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_lib.c,v 1.4 2019/02/21 17:15:00 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 | * |
@@ -61,6 +61,35 @@ tls13_cipher_hash(const SSL_CIPHER *cipher) | |||
61 | return NULL; | 61 | return NULL; |
62 | } | 62 | } |
63 | 63 | ||
64 | static void | ||
65 | tls13_alert_received_cb(uint8_t alert_level, uint8_t alert_desc, void *arg) | ||
66 | { | ||
67 | struct tls13_ctx *ctx = arg; | ||
68 | SSL *s = ctx->ssl; | ||
69 | |||
70 | if (alert_desc == SSL_AD_CLOSE_NOTIFY) { | ||
71 | ctx->ssl->internal->shutdown |= SSL_RECEIVED_SHUTDOWN; | ||
72 | S3I(ctx->ssl)->warn_alert = alert_desc; | ||
73 | return; | ||
74 | } | ||
75 | |||
76 | if (alert_desc == SSL_AD_USER_CANCELLED) { | ||
77 | /* | ||
78 | * We treat this as advisory, since a close_notify alert | ||
79 | * SHOULD follow this alert (RFC 8446 section 6.1). | ||
80 | */ | ||
81 | return; | ||
82 | } | ||
83 | |||
84 | /* All other alerts are treated as fatal in TLSv1.3. */ | ||
85 | S3I(ctx->ssl)->fatal_alert = alert_desc; | ||
86 | |||
87 | SSLerror(ctx->ssl, SSL_AD_REASON_OFFSET + alert_desc); | ||
88 | ERR_asprintf_error_data("SSL alert number %d", alert_desc); | ||
89 | |||
90 | SSL_CTX_remove_session(s->ctx, s->session); | ||
91 | } | ||
92 | |||
64 | struct tls13_ctx * | 93 | struct tls13_ctx * |
65 | tls13_ctx_new(int mode) | 94 | tls13_ctx_new(int mode) |
66 | { | 95 | { |
@@ -72,7 +101,8 @@ tls13_ctx_new(int mode) | |||
72 | ctx->mode = mode; | 101 | ctx->mode = mode; |
73 | 102 | ||
74 | if ((ctx->rl = tls13_record_layer_new(tls13_legacy_wire_read_cb, | 103 | if ((ctx->rl = tls13_record_layer_new(tls13_legacy_wire_read_cb, |
75 | tls13_legacy_wire_write_cb, NULL, NULL, ctx)) == NULL) | 104 | tls13_legacy_wire_write_cb, tls13_alert_received_cb, NULL, |
105 | ctx)) == NULL) | ||
76 | goto err; | 106 | goto err; |
77 | 107 | ||
78 | return ctx; | 108 | return ctx; |
diff --git a/src/lib/libssl/tls13_record_layer.c b/src/lib/libssl/tls13_record_layer.c index 8f6eb94df4..86062e387f 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.4 2019/02/21 17:09:51 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_record_layer.c,v 1.5 2019/02/21 17:15:00 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 | * |
@@ -26,6 +26,15 @@ struct tls13_record_layer { | |||
26 | int change_cipher_spec_seen; | 26 | int change_cipher_spec_seen; |
27 | int handshake_completed; | 27 | int handshake_completed; |
28 | 28 | ||
29 | /* | ||
30 | * Read and/or write channels are closed due to an alert being | ||
31 | * sent or received. In the case of an error alert both channels | ||
32 | * are closed, whereas in the case of a close notify only one | ||
33 | * channel is closed. | ||
34 | */ | ||
35 | int read_closed; | ||
36 | int write_closed; | ||
37 | |||
29 | struct tls13_record *rrec; | 38 | struct tls13_record *rrec; |
30 | struct tls13_record *wrec; | 39 | struct tls13_record *wrec; |
31 | 40 | ||
@@ -180,31 +189,55 @@ static ssize_t | |||
180 | tls13_record_layer_process_alert(struct tls13_record_layer *rl) | 189 | tls13_record_layer_process_alert(struct tls13_record_layer *rl) |
181 | { | 190 | { |
182 | uint8_t alert_level, alert_desc; | 191 | uint8_t alert_level, alert_desc; |
192 | ssize_t ret = TLS13_IO_FAILURE; | ||
183 | 193 | ||
184 | /* | 194 | /* |
195 | * RFC 8446 - sections 5.1 and 6. | ||
196 | * | ||
185 | * A TLSv1.3 alert record can only contain a single alert - this means | 197 | * A TLSv1.3 alert record can only contain a single alert - this means |
186 | * that processing the alert must consume all of the record. The alert | 198 | * that processing the alert must consume all of the record. The alert |
187 | * will result in one of three things - continuation (user_cancelled), | 199 | * will result in one of three things - continuation (user_cancelled), |
188 | * read channel closure (close_notify) or termination (all others). | 200 | * read channel closure (close_notify) or termination (all others). |
189 | */ | 201 | */ |
190 | if (rl->rbuf == NULL) | 202 | if (rl->rbuf == NULL) |
191 | return TLS13_IO_FAILURE; | 203 | goto err; |
192 | if (rl->rbuf_content_type != SSL3_RT_ALERT) | 204 | if (rl->rbuf_content_type != SSL3_RT_ALERT) |
193 | return TLS13_IO_FAILURE; | 205 | goto err; |
194 | 206 | ||
195 | if (!CBS_get_u8(&rl->rbuf_cbs, &alert_level)) | 207 | if (!CBS_get_u8(&rl->rbuf_cbs, &alert_level)) |
196 | return TLS13_IO_FAILURE; /* XXX - decode error alert. */ | 208 | goto err; /* XXX - decode error alert. */ |
197 | if (!CBS_get_u8(&rl->rbuf_cbs, &alert_desc)) | 209 | if (!CBS_get_u8(&rl->rbuf_cbs, &alert_desc)) |
198 | return TLS13_IO_FAILURE; /* XXX - decode error alert. */ | 210 | goto err; /* XXX - decode error alert. */ |
199 | 211 | ||
200 | if (CBS_len(&rl->rbuf_cbs) != 0) | 212 | if (CBS_len(&rl->rbuf_cbs) != 0) |
201 | return TLS13_IO_FAILURE; | 213 | goto err; /* XXX - decode error alert. */ |
202 | 214 | ||
203 | tls13_record_layer_rbuf_free(rl); | 215 | tls13_record_layer_rbuf_free(rl); |
204 | 216 | ||
217 | /* | ||
218 | * Alert level is ignored for closure alerts (RFC 8446 section 6.1), | ||
219 | * however for error alerts (RFC 8446 section 6.2), the alert level | ||
220 | * must be specified as fatal. | ||
221 | */ | ||
222 | if (alert_desc == SSL_AD_CLOSE_NOTIFY) { | ||
223 | rl->read_closed = 1; | ||
224 | ret = TLS13_IO_SUCCESS; | ||
225 | } else if (alert_desc == SSL_AD_USER_CANCELLED) { | ||
226 | /* Ignored at the record layer. */ | ||
227 | ret = TLS13_IO_SUCCESS; | ||
228 | } else if (alert_level == SSL3_AL_FATAL) { | ||
229 | rl->read_closed = 1; | ||
230 | rl->write_closed = 1; | ||
231 | ret = TLS13_IO_EOF; | ||
232 | } else { | ||
233 | /* XXX - decode error alert. */ | ||
234 | return TLS13_IO_FAILURE; | ||
235 | } | ||
236 | |||
205 | rl->alert_cb(alert_level, alert_desc, rl->cb_arg); | 237 | rl->alert_cb(alert_level, alert_desc, rl->cb_arg); |
206 | 238 | ||
207 | return TLS13_IO_SUCCESS; | 239 | err: |
240 | return ret; | ||
208 | } | 241 | } |
209 | 242 | ||
210 | int | 243 | int |
@@ -638,6 +671,9 @@ tls13_record_layer_read(struct tls13_record_layer *rl, uint8_t content_type, | |||
638 | { | 671 | { |
639 | ssize_t ret; | 672 | ssize_t ret; |
640 | 673 | ||
674 | if (rl->read_closed) | ||
675 | return TLS13_IO_EOF; | ||
676 | |||
641 | /* XXX - loop here with record and byte limits. */ | 677 | /* XXX - loop here with record and byte limits. */ |
642 | /* XXX - send alert... */ | 678 | /* XXX - send alert... */ |
643 | 679 | ||
@@ -692,6 +728,9 @@ tls13_record_layer_write_record(struct tls13_record_layer *rl, | |||
692 | { | 728 | { |
693 | ssize_t ret; | 729 | ssize_t ret; |
694 | 730 | ||
731 | if (rl->write_closed) | ||
732 | return TLS13_IO_EOF; | ||
733 | |||
695 | /* See if there is an existing record and attempt to push it out... */ | 734 | /* See if there is an existing record and attempt to push it out... */ |
696 | if (rl->wrec != NULL) { | 735 | if (rl->wrec != NULL) { |
697 | if ((ret = tls13_record_send(rl->wrec, rl->wire_write, | 736 | if ((ret = tls13_record_send(rl->wrec, rl->wire_write, |