diff --git a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h index 97dcb02f435a5..9f7228d06e13c 100644 --- a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h +++ b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -699,6 +700,8 @@ extern bool g_libSslUses32BitTime; LIGHTUP_FUNCTION(SSL_verify_client_post_handshake) \ LIGHTUP_FUNCTION(SSL_set_post_handshake_auth) \ REQUIRED_FUNCTION(SSL_version) \ + REQUIRED_FUNCTION(UI_create_method) \ + REQUIRED_FUNCTION(UI_destroy_method) \ FALLBACK_FUNCTION(X509_check_host) \ REQUIRED_FUNCTION(X509_check_purpose) \ REQUIRED_FUNCTION(X509_cmp_time) \ @@ -1249,6 +1252,8 @@ extern TYPEOF(OPENSSL_gmtime)* OPENSSL_gmtime_ptr; #define SSL_set_post_handshake_auth SSL_set_post_handshake_auth_ptr #define SSL_version SSL_version_ptr #define TLS_method TLS_method_ptr +#define UI_create_method UI_create_method_ptr +#define UI_destroy_method UI_destroy_method_ptr #define X509_check_host X509_check_host_ptr #define X509_check_purpose X509_check_purpose_ptr #define X509_cmp_time X509_cmp_time_ptr diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c index f80ef99c02515..14b4f1eaa49ee 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c @@ -556,6 +556,7 @@ static EVP_PKEY* LoadKeyFromEngine( *haveEngine = 1; EVP_PKEY* ret = NULL; ENGINE* engine = NULL; + UI_METHOD* ui = NULL; // Per https://github.com/openssl/openssl/discussions/21427 // using EVP_PKEY after freeing ENGINE is correct. @@ -567,12 +568,30 @@ static EVP_PKEY* LoadKeyFromEngine( { ret = load_func(engine, keyName, NULL, NULL); + if (ret == NULL) + { + // Some engines do not tolerate having NULL passed to the ui_method parameter. + // We re-try with a non-NULL UI_METHOD. + ERR_clear_error(); + ui = UI_create_method(".NET NULL UI"); + + if (ui) + { + ret = load_func(engine, keyName, ui, NULL); + } + } + ENGINE_finish(engine); } ENGINE_free(engine); } + if (ui) + { + UI_destroy_method(ui); + } + return ret; }