From 37569e64e8012014a4b027d896da6c6cdf372507 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Bodo=20M=C3=B6ller?= <bodo@openssl.org>
Date: Sat, 29 Jul 2000 18:50:41 +0000
Subject: [PATCH] Fix SSL 2.0 rollback checking: The previous implementation of
 the test was never triggered due to an off-by-one error.

In s23_clnt.c, don't use special rollback-attack detection padding
(RSA_SSLV23_PADDING) if SSL 2.0 is the only protocol enabled in the
client; similarly, in s23_srvr.c, don't do the rollback check if
SSL 2.0 is the only protocol enabled in the server.
---
 CHANGES              | 9 +++++++++
 crypto/rsa/rsa_ssl.c | 2 +-
 ssl/s23_clnt.c       | 3 ++-
 ssl/s23_srvr.c       | 3 ++-
 4 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/CHANGES b/CHANGES
index e25b9eaed4..159c1e27e7 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,15 @@
 
  Changes between 0.9.5a and 0.9.6  [xx XXX 2000]
 
+  *) Fix SSL 2.0 rollback checking: The previous implementation of the
+     test was never triggered due to an off-by-one error in
+     RSA_padding_check_SSLv23().
+     In s23_clnt.c, don't use special rollback-attack detection padding
+     (RSA_SSLV23_PADDING) if SSL 2.0 is the only protocol enabled in the
+     client; similarly, in s23_srvr.c, don't do the rollback check if
+     SSL 2.0 is the only protocol enabled in the server.
+     [Bodo Moeller]
+
   *) Make it possible to get hexdumps of unprintable data with 'openssl
      asn1parse'.  By implication, the functions ASN1_parse_dump() and
      BIO_dump_indent() are added.
diff --git a/crypto/rsa/rsa_ssl.c b/crypto/rsa/rsa_ssl.c
index 81a857c813..482f4a8273 100644
--- a/crypto/rsa/rsa_ssl.c
+++ b/crypto/rsa/rsa_ssl.c
@@ -134,7 +134,7 @@ int RSA_padding_check_SSLv23(unsigned char *to, int tlen, unsigned char *from,
 		{
 		if (p[k] !=  0x03) break;
 		}
-	if (k == 0)
+	if (k == -1)
 		{
 		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_SSLV3_ROLLBACK_ATTACK);
 		return(-1);
diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c
index aaedf6a9bb..99a4358255 100644
--- a/ssl/s23_clnt.c
+++ b/ssl/s23_clnt.c
@@ -366,7 +366,8 @@ static int ssl23_get_server_hello(SSL *s)
 			}
 
 		s->state=SSL2_ST_GET_SERVER_HELLO_A;
-		s->s2->ssl2_rollback=1;
+		if (!(s->client_version == SSL2_VERSION))
+			s->s2->ssl2_rollback=1;
 
 		/* setup the 5 bytes we have read so we get them from
 		 * the sslv2 buffer */
diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c
index 930769be0d..cbf2f5d836 100644
--- a/ssl/s23_srvr.c
+++ b/ssl/s23_srvr.c
@@ -495,7 +495,8 @@ int ssl23_get_client_hello(SSL *s)
 
 		s->state=SSL2_ST_GET_CLIENT_HELLO_A;
 		if ((s->options & SSL_OP_MSIE_SSLV2_RSA_PADDING) ||
-			use_sslv2_strong)
+			use_sslv2_strong ||
+			(s->options & SSL_OP_NO_TLSv1 && s->options & SSL_OP_NO_SSLv3))
 			s->s2->ssl2_rollback=0;
 		else
 			s->s2->ssl2_rollback=1;
-- 
2.40.0