Skip to content

Commit

Permalink
Re-try loading ENGINE keys with a non-NULL UI_METHOD
Browse files Browse the repository at this point in the history
  • Loading branch information
vcsjones authored Nov 13, 2024
1 parent 714c5a0 commit 22b3c90
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <openssl/sha.h>
#include <openssl/ssl.h>
#include <openssl/tls1.h>
#include <openssl/ui.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>

Expand Down Expand Up @@ -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) \
Expand Down Expand Up @@ -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
Expand Down
19 changes: 19 additions & 0 deletions src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
}

Expand Down

0 comments on commit 22b3c90

Please sign in to comment.