// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
// Copyright 2005 Nokia. All rights reserved.
//
// 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/ssl.h>

#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include <utility>

#include <openssl/cipher.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>
#include <openssl/pool.h>
#include <openssl/rand.h>

#include "../crypto/internal.h"
#include "internal.h"


BSSL_NAMESPACE_BEGIN

// The address of this is a magic value, a pointer to which is returned by
// SSL_magic_pending_session_ptr(). It allows a session callback to indicate
// that it needs to asynchronously fetch session information.
static const char g_pending_session_magic = 0;

static ExDataClass g_ex_data_class(/*with_app_data=*/true);

static void SSL_SESSION_list_remove(SSLContext *ctx, SSL_SESSION *session);
static void SSL_SESSION_list_add(SSLContext *ctx, SSL_SESSION *session);

static Span<const uint8_t> ssl_handshake_session_id_context(
    const SSL_HANDSHAKE *hs) {
  if (hs->ssl->server && hs->credential != nullptr &&
      !hs->credential->sid_ctx.empty()) {
    return hs->credential->sid_ctx;
  }
  return hs->config->cert->sid_ctx;
}

UniquePtr<SSL_SESSION> ssl_session_new(const SSL_X509_METHOD *x509_method) {
  return MakeUnique<SSL_SESSION>(x509_method);
}

uint32_t ssl_hash_session_id(Span<const uint8_t> session_id) {
  // Take the first four bytes of `session_id`. Session IDs are generated by the
  // server randomly, so we can assume even using the first four bytes results
  // in a good distribution.
  uint8_t tmp_storage[sizeof(uint32_t)];
  if (session_id.size() < sizeof(tmp_storage)) {
    OPENSSL_memset(tmp_storage, 0, sizeof(tmp_storage));
    OPENSSL_memcpy(tmp_storage, session_id.data(), session_id.size());
    session_id = tmp_storage;
  }

  uint32_t hash = ((uint32_t)session_id[0]) | ((uint32_t)session_id[1] << 8) |
                  ((uint32_t)session_id[2] << 16) |
                  ((uint32_t)session_id[3] << 24);

  return hash;
}

UniquePtr<SSL_SESSION> SSL_SESSION_dup(const SSL_SESSION *session,
                                       int dup_flags) {
  UniquePtr<SSL_SESSION> new_session = ssl_session_new(session->x509_method);
  if (!new_session) {
    return nullptr;
  }

  new_session->is_server = session->is_server;
  new_session->ssl_version = session->ssl_version;
  new_session->is_quic = session->is_quic;
  new_session->sid_ctx = session->sid_ctx;

  // Copy the key material.
  new_session->secret = session->secret;
  new_session->cipher = session->cipher;

  // Copy authentication state.
  if (session->psk_identity != nullptr) {
    new_session->psk_identity.reset(
        OPENSSL_strdup(session->psk_identity.get()));
    if (new_session->psk_identity == nullptr) {
      return nullptr;
    }
  }
  new_session->peer_cert_type = session->peer_cert_type;
  if (session->certs != nullptr) {
    new_session->certs.reset(sk_CRYPTO_BUFFER_deep_copy(
        session->certs.get(), CRYPTO_BUFFER_dup_ref, CRYPTO_BUFFER_free));
    if (new_session->certs == nullptr) {
      return nullptr;
    }
  }
  if (session->peer_raw_public_key != nullptr) {
    new_session->peer_raw_public_key = UpRef(session->peer_raw_public_key);
  }

  if (!session->x509_method->session_dup(new_session.get(), session)) {
    return nullptr;
  }

  new_session->verify_result = session->verify_result;

  new_session->ocsp_response = UpRef(session->ocsp_response);
  new_session->signed_cert_timestamp_list =
      UpRef(session->signed_cert_timestamp_list);

  OPENSSL_memcpy(new_session->peer_sha256, session->peer_sha256,
                 SHA256_DIGEST_LENGTH);
  new_session->peer_sha256_valid = session->peer_sha256_valid;

  new_session->peer_signature_algorithm = session->peer_signature_algorithm;

  new_session->timeout = session->timeout;
  new_session->auth_timeout = session->auth_timeout;
  new_session->time = session->time;

  // Copy non-authentication connection properties.
  if (dup_flags & SSL_SESSION_INCLUDE_NONAUTH) {
    new_session->session_id = session->session_id;
    new_session->group_id = session->group_id;
    new_session->original_handshake_hash = session->original_handshake_hash;
    new_session->ticket_lifetime_hint = session->ticket_lifetime_hint;
    new_session->ticket_age_add = session->ticket_age_add;
    new_session->ticket_max_early_data = session->ticket_max_early_data;
    new_session->extended_master_secret = session->extended_master_secret;
    new_session->has_application_settings = session->has_application_settings;

    if (!new_session->early_alpn.CopyFrom(session->early_alpn) ||
        !new_session->quic_early_data_context.CopyFrom(
            session->quic_early_data_context) ||
        !new_session->local_application_settings.CopyFrom(
            session->local_application_settings) ||
        !new_session->peer_application_settings.CopyFrom(
            session->peer_application_settings)) {
      return nullptr;
    }
  }

  // Copy the ticket.
  if (dup_flags & SSL_SESSION_INCLUDE_TICKET &&
      !new_session->ticket.CopyFrom(session->ticket)) {
    return nullptr;
  }

  // The new_session does not get a copy of the ex_data.

  new_session->not_resumable = true;
  return new_session;
}

