// 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 "components/ssl_errors/error_classification.h"

#include <limits.h>
#include <stddef.h>

#include <vector>

#include "base/build_time.h"
#include "base/lazy_instance.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/network_time/network_time_tracker.h"
#include "components/ssl_errors/error_info.h"
#include "components/url_formatter/url_formatter.h"
#include "net/base/network_change_notifier.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/base/url_util.h"
#include "net/cert/x509_cert_types.h"
#include "net/cert/x509_certificate.h"
#include "url/gurl.h"

#if defined(OS_WIN)
#include "base/win/win_util.h"
#include "base/win/windows_version.h"
#endif

using base::Time;
using base::TimeTicks;
using base::TimeDelta;

namespace ssl_errors {
namespace {

void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) {
  if (overridable) {
    UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.overridable", event,
                              SSL_INTERSTITIAL_CAUSE_MAX);
  } else {
    UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.nonoverridable", event,
                              SSL_INTERSTITIAL_CAUSE_MAX);
  }
}

std::vector<HostnameTokens> GetTokenizedDNSNames(
    const std::vector<std::string>& dns_names) {
  std::vector<HostnameTokens> dns_name_tokens;
  for (const auto& dns_name : dns_names) {
    HostnameTokens dns_name_token_single;
    if (dns_name.empty() || dns_name.find('\0') != std::string::npos ||
        !(HostNameHasKnownTLD(dns_name))) {
      dns_name_token_single.push_back(std::string());
    } else {
      dns_name_token_single = Tokenize(dns_name);
    }
    dns_name_tokens.push_back(dns_name_token_single);
  }
  return dns_name_tokens;
}

// If |potential_subdomain| is a subdomain of |parent|, return the number of
// different tokens. Otherwise returns -1.
int FindSubdomainDifference(const HostnameTokens& potential_subdomain,
                            const HostnameTokens& parent) {
  // A check to ensure that the number of tokens in the tokenized_parent is
  // less than the tokenized_potential_subdomain.
  if (parent.size() >= potential_subdomain.size())
    return -1;

  // Don't be ridiculous. Also, don't overflow.
  if (potential_subdomain.size() >= INT_MAX || parent.size() >= INT_MAX)
    return -1;

  int diff_size = static_cast<int>(potential_subdomain.size() - parent.size());
  for (size_t i = 0; i < parent.size(); i++) {
    if (parent[i] != potential_subdomain[i + diff_size])
      return -1;
  }
  return diff_size;
}

// We accept the inverse case for www for historical reasons.
bool IsWWWSubDomainMatch(const GURL& request_url,
                         const net::X509Certificate& cert) {
  std::string www_host;
  std::vector<std::string> dns_names;
  cert.GetSubjectAltName(&dns_names, nullptr);
  return GetWWWSubDomainMatch(request_url, dns_names, &www_host);
}

// The time to use when doing build time operations in browser tests.
base::LazyInstance<base::Time>::DestructorAtExit g_testing_build_time =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

static ssl_errors::ErrorInfo::ErrorType RecordErrorType(int cert_error) {
  ssl_errors::ErrorInfo::ErrorType error_type =
      ssl_errors::ErrorInfo::NetErrorToErrorType(cert_error);
  UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_type", error_type,
                            ssl_errors::ErrorInfo::END_OF_ENUM);
  UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.connection_type",
                            net::NetworkChangeNotifier::GetConnectionType(),
                            net::NetworkChangeNotifier::CONNECTION_LAST);
  return error_type;
}

