// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "name_constraints.h"

#include <limits.h>

#include <memory>
#include <optional>

#include <openssl/base.h>
#include <openssl/bytestring.h>

#include "cert_errors.h"
#include "common_cert_errors.h"
#include "general_names.h"
#include "input.h"
#include "ip_util.h"
#include "parser.h"
#include "string_util.h"
#include "verify_name_match.h"

BSSL_NAMESPACE_BEGIN

namespace {

// The name types of GeneralName that are fully supported in name constraints.
//
// (The other types will have the minimal checking described by RFC 5280
// section 4.2.1.10: If a name constraints extension that is marked as critical
// imposes constraints on a particular name form, and an instance of
// that name form appears in the subject field or subjectAltName
// extension of a subsequent certificate, then the application MUST
// either process the constraint or reject the certificate.)
const int kSupportedNameTypes =
    GENERAL_NAME_RFC822_NAME | GENERAL_NAME_DNS_NAME |
    GENERAL_NAME_DIRECTORY_NAME | GENERAL_NAME_IP_ADDRESS;

// Controls wildcard handling of DNSNameMatches.
// If WildcardMatchType is WILDCARD_PARTIAL_MATCH "*.bar.com" is considered to
// match the constraint "foo.bar.com". If it is WILDCARD_FULL_MATCH, "*.bar.com"
// will match "bar.com" but not "foo.bar.com".
enum WildcardMatchType { WILDCARD_PARTIAL_MATCH, WILDCARD_FULL_MATCH };

// Returns true if |name| falls in the subtree defined by |dns_constraint|.
// RFC 5280 section 4.2.1.10:
// DNS name restrictions are expressed as host.example.com. Any DNS
// name that can be constructed by simply adding zero or more labels
// to the left-hand side of the name satisfies the name constraint. For
// example, www.host.example.com would satisfy the constraint but
// host1.example.com would not.
//
// |wildcard_matching| controls handling of wildcard names (|name| starts with
// "*."). Wildcard handling is not specified by RFC 5280, but certificate
// verification allows it, name constraints must check it similarly.
bool DNSNameMatches(std::string_view name, std::string_view dns_constraint,
                    WildcardMatchType wildcard_matching) {
  // Everything matches the empty DNS name constraint.
  if (dns_constraint.empty()) {
    return true;
  }

  // Normalize absolute DNS names by removing the trailing dot, if any.
  if (!name.empty() && *name.rbegin() == '.') {
    name.remove_suffix(1);
  }
  if (!dns_constraint.empty() && *dns_constraint.rbegin() == '.') {
    dns_constraint.remove_suffix(1);
  }

  // Wildcard partial-match handling ("*.bar.com" matching name constraint
  // "foo.bar.com"). This only handles the case where the the dnsname and the
  // constraint match after removing the leftmost label, otherwise it is handled
  // by falling through to the check of whether the dnsname is fully within or
  // fully outside of the constraint.
  if (wildcard_matching == WILDCARD_PARTIAL_MATCH && name.size() > 2 &&
      name[0] == '*' && name[1] == '.') {
    size_t dns_constraint_dot_pos = dns_constraint.find('.');
    if (dns_constraint_dot_pos != std::string::npos) {
      std::string_view dns_constraint_domain =
          dns_constraint.substr(dns_constraint_dot_pos + 1);
      std::string_view wildcard_domain = name.substr(2);
      if (bssl::string_util::IsEqualNoCase(wildcard_domain,
                                           dns_constraint_domain)) {
        return true;
      }
    }
  }

  if (!bssl::string_util::EndsWithNoCase(name, dns_constraint)) {
    return false;
  }

  // Exact match.
  if (name.size() == dns_constraint.size()) {
    return true;
  }
  // If dNSName constraint starts with a dot, only subdomains should match.
  // (e.g., "foo.bar.com" matches constraint ".bar.com", but "bar.com" doesn't.)
  // RFC 5280 is ambiguous, but this matches the behavior of other platforms.
  if (!dns_constraint.empty() && dns_constraint[0] == '.') {
    dns_constraint.remove_prefix(1);
  }
  // Subtree match.
  if (name.size() > dns_constraint.size() &&
      name[name.size() - dns_constraint.size() - 1] == '.') {
    return true;
  }
  // Trailing text matches, but not in a subtree (e.g., "foobar.com" is not a
  // match for "bar.com").
  return false;
}

// Parses a GeneralSubtrees |value| and store the contents in |subtrees|.
// The individual values stored into |subtrees| are not validated by this
// function.
// NOTE: |subtrees| is not pre-initialized by the function(it is expected to be
// a default initialized object), and it will be modified regardless of the
// return value.
[[nodiscard]] bool ParseGeneralSubtrees(der::Input value,
                                        GeneralNames *subtrees,
                                        CertErrors *errors) {
  BSSL_CHECK(errors);

  // GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
  //
  // GeneralSubtree ::= SEQUENCE {
  //      base                    GeneralName,
  //      minimum         [0]     BaseDistance DEFAULT 0,
  //      maximum         [1]     BaseDistance OPTIONAL }
  //
  // BaseDistance ::= INTEGER (0..MAX)
  der::Parser sequence_parser(value);
  // The GeneralSubtrees sequence should have at least 1 element.
  if (!sequence_parser.HasMore()) {
    return false;
  }
  while (sequence_parser.HasMore()) {
    der::Parser subtree_sequence;
    if (!sequence_parser.ReadSequence(&subtree_sequence)) {
      return false;
    }

    der::Input raw_general_name;
    if (!subtree_sequence.ReadRawTLV(&raw_general_name)) {
      return false;
    }

    if (!ParseGeneralName(raw_general_name,
                          GeneralNames::IP_ADDRESS_AND_NETMASK, subtrees,
                          errors)) {
      errors->AddError(kFailedParsingGeneralName);
      return false;
    }

    // RFC 5280 section 4.2.1.10:
    // Within this profile, the minimum and maximum fields are not used with any
    // name forms, thus, the minimum MUST be zero, and maximum MUST be absent.
    // However, if an application encounters a critical name constraints
    // extension that specifies other values for minimum or maximum for a name
    // form that appears in a subsequent certificate, the application MUST
    // either process these fields or reject the certificate.

    // Note that technically failing here isn't required: rather only need to
    // fail if a name of this type actually appears in a subsequent cert and
    // this extension was marked critical. However the minimum and maximum
    // fields appear uncommon enough that implementing that isn't useful.
    if (subtree_sequence.HasMore()) {
      return false;
    }
  }
  return true;
}

bool IsAlphaDigit(char c) {
  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
         (c >= 'A' && c <= 'Z');
}

// Returns true if 'local_part' contains only characters that are valid in a
// non-quoted mailbox local-part. Does not check any other part of the syntax
// requirements. Does not allow whitespace.
bool IsAllowedRfc822LocalPart(std::string_view local_part) {
  if (local_part.empty()) {
    return false;
  }
  for (char c : local_part) {
    if (!(IsAlphaDigit(c) || c == '!' || c == '#' || c == '$' || c == '%' ||
          c == '&' || c == '\'' || c == '*' || c == '+' || c == '-' ||
          c == '/' || c == '=' || c == '?' || c == '^' || c == '_' ||
          c == '`' || c == '{' || c == '|' || c == '}' || c == '~' ||
          c == '.')) {
      return false;
    }
  }
  return true;
}

// Returns true if 'domain' contains only characters that are valid in a
// mailbox domain. Does not check any other part of the syntax
// requirements. Does not allow IPv6-address-literal as text IPv6 addresses are
// non-unique. Does not allow other address literals either as how to handle
// them with domain/subdomain matching isn't specified/possible.
bool IsAllowedRfc822Domain(std::string_view domain) {
  if (domain.empty()) {
    return false;
  }
  for (char c : domain) {
    if (!(IsAlphaDigit(c) || c == '-' || c == '.')) {
      return false;
    }
  }
  return true;
}

enum class Rfc822NameMatchType { kPermitted, kExcluded };
bool Rfc822NameMatches(std::string_view local_part, std::string_view domain,
                       std::string_view rfc822_constraint,
                       Rfc822NameMatchType match_type,
                       bool case_insensitive_local_part) {
  // In case of parsing errors, return a value that will cause the name to not
  // be permitted.
  const bool error_value =
      match_type == Rfc822NameMatchType::kPermitted ? false : true;

  std::vector<std::string_view> constraint_components =
      bssl::string_util::SplitString(rfc822_constraint, '@');
  std::string_view constraint_local_part;
  std::string_view constraint_domain;
  if (constraint_components.size() == 1) {
    constraint_domain = constraint_components[0];
  } else if (constraint_components.size() == 2) {
    constraint_local_part = constraint_components[0];
    if (!IsAllowedRfc822LocalPart(constraint_local_part)) {
      return error_value;
    }
    constraint_domain = constraint_components[1];
  } else {
    // If we did the full parsing then it is possible for a @ to be in a quoted
    // local-part of the name, but we don't do that, so just error if @ appears
    // more than once.
    return error_value;
  }
  if (!IsAllowedRfc822Domain(constraint_domain)) {
    return error_value;
  }

  // RFC 5280 section 4.2.1.10:
  // To indicate a particular mailbox, the constraint is the complete mail
  // address.  For example, "root@example.com" indicates the root mailbox on
  // the host "example.com".
  if (!constraint_local_part.empty()) {
    return (case_insensitive_local_part
                ? string_util::IsEqualNoCase(local_part, constraint_local_part)
                : local_part == constraint_local_part) &&
           string_util::IsEqualNoCase(domain, constraint_domain);
  }

  // RFC 5280 section 4.2.1.10:
  // To specify any address within a domain, the constraint is specified with a
  // leading period (as with URIs).  For example, ".example.com" indicates all
  // the Internet mail addresses in the domain "example.com", but not Internet
  // mail addresses on the host "example.com".
  if (!constraint_domain.empty() && constraint_domain[0] == '.') {
    return string_util::EndsWithNoCase(domain, constraint_domain);
  }

  // RFC 5280 section 4.2.1.10:
  // To indicate all Internet mail addresses on a particular host, the
  // constraint is specified as the host name.  For example, the constraint
  // "example.com" is satisfied by any mail address at the host "example.com".
  return string_util::IsEqualNoCase(domain, constraint_domain);
}

}  // namespace