void ssl_session_rebase_time(SSLImpl *ssl, SSL_SESSION *session) {
  OPENSSL_timeval now = ssl_ctx_get_current_time(ssl->ctx.get());

  // To avoid overflows and underflows, if we've gone back in time, update the
  // time, but mark the session expired.
  if (session->time > now.tv_sec) {
    session->time = now.tv_sec;
    session->timeout = 0;
    session->auth_timeout = 0;
    return;
  }

  // Adjust the session time and timeouts. If the session has already expired,
  // clamp the timeouts at zero.
  uint64_t delta = now.tv_sec - session->time;
  session->time = now.tv_sec;
  if (session->timeout < delta) {
    session->timeout = 0;
  } else {
    session->timeout -= delta;
  }
  if (session->auth_timeout < delta) {
    session->auth_timeout = 0;
  } else {
    session->auth_timeout -= delta;
  }
}

void ssl_session_renew_timeout(SSLImpl *ssl, SSL_SESSION *session,
                               uint32_t timeout) {
  // Rebase the timestamp relative to the current time so `timeout` is measured
  // correctly.
  ssl_session_rebase_time(ssl, session);

  if (session->timeout > timeout) {
    return;
  }

  session->timeout = timeout;
  if (session->timeout > session->auth_timeout) {
    session->timeout = session->auth_timeout;
  }
}

uint16_t ssl_session_protocol_version(const SSL_SESSION *session) {
  uint16_t ret;
  if (!ssl_protocol_version_from_wire(&ret, session->ssl_version)) {
    // An `SSL_SESSION` will never have an invalid version. This is enforced by
    // the parser.
    assert(0);
    return 0;
  }

  return ret;
}

const EVP_MD *ssl_session_get_digest(const SSL_SESSION *session) {
  return ssl_get_handshake_digest(ssl_session_protocol_version(session),
                                  session->cipher);
}

bool ssl_get_new_session(SSL_HANDSHAKE *hs) {
  SSLImpl *const ssl = hs->ssl;
  if (ssl->mode & SSL_MODE_NO_SESSION_CREATION) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_SESSION_MAY_NOT_BE_CREATED);
    return false;
  }

  UniquePtr<SSL_SESSION> session = ssl_session_new(ssl->ctx->x509_method);
  if (session == nullptr) {
    return false;
  }

  session->is_server = ssl->server;
  session->ssl_version = ssl->s3->version;
  session->is_quic = SSL_is_quic(ssl);

  // Fill in the time from the `SSL_CTX`'s clock.
  OPENSSL_timeval now = ssl_ctx_get_current_time(ssl->ctx.get());
  session->time = now.tv_sec;

  uint16_t version = ssl_protocol_version(ssl);
  if (version >= TLS1_3_VERSION) {
    // TLS 1.3 uses tickets as authenticators, so we are willing to use them for
    // longer.
    session->timeout = ssl->session_ctx->session_psk_dhe_timeout;
    session->auth_timeout = SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
  } else {
    // TLS 1.2 resumption does not incorporate new key material, so we use a
    // much shorter timeout.
    session->timeout = ssl->session_ctx->session_timeout;
    session->auth_timeout = ssl->session_ctx->session_timeout;
  }

  if (!session->sid_ctx.TryCopyFrom(ssl_handshake_session_id_context(hs))) {
    return false;
  }

  // The session is marked not resumable until it is completely filled in.
  session->not_resumable = true;
  session->verify_result = X509_V_ERR_INVALID_CALL;

  hs->new_session = std::move(session);
  ssl_set_session(ssl, nullptr);
  return true;
}

bool ssl_ctx_rotate_ticket_encryption_key(SSLContext *ctx) {
  OPENSSL_timeval now = ssl_ctx_get_current_time(ctx);
  {
    // Avoid acquiring a write lock in the common case (i.e. a non-default key
    // is used or the default keys have not expired yet).
    MutexReadLock lock(&ctx->lock);
    if (ctx->ticket_key_current &&
        (ctx->ticket_key_current->next_rotation_tv_sec == 0 ||
         ctx->ticket_key_current->next_rotation_tv_sec > now.tv_sec) &&
        (!ctx->ticket_key_prev ||
         ctx->ticket_key_prev->next_rotation_tv_sec > now.tv_sec)) {
      return true;
    }
  }

  MutexWriteLock lock(&ctx->lock);
  if (!ctx->ticket_key_current ||
      (ctx->ticket_key_current->next_rotation_tv_sec != 0 &&
       ctx->ticket_key_current->next_rotation_tv_sec <= now.tv_sec)) {
    // The current key has not been initialized or it is expired.
    auto new_key = bssl::MakeUnique<TicketKey>();
    if (!new_key) {
      return false;
    }
    RAND_bytes(new_key->name, 16);
    RAND_bytes(new_key->hmac_key, 16);
    RAND_bytes(new_key->aes_key, 16);
    new_key->next_rotation_tv_sec =
        now.tv_sec + SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
    if (ctx->ticket_key_current) {
      // The current key expired. Rotate it to prev and bump up its rotation
      // timestamp. Note that even with the new rotation time it may still be
      // expired and get dropped below.
      ctx->ticket_key_current->next_rotation_tv_sec +=
          SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
      ctx->ticket_key_prev = std::move(ctx->ticket_key_current);
    }
    ctx->ticket_key_current = std::move(new_key);
  }

  // Drop an expired prev key.
  if (ctx->ticket_key_prev &&
      ctx->ticket_key_prev->next_rotation_tv_sec <= now.tv_sec) {
    ctx->ticket_key_prev.reset();
  }

  return true;
}

