// Copyright 2014 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <openssl/base.h>

#include <stdio.h>

#if !defined(OPENSSL_WINDOWS)
#include <sys/select.h>
#else
#include <winsock2.h>
#endif

#include <string_view>

#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/ssl.h>

#include "internal.h"
#include "transport_common.h"


BSSL_NAMESPACE_BEGIN

static const struct argument kArguments[] = {
    {
        "-connect",
        kRequiredArgument,
        "The hostname and port of the server to connect to, e.g. foo.com:443",
    },
    {
        "-cipher",
        kOptionalArgument,
        "An OpenSSL-style cipher suite string that configures the offered "
        "ciphers",
    },
    {
        "-curves",
        kOptionalArgument,
        "An OpenSSL-style ECDH curves list that configures the offered curves",
    },
    {
        "-sigalgs",
        kOptionalArgument,
        "An OpenSSL-style signature algorithms list that configures the "
        "signature algorithm preferences",
    },
    {
        "-max-version",
        kOptionalArgument,
        "The maximum acceptable protocol version",
    },
    {
        "-min-version",
        kOptionalArgument,
        "The minimum acceptable protocol version",
    },
    {
        "-server-name",
        kOptionalArgument,
        "The server name to advertise",
    },
    {
        "-ech-grease",
        kBooleanArgument,
        "Enable ECH GREASE",
    },
    {
        "-ech-config-list",
        kOptionalArgument,
        "Path to file containing serialized ECHConfigs",
    },
    {
        "-select-next-proto",
        kOptionalArgument,
        "An NPN protocol to select if the server supports NPN",
    },
    {
        "-alpn-protos",
        kOptionalArgument,
        "A comma-separated list of ALPN protocols to advertise",
    },
    {
        "-fallback-scsv",
        kBooleanArgument,
        "Enable FALLBACK_SCSV",
    },
    {
        "-ocsp-stapling",
        kBooleanArgument,
        "Advertise support for OCSP stabling",
    },
    {
        "-signed-certificate-timestamps",
        kBooleanArgument,
        "Advertise support for signed certificate timestamps",
    },
    {
        "-channel-id-key",
        kOptionalArgument,
        "The key to use for signing a channel ID",
    },
    {
        "-false-start",
        kBooleanArgument,
        "Enable False Start",
    },
    {
        "-session-in",
        kOptionalArgument,
        "A file containing a session to resume.",
    },
    {
        "-session-out",
        kOptionalArgument,
        "A file to write the negotiated session to.",
    },
    {
        "-key",
        kOptionalArgument,
        "PEM-encoded file containing the private key.",
    },
    {
        "-cert",
        kOptionalArgument,
        "PEM-encoded file containing the leaf certificate and optional "
        "certificate chain. This is taken from the -key argument if this "
        "argument is not provided.",
    },
    {
        "-starttls",
        kOptionalArgument,
        "A STARTTLS mini-protocol to run before the TLS handshake. Supported"
        " values: 'smtp'",
    },
    {
        "-grease",
        kBooleanArgument,
        "Enable GREASE",
    },
    {
        "-permute-extensions",
        kBooleanArgument,
        "Permute extensions in handshake messages",
    },
    {
        "-test-resumption",
        kBooleanArgument,
        "Connect to the server twice. The first connection is closed once a "
        "session is established. The second connection offers it.",
    },
    {
        "-root-certs",
        kOptionalArgument,
        "A filename containing one or more PEM root certificates. Implies that "
        "verification is required.",
    },
    {
        "-root-cert-dir",
        kOptionalArgument,
        "A directory containing one or more root certificate PEM files in "
        "OpenSSL's hashed-directory format. Implies that verification is "
        "required.",
    },
    {
        "-early-data",
        kOptionalArgument,
        "Enable early data. The argument to "
        "this flag is the early data to send or if it starts with '@', the "
        "file to read from for early data.",
    },
    {
        "-http-tunnel",
        kOptionalArgument,
        "An HTTP proxy server to tunnel the TCP connection through",
    },
    {
        "-renegotiate-freely",
        kBooleanArgument,
        "Allow renegotiations from the peer.",
    },
    {
        "-request-trust-anchors",
        kOptionalArgument,
        "A comma-separated list of trust anchor IDs, in text form, to send to "
        "the server.",
    },
    {
        "-psk-hex",
        kOptionalArgument,
        "A hex-encoded pre-shared key to import (RFC 9258)",
    },
    {
        "-psk-identity",
        kOptionalArgument,
        "A PSK identity to configure",
    },
    {
        "-psk-context",
        kOptionalArgument,
        "A PSK context string to configure",
    },
    {
        "-psk-sha384",
        kBooleanArgument,
        "Use a SHA-384 PSK instead of a SHA-256 PSK.",
    },
    {
        "-rpk-key",
        kOptionalArgument,
        "PEM-encoded file containing the private key to use for a Raw Public "
        "Key (RFC 7250) client certificate if the server requests one.",
    },
    {
        "-accept-cert-types",
        kOptionalArgument,
        "A comma-separated list of cert types to accept from the server.",
    },
    {
        "-debug",
        kBooleanArgument,
        "Print debug information about the handshake",
    },
    {
        "",
        kOptionalArgument,
        "",
    },
};

