// Copyright 2014 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 <vector>

#include "chrome/browser/ssl/ssl_error_classification.h"

#include "base/build_time.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ssl/ssl_error_info.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h"
#include "net/base/net_util.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/cert/x509_cert_types.h"
#include "net/cert/x509_certificate.h"
#include "url/gurl.h"

#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
#include "chrome/browser/captive_portal/captive_portal_service.h"
#include "chrome/browser/captive_portal/captive_portal_service_factory.h"
#endif

#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 {

// Events for UMA. Do not reorder or change!
enum SSLInterstitialCause {
  CLOCK_PAST,
  CLOCK_FUTURE,
  WWW_SUBDOMAIN_MATCH,
  SUBDOMAIN_MATCH,
  SUBDOMAIN_INVERSE_MATCH,
  SUBDOMAIN_OUTSIDE_WILDCARD,
  HOST_NAME_NOT_KNOWN_TLD,
  LIKELY_MULTI_TENANT_HOSTING,
  LOCALHOST,
  PRIVATE_URL,
  AUTHORITY_ERROR_CAPTIVE_PORTAL,
  UNUSED_INTERSTITIAL_CAUSE_ENTRY,
};

// Events for UMA. Do not reorder or change!
enum SSLInterstitialCauseCaptivePortal {
  CAPTIVE_PORTAL_DETECTION_ENABLED,
  CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE,
  CAPTIVE_PORTAL_PROBE_COMPLETED,
  CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE,
  CAPTIVE_PORTAL_NO_RESPONSE,
  CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE,
  CAPTIVE_PORTAL_DETECTED,
  CAPTIVE_PORTAL_DETECTED_OVERRIDABLE,
  UNUSED_CAPTIVE_PORTAL_EVENT,
};

void RecordSSLInterstitialSeverityScore(float ssl_severity_score,
                                        int cert_error) {
  if (SSLErrorInfo::NetErrorToErrorType(cert_error) ==
      SSLErrorInfo::CERT_DATE_INVALID) {
    UMA_HISTOGRAM_COUNTS_100("interstitial.ssl.severity_score.date_invalid",
                             static_cast<int>(ssl_severity_score * 100));
  } else if (SSLErrorInfo::NetErrorToErrorType(cert_error) ==
      SSLErrorInfo::CERT_COMMON_NAME_INVALID) {
    UMA_HISTOGRAM_COUNTS_100(
        "interstitial.ssl.severity_score.common_name_invalid",
        static_cast<int>(ssl_severity_score * 100));
  } else if (SSLErrorInfo::NetErrorToErrorType(cert_error) ==
             SSLErrorInfo::CERT_AUTHORITY_INVALID) {
    UMA_HISTOGRAM_COUNTS_100(
        "interstitial.ssl.severity_score.authority_invalid",
        static_cast<int>(ssl_severity_score * 100));
  }
}

// Scores/weights which will be constant through all the SSL error types.
static const float kServerWeight = 0.5f;
static const float kClientWeight = 0.5f;

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

#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
void RecordCaptivePortalEventStats(SSLInterstitialCauseCaptivePortal event) {
  UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.captive_portal",
                            event,
                            UNUSED_CAPTIVE_PORTAL_EVENT);
}
#endif

int GetLevensteinDistance(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<int> kFirstRow(str2.size() + 1, 0);
  std::vector<int> kSecondRow(str2.size() + 1, 0);

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

} // namespace

SSLErrorClassification::SSLErrorClassification(
    content::WebContents* web_contents,
    const base::Time& current_time,
    const GURL& url,
    int cert_error,
    const net::X509Certificate& cert)
  : web_contents_(web_contents),
    current_time_(current_time),
    request_url_(url),
    cert_error_(cert_error),
    cert_(cert),
    captive_portal_detection_enabled_(false),
    captive_portal_probe_completed_(false),
    captive_portal_no_response_(false),
    captive_portal_detected_(false) {
#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
  Profile* profile = Profile::FromBrowserContext(
      web_contents_->GetBrowserContext());
  CaptivePortalService* captive_portal_service =
      CaptivePortalServiceFactory::GetForProfile(profile);
  captive_portal_detection_enabled_ = captive_portal_service->enabled();
  captive_portal_service->DetectCaptivePortal();
  registrar_.Add(this,
                 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
                 content::Source<Profile>(profile));
#endif
}

