// 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 "string_util.h"
#include "verify_name_match.h"
#include "input.h"
#include "parser.h"
#include "tag.h"
#include <optional>

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) {
  DCHECK(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) {
  DCHECK(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) {
  DCHECK(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 fillins::IPAddress& ip) const {
  // fillins::IPAddressMatchesPrefix internally maps v4 addresses to/from v6 on type
  // mismatch. We don't wish to do this, so check the sizes match first.
  for (const auto& excluded_ip : excluded_subtrees_.ip_address_ranges) {
    if (ip.size() == excluded_ip.first.size() &&
        fillins::IPAddressMatchesPrefix(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 (ip.size() == permitted_ip.first.size() &&
        fillins::IPAddressMatchesPrefix(ip, permitted_ip.first, permitted_ip.second)) {
      return true;
    }
  }

  return false;
}

}  // namespace net
