Skip to content

Commit f6edcb9

Browse files
committed
Use EVP_PKEY for RSA key generation (native side)
1 parent 4ec694f commit f6edcb9

File tree

9 files changed

+80
-22
lines changed

9 files changed

+80
-22
lines changed

src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.c

+16
Original file line numberDiff line numberDiff line change
@@ -788,4 +788,20 @@ int local_BIO_up_ref(BIO *bio)
788788

789789
return CRYPTO_add_lock(&bio->references, 1, CRYPTO_LOCK_BIO, __FILE__, __LINE__) > 1;
790790
}
791+
792+
int32_t local_RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd, int32_t p1, void* p2)
793+
{
794+
if (ctx != NULL)
795+
{
796+
EVP_PKEY* pkey = EVP_PKEY_CTX_get0_pkey(ctx);
797+
798+
if (EVP_PKEY_base_id(pkey) != NID_rsaEncryption)
799+
{
800+
return -1;
801+
}
802+
}
803+
804+
return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, p1, p2);
805+
}
806+
791807
#endif

src/libraries/Native/Unix/System.Security.Cryptography.Native/apibridge.h

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ int32_t local_RSA_meth_get_flags(const RSA_METHOD* meth);
2626
int32_t local_RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp);
2727
int32_t local_RSA_set0_factors(RSA* rsa, BIGNUM* p, BIGNUM* q);
2828
int32_t local_RSA_set0_key(RSA* rsa, BIGNUM* n, BIGNUM* e, BIGNUM* d);
29+
int32_t local_RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd, int32_t p1, void* p2);
2930
int32_t local_SSL_is_init_finished(const SSL* ssl);
3031
int32_t local_SSL_CTX_config(SSL_CTX* ctx, const char* name);
3132
unsigned long local_SSL_CTX_set_options(SSL_CTX* ctx, unsigned long options);

src/libraries/Native/Unix/System.Security.Cryptography.Native/entrypoints.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ static const Entry s_cryptoNative[] =
222222
DllImportEntry(CryptoNative_RecursiveFreeX509Stack)
223223
DllImportEntry(CryptoNative_RsaCreate)
224224
DllImportEntry(CryptoNative_RsaDestroy)
225-
DllImportEntry(CryptoNative_RsaGenerateKeyEx)
225+
DllImportEntry(CryptoNative_RsaGenerateKey)
226226
DllImportEntry(CryptoNative_RsaPrivateDecrypt)
227227
DllImportEntry(CryptoNative_RsaPublicEncrypt)
228228
DllImportEntry(CryptoNative_RsaSign)

src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.h

+22
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,13 @@ const X509_ALGOR* X509_get0_tbs_sigalg(const X509* x509);
176176
X509_PUBKEY* X509_get_X509_PUBKEY(const X509* x509);
177177
int32_t X509_get_version(const X509* x509);
178178
int32_t X509_up_ref(X509* x509);
179+
180+
// Redefine EVP_PKEY_CTX_set_rsa operations to use (local_)RSA_pkey_ctx_ctrl so the path is the same
181+
// for 1.0-built on 1.1 as on 1.1-built on 1.1.
182+
#undef EVP_PKEY_CTX_set_rsa_keygen_bits
183+
#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
184+
RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)
185+
179186
#endif
180187

