// 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 "cert_errors.h"
#include "common_cert_errors.h"
#include "general_names.h"
#include "ip_util.h"
#include "string_util.h"
#include "verify_name_match.h"
#include "input.h"
#include "parser.h"
#include "tag.h"
#include <optional>
#include <openssl/base.h>

namespace bssl {

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(const 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(
    const 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;
}

bool NameConstraints::Parse(const 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(der::ContextSpecificConstructed(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(der::ContextSpecificConstructed(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(const 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.Length();
  }
  // 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.Length() == 0)
    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(
    const 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(const 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;
}

}  // namespace net