NameConstraints::~NameConstraints() = default;

// static
std::unique_ptr<NameConstraints> NameConstraints::Create(
    der::Input extension_value, bool is_critical, CertErrors *errors) {
  BSSL_CHECK(errors);

  auto name_constraints = std::make_unique<NameConstraints>();
  if (!name_constraints->Parse(extension_value, is_critical, errors)) {
    return nullptr;
  }
  return name_constraints;
}

std::unique_ptr<NameConstraints> NameConstraints::CreateFromPermittedSubtrees(
    GeneralNames permitted_subtrees) {
  auto name_constraints = std::make_unique<NameConstraints>();

  name_constraints->constrained_name_types_ =
      permitted_subtrees.present_name_types;
  name_constraints->permitted_subtrees_ = std::move(permitted_subtrees);

  return name_constraints;
}

bool NameConstraints::Parse(der::Input extension_value, bool is_critical,
                            CertErrors *errors) {
  BSSL_CHECK(errors);

  der::Parser extension_parser(extension_value);
  der::Parser sequence_parser;

  // NameConstraints ::= SEQUENCE {
  //      permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
  //      excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
  if (!extension_parser.ReadSequence(&sequence_parser)) {
    return false;
  }
  if (extension_parser.HasMore()) {
    return false;
  }

  std::optional<der::Input> permitted_subtrees_value;
  if (!sequence_parser.ReadOptionalTag(
          CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0,
          &permitted_subtrees_value)) {
    return false;
  }
  if (permitted_subtrees_value &&
      !ParseGeneralSubtrees(permitted_subtrees_value.value(),
                            &permitted_subtrees_, errors)) {
    return false;
  }
  constrained_name_types_ |=
      permitted_subtrees_.present_name_types &
      (is_critical ? GENERAL_NAME_ALL_TYPES : kSupportedNameTypes);

  std::optional<der::Input> excluded_subtrees_value;
  if (!sequence_parser.ReadOptionalTag(
          CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1,
          &excluded_subtrees_value)) {
    return false;
  }
  if (excluded_subtrees_value &&
      !ParseGeneralSubtrees(excluded_subtrees_value.value(),
                            &excluded_subtrees_, errors)) {
    return false;
  }
  constrained_name_types_ |=
      excluded_subtrees_.present_name_types &
      (is_critical ? GENERAL_NAME_ALL_TYPES : kSupportedNameTypes);

  // RFC 5280 section 4.2.1.10:
  // Conforming CAs MUST NOT issue certificates where name constraints is an
  // empty sequence. That is, either the permittedSubtrees field or the
  // excludedSubtrees MUST be present.
  if (!permitted_subtrees_value && !excluded_subtrees_value) {
    return false;
  }

  if (sequence_parser.HasMore()) {
    return false;
  }

  return true;
}

