diff options
author | jsing <> | 2019-02-04 16:18:15 +0000 |
---|---|---|
committer | jsing <> | 2019-02-04 16:18:15 +0000 |
commit | 2e211d11139fe5a3b4b9e84b539811139562edfc (patch) | |
tree | 4b4a3650a0532f0cb29f66755c86aa47e29f60c6 /src | |
parent | 2f17e3ef128f8ae85aac6277ad363432a0894668 (diff) | |
download | openbsd-2e211d11139fe5a3b4b9e84b539811139562edfc.tar.gz openbsd-2e211d11139fe5a3b4b9e84b539811139562edfc.tar.bz2 openbsd-2e211d11139fe5a3b4b9e84b539811139562edfc.zip |
Implement parsing and processing of TLSv1.3 ServerHello messages.
ok tb@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/tls13_client.c | 179 | ||||
-rw-r--r-- | src/lib/libssl/tls13_handshake.c | 10 | ||||
-rw-r--r-- | src/lib/libssl/tls13_internal.h | 9 |
3 files changed, 187 insertions, 11 deletions
diff --git a/src/lib/libssl/tls13_client.c b/src/lib/libssl/tls13_client.c index 1a2529be6a..4d34cf9943 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.1 2019/01/21 13:45:57 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_client.c,v 1.2 2019/02/04 16:18:15 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 | * |
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | #include "bytestring.h" | 23 | #include "bytestring.h" |
24 | #include "ssl_tlsext.h" | 24 | #include "ssl_tlsext.h" |
25 | #include "tls13_handshake.h" | ||
25 | #include "tls13_internal.h" | 26 | #include "tls13_internal.h" |
26 | 27 | ||
27 | int | 28 | int |
@@ -137,3 +138,179 @@ tls13_client_hello_send(struct tls13_ctx *ctx) | |||
137 | 138 | ||
138 | return 1; | 139 | return 1; |
139 | } | 140 | } |
141 | |||
142 | /* | ||
143 | * HelloRetryRequest hash - RFC 8446 section 4.1.3. | ||
144 | */ | ||
145 | static const uint8_t tls13_hello_retry_request_hash[] = { | ||
146 | 0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, | ||
147 | 0xbe, 0x1d, 0x8c, 0x02, 0x1e, 0x65, 0xb8, 0x91, | ||
148 | 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, | ||
149 | 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c, | ||
150 | }; | ||
151 | |||
152 | static int | ||
153 | tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs) | ||
154 | { | ||
155 | CBS server_random, session_id; | ||
156 | uint16_t cipher_suite, legacy_version; | ||
157 | uint8_t compression_method; | ||
158 | const SSL_CIPHER *cipher; | ||
159 | SSL *s = ctx->ssl; | ||
160 | int alert; | ||
161 | |||
162 | if (!CBS_get_u16(cbs, &legacy_version)) | ||
163 | goto err; | ||
164 | if (!CBS_get_bytes(cbs, &server_random, SSL3_RANDOM_SIZE)) | ||
165 | goto err; | ||
166 | if (!CBS_get_u8_length_prefixed(cbs, &session_id)) | ||
167 | goto err; | ||
168 | if (!CBS_get_u16(cbs, &cipher_suite)) | ||
169 | goto err; | ||
170 | if (!CBS_get_u8(cbs, &compression_method)) | ||
171 | goto err; | ||
172 | |||
173 | if (!tlsext_client_parse(s, cbs, &alert, SSL_TLSEXT_MSG_SH)) | ||
174 | goto err; | ||
175 | |||
176 | if (CBS_len(cbs) != 0) | ||
177 | goto err; | ||
178 | |||
179 | /* | ||
180 | * See if a supported versions extension was returned. If it was then | ||
181 | * the legacy version must be set to 0x0303 (RFC 8446 section 4.1.3). | ||
182 | * Otherwise, fallback to the legacy version, ensuring that it is both | ||
183 | * within range and not TLS 1.3 or greater (which must use the | ||
184 | * supported version extension. | ||
185 | */ | ||
186 | if (S3I(s)->hs_tls13.server_version != 0) { | ||
187 | if (legacy_version != TLS1_2_VERSION) { | ||
188 | /* XXX - alert. */ | ||
189 | goto err; | ||
190 | } | ||
191 | } else { | ||
192 | if (legacy_version < S3I(s)->hs_tls13.min_version || | ||
193 | legacy_version > S3I(s)->hs_tls13.max_version || | ||
194 | legacy_version > TLS1_2_VERSION) { | ||
195 | /* XXX - alert. */ | ||
196 | goto err; | ||
197 | } | ||
198 | S3I(s)->hs_tls13.server_version = legacy_version; | ||
199 | } | ||
200 | |||
201 | /* XXX - session_id must match. */ | ||
202 | |||
203 | /* | ||
204 | * Ensure that the cipher suite is one that we offered in the client | ||
205 | * hello and that it matches the TLS version selected. | ||
206 | */ | ||
207 | cipher = ssl3_get_cipher_by_value(cipher_suite); | ||
208 | if (cipher == NULL || | ||
209 | sk_SSL_CIPHER_find(ssl_get_ciphers_by_id(s), cipher) < 0) { | ||
210 | /* XXX - alert. */ | ||
211 | goto err; | ||
212 | } | ||
213 | if (S3I(s)->hs_tls13.server_version == TLS1_3_VERSION && | ||
214 | cipher->algorithm_ssl != SSL_TLSV1_3) { | ||
215 | /* XXX - alert. */ | ||
216 | goto err; | ||
217 | } | ||
218 | /* XXX - move this to hs_tls13? */ | ||
219 | S3I(s)->hs.new_cipher = cipher; | ||
220 | |||
221 | if (compression_method != 0) { | ||
222 | /* XXX - alert. */ | ||
223 | goto err; | ||
224 | } | ||
225 | |||
226 | if (CBS_mem_equal(&server_random, tls13_hello_retry_request_hash, | ||
227 | sizeof(tls13_hello_retry_request_hash))) | ||
228 | ctx->handshake_stage.hs_type |= WITH_HRR; | ||
229 | |||
230 | return 1; | ||
231 | |||
232 | err: | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | int | ||
237 | tls13_server_hello_recv(struct tls13_ctx *ctx) | ||
238 | { | ||
239 | struct tls13_secrets *secrets; | ||
240 | struct tls13_secret context; | ||
241 | unsigned char buf[EVP_MAX_MD_SIZE]; | ||
242 | uint8_t *shared_key = NULL; | ||
243 | size_t hash_len; | ||
244 | SSL *s = ctx->ssl; | ||
245 | int ret = 0; | ||
246 | CBS cbs; | ||
247 | |||
248 | if (!tls13_handshake_msg_content(ctx->hs_msg, &cbs)) | ||
249 | goto err; | ||
250 | |||
251 | if (!tls13_server_hello_process(ctx, &cbs)) | ||
252 | goto err; | ||
253 | |||
254 | if (S3I(s)->hs_tls13.server_version < TLS1_3_VERSION) { | ||
255 | /* XXX - switch back to legacy client. */ | ||
256 | } | ||
257 | |||
258 | if (ctx->handshake_stage.hs_type & WITH_HRR) | ||
259 | return 1; | ||
260 | |||
261 | /* XXX - handle other key share types. */ | ||
262 | if (S3I(s)->hs_tls13.x25519_peer_public == NULL) { | ||
263 | /* XXX - alert. */ | ||
264 | goto err; | ||
265 | } | ||
266 | if ((shared_key = malloc(X25519_KEY_LENGTH)) == NULL) | ||
267 | goto err; | ||
268 | if (!X25519(shared_key, S3I(s)->hs_tls13.x25519_private, | ||
269 | S3I(s)->hs_tls13.x25519_peer_public)) | ||
270 | goto err; | ||
271 | |||
272 | s->session->cipher = S3I(s)->hs.new_cipher; | ||
273 | s->session->ssl_version = S3I(s)->hs_tls13.server_version; | ||
274 | |||
275 | if ((ctx->aead = tls13_cipher_aead(S3I(s)->hs.new_cipher)) == NULL) | ||
276 | goto err; | ||
277 | if ((ctx->hash = tls13_cipher_hash(S3I(s)->hs.new_cipher)) == NULL) | ||
278 | goto err; | ||
279 | |||
280 | if ((secrets = tls13_secrets_create(ctx->hash, 0)) == NULL) | ||
281 | goto err; | ||
282 | S3I(ctx->ssl)->hs_tls13.secrets = secrets; | ||
283 | |||
284 | /* XXX - pass in hash. */ | ||
285 | if (!tls1_handshake_hash_init(s)) | ||
286 | goto err; | ||
287 | if (!tls1_handshake_hash_value(s, buf, sizeof(buf), &hash_len)) | ||
288 | goto err; | ||
289 | context.data = buf; | ||
290 | context.len = hash_len; | ||
291 | |||
292 | /* Early secrets. */ | ||
293 | if (!tls13_derive_early_secrets(secrets, secrets->zeros.data, | ||
294 | secrets->zeros.len, &context)) | ||
295 | goto err; | ||
296 | |||
297 | /* Handshake secrets. */ | ||
298 | if (!tls13_derive_handshake_secrets(S3I(s)->hs_tls13.secrets, | ||
299 | shared_key, X25519_KEY_LENGTH, &context)) | ||
300 | goto err; | ||
301 | |||
302 | tls13_record_layer_set_aead(ctx->rl, ctx->aead); | ||
303 | tls13_record_layer_set_hash(ctx->rl, ctx->hash); | ||
304 | |||
305 | if (!tls13_record_layer_set_traffic_keys(ctx->rl, | ||
306 | &secrets->server_handshake_traffic, | ||
307 | &secrets->client_handshake_traffic)) | ||
308 | goto err; | ||
309 | |||
310 | ctx->handshake_stage.hs_type |= NEGOTIATED; | ||
311 | ret = 1; | ||
312 | |||
313 | err: | ||
314 | freezero(shared_key, X25519_KEY_LENGTH); | ||
315 | return ret; | ||
316 | } | ||
diff --git a/src/lib/libssl/tls13_handshake.c b/src/lib/libssl/tls13_handshake.c index f9cb3e5b47..b3c08ef39c 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.22 2019/01/23 23:29:56 tb Exp $ */ | 1 | /* $OpenBSD: tls13_handshake.c,v 1.23 2019/02/04 16:18:15 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> |
@@ -467,14 +467,6 @@ tls13_client_key_update_recv(struct tls13_ctx *ctx) | |||
467 | } | 467 | } |
468 | 468 | ||
469 | int | 469 | int |
470 | tls13_server_hello_recv(struct tls13_ctx *ctx) | ||
471 | { | ||
472 | ctx->handshake_stage.hs_type |= NEGOTIATED; | ||
473 | |||
474 | return 0; | ||
475 | } | ||
476 | |||
477 | int | ||
478 | tls13_server_hello_send(struct tls13_ctx *ctx) | 470 | tls13_server_hello_send(struct tls13_ctx *ctx) |
479 | { | 471 | { |
480 | ctx->handshake_stage.hs_type |= NEGOTIATED; | 472 | ctx->handshake_stage.hs_type |= NEGOTIATED; |
diff --git a/src/lib/libssl/tls13_internal.h b/src/lib/libssl/tls13_internal.h index 2738c40c4c..4b23e74ae1 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.15 2019/01/21 13:45:57 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_internal.h,v 1.16 2019/02/04 16:18:15 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> |
@@ -21,6 +21,7 @@ | |||
21 | #define HEADER_TLS13_INTERNAL_H | 21 | #define HEADER_TLS13_INTERNAL_H |
22 | 22 | ||
23 | #include <openssl/evp.h> | 23 | #include <openssl/evp.h> |
24 | #include <openssl/ssl.h> | ||
24 | 25 | ||
25 | #include "bytestring.h" | 26 | #include "bytestring.h" |
26 | 27 | ||
@@ -151,6 +152,9 @@ struct tls13_ctx { | |||
151 | uint8_t mode; | 152 | uint8_t mode; |
152 | struct tls13_handshake_stage handshake_stage; | 153 | struct tls13_handshake_stage handshake_stage; |
153 | 154 | ||
155 | const EVP_AEAD *aead; | ||
156 | const EVP_MD *hash; | ||
157 | |||
154 | struct tls13_record_layer *rl; | 158 | struct tls13_record_layer *rl; |
155 | struct tls13_handshake_msg *hs_msg; | 159 | struct tls13_handshake_msg *hs_msg; |
156 | }; | 160 | }; |
@@ -158,6 +162,9 @@ struct tls13_ctx { | |||
158 | struct tls13_ctx *tls13_ctx_new(int mode); | 162 | struct tls13_ctx *tls13_ctx_new(int mode); |
159 | void tls13_ctx_free(struct tls13_ctx *ctx); | 163 | void tls13_ctx_free(struct tls13_ctx *ctx); |
160 | 164 | ||
165 | const EVP_AEAD *tls13_cipher_aead(const SSL_CIPHER *cipher); | ||
166 | const EVP_MD *tls13_cipher_hash(const SSL_CIPHER *cipher); | ||
167 | |||
161 | /* | 168 | /* |
162 | * Legacy interfaces. | 169 | * Legacy interfaces. |
163 | */ | 170 | */ |