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

#include "content/browser/ssl/ssl_manager.h"

#include <set>
#include <utility>

#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/supports_user_data.h"
#include "base/trace_event/optional_trace_event.h"
#include "content/browser/devtools/devtools_instrumentation.h"
#include "content/browser/navigation_or_document_handle.h"
#include "content/browser/navigation_subresource_loader_params.h"
#include "content/browser/renderer_host/navigation_entry_impl.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/ssl/ssl_error_handler.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/certificate_request_result_type.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/ssl_host_state_delegate.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "net/base/url_util.h"
#include "net/cert/cert_status_flags.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/mojom/devtools/console_message.mojom.h"

namespace content {

namespace {

const char kSSLManagerKeyName[] = "content_ssl_manager";

// Used to log type of mixed content displayed/ran, matches histogram enum
// (MixedContentType). DO NOT REORDER.
enum class MixedContentType {
  kOptionallyBlockableMixedContent = 0,
  kOptionallyBlockableWithCertErrors = 1,
  kMixedForm = 2,
  kBlockableMixedContent = 3,
  kBlockableWithCertErrors = 4,
  kMaxValue = kBlockableWithCertErrors,
};

void OnAllowCertificate(SSLErrorHandler* handler,
                        StoragePartition* storage_partition,
                        SSLHostStateDelegate* state_delegate,
                        bool record_decision,
                        CertificateRequestResultType decision) {
  DCHECK(handler->ssl_info().is_valid());
  switch (decision) {
    case CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE:
      // Note that we should not call SetMaxSecurityStyle here, because
      // the active NavigationEntry has just been deleted (in
      // HideInterstitialPage) and the new NavigationEntry will not be
      // set until DidNavigate.  This is ok, because the new
      // NavigationEntry will have its max security style set within
      // DidNavigate.
      //
      // While AllowCert() executes synchronously on this thread,
      // ContinueRequest() gets posted to a different thread. Calling
      // AllowCert() first ensures deterministic ordering.
      if (record_decision && state_delegate) {
        state_delegate->AllowCert(handler->request_url().host(),
                                  *handler->ssl_info().cert.get(),
                                  handler->cert_error(), storage_partition);
      }
      handler->ContinueRequest();
      return;
    case CERTIFICATE_REQUEST_RESULT_TYPE_DENY:
      handler->DenyRequest();
      return;
    case CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL:
      handler->CancelRequest();
      return;
  }
}

class SSLManagerSet : public base::SupportsUserData::Data {
 public:
  SSLManagerSet() {
  }

  SSLManagerSet(const SSLManagerSet&) = delete;
  SSLManagerSet& operator=(const SSLManagerSet&) = delete;

  std::set<raw_ptr<SSLManager, SetExperimental>>& get() { return set_; }

