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
94 changes: 94 additions & 0 deletions tests/api/test_asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -2337,6 +2337,100 @@ int test_DecodeAltNames_length_underflow(void)
return EXPECT_RESULT();
}

/* Only one HardwareModuleName otherName (RFC 4108 Section 5) is kept, in
* cert->hwType and cert->hwSerialNum. A subjectAltName carrying a second one
* must be rejected with ASN_PARSE_E by both the template and the original
* parser, rather than the second overwriting and leaking the first's
* buffers. */
int test_DecodeAltNames_dup_hw_module_name(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_SEP) && !defined(NO_CERTS) && !defined(NO_ASN)
/* GeneralNames holding one otherName:
* [0] { type-id id-on-hardwareModuleName (1.3.6.1.5.5.7.8.4),
* [0] EXPLICIT SEQUENCE { hwType OID 1.2.3.4,
* hwSerialNum OCTET STRING 01020304 } }
*/
static const byte oneHwName[] = {
0x30, 0x1B,
0xA0, 0x19,
0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x08, 0x04,
0xA0, 0x0D,
0x30, 0x0B,
0x06, 0x03, 0x2A, 0x03, 0x04,
0x04, 0x04, 0x01, 0x02, 0x03, 0x04
};
/* The same GeneralNames with a second HardwareModuleName otherName
* (hwType 1.2.3.5, hwSerialNum 05060708) appended. */
static const byte twoHwNames[] = {
0x30, 0x36,
0xA0, 0x19,
0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x08, 0x04,
0xA0, 0x0D,
0x30, 0x0B,
0x06, 0x03, 0x2A, 0x03, 0x04,
0x04, 0x04, 0x01, 0x02, 0x03, 0x04,
0xA0, 0x19,
0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x08, 0x04,
0xA0, 0x0D,
0x30, 0x0B,
0x06, 0x03, 0x2A, 0x03, 0x05,
0x04, 0x04, 0x05, 0x06, 0x07, 0x08
};
/* A different otherName whose value is also a SEQUENCE, not shaped like
* a HardwareModuleName: id-on-permanentIdentifier (1.3.6.1.5.5.7.8.3,
* RFC 4043) with SEQUENCE { UTF8String "abc", OID 1.2.3.4 }. */
static const byte permId[] = {
0x30, 0x1A,
0xA0, 0x18,
0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x08, 0x03,
0xA0, 0x0C,
0x30, 0x0A,
0x0C, 0x03, 0x61, 0x62, 0x63,
0x06, 0x03, 0x2A, 0x03, 0x04
};
static const byte hwType[] = { 0x2A, 0x03, 0x04 };
static const byte hwSerial[] = { 0x01, 0x02, 0x03, 0x04 };
DecodedCert cert;
int isUnknown;

/* A single HardwareModuleName is decoded into hwType/hwSerialNum. */
isUnknown = 0;
wc_InitDecodedCert(&cert, oneHwName, (word32)sizeof(oneHwName), NULL);
ExpectIntEQ(DecodeExtensionType(oneHwName, (word32)sizeof(oneHwName),
ALT_NAMES_OID, 0, &cert, &isUnknown), 0);
ExpectNotNull(cert.hwType);
ExpectIntEQ(cert.hwTypeSz, (int)sizeof(hwType));
if (cert.hwType != NULL) {
ExpectBufEQ(cert.hwType, hwType, sizeof(hwType));
}
ExpectNotNull(cert.hwSerialNum);
ExpectIntEQ(cert.hwSerialNumSz, (int)sizeof(hwSerial));
if (cert.hwSerialNum != NULL) {
ExpectBufEQ(cert.hwSerialNum, hwSerial, sizeof(hwSerial));
}
wc_FreeDecodedCert(&cert);

/* A second HardwareModuleName is rejected. */
isUnknown = 0;
wc_InitDecodedCert(&cert, twoHwNames, (word32)sizeof(twoHwNames), NULL);
ExpectIntEQ(DecodeExtensionType(twoHwNames, (word32)sizeof(twoHwNames),
ALT_NAMES_OID, 0, &cert, &isUnknown), WC_NO_ERR_TRACE(ASN_PARSE_E));
wc_FreeDecodedCert(&cert);

/* Another otherName with a SEQUENCE value is not decoded as a
* HardwareModuleName. */
isUnknown = 0;
wc_InitDecodedCert(&cert, permId, (word32)sizeof(permId), NULL);
ExpectIntEQ(DecodeExtensionType(permId, (word32)sizeof(permId),
ALT_NAMES_OID, 0, &cert, &isUnknown), 0);
ExpectNull(cert.hwType);
ExpectNull(cert.hwSerialNum);
wc_FreeDecodedCert(&cert);
#endif /* WOLFSSL_SEP && !NO_CERTS && !NO_ASN */
return EXPECT_RESULT();
}

