Merge pull request #10638 from rizlik/nc_uri_trailing_dot

NameConstraints fixes
This commit is contained in:
Daniel Pouzzner
2026-07-01 17:14:08 -05:00
committed by GitHub
6 changed files with 369 additions and 122 deletions
+39 -99
View File
@@ -5670,95 +5670,12 @@ static int MatchIpName(const char* name, int nameSz, WOLFSSL_GENERAL_NAME* gn)
constraintData, constraintLen);
}
/* Extract host from URI for name constraint matching.
* URI format: scheme://[userinfo@]host[:port][/path][?query][#fragment]
* IPv6 literals are enclosed in brackets: scheme://[ipv6addr]:port/path
* Returns pointer to host start and sets hostLen, or NULL on failure. */
static const char* ExtractHostFromUri(const char* uri, int uriLen, int* hostLen)
{
const char* hostStart;
const char* hostEnd;
const char* p;
const char* uriEnd;
if (uri == NULL || uriLen <= 0 || hostLen == NULL) {
return NULL;
}
uriEnd = uri + uriLen;
/* Find "://" to skip scheme */
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 NULL;
}
/* Skip userinfo if present (look for @ before any /, ?, #)
* userinfo can contain ':' (ex: user:pass@host), don't stop at ':'
* For IPv6, also don't stop at '[' in userinfo */
for (p = hostStart; p < uriEnd; p++) {
if (*p == '@') {
hostStart = p + 1;
break;
}
if (*p == '/' || *p == '?' || *p == '#') {
/* No userinfo found */
break;
}
/* If '[' before '@', found IPv6 literal, not userinfo */
if (*p == '[') {
break;
}
}
if (hostStart >= uriEnd) {
return NULL;
}
/* Check for IPv6 literal */
if (*hostStart == '[') {
/* Find closing bracket, skip opening one */
hostStart++;
hostEnd = hostStart;
while (hostEnd < uriEnd && *hostEnd != ']') {
hostEnd++;
}
if (hostEnd >= uriEnd) {
/* No closing bracket found, malformed */
return NULL;
}
/* hostEnd points to closing bracket, extract content between */
*hostLen = (int)(hostEnd - hostStart);
if (*hostLen <= 0) {
return NULL;
}
return hostStart;
}
/* Regular hostname, find end */
hostEnd = hostStart;
while (hostEnd < uriEnd && *hostEnd != ':' && *hostEnd != '/' &&
*hostEnd != '?' && *hostEnd != '#') {
hostEnd++;
}
*hostLen = (int)(hostEnd - hostStart);
if (*hostLen <= 0) {
return NULL;
}
return hostStart;
}
/* Helper to check if name string matches a single GENERAL_NAME constraint.
* permitted selects subtree semantics for wildcard DNS names: containment
* for permitted subtrees, intersection for excluded subtrees.
* Returns 1 if matches, 0 if not. */
static int MatchNameConstraint(int type, const char* name, int nameSz,
WOLFSSL_GENERAL_NAME* gn)
WOLFSSL_GENERAL_NAME* gn, int permitted)
{
const char* baseStr;
int baseLen;
@@ -5788,21 +5705,13 @@ static int MatchNameConstraint(int type, const char* name, int nameSz,
nameSz, baseStr, baseLen);
}
else if (type == WOLFSSL_GEN_URI) {
const char* host;
int hostLen;
/* For URI, extract host and match against DNS-style */
host = ExtractHostFromUri(name, nameSz, &hostLen);
if (host == NULL) {
return 0;
}
return wolfssl_local_MatchBaseName(ASN_DNS_TYPE, host, hostLen,
return wolfssl_local_MatchUriNameConstraint(name, nameSz,
baseStr, baseLen);
}
else {
/* WOLFSSL_GEN_DNS uses DNS-style matching */
return wolfssl_local_MatchBaseName(ASN_DNS_TYPE, name, nameSz,
baseStr, baseLen);
return wolfssl_local_MatchDnsNameConstraint(name, nameSz,
baseStr, baseLen, permitted);
}
default:
@@ -5811,6 +5720,29 @@ static int MatchNameConstraint(int type, const char* name, int nameSz,
}
}
static int NameConstraintsHasType(const WOLFSSL_STACK* sk, int type)
{
int i;
int num;
if (sk == NULL) {
return 0;
}
num = wolfSSL_sk_GENERAL_SUBTREE_num(sk);
for (i = 0; i < num; i++) {
WOLFSSL_GENERAL_SUBTREE* subtree;
subtree = wolfSSL_sk_GENERAL_SUBTREE_value(sk, i);
if (subtree != NULL && subtree->base != NULL &&
subtree->base->type == type) {
return 1;
}
}
return 0;
}
/*
* Check if a name string satisfies given name constraints.
*
@@ -5841,6 +5773,14 @@ int wolfSSL_NAME_CONSTRAINTS_check_name(WOLFSSL_NAME_CONSTRAINTS* nc,
return 0;
}
if (type == WOLFSSL_GEN_URI &&
(NameConstraintsHasType(nc->permittedSubtrees, type) ||
NameConstraintsHasType(nc->excludedSubtrees, type)) &&
!wolfssl_local_UriNameHasDnsHost(name, nameSz)) {
WOLFSSL_MSG("URI name constraint applied to URI without DNS host");
return 0;
}
/* Check permitted subtrees */
if (nc->permittedSubtrees != NULL) {
num = wolfSSL_sk_GENERAL_SUBTREE_num(nc->permittedSubtrees);
@@ -5857,7 +5797,7 @@ int wolfSSL_NAME_CONSTRAINTS_check_name(WOLFSSL_NAME_CONSTRAINTS* nc,
}
hasPermittedType = 1;
if (MatchNameConstraint(type, name, nameSz, gn)) {
if (MatchNameConstraint(type, name, nameSz, gn, 1)) {
matchedPermitted = 1;
break;
}
@@ -5884,7 +5824,7 @@ int wolfSSL_NAME_CONSTRAINTS_check_name(WOLFSSL_NAME_CONSTRAINTS* nc,
continue;
}
if (MatchNameConstraint(type, name, nameSz, gn)) {
if (MatchNameConstraint(type, name, nameSz, gn, 0)) {
WOLFSSL_MSG("Name in excluded subtrees");
return 0;
}
+40
View File
@@ -23304,6 +23304,46 @@ static int test_NameConstraints_DnsUriWildcard(void)
sanSz = build_simple_san(san, sizeof(san), URI, "https://www.host.com/");
ExpectIntGT((int)sanSz, 0);
ExpectIntEQ(verify_with_otherName_chain(nc, ncSz, 1, san, sanSz), 0);
/* (11) RFC 5280 requires a DNS host when URI constraints are applied.
* Fail closed even for excluded-only constraints where a boolean
* non-match would otherwise pass. */
ncSz = build_simple_nameConstraints(nc, sizeof(nc), 1, URI,
"blocked.com");
sanSz = build_simple_san(san, sizeof(san), URI, "https://12.31.2.3/");
ExpectIntGT((int)ncSz, 0);
ExpectIntGT((int)sanSz, 0);
ExpectIntEQ(verify_with_otherName_chain(nc, ncSz, 1, san, sanSz),
WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));
sanSz = build_simple_san(san, sizeof(san), URI, "https://[v1.addr.]/");
ExpectIntGT((int)sanSz, 0);
ExpectIntEQ(verify_with_otherName_chain(nc, ncSz, 1, san, sanSz),
WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));
/* An IPv4address host with the absolute-FQDN trailing dot is still not
* a DNS host. */
sanSz = build_simple_san(san, sizeof(san), URI, "https://12.31.2.3./");
ExpectIntGT((int)sanSz, 0);
ExpectIntEQ(verify_with_otherName_chain(nc, ncSz, 1, san, sanSz),
WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));
/* (12) One trailing dot on the constraint base is the absolute-FQDN
* marker: DNS:example.com. denotes the same subtree as
* DNS:example.com, so the permitted form accepts the bare SAN and
* the excluded form rejects it. */
ncSz = build_simple_nameConstraints(nc, sizeof(nc), 0, DNS,
"example.com.");
sanSz = build_simple_san(san, sizeof(san), DNS, "example.com");
ExpectIntGT((int)ncSz, 0);
ExpectIntGT((int)sanSz, 0);
ExpectIntEQ(verify_with_otherName_chain(nc, ncSz, 1, san, sanSz), 0);
ncSz = build_simple_nameConstraints(nc, sizeof(nc), 1, DNS,
"example.com.");
ExpectIntGT((int)ncSz, 0);
ExpectIntEQ(verify_with_otherName_chain(nc, ncSz, 1, san, sanSz),
WC_NO_ERR_TRACE(ASN_NAME_INVALID_E));
#endif
return EXPECT_RESULT();
}
+25 -2
View File
@@ -1153,6 +1153,21 @@ int test_wolfssl_local_MatchUriNameConstraint(void)
ExpectIntEQ(uriNC("https://host.com.evil.com", "host.com"), 0);
ExpectIntEQ(uriNC("https://other.com", "host.com"), 0);
/* A single trailing dot is the absolute-FQDN marker: "host.com." and
* "host.com" denote the same host and must compare equal, matching the
* DNS name-constraint path. */
ExpectIntEQ(uriNC("https://host.com./", "host.com"), 1);
ExpectIntEQ(uriNC("https://host.com.:8443/x", "host.com"), 1);
ExpectIntEQ(uriNC("https://host.com", "host.com."), 1);
ExpectIntEQ(uriNC("https://host.com./", "host.com."), 1);
ExpectIntEQ(uriNC("https://v1.addr./", "v1.addr"), 1);
ExpectIntEQ(uriNC("https://v1.addr/", "v1.addr."), 1);
/* Only ONE trailing dot is the marker; an empty last label is not. */
ExpectIntEQ(uriNC("https://host.com../", "host.com"), 0);
ExpectIntEQ(uriNC("https://a.host.com../", ".host.com"), 0);
/* Empty interior labels are not valid DNS host labels. */
ExpectIntEQ(uriNC("https://a..host.com/", ".host.com"), 0);
/*
* Leading-dot constraint: proper subtree of hosts (apex excluded).
*/
@@ -1164,10 +1179,18 @@ int test_wolfssl_local_MatchUriNameConstraint(void)
ExpectIntEQ(uriNC("https://evilhost.com", ".host.com"), 0);
/*
* IPv6 literal host extraction ([..]) then exact match.
* RFC 5280 URI constraints require a DNS host. IP-literals / IPvFuture
* hosts in brackets and IPv4address hosts are not DNS reg-names.
*/
ExpectIntEQ(uriNC("https://[2001:db8::1]:443/x", "2001:db8::1"), 1);
ExpectIntEQ(uriNC("https://[2001:db8::1]:443/x", "2001:db8::1"), 0);
ExpectIntEQ(uriNC("https://[2001:db8::1]", "2001:db8::2"), 0);
ExpectIntEQ(uriNC("https://[v1.addr.]/", "v1.addr"), 0);
ExpectIntEQ(uriNC("https://[v1.addr.]/", "v1.addr."), 0);
ExpectIntEQ(uriNC("https://12.31.2.3/", "12.31.2.3"), 0);
/* An IPv4address host is still not a DNS reg-name when written with the
* absolute-FQDN trailing dot. */
ExpectIntEQ(uriNC("https://12.31.2.3./", "12.31.2.3"), 0);
ExpectIntEQ(uriNC("https://12.31.2.3./", "12.31.2.3."), 0);
/*
* Malformed / degenerate URIs and inputs (reject).
+67 -2
View File
@@ -2039,8 +2039,8 @@ int test_wolfSSL_NAME_CONSTRAINTS_uri(void)
ExpectIntEQ(wolfSSL_NAME_CONSTRAINTS_check_name(nc, GEN_URI,
"https://user:pass@www.wolfssl.com/path", 38), 1);
/* IPv6 literal URIs, host extracted without brackets.
* These don't match .wolfssl.com constraint (different host type) */
/* URI constraints require a DNS reg-name host, so IP-literals do not
* match the .wolfssl.com constraint. */
ExpectIntEQ(wolfSSL_NAME_CONSTRAINTS_check_name(nc, GEN_URI,
"https://[::1]:8080/path", 23), 0);
ExpectIntEQ(wolfSSL_NAME_CONSTRAINTS_check_name(nc, GEN_URI,
@@ -2243,6 +2243,71 @@ int test_wolfSSL_NAME_CONSTRAINTS_check_name(void)
x509 = NULL;
nc = NULL;
/* Wildcard names against an excluded DNS subtree. Build the constraints
* programmatically: excluded;DNS:foo.example.com */
ExpectNotNull(nc = wolfSSL_NAME_CONSTRAINTS_new());
if (EXPECT_SUCCESS()) {
GENERAL_SUBTREE* subtree = NULL;
ExpectNotNull(nc->excludedSubtrees = wolfSSL_sk_new_null());
if (EXPECT_SUCCESS()) {
nc->excludedSubtrees->type = STACK_TYPE_GENERAL_SUBTREE;
}
ExpectNotNull(subtree = wolfSSL_GENERAL_SUBTREE_new());
if (EXPECT_SUCCESS()) {
ExpectNotNull(subtree->base = wolfSSL_GENERAL_NAME_new());
}
if (EXPECT_SUCCESS()) {
subtree->base->type = GEN_DNS;
ExpectIntEQ(wolfSSL_ASN1_STRING_set(subtree->base->d.ia5,
"foo.example.com", 15), WOLFSSL_SUCCESS);
}
if (EXPECT_SUCCESS()) {
ExpectIntGT(wolfSSL_sk_push(nc->excludedSubtrees, subtree), 0);
}
if (EXPECT_FAIL()) {
wolfSSL_GENERAL_SUBTREE_free(subtree);
}
}
if (EXPECT_SUCCESS()) {
/* Literal names inside the excluded subtree are rejected. */
ExpectIntEQ(wolfSSL_NAME_CONSTRAINTS_check_name(nc, GEN_DNS,
"foo.example.com", 15), 0);
ExpectIntEQ(wolfSSL_NAME_CONSTRAINTS_check_name(nc, GEN_DNS,
"a.foo.example.com", 17), 0);
/* Names outside the subtree pass; there are no permitted subtrees. */
ExpectIntEQ(wolfSSL_NAME_CONSTRAINTS_check_name(nc, GEN_DNS,
"bar.example.com", 15), 1);
ExpectIntEQ(wolfSSL_NAME_CONSTRAINTS_check_name(nc, GEN_DNS,
"*.other.com", 11), 1);
/* A wildcard's '*' can expand to "foo", so "*.example.com" covers
* the excluded "foo.example.com" and must be rejected. */
ExpectIntEQ(wolfSSL_NAME_CONSTRAINTS_check_name(nc, GEN_DNS,
"*.example.com", 13), 0);
}
if (EXPECT_SUCCESS()) {
/* One trailing dot on the base is the absolute-FQDN marker:
* excluded;DNS:foo.example.com. covers the same subtree, so the
* bare name is still rejected. */
GENERAL_SUBTREE* subtree = NULL;
ExpectNotNull(subtree =
wolfSSL_sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, 0));
if (EXPECT_SUCCESS()) {
ExpectIntEQ(wolfSSL_ASN1_STRING_set(subtree->base->d.ia5,
"foo.example.com.", 16), WOLFSSL_SUCCESS);
}
ExpectIntEQ(wolfSSL_NAME_CONSTRAINTS_check_name(nc, GEN_DNS,
"foo.example.com", 15), 0);
ExpectIntEQ(wolfSSL_NAME_CONSTRAINTS_check_name(nc, GEN_DNS,
"bar.example.com", 15), 1);
}
NAME_CONSTRAINTS_free(nc);
nc = NULL;
/* Test IP address constraint checking with cert-ext-ncip.pem
* This cert has permitted IP 192.168.1.0/255.255.255.0 */
if ((f = XFOPEN("./certs/test/cert-ext-ncip.pem", "rb")) == XBADFILE) {
+193 -19
View File
@@ -18121,19 +18121,92 @@ int wolfssl_local_MatchBaseName(int type, const char* name, int nameSz,
return 1;
}
int wolfssl_local_MatchUriNameConstraint(const char* uri, int uriSz,
const char* base, int baseSz)
/* RFC 3986 host classification for URI name-constraint checks. */
typedef enum UriHostType {
URI_HOST_REG_NAME = 0,
URI_HOST_IP_LITERAL,
URI_HOST_IPV4
} UriHostType;
static int UriHostIsDecOctet(const char* s, int sSz)
{
int i;
int val = 0;
if (s == NULL || sSz <= 0 || sSz > 3) {
return 0;
}
if (sSz > 1 && s[0] == '0') {
return 0;
}
for (i = 0; i < sSz; i++) {
if (s[i] < '0' || s[i] > '9') {
return 0;
}
val = (val * 10) + (s[i] - '0');
}
return val <= 255;
}
static int UriHostIsIpv4Address(const char* host, int hostSz)
{
int i;
int partStart = 0;
int partCount = 0;
if (host == NULL || hostSz <= 0) {
return 0;
}
for (i = 0; i <= hostSz; i++) {
if (i == hostSz || host[i] == '.') {
if (!UriHostIsDecOctet(host + partStart, i - partStart)) {
return 0;
}
partCount++;
partStart = i + 1;
}
else if (host[i] < '0' || host[i] > '9') {
return 0;
}
}
return partCount == 4;
}
static int UriRegNameHasNonEmptyLabels(const char* host, int hostSz)
{
int i;
if (host == NULL || hostSz <= 0 || host[0] == '.' ||
host[hostSz - 1] == '.') {
return 0;
}
for (i = 1; i < hostSz; i++) {
if (host[i] == '.' && host[i - 1] == '.') {
return 0;
}
}
return 1;
}
static int GetUriHost(const char* uri, int uriSz, const char** host,
int* hostSz, UriHostType* hostType)
{
const char* hostStart;
const char* hostEnd;
const char* p;
const char* uriEnd;
int hostSz;
/* Need at least 3 bytes for the "://" scheme separator; rejecting short
* inputs early also keeps the loop bound (uriEnd - 2) from forming a
* pointer before `uri`. */
if (uri == NULL || uriSz < 3 || base == NULL || baseSz <= 0) {
if (uri == NULL || uriSz < 3 || host == NULL || hostSz == NULL ||
hostType == NULL) {
return 0;
}
@@ -18174,7 +18247,8 @@ int wolfssl_local_MatchUriNameConstraint(const char* uri, int uriSz,
if (hostEnd >= uriEnd) {
return 0;
}
hostSz = (int)(hostEnd - hostStart);
*hostSz = (int)(hostEnd - hostStart);
*hostType = URI_HOST_IP_LITERAL;
}
else {
hostEnd = hostStart;
@@ -18182,10 +18256,63 @@ int wolfssl_local_MatchUriNameConstraint(const char* uri, int uriSz,
*hostEnd != '?' && *hostEnd != '#') {
hostEnd++;
}
hostSz = (int)(hostEnd - hostStart);
*hostSz = (int)(hostEnd - hostStart);
/* One trailing dot is the absolute-FQDN marker and not part of the
* host: strip it before classifying so that "12.31.2.3." is
* recognized as an IPv4 address and "host.com." denotes the same
* reg-name as "host.com". */
if (*hostSz > 0 && hostStart[*hostSz - 1] == '.') {
(*hostSz)--;
if (*hostSz <= 0 || hostStart[*hostSz - 1] == '.') {
return 0;
}
}
*hostType = UriHostIsIpv4Address(hostStart, *hostSz) ?
URI_HOST_IPV4 : URI_HOST_REG_NAME;
if (*hostType == URI_HOST_REG_NAME &&
!UriRegNameHasNonEmptyLabels(hostStart, *hostSz)) {
return 0;
}
}
if (hostSz <= 0) {
if (*hostSz <= 0) {
return 0;
}
*host = hostStart;
return 1;
}
int wolfssl_local_UriNameHasDnsHost(const char* uri, int uriSz)
{
const char* host = NULL;
int hostSz = 0;
UriHostType hostType = URI_HOST_REG_NAME;
if (!GetUriHost(uri, uriSz, &host, &hostSz, &hostType)) {
return 0;
}
(void)host;
(void)hostSz;
return hostType == URI_HOST_REG_NAME;
}
int wolfssl_local_MatchUriNameConstraint(const char* uri, int uriSz,
const char* base, int baseSz)
{
const char* hostStart = NULL;
int hostSz = 0;
UriHostType hostType = URI_HOST_REG_NAME;
if (base == NULL || baseSz <= 0 ||
!GetUriHost(uri, uriSz, &hostStart, &hostSz, &hostType)) {
return 0;
}
/* RFC 5280 URI constraints apply only to host names specified as fully
* qualified domain names. RFC 3986 IP-literals and IPv4address hosts are
* not DNS reg-names. */
if (hostType != URI_HOST_REG_NAME) {
return 0;
}
@@ -18200,6 +18327,15 @@ int wolfssl_local_MatchUriNameConstraint(const char* uri, int uriSz,
}
else {
int i;
/* GetUriHost already stripped the host's absolute-FQDN trailing dot;
* treat one trailing dot on the base the same way so that "host.com."
* and "host.com" compare equal. */
if (base[baseSz - 1] == '.') {
baseSz--;
}
if (baseSz <= 0) {
return 0;
}
if (hostSz != baseSz) {
return 0;
}
@@ -18415,6 +18551,23 @@ static int DnsNameHasWildcard(const char* name, int nameSz)
return 0;
}
/* Match a DNS name against a DNS name-constraint base. A wildcard name
* denotes a set of names: permitted subtrees require containment, excluded
* subtrees intersection (selected by `permitted`). Literal names use plain
* base-name matching, which normalizes the absolute-FQDN trailing dot
* before its own length check.
* Returns 1 on match, 0 otherwise. */
int wolfssl_local_MatchDnsNameConstraint(const char* name, int nameSz,
const char* base, int baseSz, int permitted)
{
if (DnsNameHasWildcard(name, nameSz)) {
return wolfssl_local_MatchDnsConstraintWildcard(name, nameSz,
base, baseSz, permitted);
}
return wolfssl_local_MatchBaseName(ASN_DNS_TYPE, name, nameSz, base,
baseSz);
}
/* Search through the list to find if the name is permitted.
* name The DNS name to search for
* dnsList The list to search through
@@ -18465,12 +18618,10 @@ static int PermittedListOk(DNS_entry* name, Base_entry* dnsList, byte nameType)
break;
}
}
else if (nameType == ASN_DNS_TYPE &&
DnsNameHasWildcard(name->name, name->len)) {
/* Wildcard DNS SAN: a '*' can expand to a longer label, so the
* byte-length guard used for literal names below is invalid.
* Permit only if every expansion stays inside the subtree. */
if (wolfssl_local_MatchDnsConstraintWildcard(name->name,
else if (nameType == ASN_DNS_TYPE) {
/* Permit only if every expansion of a wildcard stays inside
* the subtree. */
if (wolfssl_local_MatchDnsNameConstraint(name->name,
name->len, current->name, current->nameSz, 1)) {
match = 1;
break;
@@ -18539,12 +18690,10 @@ static int IsInExcludedList(DNS_entry* name, Base_entry* dnsList, byte nameType)
break;
}
}
else if (nameType == ASN_DNS_TYPE &&
DnsNameHasWildcard(name->name, name->len)) {
/* Wildcard DNS SAN: a '*' can expand to a longer label, so the
* byte-length guard used for literal names below is invalid.
* Exclude if any expansion can fall inside the subtree. */
if (wolfssl_local_MatchDnsConstraintWildcard(name->name,
else if (nameType == ASN_DNS_TYPE) {
/* Exclude if any expansion of a wildcard can fall inside the
* subtree. */
if (wolfssl_local_MatchDnsNameConstraint(name->name,
name->len, current->name, current->nameSz, 0)) {
ret = 1;
break;
@@ -18564,12 +18713,25 @@ static int IsInExcludedList(DNS_entry* name, Base_entry* dnsList, byte nameType)
}
static int NameConstraintListHasType(Base_entry* list, byte nameType)
{
while (list != NULL) {
if (list->type == nameType) {
return 1;
}
list = list->next;
}
return 0;
}
static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
{
const byte nameTypes[] = {ASN_RFC822_TYPE, ASN_DNS_TYPE, ASN_DIR_TYPE,
ASN_IP_TYPE, ASN_URI_TYPE, ASN_OTHER_TYPE,
ASN_RID_TYPE};
int i;
int uriConstraintsApply;
if (signer == NULL || cert == NULL)
return 0;
@@ -18578,6 +18740,10 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
!signer->extNameConstraintHasUnsupported)
return 1;
uriConstraintsApply =
NameConstraintListHasType(signer->excludedNames, ASN_URI_TYPE) ||
NameConstraintListHasType(signer->permittedNames, ASN_URI_TYPE);
for (i=0; i < (int)sizeof(nameTypes); i++) {
byte nameType = nameTypes[i];
DNS_entry* name = NULL;
@@ -18660,6 +18826,14 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
while (name != NULL) {
/* Only check entries that match the current nameType. */
if (name->type == nameType) {
if (nameType == ASN_URI_TYPE && uriConstraintsApply &&
!wolfssl_local_UriNameHasDnsHost(name->name,
name->len)) {
WOLFSSL_MSG("URI name constraint applied to URI without "
"DNS host");
return 0;
}
if (IsInExcludedList(name, signer->excludedNames,
nameType) == 1) {
WOLFSSL_MSG("Excluded name was found!");
+5
View File
@@ -3222,10 +3222,15 @@ WOLFSSL_TEST_VIS int wolfssl_local_MatchIpSubnet(const byte* ip, int ipSz,
WOLFSSL_TEST_VIS int wolfssl_local_MatchUriNameConstraint(const char* uri,
int uriSz, const char* base,
int baseSz);
WOLFSSL_LOCAL int wolfssl_local_UriNameHasDnsHost(const char* uri,
int uriSz);
WOLFSSL_TEST_VIS int wolfssl_local_MatchDnsConstraintWildcard(
const char* name, int nameSz,
const char* base, int baseSz,
int permitted);
WOLFSSL_LOCAL int wolfssl_local_MatchDnsNameConstraint(const char* name,
int nameSz, const char* base,
int baseSz, int permitted);
#endif
#if ((defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)) \