 private:
  std::set<raw_ptr<SSLManager, SetExperimental>> set_;
};

}  // namespace

// static
void SSLManager::OnSSLCertificateError(
    const base::WeakPtr<SSLErrorHandler::Delegate>& delegate,
    bool is_primary_main_frame_request,
    const GURL& url,
    NavigationOrDocumentHandle* navigation_or_document,
    int net_error,
    const net::SSLInfo& ssl_info,
    bool fatal) {
  DCHECK(delegate.get());
  DVLOG(1) << "OnSSLCertificateError() cert_error: " << net_error
           << " url: " << url.spec() << " cert_status: " << std::hex
           << ssl_info.cert_status;
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  WebContents* web_contents = nullptr;
  FrameTreeNode* frame_tree_node = nullptr;
  // This handle can be null if the request is from service worker.
  if (navigation_or_document) {
    web_contents = navigation_or_document->GetWebContents();
    frame_tree_node = navigation_or_document->GetFrameTreeNode();
  }

  std::unique_ptr<SSLErrorHandler> handler(
      new SSLErrorHandler(web_contents, delegate, is_primary_main_frame_request,
                          url, net_error, ssl_info, fatal));

  if (!web_contents || !frame_tree_node) {
    // Check if the DevTools Browser target is set to ignore certificate errors.
    if (devtools_instrumentation::ShouldBypassCertificateErrors()) {
      handler->ContinueRequest();
      return;
    }
    // Requests can fail to dispatch because they don't have a WebContents. See
    // https://crbug.com/86537. In this case we have to make a decision in this
    // function. Also, if the navigation or document which have been responsible
    // for the request don't exist, there is no point in trying to process
    // further.
    handler->DenyRequest();
    return;
  }

  // Check if we should deny certificate errors using the main frame's URL.
  if (GetContentClient()->browser()->ShouldDenyRequestOnCertificateError(
          web_contents->GetLastCommittedURL())) {
    handler->DenyRequest();
    return;
  }

  NavigationControllerImpl& controller =
      frame_tree_node->navigator().controller();
  controller.SetPendingNavigationSSLError(true);

  SSLManager* manager = controller.ssl_manager();
  manager->OnCertError(std::move(handler));
}

SSLManager::SSLManager(NavigationControllerImpl* controller)
    : controller_(controller),
      ssl_host_state_delegate_(
          controller->GetBrowserContext()->GetSSLHostStateDelegate()) {
  DCHECK(controller_);

  SSLManagerSet* managers = static_cast<SSLManagerSet*>(
      controller_->GetBrowserContext()->GetUserData(kSSLManagerKeyName));
  if (!managers) {
    auto managers_owned = std::make_unique<SSLManagerSet>();
    managers = managers_owned.get();
    controller_->GetBrowserContext()->SetUserData(kSSLManagerKeyName,
                                                  std::move(managers_owned));
  }
  managers->get().insert(this);
}

SSLManager::~SSLManager() {
  SSLManagerSet* managers = static_cast<SSLManagerSet*>(
      controller_->GetBrowserContext()->GetUserData(kSSLManagerKeyName));
  managers->get().erase(this);
}

void SSLManager::DidCommitProvisionalLoad(const LoadCommittedDetails& details) {
  NavigationEntryImpl* entry = controller_->GetLastCommittedEntry();
  int add_content_status_flags = 0;
  int remove_content_status_flags = 0;

  if (!details.is_main_frame || details.is_same_document) {
    // For subframe navigations, and for same-document main-frame navigations,
    // carry over content status flags from the previously committed entry. For
    // example, the mixed content flag shouldn't clear because of a subframe
    // navigation, or because of a back/forward navigation that doesn't leave
    // the current document. (See https://crbug.com/959571.)
    NavigationEntryImpl* previous_entry =
        controller_->GetEntryAtIndex(details.previous_entry_index);
    if (previous_entry) {
      add_content_status_flags = previous_entry->GetSSL().content_status;
    }
  } else if (!details.is_prerender_activation) {
    // For main-frame navigations that are not same-document and not prerender
    // activations, clear content status flags. These flags are set based on the
    // content on the page, and thus should reflect the current content, even if
    // the navigation was to an existing entry that already had content status
    // flags set. The status flags are kept for prerender activations because
    // |entry| points to the NavigationEntry that has just committed and it may
    // contain existing ssl flags which we do not want to reset.
    remove_content_status_flags = ~0;
  }

  if (!UpdateEntry(entry, add_content_status_flags, remove_content_status_flags,
                   /*notify_changes=*/details.is_in_active_page)) {
    // Ensure the WebContents is notified that the SSL state changed when a
    // load is committed, in case the active navigation entry has changed.
    // Notification will only be called during activation if this commit is
    // triggered by prerendering.
    if (details.is_in_active_page) {
      NotifyDidChangeVisibleSSLState();
    }
  }
}

void SSLManager::DidDisplayMixedContent() {
  OPTIONAL_TRACE_EVENT0("content", "SSLManager::DidDisplayMixedContent");
  NavigationEntryImpl* entry = controller_->GetLastCommittedEntry();
  if (entry && entry->GetURL().SchemeIsCryptographic() &&
      entry->GetSSL().certificate) {
    RenderFrameHostImpl* main_frame = controller_->frame_tree().GetMainFrame();
    WebContents* contents = WebContents::FromRenderFrameHost(main_frame);
    if (contents) {
      GetContentClient()->browser()->OnDisplayInsecureContent(contents);
    }
  }
  UpdateLastCommittedEntry(SSLStatus::DISPLAYED_INSECURE_CONTENT, 0);
}

void SSLManager::DidContainInsecureFormAction() {
  OPTIONAL_TRACE_EVENT0("content", "SSLManager::DidContainInsecureFormAction");
  UpdateLastCommittedEntry(SSLStatus::DISPLAYED_FORM_WITH_INSECURE_ACTION, 0);
}

void SSLManager::DidDisplayContentWithCertErrors() {
  NavigationEntryImpl* entry = controller_->GetLastCommittedEntry();
  if (!entry)
    return;

  if (entry->GetURL().SchemeIsCryptographic() && entry->GetSSL().certificate) {
    UpdateLastCommittedEntry(SSLStatus::DISPLAYED_CONTENT_WITH_CERT_ERRORS, 0);
  }
}

void SSLManager::DidRunMixedContent(const GURL& security_origin) {
  NavigationEntryImpl* entry = controller_->GetLastCommittedEntry();
  if (!entry)
    return;

  if (ssl_host_state_delegate_) {
    ssl_host_state_delegate_->HostRanInsecureContent(
        security_origin.host(), SSLHostStateDelegate::MIXED_CONTENT);
  }
  // TODO(crbug.com/40223471): Ensure proper notify_changes is passed to
  // UpdateEntry.
  UpdateEntry(entry, 0, 0, /*notify_changes=*/true);
  NotifySSLInternalStateChanged(controller_->GetBrowserContext());
}

void SSLManager::DidRunContentWithCertErrors(const GURL& security_origin) {
  NavigationEntryImpl* entry = controller_->GetLastCommittedEntry();
  if (!entry)
    return;

  if (ssl_host_state_delegate_) {
    ssl_host_state_delegate_->HostRanInsecureContent(
        security_origin.host(), SSLHostStateDelegate::CERT_ERRORS_CONTENT);
  }
  // TODO(crbug.com/40223471): Ensure proper notify_changes is passed to
  // UpdateEntry.
  UpdateEntry(entry, 0, 0, /*notify_changes=*/true);
  NotifySSLInternalStateChanged(controller_->GetBrowserContext());
}

void SSLManager::OnCertError(std::unique_ptr<SSLErrorHandler> handler) {
  // First we check if we know the policy for this error.
  DCHECK(handler->ssl_info().is_valid());

  SSLHostStateDelegate::CertJudgment judgment;
  if (net::IsLocalhost(handler->request_url()) &&
      base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kAllowInsecureLocalhost)) {
    // If the appropriate flag is set, let requests on localhost go
    // through even if there are certificate errors. Errors on localhost
    // are unlikely to indicate actual security problems.
    judgment = SSLHostStateDelegate::ALLOWED;
  } else if (ssl_host_state_delegate_) {
    judgment = ssl_host_state_delegate_->QueryPolicy(
        handler->request_url().host(), *handler->ssl_info().cert.get(),
        handler->cert_error(),
        controller_->frame_tree().GetMainFrame()->GetStoragePartition());
  } else {
    judgment = SSLHostStateDelegate::DENIED;
  }