static int ssl_encrypt_ticket_with_cipher_ctx(SSL_HANDSHAKE *hs, CBB *out,
                                              const uint8_t *session_buf,
                                              size_t session_len) {
  ScopedEVP_CIPHER_CTX ctx;
  ScopedHMAC_CTX hctx;

  // If the session is too long, decline to send a ticket.
  static const size_t kMaxTicketOverhead =
      16 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE;
  if (session_len > 0xffff - kMaxTicketOverhead) {
    return 1;
  }

  // Initialize HMAC and cipher contexts. If callback present it does all the
  // work otherwise use generated values from parent ctx.
  SSLContext *tctx = hs->ssl->session_ctx.get();
  uint8_t iv[EVP_MAX_IV_LENGTH];
  uint8_t key_name[16];
  if (tctx->ticket_key_cb != nullptr) {
    int ret = tctx->ticket_key_cb(hs->ssl, key_name, iv, ctx.get(), hctx.get(),
                                  1 /* encrypt */);
    if (ret < 0) {
      return 0;
    }
    if (ret == 0) {
      // The caller requested to send no ticket, so write nothing to `out`.
      return 1;
    }
  } else {
    // Rotate ticket key if necessary.
    if (!ssl_ctx_rotate_ticket_encryption_key(tctx)) {
      return 0;
    }
    MutexReadLock lock(&tctx->lock);
    if (!RAND_bytes(iv, 16) ||
        !EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr,
                            tctx->ticket_key_current->aes_key, iv) ||
        !HMAC_Init_ex(hctx.get(), tctx->ticket_key_current->hmac_key, 16,
                      tlsext_tick_md(), nullptr)) {
      return 0;
    }
    OPENSSL_memcpy(key_name, tctx->ticket_key_current->name, 16);
  }

  uint8_t *ptr;
  if (!CBB_add_bytes(out, key_name, 16) ||
      !CBB_add_bytes(out, iv, EVP_CIPHER_CTX_iv_length(ctx.get())) ||
      !CBB_reserve(out, &ptr, session_len + EVP_MAX_BLOCK_LENGTH)) {
    return 0;
  }

  size_t total = 0;
  if (CRYPTO_fuzzer_mode_enabled()) {
    OPENSSL_memcpy(ptr, session_buf, session_len);
    total = session_len;
  } else {
    size_t len;
    if (!EVP_EncryptUpdate_ex(ctx.get(), ptr + total, &len,
                              session_len + EVP_MAX_BLOCK_LENGTH - total,
                              session_buf, session_len)) {
      return 0;
    }
    total += len;
    if (!EVP_EncryptFinal_ex2(ctx.get(), ptr + total, &len,
                              session_len + EVP_MAX_BLOCK_LENGTH - total)) {
      return 0;
    }
    total += len;
  }
  if (!CBB_did_write(out, total)) {
    return 0;
  }

  unsigned hlen;
  if (!HMAC_Update(hctx.get(), CBB_data(out), CBB_len(out)) ||  //
      !CBB_reserve(out, &ptr, EVP_MAX_MD_SIZE) ||               //
      !HMAC_Final(hctx.get(), ptr, &hlen) ||                    //
      !CBB_did_write(out, hlen)) {
    return 0;
  }

  return 1;
}

static int ssl_encrypt_ticket_with_method(SSL_HANDSHAKE *hs, CBB *out,
                                          const uint8_t *session_buf,
                                          size_t session_len) {
  SSLImpl *const ssl = hs->ssl;
  const SSL_TICKET_AEAD_METHOD *method = ssl->session_ctx->ticket_aead_method;
  const size_t max_overhead = method->max_overhead(ssl);
  const size_t max_out = session_len + max_overhead;
  if (max_out < max_overhead) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
    return 0;
  }

  uint8_t *ptr;
  if (!CBB_reserve(out, &ptr, max_out)) {
    return 0;
  }

  size_t out_len;
  if (!method->seal(ssl, ptr, &out_len, max_out, session_buf, session_len)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_TICKET_ENCRYPTION_FAILED);
    return 0;
  }

  if (!CBB_did_write(out, out_len)) {
    return 0;
  }

  return 1;
}

bool ssl_encrypt_ticket(SSL_HANDSHAKE *hs, CBB *out,
                        const SSL_SESSION *session) {
  // Serialize the SSL_SESSION to be encoded into the ticket.
  uint8_t *session_buf = nullptr;
  size_t session_len;
  if (!SSL_SESSION_to_bytes_for_ticket(session, &session_buf, &session_len)) {
    return false;
  }
  bssl::UniquePtr<uint8_t> free_session_buf(session_buf);

  if (hs->ssl->session_ctx->ticket_aead_method) {
    return ssl_encrypt_ticket_with_method(hs, out, session_buf, session_len);
  } else {
    return ssl_encrypt_ticket_with_cipher_ctx(hs, out, session_buf,
                                              session_len);
  }
}

SSLSessionType ssl_session_get_type(const SSL_SESSION *session) {
  if (session->not_resumable) {
    return SSLSessionType::kNotResumable;
  }
  if (ssl_session_protocol_version(session) >= TLS1_3_VERSION) {
    return session->ticket.empty() ? SSLSessionType::kNotResumable
                                   : SSLSessionType::kPreSharedKey;
  }
  if (!session->ticket.empty()) {
    return SSLSessionType::kTicket;
  }
  if (!session->session_id.empty()) {
    return SSLSessionType::kID;
  }
  return SSLSessionType::kNotResumable;
}

