// Copyright 2025 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.

// This binary contains minimal code to send an HTTP/1.1 over TLS over TCP
// request. It will be refactored to allow layering, with the goal of being able
// to use MASQUE over HTTP/2, and CONNECT in our MASQUE code.

#include <fcntl.h>
#include <netdb.h>
#include <poll.h>
#include <stdbool.h>
#include <sys/socket.h>

#include <cerrno>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "openssl/base.h"
#include "openssl/bio.h"
#include "openssl/pool.h"
#include "openssl/ssl.h"
#include "openssl/stack.h"
#include "quiche/quic/core/connecting_client_socket.h"
#include "quiche/quic/core/crypto/proof_verifier.h"
#include "quiche/quic/core/io/event_loop_socket_factory.h"
#include "quiche/quic/core/io/quic_default_event_loop.h"
#include "quiche/quic/core/io/quic_event_loop.h"
#include "quiche/quic/core/quic_default_clock.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/masque/masque_h2_connection.h"
#include "quiche/quic/platform/api/quic_default_proof_providers.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/quic/tools/fake_proof_verifier.h"
#include "quiche/quic/tools/quic_name_lookup.h"
#include "quiche/quic/tools/quic_url.h"
#include "quiche/common/http/http_header_block.h"
#include "quiche/common/platform/api/quiche_command_line_flags.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/platform/api/quiche_system_event_loop.h"
#include "quiche/common/quiche_mem_slice.h"
#include "quiche/common/quiche_text_utils.h"
#include "quiche/common/simple_buffer_allocator.h"

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    bool, disable_certificate_verification, false,
    "If true, don't verify the server certificate.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(int, address_family, 0,
                                "IP address family to use. Must be 0, 4 or 6. "
                                "Defaults to 0 which means any.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, client_cert_file, "",
                                "Path to the client certificate chain.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    std::string, client_cert_key_file, "",
    "Path to the pkcs8 client certificate private key.");

namespace quic {
namespace {

std::optional<bssl::UniquePtr<SSL_CTX>> CreateSslCtx(
    const std::string& client_cert_file,
    const std::string& client_cert_key_file) {
  if (client_cert_file.empty() != client_cert_key_file.empty()) {
    QUICHE_LOG(ERROR) << "Both private key and certificate chain are required "
                         "when using client certificates";
    return std::nullopt;
  }
  bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));

  if (!client_cert_key_file.empty() &&
      !SSL_CTX_use_PrivateKey_file(ctx.get(), client_cert_key_file.c_str(),
                                   SSL_FILETYPE_PEM)) {
    QUICHE_LOG(ERROR) << "Failed to load client certificate private key: "
                      << client_cert_key_file;
    return std::nullopt;
  }
  if (!client_cert_file.empty() && !SSL_CTX_use_certificate_chain_file(
                                       ctx.get(), client_cert_file.c_str())) {
    QUICHE_LOG(ERROR) << "Failed to load client certificate chain: "
                      << client_cert_file;
    return std::nullopt;
  }

  SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION);
  SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION);

  return ctx;
}

