diff --git a/src/lib/crypto/OSSLRSAPrivateKey.cpp b/src/lib/crypto/OSSLRSAPrivateKey.cpp index da16c45c3..1076905ce 100644 --- a/src/lib/crypto/OSSLRSAPrivateKey.cpp +++ b/src/lib/crypto/OSSLRSAPrivateKey.cpp @@ -39,9 +39,9 @@ #include #if OPENSSL_VERSION_NUMBER >= 0x30000000L #include -#else -#include +#include #endif +#include #ifdef WITH_FIPS #include #endif @@ -354,7 +354,9 @@ void OSSLRSAPrivateKey::createOSSLKey() #if OPENSSL_VERSION_NUMBER >= 0x30000000L OSSL_PARAM_BLD* param_bld = OSSL_PARAM_BLD_new(); OSSL_PARAM* params = NULL; + EVP_PKEY_CTX* ctx = NULL; bool bBuildErr = false; + if ((param_bld == NULL) || (bn_n == NULL) || (bn_e == NULL) || @@ -379,6 +381,35 @@ void OSSLRSAPrivateKey::createOSSLKey() if (!bBuildErr) params = OSSL_PARAM_BLD_to_param(param_bld); OSSL_PARAM_BLD_free(param_bld); + + if ((!bBuildErr) && (params != NULL)) + { + // Use the default provider for internal RSA key reconstruction. + ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", "provider=default"); + if ((ctx != NULL) && + (EVP_PKEY_fromdata_init(ctx) > 0) && + (EVP_PKEY_fromdata(ctx, &rsa, EVP_PKEY_KEYPAIR, params) > 0)) + { + OSSL_PARAM_free(params); + EVP_PKEY_CTX_free(ctx); + BN_free(bn_n); + BN_free(bn_e); + BN_free(bn_d); + BN_free(bn_p); + BN_free(bn_q); + BN_free(bn_dmp1); + BN_free(bn_dmq1); + BN_free(bn_iqmp); + return; + } + } + OSSL_PARAM_free(params); + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(rsa); + rsa = NULL; + +#if OPENSSL_VERSION_NUMBER >= 0x40000000L + ERROR_MSG("Could not create RSA key object"); BN_free(bn_n); BN_free(bn_e); BN_free(bn_d); @@ -387,31 +418,20 @@ void OSSLRSAPrivateKey::createOSSLKey() BN_free(bn_dmp1); BN_free(bn_dmq1); BN_free(bn_iqmp); - if ((bBuildErr) || (params == NULL)) - { - ERROR_MSG("Could not build RSA key parameters"); - return; - } - EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); - if (ctx == NULL) - { - ERROR_MSG("Could not create RSA key creation context"); - OSSL_PARAM_free(params); - return; - } - if ((EVP_PKEY_fromdata_init(ctx) <= 0) || - (EVP_PKEY_fromdata(ctx, &rsa, EVP_PKEY_KEYPAIR, params) <= 0)) - { - ERROR_MSG("Could not create RSA key object"); - OSSL_PARAM_free(params); - EVP_PKEY_CTX_free(ctx); - rsa = NULL; - return; - } - OSSL_PARAM_free(params); - EVP_PKEY_CTX_free(ctx); - + return; #else + // Provider-based RSA reconstruction may fail in Engine-based + // applications where no suitable provider is available. + // Fall back to the legacy RSA API while it is still available. + ERR_clear_error(); +#endif +#endif + +#if OPENSSL_VERSION_NUMBER < 0x40000000L +#if defined(__GNUC__) || defined(__clang__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif RSA* rsa1 = RSA_new(); if (rsa1 == NULL) { @@ -459,5 +479,8 @@ void OSSLRSAPrivateKey::createOSSLKey() rsa = NULL; return; } +#if defined(__GNUC__) || defined(__clang__) +# pragma GCC diagnostic pop +#endif #endif } diff --git a/src/lib/crypto/OSSLRSAPublicKey.cpp b/src/lib/crypto/OSSLRSAPublicKey.cpp index f14217304..8e41d39e5 100644 --- a/src/lib/crypto/OSSLRSAPublicKey.cpp +++ b/src/lib/crypto/OSSLRSAPublicKey.cpp @@ -39,9 +39,9 @@ #include #if OPENSSL_VERSION_NUMBER >= 0x30000000L #include -#else -#include +#include #endif +#include #ifdef WITH_FIPS #include #endif @@ -153,60 +153,80 @@ void OSSLRSAPublicKey::createOSSLKey() if (rsa != NULL) return; - BIGNUM* bn_n = OSSL::byteString2bn(n); BIGNUM* bn_e = OSSL::byteString2bn(e); #if OPENSSL_VERSION_NUMBER >= 0x30000000L - OSSL_PARAM_BLD *param_bld = OSSL_PARAM_BLD_new(); + OSSL_PARAM_BLD* param_bld = OSSL_PARAM_BLD_new(); + OSSL_PARAM* params = NULL; + EVP_PKEY_CTX* ctx = NULL; + bool bBuildErr = false; if ((param_bld == NULL) || - (bn_n == NULL) || - (bn_e == NULL) || - (OSSL_PARAM_BLD_push_BN(param_bld,"n",bn_n) <= 0 ) || - (OSSL_PARAM_BLD_push_BN(param_bld,"e",bn_e) <= 0 )) + (bn_n == NULL) || + (bn_e == NULL) || + (OSSL_PARAM_BLD_push_BN(param_bld, "n", bn_n) <= 0) || + (OSSL_PARAM_BLD_push_BN(param_bld, "e", bn_e) <= 0)) { - OSSL_PARAM_BLD_free(param_bld); - BN_free(bn_n); - BN_free(bn_e); - ERROR_MSG("Could not build RSA public key parameters"); - return; + bBuildErr = true; } - OSSL_PARAM* params = OSSL_PARAM_BLD_to_param(param_bld); + + if (!bBuildErr) + params = OSSL_PARAM_BLD_to_param(param_bld); OSSL_PARAM_BLD_free(param_bld); - BN_free(bn_n); - BN_free(bn_e); - EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); - if (ctx == NULL) + if ((!bBuildErr) && (params != NULL)) { - ERROR_MSG("Could not create RSA public key creation context"); - OSSL_PARAM_free(params); - return; - } - if ((EVP_PKEY_fromdata_init(ctx) <= 0) || - (EVP_PKEY_fromdata(ctx, &rsa, EVP_PKEY_PUBLIC_KEY, params) <= 0)) - { - ERROR_MSG("Could not create public RSA key object"); - OSSL_PARAM_free(params); - EVP_PKEY_CTX_free(ctx); - rsa = NULL; - return; + // Use the default provider for internal RSA key reconstruction. + ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", "provider=default"); + if ((ctx != NULL) && + (EVP_PKEY_fromdata_init(ctx) > 0) && + (EVP_PKEY_fromdata(ctx, &rsa, EVP_PKEY_PUBLIC_KEY, + params) > 0)) + { + OSSL_PARAM_free(params); + EVP_PKEY_CTX_free(ctx); + + BN_free(bn_n); + BN_free(bn_e); + return; + } } - OSSL_PARAM_free(params); + OSSL_PARAM_free(params); EVP_PKEY_CTX_free(ctx); - + EVP_PKEY_free(rsa); + rsa = NULL; + +#if OPENSSL_VERSION_NUMBER >= 0x40000000L + ERROR_MSG("Could not create public RSA key object"); + BN_free(bn_n); + BN_free(bn_e); + return; #else - RSA* rsa1 = RSA_new(); + // Provider-based RSA reconstruction may fail in Engine-based + // applications where no suitable provider is available. + // Fall back to the legacy RSA API while it is still available. + ERR_clear_error(); +#endif +#endif + +#if OPENSSL_VERSION_NUMBER < 0x40000000L +#if defined(__GNUC__) || defined(__clang__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + RSA* rsa1 = RSA_new(); if (rsa1 == NULL) - { + { BN_free(bn_n); - BN_free(bn_e); + BN_free(bn_e); ERROR_MSG("Could not build RSA object"); return; - } + } + #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -// Use the OpenSSL implementation and not any engine + // Use the OpenSSL implementation and not any engine + #ifdef WITH_FIPS if (FIPS_mode()) RSA_set_method(rsa1, FIPS_rsa_pkcs1_ssleay()); @@ -219,15 +239,18 @@ void OSSLRSAPublicKey::createOSSLKey() #else RSA_set_method(rsa1, RSA_PKCS1_OpenSSL()); #endif + RSA_set0_key(rsa1, bn_n, bn_e, NULL); + rsa = EVP_PKEY_new(); if (rsa == NULL) { ERROR_MSG("Could not build RSA PKEY"); RSA_free(rsa1); return; - } - if (EVP_PKEY_assign_RSA(rsa,rsa1) <= 0) + } + + if (EVP_PKEY_assign_RSA(rsa, rsa1) <= 0) { ERROR_MSG("Could not assign RSA PKEY"); RSA_free(rsa1); @@ -235,5 +258,9 @@ void OSSLRSAPublicKey::createOSSLKey() rsa = NULL; return; } + +#if defined(__GNUC__) || defined(__clang__) +# pragma GCC diagnostic pop +#endif #endif }