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

#include "parse_name.h"

#include <cassert>

#include <openssl/bytestring.h>
#include <openssl/mem.h>

#include "parse_values.h"
#include "string_util.h"

namespace bssl {

namespace {

// Returns a string containing the dotted numeric form of |oid|, or an empty
// string on error.
std::string OidToString(der::Input oid) {
  CBS cbs;
  CBS_init(&cbs, oid.data(), oid.size());
  bssl::UniquePtr<char> text(CBS_asn1_oid_to_text(&cbs));
  if (!text) {
    return std::string();
  }
  return text.get();
}

}  // namespace

bool X509NameAttribute::ValueAsString(std::string *out) const {
  switch (value_tag) {
    case CBS_ASN1_T61STRING:
      return der::ParseTeletexStringAsLatin1(value, out);
    case CBS_ASN1_IA5STRING:
      return der::ParseIA5String(value, out);
    case CBS_ASN1_PRINTABLESTRING:
      return der::ParsePrintableString(value, out);
    case CBS_ASN1_UTF8STRING:
      *out = BytesAsStringView(value);
      return true;
    case CBS_ASN1_UNIVERSALSTRING:
      return der::ParseUniversalString(value, out);
    case CBS_ASN1_BMPSTRING:
      return der::ParseBmpString(value, out);
    default:
      return false;
  }
}

bool X509NameAttribute::ValueAsStringWithUnsafeOptions(
    PrintableStringHandling printable_string_handling, std::string *out) const {
  if (printable_string_handling == PrintableStringHandling::kAsUTF8Hack &&
      value_tag == CBS_ASN1_PRINTABLESTRING) {
    *out = BytesAsStringView(value);
    return true;
  }
  return ValueAsString(out);
}

bool X509NameAttribute::ValueAsStringUnsafe(std::string *out) const {
  switch (value_tag) {
    case CBS_ASN1_IA5STRING:
    case CBS_ASN1_PRINTABLESTRING:
    case CBS_ASN1_T61STRING:
    case CBS_ASN1_UTF8STRING:
      *out = BytesAsStringView(value);
      return true;
    case CBS_ASN1_UNIVERSALSTRING:
      return der::ParseUniversalString(value, out);
    case CBS_ASN1_BMPSTRING:
      return der::ParseBmpString(value, out);
    default:
      assert(0);  // NOTREACHED
      return false;
  }
}

bool X509NameAttribute::AsRFC2253String(std::string *out) const {
  std::string type_string;
  std::string value_string;
  // TODO(mattm): Add streetAddress and domainComponent here?
  if (type == der::Input(kTypeCommonNameOid)) {
    type_string = "CN";
  } else if (type == der::Input(kTypeSurnameOid)) {
    type_string = "SN";
  } else if (type == der::Input(kTypeCountryNameOid)) {
    type_string = "C";
  } else if (type == der::Input(kTypeLocalityNameOid)) {
    type_string = "L";
  } else if (type == der::Input(kTypeStateOrProvinceNameOid)) {
    type_string = "ST";
  } else if (type == der::Input(kTypeOrganizationNameOid)) {
    type_string = "O";
  } else if (type == der::Input(kTypeOrganizationUnitNameOid)) {
    type_string = "OU";
  } else if (type == der::Input(kTypeGivenNameOid)) {
    type_string = "givenName";
  } else if (type == der::Input(kTypeEmailAddressOid)) {
    type_string = "emailAddress";
  } else {
    type_string = OidToString(type);
    if (type_string.empty()) {
      return false;
    }
    value_string = "#" + bssl::string_util::HexEncode(value);
  }

  if (value_string.empty()) {
    std::string unescaped;
    if (!ValueAsStringUnsafe(&unescaped)) {
      return false;
    }

    bool nonprintable = false;
    for (unsigned int i = 0; i < unescaped.length(); ++i) {
      uint8_t c = static_cast<uint8_t>(unescaped[i]);
      if (i == 0 && c == '#') {
        value_string += "\\#";
      } else if (i == 0 && c == ' ') {
        value_string += "\\ ";
      } else if (i == unescaped.length() - 1 && c == ' ') {
        value_string += "\\ ";
      } else if (c == ',' || c == '+' || c == '"' || c == '\\' || c == '<' ||
                 c == '>' || c == ';') {
        value_string += "\\";
        value_string += c;
      } else if (c < 32 || c > 126) {
        nonprintable = true;
        value_string +=
            "\\" + bssl::string_util::HexEncode(MakeConstSpan(&c, 1));
      } else {
        value_string += c;
      }
    }

    // If we have non-printable characters in a TeletexString, we hex encode
    // since we don't handle Teletex control codes.
    if (nonprintable && value_tag == CBS_ASN1_T61STRING) {
      value_string = "#" + bssl::string_util::HexEncode(value);
    }
  }

  *out = type_string + "=" + value_string;
  return true;
}

bool ReadRdn(der::Parser *parser, RelativeDistinguishedName *out) {
  while (parser->HasMore()) {
    der::Parser attr_type_and_value;
    if (!parser->ReadSequence(&attr_type_and_value)) {
      return false;
    }
    // Read the attribute type, which must be an OBJECT IDENTIFIER.
    der::Input type;
    if (!attr_type_and_value.ReadTag(CBS_ASN1_OBJECT, &type)) {
      return false;
    }

    // Read the attribute value.
    CBS_ASN1_TAG tag;
    der::Input value;
    if (!attr_type_and_value.ReadTagAndValue(&tag, &value)) {
      return false;
    }

    // There should be no more elements in the sequence after reading the
    // attribute type and value.
    if (attr_type_and_value.HasMore()) {
      return false;
    }

    out->push_back(X509NameAttribute(type, tag, value));
  }

  // RFC 5280 section 4.1.2.4
  // RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
  return out->size() != 0;
}

bool ParseName(der::Input name_tlv, RDNSequence *out) {
  der::Parser name_parser(name_tlv);
  der::Input name_value;
  if (!name_parser.ReadTag(CBS_ASN1_SEQUENCE, &name_value)) {
    return false;
  }
  return ParseNameValue(name_value, out);
}

bool ParseNameValue(der::Input name_value, RDNSequence *out) {
  der::Parser rdn_sequence_parser(name_value);
  while (rdn_sequence_parser.HasMore()) {
    der::Parser rdn_parser;
    if (!rdn_sequence_parser.ReadConstructed(CBS_ASN1_SET, &rdn_parser)) {
      return false;
    }
    RelativeDistinguishedName type_and_values;
    if (!ReadRdn(&rdn_parser, &type_and_values)) {
      return false;
    }
    out->push_back(type_and_values);
  }

  return true;
}

bool ConvertToRFC2253(const RDNSequence &rdn_sequence, std::string *out) {
  std::string rdns_string;
  size_t size = rdn_sequence.size();
  for (size_t i = 0; i < size; ++i) {
    RelativeDistinguishedName rdn = rdn_sequence[size - i - 1];
    std::string rdn_string;
    for (const auto &atv : rdn) {
      if (!rdn_string.empty()) {
        rdn_string += "+";
      }
      std::string atv_string;
      if (!atv.AsRFC2253String(&atv_string)) {
        return false;
      }
      rdn_string += atv_string;
    }
    if (!rdns_string.empty()) {
      rdns_string += ",";
    }
    rdns_string += rdn_string;
  }

  *out = rdns_string;
  return true;
}

}  // namespace bssl
