From 620c97b671a9c7bc31ca36a24b2242aa1aa80022 Mon Sep 17 00:00:00 2001 From: Kurt Roeckx Date: Sun, 9 Feb 2020 19:28:15 +0100 Subject: Check that ed25519 and ed448 are allowed by the security level Signature algorithms not using an MD weren't checked that they're allowed by the security level. Reviewed-by: Matt Caswell GH: #10785 --- ssl/t1_lib.c | 59 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 18 deletions(-) (limited to 'ssl') diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 103a8f18bb..aedb521015 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1075,6 +1075,31 @@ int tls_check_sigalg_curve(const SSL *s, int curve) } #endif +/* + * Return the number of security bits for the signature algorithm, or 0 on + * error. + */ +static int sigalg_security_bits(SSL_CTX *ctx, const SIGALG_LOOKUP *lu) +{ + const EVP_MD *md = NULL; + int secbits = 0; + + if (!tls1_lookup_md(ctx, lu, &md)) + return 0; + if (md != NULL) + { + /* Security bits: half digest bits */ + secbits = EVP_MD_size(md) * 4; + } else { + /* Values from https://tools.ietf.org/html/rfc8032#section-8.5 */ + if (lu->sigalg == TLSEXT_SIGALG_ed25519) + secbits = 128; + else if (lu->sigalg == TLSEXT_SIGALG_ed448) + secbits = 224; + } + return secbits; +} + /* * Check signature algorithm is consistent with sent supported signature * algorithms and if so set relevant digest and signature scheme in @@ -1088,6 +1113,7 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) size_t sent_sigslen, i, cidx; int pkeyid = EVP_PKEY_id(pkey); const SIGALG_LOOKUP *lu; + int secbits = 0; /* Should never happen */ if (pkeyid == -1) @@ -1189,20 +1215,20 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) SSL_R_UNKNOWN_DIGEST); return 0; } - if (md != NULL) { - /* - * Make sure security callback allows algorithm. For historical - * reasons we have to pass the sigalg as a two byte char array. - */ - sigalgstr[0] = (sig >> 8) & 0xff; - sigalgstr[1] = sig & 0xff; - if (!ssl_security(s, SSL_SECOP_SIGALG_CHECK, - EVP_MD_size(md) * 4, EVP_MD_type(md), - (void *)sigalgstr)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); - return 0; - } + /* + * Make sure security callback allows algorithm. For historical + * reasons we have to pass the sigalg as a two byte char array. + */ + sigalgstr[0] = (sig >> 8) & 0xff; + sigalgstr[1] = sig & 0xff; + secbits = sigalg_security_bits(s->ctx, lu); + if (secbits == 0 || + !ssl_security(s, SSL_SECOP_SIGALG_CHECK, secbits, + md != NULL ? EVP_MD_type(md) : NID_undef, + (void *)sigalgstr)) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, + SSL_R_WRONG_SIGNATURE_TYPE); + return 0; } /* Store the sigalg the peer uses */ s->s3.tmp.peer_sigalg = lu; @@ -1726,11 +1752,8 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) } } - if (lu->hash == NID_undef) - return 1; - /* Security bits: half digest bits */ - secbits = EVP_MD_size(ssl_md(s->ctx, lu->hash_idx)) * 4; /* Finally see if security callback allows it */ + secbits = sigalg_security_bits(s->ctx, lu); sigalgstr[0] = (lu->sigalg >> 8) & 0xff; sigalgstr[1] = lu->sigalg & 0xff; return ssl_security(s, op, secbits, lu->hash, (void *)sigalgstr); -- cgit v1.2.3