void NameConstraints::IsPermittedCert(der::Input subject_rdn_sequence,
                                      const GeneralNames *subject_alt_names,
                                      CertErrors *errors) const {
  // Checking NameConstraints is O(number_of_names * number_of_constraints).
  // Impose a hard limit to mitigate the use of name constraints as a DoS
  // mechanism. This mimics the similar check in BoringSSL x509/v_ncons.c
  // TODO(bbe): make both name constraint mechanisms subquadratic and remove
  // this check.

  const size_t kMaxChecks = 1048576;  // 1 << 20

  // Names all come from a certificate, which is bound by size_t, so adding them
  // up can not overflow a size_t.
  size_t name_count = 0;
  // Constraints all come from a certificate, which is bound by a size_t, so
  // adding them up can not overflow a size_t.
  size_t constraint_count = 0;
  if (subject_alt_names) {
    name_count = subject_alt_names->rfc822_names.size() +
                 subject_alt_names->dns_names.size() +
                 subject_alt_names->directory_names.size() +
                 subject_alt_names->ip_addresses.size();
    constraint_count = excluded_subtrees_.rfc822_names.size() +
                       permitted_subtrees_.rfc822_names.size() +
                       excluded_subtrees_.dns_names.size() +
                       permitted_subtrees_.dns_names.size() +
                       excluded_subtrees_.directory_names.size() +
                       permitted_subtrees_.directory_names.size() +
                       excluded_subtrees_.ip_address_ranges.size() +
                       permitted_subtrees_.ip_address_ranges.size();
  } else {
    constraint_count += excluded_subtrees_.directory_names.size() +
                        permitted_subtrees_.directory_names.size();
    name_count = subject_rdn_sequence.size();
  }
  // Upper bound the number of possible checks, checking for overflow.
  size_t check_count = constraint_count * name_count;
  if ((constraint_count > 0 && check_count / constraint_count != name_count) ||
      check_count > kMaxChecks) {
    errors->AddError(cert_errors::kTooManyNameConstraintChecks);
    return;
  }

  std::vector<std::string> subject_email_addresses_to_check;
  if (!subject_alt_names &&
      (constrained_name_types() & GENERAL_NAME_RFC822_NAME)) {
    if (!FindEmailAddressesInName(subject_rdn_sequence,
                                  &subject_email_addresses_to_check)) {
      // Error parsing |subject_rdn_sequence|.
      errors->AddError(cert_errors::kNotPermittedByNameConstraints);
      return;
    }
  }

  // Subject Alternative Name handling:
  //
  // RFC 5280 section 4.2.1.6:
  // id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 17 }
  //
  // SubjectAltName ::= GeneralNames
  //
  // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName

  if (subject_alt_names) {
    // Check unsupported name types:
    // constrained_name_types() for the unsupported types will only be true if
    // that type of name was present in a name constraint that was marked
    // critical.
    //
    // RFC 5280 section 4.2.1.10:
    // If a name constraints extension that is marked as critical
    // imposes constraints on a particular name form, and an instance of
    // that name form appears in the subject field or subjectAltName
    // extension of a subsequent certificate, then the application MUST
    // either process the constraint or reject the certificate.
    if (constrained_name_types() & subject_alt_names->present_name_types &
        ~kSupportedNameTypes) {
      errors->AddError(cert_errors::kNotPermittedByNameConstraints);
      return;
    }

    // Check supported name types:

    // Only check rfc822 SANs if any rfc822 constraints are present, since we
    // might fail if there are email addresses we don't know how to parse but
    // are technically correct.
    if (constrained_name_types() & GENERAL_NAME_RFC822_NAME) {
      for (const auto &rfc822_name : subject_alt_names->rfc822_names) {
        if (!IsPermittedRfc822Name(
                rfc822_name, /*case_insensitive_exclude_localpart=*/false)) {
          errors->AddError(cert_errors::kNotPermittedByNameConstraints);
          return;
        }
      }
    }

    for (const auto &dns_name : subject_alt_names->dns_names) {
      if (!IsPermittedDNSName(dns_name)) {
        errors->AddError(cert_errors::kNotPermittedByNameConstraints);
        return;
      }
    }

    for (const auto &directory_name : subject_alt_names->directory_names) {
      if (!IsPermittedDirectoryName(directory_name)) {
        errors->AddError(cert_errors::kNotPermittedByNameConstraints);
        return;
      }
    }

    for (const auto &ip_address : subject_alt_names->ip_addresses) {
      if (!IsPermittedIP(ip_address)) {
        errors->AddError(cert_errors::kNotPermittedByNameConstraints);
        return;
      }
    }
  }

  // Subject handling:

  // RFC 5280 section 4.2.1.10:
  // Legacy implementations exist where an electronic mail address is embedded
  // in the subject distinguished name in an attribute of type emailAddress
  // (Section 4.1.2.6). When constraints are imposed on the rfc822Name name
  // form, but the certificate does not include a subject alternative name, the
  // rfc822Name constraint MUST be applied to the attribute of type emailAddress
  // in the subject distinguished name.
  for (const auto &rfc822_name : subject_email_addresses_to_check) {
    // Whether local_part should be matched case-sensitive or not is somewhat
    // unclear. RFC 2821 says that it should be case-sensitive. RFC 2985 says
    // that emailAddress attributes in a Name are fully case-insensitive.
    // Some other verifier implementations always do local-part comparison
    // case-sensitive, while some always do it case-insensitive. Many but not
    // all SMTP servers interpret addresses as case-insensitive.
    //
    // Give how poorly specified this is, and the conflicting implementations
    // in the wild, this implementation will do case-insensitive match for
    // excluded names from the subject to avoid potentially allowing
    // something that wasn't expected.
    if (!IsPermittedRfc822Name(rfc822_name,
                               /*case_insensitive_exclude_localpart=*/true)) {
      errors->AddError(cert_errors::kNotPermittedByNameConstraints);
      return;
    }
  }

  // RFC 5280 4.1.2.6:
  // If subject naming information is present only in the subjectAltName
  // extension (e.g., a key bound only to an email address or URI), then the
  // subject name MUST be an empty sequence and the subjectAltName extension
  // MUST be critical.
  // This code assumes that criticality condition is checked by the caller, and
  // therefore only needs to avoid the IsPermittedDirectoryName check against an
  // empty subject in such a case.
  if (subject_alt_names && subject_rdn_sequence.empty()) {
    return;
  }

  if (!IsPermittedDirectoryName(subject_rdn_sequence)) {
    errors->AddError(cert_errors::kNotPermittedByNameConstraints);
    return;
  }
}

