Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 212 additions & 0 deletions tests/api/test_evp_pkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,218 @@ int test_wolfSSL_EVP_PKEY_set1_get1_DH(void)
return EXPECT_RESULT();
} /* END test_EVP_PKEY_set1_get1_DH */

#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && \
!defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER) && \
!defined(NO_DSA) && !defined(HAVE_SELFTEST) && \
!defined(WC_FIPS_186_5_PLUS) && defined(WOLFSSL_KEY_GEN) && \
defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_NO_MALLOC) && \
!defined(WOLFSSL_STATIC_MEMORY) && !defined(WOLFSSL_DEBUG_MEMORY) && \
!defined(WOLFSSL_CHECK_MEM_ZERO)
/* CHECK_MEM_ZERO passes free_function a pointer offset by a header. */
#define TEST_DER_WATCH_FREE_HOOK
/* Free hook watching one buffer: counts its frees and checks it is zeroed. */
static wolfSSL_Malloc_cb der_watch_prev_malloc = NULL;
static wolfSSL_Free_cb der_watch_prev_free = NULL;
static wolfSSL_Realloc_cb der_watch_prev_realloc = NULL;
static int der_watch_installed = 0;
static void* der_watch_ptr = NULL;
static int der_watch_sz = 0;
static int der_watch_frees = 0;
static int der_watch_zeroed = 0;

static void der_watch_free_cb(void* ptr)
{
if (ptr != NULL && ptr == der_watch_ptr) {
int i;
der_watch_zeroed = 1;
for (i = 0; i < der_watch_sz; i++) {
if (((byte*)ptr)[i] != 0) {
der_watch_zeroed = 0;
break;
}
}
der_watch_frees++;
der_watch_ptr = NULL; /* address may be reused */
}
if (der_watch_prev_free != NULL)
der_watch_prev_free(ptr);
else
free(ptr);
}

static void der_watch_begin(const WOLFSSL_EVP_PKEY* pkey)
{
der_watch_ptr = (pkey == NULL) ? NULL : pkey->pkey.ptr;
der_watch_sz = (pkey == NULL) ? 0 : pkey->pkey_sz;
der_watch_frees = 0;
der_watch_zeroed = 0;
}
static int der_watch_install(void)
{
if (wolfSSL_GetAllocators(&der_watch_prev_malloc, &der_watch_prev_free,
&der_watch_prev_realloc) != 0) {
return -1;
}
if (wolfSSL_SetAllocators(der_watch_prev_malloc, der_watch_free_cb,
der_watch_prev_realloc) != 0) {
return -1;
}
der_watch_installed = 1;
return 0;
}

static void der_watch_uninstall(void)
{
if (der_watch_installed) {
(void)wolfSSL_SetAllocators(der_watch_prev_malloc,
der_watch_prev_free, der_watch_prev_realloc);
der_watch_installed = 0;
}
der_watch_prev_free = NULL;
}
#define DER_WATCH_INSTALL() ExpectIntEQ(der_watch_install(), 0)
#define DER_WATCH_UNINSTALL() der_watch_uninstall()
#define DER_WATCH_BEGIN(pkey) der_watch_begin(pkey)
/* The previous DER must be freed exactly once, zeroed beforehand. */
#define DER_WATCH_END() \
do { \
ExpectIntEQ(der_watch_frees, 1); \
ExpectIntEQ(der_watch_zeroed, 1); \
der_watch_ptr = NULL; \
} while (0)
#else
#define DER_WATCH_INSTALL() WC_DO_NOTHING
#define DER_WATCH_UNINSTALL() WC_DO_NOTHING
#define DER_WATCH_BEGIN(pkey) WC_DO_NOTHING
#define DER_WATCH_END() WC_DO_NOTHING
#endif

