From ce74def87775dbcf5e221f0361b43d0746ea5710 Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Mon, 23 Mar 2026 14:00:39 -0400 Subject: [PATCH] Enforce URI name constraints in ConfirmNameConstraints --- wolfcrypt/src/asn.c | 88 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 6d275d9875e..4a2f4e5d0fc 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -19956,6 +19956,75 @@ int wolfssl_local_MatchBaseName(int type, const char* name, int nameSz, return 1; } +static int MatchUriNameConstraint(const char* uri, int uriSz, const char* base, + int baseSz) +{ + const char* hostStart; + const char* hostEnd; + const char* p; + const char* uriEnd; + int hostSz; + + if (uri == NULL || uriSz <= 0 || base == NULL || baseSz <= 0) { + return 0; + } + + uriEnd = uri + uriSz; + hostStart = NULL; + for (p = uri; p < uriEnd - 2; p++) { + if (p[0] == ':' && p[1] == '/' && p[2] == '/') { + hostStart = p + 3; + break; + } + } + if (hostStart == NULL || hostStart >= uriEnd) { + return 0; + } + + for (p = hostStart; p < uriEnd; p++) { + if (*p == '@') { + hostStart = p + 1; + break; + } + if (*p == '/' || *p == '?' || *p == '#') { + break; + } + if (*p == '[') { + break; + } + } + if (hostStart >= uriEnd) { + return 0; + } + + if (*hostStart == '[') { + hostStart++; + hostEnd = hostStart; + while (hostEnd < uriEnd && *hostEnd != ']') { + hostEnd++; + } + if (hostEnd >= uriEnd) { + return 0; + } + hostSz = (int)(hostEnd - hostStart); + } + else { + hostEnd = hostStart; + while (hostEnd < uriEnd && *hostEnd != ':' && *hostEnd != '/' && + *hostEnd != '?' && *hostEnd != '#') { + hostEnd++; + } + hostSz = (int)(hostEnd - hostStart); + } + + if (hostSz <= 0) { + return 0; + } + + return wolfssl_local_MatchBaseName(ASN_DNS_TYPE, hostStart, hostSz, base, + baseSz); +} + /* Check if IP address matches a name constraint. * IP name constraints contain IP address and subnet mask. * IPv4: ip is 4 bytes, constraint is 8 bytes (4 IP + 4 mask) @@ -20019,6 +20088,13 @@ static int PermittedListOk(DNS_entry* name, Base_entry* dnsList, byte nameType) break; } } + else if (nameType == ASN_URI_TYPE) { + if (MatchUriNameConstraint(name->name, name->len, + current->name, current->nameSz)) { + match = 1; + break; + } + } else if (name->len >= current->nameSz && wolfssl_local_MatchBaseName(nameType, name->name, name->len, current->name, current->nameSz)) { @@ -20059,6 +20135,13 @@ static int IsInExcludedList(DNS_entry* name, Base_entry* dnsList, byte nameType) break; } } + else if (nameType == ASN_URI_TYPE) { + if (MatchUriNameConstraint(name->name, name->len, + current->name, current->nameSz)) { + ret = 1; + break; + } + } else if (name->len >= current->nameSz && wolfssl_local_MatchBaseName(nameType, name->name, name->len, current->name, current->nameSz)) { @@ -20076,7 +20159,7 @@ static int IsInExcludedList(DNS_entry* name, Base_entry* dnsList, byte nameType) static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert) { const byte nameTypes[] = {ASN_RFC822_TYPE, ASN_DNS_TYPE, ASN_DIR_TYPE, - ASN_IP_TYPE}; + ASN_IP_TYPE, ASN_URI_TYPE}; int i; if (signer == NULL || cert == NULL) @@ -20137,6 +20220,9 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert) subjectDnsName.name = (char *)cert->subjectRaw; } break; + case ASN_URI_TYPE: + name = cert->altNames; + break; default: /* Other types of names are ignored for now. * Shouldn't it be rejected if it there is a altNamesByType[nameType]