diff --git a/src/pk.c b/src/pk.c index 747f14ece..6802bfe19 100644 --- a/src/pk.c +++ b/src/pk.c @@ -1779,6 +1779,47 @@ WOLFSSL_RSA* wolfSSL_PEM_read_bio_RSAPrivateKey(WOLFSSL_BIO* bio, return rsa; } +/* Create an RSA private key by reading the PEM encoded data from the file + * pointer. + * + * @param [in] fp BIO object to read from. + * @param [out] out RSA key created. + * @param [in] cb Password callback when PEM encrypted. + * @param [in] pass NUL terminated string for passphrase when PEM encrypted. + * @return RSA key on success. + * @return NULL on failure. + */ +#ifndef NO_FILESYSTEM +WOLFSSL_RSA* wolfSSL_PEM_read_RSAPrivateKey(XFILE fp, WOLFSSL_RSA** out, + wc_pem_password_cb* cb, void* pass) +{ + WOLFSSL_EVP_PKEY* pkey; + WOLFSSL_RSA* rsa = NULL; + + WOLFSSL_ENTER("PEM_read_RSAPrivateKey"); + + /* Read PEM encoded RSA private key from a file pointer. using generic EVP + * function. + */ + pkey = wolfSSL_PEM_read_PrivateKey(fp, NULL, cb, pass); + if (pkey != NULL) { + /* Since the WOLFSSL_RSA structure is being taken from WOLFSSL_EVP_PKEY + * the flag indicating that the WOLFSSL_RSA structure is owned should be + * FALSE to avoid having it free'd. */ + pkey->ownRsa = 0; + rsa = pkey->rsa; + if (out != NULL) { + /* Return WOLFSSL_RSA object through parameter too. */ + *out = rsa; + } + } + + /* Dispose of EVP_PKEY wrapper. */ + wolfSSL_EVP_PKEY_free(pkey); + return rsa; +} +#endif /* !NO_FILESYSTEM */ + #endif /* NO_BIO */ #if !defined(NO_FILESYSTEM) diff --git a/tests/api.c b/tests/api.c index a8c2565bf..651505243 100644 --- a/tests/api.c +++ b/tests/api.c @@ -32284,6 +32284,7 @@ static int test_wolfSSL_PEM_RSAPrivateKey(void) RSA* rsa = NULL; RSA* rsa_dup = NULL; BIO* bio = NULL; + XFILE f = NULL; printf(testingFmt, "wolfSSL_PEM_RSAPrivateKey()"); @@ -32309,6 +32310,12 @@ static int test_wolfSSL_PEM_RSAPrivateKey(void) RSA_free(rsa); RSA_free(rsa_dup); + f = XFOPEN(svrKeyFile, "r"); + AssertTrue((f != XBADFILE)); + AssertNotNull((rsa = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL))); + AssertIntEQ(RSA_size(rsa), 256); + RSA_free(rsa); + #ifdef HAVE_ECC AssertNotNull(bio = BIO_new_file(eccKeyFile, "rb")); AssertNull((rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL))); diff --git a/wolfssl/openssl/pem.h b/wolfssl/openssl/pem.h index 508405a5c..83139bd95 100644 --- a/wolfssl/openssl/pem.h +++ b/wolfssl/openssl/pem.h @@ -49,6 +49,10 @@ WOLFSSL_API WOLFSSL_RSA* wolfSSL_PEM_read_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA** rsa, wc_pem_password_cb* cb, void* pass); +WOLFSSL_API +WOLFSSL_RSA* wolfSSL_PEM_read_RSAPrivateKey(XFILE fp, + WOLFSSL_RSA** rsa, wc_pem_password_cb* cb, void* pass); + WOLFSSL_API int wolfSSL_PEM_write_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa); @@ -226,6 +230,7 @@ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh); /* RSA */ #define PEM_write_bio_RSAPrivateKey wolfSSL_PEM_write_bio_RSAPrivateKey #define PEM_read_bio_RSAPrivateKey wolfSSL_PEM_read_bio_RSAPrivateKey +#define PEM_read_RSAPrivateKey wolfSSL_PEM_read_RSAPrivateKey #define PEM_write_bio_RSA_PUBKEY wolfSSL_PEM_write_bio_RSA_PUBKEY #define PEM_read_bio_RSA_PUBKEY wolfSSL_PEM_read_bio_RSA_PUBKEY #define PEM_read_bio_RSAPublicKey wolfSSL_PEM_read_bio_RSA_PUBKEY