/* A certificate must not carry two certificatePolicies extensions
* (non-repeatable per RFC 5280 4.2). DecodeCertExtensions calls
* DecodeExtensionType once per extension; a second certificatePolicies
Expand Down
2 changes: 2 additions & 0 deletions tests/api/test_asn.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ int test_wolfssl_local_MatchUriNameConstraint(void);
int test_wc_DecodeRsaPssParams(void);
int test_SerialNumber0_RootCA(void);
int test_DecodeAltNames_length_underflow(void);
int test_DecodeAltNames_dup_hw_module_name(void);
int test_DecodeCertExtensions_dup_certpol(void);
int test_DecodeCertExtensions_crldp_multiple_uri(void);
int test_DecodeCertExtensions_empty_certpol(void);
Expand Down Expand Up @@ -87,6 +88,7 @@ int test_wc_AltNameNewEx(void);
TEST_DECL_GROUP("asn", test_wc_DecodeRsaPssParams), \
TEST_DECL_GROUP("asn", test_SerialNumber0_RootCA), \
TEST_DECL_GROUP("asn", test_DecodeAltNames_length_underflow), \
TEST_DECL_GROUP("asn", test_DecodeAltNames_dup_hw_module_name), \
TEST_DECL_GROUP("asn", test_DecodeCertExtensions_dup_certpol), \
TEST_DECL_GROUP("asn", test_DecodeCertExtensions_crldp_multiple_uri), \
TEST_DECL_GROUP("asn", test_DecodeCertExtensions_empty_certpol), \
Expand Down
200 changes: 200 additions & 0 deletions tests/api/test_wolfmath.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,206 @@ int test_mp_rand(void)
return EXPECT_RESULT();
} /* End test_mp_rand */

#if defined(WOLFSSL_PUBLIC_MP) && defined(USE_INTEGER_HEAP_MATH) && \
defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY) && \
!defined(WOLFSSL_DEBUG_MEMORY) && !defined(WOLFSSL_NO_MALLOC)
/* Allocators that record each live buffer's size and, on free, count the
* buffers that still hold non-zero bytes. Reallocation always moves the
* buffer, as realloc() does when it cannot grow it in place, and checks the
* old one in the same way. */
#define MP_CLEAR_TRACK_MAX 8
static void* mp_clear_ptr[MP_CLEAR_TRACK_MAX];
static size_t mp_clear_sz[MP_CLEAR_TRACK_MAX];
static int mp_clear_dirty = 0;

static void mp_clear_track(void* p, size_t sz)
{
int i;

for (i = 0; i < MP_CLEAR_TRACK_MAX; i++) {
if (mp_clear_ptr[i] == NULL) {
mp_clear_ptr[i] = p;
mp_clear_sz[i] = sz;
break;
}
}
}

static size_t mp_clear_size(void* p)
{
int i;

for (i = 0; i < MP_CLEAR_TRACK_MAX; i++) {
if ((p != NULL) && (mp_clear_ptr[i] == p)) {
return mp_clear_sz[i];
}
}
return 0;
}

static void mp_clear_untrack(void* p)
{
int i;
size_t j;

for (i = 0; i < MP_CLEAR_TRACK_MAX; i++) {
if ((p != NULL) && (mp_clear_ptr[i] == p)) {
for (j = 0; j < mp_clear_sz[i]; j++) {
if (((byte*)p)[j] != 0) {
mp_clear_dirty++;
break;
}
}
mp_clear_ptr[i] = NULL;
break;
}
}
}

static void* mp_clear_malloc(size_t sz)
{
void* p = malloc(sz);
if (p != NULL)
mp_clear_track(p, sz);
return p;
}

static void mp_clear_free(void* p)
{
mp_clear_untrack(p);
free(p);
}

static void* mp_clear_realloc(void* p, size_t sz)
{
void* n;
size_t oldSz = mp_clear_size(p);

if ((p != NULL) && (oldSz == 0)) {
/* Not allocated here, so its size is not known. */
return realloc(p, sz);
}

n = malloc(sz);
if (n != NULL) {
if (p != NULL) {
XMEMCPY(n, p, (oldSz < sz) ? oldSz : sz);
mp_clear_free(p);
}
mp_clear_track(n, sz);
}
return n;
}
#endif

/*
* Testing that mp_clear() zeroizes every digit, including those above used.
* Those can still hold part of an earlier, larger value.
*/
int test_mp_clear_zeroize(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_PUBLIC_MP) && \
(defined(WOLFSSL_SP_MATH_ALL) || defined(USE_FAST_MATH))
mp_int a;
byte val[32];
word32 i;
int nonZero = 0;

XMEMSET(val, 0xA5, sizeof(val));
XMEMSET(&a, 0, sizeof(mp_int));

ExpectIntEQ(mp_init(&a), MP_OKAY);
ExpectIntEQ(mp_read_unsigned_bin(&a, val, (word32)sizeof(val)), MP_OKAY);
/* Make the value smaller. With SP math the digits above used keep the
* earlier value. */
ExpectIntEQ(mp_set(&a, 1), MP_OKAY);
mp_clear(&a);

