Merge pull request #9678 from cconlon/otherNameSan

Fix GENERAL_NAME memory management for otherName and RID SANs
This commit is contained in:
David Garske
2026-01-20 10:56:37 -08:00
committed by GitHub
2 changed files with 172 additions and 17 deletions

View File

@@ -571,7 +571,6 @@ static int wolfssl_dns_entry_othername_to_gn(DNS_entry* dns,
tag = WOLFSSL_V_ASN1_SEQUENCE;
}
/* Create a WOLFSSL_ASN1_STRING from the DER. */
str = wolfSSL_ASN1_STRING_type_new(tag);
if (str == NULL) {
@@ -584,15 +583,23 @@ static int wolfssl_dns_entry_othername_to_gn(DNS_entry* dns,
if (type == NULL)
goto err;
wolfSSL_ASN1_TYPE_set(type, tag, str);
str = NULL; /* type now owns str */
if (wolfSSL_GENERAL_NAME_set_type(gn, WOLFSSL_GEN_OTHERNAME)
!= WOLFSSL_SUCCESS) {
goto err;
}
/* Store the object and string in general name. */
gn->d.otherName->type_id = obj;
gn->d.otherName->value = type;
type = NULL; /* gn->d.otherName owns type */
ret = 1;
err:
if (ret != 1) {
wolfSSL_ASN1_OBJECT_free(obj);
wolfSSL_ASN1_TYPE_free(type);
wolfSSL_ASN1_STRING_free(str);
}
return ret;
@@ -602,13 +609,13 @@ err:
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
static int DNS_to_GENERAL_NAME(WOLFSSL_GENERAL_NAME* gn, DNS_entry* dns)
{
gn->type = dns->type;
switch (gn->type) {
switch (dns->type) {
case WOLFSSL_GEN_OTHERNAME:
if (!wolfssl_dns_entry_othername_to_gn(dns, gn)) {
WOLFSSL_MSG("OTHERNAME set failed");
return WOLFSSL_FAILURE;
}
/* Sets gn->type internally */
if (!wolfssl_dns_entry_othername_to_gn(dns, gn)) {
WOLFSSL_MSG("OTHERNAME set failed");
return WOLFSSL_FAILURE;
}
break;
case WOLFSSL_GEN_EMAIL:
@@ -616,16 +623,18 @@ static int DNS_to_GENERAL_NAME(WOLFSSL_GENERAL_NAME* gn, DNS_entry* dns)
case WOLFSSL_GEN_URI:
case WOLFSSL_GEN_IPADD:
case WOLFSSL_GEN_IA5:
gn->d.ia5->length = dns->len;
if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name,
gn->d.ia5->length) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ASN1_STRING_set failed");
return WOLFSSL_FAILURE;
}
break;
gn->type = dns->type;
gn->d.ia5->length = dns->len;
if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name,
gn->d.ia5->length) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ASN1_STRING_set failed");
return WOLFSSL_FAILURE;
}
break;
case WOLFSSL_GEN_DIRNAME:
gn->type = dns->type;
/* wolfSSL_GENERAL_NAME_new() mallocs this by default */
wolfSSL_ASN1_STRING_free(gn->d.ia5);
gn->d.ia5 = NULL;
@@ -636,6 +645,7 @@ static int DNS_to_GENERAL_NAME(WOLFSSL_GENERAL_NAME* gn, DNS_entry* dns)
#ifdef WOLFSSL_RID_ALT_NAME
case WOLFSSL_GEN_RID:
gn->type = dns->type;
/* wolfSSL_GENERAL_NAME_new() mallocs this by default */
wolfSSL_ASN1_STRING_free(gn->d.ia5);
gn->d.ia5 = NULL;
@@ -2310,9 +2320,9 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
goto err;
}
gn->type = dns->type;
switch (gn->type) {
switch (dns->type) {
case ASN_DIR_TYPE:
gn->type = dns->type;
{
int localIdx = 0;
unsigned char* n = (unsigned char*)XMALLOC(
@@ -2336,12 +2346,14 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
break;
case ASN_OTHER_TYPE:
/* gn->type set internally */
if (!wolfssl_dns_entry_othername_to_gn(dns, gn)) {
goto err;
}
break;
case ASN_IP_TYPE:
gn->type = dns->type;
if (wolfSSL_ASN1_STRING_set(gn->d.iPAddress,
dns->name, dns->len) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ASN1_STRING_set failed");
@@ -2350,7 +2362,35 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
gn->d.iPAddress->type = WOLFSSL_V_ASN1_OCTET_STRING;
break;
#ifdef WOLFSSL_RID_ALT_NAME
case ASN_RID_TYPE:
gn->type = dns->type;
/* Free ia5 before using union for registeredID */
wolfSSL_ASN1_STRING_free(gn->d.ia5);
gn->d.ia5 = NULL;
gn->d.registeredID = wolfSSL_ASN1_OBJECT_new();
if (gn->d.registeredID == NULL) {
goto err;
}
gn->d.registeredID->obj =
(const unsigned char*)XMALLOC(dns->len,
gn->d.registeredID->heap, DYNAMIC_TYPE_ASN1);
if (gn->d.registeredID->obj == NULL) {
goto err;
}
gn->d.registeredID->dynamic |=
WOLFSSL_ASN1_DYNAMIC_DATA;
XMEMCPY((byte*)gn->d.registeredID->obj,
dns->ridString, dns->len);
gn->d.registeredID->objSz = dns->len;
gn->d.registeredID->grp = oidCertExtType;
gn->d.registeredID->nid = WC_NID_registeredAddress;
break;
#endif /* WOLFSSL_RID_ALT_NAME */
default:
gn->type = dns->type;
if (wolfSSL_ASN1_STRING_set(gn->d.dNSName,
dns->name, dns->len) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ASN1_STRING_set failed");
@@ -4643,7 +4683,12 @@ int wolfSSL_GENERAL_NAME_set0_othername(WOLFSSL_GENERAL_NAME* gen,
return WOLFSSL_FAILURE;
}
gen->type = WOLFSSL_GEN_OTHERNAME;
if (wolfSSL_GENERAL_NAME_set_type(gen, WOLFSSL_GEN_OTHERNAME)
!= WOLFSSL_SUCCESS) {
wolfSSL_ASN1_OBJECT_free(x);
return WOLFSSL_FAILURE;
}
gen->d.otherName->type_id = x;
gen->d.otherName->value = value;
return WOLFSSL_SUCCESS;
@@ -4975,6 +5020,16 @@ int wolfSSL_GENERAL_NAME_set_type(WOLFSSL_GENERAL_NAME* name, int typ)
if (name->d.uniformResourceIdentifier == NULL)
ret = MEMORY_E;
break;
case WOLFSSL_GEN_OTHERNAME:
name->d.otherName = (WOLFSSL_ASN1_OTHERNAME*)XMALLOC(
sizeof(WOLFSSL_ASN1_OTHERNAME), NULL, DYNAMIC_TYPE_ASN1);
if (name->d.otherName == NULL) {
ret = MEMORY_E;
}
else {
XMEMSET(name->d.otherName, 0, sizeof(WOLFSSL_ASN1_OTHERNAME));
}
break;
default:
name->type = WOLFSSL_GEN_IA5;
name->d.ia5 = wolfSSL_ASN1_STRING_new();