class MasqueTlsTcpClientHandler : public ConnectingClientSocket::AsyncVisitor,
                                  public MasqueH2Connection::Visitor {
 public:
  explicit MasqueTlsTcpClientHandler(QuicEventLoop* event_loop, SSL_CTX* ctx,
                                     QuicUrl url,
                                     bool disable_certificate_verification,
                                     int address_family_for_lookup)
      : event_loop_(event_loop),
        ctx_(ctx),
        socket_factory_(std::make_unique<EventLoopSocketFactory>(
            event_loop_, quiche::SimpleBufferAllocator::Get())),
        url_(url),
        disable_certificate_verification_(disable_certificate_verification),
        address_family_for_lookup_(address_family_for_lookup) {}

  ~MasqueTlsTcpClientHandler() override {
    if (socket_) {
      socket_->Disconnect();
    }
  }

  bool Start() {
    if (disable_certificate_verification_) {
      proof_verifier_ = std::make_unique<FakeProofVerifier>();
    } else {
      proof_verifier_ = CreateDefaultProofVerifier(url_.host());
      if (!proof_verifier_) {
        QUICHE_LOG(ERROR)
            << "The default proof verifier is not supported. Pass "
               "in --disable_certificate_verification.";
        return false;
      }
    }
    socket_address_ = tools::LookupAddress(
        address_family_for_lookup_, url_.host(), absl::StrCat(url_.port()));
    if (!socket_address_.IsInitialized()) {
      QUICHE_LOG(ERROR) << "Failed to resolve address for \"" << url_.host()
                        << "\"";
      return false;
    }
    socket_ = socket_factory_->CreateTcpClientSocket(socket_address_,
                                                     /*receive_buffer_size=*/0,
                                                     /*send_buffer_size=*/0,
                                                     /*async_visitor=*/this);
    if (!socket_) {
      QUICHE_LOG(ERROR) << "Failed to create TCP socket for "
                        << socket_address_;
      return false;
    }
    socket_->ConnectAsync();
    return true;
  }

  static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert) {
    return static_cast<MasqueTlsTcpClientHandler*>(SSL_get_app_data(ssl))
        ->VerifyCertificate(out_alert);
  }

  enum ssl_verify_result_t VerifyCertificate(uint8_t* out_alert) {
    const STACK_OF(CRYPTO_BUFFER)* cert_chain =
        SSL_get0_peer_certificates(ssl_.get());
    if (cert_chain == nullptr) {
      QUICHE_LOG(ERROR) << "No certificate chain";
      *out_alert = SSL_AD_INTERNAL_ERROR;
      return ssl_verify_invalid;
    }
    std::vector<std::string> certs;
    for (CRYPTO_BUFFER* cert : cert_chain) {
      certs.push_back(
          std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert)),
                      CRYPTO_BUFFER_len(cert)));
    }
    const uint8_t* ocsp_response_raw;
    size_t ocsp_response_len;
    SSL_get0_ocsp_response(ssl_.get(), &ocsp_response_raw, &ocsp_response_len);
    std::string ocsp_response(reinterpret_cast<const char*>(ocsp_response_raw),
                              ocsp_response_len);
    const uint8_t* sct_list_raw;
    size_t sct_list_len;
    SSL_get0_signed_cert_timestamp_list(ssl_.get(), &sct_list_raw,
                                        &sct_list_len);
    std::string cert_sct(reinterpret_cast<const char*>(sct_list_raw),
                         sct_list_len);
    std::string error_details;
    std::unique_ptr<ProofVerifyDetails> details;
    QuicAsyncStatus verify_status = proof_verifier_->VerifyCertChain(
        url_.host(), url_.port(), certs, ocsp_response, cert_sct,
        /*context=*/nullptr, &error_details, &details, out_alert,
        /*callback=*/nullptr);
    if (verify_status != QUIC_SUCCESS) {
      // TODO(dschinazi) properly handle QUIC_PENDING.
      QUICHE_LOG(ERROR) << "Failed to verify certificate"
                        << (verify_status == QUIC_PENDING ? " (pending)" : "")
                        << ": " << error_details;
      return ssl_verify_invalid;
    }
    QUICHE_LOG(INFO) << "Successfully verified certificate";
    return ssl_verify_ok;
  }

  // From ConnectingClientSocket::AsyncVisitor.
  void ConnectComplete(absl::Status status) override {
    if (!status.ok()) {
      QUICHE_LOG(ERROR) << "Failed to TCP connect to " << socket_address_
                        << ": " << status;
      done_ = true;
      return;
    }

    QUICHE_LOG(INFO) << "TCP connected to " << socket_address_;

    ssl_.reset((SSL_new(ctx_)));

    if (SSL_set_app_data(ssl_.get(), this) != 1) {
      QUICHE_LOG(FATAL) << "SSL_set_app_data failed";
      return;
    }
    SSL_set_custom_verify(ssl_.get(), SSL_VERIFY_PEER, &VerifyCallback);

    if (SSL_set_tlsext_host_name(ssl_.get(), url_.host().c_str()) != 1) {
      QUICHE_LOG(FATAL) << "SSL_set_tlsext_host_name failed";
      return;
    }

    static constexpr uint8_t kAlpnProtocols[] = {
        0x02, 'h', '2',                                // h2
        0x08, 'h', 't', 't', 'p', '/', '1', '.', '1',  // http/1.1
    };
    if (SSL_set_alpn_protos(ssl_.get(), kAlpnProtocols,
                            sizeof(kAlpnProtocols)) != 0) {
      QUICHE_LOG(FATAL) << "SSL_set_alpn_protos failed";
      return;
    }

    BIO* tls_io = nullptr;
    if (BIO_new_bio_pair(&transport_io_, kBioBufferSize, &tls_io,
                         kBioBufferSize) != 1) {
      QUICHE_LOG(FATAL) << "BIO_new_bio_pair failed";
      return;
    }
    SSL_set_bio(ssl_.get(), tls_io, tls_io);
    // `SSL_set_bio` causes `ssl_` to take ownership of `tls_io`.

    int ret = SSL_connect(ssl_.get());
    if (ret != 1) {
      int ssl_err = SSL_get_error(ssl_.get(), ret);
      if (ssl_err == SSL_ERROR_WANT_READ) {
        QUICHE_DVLOG(1) << "SSL_connect will require another read";
        SendToTransport();
        socket_->ReceiveAsync(kBioBufferSize);
        return;
      }
      PrintSSLError("Error while TLS connecting", ssl_err, ret);
      done_ = true;
      return;
    }
    QUICHE_LOG(INFO) << "TLS connected";

    tls_connected_ = true;
    MaybeSendRequest();
    socket_->ReceiveAsync(kBioBufferSize);
  }

  void ReceiveComplete(absl::StatusOr<quiche::QuicheMemSlice> data) override {
    if (!data.ok()) {
      QUICHE_LOG(ERROR) << "Failed to receive transport data: "
                        << data.status();
      done_ = true;
      return;
    }
    if (data->empty()) {
      QUICHE_LOG(INFO) << "Transport read closed";
      done_ = true;
      return;
    }
    QUICHE_DVLOG(1) << "Transport received " << data->length() << " bytes";
    int write_ret = BIO_write(transport_io_, data->data(), data->length());
    if (write_ret < 0) {
      QUICHE_LOG(ERROR) << "Failed to write data from transport to TLS";
      int ssl_err = SSL_get_error(ssl_.get(), write_ret);
      PrintSSLError("Error while writing data from transport to TLS", ssl_err,
                    write_ret);
      done_ = true;
      return;
    }
    if (write_ret != static_cast<int>(data->length())) {
      QUICHE_LOG(ERROR) << "Short write from transport to TLS: " << write_ret
                        << " != " << data->length();
      done_ = true;
      return;
    }
    QUICHE_DVLOG(1) << "Wrote " << data->length()
                    << " bytes from transport to TLS";
    if (h2_selected_) {
      h2_connection_->OnTransportReadable();
      socket_->ReceiveAsync(kBioBufferSize);
      return;
    }
    int handshake_ret = SSL_do_handshake(ssl_.get());
    if (handshake_ret != 1) {
      int ssl_err = SSL_get_error(ssl_.get(), handshake_ret);
      if (ssl_err == SSL_ERROR_WANT_READ) {
        SendToTransport();
        socket_->ReceiveAsync(kBioBufferSize);
        return;
      }
      PrintSSLError("Error while performing TLS handshake", ssl_err,
                    handshake_ret);
      done_ = true;
      return;
    }
    tls_connected_ = true;
    MaybeSendRequest();
    uint8_t buffer[kBioBufferSize] = {};
    while (true) {
      int ssl_read_ret = SSL_read(ssl_.get(), buffer, sizeof(buffer) - 1);
      if (ssl_read_ret < 0) {
        int ssl_err = SSL_get_error(ssl_.get(), ssl_read_ret);
        if (ssl_err == SSL_ERROR_WANT_READ) {
          SendToTransport();
          socket_->ReceiveAsync(kBioBufferSize);
          return;
        }
        PrintSSLError("Error while reading from TLS", ssl_err, ssl_read_ret);
        done_ = true;
        return;
      }
      if (ssl_read_ret == 0) {
        QUICHE_LOG(INFO) << "TLS read closed";
        done_ = true;
        return;
      }
      if (!h2_selected_) {
        QUICHE_DVLOG(1) << "TLS read " << ssl_read_ret
                        << " bytes of h1 response";
        std::cout << buffer << std::endl;
        done_ = true;
        return;
      }
    }
  }

  void SendComplete(absl::Status status) override {
    if (!status.ok()) {
      QUICHE_LOG(ERROR) << "Transport send failed: " << status;
      done_ = true;
      return;
    }
    SendToTransport();
  }

  bool IsDone() const { return done_; }

  // From MasqueH2Connection::Visitor.
  void OnConnectionReady(MasqueH2Connection* /*connection*/) override {}
  void OnConnectionFinished(MasqueH2Connection* /*connection*/) override {
    done_ = true;
  }

  void OnRequest(MasqueH2Connection* /*connection*/, int32_t /*stream_id*/,
                 const quiche::HttpHeaderBlock& /*headers*/,
                 const std::string& /*body*/) override {
    QUICHE_LOG(FATAL) << "Client cannot receive requests";
  }

  void OnResponse(MasqueH2Connection* connection, int32_t stream_id,
                  const quiche::HttpHeaderBlock& headers,
                  const std::string& body) override {
    if (connection != h2_connection_.get()) {
      QUICHE_LOG(FATAL) << "Unexpected connection";
    }
    if (stream_id != stream_id_) {
      QUICHE_LOG(FATAL) << "Unexpected stream id";
    }
    QUICHE_LOG(INFO) << "Received h2 response headers: "
                     << headers.DebugString() << " body: " << body;
    done_ = true;
  }

 private:
  void MaybeSendRequest() {
    if (request_sent_ || done_ || !tls_connected_) {
      return;
    }
    const uint8_t* alpn_data;
    unsigned alpn_len;
    SSL_get0_alpn_selected(ssl_.get(), &alpn_data, &alpn_len);
    if (alpn_len != 0) {
      std::string alpn(reinterpret_cast<const char*>(alpn_data), alpn_len);
      if (alpn == "h2") {
        h2_selected_ = true;
      }
      QUICHE_DVLOG(1) << "ALPN selected: "
                      << std::string(reinterpret_cast<const char*>(alpn_data),
                                     alpn_len);
    } else {
      QUICHE_DVLOG(1) << "No ALPN selected";
    }
    QUICHE_LOG(INFO) << "Using " << (h2_selected_ ? "h2" : "http/1.1");
    if (h2_selected_) {
      SendH2Request();
    } else {
      SendH1Request();
    }
    request_sent_ = true;
  }

  void SendToTransport() {
    char buffer[kBioBufferSize];
    int read_ret = BIO_read(transport_io_, buffer, sizeof(buffer));
    if (read_ret == 0) {
      QUICHE_LOG(ERROR) << "TCP closed while TLS waiting for handshake read";
    } else if (read_ret < 0) {
      int ssl_err = SSL_get_error(ssl_.get(), read_ret);
      if (ssl_err == SSL_ERROR_WANT_READ) {
        QUICHE_DVLOG(1) << "TLS needs more bytes from underlying socket";
      } else if (ssl_err == SSL_ERROR_SYSCALL && errno == 0) {
        QUICHE_DVLOG(1) << "TLS recoverable failure from underlying socket";
      } else {
        PrintSSLError("Error while reading from transport_io_", ssl_err,
                      read_ret);
      }
    } else {
      QUICHE_DVLOG(1) << "TLS wrote " << read_ret << " bytes to transport";
      socket_->SendAsync(std::string(buffer, read_ret));
    }
  }

  int WriteDataToTls(absl::string_view data) {
    QUICHE_DVLOG(2) << "Writing " << data.size()
                    << " app bytes to TLS:" << std::endl
                    << quiche::QuicheTextUtils::HexDump(data);
    int ssl_write_ret = SSL_write(ssl_.get(), data.data(), data.size());
    if (ssl_write_ret <= 0) {
      int ssl_err = SSL_get_error(ssl_.get(), ssl_write_ret);
      PrintSSLError("Error while writing request to TLS", ssl_err,
                    ssl_write_ret);
      done_ = true;
      return -1;
    } else {
      if (ssl_write_ret == static_cast<int>(data.size())) {
        QUICHE_DVLOG(1) << "Wrote " << data.size() << " bytes to TLS";
      } else {
        QUICHE_DVLOG(1) << "Wrote " << ssl_write_ret << " / " << data.size()
                        << "bytes to TLS";
      }
      SendToTransport();
    }
    return ssl_write_ret;
  }

  void SendH1Request() {
    std::string request = absl::StrCat("GET ", url_.PathParamsQuery(),
                                       " HTTP/1.1\r\nHost: ", url_.HostPort(),
                                       "\r\nConnection: close\r\n\r\n");
    QUICHE_DVLOG(1) << "Sending h1 request of length " << request.size()
                    << " to TLS";
    int write_res = WriteDataToTls(request);
    if (write_res < 0) {
      QUICHE_LOG(ERROR) << "Failed to write request to TLS";
      done_ = true;
      return;
    } else if (write_res != static_cast<int>(request.size())) {
      QUICHE_LOG(ERROR) << "Request TLS short write " << write_res << " < "
                        << request.size();
      done_ = true;
      return;
    }
  }

  void SendH2Request() {
    h2_connection_ =
        std::make_unique<MasqueH2Connection>(ssl_.get(),
                                             /*is_server=*/false, this);
    h2_connection_->OnTransportReadable();
    quiche::HttpHeaderBlock headers;
    headers[":method"] = "GET";
    headers[":scheme"] = url_.scheme();
    headers[":authority"] = url_.HostPort();
    headers[":path"] = url_.PathParamsQuery();
    stream_id_ = h2_connection_->SendRequest(headers, std::string());
    h2_connection_->AttemptToSend();
    if (stream_id_ >= 0) {
      QUICHE_LOG(INFO) << "Wrote h2 request to stream " << stream_id_
                       << ", now sending to transport";
      SendToTransport();
    } else {
      QUICHE_LOG(ERROR) << "Failed to send h2 request";
      done_ = true;
    }
  }

  static constexpr size_t kBioBufferSize = 16384;
  QuicEventLoop* event_loop_;  // Not owned.
  SSL_CTX* ctx_;               // Not owned.
  std::unique_ptr<EventLoopSocketFactory> socket_factory_;
  QuicUrl url_;
  bool disable_certificate_verification_;
  int address_family_for_lookup_;
  std::unique_ptr<ProofVerifier> proof_verifier_;
  QuicSocketAddress socket_address_;
  std::unique_ptr<ConnectingClientSocket> socket_;
  BIO* transport_io_ = nullptr;
  bssl::UniquePtr<SSL> ssl_;
  bool tls_connected_ = false;
  bool h2_selected_ = false;
  bool request_sent_ = false;
  bool done_ = false;
  int32_t stream_id_ = -1;
  std::unique_ptr<MasqueH2Connection> h2_connection_;
};

