diff options
author | Kurt Roeckx <kurt@roeckx.be> | 2020-02-09 19:28:15 +0100 |
---|---|---|
committer | Kurt Roeckx <kurt@roeckx.be> | 2020-02-11 23:24:03 +0100 |
commit | 620c97b671a9c7bc31ca36a24b2242aa1aa80022 (patch) | |
tree | a80bb9c33933555e073bc385c50295a37a236c3c /ssl/t1_lib.c | |
parent | 77c4d3972400adf1bcb76ceea359f5453cc3e8e4 (diff) | |
download | openssl-620c97b671a9c7bc31ca36a24b2242aa1aa80022.tar.gz |
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 <matt@openssl.org>
GH: #10785
Diffstat (limited to 'ssl/t1_lib.c')
-rw-r--r-- | ssl/t1_lib.c | 59 |
1 files changed, 41 insertions, 18 deletions
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 @@ -1076,6 +1076,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 * s. @@ -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); |