From 63eab8a620944a990ab3985620966ccd9f48d681 Mon Sep 17 00:00:00 2001
From: "Dr. Stephen Henson" <steve@openssl.org>
Date: Fri, 24 Oct 2014 02:36:13 +0100
Subject: [PATCH] Remove MS SGC

MS Server gated cryptography is obsolete and dates from the time of export
restrictions on strong encryption and is only used by ancient versions of
MSIE.
Reviewed-by: Matt Caswell <matt@openssl.org>
---
 doc/crypto/BIO_f_ssl.pod     |  2 +-
 doc/ssl/SSL_accept.pod       |  5 +--
 doc/ssl/SSL_do_handshake.pod |  5 +--
 ssl/d1_srvr.c                | 21 +++--------
 ssl/s3_both.c                | 11 ------
 ssl/s3_srvr.c                | 69 ++++--------------------------------
 ssl/ssl_locl.h               |  1 -
 7 files changed, 15 insertions(+), 99 deletions(-)

diff --git a/doc/crypto/BIO_f_ssl.pod b/doc/crypto/BIO_f_ssl.pod
index bc5861ab34..a9f23f1dd7 100644
--- a/doc/crypto/BIO_f_ssl.pod
+++ b/doc/crypto/BIO_f_ssl.pod
@@ -108,7 +108,7 @@ SSL BIOs are exceptional in that if the underlying transport
 is non blocking they can still request a retry in exceptional
 circumstances. Specifically this will happen if a session
 renegotiation takes place during a BIO_read() operation, one
-case where this happens is when SGC or step up occurs.
+case where this happens is when step up occurs.
 
 In OpenSSL 0.9.6 and later the SSL flag SSL_AUTO_RETRY can be
 set to disable this behaviour. That is when this flag is set
diff --git a/doc/ssl/SSL_accept.pod b/doc/ssl/SSL_accept.pod
index 2239444174..89ad6bd0ba 100644
--- a/doc/ssl/SSL_accept.pod
+++ b/doc/ssl/SSL_accept.pod
@@ -21,10 +21,7 @@ B<ssl> by setting an underlying B<BIO>.
 The behaviour of SSL_accept() depends on the underlying BIO. 
 
 If the underlying BIO is B<blocking>, SSL_accept() will only return once the
-handshake has been finished or an error occurred, except for SGC (Server
-Gated Cryptography). For SGC, SSL_accept() may return with -1, but
-SSL_get_error() will yield B<SSL_ERROR_WANT_READ/WRITE> and SSL_accept()
-should be called again.
+handshake has been finished or an error occurred.
 
 If the underlying BIO is B<non-blocking>, SSL_accept() will also return
 when the underlying BIO could not satisfy the needs of SSL_accept()
diff --git a/doc/ssl/SSL_do_handshake.pod b/doc/ssl/SSL_do_handshake.pod
index b35ddf5f14..8b590c9f16 100644
--- a/doc/ssl/SSL_do_handshake.pod
+++ b/doc/ssl/SSL_do_handshake.pod
@@ -23,10 +23,7 @@ L<SSL_set_accept_state(3)|SSL_set_accept_state(3)>.
 The behaviour of SSL_do_handshake() depends on the underlying BIO.
 
 If the underlying BIO is B<blocking>, SSL_do_handshake() will only return
-once the handshake has been finished or an error occurred, except for SGC
-(Server Gated Cryptography). For SGC, SSL_do_handshake() may return with -1,
-but SSL_get_error() will yield B<SSL_ERROR_WANT_READ/WRITE> and
-SSL_do_handshake() should be called again.
+once the handshake has been finished or an error occurred.
 
 If the underlying BIO is B<non-blocking>, SSL_do_handshake() will also return
 when the underlying BIO could not satisfy the needs of SSL_do_handshake()
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 0cdc51be23..bcadd310fd 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -610,24 +610,13 @@ int dtls1_accept(SSL *s)
 
 		case SSL3_ST_SR_CERT_A:
 		case SSL3_ST_SR_CERT_B:
-			/* Check for second client hello (MS SGC) */
-			ret = ssl3_check_client_hello(s);
-			if (ret <= 0)
-				goto end;
-			if (ret == 2)
+			if (s->s3->tmp.cert_request)
 				{
-				dtls1_stop_timer(s);
-				s->state = SSL3_ST_SR_CLNT_HELLO_C;
+				ret=ssl3_get_client_certificate(s);
+				if (ret <= 0) goto end;
 				}
