Check for availability of ciphersuites at run time

In 1.1.1 and below we would check for the availability of certain
algorithms based on compile time guards. However with 3.0 this is no
longer sufficient. Some algorithms that are unavailable at compile time
may become available later if 3rd party providers are loaded. Similarly,
algorithms that exist in our built-in providers at compile time may not
be available at run time if those providers are not loaded.

Fixes #13184

Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13916)
This commit is contained in:
Matt Caswell 2021-01-15 15:43:28 +00:00
parent a763ca1177
commit 05b4b85d4b

View File

@ -323,6 +323,8 @@ int ssl_load_ciphers(SSL_CTX *ctx)
{ {
size_t i; size_t i;
const ssl_cipher_table *t; const ssl_cipher_table *t;
EVP_KEYEXCH *kex = NULL;
EVP_SIGNATURE *sig = NULL;
ctx->disabled_enc_mask = 0; ctx->disabled_enc_mask = 0;
for (i = 0, t = ssl_cipher_table_cipher; i < SSL_ENC_NUM_IDX; i++, t++) { for (i = 0, t = ssl_cipher_table_cipher; i < SSL_ENC_NUM_IDX; i++, t++) {
@ -354,16 +356,33 @@ int ssl_load_ciphers(SSL_CTX *ctx)
ctx->disabled_mkey_mask = 0; ctx->disabled_mkey_mask = 0;
ctx->disabled_auth_mask = 0; ctx->disabled_auth_mask = 0;
#ifdef OPENSSL_NO_DSA /*
* We ignore any errors from the fetches below. They are expected to fail
* if theose algorithms are not available.
*/
ERR_set_mark();
sig = EVP_SIGNATURE_fetch(ctx->libctx, "DSA", ctx->propq);
if (sig == NULL)
ctx->disabled_auth_mask |= SSL_aDSS; ctx->disabled_auth_mask |= SSL_aDSS;
#endif else
#ifdef OPENSSL_NO_DH EVP_SIGNATURE_free(sig);
kex = EVP_KEYEXCH_fetch(ctx->libctx, "DH", ctx->propq);
if (kex == NULL)
ctx->disabled_mkey_mask |= SSL_kDHE | SSL_kDHEPSK; ctx->disabled_mkey_mask |= SSL_kDHE | SSL_kDHEPSK;
#endif else
#ifdef OPENSSL_NO_EC EVP_KEYEXCH_free(kex);
kex = EVP_KEYEXCH_fetch(ctx->libctx, "ECDH", ctx->propq);
if (kex == NULL)
ctx->disabled_mkey_mask |= SSL_kECDHE | SSL_kECDHEPSK; ctx->disabled_mkey_mask |= SSL_kECDHE | SSL_kECDHEPSK;
else
EVP_KEYEXCH_free(kex);
sig = EVP_SIGNATURE_fetch(ctx->libctx, "ECDSA", ctx->propq);
if (sig == NULL)
ctx->disabled_auth_mask |= SSL_aECDSA; ctx->disabled_auth_mask |= SSL_aECDSA;
#endif else
EVP_SIGNATURE_free(sig);
ERR_pop_to_mark();
#ifdef OPENSSL_NO_PSK #ifdef OPENSSL_NO_PSK
ctx->disabled_mkey_mask |= SSL_PSK; ctx->disabled_mkey_mask |= SSL_PSK;
ctx->disabled_auth_mask |= SSL_aPSK; ctx->disabled_auth_mask |= SSL_aPSK;