  if (judgment == SSLHostStateDelegate::ALLOWED) {
    handler->ContinueRequest();
    return;
  }

  DCHECK(net::IsCertificateError(handler->cert_error()));
  OnCertErrorInternal(std::move(handler));
}

bool SSLManager::HasAllowExceptionForAnyHost() {
  if (!ssl_host_state_delegate_) {
    return false;
  }
  return ssl_host_state_delegate_->HasAllowExceptionForAnyHost(
      controller_->frame_tree().GetMainFrame()->GetStoragePartition());
}

void SSLManager::DidStartResourceResponse(
    const url::SchemeHostPort& final_response_url,
    bool has_certificate_errors) {
  const std::string& scheme = final_response_url.scheme();
  const std::string& host = final_response_url.host();

  if (!GURL::SchemeIsCryptographic(scheme) || has_certificate_errors) {
    return;
  }
  // If the scheme is https: or wss and the cert did not have any errors, revoke
  // any previous decisions that have occurred.
  if (!ssl_host_state_delegate_ ||
      !ssl_host_state_delegate_->HasAllowException(
          host,
          controller_->frame_tree().GetMainFrame()->GetStoragePartition())) {
    return;
  }

  // If there's no certificate error, a good certificate has been seen, so
  // clear out any exceptions that were made by the user for bad
  // certificates. This intentionally does not apply to cached resources
  // (see https://crbug.com/634553 for an explanation).
  ssl_host_state_delegate_->RevokeUserAllowExceptions(host);
}

void SSLManager::OnCertErrorInternal(std::unique_ptr<SSLErrorHandler> handler) {
  WebContents* web_contents = handler->web_contents();
  int cert_error = handler->cert_error();
  const net::SSLInfo& ssl_info = handler->ssl_info();
  const GURL& request_url = handler->request_url();
  bool is_primary_main_frame_request = handler->is_primary_main_frame_request();
  bool fatal = handler->fatal();

  base::RepeatingCallback<void(bool, content::CertificateRequestResultType)>
      callback = base::BindRepeating(
          &OnAllowCertificate, base::Owned(handler.release()),
          controller_->frame_tree().GetMainFrame()->GetStoragePartition(),
          ssl_host_state_delegate_);

  if (devtools_instrumentation::HandleCertificateError(
          web_contents, cert_error, request_url,
          base::BindRepeating(callback, false))) {
    return;
  }

  GetContentClient()->browser()->AllowCertificateError(
      web_contents, cert_error, ssl_info, request_url,
      is_primary_main_frame_request, fatal,
      base::BindOnce(std::move(callback), true));
}