/* Reassigning a key must wipe and free the previous DER cache. */
int test_wolfSSL_EVP_PKEY_reassign_der_cache(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && \
!defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER) && \
!defined(NO_DSA) && !defined(HAVE_SELFTEST) && \
!defined(WC_FIPS_186_5_PLUS) && defined(WOLFSSL_KEY_GEN)
EVP_PKEY* pkey = NULL;
EVP_PKEY* dsaPkey = NULL;
DSA* dsa = NULL;
RSA* rsa = NULL;
RSA* rsaEmpty = NULL;
XFILE f = XBADFILE;
byte dsaDer[TWOK_BUF];
byte rsaDer[TWOK_BUF];
const unsigned char* p = NULL;
long dsaDerSz = 0;
long rsaDerSz = 0;
int dsaPkeySz = 0;
#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && \
(!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
(HAVE_FIPS_VERSION > 2)))
DH* dh = NULL;
byte dhDer[TWOK_BUF];
long dhDerSz = 0;
int dhPkeySz = 0;
#endif

ExpectTrue((f = XFOPEN("./certs/dsa2048.der", "rb")) != XBADFILE);
ExpectIntGT(dsaDerSz = (long)XFREAD(dsaDer, 1, sizeof(dsaDer), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
ExpectTrue((f = XFOPEN("./certs/client-key.der", "rb")) != XBADFILE);
ExpectIntGT(rsaDerSz = (long)XFREAD(rsaDer, 1, sizeof(rsaDer), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}

p = dsaDer;
ExpectNotNull(d2i_PrivateKey(EVP_PKEY_DSA, &dsaPkey, &p, dsaDerSz));
ExpectNotNull(dsa = EVP_PKEY_get1_DSA(dsaPkey));
p = rsaDer;
ExpectNotNull(rsa = d2i_RSAPrivateKey(NULL, &p, rsaDerSz));
ExpectNotNull(rsaEmpty = RSA_new());
ExpectNotNull(pkey = EVP_PKEY_new());
DER_WATCH_INSTALL();

/* DSA, then the same DSA again. */
ExpectIntEQ(EVP_PKEY_set1_DSA(pkey, dsa), WOLFSSL_SUCCESS);
ExpectNotNull(pkey == NULL ? NULL : pkey->pkey.ptr);
ExpectIntGT(dsaPkeySz = (pkey == NULL ? 0 : pkey->pkey_sz), 0);
DER_WATCH_BEGIN(pkey);
ExpectIntEQ(EVP_PKEY_set1_DSA(pkey, dsa), WOLFSSL_SUCCESS);
DER_WATCH_END();
ExpectIntEQ(pkey == NULL ? 0 : pkey->pkey_sz, dsaPkeySz);
Comment thread
kojo1 marked this conversation as resolved.
Resolved

/* Unencodable RSA key: old DSA DER must not remain. */
DER_WATCH_BEGIN(pkey);
ExpectIntEQ(EVP_PKEY_assign_RSA(pkey, rsaEmpty), WOLFSSL_SUCCESS);
DER_WATCH_END();
if (EXPECT_FAIL()) {
RSA_free(rsaEmpty);
}
rsaEmpty = NULL;
ExpectNull(pkey == NULL ? (char*)1 : pkey->pkey.ptr);
ExpectIntEQ(pkey == NULL ? -1 : pkey->pkey_sz, 0);

/* Private RSA key: cache holds its DER. */
ExpectIntEQ(EVP_PKEY_assign_RSA(pkey, rsa), WOLFSSL_SUCCESS);
if (EXPECT_FAIL()) {
RSA_free(rsa);
}
rsa = NULL;
ExpectIntEQ(pkey == NULL ? 0 : pkey->pkey_sz, (int)rsaDerSz);
ExpectIntEQ(pkey == NULL || pkey->pkey.ptr == NULL ? -1 :
XMEMCMP(pkey->pkey.ptr, rsaDer, (size_t)rsaDerSz), 0);

#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && \
(!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
(HAVE_FIPS_VERSION > 2)))
ExpectTrue((f = XFOPEN("./certs/dh2048.der", "rb")) != XBADFILE);
ExpectIntGT(dhDerSz = (long)XFREAD(dhDer, 1, sizeof(dhDer), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
p = dhDer;
ExpectNotNull(dh = wolfSSL_d2i_DHparams(NULL, &p, dhDerSz));

/* RSA -> DH -> DH. */
DER_WATCH_BEGIN(pkey);
ExpectIntEQ(EVP_PKEY_set1_DH(pkey, dh), WOLFSSL_SUCCESS);
DER_WATCH_END();
ExpectIntGT(dhPkeySz = (pkey == NULL ? 0 : pkey->pkey_sz), 0);
DER_WATCH_BEGIN(pkey);
ExpectIntEQ(EVP_PKEY_set1_DH(pkey, dh), WOLFSSL_SUCCESS);
DER_WATCH_END();
ExpectIntEQ(pkey == NULL ? 0 : pkey->pkey_sz, dhPkeySz);
ExpectIntEQ(pkey == NULL ? -1 : pkey->pkcs8HeaderSz, 0);
#endif

/* Back to DSA. */
DER_WATCH_BEGIN(pkey);
ExpectIntEQ(EVP_PKEY_set1_DSA(pkey, dsa), WOLFSSL_SUCCESS);
DER_WATCH_END();
ExpectIntEQ(pkey == NULL ? 0 : pkey->pkey_sz, dsaPkeySz);

DER_WATCH_UNINSTALL();
EVP_PKEY_free(pkey);
#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && \
(!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
(HAVE_FIPS_VERSION > 2)))
DH_free(dh);
#endif
RSA_free(rsaEmpty);
RSA_free(rsa);
DSA_free(dsa);
EVP_PKEY_free(dsaPkey);
#endif
return EXPECT_RESULT();
}

int test_wolfSSL_EVP_PKEY_assign(void)
{
EXPECT_DECLS;
Expand Down
2 changes: 2 additions & 0 deletions tests/api/test_evp_pkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ int test_wolfSSL_EVP_PKEY_set1_get1_DSA(void);
int test_wolfSSL_EVP_PKEY_set1_get1_EC_KEY (void);
int test_wolfSSL_EVP_PKEY_get0_EC_KEY(void);
int test_wolfSSL_EVP_PKEY_set1_get1_DH (void);
int test_wolfSSL_EVP_PKEY_reassign_der_cache(void);
int test_wolfSSL_EVP_PKEY_assign(void);
int test_wolfSSL_EVP_PKEY_assign_DH(void);
int test_EVP_PKEY_rsa(void);
Expand Down Expand Up @@ -102,6 +103,7 @@ int test_wolfSSL_CTX_use_PrivateKey_pkcs8_repopulate(void);
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_set1_get1_EC_KEY), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_get0_EC_KEY), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_set1_get1_DH), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_reassign_der_cache), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_assign), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_assign_DH), \
TEST_DECL_GROUP("evp_pkey", test_EVP_PKEY_rsa), \
Expand Down
37 changes: 37 additions & 0 deletions wolfcrypt/src/evp.c
Original file line number Diff line number Diff line change
Expand Up @@ -9671,6 +9671,16 @@ int wolfSSL_EVP_PKEY_set1_DSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DSA *key)

