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

#include "net/cert/internal/verify_name_match.h"

#include "base/logging.h"
#include "base/strings/string_util.h"
#include "net/cert/internal/cert_error_params.h"
#include "net/cert/internal/cert_errors.h"
#include "net/cert/internal/parse_name.h"
#include "net/der/input.h"
#include "net/der/parser.h"
#include "net/der/tag.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"

namespace net {

DEFINE_CERT_ERROR_ID(kFailedConvertingAttributeValue,
                     "Failed converting AttributeValue to string");
DEFINE_CERT_ERROR_ID(kFailedNormalizingString, "Failed normalizing string");

namespace {

// RFC 5280 section A.1:
//
// pkcs-9 OBJECT IDENTIFIER ::=
//   { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 }
//
// id-emailAddress      AttributeType ::= { pkcs-9 1 }
//
// In dotted form: 1.2.840.113549.1.9.1
const uint8_t kOidEmailAddress[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
                                    0x0D, 0x01, 0x09, 0x01};

// Types of character set checking that NormalizeDirectoryString can perform.
enum CharsetEnforcement {
  NO_ENFORCEMENT,
  ENFORCE_PRINTABLE_STRING,
  ENFORCE_ASCII,
};

// Normalizes |output|, a UTF-8 encoded string, as if it contained
// only ASCII characters.
//
// This could be considered a partial subset of RFC 5280 rules, and
// is compatible with RFC 2459/3280.
//
// In particular, RFC 5280, Section 7.1 describes how UTF8String
// and PrintableString should be compared - using the LDAP StringPrep
// profile of RFC 4518, with case folding and whitespace compression.
// However, because it is optional for 2459/3280 implementations and because
// it's desirable to avoid the size cost of the StringPrep tables,
// this function treats |output| as if it was composed of ASCII.
//
// That is, rather than folding all whitespace characters, it only
// folds ' '. Rather than case folding using locale-aware handling,
// it only folds A-Z to a-z.
//
// This gives better results than outright rejecting (due to mismatched
// encodings), or from doing a strict binary comparison (the minimum
// required by RFC 3280), and is sufficient for those certificates
// publicly deployed.
//
// If |charset_enforcement| is not NO_ENFORCEMENT and |output| contains any
// characters not allowed in the specified charset, returns false.
//
// NOTE: |output| will be modified regardless of the return.
WARN_UNUSED_RESULT bool NormalizeDirectoryString(
    CharsetEnforcement charset_enforcement,
    std::string* output) {
  // Normalized version will always be equal or shorter than input.
  // Normalize in place and then truncate the output if necessary.
  std::string::const_iterator read_iter = output->begin();
  std::string::iterator write_iter = output->begin();

  for (; read_iter != output->end() && *read_iter == ' '; ++read_iter) {
    // Ignore leading whitespace.
  }

  for (; read_iter != output->end(); ++read_iter) {
    const unsigned char c = *read_iter;
    if (c == ' ') {
      // If there are non-whitespace characters remaining in input, compress
      // multiple whitespace chars to a single space, otherwise ignore trailing
      // whitespace.
      std::string::const_iterator next_iter = read_iter + 1;
      if (next_iter != output->end() && *next_iter != ' ')
        *(write_iter++) = ' ';
    } else if (base::IsAsciiUpper(c)) {
      // Fold case.
      *(write_iter++) = c + ('a' - 'A');
    } else {
      // Note that these checks depend on the characters allowed by earlier
      // conditions also being valid for the enforced charset.
      switch (charset_enforcement) {
        case ENFORCE_PRINTABLE_STRING:
          // See NormalizePrintableStringValue comment for the acceptable list
          // of characters.
          if (!(base::IsAsciiLower(c) || (c >= '\'' && c <= ':') || c == '=' ||
                c == '?'))
            return false;
          break;
        case ENFORCE_ASCII:
          if (c > 0x7F)
            return false;
          break;
        case NO_ENFORCEMENT:
          break;
      }
      *(write_iter++) = c;
    }
  }
  if (write_iter != output->end())
    output->erase(write_iter, output->end());
  return true;
}

// Converts the value of X509NameAttribute |attribute| to UTF-8, normalizes it,
// and stores in |output|. The type of |attribute| must be one of the types for
// which IsNormalizableDirectoryString is true.
//
// If the value of |attribute| can be normalized, returns true and sets
// |output| to the case folded, normalized value. If the value of |attribute|
// is invalid, returns false.
// NOTE: |output| will be modified regardless of the return.
WARN_UNUSED_RESULT bool NormalizeValue(X509NameAttribute attribute,
                                       std::string* output,
                                       CertErrors* errors) {
  DCHECK(errors);

  if (!attribute.ValueAsStringUnsafe(output)) {
    errors->AddError(kFailedConvertingAttributeValue,
                     CreateCertErrorParams1SizeT("tag", attribute.value_tag));
    return false;
  }

  bool success = false;
  switch (attribute.value_tag) {
    case der::kPrintableString:
      success = NormalizeDirectoryString(ENFORCE_PRINTABLE_STRING, output);
      break;
    case der::kBmpString:
    case der::kUniversalString:
    case der::kUtf8String:
      success = NormalizeDirectoryString(NO_ENFORCEMENT, output);
      break;
    case der::kIA5String:
      success = NormalizeDirectoryString(ENFORCE_ASCII, output);
      break;
    default:
      NOTREACHED();
      success = false;
      break;
  }

  if (!success) {
    errors->AddError(kFailedNormalizingString,
                     CreateCertErrorParams1SizeT("tag", attribute.value_tag));
  }

  return success;
}

// Returns true if |tag| is a string type that NormalizeValue can handle.
bool IsNormalizableDirectoryString(der::Tag tag) {
  switch (tag) {
    case der::kPrintableString:
    case der::kUtf8String:
    // RFC 5280 only requires handling IA5String for comparing domainComponent
    // values, but handling it here avoids the need to special case anything.
    case der::kIA5String:
    case der::kUniversalString:
    case der::kBmpString:
      return true;
    // TeletexString isn't normalized. Section 8 of RFC 5280 briefly
    // describes the historical confusion between treating TeletexString
    // as Latin1String vs T.61, and there are even incompatibilities within
    // T.61 implementations. As this time is virtually unused, simply
    // treat it with a binary comparison, as permitted by RFC 3280/5280.
    default:
      return false;
  }
}

// Returns true if the value of X509NameAttribute |a| matches |b|.
bool VerifyValueMatch(X509NameAttribute a, X509NameAttribute b) {
  if (IsNormalizableDirectoryString(a.value_tag) &&
      IsNormalizableDirectoryString(b.value_tag)) {
    std::string a_normalized, b_normalized;
    // TODO(eroman): Plumb this down.
    CertErrors unused_errors;
    if (!NormalizeValue(a, &a_normalized, &unused_errors) ||
        !NormalizeValue(b, &b_normalized, &unused_errors))
      return false;
    return a_normalized == b_normalized;
  }
  // Attributes encoded with different types may be assumed to be unequal.
  if (a.value_tag != b.value_tag)
    return false;
  // All other types use binary comparison.
  return a.value == b.value;
}

// Verifies that |a_parser| and |b_parser| are the same length and that every
// AttributeTypeAndValue in |a_parser| has a matching AttributeTypeAndValue in
// |b_parser|.
bool VerifyRdnMatch(der::Parser* a_parser, der::Parser* b_parser) {
  RelativeDistinguishedName a_type_and_values, b_type_and_values;
  if (!ReadRdn(a_parser, &a_type_and_values) ||
      !ReadRdn(b_parser, &b_type_and_values))
    return false;

  // RFC 5280 section 7.1:
  // Two relative distinguished names RDN1 and RDN2 match if they have the same
  // number of naming attributes and for each naming attribute in RDN1 there is
  // a matching naming attribute in RDN2.
  if (a_type_and_values.size() != b_type_and_values.size())
    return false;

  // The ordering of elements may differ due to denormalized values sorting
  // differently in the DER encoding. Since the number of elements should be
  // small, a naive linear search for each element should be fine. (Hostile
  // certificates already have ways to provoke pathological behavior.)
  for (const auto& a : a_type_and_values) {
    auto b_iter = b_type_and_values.begin();
    for (; b_iter != b_type_and_values.end(); ++b_iter) {
      const auto& b = *b_iter;
      if (a.type == b.type && VerifyValueMatch(a, b)) {
        break;
      }
    }
    if (b_iter == b_type_and_values.end())
      return false;
    // Remove the matched element from b_type_and_values to ensure duplicate
    // elements in a_type_and_values can't match the same element in
    // b_type_and_values multiple times.
    b_type_and_values.erase(b_iter);
  }

  // Every element in |a_type_and_values| had a matching element in
  // |b_type_and_values|.
  return true;
}

enum NameMatchType {
  EXACT_MATCH,
  SUBTREE_MATCH,
};

// Verify that |a| matches |b|. If |match_type| is EXACT_MATCH, returns true if
// they are an exact match as defined by RFC 5280 7.1. If |match_type| is
// SUBTREE_MATCH, returns true if |a| is within the subtree defined by |b| as
// defined by RFC 5280 7.1.
//
// |a| and |b| are ASN.1 RDNSequence values (not including the Sequence tag),
// defined in RFC 5280 section 4.1.2.4:
//
// Name ::= CHOICE { -- only one possibility for now --
//   rdnSequence  RDNSequence }
//
// RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
//
// RelativeDistinguishedName ::=
//   SET SIZE (1..MAX) OF AttributeTypeAndValue
bool VerifyNameMatchInternal(const der::Input& a,
                             const der::Input& b,
                             NameMatchType match_type) {
  // Empty Names are allowed.  RFC 5280 section 4.1.2.4 requires "The issuer
  // field MUST contain a non-empty distinguished name (DN)", while section
  // 4.1.2.6 allows for the Subject to be empty in certain cases. The caller is
  // assumed to have verified those conditions.

  // RFC 5280 section 7.1:
  // Two distinguished names DN1 and DN2 match if they have the same number of
  // RDNs, for each RDN in DN1 there is a matching RDN in DN2, and the matching
  // RDNs appear in the same order in both DNs.

  // As an optimization, first just compare the number of RDNs:
  der::Parser a_rdn_sequence_counter(a);
  der::Parser b_rdn_sequence_counter(b);
  while (a_rdn_sequence_counter.HasMore() && b_rdn_sequence_counter.HasMore()) {
    if (!a_rdn_sequence_counter.SkipTag(der::kSet) ||
        !b_rdn_sequence_counter.SkipTag(der::kSet)) {
      return false;
    }
  }
  // If doing exact match and either of the sequences has more elements than the
  // other, not a match. If doing a subtree match, the first Name may have more
  // RDNs than the second.
  if (b_rdn_sequence_counter.HasMore())
    return false;
  if (match_type == EXACT_MATCH && a_rdn_sequence_counter.HasMore())
    return false;

  // Verify that RDNs in |a| and |b| match.
  der::Parser a_rdn_sequence(a);
  der::Parser b_rdn_sequence(b);
  while (a_rdn_sequence.HasMore() && b_rdn_sequence.HasMore()) {
    der::Parser a_rdn, b_rdn;
    if (!a_rdn_sequence.ReadConstructed(der::kSet, &a_rdn) ||
        !b_rdn_sequence.ReadConstructed(der::kSet, &b_rdn)) {
      return false;
    }
    if (!VerifyRdnMatch(&a_rdn, &b_rdn))
      return false;
  }

  return true;
}

}  // namespace

bool NormalizeName(const der::Input& name_rdn_sequence,
                   std::string* normalized_rdn_sequence,
                   CertErrors* errors) {
  DCHECK(errors);

  // RFC 5280 section 4.1.2.4
  // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
  der::Parser rdn_sequence_parser(name_rdn_sequence);

  bssl::ScopedCBB cbb;
  if (!CBB_init(cbb.get(), 0))
    return false;

  while (rdn_sequence_parser.HasMore()) {
    // RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
    der::Parser rdn_parser;
    if (!rdn_sequence_parser.ReadConstructed(der::kSet, &rdn_parser))
      return false;
    RelativeDistinguishedName type_and_values;
    if (!ReadRdn(&rdn_parser, &type_and_values))
      return false;

    CBB rdn_cbb;
    if (!CBB_add_asn1(cbb.get(), &rdn_cbb, CBS_ASN1_SET))
      return false;

    for (const auto& type_and_value : type_and_values) {
      // AttributeTypeAndValue ::= SEQUENCE {
      //   type     AttributeType,
      //   value    AttributeValue }
      CBB attribute_type_and_value_cbb, type_cbb, value_cbb;
      if (!CBB_add_asn1(&rdn_cbb, &attribute_type_and_value_cbb,
                        CBS_ASN1_SEQUENCE)) {
        return false;
      }

      // AttributeType ::= OBJECT IDENTIFIER
      if (!CBB_add_asn1(&attribute_type_and_value_cbb, &type_cbb,
                        CBS_ASN1_OBJECT) ||
          !CBB_add_bytes(&type_cbb, type_and_value.type.UnsafeData(),
                         type_and_value.type.Length())) {
        return false;
      }

      // AttributeValue ::= ANY -- DEFINED BY AttributeType
      if (IsNormalizableDirectoryString(type_and_value.value_tag)) {
        std::string normalized_value;
        if (!NormalizeValue(type_and_value, &normalized_value, errors))
          return false;
        if (!CBB_add_asn1(&attribute_type_and_value_cbb, &value_cbb,
                          CBS_ASN1_UTF8STRING) ||
            !CBB_add_bytes(&value_cbb, reinterpret_cast<const uint8_t*>(
                                           normalized_value.data()),
                           normalized_value.size()))
          return false;
      } else {
        if (!CBB_add_asn1(&attribute_type_and_value_cbb, &value_cbb,
                          type_and_value.value_tag) ||
            !CBB_add_bytes(&value_cbb, type_and_value.value.UnsafeData(),
                           type_and_value.value.Length()))
          return false;
      }

      if (!CBB_flush(&rdn_cbb))
        return false;
    }

    // Ensure the encoded AttributeTypeAndValue values in the SET OF are sorted.
    if (!CBB_flush_asn1_set_of(&rdn_cbb) || !CBB_flush(cbb.get()))
      return false;
  }

  normalized_rdn_sequence->assign(CBB_data(cbb.get()),
                                  CBB_data(cbb.get()) + CBB_len(cbb.get()));
  return true;
}

bool VerifyNameMatch(const der::Input& a_rdn_sequence,
                     const der::Input& b_rdn_sequence) {
  return VerifyNameMatchInternal(a_rdn_sequence, b_rdn_sequence, EXACT_MATCH);
}

bool VerifyNameInSubtree(const der::Input& name_rdn_sequence,
                         const der::Input& parent_rdn_sequence) {
  return VerifyNameMatchInternal(name_rdn_sequence, parent_rdn_sequence,
                                 SUBTREE_MATCH);
}

bool NameContainsEmailAddress(const der::Input& name_rdn_sequence,
                              bool* contained_email_address) {
  der::Parser rdn_sequence_parser(name_rdn_sequence);

  while (rdn_sequence_parser.HasMore()) {
    der::Parser rdn_parser;
    if (!rdn_sequence_parser.ReadConstructed(der::kSet, &rdn_parser))
      return false;

    RelativeDistinguishedName type_and_values;
    if (!ReadRdn(&rdn_parser, &type_and_values))
      return false;

    for (const auto& type_and_value : type_and_values) {
      if (type_and_value.type == der::Input(kOidEmailAddress)) {
        *contained_email_address = true;
        return true;
      }
    }
  }

  *contained_email_address = false;
  return true;
}

}  // namespace net
