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
12 changes: 9 additions & 3 deletions src/ssl_p7p12.c
Original file line number Diff line number Diff line change
Expand Up @@ -2073,11 +2073,17 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
}
InitX509(*cert, 1, heap);
InitDecodedCert(DeCert, certData, certDataSz, heap);
if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL, NULL) != 0) {
ret = ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL, NULL);
if (ret != 0) {
WOLFSSL_MSG("Issue with parsing certificate");
}
if (CopyDecodedToX509(*cert, DeCert) != 0) {
WOLFSSL_MSG("Failed to copy decoded cert");
else {
ret = CopyDecodedToX509(*cert, DeCert);
if (ret != 0) {
WOLFSSL_MSG("Failed to copy decoded cert");
}
}
if (ret != 0) {
FreeDecodedCert(DeCert);
XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (ca != NULL) {
Expand Down
165 changes: 165 additions & 0 deletions tests/api/test_ossl_p7p12.c
Original file line number Diff line number Diff line change
Expand Up @@ -2048,3 +2048,168 @@ int test_wolfSSL_PKCS12_create_mac(void)
#endif
return EXPECT_RESULT();
}

#if !defined(HAVE_FIPS) && defined(OPENSSL_EXTRA) && !defined(NO_DES3) && \
!defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) && \
!defined(NO_ASN) && !defined(NO_PWDBASED) && !defined(NO_RSA) && \
!defined(NO_SHA) && defined(HAVE_PKCS12) && defined(WOLFSSL_AES_256) && \
defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_NO_MALLOC) && \
!defined(WOLFSSL_STATIC_MEMORY)
#define TEST_PKCS12_PARSE_OOM

static int pkcs12_fail_alloc_at = -1;
static int pkcs12_alloc_seen = 0;
/* Allocators in place before the test, used for all real allocations so
* memory can be freed after they are restored. */
static wolfSSL_Malloc_cb pkcs12_prev_malloc = NULL;
static wolfSSL_Free_cb pkcs12_prev_free = NULL;
static wolfSSL_Realloc_cb pkcs12_prev_realloc = NULL;

/* Fail only the allocation at index pkcs12_fail_alloc_at. */
#ifdef WOLFSSL_DEBUG_MEMORY
static void* pkcs12_oom_malloc_cb(size_t size, const char* func,
unsigned int line)
{
if (pkcs12_alloc_seen++ == pkcs12_fail_alloc_at) {
return NULL;
}
return (pkcs12_prev_malloc != NULL) ?
pkcs12_prev_malloc(size, func, line) : malloc(size);
}
#else
static void* pkcs12_oom_malloc_cb(size_t size)
{
if (pkcs12_alloc_seen++ == pkcs12_fail_alloc_at) {
return NULL;
}
return (pkcs12_prev_malloc != NULL) ? pkcs12_prev_malloc(size) :
malloc(size);
}
#endif

#ifdef WOLFSSL_DEBUG_MEMORY
static void pkcs12_oom_free_cb(void* ptr, const char* func, unsigned int line)
{
if (pkcs12_prev_free != NULL) {
pkcs12_prev_free(ptr, func, line);
}
else {
free(ptr);
}
}
#else
static void pkcs12_oom_free_cb(void* ptr)
{
if (pkcs12_prev_free != NULL) {
pkcs12_prev_free(ptr);
}
else {
free(ptr);
}
}
#endif

#ifdef WOLFSSL_DEBUG_MEMORY
static void* pkcs12_oom_realloc_cb(void* ptr, size_t size, const char* func,
unsigned int line)
{
return (pkcs12_prev_realloc != NULL) ?
pkcs12_prev_realloc(ptr, size, func, line) : realloc(ptr, size);
}
#else
static void* pkcs12_oom_realloc_cb(void* ptr, size_t size)
{
return (pkcs12_prev_realloc != NULL) ? pkcs12_prev_realloc(ptr, size) :
realloc(ptr, size);
}
#endif