static int NextProtoSelectCallback(SSL* ssl, uint8_t** out, uint8_t* outlen,
                                   const uint8_t* in, unsigned inlen, void* arg) {
  *out = reinterpret_cast<uint8_t *>(arg);
  *outlen = strlen(reinterpret_cast<const char *>(arg));
  return SSL_TLSEXT_ERR_OK;
}

static FILE *g_keylog_file = nullptr;

static void KeyLogCallback(const SSL *ssl, const char *line) {
  fprintf(g_keylog_file, "%s\n", line);
  fflush(g_keylog_file);
}

static bssl::UniquePtr<BIO> session_out;
static bssl::UniquePtr<SSL_SESSION> resume_session;

static int NewSessionCallback(SSL *ssl, SSL_SESSION *session) {
  if (session_out) {
    if (!PEM_write_bio_SSL_SESSION(session_out.get(), session) ||
        BIO_flush(session_out.get()) <= 0) {
      fprintf(stderr, "Error while saving session:\n");
      ERR_print_errors_fp(stderr);
      return 0;
    }
  }
  resume_session = bssl::UniquePtr<SSL_SESSION>(session);
  return 1;
}

static bool WaitForSession(SSL *ssl, int sock) {
  fd_set read_fds;
  FD_ZERO(&read_fds);

  if (!SocketSetNonBlocking(sock, true)) {
    return false;
  }

  while (!resume_session) {
#if defined(OPENSSL_WINDOWS)
    // Windows sockets are really of type SOCKET, not int, but everything here
    // casts them to ints. Clang gets unhappy about signed values as a result.
    //
    // TODO(davidben): Keep everything as the appropriate platform type.
    FD_SET(static_cast<SOCKET>(sock), &read_fds);
#else
    FD_SET(sock, &read_fds);
#endif
    int ret = select(sock + 1, &read_fds, NULL, NULL, NULL);
    if (ret <= 0) {
      perror("select");
      return false;
    }

    uint8_t buffer[512];
    int ssl_ret = SSL_read(ssl, buffer, sizeof(buffer));

    if (ssl_ret <= 0) {
      int ssl_err = SSL_get_error(ssl, ssl_ret);
      if (ssl_err == SSL_ERROR_WANT_READ) {
        continue;
      }
      PrintSSLError(stderr, "Error while reading", ssl_err, ssl_ret);
      return false;
    }
  }

  return true;
}

