/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This code is made available to you under your choice of the following sets
 * of licensing terms:
 */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
/* Copyright 2014 Mozilla Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// This code implements RFC6125-ish name matching, RFC5280-ish name constraint
// checking, and related things.
//
// In this code, identifiers are classified as either "presented" or
// "reference" identifiers are defined in
// http://tools.ietf.org/html/rfc6125#section-1.8. A "presented identifier" is
// one in the subjectAltName of the certificate, or sometimes within a CN of
// the certificate's subject. The "reference identifier" is the one we are
// being asked to match the certificate against. When checking name
// constraints, the reference identifier is the entire encoded name constraint
// extension value.

#include <algorithm>

#include "mozpkix/pkixcheck.h"
#include "mozpkix/pkixutil.h"

namespace mozilla { namespace pkix {

namespace {

// GeneralName ::= CHOICE {
//      otherName                       [0]     OtherName,
//      rfc822Name                      [1]     IA5String,
//      dNSName                         [2]     IA5String,
//      x400Address                     [3]     ORAddress,
//      directoryName                   [4]     Name,
//      ediPartyName                    [5]     EDIPartyName,
//      uniformResourceIdentifier       [6]     IA5String,
//      iPAddress                       [7]     OCTET STRING,
//      registeredID                    [8]     OBJECT IDENTIFIER }
enum class GeneralNameType : uint8_t
{
  // Note that these values are NOT contiguous. Some values have the
  // der::CONSTRUCTED bit set while others do not.
  // (The der::CONSTRUCTED bit is for types where the value is a SEQUENCE.)
  otherName = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0,
  rfc822Name = der::CONTEXT_SPECIFIC | 1,
  dNSName = der::CONTEXT_SPECIFIC | 2,
  x400Address = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 3,
  directoryName = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 4,
  ediPartyName = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 5,
  uniformResourceIdentifier = der::CONTEXT_SPECIFIC | 6,
  iPAddress = der::CONTEXT_SPECIFIC | 7,
  registeredID = der::CONTEXT_SPECIFIC | 8,
  // nameConstraints is a pseudo-GeneralName used to signify that a
  // reference ID is actually the entire name constraint extension.
  nameConstraints = 0xff
};

inline Result
ReadGeneralName(Reader& reader,
                /*out*/ GeneralNameType& generalNameType,
                /*out*/ Input& value)
{
  uint8_t tag;
  Result rv = der::ReadTagAndGetValue(reader, tag, value);
  if (rv != Success) {
    return rv;
  }
  switch (tag) {
    case static_cast<uint8_t>(GeneralNameType::otherName):
      generalNameType = GeneralNameType::otherName;
      break;
    case static_cast<uint8_t>(GeneralNameType::rfc822Name):
      generalNameType = GeneralNameType::rfc822Name;
      break;
    case static_cast<uint8_t>(GeneralNameType::dNSName):
      generalNameType = GeneralNameType::dNSName;
      break;
    case static_cast<uint8_t>(GeneralNameType::x400Address):
      generalNameType = GeneralNameType::x400Address;
      break;
    case static_cast<uint8_t>(GeneralNameType::directoryName):
      generalNameType = GeneralNameType::directoryName;
      break;
    case static_cast<uint8_t>(GeneralNameType::ediPartyName):
      generalNameType = GeneralNameType::ediPartyName;
      break;
    case static_cast<uint8_t>(GeneralNameType::uniformResourceIdentifier):
      generalNameType = GeneralNameType::uniformResourceIdentifier;
      break;
    case static_cast<uint8_t>(GeneralNameType::iPAddress):
      generalNameType = GeneralNameType::iPAddress;
      break;
    case static_cast<uint8_t>(GeneralNameType::registeredID):
      generalNameType = GeneralNameType::registeredID;
      break;
    default:
      return Result::ERROR_BAD_DER;
  }
  return Success;
}

enum class MatchResult
{
  NoNamesOfGivenType = 0,
  Mismatch = 1,
  Match = 2
};

Result SearchNames(const Input* subjectAltName, Input subject,
                   GeneralNameType referenceIDType,
                   Input referenceID,
                   FallBackToSearchWithinSubject fallBackToCommonName,
                   /*out*/ MatchResult& match);
Result SearchWithinRDN(Reader& rdn,
                       GeneralNameType referenceIDType,
                       Input referenceID,
                       FallBackToSearchWithinSubject fallBackToEmailAddress,
                       FallBackToSearchWithinSubject fallBackToCommonName,
                       /*in/out*/ MatchResult& match);
Result MatchAVA(Input type,
                uint8_t valueEncodingTag,
                Input presentedID,
                GeneralNameType referenceIDType,
                Input referenceID,
                FallBackToSearchWithinSubject fallBackToEmailAddress,
                FallBackToSearchWithinSubject fallBackToCommonName,
                /*in/out*/ MatchResult& match);
Result ReadAVA(Reader& rdn,
               /*out*/ Input& type,
               /*out*/ uint8_t& valueTag,
               /*out*/ Input& value);
void MatchSubjectPresentedIDWithReferenceID(GeneralNameType presentedIDType,
                                            Input presentedID,
                                            GeneralNameType referenceIDType,
                                            Input referenceID,
                                            /*in/out*/ MatchResult& match);

Result MatchPresentedIDWithReferenceID(GeneralNameType presentedIDType,
                                       Input presentedID,
                                       GeneralNameType referenceIDType,
                                       Input referenceID,
                                       /*in/out*/ MatchResult& matchResult);
Result CheckPresentedIDConformsToConstraints(GeneralNameType referenceIDType,
                                             Input presentedID,
                                             Input nameConstraints);

uint8_t LocaleInsensitveToLower(uint8_t a);
bool StartsWithIDNALabel(Input id);

enum class IDRole
{
  ReferenceID = 0,
  PresentedID = 1,
  NameConstraint = 2,
};

enum class AllowWildcards { No = 0, Yes = 1 };

// DNSName constraints implicitly allow subdomain matching when there is no
// leading dot ("foo.example.com" matches a constraint of "example.com"), but
// RFC822Name constraints only allow subdomain matching when there is a leading
// dot ("foo.example.com" does not match "example.com" but does match
// ".example.com").
enum class AllowDotlessSubdomainMatches { No = 0, Yes = 1 };

bool IsValidDNSID(Input hostname, IDRole idRole,
                  AllowWildcards allowWildcards);

Result MatchPresentedDNSIDWithReferenceDNSID(
         Input presentedDNSID,
         AllowWildcards allowWildcards,
         AllowDotlessSubdomainMatches allowDotlessSubdomainMatches,
         IDRole referenceDNSIDRole,
         Input referenceDNSID,
         /*out*/ bool& matches);

Result MatchPresentedRFC822NameWithReferenceRFC822Name(
         Input presentedRFC822Name, IDRole referenceRFC822NameRole,
         Input referenceRFC822Name, /*out*/ bool& matches);

} // namespace

bool IsValidReferenceDNSID(Input hostname);
bool IsValidPresentedDNSID(Input hostname);
bool ParseIPv4Address(Input hostname, /*out*/ uint8_t (&out)[4]);
bool ParseIPv6Address(Input hostname, /*out*/ uint8_t (&out)[16]);

// This is used by the pkixnames_tests.cpp tests.
Result
MatchPresentedDNSIDWithReferenceDNSID(Input presentedDNSID,
                                      Input referenceDNSID,
                                      /*out*/ bool& matches)
{
  return MatchPresentedDNSIDWithReferenceDNSID(
           presentedDNSID, AllowWildcards::Yes,
           AllowDotlessSubdomainMatches::Yes, IDRole::ReferenceID,
           referenceDNSID, matches);
}