void RecordUMAStatistics(bool overridable,
                         const base::Time& current_time,
                         const GURL& request_url,
                         int cert_error,
                         const net::X509Certificate& cert) {
  ssl_errors::ErrorInfo::ErrorType error_type = RecordErrorType(cert_error);

  switch (error_type) {
    case ssl_errors::ErrorInfo::CERT_DATE_INVALID: {
      // Note: not reached when displaying the bad clock interstitial.
      // See |RecordUMAStatisticsForClockInterstitial| below.
      if (cert.HasExpired() &&
          (current_time - cert.valid_expiry()).InDays() < 28) {
        RecordSSLInterstitialCause(overridable, EXPIRED_RECENTLY);
      }
      break;
    }
    case ssl_errors::ErrorInfo::CERT_COMMON_NAME_INVALID: {
      std::string host_name = request_url.host();
      std::vector<std::string> dns_names;
      cert.GetSubjectAltName(&dns_names, nullptr);
      std::vector<HostnameTokens> dns_name_tokens =
          GetTokenizedDNSNames(dns_names);

      if (dns_names.empty())
        RecordSSLInterstitialCause(overridable, NO_SUBJECT_ALT_NAME);

      if (HostNameHasKnownTLD(host_name)) {
        HostnameTokens host_name_tokens = Tokenize(host_name);
        if (IsWWWSubDomainMatch(request_url, cert))
          RecordSSLInterstitialCause(overridable, WWW_SUBDOMAIN_MATCH2);
        if (IsSubDomainOutsideWildcard(request_url, cert))
          RecordSSLInterstitialCause(overridable, SUBDOMAIN_OUTSIDE_WILDCARD2);
        if (NameUnderAnyNames(host_name_tokens, dns_name_tokens))
          RecordSSLInterstitialCause(overridable, SUBDOMAIN_MATCH2);
        if (AnyNamesUnderName(dns_name_tokens, host_name_tokens))
          RecordSSLInterstitialCause(overridable, SUBDOMAIN_INVERSE_MATCH2);
        if (IsCertLikelyFromMultiTenantHosting(request_url, cert))
          RecordSSLInterstitialCause(overridable, LIKELY_MULTI_TENANT_HOSTING2);
        if (IsCertLikelyFromSameDomain(request_url, cert))
          RecordSSLInterstitialCause(overridable, LIKELY_SAME_DOMAIN2);
      } else {
        RecordSSLInterstitialCause(overridable, HOST_NAME_NOT_KNOWN_TLD);
      }
      break;
    }
    case ssl_errors::ErrorInfo::CERT_AUTHORITY_INVALID: {
      const std::string& hostname = request_url.HostNoBrackets();
      if (net::IsLocalhost(hostname))
        RecordSSLInterstitialCause(overridable, LOCALHOST);
      if (IsHostnameNonUniqueOrDotless(hostname))
        RecordSSLInterstitialCause(overridable, PRIVATE_URL);
      if (net::X509Certificate::IsSelfSigned(cert.os_cert_handle()))
        RecordSSLInterstitialCause(overridable, SELF_SIGNED);
      break;
    }
    default:
      break;
  }
}

void RecordUMAStatisticsForClockInterstitial(bool overridable,
                                             ssl_errors::ClockState clock_state,
                                             int cert_error) {
  ssl_errors::ErrorInfo::ErrorType error_type = RecordErrorType(cert_error);
  DCHECK(error_type == ssl_errors::ErrorInfo::CERT_DATE_INVALID);

  if (clock_state == ssl_errors::CLOCK_STATE_FUTURE) {
    RecordSSLInterstitialCause(overridable, CLOCK_FUTURE);
  } else if (clock_state == ssl_errors::CLOCK_STATE_PAST) {
    RecordSSLInterstitialCause(overridable, CLOCK_PAST);
  } else {
    NOTREACHED();
  }
}

ClockState GetClockState(
    const base::Time& now_system,
    const network_time::NetworkTimeTracker* network_time_tracker) {
  base::Time now_network;
  base::TimeDelta uncertainty;
  const base::TimeDelta kNetworkTimeFudge = base::TimeDelta::FromMinutes(5);
  NetworkClockState network_state = NETWORK_CLOCK_STATE_MAX;
  network_time::NetworkTimeTracker::NetworkTimeResult network_time_result =
      network_time_tracker->GetNetworkTime(&now_network, &uncertainty);
  switch (network_time_result) {
    case network_time::NetworkTimeTracker::NETWORK_TIME_AVAILABLE:
      if (now_system < now_network - uncertainty - kNetworkTimeFudge) {
        network_state = NETWORK_CLOCK_STATE_CLOCK_IN_PAST;
      } else if (now_system > now_network + uncertainty + kNetworkTimeFudge) {
        network_state = NETWORK_CLOCK_STATE_CLOCK_IN_FUTURE;
      } else {
        network_state = NETWORK_CLOCK_STATE_OK;
      }
      break;
    case network_time::NetworkTimeTracker::NETWORK_TIME_SYNC_LOST:
      network_state = NETWORK_CLOCK_STATE_UNKNOWN_SYNC_LOST;
      break;
    case network_time::NetworkTimeTracker::NETWORK_TIME_NO_SYNC_ATTEMPT:
      network_state = NETWORK_CLOCK_STATE_UNKNOWN_NO_SYNC_ATTEMPT;
      break;
    case network_time::NetworkTimeTracker::NETWORK_TIME_NO_SUCCESSFUL_SYNC:
      network_state = NETWORK_CLOCK_STATE_UNKNOWN_NO_SUCCESSFUL_SYNC;
      break;
    case network_time::NetworkTimeTracker::NETWORK_TIME_FIRST_SYNC_PENDING:
      network_state = NETWORK_CLOCK_STATE_UNKNOWN_FIRST_SYNC_PENDING;
      break;
    case network_time::NetworkTimeTracker::NETWORK_TIME_SUBSEQUENT_SYNC_PENDING:
      network_state = NETWORK_CLOCK_STATE_UNKNOWN_SUBSEQUENT_SYNC_PENDING;
      break;
  }

  ClockState build_time_state = CLOCK_STATE_UNKNOWN;
  base::Time build_time = g_testing_build_time.Get().is_null()
                              ? base::GetBuildTime()
                              : g_testing_build_time.Get();
  if (now_system < build_time - base::TimeDelta::FromDays(2)) {
    build_time_state = CLOCK_STATE_PAST;
  } else if (now_system > build_time + base::TimeDelta::FromDays(365)) {
    build_time_state = CLOCK_STATE_FUTURE;
  }

  UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.clockstate.network3",
                            network_state, NETWORK_CLOCK_STATE_MAX);
  UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.clockstate.build_time",
                            build_time_state, CLOCK_STATE_MAX);

  switch (network_state) {
    case NETWORK_CLOCK_STATE_UNKNOWN_SYNC_LOST:
    case NETWORK_CLOCK_STATE_UNKNOWN_NO_SYNC_ATTEMPT:
    case NETWORK_CLOCK_STATE_UNKNOWN_NO_SUCCESSFUL_SYNC:
    case NETWORK_CLOCK_STATE_UNKNOWN_FIRST_SYNC_PENDING:
    case NETWORK_CLOCK_STATE_UNKNOWN_SUBSEQUENT_SYNC_PENDING:
      return build_time_state;
    case NETWORK_CLOCK_STATE_OK:
      return CLOCK_STATE_OK;
    case NETWORK_CLOCK_STATE_CLOCK_IN_PAST:
      return CLOCK_STATE_PAST;
    case NETWORK_CLOCK_STATE_CLOCK_IN_FUTURE:
      return CLOCK_STATE_FUTURE;
    case NETWORK_CLOCK_STATE_MAX:
      NOTREACHED();
      return CLOCK_STATE_UNKNOWN;
  }

  NOTREACHED();
  return CLOCK_STATE_UNKNOWN;
}