SSLErrorClassification::~SSLErrorClassification() { }

void SSLErrorClassification::RecordCaptivePortalUMAStatistics(
    bool overridable) const {
#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
  if (captive_portal_detection_enabled_)
    RecordCaptivePortalEventStats(
        overridable ?
        CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE :
        CAPTIVE_PORTAL_DETECTION_ENABLED);
  if (captive_portal_probe_completed_)
    RecordCaptivePortalEventStats(
        overridable ?
        CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE :
        CAPTIVE_PORTAL_PROBE_COMPLETED);
  // Log only one of portal detected and no response results.
  if (captive_portal_detected_)
    RecordCaptivePortalEventStats(
        overridable ?
        CAPTIVE_PORTAL_DETECTED_OVERRIDABLE :
        CAPTIVE_PORTAL_DETECTED);
  else if (captive_portal_no_response_)
    RecordCaptivePortalEventStats(
        overridable ?
        CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE :
        CAPTIVE_PORTAL_NO_RESPONSE);
#endif
}

void SSLErrorClassification::InvalidDateSeverityScore() {
  SSLErrorInfo::ErrorType type =
      SSLErrorInfo::NetErrorToErrorType(cert_error_);
  DCHECK_EQ(type, SSLErrorInfo::CERT_DATE_INVALID);

  // Client-side characteristics. Check whether or not the system's clock is
  // wrong and whether or not the user has encountered this error before.
  float severity_date_score = 0.0f;

  static const float kCertificateExpiredWeight = 0.3f;
  static const float kNotYetValidWeight = 0.2f;

  static const float kSystemClockWeight = 0.75f;
  static const float kSystemClockWrongWeight = 0.1f;
  static const float kSystemClockRightWeight = 1.0f;

  if (IsUserClockInThePast(current_time_)  ||
      IsUserClockInTheFuture(current_time_)) {
    severity_date_score += kClientWeight * kSystemClockWeight *
        kSystemClockWrongWeight;
  } else {
    severity_date_score += kClientWeight * kSystemClockWeight *
        kSystemClockRightWeight;
  }
  // TODO(felt): (crbug.com/393262) Check website settings.

  // Server-side characteristics. Check whether the certificate has expired or
  // is not yet valid. If the certificate has expired then factor the time which
  // has passed since expiry.
  if (cert_.HasExpired()) {
    severity_date_score += kServerWeight * kCertificateExpiredWeight *
        CalculateScoreTimePassedSinceExpiry();
  }
  if (current_time_ < cert_.valid_start())
    severity_date_score += kServerWeight * kNotYetValidWeight;

  RecordSSLInterstitialSeverityScore(severity_date_score, cert_error_);
}

void SSLErrorClassification::InvalidCommonNameSeverityScore() {
  SSLErrorInfo::ErrorType type =
      SSLErrorInfo::NetErrorToErrorType(cert_error_);
  DCHECK_EQ(type, SSLErrorInfo::CERT_COMMON_NAME_INVALID);
  float severity_name_score = 0.0f;

  static const float kWWWDifferenceWeight = 0.3f;
  static const float kNameUnderAnyNamesWeight = 0.2f;
  static const float kAnyNamesUnderNameWeight = 1.0f;
  static const float kLikelyMultiTenantHostingWeight = 0.1f;

  std::string host_name = request_url_.host();
  if (IsHostNameKnownTLD(host_name)) {
    Tokens host_name_tokens = Tokenize(host_name);
    if (IsWWWSubDomainMatch())
      severity_name_score += kServerWeight * kWWWDifferenceWeight;
    if (IsSubDomainOutsideWildcard(host_name_tokens))
      severity_name_score += kServerWeight * kWWWDifferenceWeight;

    std::vector<std::string> dns_names;
    cert_.GetDNSNames(&dns_names);
    std::vector<Tokens> dns_name_tokens = GetTokenizedDNSNames(dns_names);
    if (NameUnderAnyNames(host_name_tokens, dns_name_tokens))
      severity_name_score += kServerWeight * kNameUnderAnyNamesWeight;
    // Inverse case is more likely to be a MITM attack.
    if (AnyNamesUnderName(dns_name_tokens, host_name_tokens))
      severity_name_score += kServerWeight * kAnyNamesUnderNameWeight;
    if (IsCertLikelyFromMultiTenantHosting())
      severity_name_score += kServerWeight * kLikelyMultiTenantHostingWeight;
  }

  static const float kEnvironmentWeight = 0.25f;

  severity_name_score += kClientWeight * kEnvironmentWeight *
      CalculateScoreEnvironments();

  RecordSSLInterstitialSeverityScore(severity_name_score, cert_error_);
}

