/*
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright 2005 Nokia. All rights reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <openssl/ssl.h>

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

#include <utility>

#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/lhash.h>
#include <openssl/mem.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 CRYPTO_EX_DATA_CLASS g_ex_data_class =
    CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;

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

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(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;
    }
  }
  if (session->certs != nullptr) {
    auto buf_up_ref = [](const CRYPTO_BUFFER *buf) {
      CRYPTO_BUFFER_up_ref(const_cast<CRYPTO_BUFFER *>(buf));
      return const_cast<CRYPTO_BUFFER *>(buf);
    };
    new_session->certs.reset(sk_CRYPTO_BUFFER_deep_copy(
        session->certs.get(), buf_up_ref, CRYPTO_BUFFER_free));
    if (new_session->certs == nullptr) {
      return nullptr;
    }
  }

  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(SSL *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(SSL *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) {
  SSL *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 == NULL) {
    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(hs->config->cert->sid_ctx)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    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, NULL);
  return true;
}

bool ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *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.
  SSL_CTX *tctx = hs->ssl->session_ctx.get();
  uint8_t iv[EVP_MAX_IV_LENGTH];
  uint8_t key_name[16];
  if (tctx->ticket_key_cb != NULL) {
    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(), NULL,
                            tctx->ticket_key_current->aes_key, iv) ||
        !HMAC_Init_ex(hctx.get(), tctx->ticket_key_current->hmac_key, 16,
                      tlsext_tick_md(), NULL)) {
      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 defined(BORINGSSL_UNSAFE_FUZZER_MODE)
  OPENSSL_memcpy(ptr, session_buf, session_len);
  total = session_len;
#else
  int len;
  if (!EVP_EncryptUpdate(ctx.get(), ptr + total, &len, session_buf,
                         session_len)) {
    return 0;
  }
  total += len;
  if (!EVP_EncryptFinal_ex(ctx.get(), ptr + total, &len)) {
    return 0;
  }
  total += len;
#endif
  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) {
  SSL *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 &&
         MakeConstSpan(session->sid_ctx) == hs->config->cert->sid_ctx;
}

bool ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) {
  if (session == NULL) {
    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 SSL *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 (either the full
         // certificate or just the hash) then require that the form of the
         // certificate matches the current configuration.
         ((sk_CRYPTO_BUFFER_num(session->certs.get()) == 0 &&
           !session->peer_sha256_valid) ||
          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) {
  SSL *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,
                               MakeConstSpan(client_hello->session_id,
                                             client_hello->session_id_len))) {
      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,
        MakeConstSpan(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(SSL_CTX *ctx, SSL_SESSION *session, bool lock) {
  if (session == nullptr || session->session_id.empty()) {
    return false;
  }

  if (lock) {
    CRYPTO_MUTEX_lock_write(&ctx->lock);
  }

  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) {
    CRYPTO_MUTEX_unlock_write(&ctx->lock);
  }

  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(SSL *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(SSL_CTX *ctx, SSL_SESSION *session) {
  if (session->next == NULL || session->prev == NULL) {
    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 = NULL;
      ctx->session_cache_tail = NULL;
    } 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 = NULL;
}

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

  if (ctx->session_cache_head == NULL) {
    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(SSL_CTX *ctx, UniquePtr<SSL_SESSION> session) {
  SSL_SESSION *new_session = session.get();
  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) {
    if (old_session == new_session) {
      // |session| was already in the cache. There are no linked list pointers
      // to update.
      return false;
    }

    // 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(SSL *ssl) {
  SSL_CTX *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();
    }
  }
}

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) {
  CRYPTO_new_ex_data(&ex_data);
  time = ::time(nullptr);
}

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

SSL_SESSION *SSL_SESSION_new(const SSL_CTX *ctx) {
  return ssl_session_new(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) {
    session->DecRefInternal();
  }
}

const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session,
                                  unsigned *out_len) {
  if (out_len != NULL) {
    *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(MakeConstSpan(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 == NULL) {
    // 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();
}

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 == NULL) {
    return 0;
  }

  session->time = time;
  return time;
}

uint32_t SSL_SESSION_set_timeout(SSL_SESSION *session, uint32_t timeout) {
  if (session == NULL) {
    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 != NULL) {
    *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(MakeConstSpan(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(MakeConstSpan(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_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(void) {
  return (SSL_SESSION *)&g_pending_session_magic;
}

SSL_SESSION *SSL_get_session(const SSL *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->s3->established_session != nullptr) {
    return ssl->s3->established_session.get();
  }

  // Otherwise, we must be in the initial handshake.
  SSL_HANDSHAKE *hs = ssl->s3->hs.get();
  assert(hs != nullptr);
  assert(!ssl->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 != NULL) {
    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) {
  UniquePtr<SSL_SESSION> owned_session = UpRef(session);
  MutexWriteLock lock(&ctx->lock);
  return add_session_locked(ctx, std::move(owned_session));
}

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

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

  ssl_set_session(ssl, session);
  return 1;
}

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

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

  uint32_t old_timeout = ctx->session_timeout;
  ctx->session_timeout = timeout;
  return old_timeout;
}

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

  return ctx->session_timeout;
}

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

typedef struct timeout_param_st {
  SSL_CTX *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 != NULL) {
      param->ctx->remove_session_cb(param->ctx, session);
    }
    SSL_SESSION_free(session);
  }
}

void SSL_CTX_flush_sessions(SSL_CTX *ctx, uint64_t time) {
  TIMEOUT_PARAM tp;

  tp.ctx = ctx;
  tp.cache = ctx->sessions;
  if (tp.cache == NULL) {
    return;
  }
  tp.time = time;
  MutexWriteLock lock(&ctx->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)) {
  ctx->new_session_cb = cb;
}

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

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

void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX *ctx,
                                                 SSL_SESSION *session) {
  return 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)) {
  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 ctx->get_session_cb;
}

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

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