/* Parse a new PKCS#12 object with custom allocators in place.
*
* The object is decoded before the allocators are set so that only
* wolfSSL_PKCS12_parse() sees the failure.
*/
static int pkcs12_oom_parse(const byte* der, word32 derSz, int failAt,
WOLFSSL_EVP_PKEY** pkey, WOLFSSL_X509** cert)
{
EXPECT_DECLS;
WC_PKCS12* pkcs12 = NULL;
int ret = WOLFSSL_FAILURE;
ExpectNotNull(pkcs12 = wc_PKCS12_new());
ExpectIntEQ(wc_d2i_PKCS12(der, derSz, pkcs12), 0);
ExpectIntEQ(wolfSSL_GetAllocators(&pkcs12_prev_malloc, &pkcs12_prev_free,
&pkcs12_prev_realloc), 0);
ExpectIntEQ(wolfSSL_SetAllocators(pkcs12_oom_malloc_cb, pkcs12_oom_free_cb,
pkcs12_oom_realloc_cb), 0);

if (EXPECT_SUCCESS()) {
pkcs12_alloc_seen = 0;
pkcs12_fail_alloc_at = failAt;
ret = wolfSSL_PKCS12_parse(pkcs12, "wolfSSL test", pkey, cert, NULL);
pkcs12_fail_alloc_at = -1;
}

(void)wolfSSL_SetAllocators(pkcs12_prev_malloc, pkcs12_prev_free,
pkcs12_prev_realloc);
wc_PKCS12_free(pkcs12);

return EXPECT_SUCCESS() ? ret : TEST_FAIL;
}
#endif /* TEST_PKCS12_PARSE_OOM */

/* A failure to parse the main certificate must be a failure of
* wolfSSL_PKCS12_parse() and not a success with a partially populated X509.
*
* wc_PKCS12_parse() only selects a certificate that it has parsed, so malformed
* data doesn't reach the second parse in wolfSSL_PKCS12_parse(). An allocation
* failure does. Each allocation is failed in turn.
*/
int test_wolfSSL_PKCS12_parse_main_cert_oom(void)
{
EXPECT_DECLS;
#ifdef TEST_PKCS12_PARSE_OOM
byte der[6000];
int derSz = 0;
int total = 0;
int i;
XFILE f = XBADFILE;
WOLFSSL_EVP_PKEY* pkey = NULL;
WOLFSSL_X509* cert = NULL;

ExpectTrue((f = XFOPEN("./certs/test-servercert.p12", "rb")) != XBADFILE);
ExpectIntGT(derSz = (int)XFREAD(der, 1, sizeof(der), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
}

/* Get the number of allocations. */
ExpectIntEQ(pkcs12_oom_parse(der, (word32)derSz, -1, &pkey, &cert),
WOLFSSL_SUCCESS);
ExpectNotNull(cert);
total = pkcs12_alloc_seen;
wolfSSL_EVP_PKEY_free(pkey);
pkey = NULL;
wolfSSL_X509_free(cert);
cert = NULL;

for (i = 0; (i < total) && EXPECT_SUCCESS(); i++) {
int ret = pkcs12_oom_parse(der, (word32)derSz, i, &pkey, &cert);

/* The public key is missing when the parse stopped early. Names aren't
* checked as CopyDecodedToX509() doesn't report all failures to copy
* them. No certificate is returned when the pair search can't parse
* it. */
if ((ret == WOLFSSL_SUCCESS) && (cert != NULL)) {
WOLFSSL_EVP_PKEY* certKey = NULL;

ExpectNotNull(certKey = wolfSSL_X509_get_pubkey(cert));
wolfSSL_EVP_PKEY_free(certKey);
}
wolfSSL_EVP_PKEY_free(pkey);
pkey = NULL;
wolfSSL_X509_free(cert);
cert = NULL;
}
#endif /* TEST_PKCS12_PARSE_OOM */
return EXPECT_RESULT();
}
4 changes: 3 additions & 1 deletion tests/api/test_ossl_p7p12.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ int test_wolfSSL_SMIME_write_PKCS7(void);
int test_wolfSSL_PKCS7_verify_nointern(void);
int test_wolfSSL_PKCS12(void);
int test_wolfSSL_PKCS12_create_mac(void);
int test_wolfSSL_PKCS12_parse_main_cert_oom(void);

#define TEST_OSSL_PKCS7_DECLS \
TEST_DECL_GROUP("ossl_p7", test_wolfssl_PKCS7), \
Expand All @@ -58,7 +59,8 @@ int test_wolfSSL_PKCS12_create_mac(void);

#define TEST_OSSL_PKCS12_DECLS \
TEST_DECL_GROUP("ossl_p12", test_wolfSSL_PKCS12), \
TEST_DECL_GROUP("ossl_p12", test_wolfSSL_PKCS12_create_mac)
TEST_DECL_GROUP("ossl_p12", test_wolfSSL_PKCS12_create_mac),\
TEST_DECL_GROUP("ossl_p12", test_wolfSSL_PKCS12_parse_main_cert_oom)

#endif /* WOLFCRYPT_TEST_OSSL_P7P12_H */

Loading