if((pkey == NULL) || (key == NULL))return WOLFSSL_FAILURE;
clearEVPPkeyKeys(pkey);
/* Wipe and free the previous key's DER. */
if (pkey->pkey.ptr != NULL) {
if (pkey->pkey_sz > 0) {
ForceZero(pkey->pkey.ptr, (word32)pkey->pkey_sz);
}
XFREE(pkey->pkey.ptr, pkey->heap, DYNAMIC_TYPE_PUBLIC_KEY);
pkey->pkey.ptr = NULL;
}
pkey->pkey_sz = 0;
pkey->pkcs8HeaderSz = 0;
pkey->dsa = key;
pkey->ownDsa = 0; /* pkey does not own DSA */
pkey->type = WC_EVP_PKEY_DSA;
Expand Down Expand Up @@ -9708,6 +9718,7 @@ int wolfSSL_EVP_PKEY_set1_DSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DSA *key)
else {
WOLFSSL_MSG("wc_DsaKeyToPublicDer failed");
}
ForceZero(derBuf, (word32)derMax);
XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
return WOLFSSL_FAILURE;
}
Expand All @@ -9716,11 +9727,13 @@ int wolfSSL_EVP_PKEY_set1_DSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DSA *key)
DYNAMIC_TYPE_DER);
if (pkey->pkey.ptr == NULL) {
WOLFSSL_MSG("key malloc failed");
ForceZero(derBuf, (word32)derSz);
XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
return WOLFSSL_FAILURE;
}
pkey->pkey_sz = derSz;
XMEMCPY(pkey->pkey.ptr, derBuf, (size_t)derSz);
ForceZero(derBuf, (word32)derSz);
XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);

