// 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 <cstdlib>
#include <cstring>

#include "base/logging.h"
#include "base/strings/string_piece.h"
#include "base/time/time.h"
#include "net/base/parse_number.h"
#include "net/cert/internal/parse_name.h"
#include "net/cert/x509_certificate.h"
#include "net/der/input.h"

namespace net {

namespace {

// Helper for ParseCertificateDate. |*field| must contain at least
// |field_len| characters. |*field| will be advanced by |field_len| on exit.
// |*ok| is set to false if there is an error in parsing the number, but left
// untouched otherwise. Returns the parsed integer.
int ParseIntAndAdvance(const char** field, size_t field_len, bool* ok) {
  int result = 0;
  *ok &= ParseInt32(base::StringPiece(*field, field_len),
                    ParseIntFormat::NON_NEGATIVE, &result);
  *field += field_len;
  return result;
}

}  // anonymous namespace

CertPrincipal::CertPrincipal() = default;

CertPrincipal::CertPrincipal(const std::string& name) : common_name(name) {}

CertPrincipal::~CertPrincipal() = default;

bool CertPrincipal::ParseDistinguishedName(
    const void* ber_name_data,
    size_t length,
    PrintableStringHandling printable_string_handling) {
  RDNSequence rdns;
  if (!ParseName(
          der::Input(reinterpret_cast<const uint8_t*>(ber_name_data), length),
          &rdns))
    return false;

  auto string_handling =
      printable_string_handling == PrintableStringHandling::kAsUTF8Hack
          ? X509NameAttribute::PrintableStringHandling::kAsUTF8Hack
          : X509NameAttribute::PrintableStringHandling::kDefault;
  for (const RelativeDistinguishedName& rdn : rdns) {
    for (const X509NameAttribute& name_attribute : rdn) {
      if (name_attribute.type == TypeCommonNameOid()) {
        if (common_name.empty() &&
            !name_attribute.ValueAsStringWithUnsafeOptions(string_handling,
                                                           &common_name)) {
          return false;
        }
      } else if (name_attribute.type == TypeLocalityNameOid()) {
        if (locality_name.empty() &&
            !name_attribute.ValueAsStringWithUnsafeOptions(string_handling,
                                                           &locality_name)) {
          return false;
        }
      } else if (name_attribute.type == TypeStateOrProvinceNameOid()) {
        if (state_or_province_name.empty() &&
            !name_attribute.ValueAsStringWithUnsafeOptions(
                string_handling, &state_or_province_name)) {
          return false;
        }
      } else if (name_attribute.type == TypeCountryNameOid()) {
        if (country_name.empty() &&
            !name_attribute.ValueAsStringWithUnsafeOptions(string_handling,
                                                           &country_name)) {
          return false;
        }
      } else if (name_attribute.type == TypeStreetAddressOid()) {
        std::string s;
        if (!name_attribute.ValueAsStringWithUnsafeOptions(string_handling, &s))
          return false;
        street_addresses.push_back(s);
      } else if (name_attribute.type == TypeOrganizationNameOid()) {
        std::string s;
        if (!name_attribute.ValueAsStringWithUnsafeOptions(string_handling, &s))
          return false;
        organization_names.push_back(s);
      } else if (name_attribute.type == TypeOrganizationUnitNameOid()) {
        std::string s;
        if (!name_attribute.ValueAsStringWithUnsafeOptions(string_handling, &s))
          return false;
        organization_unit_names.push_back(s);
      } else if (name_attribute.type == TypeDomainComponentOid()) {
        std::string s;
        if (!name_attribute.ValueAsStringWithUnsafeOptions(string_handling, &s))
          return false;
        domain_components.push_back(s);
      }
    }
  }
  return true;
}

std::string CertPrincipal::GetDisplayName() const {
  if (!common_name.empty())
    return common_name;
  if (!organization_names.empty())
    return organization_names[0];
  if (!organization_unit_names.empty())
    return organization_unit_names[0];

  return std::string();
}

bool ParseCertificateDate(const base::StringPiece& raw_date,
                          CertDateFormat format,
                          base::Time* time) {
  size_t year_length = format == CERT_DATE_FORMAT_UTC_TIME ? 2 : 4;

  if (raw_date.length() < 11 + year_length)
    return false;

  const char* field = raw_date.data();
  bool valid = true;
  base::Time::Exploded exploded = {0};

  exploded.year =         ParseIntAndAdvance(&field, year_length, &valid);
  exploded.month =        ParseIntAndAdvance(&field, 2, &valid);
  exploded.day_of_month = ParseIntAndAdvance(&field, 2, &valid);
  exploded.hour =         ParseIntAndAdvance(&field, 2, &valid);
  exploded.minute =       ParseIntAndAdvance(&field, 2, &valid);
  exploded.second =       ParseIntAndAdvance(&field, 2, &valid);
  if (valid && year_length == 2)
    exploded.year += exploded.year < 50 ? 2000 : 1900;

  if (!valid)
    return false;
  return base::Time::FromUTCExploded(exploded, time);
}

}  // namespace net