void SetBuildTimeForTesting(const base::Time& testing_time) {
  g_testing_build_time.Get() = testing_time;
}

bool HostNameHasKnownTLD(const std::string& host_name) {
  return net::registry_controlled_domains::HostHasRegistryControlledDomain(
      host_name, net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES,
      net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
}

HostnameTokens Tokenize(const std::string& name) {
  return base::SplitString(name, ".", base::KEEP_WHITESPACE,
                           base::SPLIT_WANT_ALL);
}

bool GetWWWSubDomainMatch(const GURL& request_url,
                          const std::vector<std::string>& dns_names,
                          std::string* www_match_host_name) {
  const std::string& host_name = request_url.host();

  if (HostNameHasKnownTLD(host_name)) {
    // Need to account for all possible domains given in the SSL certificate.
    for (const auto& dns_name : dns_names) {
      if (dns_name.empty() || dns_name.find('\0') != std::string::npos ||
          dns_name.length() == host_name.length() ||
          !HostNameHasKnownTLD(dns_name)) {
        continue;
      } else if (dns_name.length() > host_name.length()) {
        if (url_formatter::StripWWW(base::ASCIIToUTF16(dns_name)) ==
            base::ASCIIToUTF16(host_name)) {
          *www_match_host_name = dns_name;
          return true;
        }
      } else {
        if (url_formatter::StripWWW(base::ASCIIToUTF16(host_name)) ==
            base::ASCIIToUTF16(dns_name)) {
          *www_match_host_name = dns_name;
          return true;
        }
      }
    }
  }
  return false;
}

bool NameUnderAnyNames(const HostnameTokens& child,
                       const std::vector<HostnameTokens>& potential_parents) {
  // Need to account for all the possible domains given in the SSL certificate.
  for (const auto& potential_parent : potential_parents) {
    if (potential_parent.empty() || potential_parent.size() >= child.size()) {
      continue;
    }
    int domain_diff = FindSubdomainDifference(child, potential_parent);
    if (domain_diff == 1 && child[0] != "www")
      return true;
  }
  return false;
}

bool AnyNamesUnderName(const std::vector<HostnameTokens>& potential_children,
                       const HostnameTokens& parent) {
  // Need to account for all the possible domains given in the SSL certificate.
  for (const auto& potential_child : potential_children) {
    if (potential_child.empty() || potential_child.size() <= parent.size()) {
      continue;
    }
    int domain_diff = FindSubdomainDifference(potential_child, parent);
    if (domain_diff == 1 && potential_child[0] != "www")
      return true;
  }
  return false;
}

// Returns the Levenshtein distance between |str1| and |str2|.
// Which is the minimum number of single-character edits (i.e. insertions,
// deletions or substitutions) required to change one word into the other.
// https://en.wikipedia.org/wiki/Levenshtein_distance
size_t GetLevenshteinDistance(const std::string& str1,
                              const std::string& str2) {
  if (str1 == str2)
    return 0;
  if (str1.size() == 0)
    return str2.size();
  if (str2.size() == 0)
    return str1.size();

  std::vector<size_t> row(str2.size() + 1);
  for (size_t i = 0; i < row.size(); ++i)
    row[i] = i;

  for (size_t i = 0; i < str1.size(); ++i) {
    row[0] = i + 1;
    size_t previous = i;
    for (size_t j = 0; j < str2.size(); ++j) {
      size_t old_row = row[j + 1];
      int cost = str1[i] == str2[j] ? 0 : 1;
      row[j + 1] = std::min(std::min(row[j], row[j + 1]) + 1, previous + cost);
      previous = old_row;
    }
  }
  return row[str2.size()];
}

bool IsSubDomainOutsideWildcard(const GURL& request_url,
                                const net::X509Certificate& cert) {
  std::string host_name = request_url.host();
  HostnameTokens host_name_tokens = Tokenize(host_name);
  std::vector<std::string> dns_names;
  cert.GetSubjectAltName(&dns_names, nullptr);
  bool result = false;

  // This method requires that the host name be longer than the dns name on
  // the certificate.
  for (const auto& dns_name : dns_names) {
    if (dns_name.length() < 2 || dns_name.length() >= host_name.length() ||
        dns_name.find('\0') != std::string::npos ||
        !HostNameHasKnownTLD(dns_name) || dns_name[0] != '*' ||
        dns_name[1] != '.') {
      continue;
    }

    // Move past the "*.".
    std::string extracted_dns_name = dns_name.substr(2);
    if (FindSubdomainDifference(host_name_tokens,
                                Tokenize(extracted_dns_name)) == 2) {
      return true;
    }
  }
  return result;
}

bool IsCertLikelyFromMultiTenantHosting(const GURL& request_url,
                                        const net::X509Certificate& cert) {
  std::string host_name = request_url.host();
  std::vector<std::string> dns_names;
  std::vector<std::string> dns_names_domain;
  cert.GetSubjectAltName(&dns_names, nullptr);
  size_t dns_names_size = dns_names.size();

  // If there is only 1 DNS name then it is definitely not a shared certificate.
  if (dns_names_size == 0 || dns_names_size == 1)
    return false;

  // Check to see if all the domains in the SAN field in the SSL certificate are
  // the same or not.
  for (size_t i = 0; i < dns_names_size; ++i) {
    dns_names_domain.push_back(
        net::registry_controlled_domains::GetDomainAndRegistry(
            dns_names[i],
            net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));
  }
  for (size_t i = 1; i < dns_names_domain.size(); ++i) {
    if (dns_names_domain[i] != dns_names_domain[0])
      return false;
  }

  // If the number of DNS names is more than 5 then assume that it is a shared
  // certificate.
  static const int kDistinctNameThreshold = 5;
  if (dns_names_size > kDistinctNameThreshold)
    return true;

  // Heuristic - The edit distance between all the strings should be at least 5
  // for it to be counted as a shared SSLCertificate. If even one pair of
  // strings edit distance is below 5 then the certificate is no longer
  // considered as a shared certificate. Include the host name in the URL also
  // while comparing.
  dns_names.push_back(host_name);
  static const size_t kMinimumEditDistance = 5;
  for (size_t i = 0; i < dns_names_size; ++i) {
    for (size_t j = i + 1; j < dns_names_size; ++j) {
      size_t edit_distance = GetLevenshteinDistance(dns_names[i], dns_names[j]);
      if (edit_distance < kMinimumEditDistance)
        return false;
    }
  }
  return true;
}

bool IsCertLikelyFromSameDomain(const GURL& request_url,
                                const net::X509Certificate& cert) {
  std::string host_name = request_url.host();
  std::vector<std::string> dns_names;
  cert.GetSubjectAltName(&dns_names, nullptr);
  if (dns_names.empty())
    return false;

  dns_names.push_back(host_name);
  std::vector<std::string> dns_names_domain;

  for (const std::string& dns_name : dns_names) {
    dns_names_domain.push_back(
        net::registry_controlled_domains::GetDomainAndRegistry(
            dns_name,
            net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));
  }

  DCHECK(!dns_names_domain.empty());
  const std::string& host_name_domain = dns_names_domain.back();

  // Last element is the original domain. So, excluding it.
  return std::find(dns_names_domain.begin(), dns_names_domain.end() - 1,
                   host_name_domain) != dns_names_domain.end() - 1;
}

bool IsHostnameNonUniqueOrDotless(const std::string& hostname) {
  return net::IsHostnameNonUnique(hostname) ||
         hostname.find('.') == std::string::npos;
}

}  // namespace ssl_errors
