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 /src/lib/libssl/tls13_client.c | |
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@
Diffstat (limited to 'src/lib/libssl/tls13_client.c')
-rw-r--r-- | src/lib/libssl/tls13_client.c | 87 |
1 files changed, 81 insertions, 6 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; |