int RunMasqueTcpClient(int argc, char* argv[]) {
  const char* usage = "Usage: masque_tcp_client <url>";
  std::vector<std::string> urls =
      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
  if (urls.size() != 1) {
    quiche::QuichePrintCommandLineFlagHelp(usage);
    return 1;
  }

  quiche::QuicheSystemEventLoop system_event_loop("masque_client");
  const bool disable_certificate_verification =
      quiche::GetQuicheCommandLineFlag(FLAGS_disable_certificate_verification);

  std::optional<bssl::UniquePtr<SSL_CTX>> ssl_ctx = CreateSslCtx(
      quiche::GetQuicheCommandLineFlag(FLAGS_client_cert_file),
      quiche::GetQuicheCommandLineFlag(FLAGS_client_cert_key_file));
  if (!ssl_ctx.has_value()) {
    return 1;
  }

  const int address_family =
      quiche::GetQuicheCommandLineFlag(FLAGS_address_family);
  int address_family_for_lookup;
  if (address_family == 0) {
    address_family_for_lookup = AF_UNSPEC;
  } else if (address_family == 4) {
    address_family_for_lookup = AF_INET;
  } else if (address_family == 6) {
    address_family_for_lookup = AF_INET6;
  } else {
    QUICHE_LOG(ERROR) << "Invalid address_family " << address_family;
    return 1;
  }
  std::unique_ptr<QuicEventLoop> event_loop =
      GetDefaultEventLoop()->Create(QuicDefaultClock::Get());

  QuicUrl url(urls[0], "https");
  if (url.host().empty() && !absl::StrContains(urls[0], "://")) {
    url = QuicUrl(absl::StrCat("https://", urls[0]));
  }
  if (url.host().empty()) {
    QUICHE_LOG(ERROR) << "Failed to parse URL \"" << urls[0] << "\"";
    return 1;
  }

  MasqueTlsTcpClientHandler tls_handler(event_loop.get(), ssl_ctx->get(), url,
                                        disable_certificate_verification,
                                        address_family_for_lookup);
  if (!tls_handler.Start()) {
    return 1;
  }
  while (!tls_handler.IsDone()) {
    event_loop->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(50));
  }

  return 0;
}

}  // namespace

}  // namespace quic

int main(int argc, char* argv[]) {
  return quic::RunMasqueTcpClient(argc, argv);
}
