Use size of server key when selecting signature algorithm. Reviewed-by: Richard Levitte <levitte@openssl.org> Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/4389)
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 9dfbb8e..a2be135 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c
@@ -788,6 +788,27 @@ } /* + * Check if key is large enough to generate RSA-PSS signature. + * + * The key must greater than or equal to 2 * hash length + 2. + * SHA512 has a hash length of 64 bytes, which is incompatible + * with a 128 byte (1024 bit) key. + */ +#define RSA_PSS_MINIMUM_KEY_SIZE(md) (2 * EVP_MD_size(md) + 2) +static int rsa_pss_check_min_key_size(const RSA *rsa, const SIGALG_LOOKUP *lu) +{ + const EVP_MD *md; + + if (rsa == NULL) + return 0; + if (!tls1_lookup_md(lu, &md) || md == NULL) + return 0; + if (RSA_size(rsa) < RSA_PSS_MINIMUM_KEY_SIZE(md)) + return 0; + return 1; +} + +/* * Return a signature algorithm for TLS < 1.2 where the signature type * is fixed by the certificate type. */ @@ -2303,6 +2324,12 @@ #else continue; #endif + } else if (lu->sig == EVP_PKEY_RSA_PSS) { + /* validate that key is large enough for the signature algorithm */ + const RSA *rsa = EVP_PKEY_get0_RSA(s->cert->pkeys[SSL_PKEY_RSA_PSS_SIGN].privatekey); + + if (!rsa_pss_check_min_key_size(rsa, lu)) + continue; } break; } @@ -2356,6 +2383,13 @@ sig_idx = SSL_PKEY_RSA; } } + if (lu->sig == EVP_PKEY_RSA_PSS) { + /* validate that key is large enough for the signature algorithm */ + const RSA *rsa = EVP_PKEY_get0_RSA(s->cert->pkeys[SSL_PKEY_RSA_PSS_SIGN].privatekey); + + if (!rsa_pss_check_min_key_size(rsa, lu)) + continue; + } #ifndef OPENSSL_NO_EC if (curve == -1 || lu->curve == curve) #endif