bool NameConstraints::IsPermittedRfc822Name(
    std::string_view name, bool case_insensitive_exclude_localpart) const {
  // RFC 5280 4.2.1.6.  Subject Alternative Name
  //
  // When the subjectAltName extension contains an Internet mail address,
  // the address MUST be stored in the rfc822Name.  The format of an
  // rfc822Name is a "Mailbox" as defined in Section 4.1.2 of [RFC2821].
  // A Mailbox has the form "Local-part@Domain".  Note that a Mailbox has
  // no phrase (such as a common name) before it, has no comment (text
  // surrounded in parentheses) after it, and is not surrounded by "<" and
  // ">".  Rules for encoding Internet mail addresses that include
  // internationalized domain names are specified in Section 7.5.

  // Relevant parts from RFC 2821 & RFC 2822
  //
  // Mailbox = Local-part "@" Domain
  // Local-part = Dot-string / Quoted-string
  //       ; MAY be case-sensitive
  //
  // Dot-string = Atom *("." Atom)
  // Atom = 1*atext
  // Quoted-string = DQUOTE *qcontent DQUOTE
  //
  //
  // atext           =       ALPHA / DIGIT / ; Any character except controls,
  //                         "!" / "#" /     ;  SP, and specials.
  //                         "$" / "%" /     ;  Used for atoms
  //                         "&" / "'" /
  //                         "*" / "+" /
  //                         "-" / "/" /
  //                         "=" / "?" /
  //                         "^" / "_" /
  //                         "`" / "{" /
  //                         "|" / "}" /
  //                         "~"
  //
  // atom            =       [CFWS] 1*atext [CFWS]
  //
  //
  // qtext           =       NO-WS-CTL /     ; Non white space controls
  //                         %d33 /          ; The rest of the US-ASCII
  //                         %d35-91 /       ;  characters not including "\"
  //                         %d93-126        ;  or the quote character
  //
  // quoted-pair     =       ("\" text) / obs-qp
  // qcontent        =       qtext / quoted-pair
  //
  //
  // Domain = (sub-domain 1*("." sub-domain)) / address-literal
  // sub-domain = Let-dig [Ldh-str]
  //
  // Let-dig = ALPHA / DIGIT
  // Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig
  //
  // address-literal = "[" IPv4-address-literal /
  //                       IPv6-address-literal /
  //                       General-address-literal "]"
  //       ; See section 4.1.3

  // However, no one actually implements all that. Known implementations just
  // do string comparisons, but that is technically incorrect. (Ex: a
  // constraint excluding |foo@example.com| should exclude a SAN of
  // |"foo"@example.com|, while a naive direct comparison will allow it.)
  //
  // We don't implement all that either, but do something a bit more fail-safe
  // by rejecting any addresses that contain characters that are not allowed in
  // the non-quoted formats.

  std::vector<std::string_view> name_components =
      bssl::string_util::SplitString(name, '@');
  if (name_components.size() != 2) {
    // If we did the full parsing then it is possible for a @ to be in a quoted
    // local-part of the name, but we don't do that, so just fail if @ appears
    // more than once.
    return false;
  }
  if (!IsAllowedRfc822LocalPart(name_components[0]) ||
      !IsAllowedRfc822Domain(name_components[1])) {
    return false;
  }

  for (const auto &excluded_name : excluded_subtrees_.rfc822_names) {
    if (Rfc822NameMatches(name_components[0], name_components[1], excluded_name,
                          Rfc822NameMatchType::kExcluded,
                          case_insensitive_exclude_localpart)) {
      return false;
    }
  }

  // If permitted subtrees are not constrained, any name that is not excluded is
  // allowed.
  if (!(permitted_subtrees_.present_name_types & GENERAL_NAME_RFC822_NAME)) {
    return true;
  }

  for (const auto &permitted_name : permitted_subtrees_.rfc822_names) {
    if (Rfc822NameMatches(name_components[0], name_components[1],
                          permitted_name, Rfc822NameMatchType::kPermitted,
                          /*case_insenitive_local_part=*/false)) {
      return true;
    }
  }

  return false;
}

