Process signature algorithms before deciding on certificate.
authorDr. Stephen Henson <steve@openssl.org>
Mon, 17 Nov 2014 16:52:59 +0000 (16:52 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 19 Nov 2014 14:49:12 +0000 (14:49 +0000)
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

ssl/s3_srvr.c
ssl/ssl.h
ssl/ssl_err.c
ssl/ssl_locl.h
ssl/t1_lib.c

index bef055a..b553326 100644 (file)
@@ -1378,6 +1378,11 @@ int ssl3_get_client_hello(SSL *s)
                        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)
index 343247c..681dec9 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -2682,7 +2682,6 @@ void ERR_load_SSL_strings(void);
 #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 @@ void ERR_load_SSL_strings(void);
 #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. */
index 3c83fc8..463301e 100644 (file)
@@ -201,7 +201,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {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 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {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}
        };
index 1fd6bb1..8d2475c 100644 (file)
@@ -1329,6 +1329,7 @@ int tls1_shared_list(SSL *s,
 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);
index 4e08167..db45c60 100644 (file)
@@ -2967,11 +2967,54 @@ static int ssl_check_clienthello_tlsext_early(SSL *s)
                }
        }
 
+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 @@ int ssl_check_clienthello_tlsext_late(SSL *s)
        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)
                {