bool ssl_session_is_context_valid(const SSL_HANDSHAKE *hs,
                                  const SSL_SESSION *session) {
  return session != nullptr &&
         Span(session->sid_ctx) == ssl_handshake_session_id_context(hs);
}

bool ssl_session_is_time_valid(const SSLImpl *ssl, const SSL_SESSION *session) {
  if (session == nullptr) {
    return false;
  }

  OPENSSL_timeval now = ssl_ctx_get_current_time(ssl->ctx.get());

  // Reject tickets from the future to avoid underflow.
  if (now.tv_sec < session->time) {
    return false;
  }

  return session->timeout > now.tv_sec - session->time;
}

bool ssl_session_is_resumable(const SSL_HANDSHAKE *hs,
                              const SSL_SESSION *session) {
  const SSLImpl *const ssl = hs->ssl;
  return ssl_session_is_context_valid(hs, session) &&
         // The session must have been created by the same type of end point as
         // we're now using it with.
         ssl->server == session->is_server &&
         // The session must not be expired.
         ssl_session_is_time_valid(ssl, session) &&
         // Only resume if the session's version matches the negotiated
         // version.
         ssl->s3->version == session->ssl_version &&
         // Only resume if the session's cipher matches the negotiated one. This
         // is stricter than necessary for TLS 1.3, which allows cross-cipher
         // resumption if the PRF hashes match. We require an exact match for
         // simplicity. If loosening this, the 0-RTT accept logic must be
         // updated to check the cipher.
         hs->new_cipher == session->cipher &&
         // If the session contains a client certificate/RPK (either the full
         // certificate/RPK or just the hash) then require that the form of the
         // certificate/RPK matches the current configuration.
         (!ssl_session_has_peer_cred(session) ||
          session->peer_sha256_valid ==
              hs->config->retain_only_sha256_of_client_certs) &&
         // Only resume if the underlying transport protocol hasn't changed.
         // This is to prevent cross-protocol resumption between QUIC and TCP.
         SSL_is_quic(ssl) == int{session->is_quic};
}

