From 4ec694f1a1519b9f2f40932fcc27d68d09081cba Mon Sep 17 00:00:00 2001 From: Jeremy Barton Date: Fri, 5 Mar 2021 17:05:21 -0800 Subject: [PATCH 1/5] Use EVP_PKEY for RSA key generation (managed side) --- .../Interop.EvpPkey.Rsa.cs | 16 ++++++++ .../Interop.Rsa.cs | 3 -- .../Security/Cryptography/RSAOpenSsl.cs | 37 ++++--------------- ...em.Security.Cryptography.Algorithms.csproj | 2 + 4 files changed, 26 insertions(+), 32 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.Rsa.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.Rsa.cs index 1509e5196286b3..afefb5d80f8cdd 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.Rsa.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.Rsa.cs @@ -9,6 +9,22 @@ internal static partial class Interop { internal static partial class Crypto { + [DllImport(Libraries.CryptoNative)] + private static extern SafeEvpPKeyHandle CryptoNative_RsaGenerateKey(int keySize); + + internal static SafeEvpPKeyHandle RsaGenerateKey(int keySize) + { + SafeEvpPKeyHandle pkey = CryptoNative_RsaGenerateKey(keySize); + + if (pkey.IsInvalid) + { + pkey.Dispose(); + throw CreateOpenSslCryptographicException(); + } + + return pkey; + } + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpPkeyGetRsa")] internal static extern SafeRsaHandle EvpPkeyGetRsa(SafeEvpPKeyHandle pkey); diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs index 48bd75cdc2996a..2b71a08f8f687f 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs @@ -88,9 +88,6 @@ private static extern int RsaVerificationPrimitive( [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_RsaSize")] internal static extern int RsaSize(SafeRsaHandle rsa); - [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_RsaGenerateKeyEx")] - internal static extern int RsaGenerateKeyEx(SafeRsaHandle rsa, int bits, SafeBignumHandle e); - internal static bool RsaSign(int type, ReadOnlySpan m, int m_len, Span sigret, out int siglen, SafeRsaHandle rsa) => RsaSign(type, ref MemoryMarshal.GetReference(m), m_len, ref MemoryMarshal.GetReference(sigret), out siglen, rsa); diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs index df9fd27e532b02..df74f2934a221c 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs @@ -23,9 +23,6 @@ public sealed partial class RSAOpenSsl : RSA { private const int BitsPerByte = 8; - // 65537 (0x10001) in big-endian form - private static ReadOnlySpan DefaultExponent => new byte[] { 0x01, 0x00, 0x01 }; - private Lazy _key; public RSAOpenSsl() @@ -590,36 +587,18 @@ private static void CheckBoolReturn(int returnValue) private SafeRsaHandle GenerateKey() { - SafeRsaHandle key = Interop.Crypto.RsaCreate(); - bool generated = false; - - Interop.Crypto.CheckValidOpenSslHandle(key); - - try + using (SafeEvpPKeyHandle pkey = Interop.Crypto.RsaGenerateKey(KeySize)) { - using (SafeBignumHandle exponent = Interop.Crypto.CreateBignum(DefaultExponent)) - { - // The documentation for RSA_generate_key_ex does not say that it returns only - // 0 or 1, so the call marshals it back as a full Int32 and checks for a value - // of 1 explicitly. - int response = Interop.Crypto.RsaGenerateKeyEx( - key, - KeySize, - exponent); - - CheckBoolReturn(response); - generated = true; - } - } - finally - { - if (!generated) + SafeRsaHandle rsa = Interop.Crypto.EvpPkeyGetRsa(pkey); + + if (rsa.IsInvalid) { - key.Dispose(); + rsa.Dispose(); + throw Interop.Crypto.CreateOpenSslCryptographicException(); } - } - return key; + return rsa; + } } protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) => diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System.Security.Cryptography.Algorithms.csproj b/src/libraries/System.Security.Cryptography.Algorithms/src/System.Security.Cryptography.Algorithms.csproj index 465a7575d3e472..52bb2ec2d4f399 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System.Security.Cryptography.Algorithms.csproj +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System.Security.Cryptography.Algorithms.csproj @@ -589,6 +589,8 @@ Link="Common\Interop\Unix\System.Security.Cryptography.Native\Interop.EcKey.cs" /> + Date: Mon, 8 Mar 2021 14:13:34 -0800 Subject: [PATCH 2/5] Use EVP_PKEY for RSA key generation (native side) --- .../apibridge.c | 16 ++++++++++++ .../apibridge.h | 1 + .../entrypoints.c | 2 +- .../opensslshim.h | 22 ++++++++++++++++ .../pal_evp_pkey_rsa.c | 25 +++++++++++++++++++ .../pal_evp_pkey_rsa.h | 5 ++++ .../pal_rsa.c | 5 ---- .../pal_rsa.h | 7 ------ .../pal_ssl.c | 19 +++++++------- 9 files changed, 80 insertions(+), 22 deletions(-) diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c index cc383b0a7fbfe9..a1f4513b33b8d2 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c @@ -788,4 +788,20 @@ int local_BIO_up_ref(BIO *bio) return CRYPTO_add_lock(&bio->references, 1, CRYPTO_LOCK_BIO, __FILE__, __LINE__) > 1; } + +int32_t local_RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd, int32_t p1, void* p2) +{ + if (ctx != NULL) + { + EVP_PKEY* pkey = EVP_PKEY_CTX_get0_pkey(ctx); + + if (EVP_PKEY_base_id(pkey) != NID_rsaEncryption) + { + return -1; + } + } + + return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, p1, p2); +} + #endif diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.h b/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.h index c8905b44eb8ec5..a71c166a33b300 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.h +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.h @@ -26,6 +26,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); +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); unsigned long local_SSL_CTX_set_options(SSL_CTX* ctx, unsigned long options); diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/entrypoints.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native/entrypoints.c index bd379df88242e1..f7e974dd9f1f0f 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/entrypoints.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/entrypoints.c @@ -222,7 +222,7 @@ static const Entry s_cryptoNative[] = DllImportEntry(CryptoNative_RecursiveFreeX509Stack) DllImportEntry(CryptoNative_RsaCreate) DllImportEntry(CryptoNative_RsaDestroy) - DllImportEntry(CryptoNative_RsaGenerateKeyEx) + DllImportEntry(CryptoNative_RsaGenerateKey) DllImportEntry(CryptoNative_RsaPrivateDecrypt) DllImportEntry(CryptoNative_RsaPublicEncrypt) DllImportEntry(CryptoNative_RsaSign) diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h index 5490d1a83666ce..f2467ce88e7d3c 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h @@ -176,6 +176,13 @@ const X509_ALGOR* X509_get0_tbs_sigalg(const X509* x509); X509_PUBKEY* X509_get_X509_PUBKEY(const X509* x509); int32_t X509_get_version(const X509* x509); int32_t X509_up_ref(X509* x509); + +// Redefine EVP_PKEY_CTX_set_rsa operations to use (local_)RSA_pkey_ctx_ctrl so the path is the same +// for 1.0-built on 1.1 as on 1.1-built on 1.1. +#undef EVP_PKEY_CTX_set_rsa_keygen_bits +#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) + #endif #if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_0_2_RTM @@ -362,8 +369,12 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi RENAMED_FUNCTION(EVP_MD_CTX_free, EVP_MD_CTX_destroy) \ RENAMED_FUNCTION(EVP_MD_CTX_new, EVP_MD_CTX_create) \ REQUIRED_FUNCTION(EVP_MD_size) \ + REQUIRED_FUNCTION(EVP_PKEY_CTX_ctrl) \ REQUIRED_FUNCTION(EVP_PKEY_CTX_free) \ + REQUIRED_FUNCTION(EVP_PKEY_CTX_get0_pkey) \ REQUIRED_FUNCTION(EVP_PKEY_CTX_new) \ + REQUIRED_FUNCTION(EVP_PKEY_CTX_new_id) \ + REQUIRED_FUNCTION(EVP_PKEY_base_id) \ REQUIRED_FUNCTION(EVP_PKEY_derive_set_peer) \ REQUIRED_FUNCTION(EVP_PKEY_derive_init) \ REQUIRED_FUNCTION(EVP_PKEY_derive) \ @@ -371,6 +382,8 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi REQUIRED_FUNCTION(EVP_PKEY_get1_DSA) \ REQUIRED_FUNCTION(EVP_PKEY_get1_EC_KEY) \ REQUIRED_FUNCTION(EVP_PKEY_get1_RSA) \ + REQUIRED_FUNCTION(EVP_PKEY_keygen) \ + REQUIRED_FUNCTION(EVP_PKEY_keygen_init) \ REQUIRED_FUNCTION(EVP_PKEY_new) \ REQUIRED_FUNCTION(EVP_PKEY_set1_DSA) \ REQUIRED_FUNCTION(EVP_PKEY_set1_EC_KEY) \ @@ -453,6 +466,7 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi FALLBACK_FUNCTION(RSA_get0_key) \ FALLBACK_FUNCTION(RSA_meth_get_flags) \ REQUIRED_FUNCTION(RSA_new) \ + FALLBACK_FUNCTION(RSA_pkey_ctx_ctrl) \ RENAMED_FUNCTION(RSA_PKCS1_OpenSSL, RSA_PKCS1_SSLeay) \ REQUIRED_FUNCTION(RSA_private_decrypt) \ REQUIRED_FUNCTION(RSA_private_encrypt) \ @@ -773,8 +787,12 @@ FOR_ALL_OPENSSL_FUNCTIONS #define EVP_MD_CTX_free EVP_MD_CTX_free_ptr #define EVP_MD_CTX_new EVP_MD_CTX_new_ptr #define EVP_MD_size EVP_MD_size_ptr +#define EVP_PKEY_CTX_ctrl EVP_PKEY_CTX_ctrl_ptr #define EVP_PKEY_CTX_free EVP_PKEY_CTX_free_ptr +#define EVP_PKEY_CTX_get0_pkey EVP_PKEY_CTX_get0_pkey_ptr #define EVP_PKEY_CTX_new EVP_PKEY_CTX_new_ptr +#define EVP_PKEY_CTX_new_id EVP_PKEY_CTX_new_id_ptr +#define EVP_PKEY_base_id EVP_PKEY_base_id_ptr #define EVP_PKEY_derive_set_peer EVP_PKEY_derive_set_peer_ptr #define EVP_PKEY_derive_init EVP_PKEY_derive_init_ptr #define EVP_PKEY_derive EVP_PKEY_derive_ptr @@ -782,6 +800,8 @@ FOR_ALL_OPENSSL_FUNCTIONS #define EVP_PKEY_get1_DSA EVP_PKEY_get1_DSA_ptr #define EVP_PKEY_get1_EC_KEY EVP_PKEY_get1_EC_KEY_ptr #define EVP_PKEY_get1_RSA EVP_PKEY_get1_RSA_ptr +#define EVP_PKEY_keygen EVP_PKEY_keygen_ptr +#define EVP_PKEY_keygen_init EVP_PKEY_keygen_init_ptr #define EVP_PKEY_new EVP_PKEY_new_ptr #define EVP_PKEY_set1_DSA EVP_PKEY_set1_DSA_ptr #define EVP_PKEY_set1_EC_KEY EVP_PKEY_set1_EC_KEY_ptr @@ -864,6 +884,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #define RSA_get_method RSA_get_method_ptr #define RSA_meth_get_flags RSA_meth_get_flags_ptr #define RSA_new RSA_new_ptr +#define RSA_pkey_ctx_ctrl RSA_pkey_ctx_ctrl_ptr #define RSA_PKCS1_OpenSSL RSA_PKCS1_OpenSSL_ptr #define RSA_private_decrypt RSA_private_decrypt_ptr #define RSA_private_encrypt RSA_private_encrypt_ptr @@ -1084,6 +1105,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #define RSA_set0_crt_params local_RSA_set0_crt_params #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 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 diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c index ab02a5c0d64337..1d51131f5912c1 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c @@ -3,6 +3,31 @@ #include "pal_evp_pkey_rsa.h" +EVP_PKEY* CryptoNative_RsaGenerateKey(int keySize) +{ + EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + + if (ctx == NULL) + { + return NULL; + } + + EVP_PKEY* pkey = NULL; + int success = 1; + success = success && (1 == EVP_PKEY_keygen_init(ctx)); + success = success && (1 == EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, keySize)); + success = success && (1 == EVP_PKEY_keygen(ctx, &pkey)); + + if (pkey != NULL && !success) + { + EVP_PKEY_free(pkey); + pkey = NULL; + } + + EVP_PKEY_CTX_free(ctx); + return pkey; +} + RSA* CryptoNative_EvpPkeyGetRsa(EVP_PKEY* pkey) { return EVP_PKEY_get1_RSA(pkey); diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.h b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.h index 3609e677c6de30..b1ccd385f0051d 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.h +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.h @@ -5,6 +5,11 @@ #include "pal_compiler.h" #include "opensslshim.h" +/* +Creates an RSA key of the requested size. +*/ +PALEXPORT EVP_PKEY* CryptoNative_RsaGenerateKey(int32_t keySize); + /* Shims the EVP_PKEY_get1_RSA method. diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_rsa.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_rsa.c index 877eac82ca09e6..38e2fd4e6540af 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_rsa.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_rsa.c @@ -144,11 +144,6 @@ int32_t CryptoNative_RsaSize(RSA* rsa) return RSA_size(rsa); } -int32_t CryptoNative_RsaGenerateKeyEx(RSA* rsa, int32_t bits, BIGNUM* e) -{ - return RSA_generate_key_ex(rsa, bits, e, NULL); -} - int32_t CryptoNative_RsaSign(int32_t type, const uint8_t* m, int32_t mlen, uint8_t* sigret, int32_t* siglen, RSA* rsa) { diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h index 4db6722feb9a91..128b5c9f8fae97 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h @@ -85,13 +85,6 @@ Returns the RSA modulus size in bytes. */ PALEXPORT int32_t CryptoNative_RsaSize(RSA* rsa); -/* -Shims the RSA_generate_key_ex method. - -Returns 1 upon success, otherwise 0. -*/ -PALEXPORT int32_t CryptoNative_RsaGenerateKeyEx(RSA* rsa, int32_t bits, BIGNUM* e); - /* Shims the RSA_sign method. diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_ssl.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_ssl.c index c0dbf05a4154b9..b59560383f8fa3 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_ssl.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_ssl.c @@ -644,16 +644,22 @@ int32_t CryptoNative_SslGetCurrentCipherId(SSL* ssl, int32_t* cipherId) // This function generates key pair and creates simple certificate. static int MakeSelfSignedCertificate(X509 * cert, EVP_PKEY* evp) { - RSA* rsa = CryptoNative_RsaCreate(); + RSA* rsa = NULL; ASN1_TIME* time = ASN1_TIME_new(); - BIGNUM* bn = BN_new(); - BN_set_word(bn, RSA_F4); X509_NAME * asnName; unsigned char * name = (unsigned char*)"localhost"; int ret = 0; - if (rsa != NULL && CryptoNative_RsaGenerateKeyEx(rsa, 2048, bn) == 1) + EVP_PKEY* pkey = CryptoNative_RsaGenerateKey(2048); + + if (pkey != NULL) + { + rsa = EVP_PKEY_get1_RSA(pkey); + EVP_PKEY_free(pkey); + } + + if (rsa != NULL) { if (CryptoNative_EvpPkeySetRsa(evp, rsa) == 1) { @@ -675,11 +681,6 @@ static int MakeSelfSignedCertificate(X509 * cert, EVP_PKEY* evp) ret = X509_sign(cert, evp, EVP_sha256()); } - if (bn != NULL) - { - BN_free(bn); - } - if (rsa != NULL) { RSA_free(rsa); From 74e3e4bc457b773144eeb95589ad9e50196e2150 Mon Sep 17 00:00:00 2001 From: Jeremy Barton Date: Tue, 9 Mar 2021 09:00:34 -0800 Subject: [PATCH 3/5] Add missing RSA_pkey_ctx_ctrl prototype for OpenSSL 1.0 compilation --- .../Unix/System.Security.Cryptography.Native/opensslshim.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h index f2467ce88e7d3c..714abc26c216f6 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h @@ -148,6 +148,7 @@ void RSA_get0_factors(const RSA* rsa, const BIGNUM** p, const BIGNUM** q); void RSA_get0_key(const RSA* rsa, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d); int32_t RSA_meth_get_flags(const RSA_METHOD* meth); const RSA_METHOD* RSA_PKCS1_OpenSSL(void); +int32_t RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd, int32_t p1, void* p2); 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); From b600114e3a5bd0c5b29bca45c8bb8bd11f020aa9 Mon Sep 17 00:00:00 2001 From: Jeremy Barton Date: Wed, 17 Mar 2021 08:04:49 -0700 Subject: [PATCH 4/5] Simplify local_RSA_pkey_ctx_ctrl --- .../apibridge.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c index a1f4513b33b8d2..46f2b95b66a46a 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c @@ -791,17 +791,9 @@ int local_BIO_up_ref(BIO *bio) int32_t local_RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd, int32_t p1, void* p2) { - if (ctx != NULL) - { - EVP_PKEY* pkey = EVP_PKEY_CTX_get0_pkey(ctx); - - if (EVP_PKEY_base_id(pkey) != NID_rsaEncryption) - { - return -1; - } - } - - return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, p1, p2); + // On OpenSSL 1.0.2 there aren't two different identifiers for RSA, + // so just pass the request on th EVP_PKEY_CTX_ctrl with the only identifier defined. + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, optype, cmd, p1, p2); } #endif From 0f998d9f26c139a9f436e2c6afab44894abcaa28 Mon Sep 17 00:00:00 2001 From: Jeremy Barton Date: Thu, 18 Mar 2021 15:30:46 -0700 Subject: [PATCH 5/5] Use a more common short-circuit pattern in generating keys. --- .../pal_evp_pkey_rsa.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c index 1d51131f5912c1..b81870ffdd2a52 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c @@ -13,19 +13,23 @@ EVP_PKEY* CryptoNative_RsaGenerateKey(int keySize) } EVP_PKEY* pkey = NULL; - int success = 1; - success = success && (1 == EVP_PKEY_keygen_init(ctx)); - success = success && (1 == EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, keySize)); - success = success && (1 == EVP_PKEY_keygen(ctx, &pkey)); + EVP_PKEY* ret = NULL; - if (pkey != NULL && !success) + if (EVP_PKEY_keygen_init(ctx) == 1 && + EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, keySize) == 1 && + EVP_PKEY_keygen(ctx, &pkey) == 1) { - EVP_PKEY_free(pkey); + ret = pkey; pkey = NULL; } + if (pkey != NULL) + { + EVP_PKEY_free(pkey); + } + EVP_PKEY_CTX_free(ctx); - return pkey; + return ret; } RSA* CryptoNative_EvpPkeyGetRsa(EVP_PKEY* pkey)