summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2020-05-31 16:36:35 +0000
committerjsing <>2020-05-31 16:36:35 +0000
commita49dcaedc471e79508b3e5674c538ca90f5c4e2e (patch)
tree1ce257d0fa239a96e7594d053190347cb2b42c4a /src/lib
parentf05dbe69dd53b7d5eabcdb912115a58a46ab676a (diff)
downloadopenbsd-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.c4
-rw-r--r--src/lib/libssl/ssl_locl.h3
-rw-r--r--src/lib/libssl/ssl_srvr.c6
-rw-r--r--src/lib/libssl/ssl_versions.c34
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,
1095int ssl_version_set_max(const SSL_METHOD *meth, uint16_t ver, uint16_t min_ver, 1095int 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);
1097uint16_t ssl_max_server_version(SSL *s); 1097uint16_t ssl_max_server_version(SSL *s);
1098int ssl_downgrade_max_version(SSL *s, uint16_t *max_ver);
1098int ssl_cipher_is_permitted(const SSL_CIPHER *cipher, uint16_t min_ver, 1099int 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
227int
228ssl_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}