// ssl_lookup_session looks up `session_id` in the session cache and sets
// `*out_session` to an `SSL_SESSION` object if found.
static enum ssl_hs_wait_t ssl_lookup_session(
    SSL_HANDSHAKE *hs, UniquePtr<SSL_SESSION> *out_session,
    Span<const uint8_t> session_id) {
  SSLImpl *const ssl = hs->ssl;
  out_session->reset();

  if (session_id.empty() || session_id.size() > SSL_MAX_SSL_SESSION_ID_LENGTH) {
    return ssl_hs_ok;
  }

  UniquePtr<SSL_SESSION> session;
  // Try the internal cache, if it exists.
  if (!(ssl->session_ctx->session_cache_mode &
        SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) {
    uint32_t hash = ssl_hash_session_id(session_id);
    auto cmp = [](const void *key, const SSL_SESSION *sess) -> int {
      Span<const uint8_t> key_id =
          *reinterpret_cast<const Span<const uint8_t> *>(key);
      return key_id == sess->session_id ? 0 : 1;
    };
    MutexReadLock lock(&ssl->session_ctx->lock);
    // `lh_SSL_SESSION_retrieve_key` returns a non-owning pointer.
    session = UpRef(lh_SSL_SESSION_retrieve_key(ssl->session_ctx->sessions,
                                                &session_id, hash, cmp));
    // TODO(davidben): This should probably move it to the front of the list.
  }

  // Fall back to the external cache, if it exists.
  if (!session && ssl->session_ctx->get_session_cb != nullptr) {
    int copy = 1;
    session.reset(ssl->session_ctx->get_session_cb(ssl, session_id.data(),
                                                   session_id.size(), &copy));
    if (!session) {
      return ssl_hs_ok;
    }

    if (session.get() == SSL_magic_pending_session_ptr()) {
      session.release();  // This pointer is not actually owned.
      return ssl_hs_pending_session;
    }

    // Increment reference count now if the session callback asks us to do so
    // (note that if the session structures returned by the callback are shared
    // between threads, it must handle the reference count itself [i.e. copy ==
    // 0], or things won't be thread-safe).
    if (copy) {
      SSL_SESSION_up_ref(session.get());
    }

    // Add the externally cached session to the internal cache if necessary.
    if (!(ssl->session_ctx->session_cache_mode &
          SSL_SESS_CACHE_NO_INTERNAL_STORE)) {
      SSL_CTX_add_session(ssl->session_ctx.get(), session.get());
    }
  }

  if (session && !ssl_session_is_time_valid(ssl, session.get())) {
    // The session was from the cache, so remove it.
    SSL_CTX_remove_session(ssl->session_ctx.get(), session.get());
    session.reset();
  }

  *out_session = std::move(session);
  return ssl_hs_ok;
}

enum ssl_hs_wait_t ssl_get_prev_session(SSL_HANDSHAKE *hs,
                                        UniquePtr<SSL_SESSION> *out_session,
                                        bool *out_tickets_supported,
                                        bool *out_renew_ticket,
                                        const SSL_CLIENT_HELLO *client_hello) {
  // This is used only by servers.
  assert(hs->ssl->server);
  UniquePtr<SSL_SESSION> session;
  bool renew_ticket = false;

  // If tickets are disabled, always behave as if no tickets are present.
  CBS ticket;
  const bool tickets_supported =
      !(SSL_get_options(hs->ssl) & SSL_OP_NO_TICKET) &&
      ssl_client_hello_get_extension(client_hello, &ticket,
                                     TLSEXT_TYPE_session_ticket);
  if (tickets_supported && CBS_len(&ticket) != 0) {
    switch (ssl_process_ticket(
        hs, &session, &renew_ticket, ticket,
        Span(client_hello->session_id, client_hello->session_id_len),
        /*save_ticket=*/false)) {
      case ssl_ticket_aead_success:
        break;
      case ssl_ticket_aead_ignore_ticket:
        assert(!session);
        break;
      case ssl_ticket_aead_error:
        return ssl_hs_error;
      case ssl_ticket_aead_retry:
        return ssl_hs_pending_ticket;
    }
  } else {
    // The client didn't send a ticket, so the session ID is a real ID.
    enum ssl_hs_wait_t lookup_ret = ssl_lookup_session(
        hs, &session,
        Span(client_hello->session_id, client_hello->session_id_len));
    if (lookup_ret != ssl_hs_ok) {
      return lookup_ret;
    }
  }

  *out_session = std::move(session);
  *out_tickets_supported = tickets_supported;
  *out_renew_ticket = renew_ticket;
  return ssl_hs_ok;
}

static bool remove_session(SSLContext *ctx, SSL_SESSION *session, bool lock) {
  if (session == nullptr || session->session_id.empty()) {
    return false;
  }

  if (lock) {
    ctx->lock.LockWrite();
  }

  SSL_SESSION *found_session = lh_SSL_SESSION_retrieve(ctx->sessions, session);
  bool found = found_session == session;
  if (found) {
    found_session = lh_SSL_SESSION_delete(ctx->sessions, session);
    SSL_SESSION_list_remove(ctx, session);
  }

  if (lock) {
    ctx->lock.UnlockWrite();
  }

  if (found) {
    // TODO(https://crbug.com/boringssl/251): Callbacks should not be called
    // under a lock.
    if (ctx->remove_session_cb != nullptr) {
      ctx->remove_session_cb(ctx, found_session);
    }
    SSL_SESSION_free(found_session);
  }

  return found;
}

void ssl_set_session(SSLImpl *ssl, SSL_SESSION *session) {
  if (ssl->session.get() == session) {
    return;
  }

  ssl->session = UpRef(session);
}

// locked by SSL_CTX in the calling function
static void SSL_SESSION_list_remove(SSLContext *ctx, SSL_SESSION *session) {
  if (session->next == nullptr || session->prev == nullptr) {
    return;
  }

  if (session->next == (SSL_SESSION *)&ctx->session_cache_tail) {
    // last element in list
    if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) {
      // only one element in list
      ctx->session_cache_head = nullptr;
      ctx->session_cache_tail = nullptr;
    } else {
      ctx->session_cache_tail = session->prev;
      session->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail);
    }
  } else {
    if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) {
      // first element in list
      ctx->session_cache_head = session->next;
      session->next->prev = (SSL_SESSION *)&(ctx->session_cache_head);
    } else {  // middle of list
      session->next->prev = session->prev;
      session->prev->next = session->next;
    }
  }
  session->prev = session->next = nullptr;
}

static void SSL_SESSION_list_add(SSLContext *ctx, SSL_SESSION *session) {
  if (session->next != nullptr && session->prev != nullptr) {
    SSL_SESSION_list_remove(ctx, session);
  }

  if (ctx->session_cache_head == nullptr) {
    ctx->session_cache_head = session;
    ctx->session_cache_tail = session;
    session->prev = (SSL_SESSION *)&(ctx->session_cache_head);
    session->next = (SSL_SESSION *)&(ctx->session_cache_tail);
  } else {
    session->next = ctx->session_cache_head;
    session->next->prev = session;
    session->prev = (SSL_SESSION *)&(ctx->session_cache_head);
    ctx->session_cache_head = session;
  }
}

static bool add_session_locked(SSLContext *ctx,
                               UniquePtr<SSL_SESSION> session) {
  SSL_SESSION *new_session = session.get();

  // Sessions have intrusive linked lists, so they cannot be stored in two
  // SSLContexts at once.
  // TODO(crbug.com/527997772): Remove this restriction.
  if ((new_session->prev != nullptr || new_session->next != nullptr)) {
    return false;
  }

  SSL_SESSION *old_session;
  if (!lh_SSL_SESSION_insert(ctx->sessions, &old_session, new_session)) {
    return false;
  }
  // `ctx->sessions` took ownership of `new_session` and gave us back a
  // reference to `old_session`. (`old_session` may be the same as
  // `new_session`, in which case we traded identical references with
  // `ctx->sessions`.)
  session.release();
  session.reset(old_session);

  if (old_session != nullptr) {
    // The session cannot have been in the session, due to the check above.
    // TODO(crbug.com/527997772): Revisit this when we remove the check.
    BSSL_CHECK(old_session != new_session);

    // There was a session ID collision. `old_session` was replaced with
    // `session` in the hash table, so `old_session` must be removed from the
    // linked list to match.
    SSL_SESSION_list_remove(ctx, old_session);
  }

  // This does not increment the reference count. Although `session` is inserted
  // into two structures (a doubly-linked list and the hash table), `ctx` only
  // takes one reference.
  SSL_SESSION_list_add(ctx, new_session);

  // Enforce any cache size limits.
  if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
    while (lh_SSL_SESSION_num_items(ctx->sessions) >
           SSL_CTX_sess_get_cache_size(ctx)) {
      if (!remove_session(ctx, ctx->session_cache_tail,
                          /*lock=*/false)) {
        break;
      }
    }
  }

  return true;
}

