Skip to content

Commit a9acc12

Browse files
committed
asn: reject embedded NUL in dNSName / rfc822Name / URI SAN entries
RFC 5280 4.2.1.6 defines these SAN choices as IA5String; NUL is not a valid IA5String character and its presence is the textbook CVE-2009-2408 attack shape. Previously the parser stored NUL-containing bytes verbatim, which made the name-constraint matcher (length-bounded, byte-exact) accept names that the hostname matcher (NUL-stop) or downstream strcmp-style application code would truncate. Reject at parse time so every downstream consumer sees NUL-free SAN strings.
1 parent a236e27 commit a9acc12

1 file changed

Lines changed: 25 additions & 0 deletions

File tree

wolfcrypt/src/asn.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18008,6 +18008,19 @@ static int DecodeOtherName(DecodedCert* cert, const byte* input,
1800818008
* @return ASN_UNKNOWN_OID_E when the OID cannot be verified.
1800918009
* @return MEMORY_E when dynamic memory allocation fails.
1801018010
*/
18011+
/* Reject IA5String SAN content that cannot legally appear in
18012+
* dNSName / rfc822Name / URI per RFC 5280 4.2.1.6. Currently just NUL. */
18013+
static int DecodeGeneralNameCheckChars(const byte* input, int len)
18014+
{
18015+
int i;
18016+
for (i = 0; i < len; i++) {
18017+
if (input[i] == 0) {
18018+
return ASN_PARSE_E;
18019+
}
18020+
}
18021+
return 0;
18022+
}
18023+
1801118024
static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag,
1801218025
int len, DecodedCert* cert)
1801318026
{
@@ -18016,6 +18029,10 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag,
1801618029

1801718030
/* GeneralName choice: dnsName */
1801818031
if (tag == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
18032+
ret = DecodeGeneralNameCheckChars(input + idx, len);
18033+
if (ret != 0) {
18034+
return ret;
18035+
}
1801918036
ret = SetDNSEntry(cert->heap, (const char*)(input + idx), len,
1802018037
ASN_DNS_TYPE, &cert->altNames);
1802118038
if (ret == 0) {
@@ -18043,6 +18060,10 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag,
1804318060
}
1804418061
/* GeneralName choice: rfc822Name */
1804518062
else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
18063+
ret = DecodeGeneralNameCheckChars(input + idx, len);
18064+
if (ret != 0) {
18065+
return ret;
18066+
}
1804618067
ret = SetDNSEntry(cert->heap, (const char*)(input + idx), len,
1804718068
ASN_RFC822_TYPE, &cert->altEmailNames);
1804818069
if (ret == 0) {
@@ -18051,6 +18072,10 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag,
1805118072
}
1805218073
/* GeneralName choice: uniformResourceIdentifier */
1805318074
else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
18075+
ret = DecodeGeneralNameCheckChars(input + idx, len);
18076+
if (ret != 0) {
18077+
return ret;
18078+
}
1805418079
WOLFSSL_MSG("\tPutting URI into list but not using");
1805518080

1805618081
#if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_FPKI)

0 commit comments

Comments
 (0)