@@ -5666,91 +5666,6 @@ static int MatchIpName(const char* name, int nameSz, WOLFSSL_GENERAL_NAME* gn)
56665666 constraintData, constraintLen);
56675667}
56685668
5669- /* Extract host from URI for name constraint matching.
5670- * URI format: scheme://[userinfo@]host[:port][/path][?query][#fragment]
5671- * IPv6 literals are enclosed in brackets: scheme://[ipv6addr]:port/path
5672- * Returns pointer to host start and sets hostLen, or NULL on failure. */
5673- static const char* ExtractHostFromUri(const char* uri, int uriLen, int* hostLen)
5674- {
5675- const char* hostStart;
5676- const char* hostEnd;
5677- const char* p;
5678- const char* uriEnd;
5679-
5680- if (uri == NULL || uriLen <= 0 || hostLen == NULL) {
5681- return NULL;
5682- }
5683-
5684- uriEnd = uri + uriLen;
5685-
5686- /* Find "://" to skip scheme */
5687- hostStart = NULL;
5688- for (p = uri; p < uriEnd - 2; p++) {
5689- if (p[0] == ':' && p[1] == '/' && p[2] == '/') {
5690- hostStart = p + 3;
5691- break;
5692- }
5693- }
5694- if (hostStart == NULL || hostStart >= uriEnd) {
5695- return NULL;
5696- }
5697-
5698- /* Skip userinfo if present (look for @ before any /, ?, #)
5699- * userinfo can contain ':' (ex: user:pass@host), don't stop at ':'
5700- * For IPv6, also don't stop at '[' in userinfo */
5701- for (p = hostStart; p < uriEnd; p++) {
5702- if (*p == '@') {
5703- hostStart = p + 1;
5704- break;
5705- }
5706- if (*p == '/' || *p == '?' || *p == '#') {
5707- /* No userinfo found */
5708- break;
5709- }
5710- /* If '[' before '@', found IPv6 literal, not userinfo */
5711- if (*p == '[') {
5712- break;
5713- }
5714- }
5715- if (hostStart >= uriEnd) {
5716- return NULL;
5717- }
5718-
5719- /* Check for IPv6 literal */
5720- if (*hostStart == '[') {
5721- /* Find closing bracket, skip opening one */
5722- hostStart++;
5723- hostEnd = hostStart;
5724- while (hostEnd < uriEnd && *hostEnd != ']') {
5725- hostEnd++;
5726- }
5727- if (hostEnd >= uriEnd) {
5728- /* No closing bracket found, malformed */
5729- return NULL;
5730- }
5731- /* hostEnd points to closing bracket, extract content between */
5732- *hostLen = (int)(hostEnd - hostStart);
5733- if (*hostLen <= 0) {
5734- return NULL;
5735- }
5736- return hostStart;
5737- }
5738-
5739- /* Regular hostname, find end */
5740- hostEnd = hostStart;
5741- while (hostEnd < uriEnd && *hostEnd != ':' && *hostEnd != '/' &&
5742- *hostEnd != '?' && *hostEnd != '#') {
5743- hostEnd++;
5744- }
5745-
5746- *hostLen = (int)(hostEnd - hostStart);
5747- if (*hostLen <= 0) {
5748- return NULL;
5749- }
5750-
5751- return hostStart;
5752- }
5753-
57545669/* Helper to check if name string matches a single GENERAL_NAME constraint.
57555670 * Returns 1 if matches, 0 if not. */
57565671static int MatchNameConstraint(int type, const char* name, int nameSz,
@@ -5784,15 +5699,7 @@ static int MatchNameConstraint(int type, const char* name, int nameSz,
57845699 nameSz, baseStr, baseLen);
57855700 }
57865701 else if (type == WOLFSSL_GEN_URI) {
5787- const char* host;
5788- int hostLen;
5789-
5790- /* For URI, extract host and match against DNS-style */
5791- host = ExtractHostFromUri(name, nameSz, &hostLen);
5792- if (host == NULL) {
5793- return 0;
5794- }
5795- return wolfssl_local_MatchBaseName(ASN_DNS_TYPE, host, hostLen,
5702+ return wolfssl_local_MatchUriNameConstraint(name, nameSz,
57965703 baseStr, baseLen);
57975704 }
57985705 else {
@@ -5807,6 +5714,29 @@ static int MatchNameConstraint(int type, const char* name, int nameSz,
58075714 }
58085715}
58095716
5717+ static int NameConstraintsHasType(const WOLFSSL_STACK* sk, int type)
5718+ {
5719+ int i;
5720+ int num;
5721+
5722+ if (sk == NULL) {
5723+ return 0;
5724+ }
5725+
5726+ num = wolfSSL_sk_GENERAL_SUBTREE_num(sk);
5727+ for (i = 0; i < num; i++) {
5728+ WOLFSSL_GENERAL_SUBTREE* subtree;
5729+
5730+ subtree = wolfSSL_sk_GENERAL_SUBTREE_value(sk, i);
5731+ if (subtree != NULL && subtree->base != NULL &&
5732+ subtree->base->type == type) {
5733+ return 1;
5734+ }
5735+ }
5736+
5737+ return 0;
5738+ }
5739+
58105740/*
58115741 * Check if a name string satisfies given name constraints.
58125742 *
@@ -5837,6 +5767,14 @@ int wolfSSL_NAME_CONSTRAINTS_check_name(WOLFSSL_NAME_CONSTRAINTS* nc,
58375767 return 0;
58385768 }
58395769
5770+ if (type == WOLFSSL_GEN_URI &&
5771+ (NameConstraintsHasType(nc->permittedSubtrees, type) ||
5772+ NameConstraintsHasType(nc->excludedSubtrees, type)) &&
5773+ !wolfssl_local_UriNameHasDnsHost(name, nameSz)) {
5774+ WOLFSSL_MSG("URI name constraint applied to URI without DNS host");
5775+ return 0;
5776+ }
5777+
58405778 /* Check permitted subtrees */
58415779 if (nc->permittedSubtrees != NULL) {
58425780 num = wolfSSL_sk_GENERAL_SUBTREE_num(nc->permittedSubtrees);
0 commit comments