void SSLErrorClassification::InvalidAuthoritySeverityScore() {
  SSLErrorInfo::ErrorType type = SSLErrorInfo::NetErrorToErrorType(cert_error_);
  DCHECK_EQ(type, SSLErrorInfo::CERT_AUTHORITY_INVALID);

  // For |CERT_AUTHORITY_INVALID| errors if captive portals have been detected
  // then don't calculate the score, just return.
  if (captive_portal_probe_completed_ && captive_portal_detected_)
    return;

  float severity_authority_score = 0.0f;

  static const float kLocalhostWeight = 0.7f;
  static const float kPrivateURLWeight = 0.3f;
  if (net::IsLocalhost(request_url_.HostNoBrackets()))
    severity_authority_score += kClientWeight * kLocalhostWeight;
  if (IsHostnameNonUniqueOrDotless(request_url_.HostNoBrackets()))
    severity_authority_score += kClientWeight * kPrivateURLWeight;

  RecordSSLInterstitialSeverityScore(severity_authority_score, cert_error_);
}

void SSLErrorClassification::RecordUMAStatistics(
    bool overridable) const {
  SSLErrorInfo::ErrorType type =
      SSLErrorInfo::NetErrorToErrorType(cert_error_);
  switch (type) {
    case SSLErrorInfo::CERT_DATE_INVALID: {
      if (IsUserClockInThePast(base::Time::NowFromSystemTime()))
        RecordSSLInterstitialCause(overridable, CLOCK_PAST);
      if (IsUserClockInTheFuture(base::Time::NowFromSystemTime()))
        RecordSSLInterstitialCause(overridable, CLOCK_FUTURE);
      break;
    }
    case SSLErrorInfo::CERT_COMMON_NAME_INVALID: {
      std::string host_name = request_url_.host();
      if (IsHostNameKnownTLD(host_name)) {
        Tokens host_name_tokens = Tokenize(host_name);
        if (IsWWWSubDomainMatch())
          RecordSSLInterstitialCause(overridable, WWW_SUBDOMAIN_MATCH);
        if (IsSubDomainOutsideWildcard(host_name_tokens))
          RecordSSLInterstitialCause(overridable, SUBDOMAIN_OUTSIDE_WILDCARD);
        std::vector<std::string> dns_names;
        cert_.GetDNSNames(&dns_names);
        std::vector<Tokens> dns_name_tokens = GetTokenizedDNSNames(dns_names);
        if (NameUnderAnyNames(host_name_tokens, dns_name_tokens))
          RecordSSLInterstitialCause(overridable, SUBDOMAIN_MATCH);
        if (AnyNamesUnderName(dns_name_tokens, host_name_tokens))
          RecordSSLInterstitialCause(overridable, SUBDOMAIN_INVERSE_MATCH);
        if (IsCertLikelyFromMultiTenantHosting())
          RecordSSLInterstitialCause(overridable, LIKELY_MULTI_TENANT_HOSTING);
      } else {
         RecordSSLInterstitialCause(overridable, HOST_NAME_NOT_KNOWN_TLD);
      }
      break;
    }
    case SSLErrorInfo::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 (captive_portal_probe_completed_ && captive_portal_detected_)
        RecordSSLInterstitialCause(overridable, AUTHORITY_ERROR_CAPTIVE_PORTAL);
      break;
    }
    default:
      break;
  }
}

base::TimeDelta SSLErrorClassification::TimePassedSinceExpiry() const {
  base::TimeDelta delta = current_time_ - cert_.valid_expiry();
  return delta;
}

float SSLErrorClassification::CalculateScoreTimePassedSinceExpiry() const {
  base::TimeDelta delta = TimePassedSinceExpiry();
  int64 time_passed = delta.InDays();
  const int64 kHighThreshold = 7;
  const int64 kLowThreshold = 4;
  static const float kHighThresholdWeight = 0.4f;
  static const float kMediumThresholdWeight = 0.3f;
  static const float kLowThresholdWeight = 0.2f;
  if (time_passed >= kHighThreshold)
    return kHighThresholdWeight;
  else if (time_passed >= kLowThreshold)
    return kMediumThresholdWeight;
  else
    return kLowThresholdWeight;
}

