From e469af8d05dd28b1e77de9d8045b2ddd6cb6ee5d Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 17 Nov 2014 16:52:59 +0000 Subject: [PATCH] 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 (cherry picked from commit 56e8dc542bd693b2dccea8828b3d8e5fc6932d0c) Conflicts: ssl/ssl.h ssl/ssl_err.c --- ssl/s3_srvr.c | 5 +++ ssl/ssl.h | 2 +- ssl/ssl_err.c | 2 +- ssl/ssl_locl.h | 1 + ssl/t1_lib.c | 82 +++++++++++++++++++++++++++----------------------- 5 files changed, 52 insertions(+), 40 deletions(-) diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index bef055ac05..b553326281 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -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) diff --git a/ssl/ssl.h b/ssl/ssl.h index 343247ccf4..681dec9c67 100644 --- 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. */ diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 3c83fc8ae5..463301eb2f 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -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} }; diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 1fd6bb1e06..8d2475c97e 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -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); diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 4e0816746c..db45c60534 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -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) { -- 2.25.1