// Verify that the given end-entity cert, which is assumed to have been already
// validated with BuildCertChain, is valid for the given hostname. hostname is
// assumed to be a string representation of an IPv4 address, an IPv6 addresss,
// or a normalized ASCII (possibly punycode) DNS name.
Result
CheckCertHostname(Input endEntityCertDER, Input hostname,
                  NameMatchingPolicy& nameMatchingPolicy)
{
  BackCert cert(endEntityCertDER, EndEntityOrCA::MustBeEndEntity, nullptr);
  Result rv = cert.Init();
  if (rv != Success) {
    return rv;
  }

  Time notBefore(Time::uninitialized);
  rv = ParseValidity(cert.GetValidity(), &notBefore);
  if (rv != Success) {
    return rv;
  }
  FallBackToSearchWithinSubject fallBackToSearchWithinSubject;
  rv = nameMatchingPolicy.FallBackToCommonName(notBefore,
                                               fallBackToSearchWithinSubject);
  if (rv != Success) {
    return rv;
  }

  const Input* subjectAltName(cert.GetSubjectAltName());
  Input subject(cert.GetSubject());

  // For backward compatibility with legacy certificates, we may fall back to
  // searching for a name match in the subject common name for DNS names and
  // IPv4 addresses. We don't do so for IPv6 addresses because we do not think
  // there are many certificates that would need such fallback, and because
  // comparisons of string representations of IPv6 addresses are particularly
  // error prone due to the syntactic flexibility that IPv6 addresses have.
  //
  // IPv4 and IPv6 addresses are represented using the same type of GeneralName
  // (iPAddress); they are differentiated by the lengths of the values.
  MatchResult match;
  uint8_t ipv6[16];
  uint8_t ipv4[4];
  if (IsValidReferenceDNSID(hostname)) {
    rv = SearchNames(subjectAltName, subject, GeneralNameType::dNSName,
                     hostname, fallBackToSearchWithinSubject, match);
  } else if (ParseIPv6Address(hostname, ipv6)) {
    rv = SearchNames(subjectAltName, subject, GeneralNameType::iPAddress,
                     Input(ipv6), FallBackToSearchWithinSubject::No, match);
  } else if (ParseIPv4Address(hostname, ipv4)) {
    rv = SearchNames(subjectAltName, subject, GeneralNameType::iPAddress,
                     Input(ipv4), fallBackToSearchWithinSubject, match);
  } else {
    return Result::ERROR_BAD_CERT_DOMAIN;
  }
  if (rv != Success) {
    return rv;
  }
  switch (match) {
    case MatchResult::NoNamesOfGivenType: // fall through
    case MatchResult::Mismatch:
      return Result::ERROR_BAD_CERT_DOMAIN;
    case MatchResult::Match:
      return Success;
    MOZILLA_PKIX_UNREACHABLE_DEFAULT_ENUM
  }
}

// 4.2.1.10. Name Constraints
Result
CheckNameConstraints(Input encodedNameConstraints,
                     const BackCert& firstChild,
                     KeyPurposeId requiredEKUIfPresent)
{
  for (const BackCert* child = &firstChild; child; child = child->childCert) {
    FallBackToSearchWithinSubject fallBackToCommonName
      = (child->endEntityOrCA == EndEntityOrCA::MustBeEndEntity &&
         requiredEKUIfPresent == KeyPurposeId::id_kp_serverAuth)
      ? FallBackToSearchWithinSubject::Yes
      : FallBackToSearchWithinSubject::No;

    MatchResult match;
    Result rv = SearchNames(child->GetSubjectAltName(), child->GetSubject(),
                            GeneralNameType::nameConstraints,
                            encodedNameConstraints, fallBackToCommonName,
                            match);
    if (rv != Success) {
      return rv;
    }
    switch (match) {
      case MatchResult::Match: // fall through
      case MatchResult::NoNamesOfGivenType:
        break;
      case MatchResult::Mismatch:
        return Result::ERROR_CERT_NOT_IN_NAME_SPACE;
    }
  }

  return Success;
}

