/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/* ====================================================================
 * Copyright 2005 Nokia. All rights reserved.
 *
 * The portions of the attached software ("Contribution") is developed by
 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
 * license.
 *
 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
 * support (see RFC 4279) to OpenSSL.
 *
 * No patent licenses or other rights except those expressly stated in
 * the OpenSSL open source license shall be deemed granted or received
 * expressly, by implication, estoppel, or otherwise.
 *
 * No assurances are provided by Nokia that the Contribution does not
 * infringe the patent or other intellectual property rights of any third
 * party or that the license provides you with all the necessary rights
 * to make use of the Contribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
 * OTHERWISE. */

#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->quic_method != nullptr;

  // 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.
         (hs->ssl->quic_method != nullptr) == 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;
}