float SSLErrorClassification::CalculateScoreEnvironments() const {
  static const float kWifiWeight = 0.7f;
  static const float kCellularWeight = 0.7f;
  static const float kEthernetWeight = 0.7f;
  static const float kOtherWeight = 0.7f;
  net::NetworkChangeNotifier::ConnectionType type =
      net::NetworkChangeNotifier::GetConnectionType();
  if (type == net::NetworkChangeNotifier::CONNECTION_WIFI)
    return kWifiWeight;
  if (type == net::NetworkChangeNotifier::CONNECTION_2G ||
      type == net::NetworkChangeNotifier::CONNECTION_3G ||
      type == net::NetworkChangeNotifier::CONNECTION_4G ) {
    return kCellularWeight;
  }
  if (type == net::NetworkChangeNotifier::CONNECTION_ETHERNET)
    return kEthernetWeight;
#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
  // Assume if captive portals are detected then the user is connected using a
  // hot spot.
  static const float kHotspotWeight = 0.2f;
  if (captive_portal_probe_completed_ && captive_portal_detected_)
      return kHotspotWeight;
#endif
  return kOtherWeight;
}

bool SSLErrorClassification::IsUserClockInThePast(const base::Time& time_now) {
#if defined(DONT_EMBED_BUILD_METADATA) && !defined(OFFICIAL_BUILD)
  return false;
#else
  base::Time build_time = base::GetBuildTime();
  if (time_now < build_time - base::TimeDelta::FromDays(2))
    return true;
  return false;
#endif
}

bool SSLErrorClassification::IsUserClockInTheFuture(
    const base::Time& time_now) {
#if defined(DONT_EMBED_BUILD_METADATA) && !defined(OFFICIAL_BUILD)
  return false;
#else
  base::Time build_time = base::GetBuildTime();
  if (time_now > build_time + base::TimeDelta::FromDays(365))
    return true;
  return false;
#endif
}

bool SSLErrorClassification::MaybeWindowsLacksSHA256Support() {
#if defined(OS_WIN)
  return !base::win::MaybeHasSHA256Support();
#else
  return false;
#endif
}