namespace {

// SearchNames is used by CheckCertHostname and CheckNameConstraints.
//
// When called during name constraint checking, referenceIDType is
// GeneralNameType::nameConstraints and referenceID is the entire encoded name
// constraints extension value.
//
// The main benefit of using the exact same code paths for both is that we
// ensure consistency between name validation and name constraint enforcement
// regarding thing like "Which CN attributes should be considered as potential
// CN-IDs" and "Which character sets are acceptable for CN-IDs?" If the name
// matching and the name constraint enforcement logic were out of sync on these
// issues (e.g. if name matching were to consider all subject CN attributes,
// but name constraints were only enforced on the most specific subject CN),
// trivial name constraint bypasses could result.

Result
SearchNames(/*optional*/ const Input* subjectAltName,
            Input subject,
            GeneralNameType referenceIDType,
            Input referenceID,
            FallBackToSearchWithinSubject fallBackToCommonName,
            /*out*/ MatchResult& match)
{
  Result rv;

  match = MatchResult::NoNamesOfGivenType;

  // RFC 6125 says "A client MUST NOT seek a match for a reference identifier
  // of CN-ID if the presented identifiers include a DNS-ID, SRV-ID, URI-ID, or
  // any application-specific identifier types supported by the client."
  // Accordingly, we only consider CN-IDs if there are no DNS-IDs in the
  // subjectAltName.
  //
  // RFC 6125 says that IP addresses are out of scope, but for backward
  // compatibility we accept them, by considering IP addresses to be an
  // "application-specific identifier type supported by the client."
  //
  // TODO(bug XXXXXXX): Consider strengthening this check to "A client MUST NOT
  // seek a match for a reference identifier of CN-ID if the certificate
  // contains a subjectAltName extension."
  //
  // TODO(bug XXXXXXX): Consider dropping support for IP addresses as
  // identifiers completely.

  if (subjectAltName) {
    Reader altNames;
    rv = der::ExpectTagAndGetValueAtEnd(*subjectAltName, der::SEQUENCE,
                                        altNames);
    if (rv != Success) {
      return rv;
    }

    // According to RFC 5280, "If the subjectAltName extension is present, the
    // sequence MUST contain at least one entry." For compatibility reasons, we
    // do not enforce this. See bug 1143085.
    while (!altNames.AtEnd()) {
      GeneralNameType presentedIDType;
      Input presentedID;
      rv = ReadGeneralName(altNames, presentedIDType, presentedID);
      if (rv != Success) {
        return rv;
      }

      rv = MatchPresentedIDWithReferenceID(presentedIDType, presentedID,
                                           referenceIDType, referenceID,
                                           match);
      if (rv != Success) {
        return rv;
      }
      if (referenceIDType != GeneralNameType::nameConstraints &&
          match == MatchResult::Match) {
        return Success;
      }
      if (presentedIDType == GeneralNameType::dNSName ||
          presentedIDType == GeneralNameType::iPAddress) {
        fallBackToCommonName = FallBackToSearchWithinSubject::No;
      }
    }
  }

  if (referenceIDType == GeneralNameType::nameConstraints) {
    rv = CheckPresentedIDConformsToConstraints(GeneralNameType::directoryName,
                                               subject, referenceID);
    if (rv != Success) {
      return rv;
    }
  }

  FallBackToSearchWithinSubject fallBackToEmailAddress;
  if (!subjectAltName &&
      (referenceIDType == GeneralNameType::rfc822Name ||
       referenceIDType == GeneralNameType::nameConstraints)) {
    fallBackToEmailAddress = FallBackToSearchWithinSubject::Yes;
  } else {
    fallBackToEmailAddress = FallBackToSearchWithinSubject::No;
  }

  // Short-circuit the parsing of the subject name if we're not going to match
  // any names in it
  if (fallBackToEmailAddress == FallBackToSearchWithinSubject::No &&
      fallBackToCommonName == FallBackToSearchWithinSubject::No) {
    return Success;
  }

  // Attempt to match the reference ID against the CN-ID, which we consider to
  // be the most-specific CN AVA in the subject field.
  //
  // https://tools.ietf.org/html/rfc6125#section-2.3.1 says:
  //
  //   To reduce confusion, in this specification we avoid such terms and
  //   instead use the terms provided under Section 1.8; in particular, we
  //   do not use the term "(most specific) Common Name field in the subject
  //   field" from [HTTP-TLS] and instead state that a CN-ID is a Relative
  //   Distinguished Name (RDN) in the certificate subject containing one
  //   and only one attribute-type-and-value pair of type Common Name (thus
  //   removing the possibility that an RDN might contain multiple AVAs
  //   (Attribute Value Assertions) of type CN, one of which could be
  //   considered "most specific").
  //
  // https://tools.ietf.org/html/rfc6125#section-7.4 says:
  //
  //   [...] Although it would be preferable to
  //   forbid multiple CN-IDs entirely, there are several reasons at this
  //   time why this specification states that they SHOULD NOT (instead of
  //   MUST NOT) be included [...]
  //
  // Consequently, it is unclear what to do when there are multiple CNs in the
  // subject, regardless of whether there "SHOULD NOT" be.
  //
  // NSS's CERT_VerifyCertName mostly follows RFC2818 in this instance, which
  // says:
  //
  //   If a subjectAltName extension of type dNSName is present, that MUST
  //   be used as the identity. Otherwise, the (most specific) Common Name
  //   field in the Subject field of the certificate MUST be used.
  //
  //   [...]
  //
  //   In some cases, the URI is specified as an IP address rather than a
  //   hostname. In this case, the iPAddress subjectAltName must be present
  //   in the certificate and must exactly match the IP in the URI.
  //
  // (The main difference from RFC2818 is that NSS's CERT_VerifyCertName also
  // matches IP addresses in the most-specific CN.)
  //
  // NSS's CERT_VerifyCertName finds the most specific CN via
  // CERT_GetCommoName, which uses CERT_GetLastNameElement. Note that many
  // NSS-based applications, including Gecko, also use CERT_GetCommonName. It
  // is likely that other, non-NSS-based, applications also expect only the
  // most specific CN to be matched against the reference ID.
  //
  // "A Layman's Guide to a Subset of ASN.1, BER, and DER" and other sources
  // agree that an RDNSequence is ordered from most significant (least
  // specific) to least significant (most specific), as do other references.
  //
  // However, Chromium appears to use the least-specific (first) CN instead of
  // the most-specific; see https://crbug.com/366957. Also, MSIE and some other
  // popular implementations apparently attempt to match the reference ID
  // against any/all CNs in the subject. Since we're trying to phase out the
  // use of CN-IDs, we intentionally avoid trying to match MSIE's more liberal
  // behavior.

  // Name ::= CHOICE { -- only one possibility for now --
  //   rdnSequence  RDNSequence }
  //
  // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
  //
  // RelativeDistinguishedName ::=
  //   SET SIZE (1..MAX) OF AttributeTypeAndValue
  Reader subjectReader(subject);
  return der::NestedOf(subjectReader, der::SEQUENCE, der::SET,
                       der::EmptyAllowed::Yes, [&](Reader& r) {
    return SearchWithinRDN(r, referenceIDType, referenceID,
                          fallBackToEmailAddress, fallBackToCommonName, match);
  });
}

// RelativeDistinguishedName ::=
//   SET SIZE (1..MAX) OF AttributeTypeAndValue
//
// AttributeTypeAndValue ::= SEQUENCE {
//   type     AttributeType,
//   value    AttributeValue }
Result
SearchWithinRDN(Reader& rdn,
                GeneralNameType referenceIDType,
                Input referenceID,
                FallBackToSearchWithinSubject fallBackToEmailAddress,
                FallBackToSearchWithinSubject fallBackToCommonName,
                /*in/out*/ MatchResult& match)
{
  do {
    Input type;
    uint8_t valueTag;
    Input value;
    Result rv = ReadAVA(rdn, type, valueTag, value);
    if (rv != Success) {
      return rv;
    }
    rv = MatchAVA(type, valueTag, value, referenceIDType, referenceID,
                  fallBackToEmailAddress, fallBackToCommonName, match);
    if (rv != Success) {
      return rv;
    }
  } while (!rdn.AtEnd());

  return Success;
}

// AttributeTypeAndValue ::= SEQUENCE {
//   type     AttributeType,
//   value    AttributeValue }
//
// AttributeType ::= OBJECT IDENTIFIER
//
// AttributeValue ::= ANY -- DEFINED BY AttributeType
//
// DirectoryString ::= CHOICE {
//       teletexString           TeletexString (SIZE (1..MAX)),
//       printableString         PrintableString (SIZE (1..MAX)),
//       universalString         UniversalString (SIZE (1..MAX)),
//       utf8String              UTF8String (SIZE (1..MAX)),
//       bmpString               BMPString (SIZE (1..MAX)) }
Result
MatchAVA(Input type, uint8_t valueEncodingTag, Input presentedID,
         GeneralNameType referenceIDType,
         Input referenceID,
         FallBackToSearchWithinSubject fallBackToEmailAddress,
         FallBackToSearchWithinSubject fallBackToCommonName,
         /*in/out*/ MatchResult& match)
{
  // Try to match the  CN as a DNSName or an IPAddress.
  //
  // id-at-commonName        AttributeType ::= { id-at 3 }
  //
  // -- Naming attributes of type X520CommonName:
  // --   X520CommonName ::= DirectoryName (SIZE (1..ub-common-name))
  // --
  // -- Expanded to avoid parameterized type:
  // X520CommonName ::= CHOICE {
  //       teletexString     TeletexString   (SIZE (1..ub-common-name)),
  //       printableString   PrintableString (SIZE (1..ub-common-name)),
  //       universalString   UniversalString (SIZE (1..ub-common-name)),
  //       utf8String        UTF8String      (SIZE (1..ub-common-name)),
  //       bmpString         BMPString       (SIZE (1..ub-common-name)) }
  //
  // python DottedOIDToCode.py id-at-commonName 2.5.4.3
  static const uint8_t id_at_commonName[] = {
    0x55, 0x04, 0x03
  };
  if (fallBackToCommonName == FallBackToSearchWithinSubject::Yes &&
      InputsAreEqual(type, Input(id_at_commonName))) {
    // We might have previously found a match. Now that we've found another CN,
    // we no longer consider that previous match to be a match, so "forget" about
    // it.
    match = MatchResult::NoNamesOfGivenType;

    // PrintableString is a subset of ASCII that contains all the characters
    // allowed in CN-IDs except '*'. Although '*' is illegal, there are many
    // real-world certificates that are encoded this way, so we accept it.
    //
    // In the case of UTF8String, we rely on the fact that in UTF-8 the octets in
    // a multi-byte encoding of a code point are always distinct from ASCII. Any
    // non-ASCII byte in a UTF-8 string causes us to fail to match. We make no
    // attempt to detect or report malformed UTF-8 (e.g. incomplete or overlong
    // encodings of code points, or encodings of invalid code points).
    //
    // TeletexString is supported as long as it does not contain any escape
    // sequences, which are not supported. We'll reject escape sequences as
    // invalid characters in names, which means we only accept strings that are
    // in the default character set, which is a superset of ASCII. Note that NSS
    // actually treats TeletexString as ISO-8859-1. Many certificates that have
    // wildcard CN-IDs (e.g. "*.example.com") use TeletexString because
    // PrintableString is defined to not allow '*' and because, at one point in
    // history, UTF8String was too new to use for compatibility reasons.
    //
    // UniversalString and BMPString are also deprecated, and they are a little
    // harder to support because they are not single-byte ASCII superset
    // encodings, so we don't bother.
    if (valueEncodingTag != der::PrintableString &&
        valueEncodingTag != der::UTF8String &&
        valueEncodingTag != der::TeletexString) {
      return Success;
    }

    if (IsValidPresentedDNSID(presentedID)) {
      MatchSubjectPresentedIDWithReferenceID(GeneralNameType::dNSName,
                                             presentedID, referenceIDType,
                                             referenceID, match);
    } else {
      // We don't match CN-IDs for IPv6 addresses.
      // MatchSubjectPresentedIDWithReferenceID ensures that it won't match an
      // IPv4 address with an IPv6 address, so we don't need to check that
      // referenceID is an IPv4 address here.
      uint8_t ipv4[4];
      if (ParseIPv4Address(presentedID, ipv4)) {
        MatchSubjectPresentedIDWithReferenceID(GeneralNameType::iPAddress,
                                               Input(ipv4), referenceIDType,
                                               referenceID, match);
      }
    }

    // Regardless of whether there was a match, we keep going in case we find
    // another CN later. If we do find another one, then this match/mismatch
    // will be ignored, because we only care about the most specific CN.

    return Success;
  }

  // Match an email address against an emailAddress attribute in the
  // subject.
  //
  // id-emailAddress      AttributeType ::= { pkcs-9 1 }
  //
  // EmailAddress ::=     IA5String (SIZE (1..ub-emailaddress-length))
  //
  // python DottedOIDToCode.py id-emailAddress 1.2.840.113549.1.9.1
  static const uint8_t id_emailAddress[] = {
    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01
  };
  if (fallBackToEmailAddress == FallBackToSearchWithinSubject::Yes &&
      InputsAreEqual(type, Input(id_emailAddress))) {
    if (referenceIDType == GeneralNameType::rfc822Name &&
        match == MatchResult::Match) {
      // We already found a match; we don't need to match another one
      return Success;
    }
    if (valueEncodingTag != der::IA5String) {
      return Result::ERROR_BAD_DER;
    }
    return MatchPresentedIDWithReferenceID(GeneralNameType::rfc822Name,
                                           presentedID, referenceIDType,
                                           referenceID, match);
  }

  return Success;
}

void
MatchSubjectPresentedIDWithReferenceID(GeneralNameType presentedIDType,
                                       Input presentedID,
                                       GeneralNameType referenceIDType,
                                       Input referenceID,
                                       /*in/out*/ MatchResult& match)
{
  Result rv = MatchPresentedIDWithReferenceID(presentedIDType, presentedID,
                                              referenceIDType, referenceID,
                                              match);
  if (rv != Success) {
    match = MatchResult::Mismatch;
  }
}

Result
MatchPresentedIDWithReferenceID(GeneralNameType presentedIDType,
                                Input presentedID,
                                GeneralNameType referenceIDType,
                                Input referenceID,
                                /*out*/ MatchResult& matchResult)
{
  if (referenceIDType == GeneralNameType::nameConstraints) {
    // matchResult is irrelevant when checking name constraints; only the
    // pass/fail result of CheckPresentedIDConformsToConstraints matters.
    return CheckPresentedIDConformsToConstraints(presentedIDType, presentedID,
                                                 referenceID);
  }

  if (presentedIDType != referenceIDType) {
    matchResult = MatchResult::Mismatch;
    return Success;
  }

  Result rv;
  bool foundMatch;

  switch (referenceIDType) {
    case GeneralNameType::dNSName:
      rv = MatchPresentedDNSIDWithReferenceDNSID(
             presentedID, AllowWildcards::Yes,
             AllowDotlessSubdomainMatches::Yes, IDRole::ReferenceID,
             referenceID, foundMatch);
      break;

    case GeneralNameType::iPAddress:
      foundMatch = InputsAreEqual(presentedID, referenceID);
      rv = Success;
      break;

    case GeneralNameType::rfc822Name:
      rv = MatchPresentedRFC822NameWithReferenceRFC822Name(
             presentedID, IDRole::ReferenceID, referenceID, foundMatch);
      break;

    case GeneralNameType::directoryName:
      // TODO: At some point, we may add APIs for matching DirectoryNames.
      // fall through

    case GeneralNameType::otherName: // fall through
    case GeneralNameType::x400Address: // fall through
    case GeneralNameType::ediPartyName: // fall through
    case GeneralNameType::uniformResourceIdentifier: // fall through
    case GeneralNameType::registeredID: // fall through
    case GeneralNameType::nameConstraints:
      return NotReached("unexpected nameType for SearchType::Match",
                        Result::FATAL_ERROR_INVALID_ARGS);

    MOZILLA_PKIX_UNREACHABLE_DEFAULT_ENUM
 }

  if (rv != Success) {
    return rv;
  }
  matchResult = foundMatch ? MatchResult::Match : MatchResult::Mismatch;
  return Success;
}

enum class NameConstraintsSubtrees : uint8_t
{
  permittedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 0,
  excludedSubtrees  = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 1
};

Result CheckPresentedIDConformsToNameConstraintsSubtrees(
         GeneralNameType presentedIDType,
         Input presentedID,
         Reader& nameConstraints,
         NameConstraintsSubtrees subtreesType);
Result MatchPresentedIPAddressWithConstraint(Input presentedID,
                                             Input iPAddressConstraint,
                                             /*out*/ bool& foundMatch);
Result MatchPresentedDirectoryNameWithConstraint(
         NameConstraintsSubtrees subtreesType, Input presentedID,
         Input directoryNameConstraint, /*out*/ bool& matches);

Result
CheckPresentedIDConformsToConstraints(
  GeneralNameType presentedIDType,
  Input presentedID,
  Input encodedNameConstraints)
{
  // NameConstraints ::= SEQUENCE {
  //      permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
  //      excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
  Reader nameConstraints;
  Result rv = der::ExpectTagAndGetValueAtEnd(encodedNameConstraints,
                                             der::SEQUENCE, nameConstraints);
  if (rv != Success) {
    return rv;
  }

  // RFC 5280 says "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 (nameConstraints.AtEnd()) {
    return Result::ERROR_BAD_DER;
  }