static bool DoConnection(SSL_CTX *ctx,
                         std::map<std::string, std::string> args_map,
                         bool (*cb)(SSL *ssl, int sock)) {
  int sock = -1;
  if (args_map.count("-http-tunnel") != 0) {
    if (!Connect(&sock, args_map["-http-tunnel"]) ||
        !DoHTTPTunnel(sock, args_map["-connect"])) {
      return false;
    }
  } else if (!Connect(&sock, args_map["-connect"])) {
    return false;
  }

  if (args_map.count("-starttls") != 0) {
    const std::string& starttls = args_map["-starttls"];
    if (starttls == "smtp") {
      if (!DoSMTPStartTLS(sock)) {
        return false;
      }
    } else {
      fprintf(stderr, "Unknown value for -starttls: %s\n", starttls.c_str());
      return false;
    }
  }

  bssl::UniquePtr<BIO> bio(BIO_new_socket(sock, BIO_CLOSE));
  bssl::UniquePtr<SSL> ssl(SSL_new(ctx));

  if (args_map.count("-server-name") != 0) {
    SSL_set_tlsext_host_name(ssl.get(), args_map["-server-name"].c_str());
  }

  if (args_map.count("-ech-grease") != 0) {
    SSL_set_enable_ech_grease(ssl.get(), 1);
  }

  if (args_map.count("-ech-config-list") != 0) {
    const char *filename = args_map["-ech-config-list"].c_str();
    ScopedFILE f(fopen(filename, "rb"));
    std::vector<uint8_t> data;
    if (f == nullptr || !ReadAll(&data, f.get())) {
      fprintf(stderr, "Error reading %s.\n", filename);
      return false;
    }
    if (!SSL_set1_ech_config_list(ssl.get(), data.data(), data.size())) {
      fprintf(stderr, "Error setting ECHConfigList\n");
      return false;
    }
  }

  if (args_map.count("-session-in") != 0) {
    bssl::UniquePtr<BIO> in(BIO_new_file(args_map["-session-in"].c_str(),
                                         "rb"));
    if (!in) {
      fprintf(stderr, "Error reading session\n");
      ERR_print_errors_fp(stderr);
      return false;
    }
    bssl::UniquePtr<SSL_SESSION> session(PEM_read_bio_SSL_SESSION(in.get(),
                                         nullptr, nullptr, nullptr));
    if (!session) {
      fprintf(stderr, "Error reading session\n");
      ERR_print_errors_fp(stderr);
      return false;
    }
    SSL_set_session(ssl.get(), session.get());
  }

  if (args_map.count("-renegotiate-freely") != 0) {
    SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_freely);
  }

  if (resume_session) {
    SSL_set_session(ssl.get(), resume_session.get());
  }

  SSL_set_bio(ssl.get(), bio.get(), bio.get());
  bio.release();

  int ret = SSL_connect(ssl.get());
  if (ret != 1) {
    int ssl_err = SSL_get_error(ssl.get(), ret);
    PrintSSLError(stderr, "Error while connecting", ssl_err, ret);
    return false;
  }

  if (args_map.count("-early-data") != 0 && SSL_in_early_data(ssl.get())) {
    std::string early_data = args_map["-early-data"];
    if (early_data.size() > 0 && early_data[0] == '@') {
      const char *filename = early_data.c_str() + 1;
      std::vector<uint8_t> data;
      ScopedFILE f(fopen(filename, "rb"));
      if (f == nullptr || !ReadAll(&data, f.get())) {
        fprintf(stderr, "Error reading %s.\n", filename);
        return false;
      }
      early_data = std::string(data.begin(), data.end());
    }
    if (!early_data.empty()) {
      int ed_size = early_data.size();
      int ssl_ret = SSL_write(ssl.get(), early_data.data(), ed_size);
      if (ssl_ret <= 0) {
        int ssl_err = SSL_get_error(ssl.get(), ssl_ret);
        PrintSSLError(stderr, "Error while writing", ssl_err, ssl_ret);
        return false;
      } else if (ssl_ret != ed_size) {
        fprintf(stderr, "Short write from SSL_write.\n");
        return false;
      }
    }
  }

  fprintf(stderr, "Connected.\n");
  bssl::UniquePtr<BIO> bio_stderr(BIO_new_fp(stderr, BIO_NOCLOSE));
  PrintConnectionInfo(bio_stderr.get(), ssl.get());

  return cb(ssl.get(), sock);
}

