Unix: Additional check if the RSA key is external.
authorKevin Jones <kevin@vcsjones.com>
Wed, 2 Jun 2021 23:53:45 +0000 (19:53 -0400)
committerGitHub <noreply@github.com>
Wed, 2 Jun 2021 23:53:45 +0000 (16:53 -0700)
Currently we are checking the RSA_METHOD to see if an RSA key "external",
where the private key material may not be exportable. This may not work
because the RSA key itself can declare if it is external or not.

This also checks the flags of the RSA key object itself so attempting
to export the private key is not performed.

src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c
src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.h
src/libraries/Native/Unix/System.Security.Cryptography.Native/openssl_1_0_structs.h
src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
src/libraries/Native/Unix/System.Security.Cryptography.Native/osslcompat_111.h
src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c

index 27b72a320c6f548a58c557ec3955e90d06a19462..daf13002b118511d321d4ba77f59cc8b5445e8c0 100644 (file)
@@ -813,4 +813,9 @@ int32_t local_RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd,
     return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, optype, cmd, p1, p2);
 }
 
+int local_RSA_test_flags(const RSA *r, int flags)
+{
+    return r->flags & flags;
+}
+
 #endif
index b9060b7f761e9d08fec8881732b19ebc0d312abc..1b866bc4474d283c6853b71e77345fad12c212b1 100644 (file)
@@ -27,6 +27,7 @@ int32_t local_RSA_meth_get_flags(const RSA_METHOD* meth);
 int32_t local_RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp);
 int32_t local_RSA_set0_factors(RSA* rsa, BIGNUM* p, BIGNUM* q);
 int32_t local_RSA_set0_key(RSA* rsa, BIGNUM* n, BIGNUM* e, BIGNUM* d);
+int local_RSA_test_flags(const RSA *r, int flags);
 int32_t local_RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd, int32_t p1, void* p2);
 int32_t local_SSL_is_init_finished(const SSL* ssl);
 int32_t local_SSL_CTX_config(SSL_CTX* ctx, const char* name);
index fb282bdf21f1187ab219568305ae09f04a1ce2cd..f730dd39387ffa6ee308efa10178a253f9bb7ce5 100644 (file)
@@ -80,6 +80,9 @@ struct rsa_st
     BIGNUM* dmp1;
     BIGNUM* dmq1;
     BIGNUM* iqmp;
+    struct crypto_ex_data_10_st ex_data;
+    int _ignored3;
+    int flags;
 };
 
 struct x509_cinf_st
index 602cca604a412d0e980b5c9c37323b48b90933cd..8bf1befbb0f5b983180c7a42a9c429318df96cf2 100644 (file)
@@ -439,6 +439,7 @@ const EVP_CIPHER* EVP_chacha20_poly1305(void);
     FALLBACK_FUNCTION(RSA_set0_key) \
     REQUIRED_FUNCTION(RSA_set_method) \
     REQUIRED_FUNCTION(RSA_size) \
+    FALLBACK_FUNCTION(RSA_test_flags) \
     REQUIRED_FUNCTION(RSA_up_ref) \
     REQUIRED_FUNCTION(RSA_verify) \
     LIGHTUP_FUNCTION(SSL_CIPHER_find) \
@@ -875,6 +876,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
 #define RSA_set0_key RSA_set0_key_ptr
 #define RSA_set_method RSA_set_method_ptr
 #define RSA_size RSA_size_ptr
+#define RSA_test_flags RSA_test_flags_ptr
 #define RSA_up_ref RSA_up_ref_ptr
 #define RSA_verify RSA_verify_ptr
 #define SSL_CIPHER_get_bits SSL_CIPHER_get_bits_ptr
@@ -1107,6 +1109,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
 #define RSA_set0_factors local_RSA_set0_factors
 #define RSA_set0_key local_RSA_set0_key
 #define RSA_pkey_ctx_ctrl local_RSA_pkey_ctx_ctrl
+#define RSA_test_flags local_RSA_test_flags
 #define SSL_CTX_set_security_level local_SSL_CTX_set_security_level
 #define SSL_is_init_finished local_SSL_is_init_finished
 #define X509_CRL_get0_nextUpdate local_X509_CRL_get0_nextUpdate
index e8cf8c2a75dbd2864ed94710448535c219361a2d..e9a1b4939bab3de07c156bc8c8d995419c2fffa2 100644 (file)
@@ -51,6 +51,7 @@ int32_t RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd, int32_
 int32_t RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp);
 int32_t RSA_set0_factors(RSA* rsa, BIGNUM* p, BIGNUM* q);
 int32_t RSA_set0_key(RSA* rsa, BIGNUM* n, BIGNUM* e, BIGNUM* d);
+int RSA_test_flags(const RSA *r, int flags);
 int SSL_CTX_config(SSL_CTX* ctx, const char* name);
 unsigned long SSL_CTX_set_options(SSL_CTX* ctx, unsigned long options);
 void SSL_CTX_set_security_level(SSL_CTX* ctx, int32_t level);
index 5ae47559cc7a7f9fab070c6065458984766d331a..fa88420cf967054b1c6a6a694a76c9366fc149a9 100644 (file)
@@ -316,7 +316,7 @@ static int HasNoPrivateKey(const RSA* rsa)
     // That doesn't mean it's actually present, but we can't tell.
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wcast-qual"
-    if (RSA_meth_get_flags((RSA_METHOD*)meth) & RSA_FLAG_EXT_PKEY)
+    if (RSA_test_flags(rsa, RSA_FLAG_EXT_PKEY) || RSA_meth_get_flags((RSA_METHOD*)meth) & RSA_FLAG_EXT_PKEY)
 #pragma clang diagnostic pop
     {
         return 0;