  rv = CheckPresentedIDConformsToNameConstraintsSubtrees(
         presentedIDType, presentedID, nameConstraints,
         NameConstraintsSubtrees::permittedSubtrees);
  if (rv != Success) {
    return rv;
  }

  rv = CheckPresentedIDConformsToNameConstraintsSubtrees(
         presentedIDType, presentedID, nameConstraints,
         NameConstraintsSubtrees::excludedSubtrees);
  if (rv != Success) {
    return rv;
  }

  return der::End(nameConstraints);
}

Result
CheckPresentedIDConformsToNameConstraintsSubtrees(
  GeneralNameType presentedIDType,
  Input presentedID,
  Reader& nameConstraints,
  NameConstraintsSubtrees subtreesType)
{
  if (!nameConstraints.Peek(static_cast<uint8_t>(subtreesType))) {
    return Success;
  }

  Reader subtrees;
  Result rv = der::ExpectTagAndGetValue(nameConstraints,
                                        static_cast<uint8_t>(subtreesType),
                                        subtrees);
  if (rv != Success) {
    return rv;
  }

  bool hasPermittedSubtreesMatch = false;
  bool hasPermittedSubtreesMismatch = false;

  // GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
  //
  // do { ... } while(...) because subtrees isn't allowed to be empty.
  do {
    // GeneralSubtree ::= SEQUENCE {
    //      base                    GeneralName,
    //      minimum         [0]     BaseDistance DEFAULT 0,
    //      maximum         [1]     BaseDistance OPTIONAL }
    Reader subtree;
    rv = ExpectTagAndGetValue(subtrees, der::SEQUENCE, subtree);
    if (rv != Success) {
      return rv;
    }
    GeneralNameType nameConstraintType;
    Input base;
    rv = ReadGeneralName(subtree, nameConstraintType, base);
    if (rv != Success) {
      return rv;
    }
    // http://tools.ietf.org/html/rfc5280#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."
    //
    // Since the default value isn't allowed to be encoded according to the DER
    // encoding rules for DEFAULT, this is equivalent to saying that neither
    // minimum or maximum must be encoded.
    rv = der::End(subtree);
    if (rv != Success) {
      return rv;
    }

    if (presentedIDType == nameConstraintType) {
      bool matches;

      switch (presentedIDType) {
        case GeneralNameType::dNSName:
          rv = MatchPresentedDNSIDWithReferenceDNSID(
                 presentedID, AllowWildcards::Yes,
                 AllowDotlessSubdomainMatches::Yes, IDRole::NameConstraint,
                 base, matches);
          if (rv != Success) {
            return rv;
          }
          break;

        case GeneralNameType::iPAddress:
          rv = MatchPresentedIPAddressWithConstraint(presentedID, base,
                                                     matches);
          if (rv != Success) {
            return rv;
          }
          break;

        case GeneralNameType::directoryName:
          rv = MatchPresentedDirectoryNameWithConstraint(subtreesType,
                                                         presentedID, base,
                                                         matches);
          if (rv != Success) {
            return rv;
          }
          break;

        case GeneralNameType::rfc822Name:
          rv = MatchPresentedRFC822NameWithReferenceRFC822Name(
                 presentedID, IDRole::NameConstraint, base, matches);
          if (rv != Success) {
            return rv;
          }
          break;

        // RFC 5280 says "Conforming CAs [...] SHOULD NOT impose name
        // constraints on the x400Address, ediPartyName, or registeredID
        // name forms. It also says "Applications conforming to this profile
        // [...] SHOULD be able to process name constraints that are imposed
        // on [...] uniformResourceIdentifier [...]", but we don't bother.
        //
        // TODO: Ask to have spec updated to say ""Conforming CAs [...] SHOULD
        // NOT impose name constraints on the otherName, x400Address,
        // ediPartyName, uniformResourceIdentifier, or registeredID name
        // forms."
        case GeneralNameType::otherName: // fall through
        case GeneralNameType::x400Address: // fall through
        case GeneralNameType::ediPartyName: // fall through
        case GeneralNameType::uniformResourceIdentifier: // fall through
        case GeneralNameType::registeredID: // fall through
          return Result::ERROR_CERT_NOT_IN_NAME_SPACE;

        case GeneralNameType::nameConstraints:
          return NotReached("invalid presentedIDType",
                            Result::FATAL_ERROR_LIBRARY_FAILURE);

        MOZILLA_PKIX_UNREACHABLE_DEFAULT_ENUM
      }

      switch (subtreesType) {
        case NameConstraintsSubtrees::permittedSubtrees:
          if (matches) {
            hasPermittedSubtreesMatch = true;
          } else {
            hasPermittedSubtreesMismatch = true;
          }
          break;
        case NameConstraintsSubtrees::excludedSubtrees:
          if (matches) {
            return Result::ERROR_CERT_NOT_IN_NAME_SPACE;
          }
          break;
      }
    }
  } while (!subtrees.AtEnd());

  if (hasPermittedSubtreesMismatch && !hasPermittedSubtreesMatch) {
    // If there was any entry of the given type in permittedSubtrees, then it
    // required that at least one of them must match. Since none of them did,
    // we have a failure.
    return Result::ERROR_CERT_NOT_IN_NAME_SPACE;
  }

  return Success;
}