181188
#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_0_2_RTM
@@ -362,15 +369,21 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
362369
RENAMED_FUNCTION(EVP_MD_CTX_free, EVP_MD_CTX_destroy) \
363370
RENAMED_FUNCTION(EVP_MD_CTX_new, EVP_MD_CTX_create) \
364371
REQUIRED_FUNCTION(EVP_MD_size) \
372+
REQUIRED_FUNCTION(EVP_PKEY_CTX_ctrl) \
365373
REQUIRED_FUNCTION(EVP_PKEY_CTX_free) \
374+
REQUIRED_FUNCTION(EVP_PKEY_CTX_get0_pkey) \
366375
REQUIRED_FUNCTION(EVP_PKEY_CTX_new) \
376+
REQUIRED_FUNCTION(EVP_PKEY_CTX_new_id) \
377+
REQUIRED_FUNCTION(EVP_PKEY_base_id) \
367378
REQUIRED_FUNCTION(EVP_PKEY_derive_set_peer) \
368379
REQUIRED_FUNCTION(EVP_PKEY_derive_init) \
369380
REQUIRED_FUNCTION(EVP_PKEY_derive) \
370381
REQUIRED_FUNCTION(EVP_PKEY_free) \
371382
REQUIRED_FUNCTION(EVP_PKEY_get1_DSA) \
372383
REQUIRED_FUNCTION(EVP_PKEY_get1_EC_KEY) \
373384
REQUIRED_FUNCTION(EVP_PKEY_get1_RSA) \
385+
REQUIRED_FUNCTION(EVP_PKEY_keygen) \
386+
REQUIRED_FUNCTION(EVP_PKEY_keygen_init) \
374387
REQUIRED_FUNCTION(EVP_PKEY_new) \
375388
REQUIRED_FUNCTION(EVP_PKEY_set1_DSA) \
376389
REQUIRED_FUNCTION(EVP_PKEY_set1_EC_KEY) \
@@ -453,6 +466,7 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
453466
FALLBACK_FUNCTION(RSA_get0_key) \
454467
FALLBACK_FUNCTION(RSA_meth_get_flags) \
455468
REQUIRED_FUNCTION(RSA_new) \
469+
FALLBACK_FUNCTION(RSA_pkey_ctx_ctrl) \
456470
RENAMED_FUNCTION(RSA_PKCS1_OpenSSL, RSA_PKCS1_SSLeay) \
457471
REQUIRED_FUNCTION(RSA_private_decrypt) \
458472
REQUIRED_FUNCTION(RSA_private_encrypt) \
@@ -773,15 +787,21 @@ FOR_ALL_OPENSSL_FUNCTIONS
773787
#define EVP_MD_CTX_free EVP_MD_CTX_free_ptr
774788
#define EVP_MD_CTX_new EVP_MD_CTX_new_ptr
775789
#define EVP_MD_size EVP_MD_size_ptr
790+
#define EVP_PKEY_CTX_ctrl EVP_PKEY_CTX_ctrl_ptr
776791
#define EVP_PKEY_CTX_free EVP_PKEY_CTX_free_ptr
792+
#define EVP_PKEY_CTX_get0_pkey EVP_PKEY_CTX_get0_pkey_ptr
777793
#define EVP_PKEY_CTX_new EVP_PKEY_CTX_new_ptr
794+
#define EVP_PKEY_CTX_new_id EVP_PKEY_CTX_new_id_ptr
795+
#define EVP_PKEY_base_id EVP_PKEY_base_id_ptr
778796
#define EVP_PKEY_derive_set_peer EVP_PKEY_derive_set_peer_ptr
779797
#define EVP_PKEY_derive_init EVP_PKEY_derive_init_ptr
780798
#define EVP_PKEY_derive EVP_PKEY_derive_ptr
781799
#define EVP_PKEY_free EVP_PKEY_free_ptr
782800
#define EVP_PKEY_get1_DSA EVP_PKEY_get1_DSA_ptr
783801
#define EVP_PKEY_get1_EC_KEY EVP_PKEY_get1_EC_KEY_ptr
784802
#define EVP_PKEY_get1_RSA EVP_PKEY_get1_RSA_ptr
803+
#define EVP_PKEY_keygen EVP_PKEY_keygen_ptr
804+
#define EVP_PKEY_keygen_init EVP_PKEY_keygen_init_ptr
785805
#define EVP_PKEY_new EVP_PKEY_new_ptr
786806
#define EVP_PKEY_set1_DSA EVP_PKEY_set1_DSA_ptr
787807
#define EVP_PKEY_set1_EC_KEY EVP_PKEY_set1_EC_KEY_ptr
@@ -864,6 +884,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
864884
#define RSA_get_method RSA_get_method_ptr
865885
#define RSA_meth_get_flags RSA_meth_get_flags_ptr
866886
#define RSA_new RSA_new_ptr
887+
#define RSA_pkey_ctx_ctrl RSA_pkey_ctx_ctrl_ptr
867888
#define RSA_PKCS1_OpenSSL RSA_PKCS1_OpenSSL_ptr
868889
#define RSA_private_decrypt RSA_private_decrypt_ptr
869890
#define RSA_private_encrypt RSA_private_encrypt_ptr
@@ -1084,6 +1105,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
10841105
#define RSA_set0_crt_params local_RSA_set0_crt_params
10851106
#define RSA_set0_factors local_RSA_set0_factors
10861107
#define RSA_set0_key local_RSA_set0_key
1108+
#define RSA_pkey_ctx_ctrl local_RSA_pkey_ctx_ctrl
10871109
#define SSL_CTX_set_security_level local_SSL_CTX_set_security_level
10881110
#define SSL_is_init_finished local_SSL_is_init_finished
10891111
#define X509_CRL_get0_nextUpdate local_X509_CRL_get0_nextUpdate