static void InfoCallback(const SSL *ssl, int type, int value) {
  switch (type) {
    case SSL_CB_HANDSHAKE_START:
      fprintf(stderr, "Handshake started.\n");
      break;
    case SSL_CB_HANDSHAKE_DONE:
      fprintf(stderr, "Handshake done.\n");
      break;
    case SSL_CB_CONNECT_LOOP:
      fprintf(stderr, "Handshake progress: %s\n", SSL_state_string_long(ssl));
      break;
  }
}

bool Client(const std::vector<std::string> &args) {
  if (!InitSocketLibrary()) {
    return false;
  }

  std::map<std::string, std::string> args_map;

  if (!ParseKeyValueArguments(&args_map, args, kArguments)) {
    PrintUsage(kArguments);
    return false;
  }

  bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));

  const char *keylog_file = getenv("SSLKEYLOGFILE");
  if (keylog_file) {
    g_keylog_file = fopen(keylog_file, "a");
    if (g_keylog_file == nullptr) {
      perror("fopen");
      return false;
    }
    SSL_CTX_set_keylog_callback(ctx.get(), KeyLogCallback);
  }

  if (args_map.count("-cipher") != 0 &&
      !SSL_CTX_set_strict_cipher_list(ctx.get(), args_map["-cipher"].c_str())) {
    fprintf(stderr, "Failed setting cipher list\n");
    return false;
  }

  if (args_map.count("-curves") != 0 &&
      !SSL_CTX_set1_curves_list(ctx.get(), args_map["-curves"].c_str())) {
    fprintf(stderr, "Failed setting curves list\n");
    return false;
  }

  if (args_map.count("-sigalgs") != 0 &&
      !SSL_CTX_set1_sigalgs_list(ctx.get(), args_map["-sigalgs"].c_str())) {
    fprintf(stderr, "Failed setting signature algorithms list\n");
    return false;
  }

  uint16_t max_version = TLS1_3_VERSION;
  if (args_map.count("-max-version") != 0 &&
      !VersionFromString(&max_version, args_map["-max-version"])) {
    fprintf(stderr, "Unknown protocol version: '%s'\n",
            args_map["-max-version"].c_str());
    return false;
  }

  if (!SSL_CTX_set_max_proto_version(ctx.get(), max_version)) {
    return false;
  }

  if (args_map.count("-min-version") != 0) {
    uint16_t version;
    if (!VersionFromString(&version, args_map["-min-version"])) {
      fprintf(stderr, "Unknown protocol version: '%s'\n",
              args_map["-min-version"].c_str());
      return false;
    }
    if (!SSL_CTX_set_min_proto_version(ctx.get(), version)) {
      return false;
    }
  }

  if (args_map.count("-select-next-proto") != 0) {
    const std::string &proto = args_map["-select-next-proto"];
    if (proto.size() > 255) {
      fprintf(stderr, "Bad NPN protocol: '%s'\n", proto.c_str());
      return false;
    }
    // `SSL_CTX_set_next_proto_select_cb` is not const-correct.
    SSL_CTX_set_next_proto_select_cb(ctx.get(), NextProtoSelectCallback,
                                     const_cast<char *>(proto.c_str()));
  }

  if (args_map.count("-alpn-protos") != 0) {
    const std::string &alpn_protos = args_map["-alpn-protos"];
    std::vector<uint8_t> wire;
    for (std::string_view proto : SplitString(alpn_protos, ",")) {
      if (proto.empty() || proto.size() > 255) {
        fprintf(stderr, "Invalid ALPN protocols: '%s'\n", alpn_protos.c_str());
        return false;
      }
      wire.push_back(static_cast<uint8_t>(proto.size()));
      wire.insert(wire.end(), proto.begin(), proto.end());
    }
    if (SSL_CTX_set_alpn_protos(ctx.get(), wire.data(), wire.size()) != 0) {
      return false;
    }
  }

  if (args_map.count("-fallback-scsv") != 0) {
    SSL_CTX_set_mode(ctx.get(), SSL_MODE_SEND_FALLBACK_SCSV);
  }

  if (args_map.count("-ocsp-stapling") != 0) {
    SSL_CTX_enable_ocsp_stapling(ctx.get());
  }

  if (args_map.count("-signed-certificate-timestamps") != 0) {
    SSL_CTX_enable_signed_cert_timestamps(ctx.get());
  }

  if (args_map.count("-channel-id-key") != 0) {
    bssl::UniquePtr<EVP_PKEY> pkey =
        LoadPrivateKeyFile(args_map["-channel-id-key"]);
    if (!pkey || !SSL_CTX_set1_tls_channel_id(ctx.get(), pkey.get())) {
      return false;
    }
  }

  if (args_map.count("-false-start") != 0) {
    SSL_CTX_set_mode(ctx.get(), SSL_MODE_ENABLE_FALSE_START);
  }

  if (args_map.count("-key") != 0) {
    const std::string &key = args_map["-key"];
    if (!SSL_CTX_use_PrivateKey_file(ctx.get(), key.c_str(),
                                     SSL_FILETYPE_PEM)) {
      fprintf(stderr, "Failed to load private key: %s\n", key.c_str());
      return false;
    }
    const std::string &cert =
        args_map.count("-cert") != 0 ? args_map["-cert"] : key;
    if (!SSL_CTX_use_certificate_chain_file(ctx.get(), cert.c_str())) {
      fprintf(stderr, "Failed to load cert chain: %s\n", cert.c_str());
      return false;
    }
  }

  if (args_map.count("-rpk-key") != 0) {
    UniquePtr<EVP_PKEY> pkey = LoadPrivateKeyFile(args_map["-rpk-key"]);
    if (!pkey) {
      return false;
    }
    UniquePtr<SSL_CREDENTIAL> cred(
        SSL_CREDENTIAL_new_raw_public_key(pkey.get()));
    if (!cred || !SSL_CTX_add1_credential(ctx.get(), cred.get())) {
      fprintf(stderr, "Failed to add RPK\n");
      return false;
    }
  }

  if (auto psk_hex = args_map.find("-psk-hex"); psk_hex != args_map.end()) {
    auto psk = DecodeHex(psk_hex->second);
    if (!psk) {
      fprintf(stderr, "Could not convert PSK from hex\n");
      return false;
    }
    auto psk_id_arg = args_map.find("-psk-identity");
    if (psk_id_arg == args_map.end()) {
      fprintf(stderr, "No PSK identity specified\n");
      return false;
    }
    Span<const uint8_t> psk_id = StringAsBytes(psk_id_arg->second);
    Span<const uint8_t> psk_context;
    if (auto it = args_map.find("-psk-context"); it != args_map.end()) {
      psk_context = StringAsBytes(it->second);
    }
    const EVP_MD *psk_md =
        args_map.count("-psk-sha384") ? EVP_sha384() : EVP_sha256();
    UniquePtr<SSL_CREDENTIAL> cred(SSL_CREDENTIAL_new_pre_shared_key(
        psk->data(), psk->size(), psk_id.data(), psk_id.size(), psk_md,
        psk_context.data(), psk_context.size()));
    if (!cred || !SSL_CTX_add1_credential(ctx.get(), cred.get())) {
      fprintf(stderr, "Failed to load PSK\n");
      return false;
    }
  }

  SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_CLIENT);
  SSL_CTX_sess_set_new_cb(ctx.get(), NewSessionCallback);

  if (args_map.count("-session-out") != 0) {
    session_out.reset(BIO_new_file(args_map["-session-out"].c_str(), "wb"));
    if (!session_out) {
      fprintf(stderr, "Error while opening %s:\n",
              args_map["-session-out"].c_str());
      ERR_print_errors_fp(stderr);
      return false;
    }
  }

  if (args_map.count("-grease") != 0) {
    SSL_CTX_set_grease_enabled(ctx.get(), 1);
  }

  if (args_map.count("-permute-extensions") != 0) {
    SSL_CTX_set_permute_extensions(ctx.get(), 1);
  }

  // Configure accepted roots.
  if (args_map.count("-root-certs") != 0) {
    if (!SSL_CTX_load_verify_locations(
            ctx.get(), args_map["-root-certs"].c_str(), nullptr)) {
      fprintf(stderr, "Failed to load root certificates.\n");
      ERR_print_errors_fp(stderr);
      return false;
    }
    SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER, nullptr);
  }
  if (args_map.count("-root-cert-dir") != 0) {
    if (!SSL_CTX_load_verify_locations(
            ctx.get(), nullptr, args_map["-root-cert-dir"].c_str())) {
      fprintf(stderr, "Failed to load root certificates.\n");
      ERR_print_errors_fp(stderr);
      return false;
    }
    SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER, nullptr);
  }
  // Otherwise, just require the server to send any cert.
  if (args_map.count("-root-certs") == 0 &&
      args_map.count("-root-cert-dir") == 0) {
    SSL_CTX_set_custom_verify(
        ctx.get(), SSL_VERIFY_PEER,
        [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
          return ssl_verify_ok;
        });
  }

  if (args_map.count("-request-trust-anchors") != 0) {
    const std::string &trust_anchors = args_map["-request-trust-anchors"];
    bssl::ScopedCBB cbb;
    if (!CBB_init(cbb.get(), 32)) {
      return false;
    }
    // Treat an empty input as requesting no trust anchors, rather than a single
    // empty string.
    if (!trust_anchors.empty()) {
      for (std::string_view trust_anchor : SplitString(trust_anchors, ",")) {
        trust_anchor = TrimSpace(trust_anchor);
        CBB id;
        if (!CBB_add_u8_length_prefixed(cbb.get(), &id) ||
            !CBB_add_asn1_relative_oid_from_text(&id, trust_anchor.data(),
                                                 trust_anchor.size()) ||
            !CBB_flush(cbb.get())) {
          fprintf(stderr, "Invalid trust anchor ID list: '%s'\n",
                  trust_anchors.c_str());
          return false;
        }
      }
    }
    if (!SSL_CTX_set1_requested_trust_anchors(ctx.get(), CBB_data(cbb.get()),
                                              CBB_len(cbb.get()))) {
      return false;
    }
  }

  if (args_map.count("-early-data") != 0) {
    SSL_CTX_set_early_data_enabled(ctx.get(), 1);
  }

  if (args_map.count("-accept-cert-types") != 0) {
    auto accepted_client_cert_types =
        CertificateTypesFromString(args_map["-accept-cert-types"]);
    if (!accepted_client_cert_types.has_value() ||
        !SSL_CTX_set1_accepted_peer_cert_types(
            ctx.get(), accepted_client_cert_types->data(),
            accepted_client_cert_types->size())) {
      return false;
    }
  }

  if (args_map.count("-debug") != 0) {
    SSL_CTX_set_info_callback(ctx.get(), InfoCallback);
  }

  if (args_map.count("-test-resumption") != 0) {
    if (args_map.count("-session-in") != 0) {
      fprintf(stderr,
              "Flags -session-in and -test-resumption are incompatible.\n");
      return false;
    }

    if (!DoConnection(ctx.get(), args_map, &WaitForSession)) {
      return false;
    }
  }

  return DoConnection(ctx.get(), args_map, &TransferData);
}

BSSL_NAMESPACE_END