// We do not distinguish between a syntactically-invalid presentedDNSID and one
// that is syntactically valid but does not match referenceDNSID; in both
// cases, the result is false.
//
// We assume that both presentedDNSID and referenceDNSID are encoded in such a
// way that US-ASCII (7-bit) characters are encoded in one byte and no encoding
// of a non-US-ASCII character contains a code point in the range 0-127. For
// example, UTF-8 is OK but UTF-16 is not.
//
// RFC6125 says that a wildcard label may be of the form <x>*<y>.<DNSID>, where
// <x> and/or <y> may be empty. However, NSS requires <y> to be empty, and we
// follow NSS's stricter policy by accepting wildcards only of the form
// <x>*.<DNSID>, where <x> may be empty.
//
// An relative presented DNS ID matches both an absolute reference ID and a
// relative reference ID. Absolute presented DNS IDs are not supported:
//
//      Presented ID   Reference ID  Result
//      -------------------------------------
//      example.com    example.com   Match
//      example.com.   example.com   Mismatch
//      example.com    example.com.  Match
//      example.com.   example.com.  Mismatch
//
// There are more subtleties documented inline in the code.
//
// Name constraints ///////////////////////////////////////////////////////////
//
// This is all RFC 5280 has to say about DNSName constraints:
//
//     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.
//
// This lack of specificity has lead to a lot of uncertainty regarding
// subdomain matching. In particular, the following questions have been
// raised and answered:
//
//     Q: Does a presented identifier equal (case insensitive) to the name
//        constraint match the constraint? For example, does the presented
//        ID "host.example.com" match a "host.example.com" constraint?
//     A: Yes. RFC5280 says "by simply adding zero or more labels" and this
//        is the case of adding zero labels.
//
//     Q: When the name constraint does not start with ".", do subdomain
//        presented identifiers match it? For example, does the presented
//        ID "www.host.example.com" match a "host.example.com" constraint?
//     A: Yes. RFC5280 says "by simply adding zero or more labels" and this
//        is the case of adding more than zero labels. The example is the
//        one from RFC 5280.
//
//     Q: When the name constraint does not start with ".", does a
//        non-subdomain prefix match it? For example, does "bigfoo.bar.com"
//        match "foo.bar.com"? [4]
//     A: No. We interpret RFC 5280's language of "adding zero or more labels"
//        to mean that whole labels must be prefixed.
//
//     (Note that the above three scenarios are the same as the RFC 6265
//     domain matching rules [0].)
//
//     Q: Is a name constraint that starts with "." valid, and if so, what
//        semantics does it have? For example, does a presented ID of
//        "www.example.com" match a constraint of ".example.com"? Does a
//        presented ID of "example.com" match a constraint of ".example.com"?
//     A: This implementation, NSS[1], and SChannel[2] all support a
//        leading ".", but OpenSSL[3] does not yet. Amongst the
//        implementations that support it, a leading "." is legal and means
//        the same thing as when the "." is omitted, EXCEPT that a
//        presented identifier equal (case insensitive) to the name
//        constraint is not matched; i.e. presented DNSName identifiers
//        must be subdomains. Some CAs in Mozilla's CA program (e.g. HARICA)
//        have name constraints with the leading "." in their root
//        certificates. The name constraints imposed on DCISS by Mozilla also
//        have the it, so supporting this is a requirement for backward
//        compatibility, even if it is not yet standardized. So, for example, a
//        presented ID of "www.example.com" matches a constraint of
//        ".example.com" but a presented ID of "example.com" does not.
//
//     Q: Is there a way to prevent subdomain matches?
//     A: Yes.
//
//        Some people have proposed that dNSName constraints that do not
//        start with a "." should be restricted to exact (case insensitive)
//        matches. However, such a change of semantics from what RFC5280
//        specifies would be a non-backward-compatible change in the case of
//        permittedSubtrees constraints, and it would be a security issue for
//        excludedSubtrees constraints.
//
//        However, it can be done with a combination of permittedSubtrees and
//        excludedSubtrees, e.g. "example.com" in permittedSubtrees and
//        ".example.com" in excudedSubtrees.
//
//     Q: Are name constraints allowed to be specified as absolute names?
//        For example, does a presented ID of "example.com" match a name
//        constraint of "example.com." and vice versa.
//     A: Absolute names are not supported as presented IDs or name
//        constraints. Only reference IDs may be absolute.
//
//     Q: Is "" a valid DNSName constraints? If so, what does it mean?
//     A: Yes. Any valid presented DNSName can be formed "by simply adding zero
//        or more labels to the left-hand side" of "". In particular, an
//        excludedSubtrees DNSName constraint of "" forbids all DNSNames.
//
//     Q: Is "." a valid DNSName constraints? If so, what does it mean?
//     A: No, because absolute names are not allowed (see above).
//
// [0] RFC 6265 (Cookies) Domain Matching rules:
//     http://tools.ietf.org/html/rfc6265#section-5.1.3
// [1] NSS source code:
//     https://mxr.mozilla.org/nss/source/lib/certdb/genname.c?rev=2a7348f013cb#1209
// [2] Description of SChannel's behavior from Microsoft:
//     http://www.imc.org/ietf-pkix/mail-archive/msg04668.html
// [3] Proposal to add such support to OpenSSL:
//     http://www.mail-archive.com/openssl-dev%40openssl.org/msg36204.html
//     https://rt.openssl.org/Ticket/Display.html?id=3562
// [4] Feedback on the lack of clarify in the definition that never got
//     incorporated into the spec:
//     https://www.ietf.org/mail-archive/web/pkix/current/msg21192.html
Result
MatchPresentedDNSIDWithReferenceDNSID(
  Input presentedDNSID,
  AllowWildcards allowWildcards,
  AllowDotlessSubdomainMatches allowDotlessSubdomainMatches,
  IDRole referenceDNSIDRole,
  Input referenceDNSID,
  /*out*/ bool& matches)
{
  if (!IsValidDNSID(presentedDNSID, IDRole::PresentedID, allowWildcards)) {
    return Result::ERROR_BAD_DER;
  }

  if (!IsValidDNSID(referenceDNSID, referenceDNSIDRole, AllowWildcards::No)) {
    return Result::ERROR_BAD_DER;
  }

  Reader presented(presentedDNSID);
  Reader reference(referenceDNSID);

  switch (referenceDNSIDRole)
  {
    case IDRole::ReferenceID:
      break;

    case IDRole::NameConstraint:
    {
      if (presentedDNSID.GetLength() > referenceDNSID.GetLength()) {
        if (referenceDNSID.GetLength() == 0) {
          // An empty constraint matches everything.
          matches = true;
          return Success;
        }
        // If the reference ID starts with a dot then skip the prefix of
        // of the presented ID and start the comparison at the position of that
        // dot. Examples:
        //
        //                                       Matches     Doesn't Match
        //     -----------------------------------------------------------
        //       original presented ID:  www.example.com    badexample.com
        //                     skipped:  www                ba
        //     presented ID w/o prefix:     .example.com      dexample.com
        //                reference ID:     .example.com      .example.com
        //
        // If the reference ID does not start with a dot then we skip the
        // prefix of the presented ID but also verify that the prefix ends with
        // a dot. Examples:
        //
        //                                       Matches     Doesn't Match
        //     -----------------------------------------------------------
        //       original presented ID:  www.example.com    badexample.com
        //                     skipped:  www                ba
        //                 must be '.':     .                 d
        //     presented ID w/o prefix:      example.com       example.com
        //                reference ID:      example.com       example.com
        //
        if (reference.Peek('.')) {
          if (presented.Skip(static_cast<Input::size_type>(
                               presentedDNSID.GetLength() -
                                 referenceDNSID.GetLength())) != Success) {
            return NotReached("skipping subdomain failed",
                              Result::FATAL_ERROR_LIBRARY_FAILURE);
          }
        } else if (allowDotlessSubdomainMatches ==
                   AllowDotlessSubdomainMatches::Yes) {
          if (presented.Skip(static_cast<Input::size_type>(
                               presentedDNSID.GetLength() -
                                 referenceDNSID.GetLength() - 1)) != Success) {
            return NotReached("skipping subdomains failed",
                              Result::FATAL_ERROR_LIBRARY_FAILURE);
          }
          uint8_t b;
          if (presented.Read(b) != Success) {
            return NotReached("reading from presentedDNSID failed",
                              Result::FATAL_ERROR_LIBRARY_FAILURE);
          }
          if (b != '.') {
            matches = false;
            return Success;
          }
        }
      }
      break;
    }

    case IDRole::PresentedID: // fall through
      return NotReached("IDRole::PresentedID is not a valid referenceDNSIDRole",
                        Result::FATAL_ERROR_INVALID_ARGS);
  }

  // We only allow wildcard labels that consist only of '*'.
  if (presented.Peek('*')) {
    if (presented.Skip(1) != Success) {
      return NotReached("Skipping '*' failed",
                        Result::FATAL_ERROR_LIBRARY_FAILURE);
    }
    do {
      // This will happen if reference is a single, relative label
      if (reference.AtEnd()) {
        matches = false;
        return Success;
      }
      uint8_t referenceByte;
      if (reference.Read(referenceByte) != Success) {
        return NotReached("invalid reference ID",
                          Result::FATAL_ERROR_INVALID_ARGS);
      }
    } while (!reference.Peek('.'));
  }

  for (;;) {
    uint8_t presentedByte;
    if (presented.Read(presentedByte) != Success) {
      matches = false;
      return Success;
    }
    uint8_t referenceByte;
    if (reference.Read(referenceByte) != Success) {
      matches = false;
      return Success;
    }
    if (LocaleInsensitveToLower(presentedByte) !=
        LocaleInsensitveToLower(referenceByte)) {
      matches = false;
      return Success;
    }
    if (presented.AtEnd()) {
      // Don't allow presented IDs to be absolute.
      if (presentedByte == '.') {
        return Result::ERROR_BAD_DER;
      }
      break;
    }
  }

  // Allow a relative presented DNS ID to match an absolute reference DNS ID,
  // unless we're matching a name constraint.
  if (!reference.AtEnd()) {
    if (referenceDNSIDRole != IDRole::NameConstraint) {
      uint8_t referenceByte;
      if (reference.Read(referenceByte) != Success) {
        return NotReached("read failed but not at end",
                          Result::FATAL_ERROR_LIBRARY_FAILURE);
      }
      if (referenceByte != '.') {
        matches = false;
        return Success;
      }
    }
    if (!reference.AtEnd()) {
      matches = false;
      return Success;
    }
  }

  matches = true;
  return Success;
}