bool SSLManager::UpdateEntry(NavigationEntryImpl* entry,
                             int add_content_status_flags,
                             int remove_content_status_flags,
                             bool notify_changes) {
  // We don't always have a navigation entry to update, for example in the
  // case of the Web Inspector.
  if (!entry)
    return false;

  SSLStatus original_ssl_status = entry->GetSSL();  // Copy!
  entry->GetSSL().initialized = true;
  entry->GetSSL().content_status &= ~remove_content_status_flags;
  entry->GetSSL().content_status |= add_content_status_flags;

  if (ssl_host_state_delegate_) {
    const std::optional<url::Origin>& entry_origin =
        entry->root_node()->frame_entry->committed_origin();
    // In some cases (e.g., unreachable URLs), navigation entries might not have
    // origins attached to them. We don't care about tracking mixed content for
    // those cases.
    if (entry_origin.has_value()) {
      const std::string& host = entry_origin->host();
      if (ssl_host_state_delegate_->DidHostRunInsecureContent(
              host, SSLHostStateDelegate::MIXED_CONTENT)) {
        entry->GetSSL().content_status |= SSLStatus::RAN_INSECURE_CONTENT;
      }

      // Only record information about subresources with cert errors if the
      // main page is HTTPS with a certificate.
      if (entry->GetURL().SchemeIsCryptographic() &&
          entry->GetSSL().certificate &&
          ssl_host_state_delegate_->DidHostRunInsecureContent(
              host, SSLHostStateDelegate::CERT_ERRORS_CONTENT)) {
        entry->GetSSL().content_status |=
            SSLStatus::RAN_CONTENT_WITH_CERT_ERRORS;
      }
    }
  }

  if (entry->GetSSL().initialized != original_ssl_status.initialized ||
      entry->GetSSL().content_status != original_ssl_status.content_status) {
    if (notify_changes) {
      NotifyDidChangeVisibleSSLState();
    }
    return true;
  }

  return false;
}

void SSLManager::UpdateLastCommittedEntry(int add_content_status_flags,
                                          int remove_content_status_flags) {
  NavigationEntryImpl* entry;
  if (controller_->frame_tree().is_fenced_frame()) {
    // Only the primary frame tree's NavigationEntries are exposed outside of
    // content, so the primary frame tree's NavigationController needs to
    // represent an aggregate view of the security state of its inner frame
    // trees.
    RenderFrameHostImpl* rfh =
        controller_->frame_tree().root()->current_frame_host();
    DCHECK(rfh);
    CHECK_NE(RenderFrameHostImpl::LifecycleStateImpl::kPrerendering,
             rfh->GetOutermostMainFrame()->lifecycle_state());
    WebContentsImpl* contents =
        WebContentsImpl::FromRenderFrameHostImpl(rfh->GetOutermostMainFrame());
    entry = contents->GetController().GetLastCommittedEntry();
  } else {
    entry = controller_->GetLastCommittedEntry();
  }

  if (!entry)
    return;
  // TODO(crbug.com/40223471): Ensure proper notify_changes is passed to
  // UpdateEntry.
  UpdateEntry(entry, add_content_status_flags, remove_content_status_flags,
              /*notify_changes=*/true);
}

void SSLManager::NotifyDidChangeVisibleSSLState() {
  RenderFrameHostImpl* main_frame = controller_->frame_tree().GetMainFrame();
  WebContentsImpl* contents = static_cast<WebContentsImpl*>(
      WebContents::FromRenderFrameHost(main_frame));
  contents->DidChangeVisibleSecurityState();
}

// static
void SSLManager::NotifySSLInternalStateChanged(BrowserContext* context) {
  SSLManagerSet* managers =
      static_cast<SSLManagerSet*>(context->GetUserData(kSSLManagerKeyName));

  for (SSLManager* manager : managers->get()) {
    // TODO(crbug.com/40223471): Ensure proper notify_changes is passed to
    // UpdateEntry.
    manager->UpdateEntry(manager->controller()->GetLastCommittedEntry(), 0, 0,
                         /*notify_changes=*/true);
  }
}

}  // namespace content
