From a9669ddc64e9e383b48bfb7f802c845616d5f66e Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 25 Jan 2017 19:12:48 +0000 Subject: [PATCH] Use correct signature algorithm list when sending or checking. Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/2290) --- ssl/ssl_locl.h | 2 +- ssl/statem/extensions_clnt.c | 2 +- ssl/statem/statem_srvr.c | 2 +- ssl/t1_lib.c | 17 ++++++++++------- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index c7e7872dbd..39e27eac1b 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -2188,7 +2188,7 @@ __owur int tls12_copy_sigalgs(SSL *s, WPACKET *pkt, const unsigned int *psig, size_t psiglen); __owur int tls1_save_sigalgs(SSL *s, PACKET *pkt); __owur int tls1_process_sigalgs(SSL *s); -__owur size_t tls12_get_psigalgs(SSL *s, const unsigned int **psigs); +__owur size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned int **psigs); __owur int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, unsigned int sig, EVP_PKEY *pkey); void ssl_set_client_disabled(SSL *s); diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 18f5ca3d1b..fe007492c5 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -231,7 +231,7 @@ int tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx, if (!SSL_CLIENT_USE_SIGALGS(s)) return 1; - salglen = tls12_get_psigalgs(s, &salg); + salglen = tls12_get_psigalgs(s, 1, &salg); if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signature_algorithms) /* Sub-packet for sig-algs extension */ || !WPACKET_start_sub_packet_u16(pkt) diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 3bde0d6b4a..0043b05dac 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -2310,7 +2310,7 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt) if (SSL_USE_SIGALGS(s)) { const unsigned int *psigs; - size_t nl = tls12_get_psigalgs(s, &psigs); + size_t nl = tls12_get_psigalgs(s, 1, &psigs); if (!WPACKET_start_sub_packet_u16(pkt) || !tls12_copy_sigalgs(s, pkt, psigs, nl) diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index d59d32cdaa..b05d148beb 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -773,8 +773,7 @@ static int tls_sigalg_get_sig(unsigned int sigalg) return 0; } - -size_t tls12_get_psigalgs(SSL *s, const unsigned int **psigs) +size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned int **psigs) { /* * If Suite B mode use Suite B sigalgs only, ignore any other @@ -795,8 +794,12 @@ size_t tls12_get_psigalgs(SSL *s, const unsigned int **psigs) return 1; } #endif - /* If server use client authentication sigalgs if not NULL */ - if (s->server && s->cert->client_sigalgs) { + /* + * We use client_sigalgs (if not NULL) if we're a server + * and sending a certificate request or if we're a client and + * determining which shared algorithm to use. + */ + if ((s->server == sent) && s->cert->client_sigalgs != NULL) { *psigs = s->cert->client_sigalgs; return s->cert->client_sigalgslen; } else if (s->cert->conf_sigalgs) { @@ -861,7 +864,7 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, unsigned int sig, #endif /* Check signature matches a type we sent */ - sent_sigslen = tls12_get_psigalgs(s, &sent_sigs); + sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs); for (i = 0; i < sent_sigslen; i++, sent_sigs++) { if (sig == *sent_sigs) break; @@ -1429,7 +1432,7 @@ void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op) * RSA, DSA, ECDSA. Do this for all versions not just TLS 1.2. To keep * down calls to security callback only check if we have to. */ - sigalgslen = tls12_get_psigalgs(s, &sigalgs); + sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs); for (i = 0; i < sigalgslen; i ++, sigalgs++) { switch (tls_sigalg_get_sig(*sigalgs)) { #ifndef OPENSSL_NO_RSA @@ -1523,7 +1526,7 @@ static int tls1_set_shared_sigalgs(SSL *s) conf = c->conf_sigalgs; conflen = c->conf_sigalgslen; } else - conflen = tls12_get_psigalgs(s, &conf); + conflen = tls12_get_psigalgs(s, 0, &conf); if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) { pref = conf; preflen = conflen; -- 2.25.1