void ssl_update_cache(SSLImpl *ssl) {
  SSLContext *ctx = ssl->session_ctx.get();
  SSL_SESSION *session = ssl->s3->established_session.get();
  int mode = SSL_is_server(ssl) ? SSL_SESS_CACHE_SERVER : SSL_SESS_CACHE_CLIENT;
  if (!SSL_SESSION_is_resumable(session) ||
      (ctx->session_cache_mode & mode) != mode) {
    return;
  }

  // Clients never use the internal session cache.
  if (ssl->server &&
      !(ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE)) {
    UniquePtr<SSL_SESSION> ref = UpRef(session);
    bool remove_expired_sessions = false;
    {
      MutexWriteLock lock(&ctx->lock);
      add_session_locked(ctx, std::move(ref));

      if (!(ctx->session_cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR)) {
        // Automatically flush the internal session cache every 255 connections.
        ctx->handshakes_since_cache_flush++;
        if (ctx->handshakes_since_cache_flush >= 255) {
          remove_expired_sessions = true;
          ctx->handshakes_since_cache_flush = 0;
        }
      }
    }

    if (remove_expired_sessions) {
      // `SSL_CTX_flush_sessions` takes the lock we just released. We could
      // merge the critical sections, but we'd then call user code under a
      // lock, or compute `now` earlier, even when not flushing.
      OPENSSL_timeval now = ssl_ctx_get_current_time(ssl->ctx.get());
      SSL_CTX_flush_sessions(ctx, now.tv_sec);
    }
  }

  if (ctx->new_session_cb != nullptr) {
    UniquePtr<SSL_SESSION> ref = UpRef(session);
    if (ctx->new_session_cb(ssl, ref.get())) {
      // `new_session_cb`'s return value signals whether it took ownership.
      ref.release();
    }
  }
}

bool ssl_session_has_peer_cred(const SSL_SESSION *session) {
  return sk_CRYPTO_BUFFER_num(SSL_SESSION_get0_peer_certificates(session)) >
             0 ||
         SSL_SESSION_get0_peer_rpk(session) != nullptr ||
         session->peer_sha256_valid;
}

BSSL_NAMESPACE_END

using namespace bssl;

ssl_session_st::ssl_session_st(const SSL_X509_METHOD *method)
    : RefCounted(CheckSubClass()),
      x509_method(method),
      extended_master_secret(false),
      peer_sha256_valid(false),
      not_resumable(false),
      ticket_age_add_valid(false),
      is_server(false),
      is_quic(false),
      has_application_settings(false),
      is_resumable_across_names(false) {
  CRYPTO_new_ex_data(&ex_data);
  time = ::time(nullptr);
}

ssl_session_st::~ssl_session_st() {
  CRYPTO_free_ex_data(&g_ex_data_class, &ex_data);
  x509_method->session_clear(this);
}

SSL_SESSION *SSL_SESSION_new(const SSL_CTX *ctx) {
  return ssl_session_new(FromOpaque(ctx)->x509_method).release();
}

int SSL_SESSION_up_ref(SSL_SESSION *session) {
  session->UpRefInternal();
  return 1;
}

void SSL_SESSION_free(SSL_SESSION *session) {
  if (session == nullptr) {
    return;
  }
  session->DecRefInternal();
}

const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session,
                                  unsigned *out_len) {
  if (out_len != nullptr) {
    *out_len = session->session_id.size();
  }
  return session->session_id.data();
}

int SSL_SESSION_set1_id(SSL_SESSION *session, const uint8_t *sid,
                        size_t sid_len) {
  if (!session->session_id.TryCopyFrom(Span(sid, sid_len))) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_TOO_LONG);
    return 0;
  }

  return 1;
}

uint32_t SSL_SESSION_get_timeout(const SSL_SESSION *session) {
  return session->timeout;
}

uint64_t SSL_SESSION_get_time(const SSL_SESSION *session) {
  if (session == nullptr) {
    // NULL should crash, but silently accept it here for compatibility.
    return 0;
  }
  return session->time;
}

X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session) {
  return session->x509_peer;
}

const STACK_OF(CRYPTO_BUFFER) *SSL_SESSION_get0_peer_certificates(
    const SSL_SESSION *session) {
  return session->certs.get();
}

EVP_PKEY *SSL_SESSION_get0_peer_rpk(const SSL_SESSION *session) {
  return session->peer_raw_public_key.get();
}

void SSL_SESSION_get0_signed_cert_timestamp_list(const SSL_SESSION *session,
                                                 const uint8_t **out,
                                                 size_t *out_len) {
  if (session->signed_cert_timestamp_list) {
    *out = CRYPTO_BUFFER_data(session->signed_cert_timestamp_list.get());
    *out_len = CRYPTO_BUFFER_len(session->signed_cert_timestamp_list.get());
  } else {
    *out = nullptr;
    *out_len = 0;
  }
}

