Process signature algorithms before deciding on certificate.

The supported signature algorithms extension needs to be processed before
the certificate to use is decided and before a cipher is selected (as the
set of shared signature algorithms supported may impact the choice).
Reviewed-by: Matt Caswell <matt@openssl.org>

(cherry picked from commit 56e8dc542bd693b2dccea8828b3d8e5fc6932d0c)

Conflicts:
	ssl/ssl.h
	ssl/ssl_err.c
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index bef055a..b553326 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -1378,6 +1378,11 @@
 			goto f_err;
 			}
 		ciphers=NULL;
+		if (!tls1_set_server_sigalgs(s))
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
+			goto err;
+			}
 		/* Let cert callback update server certificates if required */
 		retry_cert:		
 		if (s->cert->cert_cb)
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 343247c..681dec9 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -2682,7 +2682,6 @@
 #define SSL_F_SSL_CERT_INSTANTIATE			 214
 #define SSL_F_SSL_CERT_NEW				 162
 #define SSL_F_SSL_CERT_SET0_CHAIN			 340
-#define SSL_F_SSL_CHECK_CLIENTHELLO_TLSEXT_LATE		 335
 #define SSL_F_SSL_CHECK_PRIVATE_KEY			 163
 #define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT		 280
 #define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG		 279
@@ -2782,6 +2781,7 @@
 #define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT		 276
 #define SSL_F_TLS1_PRF					 284
 #define SSL_F_TLS1_SETUP_KEY_BLOCK			 211
+#define SSL_F_TLS1_SET_SERVER_SIGALGS			 335
 #define SSL_F_WRITE_PENDING				 212
 
 /* Reason codes. */
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 3c83fc8..463301e 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -201,7 +201,6 @@
 {ERR_FUNC(SSL_F_SSL_CERT_INSTANTIATE),	"SSL_CERT_INSTANTIATE"},
 {ERR_FUNC(SSL_F_SSL_CERT_NEW),	"ssl_cert_new"},
 {ERR_FUNC(SSL_F_SSL_CERT_SET0_CHAIN),	"ssl_cert_set0_chain"},
-{ERR_FUNC(SSL_F_SSL_CHECK_CLIENTHELLO_TLSEXT_LATE),	"ssl_check_clienthello_tlsext_late"},
 {ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY),	"SSL_check_private_key"},
 {ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT),	"SSL_CHECK_SERVERHELLO_TLSEXT"},
 {ERR_FUNC(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG),	"ssl_check_srvr_ecc_cert_and_alg"},
@@ -301,6 +300,7 @@
 {ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT),	"TLS1_PREPARE_SERVERHELLO_TLSEXT"},
 {ERR_FUNC(SSL_F_TLS1_PRF),	"tls1_prf"},
 {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK),	"tls1_setup_key_block"},
+{ERR_FUNC(SSL_F_TLS1_SET_SERVER_SIGALGS),	"tls1_set_server_sigalgs"},
 {ERR_FUNC(SSL_F_WRITE_PENDING),	"WRITE_PENDING"},
 {0,NULL}
 	};
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 1fd6bb1..8d2475c 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -1329,6 +1329,7 @@
 unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit, int *al);
 unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit, int *al);
 int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n);
+int tls1_set_server_sigalgs(SSL *s);
 int ssl_check_clienthello_tlsext_late(SSL *s);
 int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n);
 int ssl_prepare_clienthello_tlsext(SSL *s);
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 4e08167..db45c60 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -2967,11 +2967,54 @@
 		}
 	}
 
+int tls1_set_server_sigalgs(SSL *s)
+	{
+	int al;
+	size_t i;
+	/* Clear any shared sigtnature algorithms */
+	if (s->cert->shared_sigalgs)
+		{
+		OPENSSL_free(s->cert->shared_sigalgs);
+		s->cert->shared_sigalgs = NULL;
+		}
+	/* Clear certificate digests and validity flags */
+	for (i = 0; i < SSL_PKEY_NUM; i++)
+		{
+		s->cert->pkeys[i].digest = NULL;
+		s->cert->pkeys[i].valid_flags = 0;
+		}
+
+	/* If sigalgs received process it. */
+	if (s->cert->peer_sigalgs)
+		{
+		if (!tls1_process_sigalgs(s))
+			{
+			SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
+					ERR_R_MALLOC_FAILURE);
+			al = SSL_AD_INTERNAL_ERROR;
+			goto err;
+			}
+		/* Fatal error is no shared signature algorithms */
+		if (!s->cert->shared_sigalgs)
+			{
+			SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
+					SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
+			al = SSL_AD_ILLEGAL_PARAMETER;
+			goto err;
+			}
+		}
+	else
+		ssl_cert_set_default_md(s->cert);
+	return 1;
+	err:
+	ssl3_send_alert(s, SSL3_AL_FATAL, al);
+	return 0;
+	}
+
 int ssl_check_clienthello_tlsext_late(SSL *s)
 	{
 	int ret = SSL_TLSEXT_ERR_OK;
 	int al;
-	size_t i;
 
 	/* If status request then ask callback what to do.
  	 * Note: this must be called after servername callbacks in case
@@ -3017,43 +3060,6 @@
 	else
 		s->tlsext_status_expected = 0;
 
-	/* Clear any shared sigtnature algorithms */
-	if (s->cert->shared_sigalgs)
-		{
-		OPENSSL_free(s->cert->shared_sigalgs);
-		s->cert->shared_sigalgs = NULL;
-		}
-	/* Clear certificate digests and validity flags */
-	for (i = 0; i < SSL_PKEY_NUM; i++)
-		{
-		s->cert->pkeys[i].digest = NULL;
-		s->cert->pkeys[i].valid_flags = 0;
-		}
-
-	/* If sigalgs received process it. */
-	if (s->cert->peer_sigalgs)
-		{
-		if (!tls1_process_sigalgs(s))
-			{
-			SSLerr(SSL_F_SSL_CHECK_CLIENTHELLO_TLSEXT_LATE,
-					ERR_R_MALLOC_FAILURE);
-			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-			al = SSL_AD_INTERNAL_ERROR;
-			goto err;
-			}
-		/* Fatal error is no shared signature algorithms */
-		if (!s->cert->shared_sigalgs)
-			{
-			SSLerr(SSL_F_SSL_CHECK_CLIENTHELLO_TLSEXT_LATE,
-					SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
-			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-			al = SSL_AD_ILLEGAL_PARAMETER;
-			goto err;
-			}
-		}
-	else
-		ssl_cert_set_default_md(s->cert);
-
  err:
 	switch (ret)
 		{