summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2019-04-04 16:53:57 +0000
committerjsing <>2019-04-04 16:53:57 +0000
commitd61ab6dc79dc9489283d02320a56b12002dce985 (patch)
treeb5bc127ec451e17e440fdd24c01d7da7109c87fc
parent4ee3e34310a4dd1cee5a12b0e0b222cbea806322 (diff)
downloadopenbsd-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.c87
-rw-r--r--src/lib/libssl/tls13_handshake.c5
-rw-r--r--src/lib/libssl/tls13_internal.h3
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
93int
94tls13_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
90static int 134static int
91tls13_client_hello_build(SSL *s, CBB *cbb) 135tls13_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
158static int 202static int
203tls13_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
231static int
159tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs) 232tls13_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
39typedef void (*tls13_alert_cb)(uint8_t _alert_desc, void *_cb_arg); 40typedef void (*tls13_alert_cb)(uint8_t _alert_desc, void *_cb_arg);
40typedef int (*tls13_post_handshake_cb)(void *_cb_arg); 41typedef int (*tls13_post_handshake_cb)(void *_cb_arg);