The branch master has been updated via 030da84412c5e01c070a580ad237e713c2057626 (commit) via ecfbe2f0461b399b6bf99bdaa95c460ece8e693e (commit) from 76191c7999e0d1f709ea468950457f71cea378c4 (commit)
- Log ----------------------------------------------------------------- commit 030da84412c5e01c070a580ad237e713c2057626 Author: Richard Levitte <levi...@openssl.org> Date: Fri Dec 4 09:34:25 2020 +0100 EVP: Adjust EVP_PKEY_size(), EVP_PKEY_bits() and EVP_PKEY_security_bits() These functions are documented to return 0 if the size they are supposed to return 0 if the size isn't available. They needed a bit of adjustment to actually do so, since the backend functions they call might return negative numbers in that case. Reviewed-by: Tomas Mraz <tm...@fedoraproject.org> (Merged from https://github.com/openssl/openssl/pull/13611) commit ecfbe2f0461b399b6bf99bdaa95c460ece8e693e Author: Richard Levitte <levi...@openssl.org> Date: Fri Dec 4 08:55:19 2020 +0100 DSA: Make DSA_bits() and DSA_size() check that there are key parameters Without these check, a DSA structure without key parameters will cause these functions to crash. This is also the case in pre-3.0 OpenSSL, but since we now extract these data early, to cache them in the EVP_PKEY structure, the same crash happens earlier and much more internally. The added checks are of the same kind as DSA_security_bits() already does. Fixes #13610 Reviewed-by: Tomas Mraz <tm...@fedoraproject.org> (Merged from https://github.com/openssl/openssl/pull/13611) ----------------------------------------------------------------------- Summary of changes: crypto/dsa/dsa_lib.c | 4 +++- crypto/dsa/dsa_sign.c | 12 +++++++----- crypto/evp/p_lib.c | 28 +++++++++++++++------------- doc/man3/DSA_size.pod | 19 +++++++++++-------- 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index 983a463ff5..4a9f572edd 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -335,7 +335,9 @@ int DSA_security_bits(const DSA *d) int DSA_bits(const DSA *dsa) { - return BN_num_bits(dsa->params.p); + if (dsa->params.p != NULL) + return BN_num_bits(dsa->params.p); + return -1; } FFC_PARAMS *dsa_get0_params(DSA *dsa) diff --git a/crypto/dsa/dsa_sign.c b/crypto/dsa/dsa_sign.c index 58e53e5c35..0f866c12fe 100644 --- a/crypto/dsa/dsa_sign.c +++ b/crypto/dsa/dsa_sign.c @@ -118,14 +118,16 @@ int i2d_DSA_SIG(const DSA_SIG *sig, unsigned char **ppout) int DSA_size(const DSA *dsa) { - int ret; + int ret = -1; DSA_SIG sig; - sig.r = sig.s = dsa->params.q; - ret = i2d_DSA_SIG(&sig, NULL); + if (dsa->params.q != NULL) { + sig.r = sig.s = dsa->params.q; + ret = i2d_DSA_SIG(&sig, NULL); - if (ret < 0) - ret = 0; + if (ret < 0) + ret = 0; + } return ret; } diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index b8c623f90a..f1eb859cef 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -55,24 +55,26 @@ static void evp_pkey_free_it(EVP_PKEY *key); int EVP_PKEY_bits(const EVP_PKEY *pkey) { + int size = 0; + if (pkey != NULL) { - if (pkey->ameth == NULL) - return pkey->cache.bits; - else if (pkey->ameth->pkey_bits) - return pkey->ameth->pkey_bits(pkey); + size = pkey->cache.bits; + if (pkey->ameth != NULL && pkey->ameth->pkey_bits != NULL) + size = pkey->ameth->pkey_bits(pkey); } - return 0; + return size < 0 ? 0 : size; } int EVP_PKEY_security_bits(const EVP_PKEY *pkey) { - if (pkey == NULL) - return 0; - if (pkey->ameth == NULL) - return pkey->cache.security_bits; - if (pkey->ameth->pkey_security_bits == NULL) - return -2; - return pkey->ameth->pkey_security_bits(pkey); + int size = 0; + + if (pkey != NULL) { + size = pkey->cache.security_bits; + if (pkey->ameth != NULL && pkey->ameth->pkey_security_bits != NULL) + size = pkey->ameth->pkey_security_bits(pkey); + } + return size < 0 ? 0 : size; } int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) @@ -1656,7 +1658,7 @@ int EVP_PKEY_size(const EVP_PKEY *pkey) size = pkey->ameth->pkey_size(pkey); #endif } - return size; + return size < 0 ? 0 : size; } void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx, diff --git a/doc/man3/DSA_size.pod b/doc/man3/DSA_size.pod index 404f1bb231..992357c4e0 100644 --- a/doc/man3/DSA_size.pod +++ b/doc/man3/DSA_size.pod @@ -20,27 +20,30 @@ L<openssl_user_macros(7)>: =head1 DESCRIPTION -DSA_bits() returns the number of bits in key B<dsa>: this is the number -of bits in the B<p> parameter. +DSA_bits() returns the number of bits in key I<dsa>: this is the number +of bits in the I<p> parameter. The remaining functions described on this page are deprecated. Applications should instead use L<EVP_PKEY_security_bits(3)> and L<EVP_PKEY_size(3)>. DSA_size() returns the maximum size of an ASN.1 encoded DSA signature -for key B<dsa> in bytes. It can be used to determine how much memory must +for key I<dsa> in bytes. It can be used to determine how much memory must be allocated for a DSA signature. -B<dsa-E<gt>q> must not be B<NULL>. - -DSA_security_bits() returns the number of security bits of the given B<dsa> +DSA_security_bits() returns the number of security bits of the given I<dsa> key. See L<BN_security_bits(3)>. =head1 RETURN VALUES -DSA_bits() returns the number of bits in the key. +DSA_security_bits() returns the number of security bits in the key, or -1 if +I<dsa> doesn't hold any key parameters. + +DSA_bits() returns the number of bits in the key, or -1 if I<dsa> doesn't +hold any key parameters. -DSA_size() returns the signature size in bytes. +DSA_size() returns the signature size in bytes, or -1 if I<dsa> doesn't +hold any key parameters. =head1 SEE ALSO