// https://tools.ietf.org/html/rfc5280#section-4.2.1.10 says:
//
//     For IPv4 addresses, the iPAddress field of GeneralName MUST contain
//     eight (8) octets, encoded in the style of RFC 4632 (CIDR) to represent
//     an address range [RFC4632].  For IPv6 addresses, the iPAddress field
//     MUST contain 32 octets similarly encoded.  For example, a name
//     constraint for "class C" subnet 192.0.2.0 is represented as the
//     octets C0 00 02 00 FF FF FF 00, representing the CIDR notation
//     192.0.2.0/24 (mask 255.255.255.0).
Result
MatchPresentedIPAddressWithConstraint(Input presentedID,
                                      Input iPAddressConstraint,
                                      /*out*/ bool& foundMatch)
{
  if (presentedID.GetLength() != 4 && presentedID.GetLength() != 16) {
    return Result::ERROR_BAD_DER;
  }
  if (iPAddressConstraint.GetLength() != 8 &&
      iPAddressConstraint.GetLength() != 32) {
    return Result::ERROR_BAD_DER;
  }

  // an IPv4 address never matches an IPv6 constraint, and vice versa.
  if (presentedID.GetLength() * 2 != iPAddressConstraint.GetLength()) {
    foundMatch = false;
    return Success;
  }

  Reader constraint(iPAddressConstraint);
  Reader constraintAddress;
  Result rv = constraint.Skip(iPAddressConstraint.GetLength() / 2u,
                              constraintAddress);
  if (rv != Success) {
    return rv;
  }
  Reader constraintMask;
  rv = constraint.Skip(iPAddressConstraint.GetLength() / 2u, constraintMask);
  if (rv != Success) {
    return rv;
  }
  rv = der::End(constraint);
  if (rv != Success) {
    return rv;
  }

  Reader presented(presentedID);
  do {
    uint8_t presentedByte;
    rv = presented.Read(presentedByte);
    if (rv != Success) {
      return rv;
    }
    uint8_t constraintAddressByte;
    rv = constraintAddress.Read(constraintAddressByte);
    if (rv != Success) {
      return rv;
    }
    uint8_t constraintMaskByte;
    rv = constraintMask.Read(constraintMaskByte);
    if (rv != Success) {
      return rv;
    }
    foundMatch =
      ((presentedByte ^ constraintAddressByte) & constraintMaskByte) == 0;
  } while (foundMatch && !presented.AtEnd());

  return Success;
}

// AttributeTypeAndValue ::= SEQUENCE {
//   type     AttributeType,
//   value    AttributeValue }
//
// AttributeType ::= OBJECT IDENTIFIER
//
// AttributeValue ::= ANY -- DEFINED BY AttributeType
Result
ReadAVA(Reader& rdn,
        /*out*/ Input& type,
        /*out*/ uint8_t& valueTag,
        /*out*/ Input& value)
{
  return der::Nested(rdn, der::SEQUENCE, [&](Reader& ava) -> Result {
    Result rv = der::ExpectTagAndGetValue(ava, der::OIDTag, type);
    if (rv != Success) {
      return rv;
    }
    rv = der::ReadTagAndGetValue(ava, valueTag, value);
    if (rv != Success) {
      return rv;
    }
    return Success;
  });
}

// Names are sequences of RDNs. RDNS are sets of AVAs. That means that RDNs are
// unordered, so in theory we should match RDNs with equivalent AVAs that are
// in different orders. Within the AVAs are DirectoryNames that are supposed to
// be compared according to LDAP stringprep normalization rules (e.g.
// normalizing whitespace), consideration of different character encodings,
// etc. Indeed, RFC 5280 says we MUST deal with all of that.
//
// In practice, many implementations, including NSS, only match Names in a way
// that only meets a subset of the requirements of RFC 5280. Those
// normalization and character encoding conversion steps appear to be
// unnecessary for processing real-world certificates, based on experience from
// having used NSS in Firefox for many years.
//
// RFC 5280 also says "CAs issuing certificates with a restriction of the form
// directoryName SHOULD NOT rely on implementation of the full
// ISO DN name comparison algorithm. This implies name restrictions MUST
// be stated identically to the encoding used in the subject field or
// subjectAltName extension." It goes on to say, in the security
// considerations:
//
//     In addition, name constraints for distinguished names MUST be stated
//     identically to the encoding used in the subject field or
//     subjectAltName extension.  If not, then name constraints stated as
//     excludedSubtrees will not match and invalid paths will be accepted
//     and name constraints expressed as permittedSubtrees will not match
//     and valid paths will be rejected.  To avoid acceptance of invalid
//     paths, CAs SHOULD state name constraints for distinguished names as
//     permittedSubtrees wherever possible.
//
// For permittedSubtrees, the MUST-level requirement is relaxed for
// compatibility in the case of PrintableString and UTF8String. That is, if a
// name constraint has been encoded using UTF8String and the presented ID has
// been encoded with a PrintableString (or vice-versa), they are considered to
// match if they are equal everywhere except for the tag identifying the
// encoding. See bug 1150114.
//
// For excludedSubtrees, we simply prohibit any non-empty directoryName
// constraint to ensure we are not being too lenient. We support empty
// DirectoryName constraints in excludedSubtrees so that a CA can say "Do not
// allow any DirectoryNames in issued certificates."
Result
MatchPresentedDirectoryNameWithConstraint(NameConstraintsSubtrees subtreesType,
                                          Input presentedID,
                                          Input directoryNameConstraint,
                                          /*out*/ bool& matches)
{
  Reader constraintRDNs;
  Result rv = der::ExpectTagAndGetValueAtEnd(directoryNameConstraint,
                                             der::SEQUENCE, constraintRDNs);
  if (rv != Success) {
    return rv;
  }
  Reader presentedRDNs;
  rv = der::ExpectTagAndGetValueAtEnd(presentedID, der::SEQUENCE,
                                      presentedRDNs);
  if (rv != Success) {
    return rv;
  }

  switch (subtreesType) {
    case NameConstraintsSubtrees::permittedSubtrees:
      break; // dealt with below
    case NameConstraintsSubtrees::excludedSubtrees:
      if (!constraintRDNs.AtEnd() || !presentedRDNs.AtEnd()) {
        return Result::ERROR_CERT_NOT_IN_NAME_SPACE;
      }
      matches = true;
      return Success;
  }

  for (;;) {
    // The AVAs have to be fully equal, but the constraint RDNs just need to be
    // a prefix of the presented RDNs.
    if (constraintRDNs.AtEnd()) {
      matches = true;
      return Success;
    }
    if (presentedRDNs.AtEnd()) {
      matches = false;
      return Success;
    }
    Reader constraintRDN;
    rv = der::ExpectTagAndGetValue(constraintRDNs, der::SET, constraintRDN);
    if (rv != Success) {
      return rv;
    }
    Reader presentedRDN;
    rv = der::ExpectTagAndGetValue(presentedRDNs, der::SET, presentedRDN);
    if (rv != Success) {
      return rv;
    }
    while (!constraintRDN.AtEnd() && !presentedRDN.AtEnd()) {
      Input constraintType;
      uint8_t constraintValueTag;
      Input constraintValue;
      rv = ReadAVA(constraintRDN, constraintType, constraintValueTag,
                   constraintValue);
      if (rv != Success) {
        return rv;
      }
      Input presentedType;
      uint8_t presentedValueTag;
      Input presentedValue;
      rv = ReadAVA(presentedRDN, presentedType, presentedValueTag,
                   presentedValue);
      if (rv != Success) {
        return rv;
      }
      // TODO (bug 1155767): verify that if an AVA is a PrintableString it
      // consists only of characters valid for PrintableStrings.
      bool avasMatch =
        InputsAreEqual(constraintType, presentedType) &&
        InputsAreEqual(constraintValue, presentedValue) &&
        (constraintValueTag == presentedValueTag ||
         (constraintValueTag == der::Tag::UTF8String &&
          presentedValueTag == der::Tag::PrintableString) ||
         (constraintValueTag == der::Tag::PrintableString &&
          presentedValueTag == der::Tag::UTF8String));
      if (!avasMatch) {
        matches = false;
        return Success;
      }
    }
    if (!constraintRDN.AtEnd() || !presentedRDN.AtEnd()) {
      matches = false;
      return Success;
    }
  }
}