bool NameConstraints::IsPermittedDNSName(std::string_view name) const {
  for (const auto &excluded_name : excluded_subtrees_.dns_names) {
    // When matching wildcard hosts against excluded subtrees, consider it a
    // match if the constraint would match any expansion of the wildcard. Eg,
    // *.bar.com should match a constraint of foo.bar.com.
    if (DNSNameMatches(name, excluded_name, WILDCARD_PARTIAL_MATCH)) {
      return false;
    }
  }

  // If permitted subtrees are not constrained, any name that is not excluded is
  // allowed.
  if (!(permitted_subtrees_.present_name_types & GENERAL_NAME_DNS_NAME)) {
    return true;
  }

  for (const auto &permitted_name : permitted_subtrees_.dns_names) {
    // When matching wildcard hosts against permitted subtrees, consider it a
    // match only if the constraint would match all expansions of the wildcard.
    // Eg, *.bar.com should match a constraint of bar.com, but not foo.bar.com.
    if (DNSNameMatches(name, permitted_name, WILDCARD_FULL_MATCH)) {
      return true;
    }
  }

  return false;
}

bool NameConstraints::IsPermittedDirectoryName(
    der::Input name_rdn_sequence) const {
  for (const auto &excluded_name : excluded_subtrees_.directory_names) {
    if (VerifyNameInSubtree(name_rdn_sequence, excluded_name)) {
      return false;
    }
  }

  // If permitted subtrees are not constrained, any name that is not excluded is
  // allowed.
  if (!(permitted_subtrees_.present_name_types & GENERAL_NAME_DIRECTORY_NAME)) {
    return true;
  }

  for (const auto &permitted_name : permitted_subtrees_.directory_names) {
    if (VerifyNameInSubtree(name_rdn_sequence, permitted_name)) {
      return true;
    }
  }

  return false;
}

bool NameConstraints::IsPermittedIP(der::Input ip) const {
  for (const auto &excluded_ip : excluded_subtrees_.ip_address_ranges) {
    if (IPAddressMatchesWithNetmask(ip, excluded_ip.first,
                                    excluded_ip.second)) {
      return false;
    }
  }

  // If permitted subtrees are not constrained, any name that is not excluded is
  // allowed.
  if (!(permitted_subtrees_.present_name_types & GENERAL_NAME_IP_ADDRESS)) {
    return true;
  }

  for (const auto &permitted_ip : permitted_subtrees_.ip_address_ranges) {
    if (IPAddressMatchesWithNetmask(ip, permitted_ip.first,
                                    permitted_ip.second)) {
      return true;
    }
  }

  return false;
}

BSSL_NAMESPACE_END
