// Copyright (c) 2012 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/x509_cert_types.h"

#include <CoreServices/CoreServices.h>
#include <Security/SecAsn1Coder.h>
#include <Security/Security.h>

#include "base/i18n/icu_string_conversions.h"
#include "base/logging.h"
#include "base/mac/mac_logging.h"
#include "base/strings/utf_string_conversions.h"

namespace net {

namespace {

// The BER encoding of 0.9.2342.19200300.100.1.25.
// On 10.6 and later this is available as CSSMOID_DomainComponent, which is an
// external symbol from Security.framework. However, it appears that Apple's
// implementation improperly encoded this on 10.6+, and even still is
// unavailable on 10.5, so simply including the raw BER here.
//
// Note: CSSM is allowed to store CSSM_OIDs in any arbitrary format desired,
// as long as the symbols are properly exposed. The fact that Apple's
// implementation stores it in BER is an internal implementation detail
// observed by studying libsecurity_cssm.
const uint8 kDomainComponentData[] = {
  0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19
};

const CSSM_OID kDomainComponentOID = {
    arraysize(kDomainComponentData),
    const_cast<uint8*>(kDomainComponentData)
};

const CSSM_OID* kOIDs[] = {
    &CSSMOID_CommonName,
    &CSSMOID_LocalityName,
    &CSSMOID_StateProvinceName,
    &CSSMOID_CountryName,
    &CSSMOID_StreetAddress,
    &CSSMOID_OrganizationName,
    &CSSMOID_OrganizationalUnitName,
    &kDomainComponentOID,
};

// The following structs and templates work with Apple's very arcane and under-
// documented SecAsn1Parser API, which is apparently the same as NSS's ASN.1
// decoder:
// http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn1.html

// These are used to parse the contents of a raw
// BER DistinguishedName structure.

const SecAsn1Template kStringValueTemplate[] = {
  { SEC_ASN1_CHOICE, offsetof(CSSM_X509_TYPE_VALUE_PAIR, valueType), },
  { SEC_ASN1_PRINTABLE_STRING,
    offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0,
    BER_TAG_PRINTABLE_STRING },
  { SEC_ASN1_IA5_STRING,
    offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0,
    BER_TAG_IA5_STRING },
  { SEC_ASN1_T61_STRING,
    offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0,
    BER_TAG_T61_STRING },
  { SEC_ASN1_UTF8_STRING,
    offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0,
    BER_TAG_PKIX_UTF8_STRING },
  { SEC_ASN1_BMP_STRING,
    offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0,
    BER_TAG_PKIX_BMP_STRING },
  { SEC_ASN1_UNIVERSAL_STRING,
    offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0,
    BER_TAG_PKIX_UNIVERSAL_STRING },
  { 0, }
};

const SecAsn1Template kKeyValuePairTemplate[] = {
  { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CSSM_X509_TYPE_VALUE_PAIR) },
  { SEC_ASN1_OBJECT_ID, offsetof(CSSM_X509_TYPE_VALUE_PAIR, type), },
  { SEC_ASN1_INLINE, 0, &kStringValueTemplate, },
  { 0, }
};

struct KeyValuePairs {
  CSSM_X509_TYPE_VALUE_PAIR* pairs;
};

const SecAsn1Template kKeyValuePairSetTemplate[] = {
  { SEC_ASN1_SET_OF, offsetof(KeyValuePairs, pairs),
      kKeyValuePairTemplate, sizeof(KeyValuePairs) }
};

struct X509Name {
  KeyValuePairs** pairs_list;
};

const SecAsn1Template kNameTemplate[] = {
  { SEC_ASN1_SEQUENCE_OF, offsetof(X509Name, pairs_list),
      kKeyValuePairSetTemplate, sizeof(X509Name) }
};

// Converts raw CSSM_DATA to a std::string. (Char encoding is unaltered.)
std::string DataToString(CSSM_DATA data) {
  return std::string(
      reinterpret_cast<std::string::value_type*>(data.Data),
      data.Length);
}

// Converts raw CSSM_DATA in ISO-8859-1 to a std::string in UTF-8.
std::string Latin1DataToUTF8String(CSSM_DATA data) {
  base::string16 utf16;
  if (!CodepageToUTF16(DataToString(data), base::kCodepageLatin1,
                       base::OnStringConversionError::FAIL, &utf16))
    return "";
  return UTF16ToUTF8(utf16);
}

// Converts big-endian UTF-16 to UTF-8 in a std::string.
// Note: The byte-order flipping is done in place on the input buffer!
bool UTF16BigEndianToUTF8(base::char16* chars, size_t length,
                          std::string* out_string) {
  for (size_t i = 0; i < length; i++)
    chars[i] = EndianU16_BtoN(chars[i]);
  return UTF16ToUTF8(chars, length, out_string);
}

// Converts big-endian UTF-32 to UTF-8 in a std::string.
// Note: The byte-order flipping is done in place on the input buffer!
bool UTF32BigEndianToUTF8(char32* chars, size_t length,
                          std::string* out_string) {
  for (size_t i = 0; i < length; ++i)
    chars[i] = EndianS32_BtoN(chars[i]);
#if defined(WCHAR_T_IS_UTF32)
  return WideToUTF8(reinterpret_cast<const wchar_t*>(chars),
                    length, out_string);
#else
#error This code doesn't handle 16-bit wchar_t.
#endif
}

// Adds a type+value pair to the appropriate vector from a C array.
// The array is keyed by the matching OIDs from kOIDS[].
void AddTypeValuePair(const CSSM_OID type,
                      const std::string& value,
                      std::vector<std::string>* values[]) {
  for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) {
    if (CSSMOIDEqual(&type, kOIDs[oid])) {
      values[oid]->push_back(value);
      break;
    }
  }
}