// RFC 5280 says:
//
//     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.
//
// and:
//
//     A name constraint for Internet mail addresses MAY specify a
//     particular mailbox, all addresses at a particular host, or all
//     mailboxes in a domain.  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".  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".  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".

bool
IsValidRFC822Name(Input input)
{
  Reader reader(input);

  // Local-part@.
  bool startOfAtom = true;
  for (;;) {
    uint8_t presentedByte;
    if (reader.Read(presentedByte) != Success) {
      return false;
    }
    switch (presentedByte) {
      // atext is defined in https://tools.ietf.org/html/rfc2822#section-3.2.4
      case 'A': case 'a': case 'N': case 'n': case '0': case '!': case '#':
      case 'B': case 'b': case 'O': case 'o': case '1': case '$': case '%':
      case 'C': case 'c': case 'P': case 'p': case '2': case '&': case '\'':
      case 'D': case 'd': case 'Q': case 'q': case '3': case '*': case '+':
      case 'E': case 'e': case 'R': case 'r': case '4': case '-': case '/':
      case 'F': case 'f': case 'S': case 's': case '5': case '=': case '?':
      case 'G': case 'g': case 'T': case 't': case '6': case '^': case '_':
      case 'H': case 'h': case 'U': case 'u': case '7': case '`': case '{':
      case 'I': case 'i': case 'V': case 'v': case '8': case '|': case '}':
      case 'J': case 'j': case 'W': case 'w': case '9': case '~':
      case 'K': case 'k': case 'X': case 'x':
      case 'L': case 'l': case 'Y': case 'y':
      case 'M': case 'm': case 'Z': case 'z':
        startOfAtom = false;
        break;

      case '.':
        if (startOfAtom) {
          return false;
        }
        startOfAtom = true;
        break;

      case '@':
      {
        if (startOfAtom) {
          return false;
        }
        Input domain;
        if (reader.SkipToEnd(domain) != Success) {
          return false;
        }
        return IsValidDNSID(domain, IDRole::PresentedID, AllowWildcards::No);
      }

      default:
        return false;
    }
  }
}

Result
MatchPresentedRFC822NameWithReferenceRFC822Name(Input presentedRFC822Name,
                                                IDRole referenceRFC822NameRole,
                                                Input referenceRFC822Name,
                                                /*out*/ bool& matches)
{
  if (!IsValidRFC822Name(presentedRFC822Name)) {
    return Result::ERROR_BAD_DER;
  }
  Reader presented(presentedRFC822Name);

  switch (referenceRFC822NameRole)
  {
    case IDRole::PresentedID:
      return Result::FATAL_ERROR_INVALID_ARGS;

    case IDRole::ReferenceID:
      break;

    case IDRole::NameConstraint:
    {
      if (InputContains(referenceRFC822Name, '@')) {
        // The constraint is of the form "Local-part@Domain".
        break;
      }

      // The constraint is of the form "example.com" or ".example.com".

      // Skip past the '@' in the presented ID.
      for (;;) {
        uint8_t presentedByte;
        if (presented.Read(presentedByte) != Success) {
          return Result::FATAL_ERROR_LIBRARY_FAILURE;
        }
        if (presentedByte == '@') {
          break;
        }
      }

      Input presentedDNSID;
      if (presented.SkipToEnd(presentedDNSID) != Success) {
        return Result::FATAL_ERROR_LIBRARY_FAILURE;
      }

      return MatchPresentedDNSIDWithReferenceDNSID(
               presentedDNSID, AllowWildcards::No,
               AllowDotlessSubdomainMatches::No, IDRole::NameConstraint,
               referenceRFC822Name, matches);
    }
  }

  if (!IsValidRFC822Name(referenceRFC822Name)) {
    return Result::ERROR_BAD_DER;
  }

  Reader reference(referenceRFC822Name);

  for (;;) {
    uint8_t presentedByte;
    if (presented.Read(presentedByte) != Success) {
      matches = reference.AtEnd();
      return Success;
    }
    uint8_t referenceByte;
    if (reference.Read(referenceByte) != Success) {
      matches = false;
      return Success;
    }
    if (LocaleInsensitveToLower(presentedByte) !=
        LocaleInsensitveToLower(referenceByte)) {
      matches = false;
      return Success;
    }
  }
}

// We avoid isdigit because it is locale-sensitive. See
// http://pubs.opengroup.org/onlinepubs/009695399/functions/tolower.html.
inline uint8_t
LocaleInsensitveToLower(uint8_t a)
{
  if (a >= 'A' && a <= 'Z') { // unlikely
    return static_cast<uint8_t>(
             static_cast<uint8_t>(a - static_cast<uint8_t>('A')) +
             static_cast<uint8_t>('a'));
  }
  return a;
}

bool
StartsWithIDNALabel(Input id)
{
  static const uint8_t IDN_ALABEL_PREFIX[4] = { 'x', 'n', '-', '-' };
  Reader input(id);
  for (const uint8_t prefixByte : IDN_ALABEL_PREFIX) {
    uint8_t b;
    if (input.Read(b) != Success) {
      return false;
    }
    if (b != prefixByte) {
      return false;
    }
  }
  return true;
}

bool
ReadIPv4AddressComponent(Reader& input, bool lastComponent,
                         /*out*/ uint8_t& valueOut)
{
  size_t length = 0;
  unsigned int value = 0; // Must be larger than uint8_t.

  for (;;) {
    if (input.AtEnd() && lastComponent) {
      break;
    }

    uint8_t b;
    if (input.Read(b) != Success) {
      return false;
    }

    if (b >= '0' && b <= '9') {
      if (value == 0 && length > 0) {
        return false; // Leading zeros are not allowed.
      }
      value = (value * 10) + (b - '0');
      if (value > 255) {
        return false; // Component's value is too large.
      }
      ++length;
    } else if (!lastComponent && b == '.') {
      break;
    } else {
      return false; // Invalid character.
    }
  }

  if (length == 0) {
    return false; // empty components not allowed
  }

  valueOut = static_cast<uint8_t>(value);
  return true;
}

} // namespace

// On Windows and maybe other platforms, OS-provided IP address parsing
// functions might fail if the protocol (IPv4 or IPv6) has been disabled, so we
// can't rely on them.
bool
ParseIPv4Address(Input hostname, /*out*/ uint8_t (&out)[4])
{
  Reader input(hostname);
  return ReadIPv4AddressComponent(input, false, out[0]) &&
         ReadIPv4AddressComponent(input, false, out[1]) &&
         ReadIPv4AddressComponent(input, false, out[2]) &&
         ReadIPv4AddressComponent(input, true, out[3]);
}

namespace {

bool
FinishIPv6Address(/*in/out*/ uint8_t (&address)[16], int numComponents,
                  int contractionIndex)
{
  assert(numComponents >= 0);
  assert(numComponents <= 8);
  assert(contractionIndex >= -1);
  assert(contractionIndex <= 8);
  assert(contractionIndex <= numComponents);
  if (!(numComponents >= 0 &&
        numComponents <= 8 &&
        contractionIndex >= -1 &&
        contractionIndex <= 8 &&
        contractionIndex <= numComponents)) {
    return false;
  }

  if (contractionIndex == -1) {
    // no contraction
    return numComponents == 8;
  }

  if (numComponents >= 8) {
    return false; // no room left to expand the contraction.
  }

  // Shift components that occur after the contraction over.
  std::copy_backward(address + (2u * static_cast<size_t>(contractionIndex)),
                     address + (2u * static_cast<size_t>(numComponents)),
                     address + (2u * 8u));
  // Fill in the contracted area with zeros.
  std::fill_n(address + 2u * static_cast<size_t>(contractionIndex),
              (8u - static_cast<size_t>(numComponents)) * 2u, static_cast<uint8_t>(0u));

  return true;
}

} // namespace