return WOLFSSL_SUCCESS;
Expand Down Expand Up @@ -9851,6 +9864,7 @@ int wolfSSL_EVP_PKEY_set1_DH(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DH *key)
byte havePublic = 0, havePrivate = 0;
int ret;
word32 derSz = 0;
word32 derAllocSz = 0;
byte* derBuf = NULL;
DhKey* dhkey = NULL;

Expand All @@ -9860,6 +9874,16 @@ int wolfSSL_EVP_PKEY_set1_DH(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DH *key)
return WOLFSSL_FAILURE;

clearEVPPkeyKeys(pkey);
/* Wipe and free the previous key's DER. */
if (pkey->pkey.ptr != NULL) {
if (pkey->pkey_sz > 0) {
ForceZero(pkey->pkey.ptr, (word32)pkey->pkey_sz);
}
XFREE(pkey->pkey.ptr, pkey->heap, DYNAMIC_TYPE_PUBLIC_KEY);
pkey->pkey.ptr = NULL;
}
pkey->pkey_sz = 0;
pkey->pkcs8HeaderSz = 0;

if (wolfSSL_DH_up_ref(key) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Failed to increase dh key ref count");
Expand Down Expand Up @@ -9900,6 +9924,7 @@ int wolfSSL_EVP_PKEY_set1_DH(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DH *key)
WOLFSSL_MSG("malloc failed");
return WOLFSSL_FAILURE;
}
derAllocSz = derSz;

/* Fill DER buffer */
if (havePublic && !havePrivate) {
Expand All @@ -9912,6 +9937,7 @@ int wolfSSL_EVP_PKEY_set1_DH(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DH *key)

if (ret <= 0) {
WOLFSSL_MSG("Failed to export DH Key");
ForceZero(derBuf, derAllocSz);
XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
return WOLFSSL_FAILURE;
}
Expand Down Expand Up @@ -11010,6 +11036,16 @@ int wolfSSL_EVP_PKEY_assign_RSA(WOLFSSL_EVP_PKEY* pkey, WOLFSSL_RSA* key)
return WOLFSSL_FAILURE;

clearEVPPkeyKeys(pkey);
/* Wipe and free the previous key's DER. */
if (pkey->pkey.ptr != NULL) {
if (pkey->pkey_sz > 0) {
ForceZero(pkey->pkey.ptr, (word32)pkey->pkey_sz);
}
XFREE(pkey->pkey.ptr, pkey->heap, DYNAMIC_TYPE_PUBLIC_KEY);
pkey->pkey.ptr = NULL;
}
pkey->pkey_sz = 0;
pkey->pkcs8HeaderSz = 0;
pkey->type = WC_EVP_PKEY_RSA;
pkey->rsa = key;
pkey->ownRsa = 1;
Expand All @@ -11029,6 +11065,7 @@ int wolfSSL_EVP_PKEY_assign_RSA(WOLFSSL_EVP_PKEY* pkey, WOLFSSL_RSA* key)
pkey->pkey.ptr = (char*)derBuf;
}
else { /* failure - okay to ignore */
ForceZero(derBuf, derSz);
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
derBuf = NULL;
}
Expand Down
Loading