- Add fail-closed wolfSSL small-math policy and vectors - Backport DHCP, EMS, and X.509 allocation fixes - Extend source override validation and operational documentation
77 lines
3.6 KiB
C
77 lines
3.6 KiB
C
/* SPDX-License-Identifier: GPL-3.0-only */
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "mbedtls/x509.h"
|
|
#include "mbedtls/asn1write.h"
|
|
#include "mbedtls/oid.h"
|
|
static unsigned allocations, fail_at, live;
|
|
static void *test_calloc(size_t n, size_t size)
|
|
{
|
|
if (++allocations == fail_at) return NULL;
|
|
void *p = calloc(n, size); assert(p); live++; return p;
|
|
}
|
|
static void test_free(void *p) { if (p) { assert(live); live--; free(p); } }
|
|
#define mbedtls_calloc test_calloc
|
|
#define mbedtls_free test_free
|
|
void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
|
|
{
|
|
while (*head) {
|
|
mbedtls_asn1_named_data *next = (*head)->next;
|
|
test_free((*head)->oid.p); test_free((*head)->val.p); test_free(*head);
|
|
*head = next;
|
|
}
|
|
}
|
|
/* Storage double: preserve the real parser's allocation/copy/free sequence;
|
|
* unrelated repeated-OID replacement behavior is deliberately not modeled. */
|
|
mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(mbedtls_asn1_named_data **head,
|
|
const char *oid, size_t oid_len, const unsigned char *val, size_t val_len)
|
|
{
|
|
mbedtls_asn1_named_data *node = test_calloc(1, sizeof(*node));
|
|
if (!node) return NULL;
|
|
node->oid.p = test_calloc(1, oid_len);
|
|
node->val.p = test_calloc(1, val_len);
|
|
if (!node->oid.p || !node->val.p) {
|
|
test_free(node->oid.p); test_free(node->val.p); test_free(node); return NULL;
|
|
}
|
|
memcpy(node->oid.p, oid, oid_len); node->oid.len = oid_len;
|
|
memcpy(node->val.p, val, val_len); node->val.len = val_len;
|
|
node->next = *head; *head = node; return node;
|
|
}
|
|
int mbedtls_oid_from_numeric_string(mbedtls_asn1_buf *oid, const char *p, size_t n)
|
|
{ assert(!"numeric OID outside this focused test"); return -1; }
|
|
int mbedtls_asn1_get_len(unsigned char **p, const unsigned char *end, size_t *len)
|
|
{ assert(!"hex DER outside this focused test"); return -1; }
|
|
/* SDK_FUNCTIONS */
|
|
int main(void)
|
|
{
|
|
/* Subject and issuer each call this same parser; fail each allocation in
|
|
* their separate lists, then destroy partial lists and retry from scratch. */
|
|
for (unsigned failure = 1; failure <= 8; failure++) {
|
|
mbedtls_asn1_named_data *subject = NULL, *issuer = NULL;
|
|
allocations = 0; fail_at = failure;
|
|
int ret = mbedtls_x509_string_to_names(&subject, "CN=ESP32 SAK ABCDEF");
|
|
if (!ret) ret = mbedtls_x509_string_to_names(&issuer, "CN=ESP32 SAK ABCDEF");
|
|
assert(ret == MBEDTLS_ERR_X509_ALLOC_FAILED);
|
|
mbedtls_asn1_free_named_data_list(&subject);
|
|
mbedtls_asn1_free_named_data_list(&issuer);
|
|
assert(live == 0);
|
|
allocations = 0; fail_at = 0;
|
|
assert(mbedtls_x509_string_to_names(&subject, "CN=ESP32 SAK ABCDEF") == 0);
|
|
assert(mbedtls_x509_string_to_names(&issuer, "CN=ESP32 SAK ABCDEF") == 0);
|
|
assert(subject->val.len == strlen("ESP32 SAK ABCDEF"));
|
|
assert(memcmp(subject->val.p, "ESP32 SAK ABCDEF", subject->val.len) == 0);
|
|
assert(issuer->val.tag == MBEDTLS_ASN1_UTF8_STRING);
|
|
mbedtls_asn1_free_named_data_list(&subject);
|
|
mbedtls_asn1_free_named_data_list(&issuer);
|
|
assert(live == 0);
|
|
}
|
|
mbedtls_asn1_named_data *head = NULL;
|
|
allocations = 0; fail_at = 5; /* Second known-attribute OID, after a live node. */
|
|
assert(mbedtls_x509_string_to_names(&head, "CN=first,O=second") == MBEDTLS_ERR_X509_ALLOC_FAILED);
|
|
assert(head && head->val.len == 5);
|
|
mbedtls_asn1_free_named_data_list(&head); assert(live == 0);
|
|
puts("X509 extracted name parser/helpers: subject/issuer OOM, partial-list cleanup, successful retry PASS");
|
|
}
|