void SSL_SESSION_get0_ocsp_response(const SSL_SESSION *session,
                                    const uint8_t **out, size_t *out_len) {
  if (session->ocsp_response) {
    *out = CRYPTO_BUFFER_data(session->ocsp_response.get());
    *out_len = CRYPTO_BUFFER_len(session->ocsp_response.get());
  } else {
    *out = nullptr;
    *out_len = 0;
  }
}

size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, uint8_t *out,
                                  size_t max_out) {
  if (max_out == 0) {
    return session->secret.size();
  }
  if (max_out > session->secret.size()) {
    max_out = session->secret.size();
  }
  OPENSSL_memcpy(out, session->secret.data(), max_out);
  return max_out;
}

uint64_t SSL_SESSION_set_time(SSL_SESSION *session, uint64_t time) {
  if (session == nullptr) {
    return 0;
  }

  session->time = time;
  return time;
}

uint32_t SSL_SESSION_set_timeout(SSL_SESSION *session, uint32_t timeout) {
  if (session == nullptr) {
    return 0;
  }

  session->timeout = timeout;
  session->auth_timeout = timeout;
  return 1;
}

const uint8_t *SSL_SESSION_get0_id_context(const SSL_SESSION *session,
                                           unsigned *out_len) {
  if (out_len != nullptr) {
    *out_len = session->sid_ctx.size();
  }
  return session->sid_ctx.data();
}

int SSL_SESSION_set1_id_context(SSL_SESSION *session, const uint8_t *sid_ctx,
                                size_t sid_ctx_len) {
  if (!session->sid_ctx.TryCopyFrom(Span(sid_ctx, sid_ctx_len))) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
    return 0;
  }

  return 1;
}

int SSL_SESSION_should_be_single_use(const SSL_SESSION *session) {
  return ssl_session_protocol_version(session) >= TLS1_3_VERSION;
}

int SSL_SESSION_is_resumable(const SSL_SESSION *session) {
  return ssl_session_get_type(session) != SSLSessionType::kNotResumable;
}

int SSL_SESSION_has_ticket(const SSL_SESSION *session) {
  return !session->ticket.empty();
}

void SSL_SESSION_get0_ticket(const SSL_SESSION *session,
                             const uint8_t **out_ticket, size_t *out_len) {
  if (out_ticket != nullptr) {
    *out_ticket = session->ticket.data();
  }
  *out_len = session->ticket.size();
}

int SSL_SESSION_set_ticket(SSL_SESSION *session, const uint8_t *ticket,
                           size_t ticket_len) {
  return session->ticket.CopyFrom(Span(ticket, ticket_len));
}

uint32_t SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session) {
  return session->ticket_lifetime_hint;
}

const SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *session) {
  return session->cipher;
}

int SSL_SESSION_has_peer_sha256(const SSL_SESSION *session) {
  return session->peer_sha256_valid;
}

void SSL_SESSION_get0_peer_sha256(const SSL_SESSION *session,
                                  const uint8_t **out_ptr, size_t *out_len) {
  if (session->peer_sha256_valid) {
    *out_ptr = session->peer_sha256;
    *out_len = sizeof(session->peer_sha256);
  } else {
    *out_ptr = nullptr;
    *out_len = 0;
  }
}

int SSL_SESSION_is_resumable_across_names(const SSL_SESSION *session) {
  return session->is_resumable_across_names;
}

int SSL_SESSION_early_data_capable(const SSL_SESSION *session) {
  return ssl_session_protocol_version(session) >= TLS1_3_VERSION &&
         session->ticket_max_early_data != 0;
}

SSL_SESSION *SSL_SESSION_copy_without_early_data(SSL_SESSION *session) {
  if (!SSL_SESSION_early_data_capable(session)) {
    return UpRef(session).release();
  }

  bssl::UniquePtr<SSL_SESSION> copy =
      SSL_SESSION_dup(session, SSL_SESSION_DUP_ALL);
  if (!copy) {
    return nullptr;
  }

  copy->ticket_max_early_data = 0;
  // Copied sessions are non-resumable until they're completely filled in.
  copy->not_resumable = session->not_resumable;
  assert(!SSL_SESSION_early_data_capable(copy.get()));
  return copy.release();
}

SSL_SESSION *SSL_magic_pending_session_ptr() {
  return (SSL_SESSION *)&g_pending_session_magic;
}

SSL_SESSION *SSL_get_session(const SSL *ssl) {
  const auto *ssl_impl = FromOpaque(ssl);
  // Once the initially handshake completes, we return the most recently
  // established session. In particular, if there is a pending renegotiation, we
  // do not return information about it until it completes.
  //
  // Code in the handshake must either use `hs->new_session` (if updating a
  // partial session) or `ssl_handshake_session` (if trying to query properties
  // consistently across TLS 1.2 resumption and other handshakes).
  if (ssl_impl->s3->established_session != nullptr) {
    return ssl_impl->s3->established_session.get();
  }

  // Otherwise, we must be in the initial handshake.
  SSL_HANDSHAKE *hs = ssl_impl->s3->hs.get();
  assert(hs != nullptr);
  assert(!ssl_impl->s3->initial_handshake_complete);

  // Return the 0-RTT session, if in the 0-RTT state. While the handshake has
  // not actually completed, the public accessors all report properties as if
  // it has.
  if (hs->early_session) {
    return hs->early_session.get();
  }

  // Otherwise, return the partial session.
  return (SSL_SESSION *)ssl_handshake_session(hs);
}