-			else {
-				if (s->s3->tmp.cert_request)
-					{
-					ret=ssl3_get_client_certificate(s);
-					if (ret <= 0) goto end;
-					}
-				s->init_num=0;
-				s->state=SSL3_ST_SR_KEY_EXCH_A;
-			}
+			s->init_num=0;
+			s->state=SSL3_ST_SR_KEY_EXCH_A;
 			break;
 
 		case SSL3_ST_SR_KEY_EXCH_A:
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
index 6c0fb37c29..845c803e23 100644
--- a/ssl/s3_both.c
+++ b/ssl/s3_both.c
@@ -412,17 +412,6 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
 			SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
 			goto f_err;
 			}
-		if ((mt < 0) && (*p == SSL3_MT_CLIENT_HELLO) &&
-					(st1 == SSL3_ST_SR_CERT_A) &&
-					(stn == SSL3_ST_SR_CERT_B))
-			{
-			/* At this point we have got an MS SGC second client
-			 * hello (maybe we should always allow the client to
-			 * start a new handshake?). We need to restart the mac.
-			 * Don't increment {num,total}_renegotiations because
-			 * we have not completed the handshake. */
-			ssl3_init_finished_mac(s);
-			}
 
 		s->s3->tmp.message_type= *(p++);
 
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index a3085771d6..6c0bdcf437 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -308,7 +308,6 @@ int ssl3_accept(SSL *s)
 				}
 
 			s->init_num=0;
-			s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
 			s->s3->flags &= ~TLS1_FLAGS_SKIP_CERT_VERIFY;
 			s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
 			/* Should have been reset by ssl3_get_finished, too. */
@@ -592,21 +591,13 @@ int ssl3_accept(SSL *s)
 
 		case SSL3_ST_SR_CERT_A:
 		case SSL3_ST_SR_CERT_B:
-			/* Check for second client hello (MS SGC) */
-			ret = ssl3_check_client_hello(s);
-			if (ret <= 0)
-				goto end;
-			if (ret == 2)
-				s->state = SSL3_ST_SR_CLNT_HELLO_C;
-			else {
-				if (s->s3->tmp.cert_request)
-					{
-					ret=ssl3_get_client_certificate(s);
-					if (ret <= 0) goto end;
-					}
-				s->init_num=0;
-				s->state=SSL3_ST_SR_KEY_EXCH_A;
-			}
+			if (s->s3->tmp.cert_request)
+				{
+				ret=ssl3_get_client_certificate(s);
+				if (ret <= 0) goto end;
+				}
+			s->init_num=0;
+			s->state=SSL3_ST_SR_KEY_EXCH_A;
 			break;
 
 		case SSL3_ST_SR_KEY_EXCH_A:
@@ -907,52 +898,6 @@ int ssl3_send_hello_request(SSL *s)
 	return ssl_do_write(s);
 	}
 
-int ssl3_check_client_hello(SSL *s)
-	{
-	int ok;
-	long n;
-
-	/* this function is called when we really expect a Certificate message,
-	 * so permit appropriate message length */
-	n=s->method->ssl_get_message(s,
-		SSL3_ST_SR_CERT_A,
-		SSL3_ST_SR_CERT_B,
-		-1,
-		s->max_cert_list,
-		&ok);
-	if (!ok) return((int)n);
-	s->s3->tmp.reuse_message = 1;
-	if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
-		{
-		/* We only allow the client to restart the handshake once per
-		 * negotiation. */
-		if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE)
-			{
-			SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS);
-			return -1;
-			}
-		/* Throw away what we have done so far in the current handshake,
-		 * which will now be aborted. (A full SSL_clear would be too much.) */
-#ifndef OPENSSL_NO_DH
-		if (s->s3->tmp.dh != NULL)
-			{
-			DH_free(s->s3->tmp.dh);
-			s->s3->tmp.dh = NULL;
-			}
-#endif
-#ifndef OPENSSL_NO_ECDH
-		if (s->s3->tmp.ecdh != NULL)
-			{
-			EC_KEY_free(s->s3->tmp.ecdh);
-			s->s3->tmp.ecdh = NULL;
-			}
-#endif
-		s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE;
-		return 2;
-		}
-	return 1;
-}
-
 int ssl3_get_client_hello(SSL *s)
 	{
 	int i,j,ok,al=SSL_AD_INTERNAL_ERROR,ret= -1;
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index facfec5d3b..33a55fe699 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -1185,7 +1185,6 @@ int ssl3_send_hello_request(SSL *s);
 int ssl3_send_server_key_exchange(SSL *s);
 int ssl3_send_certificate_request(SSL *s);
 int ssl3_send_server_done(SSL *s);
-int ssl3_check_client_hello(SSL *s);
 int ssl3_get_client_certificate(SSL *s);
 int ssl3_get_client_key_exchange(SSL *s);
 int ssl3_get_cert_verify(SSL *s);
-- 
GitLab