// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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
//
//   http://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 "kudu/security/tls_handshake.h"

#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>

#include <cstdint>
#include <memory>
#include <string>
#include <ostream>
#include <utility>

#include "kudu/gutil/strings/strip.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/security/cert.h"
#include "kudu/security/tls_socket.h"
#include "kudu/util/net/socket.h"
#include "kudu/util/openssl_util.h"
#include "kudu/util/status.h"
#include "kudu/util/trace.h"

#if OPENSSL_VERSION_NUMBER < 0x10002000L
#include "kudu/security/x509_check_host.h"
#endif // OPENSSL_VERSION_NUMBER

#ifndef TLS1_3_VERSION
#define TLS1_3_VERSION 0x0304
#endif

using std::string;
using std::unique_ptr;
using strings::Substitute;

namespace kudu {
namespace security {

void TlsHandshake::SetSSLVerify() {
  SCOPED_OPENSSL_NO_PENDING_ERRORS;
  CHECK(ssl_);
  CHECK(!has_started_);
  int ssl_mode = 0;
  switch (verification_mode_) {
    case TlsVerificationMode::VERIFY_NONE:
      ssl_mode = SSL_VERIFY_NONE;
      break;
    case TlsVerificationMode::VERIFY_REMOTE_CERT_AND_HOST:
      // Server mode: the server sends a client certificate request to the client. The
      // certificate returned (if any) is checked. If the verification process fails, the TLS/SSL
      // handshake is immediately terminated with an alert message containing the reason for the
      // verification failure. The behaviour can be controlled by the additional
      // SSL_VERIFY_FAIL_IF_NO_PEER_CERT and SSL_VERIFY_CLIENT_ONCE flags.

      // Client mode: the server certificate is verified. If the verification process fails, the
      // TLS/SSL handshake is immediately terminated with an alert message containing the reason
      // for the verification failure. If no server certificate is sent, because an anonymous
      // cipher is used, SSL_VERIFY_PEER is ignored.
      ssl_mode |= SSL_VERIFY_PEER;

      // Server mode: if the client did not return a certificate, the TLS/SSL handshake is
      // immediately terminated with a "handshake failure" alert. This flag must be used
      // together with SSL_VERIFY_PEER.
      ssl_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
      // Server mode: only request a client certificate on the initial TLS/SSL handshake. Do
      // not ask for a client certificate again in case of a renegotiation. This flag must be
      // used together with SSL_VERIFY_PEER.
      ssl_mode |= SSL_VERIFY_CLIENT_ONCE;
      break;
  }

  SSL_set_verify(ssl_.get(), ssl_mode, /* callback = */nullptr);
}

TlsHandshake::TlsHandshake(TlsHandshakeType type)
    : type_(type) {
}

Status TlsHandshake::Init(c_unique_ptr<SSL> s) {
  SCOPED_OPENSSL_NO_PENDING_ERRORS;
  DCHECK(s);

  if (ssl_) {
    return Status::IllegalState("TlsHandshake is already initialized");
  }

  auto rbio = ssl_make_unique(BIO_new(BIO_s_mem()));
  if (!rbio) {
    return Status::RuntimeError(
        "failed to create memory-based read BIO", GetOpenSSLErrors());
  }
  auto wbio = ssl_make_unique(BIO_new(BIO_s_mem()));
  if (!wbio) {
    return Status::RuntimeError(
        "failed to create memory-based write BIO", GetOpenSSLErrors());
  }
  ssl_ = std::move(s);
  auto* ssl = ssl_.get();
  SSL_set_bio(ssl, rbio.release(), wbio.release());

  switch (type_) {
    case TlsHandshakeType::SERVER:
      SSL_set_accept_state(ssl);
      break;
    case TlsHandshakeType::CLIENT:
      SSL_set_connect_state(ssl);
      break;
  }
  return Status::OK();
}

Status TlsHandshake::Continue(const string& recv, string* send) {
  SCOPED_OPENSSL_NO_PENDING_ERRORS;
  if (!has_started_) {
    SetSSLVerify();
    has_started_ = true;
  }
  DCHECK(ssl_);
  auto* ssl = ssl_.get();

  // +------+                       +-----+
  // |      |--> BIO_write(rbio) -->|     |--> SSL_read(ssl)  --> IN
  // | SASL |                       | SSL |
  // |      |<--  BIO_read(wbio) <--|     |<-- SSL_write(ssl) <-- OUT
  // +------+                       +-----+
  BIO* rbio = SSL_get_rbio(ssl);
  int n = BIO_write(rbio, recv.data(), recv.size());
  DCHECK(n == recv.size() || (n == -1 && recv.empty()));
  DCHECK_EQ(BIO_ctrl_pending(rbio), recv.size());

  int rc = SSL_do_handshake(ssl);
  if (rc != 1) {
    int ssl_err = SSL_get_error(ssl, rc);
    // WANT_READ and WANT_WRITE indicate that the handshake is not yet complete.
    if (ssl_err != SSL_ERROR_WANT_READ && ssl_err != SSL_ERROR_WANT_WRITE) {
      return Status::RuntimeError("TLS Handshake error", GetSSLErrorDescription(ssl_err));
    }
    // In the case that we got SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE,
    // the OpenSSL implementation guarantees that there is no error entered into
    // the ERR error queue, so no need to ERR_clear_error() here.
  }

  BIO* wbio = SSL_get_wbio(ssl);
  int pending = BIO_ctrl_pending(wbio);
  DCHECK_GE(pending, 0);

  send->resize(pending);
  if (pending > 0) {
    int bytes_read = BIO_read(wbio, &(*send)[0], send->size());
    DCHECK_EQ(bytes_read, send->size());
    DCHECK_EQ(BIO_ctrl_pending(wbio), 0);
  }

  if (rc == 1) {
    // SSL_do_handshake() must have read all the pending data.
    DCHECK_EQ(0, BIO_ctrl_pending(rbio));
    VLOG(2) << Substitute("TSL Handshake complete");
    return Status::OK();
  }
  return Status::Incomplete("TLS Handshake incomplete");
}

bool TlsHandshake::NeedsExtraStep(const Status& continue_status,
                                  const string& token) const {
  DCHECK(has_started_);
  DCHECK(ssl_);
  DCHECK(continue_status.ok() || continue_status.IsIncomplete());

  if (continue_status.IsIncomplete()) {
    return true;
  }
  if (continue_status.ok()) {
    switch (type_) {
      case TlsHandshakeType::CLIENT:
        return !token.empty();
      case TlsHandshakeType::SERVER:
        if (SSL_version(ssl_.get()) == TLS1_3_VERSION) {
          return false;
        }
        return !token.empty();
    }
  }
  return false;
}

void TlsHandshake::StorePendingData(string data) {
  DCHECK(!data.empty());
  // This is used only for the TLSv1.3 protocol.
  DCHECK_EQ(TLS1_3_VERSION, SSL_version(ssl_.get()));
  rbio_pending_data_ = std::move(data);
}

Status TlsHandshake::Verify(const Socket& /*socket*/) const {
  SCOPED_OPENSSL_NO_PENDING_ERRORS;
  DCHECK(SSL_is_init_finished(ssl_.get()));
  CHECK(ssl_);

  if (verification_mode_ == TlsVerificationMode::VERIFY_NONE) {
    return Status::OK();
  }
  DCHECK(verification_mode_ == TlsVerificationMode::VERIFY_REMOTE_CERT_AND_HOST);

  int rc = SSL_get_verify_result(ssl_.get());
  if (rc != X509_V_OK) {
    return Status::NotAuthorized(Substitute("SSL cert verification failed: $0",
                                            X509_verify_cert_error_string(rc)),
                                 GetOpenSSLErrors());
  }

  // Get the peer certificate.
  X509* cert = remote_cert_.GetTopOfChainX509();
  if (!cert) {
    if (SSL_get_verify_mode(ssl_.get()) & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
      return Status::NotAuthorized("Handshake failed: unable to retreive peer certificate");
    }
    // No cert, but we weren't requiring one.
    TRACE("Got no cert from peer, but not required");
    return Status::OK();
  }

  // TODO(KUDU-1886): Do hostname verification.
  /*
  TRACE("Verifying peer cert");

  // Get the peer's hostname
  Sockaddr peer_addr;
  if (!socket.GetPeerAddress(&peer_addr).ok()) {
    return Status::NotAuthorized(
        "TLS certificate hostname verification failed: unable to get peer address");
  }
  string peer_hostname;
  RETURN_NOT_OK_PREPEND(peer_addr.LookupHostname(&peer_hostname),
      "TLS certificate hostname verification failed: unable to lookup peer hostname");

  // Check if the hostname matches with either the Common Name or any of the Subject Alternative
  // Names of the certificate.
  int match = X509_check_host(cert,
                              peer_hostname.c_str(),
                              peer_hostname.length(),
                              0,
                              nullptr);
  if (match == 0) {
    return Status::NotAuthorized("TLS certificate hostname verification failed");
  }
  if (match < 0) {
    return Status::RuntimeError("TLS certificate hostname verification error", GetOpenSSLErrors());
  }
  DCHECK_EQ(match, 1);
  */
  return Status::OK();
}

Status TlsHandshake::GetCerts() {
  SCOPED_OPENSSL_NO_PENDING_ERRORS;
  X509* cert = SSL_get_certificate(ssl_.get());
  if (cert) {
    // For whatever reason, SSL_get_certificate (unlike SSL_get_peer_certificate)
    // does not increment the X509's reference count.
    local_cert_.AdoptAndAddRefX509(cert);
  }

  cert = SSL_get_peer_certificate(ssl_.get());
  if (cert) {
    remote_cert_.AdoptX509(cert);
  }
  return Status::OK();
}

Status TlsHandshake::Finish(unique_ptr<Socket>* socket) {
  SCOPED_OPENSSL_NO_PENDING_ERRORS;
  RETURN_NOT_OK(GetCerts());
  RETURN_NOT_OK(Verify(**socket));

  int fd = (*socket)->Release();
  auto* ssl = ssl_.get();

  // Nothing should left in the memory-based BIOs upon Finish() is called.
  // Otherwise, the buffered data would be lost because those BIOs are destroyed
  // when SSL_set_fd() is called below.
  DCHECK_EQ(0, SSL_pending(ssl));

  BIO* wbio = SSL_get_wbio(ssl);
  DCHECK_EQ(0, BIO_ctrl_pending(wbio));
  DCHECK_EQ(0, BIO_ctrl_wpending(wbio));

  BIO* rbio = SSL_get_rbio(ssl);
  DCHECK_EQ(0, BIO_ctrl_pending(rbio));
  DCHECK_EQ(0, BIO_ctrl_wpending(rbio));

  // Give the socket to the SSL instance. This will automatically free the
  // read and write memory BIO instances.
  int ret = SSL_set_fd(ssl, fd);
  if (ret != 1) {
    return Status::RuntimeError("TLS handshake error", GetOpenSSLErrors());
  }

  const auto data_size = rbio_pending_data_.size();
  if (data_size != 0) {
    int fd = SSL_get_fd(ssl);
    Socket sock(fd);
    const uint8_t* data = reinterpret_cast<const uint8_t*>(rbio_pending_data_.data());
    int32_t written = 0;
    RETURN_NOT_OK(sock.Write(data, data_size, &written));
    if (written != data_size) {
      // The socket should be in blocking mode, so Write() should return with
      // success only if all the data is written.
      return Status::IllegalState(
          Substitute("wrote only $0 out of $1 bytes", written, data_size));
    }
    sock.Release(); // do not close the descriptor when Socket goes out of scope
    rbio_pending_data_.clear();
  }

  // Transfer the SSL instance to the socket.
  socket->reset(new TlsSocket(fd, std::move(ssl_)));

  return Status::OK();
}

Status TlsHandshake::FinishNoWrap(const Socket& socket) {
  SCOPED_OPENSSL_NO_PENDING_ERRORS;
  RETURN_NOT_OK(GetCerts());
  return Verify(socket);
}

Status TlsHandshake::GetLocalCert(Cert* cert) const {
  SCOPED_OPENSSL_NO_PENDING_ERRORS;
  if (!local_cert_.GetRawData()) {
    return Status::RuntimeError("no local certificate");
  }
  cert->AdoptAndAddRefRawData(local_cert_.GetRawData());
  return Status::OK();
}

Status TlsHandshake::GetRemoteCert(Cert* cert) const {
  SCOPED_OPENSSL_NO_PENDING_ERRORS;
  if (!remote_cert_.GetRawData()) {
    return Status::RuntimeError("no remote certificate");
  }
  cert->AdoptAndAddRefRawData(remote_cert_.GetRawData());
  return Status::OK();
}

string TlsHandshake::GetCipherSuite() const {
  SCOPED_OPENSSL_NO_PENDING_ERRORS;
  CHECK(has_started_);
  return SSL_get_cipher_name(ssl_.get());
}

string TlsHandshake::GetProtocol() const {
  SCOPED_OPENSSL_NO_PENDING_ERRORS;
  CHECK(has_started_);
  return SSL_get_version(ssl_.get());
}

string TlsHandshake::GetCipherDescription() const {
  SCOPED_OPENSSL_NO_PENDING_ERRORS;
  CHECK(has_started_);
  const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_.get());
  if (!cipher) {
    return "NONE";
  }
  char buf[512];
  const char* description = SSL_CIPHER_description(cipher, buf, sizeof(buf));
  if (!description) {
    return "NONE";
  }
  string ret(description);
  StripTrailingNewline(&ret);
  StripDupCharacters(&ret, ' ', 0);
  return ret;
}

} // namespace security
} // namespace kudu
