diff options
author | jsing <> | 2019-04-04 16:53:57 +0000 |
---|---|---|
committer | jsing <> | 2019-04-04 16:53:57 +0000 |
commit | d61ab6dc79dc9489283d02320a56b12002dce985 (patch) | |
tree | b5bc127ec451e17e440fdd24c01d7da7109c87fc | |
parent | 4ee3e34310a4dd1cee5a12b0e0b222cbea806322 (diff) | |
download | openbsd-d61ab6dc79dc9489283d02320a56b12002dce985.tar.gz openbsd-d61ab6dc79dc9489283d02320a56b12002dce985.tar.bz2 openbsd-d61ab6dc79dc9489283d02320a56b12002dce985.zip |
Implement legacy fallback for the TLS 1.3 client.
If the Server Hello received indicates that the server did not negotiate
TLS 1.3, fallback to the original TLS client implementation.
ok bcook@, tb@
-rw-r--r-- | src/lib/libssl/tls13_client.c | 87 | ||||
-rw-r--r-- | src/lib/libssl/tls13_handshake.c | 5 | ||||
-rw-r--r-- | src/lib/libssl/tls13_internal.h | 3 |
3 files changed, 87 insertions, 8 deletions
diff --git a/src/lib/libssl/tls13_client.c b/src/lib/libssl/tls13_client.c index 5b4ecdb47d..1729401505 100644 --- a/src/lib/libssl/tls13_client.c +++ b/src/lib/libssl/tls13_client.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls13_client.c,v 1.14 2019/03/25 17:21:18 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_client.c,v 1.15 2019/04/04 16:53:57 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 | * |
@@ -81,12 +81,56 @@ tls13_legacy_connect(SSL *ssl) | |||
81 | 81 | ||
82 | S3I(ssl)->hs.state = SSL_ST_CONNECT; | 82 | S3I(ssl)->hs.state = SSL_ST_CONNECT; |
83 | 83 | ||
84 | if ((ret = tls13_connect(ctx)) == TLS13_IO_SUCCESS) | 84 | ret = tls13_connect(ctx); |
85 | if (ret == TLS13_IO_USE_LEGACY) | ||
86 | return ssl->method->internal->ssl_connect(ssl); | ||
87 | if (ret == TLS13_IO_SUCCESS) | ||
85 | S3I(ssl)->hs.state = SSL_ST_OK; | 88 | S3I(ssl)->hs.state = SSL_ST_OK; |
86 | 89 | ||
87 | return tls13_legacy_return_code(ssl, ret); | 90 | return tls13_legacy_return_code(ssl, ret); |
88 | } | 91 | } |
89 | 92 | ||
93 | int | ||
94 | tls13_use_legacy_client(struct tls13_ctx *ctx) | ||
95 | { | ||
96 | SSL *s = ctx->ssl; | ||
97 | CBS cbs; | ||
98 | |||
99 | s->method = tls_legacy_client_method(); | ||
100 | s->client_version = s->version = s->method->internal->max_version; | ||
101 | |||
102 | if (!ssl3_setup_init_buffer(s)) | ||
103 | goto err; | ||
104 | if (!ssl3_setup_buffers(s)) | ||
105 | goto err; | ||
106 | if (!ssl_init_wbio_buffer(s, 0)) | ||
107 | goto err; | ||
108 | |||
109 | if (s->bbio != s->wbio) | ||
110 | s->wbio = BIO_push(s->bbio, s->wbio); | ||
111 | |||
112 | if (!tls13_handshake_msg_content(ctx->hs_msg, &cbs)) | ||
113 | goto err; | ||
114 | |||
115 | if (!BUF_MEM_grow_clean(s->internal->init_buf, CBS_len(&cbs) + 4)) | ||
116 | goto err; | ||
117 | |||
118 | if (!CBS_write_bytes(&cbs, s->internal->init_buf->data + 4, | ||
119 | s->internal->init_buf->length - 4, NULL)) | ||
120 | goto err; | ||
121 | |||
122 | S3I(s)->tmp.reuse_message = 1; | ||
123 | S3I(s)->tmp.message_type = tls13_handshake_msg_type(ctx->hs_msg); | ||
124 | S3I(s)->tmp.message_size = CBS_len(&cbs); | ||
125 | |||
126 | S3I(s)->hs.state = SSL3_ST_CR_SRVR_HELLO_A; | ||
127 | |||
128 | return 1; | ||
129 | |||
130 | err: | ||
131 | return 0; | ||
132 | } | ||
133 | |||
90 | static int | 134 | static int |
91 | tls13_client_hello_build(SSL *s, CBB *cbb) | 135 | tls13_client_hello_build(SSL *s, CBB *cbb) |
92 | { | 136 | { |
@@ -156,6 +200,35 @@ static const uint8_t tls13_hello_retry_request_hash[] = { | |||
156 | }; | 200 | }; |
157 | 201 | ||
158 | static int | 202 | static int |
203 | tls13_server_hello_is_legacy(CBS *cbs) | ||
204 | { | ||
205 | CBS extensions_block, extensions, extension_data; | ||
206 | uint16_t selected_version = 0; | ||
207 | uint16_t type; | ||
208 | |||
209 | CBS_dup(cbs, &extensions_block); | ||
210 | |||
211 | if (!CBS_get_u16_length_prefixed(&extensions_block, &extensions)) | ||
212 | return 1; | ||
213 | |||
214 | while (CBS_len(&extensions) > 0) { | ||
215 | if (!CBS_get_u16(&extensions, &type)) | ||
216 | return 1; | ||
217 | if (!CBS_get_u16_length_prefixed(&extensions, &extension_data)) | ||
218 | return 1; | ||
219 | |||
220 | if (type != TLSEXT_TYPE_supported_versions) | ||
221 | continue; | ||
222 | if (!CBS_get_u16(&extension_data, &selected_version)) | ||
223 | return 1; | ||
224 | if (CBS_len(&extension_data) != 0) | ||
225 | return 1; | ||
226 | } | ||
227 | |||
228 | return (selected_version < TLS1_3_VERSION); | ||
229 | } | ||
230 | |||
231 | static int | ||
159 | tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs) | 232 | tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs) |
160 | { | 233 | { |
161 | CBS server_random, session_id; | 234 | CBS server_random, session_id; |
@@ -176,6 +249,9 @@ tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs) | |||
176 | if (!CBS_get_u8(cbs, &compression_method)) | 249 | if (!CBS_get_u8(cbs, &compression_method)) |
177 | goto err; | 250 | goto err; |
178 | 251 | ||
252 | if (tls13_server_hello_is_legacy(cbs)) | ||
253 | return tls13_use_legacy_client(ctx); | ||
254 | |||
179 | if (!tlsext_client_parse(s, cbs, &alert, SSL_TLSEXT_MSG_SH)) | 255 | if (!tlsext_client_parse(s, cbs, &alert, SSL_TLSEXT_MSG_SH)) |
180 | goto err; | 256 | goto err; |
181 | 257 | ||
@@ -259,10 +335,9 @@ tls13_server_hello_recv(struct tls13_ctx *ctx) | |||
259 | if (!tls13_server_hello_process(ctx, &cbs)) | 335 | if (!tls13_server_hello_process(ctx, &cbs)) |
260 | goto err; | 336 | goto err; |
261 | 337 | ||
262 | if (ctx->hs->server_version < TLS1_3_VERSION) { | 338 | /* See if we switched back to the legacy client method. */ |
263 | /* XXX - switch back to legacy client. */ | 339 | if (s->method->internal->version < TLS1_3_VERSION) |
264 | goto err; | 340 | return 1; |
265 | } | ||
266 | 341 | ||
267 | if (ctx->handshake_stage.hs_type & WITH_HRR) | 342 | if (ctx->handshake_stage.hs_type & WITH_HRR) |
268 | return 1; | 343 | return 1; |
diff --git a/src/lib/libssl/tls13_handshake.c b/src/lib/libssl/tls13_handshake.c index a55c20525a..cb39974da5 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.32 2019/03/17 15:48:02 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_handshake.c,v 1.33 2019/04/04 16:53:57 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2018-2019 Theo Buehler <tb@openbsd.org> | 3 | * Copyright (c) 2018-2019 Theo Buehler <tb@openbsd.org> |
4 | * Copyright (c) 2019 Joel Sing <jsing@openbsd.org> | 4 | * Copyright (c) 2019 Joel Sing <jsing@openbsd.org> |
@@ -389,6 +389,9 @@ tls13_handshake_recv_action(struct tls13_ctx *ctx, | |||
389 | tls13_handshake_msg_free(ctx->hs_msg); | 389 | tls13_handshake_msg_free(ctx->hs_msg); |
390 | ctx->hs_msg = NULL; | 390 | ctx->hs_msg = NULL; |
391 | 391 | ||
392 | if (ctx->ssl->method->internal->version < TLS1_3_VERSION) | ||
393 | return TLS13_IO_USE_LEGACY; | ||
394 | |||
392 | return ret; | 395 | return ret; |
393 | } | 396 | } |
394 | 397 | ||
diff --git a/src/lib/libssl/tls13_internal.h b/src/lib/libssl/tls13_internal.h index 1fe8f547a1..c9ef37a39f 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.26 2019/03/17 15:13:23 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_internal.h,v 1.27 2019/04/04 16:53:57 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> |
@@ -35,6 +35,7 @@ __BEGIN_HIDDEN_DECLS | |||
35 | #define TLS13_IO_FAILURE -1 | 35 | #define TLS13_IO_FAILURE -1 |
36 | #define TLS13_IO_WANT_POLLIN -2 | 36 | #define TLS13_IO_WANT_POLLIN -2 |
37 | #define TLS13_IO_WANT_POLLOUT -3 | 37 | #define TLS13_IO_WANT_POLLOUT -3 |
38 | #define TLS13_IO_USE_LEGACY -4 | ||
38 | 39 | ||
39 | typedef void (*tls13_alert_cb)(uint8_t _alert_desc, void *_cb_arg); | 40 | typedef void (*tls13_alert_cb)(uint8_t _alert_desc, void *_cb_arg); |
40 | typedef int (*tls13_post_handshake_cb)(void *_cb_arg); | 41 | typedef int (*tls13_post_handshake_cb)(void *_cb_arg); |