diff options
author | jsing <> | 2020-05-31 16:36:35 +0000 |
---|---|---|
committer | jsing <> | 2020-05-31 16:36:35 +0000 |
commit | a49dcaedc471e79508b3e5674c538ca90f5c4e2e (patch) | |
tree | 1ce257d0fa239a96e7594d053190347cb2b42c4a /src/lib | |
parent | f05dbe69dd53b7d5eabcdb912115a58a46ab676a (diff) | |
download | openbsd-a49dcaedc471e79508b3e5674c538ca90f5c4e2e.tar.gz openbsd-a49dcaedc471e79508b3e5674c538ca90f5c4e2e.tar.bz2 openbsd-a49dcaedc471e79508b3e5674c538ca90f5c4e2e.zip |
Correct downgrade sentinels when a version pinned method is in use.
Previously only the enabled protocol versions were considered, however we
also have to consider the method in use which may be version pinned.
Found the hard way by danj@ with haproxy and force-tlsv12.
ok beck@ inoguchi@ tb@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libssl/ssl_clnt.c | 4 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 3 | ||||
-rw-r--r-- | src/lib/libssl/ssl_srvr.c | 6 | ||||
-rw-r--r-- | src/lib/libssl/ssl_versions.c | 34 |
4 files changed, 40 insertions, 7 deletions
diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c index fb29e4f5f6..4d003466c4 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.67 2020/05/19 16:35:20 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_clnt.c,v 1.68 2020/05/31 16:36:35 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 | * |
@@ -873,7 +873,7 @@ ssl3_get_server_hello(SSL *s) | |||
873 | sizeof(s->s3->server_random), NULL)) | 873 | sizeof(s->s3->server_random), NULL)) |
874 | goto err; | 874 | goto err; |
875 | 875 | ||
876 | if (!SSL_IS_DTLS(s) && !ssl_enabled_version_range(s, NULL, &max_version)) | 876 | if (!ssl_downgrade_max_version(s, &max_version)) |
877 | goto err; | 877 | goto err; |
878 | if (!SSL_IS_DTLS(s) && max_version >= TLS1_2_VERSION && | 878 | if (!SSL_IS_DTLS(s) && max_version >= TLS1_2_VERSION && |
879 | s->version < max_version) { | 879 | s->version < max_version) { |
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index e7e3e56154..03c2c227ed 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.277 2020/05/29 18:00:10 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.278 2020/05/31 16:36:35 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 | * |
@@ -1095,6 +1095,7 @@ int ssl_version_set_min(const SSL_METHOD *meth, uint16_t ver, uint16_t max_ver, | |||
1095 | int ssl_version_set_max(const SSL_METHOD *meth, uint16_t ver, uint16_t min_ver, | 1095 | int ssl_version_set_max(const SSL_METHOD *meth, uint16_t ver, uint16_t min_ver, |
1096 | uint16_t *out_ver); | 1096 | uint16_t *out_ver); |
1097 | uint16_t ssl_max_server_version(SSL *s); | 1097 | uint16_t ssl_max_server_version(SSL *s); |
1098 | int ssl_downgrade_max_version(SSL *s, uint16_t *max_ver); | ||
1098 | int ssl_cipher_is_permitted(const SSL_CIPHER *cipher, uint16_t min_ver, | 1099 | int ssl_cipher_is_permitted(const SSL_CIPHER *cipher, uint16_t min_ver, |
1099 | uint16_t max_ver); | 1100 | uint16_t max_ver); |
1100 | 1101 | ||
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index 6a90ad17eb..fac24f4d00 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.76 2020/05/19 16:35:20 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_srvr.c,v 1.77 2020/05/31 16:36:35 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 | * |
@@ -852,6 +852,8 @@ ssl3_get_client_hello(SSL *s) | |||
852 | * Use version from inside client hello, not from record header. | 852 | * Use version from inside client hello, not from record header. |
853 | * (may differ: see RFC 2246, Appendix E, second paragraph) | 853 | * (may differ: see RFC 2246, Appendix E, second paragraph) |
854 | */ | 854 | */ |
855 | if (!ssl_downgrade_max_version(s, &max_version)) | ||
856 | goto err; | ||
855 | if (ssl_max_shared_version(s, client_version, &shared_version) != 1) { | 857 | if (ssl_max_shared_version(s, client_version, &shared_version) != 1) { |
856 | SSLerror(s, SSL_R_WRONG_VERSION_NUMBER); | 858 | SSLerror(s, SSL_R_WRONG_VERSION_NUMBER); |
857 | if ((s->client_version >> 8) == SSL3_VERSION_MAJOR && | 859 | if ((s->client_version >> 8) == SSL3_VERSION_MAJOR && |
@@ -1047,8 +1049,6 @@ ssl3_get_client_hello(SSL *s) | |||
1047 | */ | 1049 | */ |
1048 | arc4random_buf(s->s3->server_random, SSL3_RANDOM_SIZE); | 1050 | arc4random_buf(s->s3->server_random, SSL3_RANDOM_SIZE); |
1049 | 1051 | ||
1050 | if (!SSL_IS_DTLS(s) && !ssl_enabled_version_range(s, NULL, &max_version)) | ||
1051 | goto err; | ||
1052 | if (!SSL_IS_DTLS(s) && max_version >= TLS1_2_VERSION && | 1052 | if (!SSL_IS_DTLS(s) && max_version >= TLS1_2_VERSION && |
1053 | s->version < max_version) { | 1053 | s->version < max_version) { |
1054 | /* | 1054 | /* |
diff --git a/src/lib/libssl/ssl_versions.c b/src/lib/libssl/ssl_versions.c index 2b5e94e5b8..03eb41582a 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.4 2018/11/06 01:40:23 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_versions.c,v 1.5 2020/05/31 16:36:35 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 | * |
@@ -223,3 +223,35 @@ ssl_max_server_version(SSL *s) | |||
223 | 223 | ||
224 | return (max_version); | 224 | return (max_version); |
225 | } | 225 | } |
226 | |||
227 | int | ||
228 | ssl_downgrade_max_version(SSL *s, uint16_t *max_ver) | ||
229 | { | ||
230 | uint16_t min_version, max_version; | ||
231 | |||
232 | /* | ||
233 | * The downgrade maximum version is based on the versions that are | ||
234 | * enabled, however we also have to then limit to the versions | ||
235 | * supported by the method. The SSL method will be changed during | ||
236 | * version negotiation and when switching from the new stack to | ||
237 | * the legacy context, as such we want to use the method from the | ||
238 | * context. | ||
239 | */ | ||
240 | |||
241 | if (SSL_IS_DTLS(s)) { | ||
242 | *max_ver = DTLS1_VERSION; | ||
243 | return 1; | ||
244 | } | ||
245 | |||
246 | if (!ssl_enabled_version_range(s, &min_version, &max_version)) | ||
247 | return 0; | ||
248 | |||
249 | if (!ssl_clamp_version_range(&min_version, &max_version, | ||
250 | s->ctx->method->internal->min_version, | ||
251 | s->ctx->method->internal->max_version)) | ||
252 | return 0; | ||
253 | |||
254 | *max_ver = max_version; | ||
255 | |||
256 | return 1; | ||
257 | } | ||