From fba534dce03f170af1e80ec1f452c3d4a0529118 Mon Sep 17 00:00:00 2001 From: Satoshi Yamaguchi Date: Sun, 14 Aug 2022 16:08:22 +0900 Subject: [PATCH 1/5] Add wolfSSL_PEM_read_RSA_PUBKEY to OpenSSL compatible API --- src/pk.c | 36 ++++++++++++++++++++++++++++++++++++ src/ssl.c | 32 ++++++++++++++++++++++++-------- tests/api.c | 43 +++++++++++++++++++++++++++++++++++++++++++ wolfssl/openssl/pem.h | 5 +++++ 4 files changed, 108 insertions(+), 8 deletions(-) diff --git a/src/pk.c b/src/pk.c index aff129669..cb2c47f35 100644 --- a/src/pk.c +++ b/src/pk.c @@ -1568,6 +1568,42 @@ WOLFSSL_RSA *wolfSSL_PEM_read_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, return rsa; } +#ifndef NO_FILESYSTEM +/* Create an RSA public key by reading the PEM encoded data from the BIO. + * + * @param [in] fp File pointer 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. + */ +WOLFSSL_RSA *wolfSSL_PEM_read_RSA_PUBKEY(XFILE fp, + WOLFSSL_RSA** out, wc_pem_password_cb* cb, void *pass) +{ + WOLFSSL_EVP_PKEY* pkey; + WOLFSSL_RSA* rsa = NULL; + + WOLFSSL_ENTER("wolfSSL_PEM_read_RSA_PUBKEY"); + + /* Read into a new EVP_PKEY. */ + pkey = wolfSSL_PEM_read_PUBKEY(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) { + *out = rsa; + } + + wolfSSL_EVP_PKEY_free(pkey); + } + + return rsa; +} +#endif /* NO_FILESYSTEM */ #endif /* !NO_BIO */ #if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) && \ diff --git a/src/ssl.c b/src/ssl.c index dc629deed..77f941f4f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -28261,22 +28261,38 @@ WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio, return pkey; } -#endif /* !NO_BIO */ - #if !defined(NO_FILESYSTEM) WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY **x, wc_pem_password_cb *cb, void *u) { - (void)fp; - (void)x; - (void)cb; - (void)u; + int err = 0; + WOLFSSL_EVP_PKEY* ret = NULL; + WOLFSSL_BIO* bio = NULL; - WOLFSSL_MSG("wolfSSL_PEM_read_PUBKEY not implemented"); + WOLFSSL_ENTER("wolfSSL_PEM_read_PUBKEY"); - return NULL; + if (fp == XBADFILE) { + err = 1; + } + if (err == 0) { + bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()); + err = bio == NULL; + } + if (err == 0) { + err = wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS; + } + if (err == 0) { + ret = wolfSSL_PEM_read_bio_PUBKEY(bio, x, cb, u); + } + + if (bio != NULL) { + wolfSSL_BIO_free(bio); + } + + return ret; } #endif /* NO_FILESYSTEM */ +#endif /* !NO_BIO */ #endif /* OPENSSL_EXTRA */ #ifdef WOLFSSL_ALT_CERT_CHAINS diff --git a/tests/api.c b/tests/api.c index e91cf04f9..d766b69e6 100644 --- a/tests/api.c +++ b/tests/api.c @@ -31986,6 +31986,29 @@ static int test_wolfSSL_PEM_read_PrivateKey(void) return 0; } +static int test_wolfSSL_PEM_read_PUBKEY(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) \ + && !defined(NO_FILESYSTEM) && !defined(NO_BIO) + XFILE file; + const char* fname = "./certs/client-keyPub.pem"; + EVP_PKEY* pkey; + + printf(testingFmt, "test_wolfSSL_PEM_read_PUBKEY()"); + + /* Check error case. */ + AssertNull(pkey = PEM_read_PUBKEY(NULL, NULL, NULL, NULL)); + + /* Read in an RSA key. */ + file = XFOPEN(fname, "rb"); + AssertTrue(file != XBADFILE); + AssertNotNull(pkey = PEM_read_PUBKEY(file, NULL, NULL, NULL)); + XFCLOSE(file); +#endif + + return 0; +} + static int test_wolfSSL_PEM_PrivateKey(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ @@ -32454,6 +32477,24 @@ static int test_wolfSSL_PEM_RSAPrivateKey(void) return 0; } +static int test_wolfSSL_PEM_read_RSA_PUBKEY(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) + XFILE file; + const char* fname = "./certs/client-keyPub.pem"; + RSA *rsa; + + file = XFOPEN(fname, "rb"); + AssertTrue((file != XBADFILE)); + AssertNotNull((rsa = PEM_read_RSA_PUBKEY(file, NULL, NULL, NULL))); + AssertIntEQ(RSA_size(rsa), 256); + RSA_free(rsa); +#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) */ + + return 0; +} + static int test_wolfSSL_PEM_bio_DSAKey(void) { #ifndef HAVE_SELFTEST @@ -57245,6 +57286,8 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_ASN1_GENERALIZEDTIME_free), TEST_DECL(test_wolfSSL_private_keys), TEST_DECL(test_wolfSSL_PEM_read_PrivateKey), + TEST_DECL(test_wolfSSL_PEM_read_RSA_PUBKEY), + TEST_DECL(test_wolfSSL_PEM_read_PUBKEY), TEST_DECL(test_wolfSSL_PEM_PrivateKey), #ifndef NO_BIO TEST_DECL(test_wolfSSL_PEM_bio_RSAKey), diff --git a/wolfssl/openssl/pem.h b/wolfssl/openssl/pem.h index 508405a5c..824f7f8d8 100644 --- a/wolfssl/openssl/pem.h +++ b/wolfssl/openssl/pem.h @@ -81,6 +81,10 @@ int wolfSSL_PEM_write_RSAPublicKey(XFILE fp, WOLFSSL_RSA* key); WOLFSSL_API int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA *x); + +WOLFSSL_API +WOLFSSL_RSA *wolfSSL_PEM_read_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA** rsa, + wc_pem_password_cb* cb, void *pass); #endif /* NO_FILESYSTEM */ /* DSA */ @@ -232,6 +236,7 @@ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh); #define PEM_read_bio_ECPKParameters wolfSSL_PEM_read_bio_ECPKParameters #define PEM_write_RSAPrivateKey wolfSSL_PEM_write_RSAPrivateKey #define PEM_write_RSA_PUBKEY wolfSSL_PEM_write_RSA_PUBKEY +#define PEM_read_RSA_PUBKEY wolfSSL_PEM_read_RSA_PUBKEY #define PEM_write_RSAPublicKey wolfSSL_PEM_write_RSAPublicKey #define PEM_read_RSAPublicKey wolfSSL_PEM_read_RSAPublicKey /* DSA */ From 524f9ebd32a66c369f93fffc678a6d1d6a6864dc Mon Sep 17 00:00:00 2001 From: Satoshi Yamaguchi Date: Mon, 15 Aug 2022 16:09:40 +0900 Subject: [PATCH 2/5] Add argument check and error message to wolfSSL_PEM_read_RSA_PUBKEY --- src/pk.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pk.c b/src/pk.c index cb2c47f35..4e3140773 100644 --- a/src/pk.c +++ b/src/pk.c @@ -1585,6 +1585,12 @@ WOLFSSL_RSA *wolfSSL_PEM_read_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA* rsa = NULL; WOLFSSL_ENTER("wolfSSL_PEM_read_RSA_PUBKEY"); + + /* Validate parameters. */ + if (fp == NULL) { + WOLFSSL_MSG("Bad function arguments"); + return NULL; + } /* Read into a new EVP_PKEY. */ pkey = wolfSSL_PEM_read_PUBKEY(fp, NULL, cb, pass); @@ -1600,6 +1606,9 @@ WOLFSSL_RSA *wolfSSL_PEM_read_RSA_PUBKEY(XFILE fp, wolfSSL_EVP_PKEY_free(pkey); } + else { + WOLFSSL_MSG("wolfSSL_PEM_read_PUBKEY failed"); + } return rsa; } From 091fc71c74020d2f423d4aa6f40f6a04f4502fac Mon Sep 17 00:00:00 2001 From: Satoshi Yamaguchi Date: Wed, 17 Aug 2022 01:03:09 +0900 Subject: [PATCH 3/5] Fix EVP_PKEY not freed and FILE pointer not closed --- tests/api.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/api.c b/tests/api.c index d766b69e6..77a8f9c58 100644 --- a/tests/api.c +++ b/tests/api.c @@ -32003,6 +32003,7 @@ static int test_wolfSSL_PEM_read_PUBKEY(void) file = XFOPEN(fname, "rb"); AssertTrue(file != XBADFILE); AssertNotNull(pkey = PEM_read_PUBKEY(file, NULL, NULL, NULL)); + EVP_PKEY_free(pkey); XFCLOSE(file); #endif @@ -32490,6 +32491,7 @@ static int test_wolfSSL_PEM_read_RSA_PUBKEY(void) AssertNotNull((rsa = PEM_read_RSA_PUBKEY(file, NULL, NULL, NULL))); AssertIntEQ(RSA_size(rsa), 256); RSA_free(rsa); + XFCLOSE(file); #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) */ return 0; From f5a257c383d4aed8399f126e052590f2540db155 Mon Sep 17 00:00:00 2001 From: Satoshi Yamaguchi Date: Wed, 17 Aug 2022 11:56:46 +0900 Subject: [PATCH 4/5] Add WOLFSSL_LEAVE to wolfSSL_PEM_read_RSA_PUBKEY and wolfSSL_PEM_read_PUBKEY --- src/pk.c | 4 +++- src/ssl.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pk.c b/src/pk.c index 4e3140773..b560b8e58 100644 --- a/src/pk.c +++ b/src/pk.c @@ -1588,7 +1588,7 @@ WOLFSSL_RSA *wolfSSL_PEM_read_RSA_PUBKEY(XFILE fp, /* Validate parameters. */ if (fp == NULL) { - WOLFSSL_MSG("Bad function arguments"); + WOLFSSL_LEAVE("wolfSSL_PEM_read_RSA_PUBKEY", BAD_FUNC_ARG); return NULL; } @@ -1609,6 +1609,8 @@ WOLFSSL_RSA *wolfSSL_PEM_read_RSA_PUBKEY(XFILE fp, else { WOLFSSL_MSG("wolfSSL_PEM_read_PUBKEY failed"); } + + WOLFSSL_LEAVE("wolfSSL_PEM_read_RSA_PUBKEY", 0); return rsa; } diff --git a/src/ssl.c b/src/ssl.c index 77f941f4f..c4d846480 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -28289,6 +28289,8 @@ WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY **x, wolfSSL_BIO_free(bio); } + WOLFSSL_LEAVE("wolfSSL_PEM_read_PUBKEY", 0); + return ret; } #endif /* NO_FILESYSTEM */ From 61c700352024523b7cf3a6b9350db39bee04be86 Mon Sep 17 00:00:00 2001 From: Satoshi Yamaguchi Date: Fri, 19 Aug 2022 12:38:07 +0900 Subject: [PATCH 5/5] Fix whitespace --- src/pk.c | 4 ++-- tests/api.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pk.c b/src/pk.c index b560b8e58..bcf412ead 100644 --- a/src/pk.c +++ b/src/pk.c @@ -1585,7 +1585,7 @@ WOLFSSL_RSA *wolfSSL_PEM_read_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA* rsa = NULL; WOLFSSL_ENTER("wolfSSL_PEM_read_RSA_PUBKEY"); - + /* Validate parameters. */ if (fp == NULL) { WOLFSSL_LEAVE("wolfSSL_PEM_read_RSA_PUBKEY", BAD_FUNC_ARG); @@ -1609,7 +1609,7 @@ WOLFSSL_RSA *wolfSSL_PEM_read_RSA_PUBKEY(XFILE fp, else { WOLFSSL_MSG("wolfSSL_PEM_read_PUBKEY failed"); } - + WOLFSSL_LEAVE("wolfSSL_PEM_read_RSA_PUBKEY", 0); return rsa; diff --git a/tests/api.c b/tests/api.c index 77a8f9c58..1e297dec8 100644 --- a/tests/api.c +++ b/tests/api.c @@ -32485,7 +32485,7 @@ static int test_wolfSSL_PEM_read_RSA_PUBKEY(void) XFILE file; const char* fname = "./certs/client-keyPub.pem"; RSA *rsa; - + file = XFOPEN(fname, "rb"); AssertTrue((file != XBADFILE)); AssertNotNull((rsa = PEM_read_RSA_PUBKEY(file, NULL, NULL, NULL)));