diff options
author | beck <> | 2020-06-06 01:40:09 +0000 |
---|---|---|
committer | beck <> | 2020-06-06 01:40:09 +0000 |
commit | 5c5463afc09ad28dc5717f3c90e5fb9e9f4ffa60 (patch) | |
tree | 921562c039b5a27a1e18f71fe397784a1d3435d3 /src/lib | |
parent | a6cda271c8a6d54db86ab3cb8d7586a529351181 (diff) | |
download | openbsd-5c5463afc09ad28dc5717f3c90e5fb9e9f4ffa60.tar.gz openbsd-5c5463afc09ad28dc5717f3c90e5fb9e9f4ffa60.tar.bz2 openbsd-5c5463afc09ad28dc5717f3c90e5fb9e9f4ffa60.zip |
Implement a rolling hash of the ClientHello message, Enforce RFC 8446
section 4.1.2 to ensure subsequent ClientHello messages after a
HelloRetryRequest messages must be unchanged from the initial
ClientHello.
ok tb@ jsing@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libssl/s3_lib.c | 4 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 8 | ||||
-rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 36 | ||||
-rw-r--r-- | src/lib/libssl/tls13_internal.h | 9 | ||||
-rw-r--r-- | src/lib/libssl/tls13_lib.c | 81 | ||||
-rw-r--r-- | src/lib/libssl/tls13_server.c | 48 |
6 files changed, 179 insertions, 7 deletions
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c index e2fef72588..c2cf922973 100644 --- a/src/lib/libssl/s3_lib.c +++ b/src/lib/libssl/s3_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: s3_lib.c,v 1.195 2020/06/05 18:14:05 jsing Exp $ */ | 1 | /* $OpenBSD: s3_lib.c,v 1.196 2020/06/06 01:40:08 beck 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 | * |
@@ -1568,6 +1568,7 @@ ssl3_free(SSL *s) | |||
1568 | tls13_key_share_free(S3I(s)->hs_tls13.key_share); | 1568 | tls13_key_share_free(S3I(s)->hs_tls13.key_share); |
1569 | tls13_secrets_destroy(S3I(s)->hs_tls13.secrets); | 1569 | tls13_secrets_destroy(S3I(s)->hs_tls13.secrets); |
1570 | freezero(S3I(s)->hs_tls13.cookie, S3I(s)->hs_tls13.cookie_len); | 1570 | freezero(S3I(s)->hs_tls13.cookie, S3I(s)->hs_tls13.cookie_len); |
1571 | tls13_clienthello_hash_clear(&S3I(s)->hs_tls13); | ||
1571 | 1572 | ||
1572 | sk_X509_NAME_pop_free(S3I(s)->tmp.ca_names, X509_NAME_free); | 1573 | sk_X509_NAME_pop_free(S3I(s)->tmp.ca_names, X509_NAME_free); |
1573 | 1574 | ||
@@ -1612,6 +1613,7 @@ ssl3_clear(SSL *s) | |||
1612 | freezero(S3I(s)->hs_tls13.cookie, S3I(s)->hs_tls13.cookie_len); | 1613 | freezero(S3I(s)->hs_tls13.cookie, S3I(s)->hs_tls13.cookie_len); |
1613 | S3I(s)->hs_tls13.cookie = NULL; | 1614 | S3I(s)->hs_tls13.cookie = NULL; |
1614 | S3I(s)->hs_tls13.cookie_len = 0; | 1615 | S3I(s)->hs_tls13.cookie_len = 0; |
1616 | tls13_clienthello_hash_clear(&S3I(s)->hs_tls13); | ||
1615 | 1617 | ||
1616 | S3I(s)->hs.extensions_seen = 0; | 1618 | S3I(s)->hs.extensions_seen = 0; |
1617 | 1619 | ||
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index bfc3c1ad9b..bf1f846d13 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.279 2020/05/31 18:03:32 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.280 2020/06/06 01:40:09 beck 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 | * |
@@ -470,6 +470,12 @@ typedef struct ssl_handshake_tls13_st { | |||
470 | /* Legacy session ID. */ | 470 | /* Legacy session ID. */ |
471 | uint8_t legacy_session_id[SSL_MAX_SSL_SESSION_ID_LENGTH]; | 471 | uint8_t legacy_session_id[SSL_MAX_SSL_SESSION_ID_LENGTH]; |
472 | size_t legacy_session_id_len; | 472 | size_t legacy_session_id_len; |
473 | |||
474 | /* ClientHello hash, used to validate following HelloRetryRequest */ | ||
475 | EVP_MD_CTX *clienthello_md_ctx; | ||
476 | unsigned char *clienthello_hash; | ||
477 | unsigned int clienthello_hash_len; | ||
478 | |||
473 | } SSL_HANDSHAKE_TLS13; | 479 | } SSL_HANDSHAKE_TLS13; |
474 | 480 | ||
475 | typedef struct ssl_ctx_internal_st { | 481 | typedef struct ssl_ctx_internal_st { |
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c index cf54fc4d2c..f6943c83ae 100644 --- a/src/lib/libssl/ssl_tlsext.c +++ b/src/lib/libssl/ssl_tlsext.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_tlsext.c,v 1.74 2020/05/29 17:39:42 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.c,v 1.75 2020/06/06 01:40:09 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org> |
4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> | 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> |
@@ -2059,6 +2059,33 @@ tlsext_build(SSL *s, CBB *cbb, int is_server, uint16_t msg_type) | |||
2059 | return 1; | 2059 | return 1; |
2060 | } | 2060 | } |
2061 | 2061 | ||
2062 | int | ||
2063 | tlsext_clienthello_hash_extension(SSL *s, uint16_t type, CBS *cbs) | ||
2064 | { | ||
2065 | /* | ||
2066 | * RFC 8446 4.1.2. For subsequent CH, early data will be removed, | ||
2067 | * cookie may be added, padding may be removed. | ||
2068 | */ | ||
2069 | struct tls13_ctx *ctx = s->internal->tls13; | ||
2070 | |||
2071 | if (type == TLSEXT_TYPE_early_data || type == TLSEXT_TYPE_cookie || | ||
2072 | type == TLSEXT_TYPE_padding) | ||
2073 | return 1; | ||
2074 | if (!tls13_clienthello_hash_update_bytes(ctx, (void *)&type, | ||
2075 | sizeof(type))) | ||
2076 | return 0; | ||
2077 | /* | ||
2078 | * key_share data may be changed, and pre_shared_key data may | ||
2079 | * be changed | ||
2080 | */ | ||
2081 | if (type == TLSEXT_TYPE_pre_shared_key || type == TLSEXT_TYPE_key_share) | ||
2082 | return 1; | ||
2083 | if (!tls13_clienthello_hash_update(ctx, cbs)) | ||
2084 | return 0; | ||
2085 | |||
2086 | return 1; | ||
2087 | } | ||
2088 | |||
2062 | static int | 2089 | static int |
2063 | tlsext_parse(SSL *s, CBS *cbs, int *alert, int is_server, uint16_t msg_type) | 2090 | tlsext_parse(SSL *s, CBS *cbs, int *alert, int is_server, uint16_t msg_type) |
2064 | { | 2091 | { |
@@ -2098,6 +2125,13 @@ tlsext_parse(SSL *s, CBS *cbs, int *alert, int is_server, uint16_t msg_type) | |||
2098 | CBS_len(&extension_data), | 2125 | CBS_len(&extension_data), |
2099 | s->internal->tlsext_debug_arg); | 2126 | s->internal->tlsext_debug_arg); |
2100 | 2127 | ||
2128 | if (!SSL_IS_DTLS(s) && version >= TLS1_3_VERSION && is_server && | ||
2129 | msg_type == SSL_TLSEXT_MSG_CH) { | ||
2130 | if (!tlsext_clienthello_hash_extension(s, type, | ||
2131 | &extension_data)) | ||
2132 | goto err; | ||
2133 | } | ||
2134 | |||
2101 | /* Unknown extensions are ignored. */ | 2135 | /* Unknown extensions are ignored. */ |
2102 | if ((tlsext = tls_extension_find(type, &idx)) == NULL) | 2136 | if ((tlsext = tls_extension_find(type, &idx)) == NULL) |
2103 | continue; | 2137 | continue; |
diff --git a/src/lib/libssl/tls13_internal.h b/src/lib/libssl/tls13_internal.h index 96ed981959..a18184f505 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.83 2020/05/29 17:47:30 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_internal.h,v 1.84 2020/06/06 01:40:09 beck 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> |
@@ -386,6 +386,13 @@ int tls13_cert_add(struct tls13_ctx *ctx, CBB *cbb, X509 *cert, | |||
386 | int(*build_extensions)(SSL *s, CBB *cbb, uint16_t msg_type)); | 386 | int(*build_extensions)(SSL *s, CBB *cbb, uint16_t msg_type)); |
387 | 387 | ||
388 | int tls13_synthetic_handshake_message(struct tls13_ctx *ctx); | 388 | int tls13_synthetic_handshake_message(struct tls13_ctx *ctx); |
389 | int tls13_clienthello_hash_init(struct tls13_ctx *ctx); | ||
390 | void tls13_clienthello_hash_clear(struct ssl_handshake_tls13_st *hs); | ||
391 | int tls13_clienthello_hash_update_bytes(struct tls13_ctx *ctx, void *data, | ||
392 | size_t len); | ||
393 | int tls13_clienthello_hash_update(struct tls13_ctx *ctx, CBS *cbs); | ||
394 | int tls13_clienthello_hash_finalize(struct tls13_ctx *ctx); | ||
395 | int tls13_clienthello_hash_validate(struct tls13_ctx *ctx); | ||
389 | 396 | ||
390 | int tls13_error_set(struct tls13_error *error, int code, int subcode, | 397 | int tls13_error_set(struct tls13_error *error, int code, int subcode, |
391 | const char *file, int line, const char *fmt, ...); | 398 | const char *file, int line, const char *fmt, ...); |
diff --git a/src/lib/libssl/tls13_lib.c b/src/lib/libssl/tls13_lib.c index 174da2f9c3..b5939aecab 100644 --- a/src/lib/libssl/tls13_lib.c +++ b/src/lib/libssl/tls13_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls13_lib.c,v 1.50 2020/05/22 02:37:27 beck Exp $ */ | 1 | /* $OpenBSD: tls13_lib.c,v 1.51 2020/06/06 01:40:09 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> |
4 | * Copyright (c) 2019 Bob Beck <beck@openbsd.org> | 4 | * Copyright (c) 2019 Bob Beck <beck@openbsd.org> |
@@ -486,3 +486,82 @@ tls13_synthetic_handshake_message(struct tls13_ctx *ctx) | |||
486 | 486 | ||
487 | return ret; | 487 | return ret; |
488 | } | 488 | } |
489 | |||
490 | int | ||
491 | tls13_clienthello_hash_init(struct tls13_ctx *ctx) | ||
492 | { | ||
493 | if (ctx->hs->clienthello_md_ctx != NULL) | ||
494 | return 0; | ||
495 | if ((ctx->hs->clienthello_md_ctx = EVP_MD_CTX_new()) == NULL) | ||
496 | return 0; | ||
497 | if (!EVP_DigestInit_ex(ctx->hs->clienthello_md_ctx, | ||
498 | EVP_sha256(), NULL)) | ||
499 | return 0; | ||
500 | |||
501 | if ((ctx->hs->clienthello_hash == NULL) && | ||
502 | (ctx->hs->clienthello_hash = calloc(1, EVP_MAX_MD_SIZE)) == | ||
503 | NULL) | ||
504 | return 0; | ||
505 | |||
506 | return 1; | ||
507 | } | ||
508 | |||
509 | void | ||
510 | tls13_clienthello_hash_clear(struct ssl_handshake_tls13_st *hs) | ||
511 | { | ||
512 | EVP_MD_CTX_free(hs->clienthello_md_ctx); | ||
513 | hs->clienthello_md_ctx = NULL; | ||
514 | freezero(hs->clienthello_hash, EVP_MAX_MD_SIZE); | ||
515 | hs->clienthello_hash = NULL; | ||
516 | } | ||
517 | |||
518 | int | ||
519 | tls13_clienthello_hash_update_bytes(struct tls13_ctx *ctx, void *data, | ||
520 | size_t len) | ||
521 | { | ||
522 | return EVP_DigestUpdate(ctx->hs->clienthello_md_ctx, data, len); | ||
523 | } | ||
524 | |||
525 | int | ||
526 | tls13_clienthello_hash_update(struct tls13_ctx *ctx, CBS *cbs) | ||
527 | { | ||
528 | return tls13_clienthello_hash_update_bytes(ctx, (void *)CBS_data(cbs), | ||
529 | CBS_len(cbs)); | ||
530 | } | ||
531 | |||
532 | int | ||
533 | tls13_clienthello_hash_finalize(struct tls13_ctx *ctx) | ||
534 | { | ||
535 | if (!EVP_DigestFinal_ex(ctx->hs->clienthello_md_ctx, | ||
536 | ctx->hs->clienthello_hash, | ||
537 | &ctx->hs->clienthello_hash_len)) | ||
538 | return 0; | ||
539 | EVP_MD_CTX_free(ctx->hs->clienthello_md_ctx); | ||
540 | ctx->hs->clienthello_md_ctx = NULL; | ||
541 | return 1; | ||
542 | } | ||
543 | |||
544 | int | ||
545 | tls13_clienthello_hash_validate(struct tls13_ctx *ctx) | ||
546 | { | ||
547 | unsigned char new_ch_hash[EVP_MAX_MD_SIZE]; | ||
548 | unsigned int new_ch_hash_len; | ||
549 | |||
550 | if (ctx->hs->clienthello_hash == NULL) | ||
551 | return 0; | ||
552 | |||
553 | if (!EVP_DigestFinal_ex(ctx->hs->clienthello_md_ctx, | ||
554 | new_ch_hash, &new_ch_hash_len)) | ||
555 | return 0; | ||
556 | EVP_MD_CTX_free(ctx->hs->clienthello_md_ctx); | ||
557 | ctx->hs->clienthello_md_ctx = NULL; | ||
558 | |||
559 | if (ctx->hs->clienthello_hash_len != new_ch_hash_len) | ||
560 | return 0; | ||
561 | if (memcmp(ctx->hs->clienthello_hash, new_ch_hash, | ||
562 | new_ch_hash_len) != 0) | ||
563 | return 0; | ||
564 | |||
565 | return 1; | ||
566 | } | ||
567 | |||
diff --git a/src/lib/libssl/tls13_server.c b/src/lib/libssl/tls13_server.c index edc87fcdcb..ccbb46652b 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.57 2020/06/04 18:46:21 tb Exp $ */ | 1 | /* $OpenBSD: tls13_server.c,v 1.58 2020/06/06 01:40:09 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2019, 2020 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2019, 2020 Joel Sing <jsing@openbsd.org> |
4 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 4 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
@@ -126,11 +126,52 @@ tls13_client_hello_process(struct tls13_ctx *ctx, CBS *cbs) | |||
126 | return tls13_use_legacy_server(ctx); | 126 | return tls13_use_legacy_server(ctx); |
127 | } | 127 | } |
128 | 128 | ||
129 | /* Add decoded values to the current ClientHello hash */ | ||
130 | if (!tls13_clienthello_hash_init(ctx)) { | ||
131 | ctx->alert = TLS13_ALERT_INTERNAL_ERROR; | ||
132 | goto err; | ||
133 | } | ||
134 | if (!tls13_clienthello_hash_update_bytes(ctx, (void *)&legacy_version, | ||
135 | sizeof(legacy_version))) { | ||
136 | ctx->alert = TLS13_ALERT_INTERNAL_ERROR; | ||
137 | goto err; | ||
138 | } | ||
139 | if (!tls13_clienthello_hash_update(ctx, &client_random)) { | ||
140 | ctx->alert = TLS13_ALERT_INTERNAL_ERROR; | ||
141 | goto err; | ||
142 | } | ||
143 | if (!tls13_clienthello_hash_update(ctx, &session_id)) { | ||
144 | ctx->alert = TLS13_ALERT_INTERNAL_ERROR; | ||
145 | goto err; | ||
146 | } | ||
147 | if (!tls13_clienthello_hash_update(ctx, &cipher_suites)) { | ||
148 | ctx->alert = TLS13_ALERT_INTERNAL_ERROR; | ||
149 | goto err; | ||
150 | } | ||
151 | if (!tls13_clienthello_hash_update(ctx, &compression_methods)) { | ||
152 | ctx->alert = TLS13_ALERT_INTERNAL_ERROR; | ||
153 | goto err; | ||
154 | } | ||
155 | |||
129 | if (!tlsext_server_parse(s, cbs, &alert_desc, SSL_TLSEXT_MSG_CH)) { | 156 | if (!tlsext_server_parse(s, cbs, &alert_desc, SSL_TLSEXT_MSG_CH)) { |
130 | ctx->alert = alert_desc; | 157 | ctx->alert = alert_desc; |
131 | goto err; | 158 | goto err; |
132 | } | 159 | } |
133 | 160 | ||
161 | /* Finalize first ClientHello hash, or validate against it */ | ||
162 | if (!ctx->hs->hrr) { | ||
163 | if (!tls13_clienthello_hash_finalize(ctx)) { | ||
164 | ctx->alert = TLS13_ALERT_INTERNAL_ERROR; | ||
165 | goto err; | ||
166 | } | ||
167 | } else { | ||
168 | if (!tls13_clienthello_hash_validate(ctx)) { | ||
169 | ctx->alert = TLS13_ALERT_ILLEGAL_PARAMETER; | ||
170 | goto err; | ||
171 | } | ||
172 | tls13_clienthello_hash_clear(ctx->hs); | ||
173 | } | ||
174 | |||
134 | /* | 175 | /* |
135 | * If we got this far we have a supported versions extension that offers | 176 | * If we got this far we have a supported versions extension that offers |
136 | * TLS 1.3 or later. This requires the legacy version be set to 0x0303. | 177 | * TLS 1.3 or later. This requires the legacy version be set to 0x0303. |
@@ -146,8 +187,11 @@ tls13_client_hello_process(struct tls13_ctx *ctx, CBS *cbs) | |||
146 | goto err; | 187 | goto err; |
147 | } | 188 | } |
148 | if (!CBS_write_bytes(&session_id, ctx->hs->legacy_session_id, | 189 | if (!CBS_write_bytes(&session_id, ctx->hs->legacy_session_id, |
149 | sizeof(ctx->hs->legacy_session_id), &ctx->hs->legacy_session_id_len)) | 190 | sizeof(ctx->hs->legacy_session_id), |
191 | &ctx->hs->legacy_session_id_len)) { | ||
192 | ctx->alert = TLS13_ALERT_INTERNAL_ERROR; | ||
150 | goto err; | 193 | goto err; |
194 | } | ||
151 | 195 | ||
152 | /* Parse cipher suites list and select preferred cipher. */ | 196 | /* Parse cipher suites list and select preferred cipher. */ |
153 | if ((ciphers = ssl_bytes_to_cipher_list(s, &cipher_suites)) == NULL) { | 197 | if ((ciphers = ssl_bytes_to_cipher_list(s, &cipher_suites)) == NULL) { |