// On Windows and maybe other platforms, OS-provided IP address parsing
// functions might fail if the protocol (IPv4 or IPv6) has been disabled, so we
// can't rely on them.
bool
ParseIPv6Address(Input hostname, /*out*/ uint8_t (&out)[16])
{
  Reader input(hostname);

  int currentComponentIndex = 0;
  int contractionIndex = -1;

  if (input.Peek(':')) {
    // A valid input can only start with ':' if there is a contraction at the
    // beginning.
    uint8_t b;
    if (input.Read(b) != Success || b != ':') {
      assert(false);
      return false;
    }
    if (input.Read(b) != Success) {
      return false;
    }
    if (b != ':') {
      return false;
    }
    contractionIndex = 0;
  }

  for (;;) {
    // If we encounter a '.' then we'll have to backtrack to parse the input
    // from startOfComponent to the end of the input as an IPv4 address.
    Reader::Mark startOfComponent(input.GetMark());
    uint16_t componentValue = 0;
    size_t componentLength = 0;
    while (!input.AtEnd() && !input.Peek(':')) {
      uint8_t value;
      uint8_t b;
      if (input.Read(b) != Success) {
        assert(false);
        return false;
      }
      switch (b) {
        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
          value = static_cast<uint8_t>(b - static_cast<uint8_t>('0'));
          break;
        case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
          value = static_cast<uint8_t>(b - static_cast<uint8_t>('a') +
                                       UINT8_C(10));
          break;
        case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
          value = static_cast<uint8_t>(b - static_cast<uint8_t>('A') +
                                       UINT8_C(10));
          break;
        case '.':
        {
          // A dot indicates we hit a IPv4-syntax component. Backtrack, parsing
          // the input from startOfComponent to the end of the input as an IPv4
          // address, and then combine it with the other components.

          if (currentComponentIndex > 6) {
            return false; // Too many components before the IPv4 component
          }

          input.SkipToEnd();
          Input ipv4Component;
          if (input.GetInput(startOfComponent, ipv4Component) != Success) {
            return false;
          }
          uint8_t (*ipv4)[4] =
            reinterpret_cast<uint8_t(*)[4]>(&out[2 * currentComponentIndex]);
          if (!ParseIPv4Address(ipv4Component, *ipv4)) {
            return false;
          }
          assert(input.AtEnd());
          currentComponentIndex += 2;

          return FinishIPv6Address(out, currentComponentIndex,
                                   contractionIndex);
        }
        default:
          return false;
      }
      if (componentLength >= 4) {
        // component too long
        return false;
      }
      ++componentLength;
      componentValue = (componentValue * 0x10u) + value;
    }

    if (currentComponentIndex >= 8) {
      return false; // too many components
    }

    if (componentLength == 0) {
      if (input.AtEnd() && currentComponentIndex == contractionIndex) {
        if (contractionIndex == 0) {
          // don't accept "::"
          return false;
        }
        return FinishIPv6Address(out, currentComponentIndex,
                                 contractionIndex);
      }
      return false;
    }

    out[2 * currentComponentIndex] =
      static_cast<uint8_t>(componentValue / 0x100);
    out[(2 * currentComponentIndex) + 1] =
      static_cast<uint8_t>(componentValue % 0x100);

    ++currentComponentIndex;

    if (input.AtEnd()) {
      return FinishIPv6Address(out, currentComponentIndex,
                               contractionIndex);
    }

    uint8_t b;
    if (input.Read(b) != Success || b != ':') {
      assert(false);
      return false;
    }

    if (input.Peek(':')) {
      // Contraction
      if (contractionIndex != -1) {
        return false; // multiple contractions are not allowed.
      }
      if (input.Read(b) != Success || b != ':') {
        assert(false);
        return false;
      }
      contractionIndex = currentComponentIndex;
      if (input.AtEnd()) {
        // "::" at the end of the input.
        return FinishIPv6Address(out, currentComponentIndex,
                                 contractionIndex);
      }
    }
  }
}

bool
IsValidReferenceDNSID(Input hostname)
{
  return IsValidDNSID(hostname, IDRole::ReferenceID, AllowWildcards::No);
}

bool
IsValidPresentedDNSID(Input hostname)
{
  return IsValidDNSID(hostname, IDRole::PresentedID, AllowWildcards::Yes);
}

namespace {

// RFC 5280 Section 4.2.1.6 says that a dNSName "MUST be in the 'preferred name
// syntax', as specified by Section 3.5 of [RFC1034] and as modified by Section
// 2.1 of [RFC1123]" except "a dNSName of ' ' MUST NOT be used." Additionally,
// we allow underscores for compatibility with existing practice.
bool
IsValidDNSID(Input hostname, IDRole idRole, AllowWildcards allowWildcards)
{
  if (hostname.GetLength() > 253) {
    return false;
  }

  Reader input(hostname);

  if (idRole == IDRole::NameConstraint && input.AtEnd()) {
    return true;
  }

  size_t dotCount = 0;
  size_t labelLength = 0;
  bool labelIsAllNumeric = false;
  bool labelEndsWithHyphen = false;

  // Only presented IDs are allowed to have wildcard labels. And, like
  // Chromium, be stricter than RFC 6125 requires by insisting that a
  // wildcard label consist only of '*'.
  bool isWildcard = allowWildcards == AllowWildcards::Yes && input.Peek('*');
  bool isFirstByte = !isWildcard;
  if (isWildcard) {
    Result rv = input.Skip(1);
    if (rv != Success) {
      assert(false);
      return false;
    }

    uint8_t b;
    rv = input.Read(b);
    if (rv != Success) {
      return false;
    }
    if (b != '.') {
      return false;
    }
    ++dotCount;
  }

  do {
    static const size_t MAX_LABEL_LENGTH = 63;

    uint8_t b;
    if (input.Read(b) != Success) {
      return false;
    }
    switch (b) {
      case '-':
        if (labelLength == 0) {
          return false; // Labels must not start with a hyphen.
        }
        labelIsAllNumeric = false;
        labelEndsWithHyphen = true;
        ++labelLength;
        if (labelLength > MAX_LABEL_LENGTH) {
          return false;
        }
        break;

      // We avoid isdigit because it is locale-sensitive. See
      // http://pubs.opengroup.org/onlinepubs/009695399/functions/isdigit.html
      case '0': case '5':
      case '1': case '6':
      case '2': case '7':
      case '3': case '8':
      case '4': case '9':
        if (labelLength == 0) {
          labelIsAllNumeric = true;
        }
        labelEndsWithHyphen = false;
        ++labelLength;
        if (labelLength > MAX_LABEL_LENGTH) {
          return false;
        }
        break;

      // We avoid using islower/isupper/tolower/toupper or similar things, to
      // avoid any possibility of this code being locale-sensitive. See
      // http://pubs.opengroup.org/onlinepubs/009695399/functions/isupper.html
      case 'a': case 'A': case 'n': case 'N':
      case 'b': case 'B': case 'o': case 'O':
      case 'c': case 'C': case 'p': case 'P':
      case 'd': case 'D': case 'q': case 'Q':
      case 'e': case 'E': case 'r': case 'R':
      case 'f': case 'F': case 's': case 'S':
      case 'g': case 'G': case 't': case 'T':
      case 'h': case 'H': case 'u': case 'U':
      case 'i': case 'I': case 'v': case 'V':
      case 'j': case 'J': case 'w': case 'W':
      case 'k': case 'K': case 'x': case 'X':
      case 'l': case 'L': case 'y': case 'Y':
      case 'm': case 'M': case 'z': case 'Z':
      // We allow underscores for compatibility with existing practices.
      // See bug 1136616.
      case '_':
        labelIsAllNumeric = false;
        labelEndsWithHyphen = false;
        ++labelLength;
        if (labelLength > MAX_LABEL_LENGTH) {
          return false;
        }
        break;

      case '.':
        ++dotCount;
        if (labelLength == 0 &&
            (idRole != IDRole::NameConstraint || !isFirstByte)) {
          return false;
        }
        if (labelEndsWithHyphen) {
          return false; // Labels must not end with a hyphen.
        }
        labelLength = 0;
        break;

      default:
        return false; // Invalid character.
    }
    isFirstByte = false;
  } while (!input.AtEnd());

  // Only reference IDs, not presented IDs or name constraints, may be
  // absolute.
  if (labelLength == 0 && idRole != IDRole::ReferenceID) {
    return false;
  }

  if (labelEndsWithHyphen) {
    return false; // Labels must not end with a hyphen.
  }

  if (labelIsAllNumeric) {
    return false; // Last label must not be all numeric.
  }

  if (isWildcard) {
    // If the DNS ID ends with a dot, the last dot signifies an absolute ID.
    size_t labelCount = (labelLength == 0) ? dotCount : (dotCount + 1);

    // Like NSS, require at least two labels to follow the wildcard label.
    //
    // TODO(bug XXXXXXX): Allow the TrustDomain to control this on a
    // per-eTLD+1 basis, similar to Chromium. Even then, it might be better to
    // still enforce that there are at least two labels after the wildcard.
    if (labelCount < 3) {
      return false;
    }
    // XXX: RFC6125 says that we shouldn't accept wildcards within an IDN
    // A-Label. The consequence of this is that we effectively discriminate
    // against users of languages that cannot be encoded with ASCII.
    if (StartsWithIDNALabel(hostname)) {
      return false;
    }

    // TODO(bug XXXXXXX): Wildcards are not allowed for EV certificates.
    // Provide an option to indicate whether wildcards should be matched, for
    // the purpose of helping the application enforce this.
  }

  return true;
}

} // namespace

} } // namespace mozilla::pkix