SSL_SESSION *SSL_get1_session(SSL *ssl) {
  SSL_SESSION *ret = SSL_get_session(ssl);
  if (ret != nullptr) {
    SSL_SESSION_up_ref(ret);
  }
  return ret;
}

int SSL_SESSION_get_ex_new_index(long argl, void *argp,
                                 CRYPTO_EX_unused *unused,
                                 CRYPTO_EX_dup *dup_unused,
                                 CRYPTO_EX_free *free_func) {
  return CRYPTO_get_ex_new_index_ex(&g_ex_data_class, argl, argp, free_func);
}

int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, void *arg) {
  return CRYPTO_set_ex_data(&session->ex_data, idx, arg);
}

void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, int idx) {
  return CRYPTO_get_ex_data(&session->ex_data, idx);
}

int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session) {
  auto *ctx_impl = FromOpaque(ctx);
  UniquePtr<SSL_SESSION> owned_session = UpRef(session);
  MutexWriteLock lock(&ctx_impl->lock);
  return add_session_locked(ctx_impl, std::move(owned_session));
}

int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session) {
  return remove_session(FromOpaque(ctx), session, /*lock=*/true);
}

int SSL_set_session(SSL *ssl, SSL_SESSION *session) {
  auto *ssl_impl = FromOpaque(ssl);
  // SSL_set_session may only be called before the handshake has started.
  if (ssl_impl->s3->initial_handshake_complete ||  //
      ssl_impl->s3->hs == nullptr ||               //
      ssl_impl->s3->hs->state != 0) {
    abort();
  }

  ssl_set_session(ssl_impl, session);
  return 1;
}

uint32_t SSL_CTX_set_timeout(SSL_CTX *ctx, uint32_t timeout) {
  if (ctx == nullptr) {
    return 0;
  }

  // Historically, zero was treated as `SSL_DEFAULT_SESSION_TIMEOUT`.
  if (timeout == 0) {
    timeout = SSL_DEFAULT_SESSION_TIMEOUT;
  }

  return std::exchange(FromOpaque(ctx)->session_timeout, timeout);
}

uint32_t SSL_CTX_get_timeout(const SSL_CTX *ctx) {
  if (ctx == nullptr) {
    return 0;
  }

  return FromOpaque(ctx)->session_timeout;
}

void SSL_CTX_set_session_psk_dhe_timeout(SSL_CTX *ctx, uint32_t timeout) {
  FromOpaque(ctx)->session_psk_dhe_timeout = timeout;
}

typedef struct timeout_param_st {
  SSLContext *ctx;
  uint64_t time;
  LHASH_OF(SSL_SESSION) *cache;
} TIMEOUT_PARAM;

static void timeout_doall_arg(SSL_SESSION *session, void *void_param) {
  TIMEOUT_PARAM *param = reinterpret_cast<TIMEOUT_PARAM *>(void_param);

  if (param->time == 0 ||                                  //
      session->time + session->timeout < session->time ||  //
      param->time > (session->time + session->timeout)) {
    // TODO(davidben): This can probably just call `remove_session`.
    (void)lh_SSL_SESSION_delete(param->cache, session);
    SSL_SESSION_list_remove(param->ctx, session);
    // TODO(https://crbug.com/boringssl/251): Callbacks should not be called
    // under a lock.
    if (param->ctx->remove_session_cb != nullptr) {
      param->ctx->remove_session_cb(param->ctx, session);
    }
    SSL_SESSION_free(session);
  }
}

void SSL_CTX_flush_sessions(SSL_CTX *ctx, uint64_t time) {
  auto *ctx_impl = FromOpaque(ctx);
  TIMEOUT_PARAM tp;
  tp.ctx = ctx_impl;
  tp.cache = ctx_impl->sessions;
  if (tp.cache == nullptr) {
    return;
  }
  tp.time = time;
  MutexWriteLock lock(&ctx_impl->lock);
  lh_SSL_SESSION_doall_arg(tp.cache, timeout_doall_arg, &tp);
}

void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
                             int (*cb)(SSL *ssl, SSL_SESSION *session)) {
  FromOpaque(ctx)->new_session_cb = cb;
}

int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *session) {
  return FromOpaque(ctx)->new_session_cb;
}

void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
                                void (*cb)(SSL_CTX *ctx,
                                           SSL_SESSION *session)) {
  FromOpaque(ctx)->remove_session_cb = cb;
}

void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX *ctx,
                                                 SSL_SESSION *session) {
  return FromOpaque(ctx)->remove_session_cb;
}

void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
                             SSL_SESSION *(*cb)(SSL *ssl, const uint8_t *id,
                                                int id_len, int *out_copy)) {
  FromOpaque(ctx)->get_session_cb = cb;
}

SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl,
                                                      const uint8_t *id,
                                                      int id_len,
                                                      int *out_copy) {
  return FromOpaque(ctx)->get_session_cb;
}

void SSL_CTX_set_resumption_across_names_enabled(SSL_CTX *ctx, int enabled) {
  FromOpaque(ctx)->resumption_across_names_enabled = !!enabled;
}

void SSL_set_resumption_across_names_enabled(SSL *ssl, int enabled) {
  FromOpaque(ssl)->resumption_across_names_enabled = !!enabled;
}

void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*cb)(const SSL *ssl,
                                                        int type, int value)) {
  FromOpaque(ctx)->info_callback = cb;
}

void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, int type,
                                                int value) {
  return FromOpaque(ctx)->info_callback;
}