// Stores the first string of the vector, if any, to *single_value.
void SetSingle(const std::vector<std::string>& values,
               std::string* single_value) {
  // We don't expect to have more than one CN, L, S, and C.
  LOG_IF(WARNING, values.size() > 1) << "Didn't expect multiple values";
  if (!values.empty())
    *single_value = values[0];
}

bool match(const std::string& str, const std::string& against) {
  // TODO(snej): Use the full matching rules specified in RFC 5280 sec. 7.1
  // including trimming and case-folding: <http://www.ietf.org/rfc/rfc5280.txt>.
  return against == str;
}

bool match(const std::vector<std::string>& rdn1,
           const std::vector<std::string>& rdn2) {
  // "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." --RFC 5280 sec. 7.1.
  if (rdn1.size() != rdn2.size())
    return false;
  for (unsigned i1 = 0; i1 < rdn1.size(); ++i1) {
    unsigned i2;
    for (i2 = 0; i2 < rdn2.size(); ++i2) {
      if (match(rdn1[i1], rdn2[i2]))
          break;
    }
    if (i2 == rdn2.size())
      return false;
  }
  return true;
}

}  // namespace

bool CertPrincipal::ParseDistinguishedName(const void* ber_name_data,
                                           size_t length) {
  DCHECK(ber_name_data);

  // First parse the BER |name_data| into the above structs.
  SecAsn1CoderRef coder = NULL;
  SecAsn1CoderCreate(&coder);
  DCHECK(coder);
  X509Name* name = NULL;
  OSStatus err = SecAsn1Decode(coder, ber_name_data, length, kNameTemplate,
                               &name);
  if (err) {
    OSSTATUS_LOG(ERROR, err) << "SecAsn1Decode";
    SecAsn1CoderRelease(coder);
    return false;
  }

  // Now scan the structs and add the values to my string vectors.
  // I don't store multiple common/locality/state/country names, so use
  // temporary vectors for those.
  std::vector<std::string> common_names, locality_names, state_names,
      country_names;
  std::vector<std::string>* values[] = {
      &common_names, &locality_names,
      &state_names, &country_names,
      &this->street_addresses,
      &this->organization_names,
      &this->organization_unit_names,
      &this->domain_components
  };
  DCHECK(arraysize(kOIDs) == arraysize(values));

  for (int rdn = 0; name[rdn].pairs_list; ++rdn) {
    CSSM_X509_TYPE_VALUE_PAIR* pair;
    for (int pair_index = 0;
         NULL != (pair = name[rdn].pairs_list[0][pair_index].pairs);
         ++pair_index) {
      switch (pair->valueType) {
        case BER_TAG_IA5_STRING:          // ASCII (that means 7-bit!)
        case BER_TAG_PRINTABLE_STRING:    // a subset of ASCII
        case BER_TAG_PKIX_UTF8_STRING:    // UTF-8
          AddTypeValuePair(pair->type, DataToString(pair->value), values);
          break;
        case BER_TAG_T61_STRING:          // T61, pretend it's Latin-1
          AddTypeValuePair(pair->type,
                           Latin1DataToUTF8String(pair->value),
                           values);
          break;
        case BER_TAG_PKIX_BMP_STRING: {        // UTF-16, big-endian
          std::string value;
          UTF16BigEndianToUTF8(
              reinterpret_cast<base::char16*>(pair->value.Data),
              pair->value.Length / sizeof(base::char16),
              &value);
          AddTypeValuePair(pair->type, value, values);
          break;
        }
        case BER_TAG_PKIX_UNIVERSAL_STRING: {  // UTF-32, big-endian
          std::string value;
          UTF32BigEndianToUTF8(reinterpret_cast<char32*>(pair->value.Data),
                               pair->value.Length / sizeof(char32),
                               &value);
          AddTypeValuePair(pair->type, value, values);
          break;
        }
        default:
          DCHECK_EQ(pair->valueType, BER_TAG_UNKNOWN);
          // We don't know what data type this is, but we'll store it as a blob.
          // Displaying the string may not work, but at least it can be compared
          // byte-for-byte by a Matches() call.
          AddTypeValuePair(pair->type, DataToString(pair->value), values);
          break;
      }
    }
  }

  SetSingle(common_names, &this->common_name);
  SetSingle(locality_names, &this->locality_name);
  SetSingle(state_names, &this->state_or_province_name);
  SetSingle(country_names, &this->country_name);

  // Releasing |coder| frees all the memory pointed to via |name|.
  SecAsn1CoderRelease(coder);
  return true;
}

bool CertPrincipal::Matches(const CertPrincipal& against) const {
  return match(common_name, against.common_name) &&
      match(locality_name, against.locality_name) &&
      match(state_or_province_name, against.state_or_province_name) &&
      match(country_name, against.country_name) &&
      match(street_addresses, against.street_addresses) &&
      match(organization_names, against.organization_names) &&
      match(organization_unit_names, against.organization_unit_names) &&
      match(domain_components, against.domain_components);
}

}  // namespace net
