From 48d78838532f827ee48f8f73f24be6e77d4bbf0f Mon Sep 17 00:00:00 2001 From: jsing <> Date: Sat, 23 Oct 2021 14:40:54 +0000 Subject: Provide a way to determine our maximum legacy version. With the introduction of TLSv1.3, we need the ability to determine our maximum legacy version and to track our peer's maximum legacy version. This is needed for both the TLS record layer when using TLSv1.3, plus it is needed for RSA key exhange in TLS prior to TLSv1.3, where the maximum legacy version is incorporated in the pre-master secret to avoid downgrade attacks. This unbreaks RSA KEX for the TLS client when the non-version specific method is used with TLSv1.0 or TLSv1.1 (clearly no one does this). ok tb@ --- src/lib/libssl/ssl_srvr.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'src/lib/libssl/ssl_srvr.c') 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 @@ -/* $OpenBSD: ssl_srvr.c,v 1.121 2021/10/23 13:36:03 jsing Exp $ */ +/* $OpenBSD: ssl_srvr.c,v 1.122 2021/10/23 14:40:54 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -837,19 +837,19 @@ ssl3_get_client_hello(SSL *s) * (may differ: see RFC 2246, Appendix E, second paragraph) */ if (!ssl_max_shared_version(s, client_version, &shared_version)) { - if ((s->client_version >> 8) == SSL3_VERSION_MAJOR && + if ((client_version >> 8) == SSL3_VERSION_MAJOR && !tls12_record_layer_write_protected(s->internal->rl)) { /* * Similar to ssl3_get_record, send alert using remote * version number. */ - s->version = s->client_version; + s->version = client_version; } SSLerror(s, SSL_R_WRONG_VERSION_NUMBER); al = SSL_AD_PROTOCOL_VERSION; goto fatal_err; } - s->client_version = client_version; + S3I(s)->hs.peer_legacy_version = client_version; s->version = shared_version; S3I(s)->hs.negotiated_tls_version = ssl_tls_version(shared_version); @@ -1723,9 +1723,8 @@ ssl3_get_client_kex_rsa(SSL *s, CBS *cbs) arc4random_buf(fakekey, sizeof(fakekey)); - /* XXX - peer max protocol version. */ - fakekey[0] = s->client_version >> 8; - fakekey[1] = s->client_version & 0xff; + fakekey[0] = S3I(s)->hs.peer_legacy_version >> 8; + fakekey[1] = S3I(s)->hs.peer_legacy_version & 0xff; pkey = s->cert->pkeys[SSL_PKEY_RSA].privatekey; if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA) || @@ -1760,9 +1759,8 @@ ssl3_get_client_kex_rsa(SSL *s, CBS *cbs) /* SSLerror(s, SSL_R_BAD_RSA_DECRYPT); */ } - /* XXX - peer max version. */ - if ((al == -1) && !((pms[0] == (s->client_version >> 8)) && - (pms[1] == (s->client_version & 0xff)))) { + if ((al == -1) && !((pms[0] == (S3I(s)->hs.peer_legacy_version >> 8)) && + (pms[1] == (S3I(s)->hs.peer_legacy_version & 0xff)))) { /* * The premaster secret must contain the same version number * as the ClientHello to detect version rollback attacks -- cgit v1.2.3-55-g6feb