diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/ssl_clnt.c | 52 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 10 | ||||
-rw-r--r-- | src/lib/libssl/ssl_srvr.c | 18 | ||||
-rw-r--r-- | src/lib/libssl/ssl_versions.c | 20 | ||||
-rw-r--r-- | src/lib/libssl/tls13_client.c | 10 | ||||
-rw-r--r-- | src/lib/libssl/tls13_legacy.c | 6 | ||||
-rw-r--r-- | src/lib/libssl/tls13_server.c | 3 |
7 files changed, 62 insertions, 57 deletions
diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c index ea13f81596..2e7047eb55 100644 --- a/src/lib/libssl/ssl_clnt.c +++ b/src/lib/libssl/ssl_clnt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_clnt.c,v 1.114 2021/10/23 13:36:03 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_clnt.c,v 1.115 2021/10/23 14:40:54 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 | * |
@@ -650,7 +650,7 @@ ssl3_send_client_hello(SSL *s) | |||
650 | SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE); | 650 | SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE); |
651 | return (-1); | 651 | return (-1); |
652 | } | 652 | } |
653 | s->client_version = s->version = max_version; | 653 | s->version = max_version; |
654 | 654 | ||
655 | if (sess == NULL || | 655 | if (sess == NULL || |
656 | sess->ssl_version != s->version || | 656 | sess->ssl_version != s->version || |
@@ -673,37 +673,7 @@ ssl3_send_client_hello(SSL *s) | |||
673 | SSL3_MT_CLIENT_HELLO)) | 673 | SSL3_MT_CLIENT_HELLO)) |
674 | goto err; | 674 | goto err; |
675 | 675 | ||
676 | /* | 676 | if (!CBB_add_u16(&client_hello, s->version)) |
677 | * Version indicates the negotiated version: for example from | ||
678 | * an SSLv2/v3 compatible client hello). The client_version | ||
679 | * field is the maximum version we permit and it is also | ||
680 | * used in RSA encrypted premaster secrets. Some servers can | ||
681 | * choke if we initially report a higher version then | ||
682 | * renegotiate to a lower one in the premaster secret. This | ||
683 | * didn't happen with TLS 1.0 as most servers supported it | ||
684 | * but it can with TLS 1.1 or later if the server only supports | ||
685 | * 1.0. | ||
686 | * | ||
687 | * Possible scenario with previous logic: | ||
688 | * 1. Client hello indicates TLS 1.2 | ||
689 | * 2. Server hello says TLS 1.0 | ||
690 | * 3. RSA encrypted premaster secret uses 1.2. | ||
691 | * 4. Handhaked proceeds using TLS 1.0. | ||
692 | * 5. Server sends hello request to renegotiate. | ||
693 | * 6. Client hello indicates TLS v1.0 as we now | ||
694 | * know that is maximum server supports. | ||
695 | * 7. Server chokes on RSA encrypted premaster secret | ||
696 | * containing version 1.0. | ||
697 | * | ||
698 | * For interoperability it should be OK to always use the | ||
699 | * maximum version we support in client hello and then rely | ||
700 | * on the checking of version to ensure the servers isn't | ||
701 | * being inconsistent: for example initially negotiating with | ||
702 | * TLS 1.0 and renegotiating with TLS 1.2. We do this by using | ||
703 | * client_version in client hello and not resetting it to | ||
704 | * the negotiated version. | ||
705 | */ | ||
706 | if (!CBB_add_u16(&client_hello, s->client_version)) | ||
707 | goto err; | 677 | goto err; |
708 | 678 | ||
709 | /* Random stuff */ | 679 | /* Random stuff */ |
@@ -889,6 +859,7 @@ ssl3_get_server_hello(SSL *s) | |||
889 | al = SSL_AD_PROTOCOL_VERSION; | 859 | al = SSL_AD_PROTOCOL_VERSION; |
890 | goto fatal_err; | 860 | goto fatal_err; |
891 | } | 861 | } |
862 | S3I(s)->hs.peer_legacy_version = server_version; | ||
892 | s->version = server_version; | 863 | s->version = server_version; |
893 | 864 | ||
894 | S3I(s)->hs.negotiated_tls_version = ssl_tls_version(server_version); | 865 | S3I(s)->hs.negotiated_tls_version = ssl_tls_version(server_version); |
@@ -1952,6 +1923,7 @@ ssl3_send_client_kex_rsa(SSL *s, SESS_CERT *sess_cert, CBB *cbb) | |||
1952 | { | 1923 | { |
1953 | unsigned char pms[SSL_MAX_MASTER_KEY_LENGTH]; | 1924 | unsigned char pms[SSL_MAX_MASTER_KEY_LENGTH]; |
1954 | unsigned char *enc_pms = NULL; | 1925 | unsigned char *enc_pms = NULL; |
1926 | uint16_t max_legacy_version; | ||
1955 | EVP_PKEY *pkey = NULL; | 1927 | EVP_PKEY *pkey = NULL; |
1956 | int ret = -1; | 1928 | int ret = -1; |
1957 | int enc_len; | 1929 | int enc_len; |
@@ -1968,9 +1940,17 @@ ssl3_send_client_kex_rsa(SSL *s, SESS_CERT *sess_cert, CBB *cbb) | |||
1968 | goto err; | 1940 | goto err; |
1969 | } | 1941 | } |
1970 | 1942 | ||
1971 | /* XXX - our max protocol version. */ | 1943 | /* |
1972 | pms[0] = s->client_version >> 8; | 1944 | * Our maximum legacy protocol version - while RFC 5246 section 7.4.7.1 |
1973 | pms[1] = s->client_version & 0xff; | 1945 | * says "The latest (newest) version supported by the client", if we're |
1946 | * doing RSA key exchange then we have to presume that we're talking to | ||
1947 | * a server that does not understand the supported versions extension | ||
1948 | * and therefore our maximum version is that sent in the ClientHello. | ||
1949 | */ | ||
1950 | if (!ssl_max_legacy_version(s, &max_legacy_version)) | ||
1951 | goto err; | ||
1952 | pms[0] = max_legacy_version >> 8; | ||
1953 | pms[1] = max_legacy_version & 0xff; | ||
1974 | arc4random_buf(&pms[2], sizeof(pms) - 2); | 1954 | arc4random_buf(&pms[2], sizeof(pms) - 2); |
1975 | 1955 | ||
1976 | if ((enc_pms = malloc(RSA_size(pkey->pkey.rsa))) == NULL) { | 1956 | if ((enc_pms = malloc(RSA_size(pkey->pkey.rsa))) == NULL) { |
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index b41a5d803f..3c58e5ac21 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.362 2021/10/23 11:41:52 beck Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.363 2021/10/23 14:40:54 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 | * |
@@ -583,6 +583,13 @@ typedef struct ssl_handshake_st { | |||
583 | uint16_t negotiated_tls_version; | 583 | uint16_t negotiated_tls_version; |
584 | 584 | ||
585 | /* | 585 | /* |
586 | * Legacy version advertised by our peer. For a server this is the | ||
587 | * version specified by the client in the ClientHello message. For a | ||
588 | * client, this is the version provided in the ServerHello message. | ||
589 | */ | ||
590 | uint16_t peer_legacy_version; | ||
591 | |||
592 | /* | ||
586 | * Current handshake state - contains one of the SSL3_ST_* values and | 593 | * Current handshake state - contains one of the SSL3_ST_* values and |
587 | * is used by the TLSv1.2 state machine, as well as being updated by | 594 | * is used by the TLSv1.2 state machine, as well as being updated by |
588 | * the TLSv1.3 stack due to it being exposed externally. | 595 | * the TLSv1.3 stack due to it being exposed externally. |
@@ -1291,6 +1298,7 @@ int ssl_supported_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver | |||
1291 | uint16_t ssl_tls_version(uint16_t version); | 1298 | uint16_t ssl_tls_version(uint16_t version); |
1292 | uint16_t ssl_effective_tls_version(SSL *s); | 1299 | uint16_t ssl_effective_tls_version(SSL *s); |
1293 | int ssl_max_supported_version(SSL *s, uint16_t *max_ver); | 1300 | int ssl_max_supported_version(SSL *s, uint16_t *max_ver); |
1301 | int ssl_max_legacy_version(SSL *s, uint16_t *max_ver); | ||
1294 | int ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver); | 1302 | int ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver); |
1295 | int ssl_check_version_from_server(SSL *s, uint16_t server_version); | 1303 | int ssl_check_version_from_server(SSL *s, uint16_t server_version); |
1296 | int ssl_legacy_stack_version(SSL *s, uint16_t version); | 1304 | int ssl_legacy_stack_version(SSL *s, uint16_t version); |
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index 1aa0324b15..ec1e69a8bb 100644 --- a/src/lib/libssl/ssl_srvr.c +++ b/src/lib/libssl/ssl_srvr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_srvr.c,v 1.121 2021/10/23 13:36:03 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_srvr.c,v 1.122 2021/10/23 14:40:54 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 | * |
@@ -837,19 +837,19 @@ ssl3_get_client_hello(SSL *s) | |||
837 | * (may differ: see RFC 2246, Appendix E, second paragraph) | 837 | * (may differ: see RFC 2246, Appendix E, second paragraph) |
838 | */ | 838 | */ |
839 | if (!ssl_max_shared_version(s, client_version, &shared_version)) { | 839 | if (!ssl_max_shared_version(s, client_version, &shared_version)) { |
840 | if ((s->client_version >> 8) == SSL3_VERSION_MAJOR && | 840 | if ((client_version >> 8) == SSL3_VERSION_MAJOR && |
841 | !tls12_record_layer_write_protected(s->internal->rl)) { | 841 | !tls12_record_layer_write_protected(s->internal->rl)) { |
842 | /* | 842 | /* |
843 | * Similar to ssl3_get_record, send alert using remote | 843 | * Similar to ssl3_get_record, send alert using remote |
844 | * version number. | 844 | * version number. |
845 | */ | 845 | */ |
846 | s->version = s->client_version; | 846 | s->version = client_version; |
847 | } | 847 | } |
848 | SSLerror(s, SSL_R_WRONG_VERSION_NUMBER); | 848 | SSLerror(s, SSL_R_WRONG_VERSION_NUMBER); |
849 | al = SSL_AD_PROTOCOL_VERSION; | 849 | al = SSL_AD_PROTOCOL_VERSION; |
850 | goto fatal_err; | 850 | goto fatal_err; |
851 | } | 851 | } |
852 | s->client_version = client_version; | 852 | S3I(s)->hs.peer_legacy_version = client_version; |
853 | s->version = shared_version; | 853 | s->version = shared_version; |
854 | 854 | ||
855 | S3I(s)->hs.negotiated_tls_version = ssl_tls_version(shared_version); | 855 | S3I(s)->hs.negotiated_tls_version = ssl_tls_version(shared_version); |
@@ -1723,9 +1723,8 @@ ssl3_get_client_kex_rsa(SSL *s, CBS *cbs) | |||
1723 | 1723 | ||
1724 | arc4random_buf(fakekey, sizeof(fakekey)); | 1724 | arc4random_buf(fakekey, sizeof(fakekey)); |
1725 | 1725 | ||
1726 | /* XXX - peer max protocol version. */ | 1726 | fakekey[0] = S3I(s)->hs.peer_legacy_version >> 8; |
1727 | fakekey[0] = s->client_version >> 8; | 1727 | fakekey[1] = S3I(s)->hs.peer_legacy_version & 0xff; |
1728 | fakekey[1] = s->client_version & 0xff; | ||
1729 | 1728 | ||
1730 | pkey = s->cert->pkeys[SSL_PKEY_RSA].privatekey; | 1729 | pkey = s->cert->pkeys[SSL_PKEY_RSA].privatekey; |
1731 | if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA) || | 1730 | if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA) || |
@@ -1760,9 +1759,8 @@ ssl3_get_client_kex_rsa(SSL *s, CBS *cbs) | |||
1760 | /* SSLerror(s, SSL_R_BAD_RSA_DECRYPT); */ | 1759 | /* SSLerror(s, SSL_R_BAD_RSA_DECRYPT); */ |
1761 | } | 1760 | } |
1762 | 1761 | ||
1763 | /* XXX - peer max version. */ | 1762 | if ((al == -1) && !((pms[0] == (S3I(s)->hs.peer_legacy_version >> 8)) && |
1764 | if ((al == -1) && !((pms[0] == (s->client_version >> 8)) && | 1763 | (pms[1] == (S3I(s)->hs.peer_legacy_version & 0xff)))) { |
1765 | (pms[1] == (s->client_version & 0xff)))) { | ||
1766 | /* | 1764 | /* |
1767 | * The premaster secret must contain the same version number | 1765 | * The premaster secret must contain the same version number |
1768 | * as the ClientHello to detect version rollback attacks | 1766 | * as the ClientHello to detect version rollback attacks |
diff --git a/src/lib/libssl/ssl_versions.c b/src/lib/libssl/ssl_versions.c index c633b58c25..b5834dbe33 100644 --- a/src/lib/libssl/ssl_versions.c +++ b/src/lib/libssl/ssl_versions.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_versions.c,v 1.20 2021/07/01 17:53:39 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_versions.c,v 1.21 2021/10/23 14:40:54 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -251,6 +251,24 @@ ssl_max_supported_version(SSL *s, uint16_t *max_ver) | |||
251 | } | 251 | } |
252 | 252 | ||
253 | int | 253 | int |
254 | ssl_max_legacy_version(SSL *s, uint16_t *max_ver) | ||
255 | { | ||
256 | uint16_t max_version; | ||
257 | |||
258 | if ((max_version = S3I(s)->hs.our_max_tls_version) > TLS1_2_VERSION) | ||
259 | max_version = TLS1_2_VERSION; | ||
260 | |||
261 | if (SSL_is_dtls(s)) { | ||
262 | if ((max_version = ssl_tls_to_dtls_version(max_version)) == 0) | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | *max_ver = max_version; | ||
267 | |||
268 | return 1; | ||
269 | } | ||
270 | |||
271 | int | ||
254 | ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver) | 272 | ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver) |
255 | { | 273 | { |
256 | uint16_t min_version, max_version, peer_tls_version, shared_version; | 274 | uint16_t min_version, max_version, peer_tls_version, shared_version; |
diff --git a/src/lib/libssl/tls13_client.c b/src/lib/libssl/tls13_client.c index 62c5174490..00a1c6baa4 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.86 2021/06/29 19:20:39 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_client.c,v 1.87 2021/10/23 14:40:54 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 | * |
@@ -36,7 +36,7 @@ tls13_client_init(struct tls13_ctx *ctx) | |||
36 | SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE); | 36 | SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE); |
37 | return 0; | 37 | return 0; |
38 | } | 38 | } |
39 | s->client_version = s->version = ctx->hs->our_max_tls_version; | 39 | s->version = ctx->hs->our_max_tls_version; |
40 | 40 | ||
41 | tls13_record_layer_set_retry_after_phh(ctx->rl, | 41 | tls13_record_layer_set_retry_after_phh(ctx->rl, |
42 | (s->internal->mode & SSL_MODE_AUTO_RETRY) != 0); | 42 | (s->internal->mode & SSL_MODE_AUTO_RETRY) != 0); |
@@ -92,9 +92,8 @@ tls13_client_hello_build(struct tls13_ctx *ctx, CBB *cbb) | |||
92 | SSL *s = ctx->ssl; | 92 | SSL *s = ctx->ssl; |
93 | 93 | ||
94 | /* Legacy client version is capped at TLS 1.2. */ | 94 | /* Legacy client version is capped at TLS 1.2. */ |
95 | client_version = ctx->hs->our_max_tls_version; | 95 | if (!ssl_max_legacy_version(s, &client_version)) |
96 | if (client_version > TLS1_2_VERSION) | 96 | goto err; |
97 | client_version = TLS1_2_VERSION; | ||
98 | 97 | ||
99 | if (!CBB_add_u16(cbb, client_version)) | 98 | if (!CBB_add_u16(cbb, client_version)) |
100 | goto err; | 99 | goto err; |
@@ -282,6 +281,7 @@ tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs) | |||
282 | goto err; | 281 | goto err; |
283 | } | 282 | } |
284 | ctx->hs->negotiated_tls_version = ctx->hs->tls13.server_version; | 283 | ctx->hs->negotiated_tls_version = ctx->hs->tls13.server_version; |
284 | ctx->hs->peer_legacy_version = legacy_version; | ||
285 | 285 | ||
286 | /* The session_id must match. */ | 286 | /* The session_id must match. */ |
287 | if (!CBS_mem_equal(&session_id, ctx->hs->tls13.legacy_session_id, | 287 | if (!CBS_mem_equal(&session_id, ctx->hs->tls13.legacy_session_id, |
diff --git a/src/lib/libssl/tls13_legacy.c b/src/lib/libssl/tls13_legacy.c index f668dd4ea3..18e6fa3681 100644 --- a/src/lib/libssl/tls13_legacy.c +++ b/src/lib/libssl/tls13_legacy.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls13_legacy.c,v 1.31 2021/09/16 19:25:30 jsing Exp $ */ | 1 | /* $OpenBSD: tls13_legacy.c,v 1.32 2021/10/23 14:40:54 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 | * |
@@ -383,7 +383,7 @@ tls13_use_legacy_client(struct tls13_ctx *ctx) | |||
383 | return 0; | 383 | return 0; |
384 | 384 | ||
385 | s->internal->handshake_func = s->method->ssl_connect; | 385 | s->internal->handshake_func = s->method->ssl_connect; |
386 | s->client_version = s->version = s->method->max_tls_version; | 386 | s->version = s->method->max_tls_version; |
387 | 387 | ||
388 | return 1; | 388 | return 1; |
389 | } | 389 | } |
@@ -397,7 +397,7 @@ tls13_use_legacy_server(struct tls13_ctx *ctx) | |||
397 | return 0; | 397 | return 0; |
398 | 398 | ||
399 | s->internal->handshake_func = s->method->ssl_accept; | 399 | s->internal->handshake_func = s->method->ssl_accept; |
400 | s->client_version = s->version = s->method->max_tls_version; | 400 | s->version = s->method->max_tls_version; |
401 | s->server = 1; | 401 | s->server = 1; |
402 | 402 | ||
403 | return 1; | 403 | return 1; |
diff --git a/src/lib/libssl/tls13_server.c b/src/lib/libssl/tls13_server.c index 9c0369fc91..a19b3825fe 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.85 2021/10/23 13:12:55 tb Exp $ */ | 1 | /* $OpenBSD: tls13_server.c,v 1.86 2021/10/23 14:40:54 jsing 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> |
@@ -164,6 +164,7 @@ tls13_client_hello_process(struct tls13_ctx *ctx, CBS *cbs) | |||
164 | return tls13_use_legacy_server(ctx); | 164 | return tls13_use_legacy_server(ctx); |
165 | } | 165 | } |
166 | ctx->hs->negotiated_tls_version = TLS1_3_VERSION; | 166 | ctx->hs->negotiated_tls_version = TLS1_3_VERSION; |
167 | ctx->hs->peer_legacy_version = legacy_version; | ||
167 | 168 | ||
168 | /* Ensure we send subsequent alerts with the correct record version. */ | 169 | /* Ensure we send subsequent alerts with the correct record version. */ |
169 | tls13_record_layer_set_legacy_version(ctx->rl, TLS1_2_VERSION); | 170 | tls13_record_layer_set_legacy_version(ctx->rl, TLS1_2_VERSION); |