/* The digits are held in the mp_int itself, so can be checked. */
for (i = 0; i < (word32)((sizeof(val) + sizeof(mp_digit) - 1) /
sizeof(mp_digit)); i++) {
nonZero |= (a.dp[i] != 0);
}
ExpectIntEQ(nonZero, 0);
#elif defined(USE_WOLFSSL_MEMORY) && defined(WOLFSSL_PUBLIC_MP) && \
defined(USE_INTEGER_HEAP_MATH) && !defined(WOLFSSL_STATIC_MEMORY) && \
!defined(WOLFSSL_DEBUG_MEMORY) && !defined(WOLFSSL_NO_MALLOC)
wolfSSL_Malloc_cb prevM = NULL;
wolfSSL_Free_cb prevF = NULL;
wolfSSL_Realloc_cb prevR = NULL;
mp_int a;
byte val[32];

XMEMSET(val, 0xA5, sizeof(val));
XMEMSET(&a, 0, sizeof(mp_int));
XMEMSET(mp_clear_ptr, 0, sizeof(mp_clear_ptr));
mp_clear_dirty = 0;

ExpectIntEQ(wolfSSL_GetAllocators(&prevM, &prevF, &prevR), 0);
ExpectIntEQ(wolfSSL_SetAllocators(mp_clear_malloc, mp_clear_free,
mp_clear_realloc), 0);

ExpectIntEQ(mp_init(&a), MP_OKAY);
ExpectIntEQ(mp_read_unsigned_bin(&a, val, (word32)sizeof(val)), MP_OKAY);
/* Make the value smaller without clearing the digits above used, as an
* operation that does not clear its excess digits would. */
a.used = 1;
mp_clear(&a);

/* The freed digit buffer must have been wiped in full. */
ExpectIntEQ(mp_clear_dirty, 0);

(void)wolfSSL_SetAllocators(prevM, prevF, prevR);
#endif
return EXPECT_RESULT();
} /* End test_mp_clear_zeroize */

/*
* Testing that mp_grow() wipes the digit array it replaces, which holds the
* value, before freeing it.
*/
int test_mp_grow_zeroize(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_PUBLIC_MP) && defined(USE_INTEGER_HEAP_MATH) && \
defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY) && \
!defined(WOLFSSL_DEBUG_MEMORY) && !defined(WOLFSSL_NO_MALLOC)
wolfSSL_Malloc_cb prevM = NULL;
wolfSSL_Free_cb prevF = NULL;
wolfSSL_Realloc_cb prevR = NULL;
mp_int a;
mp_int b;
byte val[32];

XMEMSET(val, 0xA5, sizeof(val));
XMEMSET(&a, 0, sizeof(mp_int));
XMEMSET(&b, 0, sizeof(mp_int));
XMEMSET(mp_clear_ptr, 0, sizeof(mp_clear_ptr));
mp_clear_dirty = 0;

ExpectIntEQ(wolfSSL_GetAllocators(&prevM, &prevF, &prevR), 0);
ExpectIntEQ(wolfSSL_SetAllocators(mp_clear_malloc, mp_clear_free,
mp_clear_realloc), 0);

ExpectIntEQ(mp_init(&a), MP_OKAY);
ExpectIntEQ(mp_init(&b), MP_OKAY);
ExpectIntEQ(mp_read_unsigned_bin(&a, val, (word32)sizeof(val)), MP_OKAY);
ExpectIntEQ(mp_read_unsigned_bin(&b, val, (word32)sizeof(val)), MP_OKAY);
/* Grow beyond the current allocation so that a new array is needed. */
ExpectIntEQ(mp_grow(&a, a.alloc + 8), MP_OKAY);

/* The old array must have been wiped, and the value kept. */
ExpectIntEQ(mp_clear_dirty, 0);
ExpectIntEQ(mp_cmp(&a, &b), MP_EQ);

mp_clear(&a);
mp_clear(&b);
(void)wolfSSL_SetAllocators(prevM, prevF, prevR);
#endif
return EXPECT_RESULT();
} /* End test_mp_grow_zeroize */

/*
* Testing wc_export_int
*/
Expand Down
4 changes: 4 additions & 0 deletions tests/api/test_wolfmath.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ int test_mp_get_digit(void);
int test_mp_get_rand_digit(void);
int test_mp_cond_copy(void);
int test_mp_rand(void);
int test_mp_clear_zeroize(void);
int test_mp_grow_zeroize(void);
int test_wc_export_int(void);
int test_wc_SpIntSizeDecisionCoverage(void);
int test_wc_SpIntShiftDecisionCoverage(void);
Expand All @@ -43,6 +45,8 @@ int test_wc_SpIntExptGcdDecisionCoverage(void);
TEST_DECL_GROUP("wolfmath", test_mp_get_rand_digit), \
TEST_DECL_GROUP("wolfmath", test_mp_cond_copy), \
TEST_DECL_GROUP("wolfmath", test_mp_rand), \
TEST_DECL_GROUP("wolfmath", test_mp_clear_zeroize), \
TEST_DECL_GROUP("wolfmath", test_mp_grow_zeroize), \
TEST_DECL_GROUP("wolfmath", test_wc_export_int), \
TEST_DECL_GROUP("wolfmath", test_wc_SpIntSizeDecisionCoverage), \
TEST_DECL_GROUP("wolfmath", test_wc_SpIntShiftDecisionCoverage), \
Expand Down
Loading
Loading