Feat: Allow for a wrapper for pem write privatekey & PUBKEY

This commit is contained in:
Roy Carter
2026-04-26 16:52:02 +03:00
parent 22e505bcfa
commit 96e966e779
4 changed files with 228 additions and 0 deletions
+119
View File
@@ -6282,6 +6282,125 @@ int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
}
#endif /* !NO_BIO */
#ifndef NO_FILESYSTEM
/* Writes a public key to a file pointer encoded in PEM format.
*
* Mirrors wolfSSL_PEM_read_PUBKEY: convert the EVP_PKEY to public-key DER and
* write it with the generic PUBLIC KEY PEM type.
*
* @param [in] fp File pointer to write to.
* @param [in] key Public key to write in PEM format.
* @return 1 on success.
* @return 0 on failure.
*/
int wolfSSL_PEM_write_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY* key)
{
int ret = 0;
#if !defined(NO_ASN) && !defined(NO_PWDBASED)
unsigned char* der = NULL;
int derSz;
#endif
WOLFSSL_ENTER("wolfSSL_PEM_write_PUBKEY");
if ((fp == XBADFILE) || (key == NULL)) {
WOLFSSL_MSG("Bad Function Arguments");
return 0;
}
#if !defined(NO_ASN) && !defined(NO_PWDBASED)
derSz = wolfSSL_i2d_PUBKEY(key, &der);
if (derSz > 0) {
ret = der_write_to_file_as_pem(der, derSz, fp, PUBLICKEY_TYPE, NULL);
}
XFREE(der, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
#else
WOLFSSL_MSG("i2d_PUBKEY not supported in this build");
#endif
return ret;
}
/* Writes a private key to a file pointer encoded in PEM format.
*
* Mirrors wolfSSL_PEM_read_PrivateKey's key-type switch and writes the stored
* DER as the matching PEM private key type.
*
* @param [in] fp File pointer to write to.
* @param [in] key Private key to write in PEM format.
* @param [in] cipher Encryption cipher to use. May be NULL.
* @param [in] passwd Password to use when encrypting. May be NULL.
* @param [in] len Length of password.
* @param [in] cb Password callback.
* @param [in] arg Password callback argument.
* @return 1 on success.
* @return 0 on failure.
*/
int wolfSSL_PEM_write_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY* key,
const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int len,
wc_pem_password_cb* cb, void* arg)
{
int err = 0;
int type = 0;
WOLFSSL_ENTER("wolfSSL_PEM_write_PrivateKey");
/* Validate parameters. */
if ((fp == XBADFILE) || (key == NULL)) {
WOLFSSL_MSG("Bad Function Arguments");
err = 1;
}
if ((!err) && ((cipher != NULL) || (passwd != NULL) || (len != 0) ||
(cb != NULL) || (arg != NULL))) {
WOLFSSL_MSG("PEM private key encryption not supported here");
}
if (!err) {
/* Set PEM type based on key type, inverse of PEM_read_PrivateKey. */
switch (key->type) {
#ifndef NO_RSA
case WC_EVP_PKEY_RSA:
type = PRIVATEKEY_TYPE;
break;
#endif
#ifndef NO_DSA
case WC_EVP_PKEY_DSA:
type = DSA_PRIVATEKEY_TYPE;
break;
#endif
#ifdef HAVE_ECC
case WC_EVP_PKEY_EC:
type = ECC_PRIVATEKEY_TYPE;
break;
#endif
#ifndef NO_DH
case WC_EVP_PKEY_DH:
type = DH_PRIVATEKEY_TYPE;
break;
#endif
default:
type = WOLFSSL_FATAL_ERROR;
break;
}
}
if ((!err) && (type == WOLFSSL_FATAL_ERROR)) {
err = 1;
}
/* Write DER data as the selected PEM private key type. */
if ((!err) && (der_write_to_file_as_pem((byte*)key->pkey.ptr, key->pkey_sz,
fp, type, NULL) != 1)) {
err = 1;
}
WOLFSSL_LEAVE("wolfSSL_PEM_write_PrivateKey", err);
return !err;
}
#endif /* !NO_FILESYSTEM */
#ifndef NO_BIO
/* Create a private key object from the data in the BIO.
*
+98
View File
@@ -755,6 +755,104 @@ int test_wolfSSL_PEM_PrivateKey(void)
return EXPECT_RESULT();
}
int test_wolfSSL_PEM_write_PrivateKey_PUBKEY(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_RSA) && \
!defined(NO_FILESYSTEM) && defined(USE_CERT_BUFFERS_2048) && \
!defined(NO_ASN) && !defined(NO_PWDBASED)
const char* privFile = "./test-pem-write-private-key.pem";
const char* pubFile = "./test-pem-write-pubkey.pem";
const unsigned char* serverKey =
(const unsigned char*)server_key_der_2048;
EVP_PKEY* pkey = NULL;
EVP_PKEY* readPriv = NULL;
EVP_PKEY* readPub = NULL;
unsigned char* pubDer = NULL;
unsigned char* readPubDer = NULL;
XFILE fp = XBADFILE;
long privSz = 0;
long pubSz = 0;
int pubDerSz = 0;
int readPubDerSz = 0;
remove(privFile);
remove(pubFile);
ExpectNotNull(wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, &pkey, &serverKey,
(long)sizeof_server_key_der_2048));
ExpectIntEQ(PEM_write_PrivateKey(XBADFILE, pkey, NULL, NULL, 0, NULL,
NULL), 0);
ExpectIntEQ(PEM_write_PrivateKey(stderr, NULL, NULL, NULL, 0, NULL,
NULL), 0);
ExpectIntEQ(PEM_write_PUBKEY(XBADFILE, pkey), 0);
ExpectIntEQ(PEM_write_PUBKEY(stderr, NULL), 0);
ExpectTrue((fp = XFOPEN(privFile, "wb")) != XBADFILE);
if (fp != XBADFILE) {
ExpectIntEQ(PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL),
1);
XFCLOSE(fp);
fp = XBADFILE;
}
ExpectTrue((fp = XFOPEN(privFile, "rb")) != XBADFILE);
if (fp != XBADFILE) {
ExpectTrue(XFSEEK(fp, 0, XSEEK_END) == 0);
ExpectIntGT(privSz = XFTELL(fp), 0);
ExpectTrue(XFSEEK(fp, 0, XSEEK_SET) == 0);
ExpectNotNull(readPriv = PEM_read_PrivateKey(fp, NULL, NULL, NULL));
XFCLOSE(fp);
fp = XBADFILE;
}
if ((pkey != NULL) && (readPriv != NULL) && (pkey->pkey.ptr != NULL) &&
(readPriv->pkey.ptr != NULL)) {
ExpectIntEQ(pkey->pkey_sz, readPriv->pkey_sz);
ExpectIntEQ(XMEMCMP(pkey->pkey.ptr, readPriv->pkey.ptr,
pkey->pkey_sz), 0);
}
ExpectIntGT(pubDerSz = wolfSSL_i2d_PUBKEY(pkey, &pubDer), 0);
ExpectTrue((fp = XFOPEN(pubFile, "wb")) != XBADFILE);
if (fp != XBADFILE) {
ExpectIntEQ(PEM_write_PUBKEY(fp, pkey), 1);
XFCLOSE(fp);
fp = XBADFILE;
}
ExpectTrue((fp = XFOPEN(pubFile, "rb")) != XBADFILE);
if (fp != XBADFILE) {
ExpectTrue(XFSEEK(fp, 0, XSEEK_END) == 0);
ExpectIntGT(pubSz = XFTELL(fp), 0);
ExpectTrue(XFSEEK(fp, 0, XSEEK_SET) == 0);
ExpectNotNull(readPub = PEM_read_PUBKEY(fp, NULL, NULL, NULL));
XFCLOSE(fp);
fp = XBADFILE;
}
ExpectIntGT(readPubDerSz = wolfSSL_i2d_PUBKEY(readPub, &readPubDer), 0);
ExpectIntEQ(pubDerSz, readPubDerSz);
if ((pubDer != NULL) && (readPubDer != NULL) && (pubDerSz > 0) &&
(pubDerSz == readPubDerSz)) {
ExpectIntEQ(XMEMCMP(pubDer, readPubDer, pubDerSz), 0);
}
ExpectIntGT(privSz, pubSz);
XFREE(readPubDer, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
XFREE(pubDer, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
EVP_PKEY_free(readPub);
EVP_PKEY_free(readPriv);
EVP_PKEY_free(pkey);
if (fp != XBADFILE) {
XFCLOSE(fp);
}
remove(privFile);
remove(pubFile);
#endif
return EXPECT_RESULT();
}
int test_wolfSSL_PEM_file_RSAKey(void)
{
EXPECT_DECLS;
+2
View File
@@ -32,6 +32,7 @@ int test_wolfSSL_PEM_PrivateKey_ecc(void);
int test_wolfSSL_PEM_PrivateKey_dsa(void);
int test_wolfSSL_PEM_PrivateKey_dh(void);
int test_wolfSSL_PEM_PrivateKey(void);
int test_wolfSSL_PEM_write_PrivateKey_PUBKEY(void);
int test_wolfSSL_PEM_file_RSAKey(void);
int test_wolfSSL_PEM_file_RSAPrivateKey(void);
int test_wolfSSL_PEM_read_RSA_PUBKEY(void);
@@ -52,6 +53,7 @@ int test_wolfSSL_PEM_PUBKEY(void);
TEST_DECL_GROUP("ossl_pem", test_wolfSSL_PEM_PrivateKey_dsa), \
TEST_DECL_GROUP("ossl_pem", test_wolfSSL_PEM_PrivateKey_dh), \
TEST_DECL_GROUP("ossl_pem", test_wolfSSL_PEM_PrivateKey), \
TEST_DECL_GROUP("ossl_pem", test_wolfSSL_PEM_write_PrivateKey_PUBKEY), \
TEST_DECL_GROUP("ossl_pem", test_wolfSSL_PEM_file_RSAKey), \
TEST_DECL_GROUP("ossl_pem", test_wolfSSL_PEM_file_RSAPrivateKey), \
TEST_DECL_GROUP("ossl_pem", test_wolfSSL_PEM_read_RSA_PUBKEY), \
+9
View File
@@ -231,6 +231,13 @@ WOLFSSL_API
int wolfSSL_PEM_write_X509(XFILE fp, WOLFSSL_X509 *x);
WOLFSSL_API
int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh);
WOLFSSL_API
int wolfSSL_PEM_write_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY* key,
const WOLFSSL_EVP_CIPHER* cipher,
unsigned char* passwd, int len,
wc_pem_password_cb* cb, void* arg);
WOLFSSL_API
int wolfSSL_PEM_write_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY* key);
#endif /* NO_FILESYSTEM */
#ifndef OPENSSL_COEXIST
@@ -244,6 +251,7 @@ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh);
#define PEM_read_X509 wolfSSL_PEM_read_X509
#define PEM_read_PrivateKey wolfSSL_PEM_read_PrivateKey
#define PEM_write_PrivateKey wolfSSL_PEM_write_PrivateKey
#define PEM_write_X509 wolfSSL_PEM_write_X509
#define PEM_write_bio_PrivateKey wolfSSL_PEM_write_bio_PrivateKey
#define PEM_write_bio_PKCS8PrivateKey wolfSSL_PEM_write_bio_PKCS8PrivateKey
@@ -287,6 +295,7 @@ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh);
#define PEM_read_PUBKEY wolfSSL_PEM_read_PUBKEY
#define PEM_read_bio_PUBKEY wolfSSL_PEM_read_bio_PUBKEY
#define PEM_write_bio_PUBKEY wolfSSL_PEM_write_bio_PUBKEY
#define PEM_write_PUBKEY wolfSSL_PEM_write_PUBKEY
#define PEM_write_bio_PKCS8_PRIV_KEY_INFO wolfSSL_PEM_write_bio_PKCS8_PRIV_KEY_INFO
#define PEM_read_bio_PKCS8_PRIV_KEY_INFO wolfSSL_PEM_read_bio_PKCS8_PRIV_KEY_INFO