summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_clnt.c
diff options
context:
space:
mode:
authorjsing <>2021-10-23 14:40:54 +0000
committerjsing <>2021-10-23 14:40:54 +0000
commit48d78838532f827ee48f8f73f24be6e77d4bbf0f (patch)
treece6df35f3dc86483e4bf5fb3d4d1a4ada8d56b08 /src/lib/libssl/ssl_clnt.c
parent29938589622ccf645f7dc926feb10e611775c666 (diff)
downloadopenbsd-48d78838532f827ee48f8f73f24be6e77d4bbf0f.tar.gz
openbsd-48d78838532f827ee48f8f73f24be6e77d4bbf0f.tar.bz2
openbsd-48d78838532f827ee48f8f73f24be6e77d4bbf0f.zip
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@
Diffstat (limited to 'src/lib/libssl/ssl_clnt.c')
-rw-r--r--src/lib/libssl/ssl_clnt.c52
1 files changed, 16 insertions, 36 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) {