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:44:42 +0000 (14:44 +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>
ssl/s3_srvr.c
ssl/ssl.h
ssl/ssl_err.c
ssl/ssl_locl.h
ssl/t1_lib.c

index f92084b9f0af70c94925737d80c3a81c36f7a74d..cb003a5391f03bdc337e95f51c75b8bc9703dd3b 100644 (file)
@@ -1371,6 +1371,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 7da0b212b86b9aebe96bb80304c850e5f1c35d1e..82e5894a3aa1b5f081fa078ffc0cb29b45075f78 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -2586,7 +2586,6 @@ void ERR_load_SSL_strings(void);
 #define SSL_F_SSL_CERT_INST                             222
 #define SSL_F_SSL_CERT_INSTANTIATE                      214
 #define SSL_F_SSL_CERT_NEW                              162
-#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
@@ -2686,6 +2685,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 bcd124ed6b58ce303397f2ed23ad866d0d664359..b3dc65ba83575cdaa0b22092f278c73d6ca5905f 100644 (file)
@@ -199,7 +199,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_FUNC(SSL_F_SSL_CERT_INST),        "ssl_cert_inst"},
 {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_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"},
@@ -299,6 +298,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 afd144645b31b580bdc47294f8ef7dc2262ddacc..3973fafdc76d56677230ea110a45c84d75a7cb86 100644 (file)
@@ -1312,6 +1312,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 bbd353a1889848f1942633a048990f1217cfe6b4..f85a0b8c0821aad020c70dd5f0fed99609c1a776 100644 (file)
@@ -3008,11 +3008,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
@@ -3058,43 +3101,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)
                {