diff options
author | jsing <> | 2020-01-22 15:47:22 +0000 |
---|---|---|
committer | jsing <> | 2020-01-22 15:47:22 +0000 |
commit | 10c7e6c36bf0dc3cca36f953f4d1a51e178aa2de (patch) | |
tree | 1108aa572ec1515fb5e57ca2cad76f6f6230b16c | |
parent | 7655835d7e1b8fa812246e1e652a1747a4f67b32 (diff) | |
download | openbsd-10c7e6c36bf0dc3cca36f953f4d1a51e178aa2de.tar.gz openbsd-10c7e6c36bf0dc3cca36f953f4d1a51e178aa2de.tar.bz2 openbsd-10c7e6c36bf0dc3cca36f953f4d1a51e178aa2de.zip |
Wire up the TLSv1.3 server.
This currently only has enough code to handle fallback to the legacy TLS
stack for TLSv1.2 or earlier, however allows for further development and
testing.
ok beck@
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 3 | ||||
-rw-r--r-- | src/lib/libssl/ssl_methods.c | 48 | ||||
-rw-r--r-- | src/lib/libssl/tls13_server.c | 137 |
3 files changed, 182 insertions, 6 deletions
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index 7936378213..1c60f10684 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_locl.h,v 1.251 2020/01/22 13:06:20 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.252 2020/01/22 15:47:22 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -1078,6 +1078,7 @@ int ssl_cipher_is_permitted(const SSL_CIPHER *cipher, uint16_t min_ver, | |||
1078 | uint16_t max_ver); | 1078 | uint16_t max_ver); |
1079 | 1079 | ||
1080 | const SSL_METHOD *tls_legacy_client_method(void); | 1080 | const SSL_METHOD *tls_legacy_client_method(void); |
1081 | const SSL_METHOD *tls_legacy_server_method(void); | ||
1081 | 1082 | ||
1082 | const SSL_METHOD *dtls1_get_client_method(int ver); | 1083 | const SSL_METHOD *dtls1_get_client_method(int ver); |
1083 | const SSL_METHOD *dtls1_get_server_method(int ver); | 1084 | const SSL_METHOD *dtls1_get_server_method(int ver); |
diff --git a/src/lib/libssl/ssl_methods.c b/src/lib/libssl/ssl_methods.c index 8e544f6e93..30838f7407 100644 --- a/src/lib/libssl/ssl_methods.c +++ b/src/lib/libssl/ssl_methods.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_methods.c,v 1.7 2020/01/22 02:34:39 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_methods.c,v 1.8 2020/01/22 15:47:22 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -579,7 +579,39 @@ TLSv1_2_method(void) | |||
579 | return (&TLSv1_2_method_data); | 579 | return (&TLSv1_2_method_data); |
580 | } | 580 | } |
581 | 581 | ||
582 | #ifdef LIBRESSL_HAS_TLS1_3_SERVER | ||
582 | static const SSL_METHOD_INTERNAL TLS_server_method_internal_data = { | 583 | static const SSL_METHOD_INTERNAL TLS_server_method_internal_data = { |
584 | .version = TLS1_3_VERSION, | ||
585 | .min_version = TLS1_VERSION, | ||
586 | .max_version = TLS1_3_VERSION, | ||
587 | .ssl_new = tls1_new, | ||
588 | .ssl_clear = tls1_clear, | ||
589 | .ssl_free = tls1_free, | ||
590 | .ssl_accept = tls13_legacy_accept, | ||
591 | .ssl_connect = ssl_undefined_function, | ||
592 | .ssl_shutdown = tls13_legacy_shutdown, | ||
593 | .get_ssl_method = tls1_get_server_method, | ||
594 | .get_timeout = tls1_default_timeout, | ||
595 | .ssl_version = ssl_undefined_void_function, | ||
596 | .ssl_renegotiate = ssl_undefined_function, | ||
597 | .ssl_renegotiate_check = ssl_ok, | ||
598 | .ssl_get_message = ssl3_get_message, | ||
599 | .ssl_read_bytes = tls13_legacy_read_bytes, | ||
600 | .ssl_write_bytes = tls13_legacy_write_bytes, | ||
601 | .ssl3_enc = &TLSv1_2_enc_data, | ||
602 | }; | ||
603 | |||
604 | static const SSL_METHOD TLS_server_method_data = { | ||
605 | .ssl_dispatch_alert = ssl3_dispatch_alert, | ||
606 | .num_ciphers = ssl3_num_ciphers, | ||
607 | .get_cipher = ssl3_get_cipher, | ||
608 | .get_cipher_by_char = ssl3_get_cipher_by_char, | ||
609 | .put_cipher_by_char = ssl3_put_cipher_by_char, | ||
610 | .internal = &TLS_server_method_internal_data, | ||
611 | }; | ||
612 | #endif | ||
613 | |||
614 | static const SSL_METHOD_INTERNAL TLS_legacy_server_method_internal_data = { | ||
583 | .version = TLS1_2_VERSION, | 615 | .version = TLS1_2_VERSION, |
584 | .min_version = TLS1_VERSION, | 616 | .min_version = TLS1_VERSION, |
585 | .max_version = TLS1_2_VERSION, | 617 | .max_version = TLS1_2_VERSION, |
@@ -600,13 +632,13 @@ static const SSL_METHOD_INTERNAL TLS_server_method_internal_data = { | |||
600 | .ssl3_enc = &TLSv1_2_enc_data, | 632 | .ssl3_enc = &TLSv1_2_enc_data, |
601 | }; | 633 | }; |
602 | 634 | ||
603 | static const SSL_METHOD TLS_server_method_data = { | 635 | static const SSL_METHOD TLS_legacy_server_method_data = { |
604 | .ssl_dispatch_alert = ssl3_dispatch_alert, | 636 | .ssl_dispatch_alert = ssl3_dispatch_alert, |
605 | .num_ciphers = ssl3_num_ciphers, | 637 | .num_ciphers = ssl3_num_ciphers, |
606 | .get_cipher = ssl3_get_cipher, | 638 | .get_cipher = ssl3_get_cipher, |
607 | .get_cipher_by_char = ssl3_get_cipher_by_char, | 639 | .get_cipher_by_char = ssl3_get_cipher_by_char, |
608 | .put_cipher_by_char = ssl3_put_cipher_by_char, | 640 | .put_cipher_by_char = ssl3_put_cipher_by_char, |
609 | .internal = &TLS_server_method_internal_data, | 641 | .internal = &TLS_legacy_server_method_internal_data, |
610 | }; | 642 | }; |
611 | 643 | ||
612 | static const SSL_METHOD_INTERNAL TLSv1_server_method_internal_data = { | 644 | static const SSL_METHOD_INTERNAL TLSv1_server_method_internal_data = { |
@@ -720,7 +752,17 @@ SSLv23_server_method(void) | |||
720 | const SSL_METHOD * | 752 | const SSL_METHOD * |
721 | TLS_server_method(void) | 753 | TLS_server_method(void) |
722 | { | 754 | { |
755 | #ifdef LIBRESSL_HAS_TLS1_3_SERVER | ||
723 | return (&TLS_server_method_data); | 756 | return (&TLS_server_method_data); |
757 | #else | ||
758 | return tls_legacy_server_method(); | ||
759 | #endif | ||
760 | } | ||
761 | |||
762 | const SSL_METHOD * | ||
763 | tls_legacy_server_method(void) | ||
764 | { | ||
765 | return (&TLS_legacy_server_method_data); | ||
724 | } | 766 | } |
725 | 767 | ||
726 | const SSL_METHOD * | 768 | const SSL_METHOD * |
diff --git a/src/lib/libssl/tls13_server.c b/src/lib/libssl/tls13_server.c index 90a339dc61..ee7b92b9a3 100644 --- a/src/lib/libssl/tls13_server.c +++ b/src/lib/libssl/tls13_server.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls13_server.c,v 1.6 2020/01/22 13:10:51 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_server.c,v 1.7 2020/01/22 15:47:22 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2019 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2019 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -16,6 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include "ssl_locl.h" | 18 | #include "ssl_locl.h" |
19 | #include "ssl_tlsext.h" | ||
19 | 20 | ||
20 | #include "tls13_handshake.h" | 21 | #include "tls13_handshake.h" |
21 | #include "tls13_internal.h" | 22 | #include "tls13_internal.h" |
@@ -40,7 +41,8 @@ tls13_server_init(struct tls13_ctx *ctx) | |||
40 | return 0; | 41 | return 0; |
41 | } | 42 | } |
42 | 43 | ||
43 | /* XXX implement. */ | 44 | if (!tls1_transcript_init(s)) |
45 | return 0; | ||
44 | 46 | ||
45 | return 1; | 47 | return 1; |
46 | } | 48 | } |
@@ -79,10 +81,141 @@ tls13_legacy_accept(SSL *ssl) | |||
79 | } | 81 | } |
80 | 82 | ||
81 | int | 83 | int |
84 | tls13_use_legacy_server(struct tls13_ctx *ctx) | ||
85 | { | ||
86 | SSL *s = ctx->ssl; | ||
87 | CBS cbs; | ||
88 | |||
89 | s->method = tls_legacy_server_method(); | ||
90 | s->client_version = s->version = s->method->internal->max_version; | ||
91 | s->server = 1; | ||
92 | |||
93 | if (!ssl3_setup_init_buffer(s)) | ||
94 | goto err; | ||
95 | if (!ssl3_setup_buffers(s)) | ||
96 | goto err; | ||
97 | if (!ssl_init_wbio_buffer(s, 0)) | ||
98 | goto err; | ||
99 | |||
100 | if (s->bbio != s->wbio) | ||
101 | s->wbio = BIO_push(s->bbio, s->wbio); | ||
102 | |||
103 | /* Stash any unprocessed data from the last record. */ | ||
104 | tls13_record_layer_rbuf(ctx->rl, &cbs); | ||
105 | if (CBS_len(&cbs) > 0) { | ||
106 | if (!CBS_write_bytes(&cbs, | ||
107 | S3I(s)->rbuf.buf + SSL3_RT_HEADER_LENGTH, | ||
108 | S3I(s)->rbuf.len - SSL3_RT_HEADER_LENGTH, NULL)) | ||
109 | goto err; | ||
110 | |||
111 | S3I(s)->rbuf.offset = SSL3_RT_HEADER_LENGTH; | ||
112 | S3I(s)->rbuf.left = CBS_len(&cbs); | ||
113 | S3I(s)->rrec.type = SSL3_RT_HANDSHAKE; | ||
114 | S3I(s)->rrec.length = CBS_len(&cbs); | ||
115 | s->internal->rstate = SSL_ST_READ_BODY; | ||
116 | s->internal->packet = S3I(s)->rbuf.buf; | ||
117 | s->internal->packet_length = SSL3_RT_HEADER_LENGTH; | ||
118 | s->internal->mac_packet = 1; | ||
119 | } | ||
120 | |||
121 | /* Stash the current handshake message. */ | ||
122 | tls13_handshake_msg_data(ctx->hs_msg, &cbs); | ||
123 | if (!CBS_write_bytes(&cbs, s->internal->init_buf->data, | ||
124 | s->internal->init_buf->length, NULL)) | ||
125 | goto err; | ||
126 | |||
127 | S3I(s)->tmp.reuse_message = 1; | ||
128 | S3I(s)->tmp.message_type = tls13_handshake_msg_type(ctx->hs_msg); | ||
129 | S3I(s)->tmp.message_size = CBS_len(&cbs); | ||
130 | |||
131 | S3I(s)->hs.state = SSL3_ST_SR_CLNT_HELLO_A; | ||
132 | |||
133 | return 1; | ||
134 | |||
135 | err: | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static int | ||
140 | tls13_client_hello_is_legacy(CBS *cbs) | ||
141 | { | ||
142 | CBS extensions_block, extensions, extension_data; | ||
143 | uint16_t selected_version = 0; | ||
144 | uint16_t type; | ||
145 | |||
146 | CBS_dup(cbs, &extensions_block); | ||
147 | |||
148 | if (!CBS_get_u16_length_prefixed(&extensions_block, &extensions)) | ||
149 | return 1; | ||
150 | |||
151 | while (CBS_len(&extensions) > 0) { | ||
152 | if (!CBS_get_u16(&extensions, &type)) | ||
153 | return 1; | ||
154 | if (!CBS_get_u16_length_prefixed(&extensions, &extension_data)) | ||
155 | return 1; | ||
156 | |||
157 | if (type != TLSEXT_TYPE_supported_versions) | ||
158 | continue; | ||
159 | if (!CBS_get_u16(&extension_data, &selected_version)) | ||
160 | return 1; | ||
161 | if (CBS_len(&extension_data) != 0) | ||
162 | return 1; | ||
163 | } | ||
164 | |||
165 | return (selected_version < TLS1_3_VERSION); | ||
166 | } | ||
167 | |||
168 | static int | ||
169 | tls13_client_hello_process(struct tls13_ctx *ctx, CBS *cbs) | ||
170 | { | ||
171 | CBS cipher_suites, client_random, compression_methods, session_id; | ||
172 | uint16_t legacy_version; | ||
173 | SSL *s = ctx->ssl; | ||
174 | int alert; | ||
175 | |||
176 | if (!CBS_get_u16(cbs, &legacy_version)) | ||
177 | goto err; | ||
178 | if (!CBS_get_bytes(cbs, &client_random, SSL3_RANDOM_SIZE)) | ||
179 | goto err; | ||
180 | if (!CBS_get_u8_length_prefixed(cbs, &session_id)) | ||
181 | goto err; | ||
182 | if (!CBS_get_u8_length_prefixed(cbs, &cipher_suites)) | ||
183 | goto err; | ||
184 | if (!CBS_get_u8_length_prefixed(cbs, &compression_methods)) | ||
185 | goto err; | ||
186 | |||
187 | if (tls13_client_hello_is_legacy(cbs)) { | ||
188 | if (!CBS_skip(cbs, CBS_len(cbs))) | ||
189 | goto err; | ||
190 | return tls13_use_legacy_server(ctx); | ||
191 | } | ||
192 | |||
193 | if (!tlsext_server_parse(s, cbs, &alert, SSL_TLSEXT_MSG_CH)) | ||
194 | goto err; | ||
195 | |||
196 | /* XXX - implement. */ | ||
197 | |||
198 | err: | ||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | int | ||
82 | tls13_client_hello_recv(struct tls13_ctx *ctx, CBS *cbs) | 203 | tls13_client_hello_recv(struct tls13_ctx *ctx, CBS *cbs) |
83 | { | 204 | { |
205 | SSL *s = ctx->ssl; | ||
206 | |||
207 | if (!tls13_client_hello_process(ctx, cbs)) | ||
208 | goto err; | ||
209 | |||
210 | /* See if we switched back to the legacy client method. */ | ||
211 | if (s->method->internal->version < TLS1_3_VERSION) | ||
212 | return 1; | ||
213 | |||
84 | tls13_record_layer_allow_ccs(ctx->rl, 1); | 214 | tls13_record_layer_allow_ccs(ctx->rl, 1); |
85 | 215 | ||
216 | return 1; | ||
217 | |||
218 | err: | ||
86 | return 0; | 219 | return 0; |
87 | } | 220 | } |
88 | 221 | ||