src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c

+25
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,31 @@
33

44
#include "pal_evp_pkey_rsa.h"
55

6+
EVP_PKEY* CryptoNative_RsaGenerateKey(int keySize)
7+
{
8+
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
9+
10+
if (ctx == NULL)
11+
{
12+
return NULL;
13+
}
14+
15+
EVP_PKEY* pkey = NULL;
16+
int success = 1;
17+
success = success && (1 == EVP_PKEY_keygen_init(ctx));
18+
success = success && (1 == EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, keySize));
19+
success = success && (1 == EVP_PKEY_keygen(ctx, &pkey));
20+
21+
if (pkey != NULL && !success)
22+
{
23+
EVP_PKEY_free(pkey);
24+
pkey = NULL;
25+
}
26+
27+
EVP_PKEY_CTX_free(ctx);
28+
return pkey;
29+
}
30+
631
RSA* CryptoNative_EvpPkeyGetRsa(EVP_PKEY* pkey)
732
{
833
return EVP_PKEY_get1_RSA(pkey);

src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.h

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
#include "pal_compiler.h"
66
#include "opensslshim.h"
77

8+
/*
9+
Creates an RSA key of the requested size.
10+
*/
11+
PALEXPORT EVP_PKEY* CryptoNative_RsaGenerateKey(int32_t keySize);
12+
813
/*
914
Shims the EVP_PKEY_get1_RSA method.
1015

src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_rsa.c

-5
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,6 @@ int32_t CryptoNative_RsaSize(RSA* rsa)
144144
return RSA_size(rsa);
145145
}
146146

147-
int32_t CryptoNative_RsaGenerateKeyEx(RSA* rsa, int32_t bits, BIGNUM* e)
148-
{
149-
return RSA_generate_key_ex(rsa, bits, e, NULL);
150-
}
151-
152147
int32_t
153148
CryptoNative_RsaSign(int32_t type, const uint8_t* m, int32_t mlen, uint8_t* sigret, int32_t* siglen, RSA* rsa)
154149
{

src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h

-7
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,6 @@ Returns the RSA modulus size in bytes.
8585
*/
8686
PALEXPORT int32_t CryptoNative_RsaSize(RSA* rsa);
8787

88-
/*
89-
Shims the RSA_generate_key_ex method.
90-
91-
Returns 1 upon success, otherwise 0.
92-
*/
93-
PALEXPORT int32_t CryptoNative_RsaGenerateKeyEx(RSA* rsa, int32_t bits, BIGNUM* e);
94-
9588
/*
9689
Shims the RSA_sign method.
9790

src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_ssl.c

+10-9
Original file line numberDiff line numberDiff line change
@@ -644,16 +644,22 @@ int32_t CryptoNative_SslGetCurrentCipherId(SSL* ssl, int32_t* cipherId)
644644
// This function generates key pair and creates simple certificate.
645645
static int MakeSelfSignedCertificate(X509 * cert, EVP_PKEY* evp)
646646
{
647-
RSA* rsa = CryptoNative_RsaCreate();
647+
RSA* rsa = NULL;
648648
ASN1_TIME* time = ASN1_TIME_new();
649-
BIGNUM* bn = BN_new();
650-
BN_set_word(bn, RSA_F4);
651649
X509_NAME * asnName;
652650
unsigned char * name = (unsigned char*)"localhost";
653651

654652
int ret = 0;
655653

656-
if (rsa != NULL && CryptoNative_RsaGenerateKeyEx(rsa, 2048, bn) == 1)
654+
EVP_PKEY* pkey = CryptoNative_RsaGenerateKey(2048);
655+
656+
if (pkey != NULL)
657+
{
658+
rsa = EVP_PKEY_get1_RSA(pkey);
659+
EVP_PKEY_free(pkey);
660+
}
661+
662+
if (rsa != NULL)
657663
{
658664
if (CryptoNative_EvpPkeySetRsa(evp, rsa) == 1)
659665
{
@@ -675,11 +681,6 @@ static int MakeSelfSignedCertificate(X509 * cert, EVP_PKEY* evp)
675681
ret = X509_sign(cert, evp, EVP_sha256());
676682
}
677683

678-
if (bn != NULL)
679-
{
680-
BN_free(bn);
681-
}
682-
683684
if (rsa != NULL)
684685
{
685686
RSA_free(rsa);

0 commit comments

Comments
 (0)