bool SSLErrorClassification::IsHostNameKnownTLD(const std::string& host_name) {
  size_t tld_length =
      net::registry_controlled_domains::GetRegistryLength(
          host_name,
          net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES,
          net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
  if (tld_length == 0 || tld_length == std::string::npos)
    return false;
  return true;
}

std::vector<SSLErrorClassification::Tokens> SSLErrorClassification::
GetTokenizedDNSNames(const std::vector<std::string>& dns_names) {
  std::vector<std::vector<std::string>> dns_name_tokens;
  for (size_t i = 0; i < dns_names.size(); ++i) {
    std::vector<std::string> dns_name_token_single;
    if (dns_names[i].empty() || dns_names[i].find('\0') != std::string::npos
        || !(IsHostNameKnownTLD(dns_names[i]))) {
      dns_name_token_single.push_back(std::string());
    } else {
      dns_name_token_single = Tokenize(dns_names[i]);
    }
    dns_name_tokens.push_back(dns_name_token_single);
  }
  return dns_name_tokens;
}

size_t SSLErrorClassification::FindSubDomainDifference(
    const Tokens& potential_subdomain, const Tokens& parent) const {
  // 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 0;

  size_t tokens_match = 0;
  size_t diff_size = potential_subdomain.size() - parent.size();
  for (size_t i = 0; i < parent.size(); ++i) {
    if (parent[i] == potential_subdomain[i + diff_size])
      tokens_match++;
  }
  if (tokens_match == parent.size())
    return diff_size;
  return 0;
}

SSLErrorClassification::Tokens SSLErrorClassification::
Tokenize(const std::string& name) {
  Tokens name_tokens;
  base::SplitStringDontTrim(name, '.', &name_tokens);
  return name_tokens;
}

// We accept the inverse case for www for historical reasons.
bool SSLErrorClassification::IsWWWSubDomainMatch() const {
  std::string host_name = request_url_.host();
  if (IsHostNameKnownTLD(host_name)) {
    std::vector<std::string> dns_names;
    cert_.GetDNSNames(&dns_names);
    bool result = false;
    // Need to account for all possible domains given in the SSL certificate.
    for (size_t i = 0; i < dns_names.size(); ++i) {
      if (dns_names[i].empty() || dns_names[i].find('\0') != std::string::npos
          || dns_names[i].length() == host_name.length()
          || !(IsHostNameKnownTLD(dns_names[i]))) {
        result = result || false;
      } else if (dns_names[i].length() > host_name.length()) {
        result = result ||
            net::StripWWW(base::ASCIIToUTF16(dns_names[i])) ==
            base::ASCIIToUTF16(host_name);
      } else {
        result = result ||
            net::StripWWW(base::ASCIIToUTF16(host_name)) ==
            base::ASCIIToUTF16(dns_names[i]);
      }
    }
    return result;
  }
  return false;
}

bool SSLErrorClassification::NameUnderAnyNames(
    const Tokens& child,
    const std::vector<Tokens>& potential_parents) const {
  bool result = false;
  // Need to account for all the possible domains given in the SSL certificate.
  for (size_t i = 0; i < potential_parents.size(); ++i) {
    if (potential_parents[i].empty() ||
        potential_parents[i].size() >= child.size()) {
      result = result || false;
    } else {
      size_t domain_diff = FindSubDomainDifference(child,
                                                   potential_parents[i]);
      if (domain_diff == 1 &&  child[0] != "www")
        result = result || true;
    }
  }
  return result;
}

bool SSLErrorClassification::AnyNamesUnderName(
    const std::vector<Tokens>& potential_children,
    const Tokens& parent) const {
  bool result = false;
  // Need to account for all the possible domains given in the SSL certificate.
  for (size_t i = 0; i < potential_children.size(); ++i) {
    if (potential_children[i].empty() ||
        potential_children[i].size() <= parent.size()) {
      result = result || false;
    } else {
      size_t domain_diff = FindSubDomainDifference(potential_children[i],
                                                   parent);
      if (domain_diff == 1 &&  potential_children[i][0] != "www")
        result = result || true;
    }
  }
  return result;
}

bool SSLErrorClassification::IsSubDomainOutsideWildcard(
    const Tokens& host_name_tokens) const {
  std::string host_name = request_url_.host();
  std::vector<std::string> dns_names;
  cert_.GetDNSNames(&dns_names);
  bool result = false;

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

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

bool SSLErrorClassification::IsCertLikelyFromMultiTenantHosting() const {
  std::string host_name = request_url_.host();
  std::vector<std::string> dns_names;
  std::vector<std::string> dns_names_domain;
  cert_.GetDNSNames(&dns_names);
  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 int kMinimumEditDsitance = 5;
  for (size_t i = 0; i < dns_names_size; ++i) {
    for (size_t j = i + 1; j < dns_names_size; ++j) {
      int edit_distance = GetLevensteinDistance(dns_names[i], dns_names[j]);
      if (edit_distance < kMinimumEditDsitance)
        return false;
    }
  }
  return true;
}

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

void SSLErrorClassification::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
  // When detection is disabled, captive portal service always sends
  // RESULT_INTERNET_CONNECTED. Ignore any probe results in that case.
  if (!captive_portal_detection_enabled_)
    return;
  if (type == chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT) {
    captive_portal_probe_completed_ = true;
    CaptivePortalService::Results* results =
        content::Details<CaptivePortalService::Results>(
            details).ptr();
    // If a captive portal was detected at any point when the interstitial was
    // displayed, assume that the interstitial was caused by a captive portal.
    // Example scenario:
    // 1- Interstitial displayed and captive portal detected, setting the flag.
    // 2- Captive portal detection automatically opens portal login page.
    // 3- User logs in on the portal login page.
    // A notification will be received here for RESULT_INTERNET_CONNECTED. Make
    // sure we don't clear the captive protal flag, since the interstitial was
    // potentially caused by the captive portal.
    captive_portal_detected_ = captive_portal_detected_ ||
        (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL);
    // Also keep track of non-HTTP portals and error cases.
    captive_portal_no_response_ = captive_portal_no_response_ ||
        (results->result == captive_portal::RESULT_NO_RESPONSE);
  }
#endif
}
