/* 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 <stdio.h>

#include <openssl/engine.h>
#include <openssl/err.h>
#include <openssl/lhash.h>
#include <openssl/mem.h>
#include <openssl/rand.h>

#include "ssl_locl.h"

/* 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 void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s);
static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);

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

SSL_SESSION *SSL_get_session(const SSL *ssl)
{
  /* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
  return ssl->session;
}

SSL_SESSION *SSL_get1_session(SSL *ssl) {
  /* variant of SSL_get_session: caller really gets something */
  return SSL_SESSION_up_ref(ssl->session);
}

int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                                 CRYPTO_EX_dup *dup_func,
                                 CRYPTO_EX_free *free_func) {
  return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp,
                                 new_func, dup_func, free_func);
}

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

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

SSL_SESSION *SSL_SESSION_new(void) {
  SSL_SESSION *ss;

  ss = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
  if (ss == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_SESSION_new, ERR_R_MALLOC_FAILURE);
    return 0;
  }
  memset(ss, 0, sizeof(SSL_SESSION));

  ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
  ss->references = 1;
  ss->timeout = SSL_DEFAULT_SESSION_TIMEOUT;
  ss->time = (unsigned long)time(NULL);
  CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
  return ss;
}

const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len) {
  if (len) {
    *len = s->session_id_length;
  }
  return s->session_id;
}

/* Even with SSLv2, we have 16 bytes (128 bits) of session ID space.
 * SSLv3/TLSv1 has 32 bytes (256 bits). As such, filling the ID with random
 * gunk repeatedly until we have no conflict is going to complete in one
 * iteration pretty much "most" of the time (btw: understatement). So, if it
 * takes us 10 iterations and we still can't avoid a conflict - well that's a
 * reasonable point to call it quits. Either the RAND code is broken or someone
 * is trying to open roughly very close to 2^128 (or 2^256) SSL sessions to our
 * server. How you might store that many sessions is perhaps a more interesting
 * question ... */
static int def_generate_session_id(const SSL *ssl, uint8_t *id,
                                   unsigned int *id_len) {
  static const unsigned kMaxAttempts = 10;
  unsigned int retry = 0;
  do {
    if (!RAND_bytes(id, *id_len)) {
      return 0;
    }
  } while (SSL_has_matching_session_id(ssl, id, *id_len) &&
           (++retry < kMaxAttempts));

  if (retry < kMaxAttempts) {
    return 1;
  }

  /* else - woops a session_id match */
  /* XXX We should also check the external cache -- but the probability of a
   * collision is negligible, and we could not prevent the concurrent creation
   * of sessions with identical IDs since we currently don't have means to
   * atomically check whether a session ID already exists and make a
   * reservation for it if it does not (this problem applies to the internal
   * cache as well). */
  return 0;
}

int ssl_get_new_session(SSL *s, int session) {
  /* This gets used by clients and servers. */

  unsigned int tmp;
  SSL_SESSION *ss = NULL;
  GEN_SESSION_CB cb = def_generate_session_id;

  if (s->mode & SSL_MODE_NO_SESSION_CREATION) {
    OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
                      SSL_R_SESSION_MAY_NOT_BE_CREATED);
    return 0;
  }

  ss = SSL_SESSION_new();
  if (ss == NULL) {
    return 0;
  }

  /* If the context has a default timeout, use it over the default. */
  if (s->initial_ctx->session_timeout != 0) {
    ss->timeout = s->initial_ctx->session_timeout;
  }

  if (s->session != NULL) {
    SSL_SESSION_free(s->session);
    s->session = NULL;
  }

  if (session) {
    if (s->version == SSL3_VERSION || s->version == TLS1_VERSION ||
        s->version == TLS1_1_VERSION || s->version == TLS1_2_VERSION ||
        s->version == DTLS1_VERSION || s->version == DTLS1_2_VERSION) {
      ss->ssl_version = s->version;
      ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
    } else {
      OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
                        SSL_R_UNSUPPORTED_SSL_VERSION);
      SSL_SESSION_free(ss);
      return 0;
    }

    /* If RFC4507 ticket use empty session ID */
    if (s->tlsext_ticket_expected) {
      ss->session_id_length = 0;
      goto sess_id_done;
    }

    /* Choose which callback will set the session ID */
    CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
    if (s->generate_session_id) {
      cb = s->generate_session_id;
    } else if (s->initial_ctx->generate_session_id) {
      cb = s->initial_ctx->generate_session_id;
    }
    CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);

    /* Choose a session ID */
    tmp = ss->session_id_length;
    if (!cb(s, ss->session_id, &tmp)) {
      /* The callback failed */
      OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
                        SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
      SSL_SESSION_free(ss);
      return 0;
    }

    /* Don't allow the callback to set the session length to zero. nor set it
     * higher than it was. */
    if (!tmp || tmp > ss->session_id_length) {
      /* The callback set an illegal length */
      OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
                        SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
      SSL_SESSION_free(ss);
      return 0;
    }

    ss->session_id_length = tmp;
    /* Finally, check for a conflict */
    if (SSL_has_matching_session_id(s, ss->session_id, ss->session_id_length)) {
      OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
                        SSL_R_SSL_SESSION_ID_CONFLICT);
      SSL_SESSION_free(ss);
      return 0;
    }

  sess_id_done:
    if (s->tlsext_hostname) {
      ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
      if (ss->tlsext_hostname == NULL) {
        OPENSSL_PUT_ERROR(SSL, ssl_get_new_session, ERR_R_INTERNAL_ERROR);
        SSL_SESSION_free(ss);
        return 0;
      }
    }
  } else {
    ss->session_id_length = 0;
  }

  if (s->sid_ctx_length > sizeof(ss->sid_ctx)) {
    OPENSSL_PUT_ERROR(SSL, ssl_get_new_session, ERR_R_INTERNAL_ERROR);
    SSL_SESSION_free(ss);
    return 0;
  }

  memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length);
  ss->sid_ctx_length = s->sid_ctx_length;
  s->session = ss;
  ss->ssl_version = s->version;
  ss->verify_result = X509_V_OK;

  return 1;
}

/* ssl_get_prev attempts to find an SSL_SESSION to be used to resume this
 * connection. It is only called by servers.
 *
 *   ctx: contains the early callback context, which is the result of a
 *       shallow parse of the ClientHello.
 *
 * Returns:
 *   -1: error
 *    0: a session may have been found.
 *
 * Side effects:
 *   - If a session is found then s->session is pointed at it (after freeing an
 *     existing session if need be) and s->verify_result is set from the session.
 *   - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1
 *     if the server should issue a new session ticket (to 0 otherwise). */
int ssl_get_prev_session(SSL *s, const struct ssl_early_callback_ctx *ctx) {
  /* This is used only by servers. */
  SSL_SESSION *ret = NULL;
  int fatal = 0;
  int try_session_cache = 1;
  int r;

  if (ctx->session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
    goto err;
  }

  if (ctx->session_id_len == 0) {
    try_session_cache = 0;
  }

  r = tls1_process_ticket(s, ctx, &ret); /* sets s->tlsext_ticket_expected */
  switch (r) {
    case -1: /* Error during processing */
      fatal = 1;
      goto err;

    case 0:  /* No ticket found */
    case 1:  /* Zero length ticket found */
      break; /* Ok to carry on processing session id. */

    case 2:  /* Ticket found but not decrypted. */
    case 3:  /* Ticket decrypted, *ret has been set. */
      try_session_cache = 0;
      break;

    default:
      abort();
  }

  if (try_session_cache && ret == NULL &&
      !(s->initial_ctx->session_cache_mode &
        SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) {
    SSL_SESSION data;
    data.ssl_version = s->version;
    data.session_id_length = ctx->session_id_len;
    if (ctx->session_id_len == 0) {
      return 0;
    }
    memcpy(data.session_id, ctx->session_id, ctx->session_id_len);
    CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
    ret = SSL_SESSION_up_ref(lh_SSL_SESSION_retrieve(s->initial_ctx->sessions,
                                                     &data));
    CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
    if (ret == NULL) {
      s->initial_ctx->stats.sess_miss++;
    }
  }

  if (try_session_cache && ret == NULL &&
      s->initial_ctx->get_session_cb != NULL) {
    int copy = 1;

    ret = s->initial_ctx->get_session_cb(s, (uint8_t *)ctx->session_id,
                                         ctx->session_id_len, &copy);
    if (ret != NULL) {
      if (ret == SSL_magic_pending_session_ptr()) {
        /* This is a magic value which indicates that the callback needs to
         * unwind the stack and figure out the session asynchronously. */
        return PENDING_SESSION;
      }
      s->initial_ctx->stats.sess_cb_hit++;

      /* 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(ret);
      }

      /* Add the externally cached session to the internal cache as well if and
       * only if we are supposed to. */
      if (!(s->initial_ctx->session_cache_mode &
            SSL_SESS_CACHE_NO_INTERNAL_STORE)) {
        /* The following should not return 1, otherwise, things are very
         * strange */
        SSL_CTX_add_session(s->initial_ctx, ret);
      }
    }
  }

  if (ret == NULL) {
    goto err;
  }

  /* Now ret is non-NULL and we own one of its reference counts. */

  if (ret->sid_ctx_length != s->sid_ctx_length ||
      memcmp(ret->sid_ctx, s->sid_ctx, ret->sid_ctx_length)) {
    /* We have the session requested by the client, but we don't want to use it
     * in this context. */
    goto err; /* treat like cache miss */
  }

  if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) {
    /* We can't be sure if this session is being used out of context, which is
     * especially important for SSL_VERIFY_PEER. The application should have
     * used SSL[_CTX]_set_session_id_context.
     *
     * For this error case, we generate an error instead of treating the event
     * like a cache miss (otherwise it would be easy for applications to
     * effectively disable the session cache by accident without anyone
     * noticing). */
    OPENSSL_PUT_ERROR(SSL, ssl_get_prev_session,
                      SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
    fatal = 1;
    goto err;
  }

  if (ret->timeout < (long)(time(NULL) - ret->time)) {
    /* timeout */
    s->initial_ctx->stats.sess_timeout++;
    if (try_session_cache) {
      /* session was from the cache, so remove it */
      SSL_CTX_remove_session(s->initial_ctx, ret);
    }
    goto err;
  }

  s->initial_ctx->stats.sess_hit++;

  if (s->session != NULL) {
    SSL_SESSION_free(s->session);
  }
  s->session = ret;
  s->verify_result = s->session->verify_result;
  return 1;

err:
  if (ret != NULL) {
    SSL_SESSION_free(ret);
    if (!try_session_cache) {
      /* The session was from a ticket, so we should
       * issue a ticket for the new session */
      s->tlsext_ticket_expected = 1;
    }
  }
  if (fatal) {
    return -1;
  }
  return 0;
}

int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) {
  int ret = 0;
  SSL_SESSION *s;

  /* add just 1 reference count for the SSL_CTX's session cache even though it
   * has two ways of access: each session is in a doubly linked list and an
   * lhash */
  SSL_SESSION_up_ref(c);
  /* if session c is in already in cache, we take back the increment later */

  CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
  if (!lh_SSL_SESSION_insert(ctx->sessions, &s, c)) {
    return 0;
  }

  /* s != NULL iff we already had a session with the given PID. In this case, s
   * == c should hold (then we did not really modify ctx->sessions), or we're
   * in trouble. */
  if (s != NULL && s != c) {
    /* We *are* in trouble ... */
    SSL_SESSION_list_remove(ctx, s);
    SSL_SESSION_free(s);
    /* ... so pretend the other session did not exist in cache (we cannot
     * handle two SSL_SESSION structures with identical session ID in the same
     * cache, which could happen e.g. when two threads concurrently obtain the
     * same session from an external cache) */
    s = NULL;
  }

  /* Put at the head of the queue unless it is already in the cache */
  if (s == NULL) {
    SSL_SESSION_list_add(ctx, c);
  }

  if (s != NULL) {
    /* existing cache entry -- decrement previously incremented reference count
     * because it already takes into account the cache */
    SSL_SESSION_free(s); /* s == c */
    ret = 0;
  } else {
    /* new cache entry -- remove old ones if cache has become too large */
    ret = 1;

    if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
      while (SSL_CTX_sess_number(ctx) > SSL_CTX_sess_get_cache_size(ctx)) {
        if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) {
          break;
        }
        ctx->stats.sess_cache_full++;
      }
    }
  }

  CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
  return ret;
}

int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) {
  return remove_session_lock(ctx, c, 1);
}

static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lock) {
  SSL_SESSION *r;
  int ret = 0;

  if (c != NULL && c->session_id_length != 0) {
    if (lock) {
      CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
    }
    r = lh_SSL_SESSION_retrieve(ctx->sessions, c);
    if (r == c) {
      ret = 1;
      r = lh_SSL_SESSION_delete(ctx->sessions, c);
      SSL_SESSION_list_remove(ctx, c);
    }

    if (lock) {
      CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
    }

    if (ret) {
      r->not_resumable = 1;
      if (ctx->remove_session_cb != NULL) {
        ctx->remove_session_cb(ctx, r);
      }
      SSL_SESSION_free(r);
    }
  }

  return ret;
}

SSL_SESSION *SSL_SESSION_up_ref(SSL_SESSION *session) {
  if (session) {
    CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION);
  }
  return session;
}

void SSL_SESSION_free(SSL_SESSION *ss) {
  int i;

  if (ss == NULL) {
    return;
  }

  i = CRYPTO_add(&ss->references, -1, CRYPTO_LOCK_SSL_SESSION);
  if (i > 0) {
    return;
  }

  CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);

  OPENSSL_cleanse(ss->master_key, sizeof ss->master_key);
  OPENSSL_cleanse(ss->session_id, sizeof ss->session_id);
  if (ss->sess_cert != NULL) {
    ssl_sess_cert_free(ss->sess_cert);
  }
  if (ss->peer != NULL) {
    X509_free(ss->peer);
  }
  if (ss->tlsext_hostname != NULL) {
    OPENSSL_free(ss->tlsext_hostname);
  }
  if (ss->tlsext_tick != NULL) {
    OPENSSL_free(ss->tlsext_tick);
  }
  if (ss->tlsext_signed_cert_timestamp_list != NULL) {
    OPENSSL_free(ss->tlsext_signed_cert_timestamp_list);
  }
  if (ss->ocsp_response != NULL) {
    OPENSSL_free(ss->ocsp_response);
  }
  if (ss->psk_identity != NULL) {
    OPENSSL_free(ss->psk_identity);
  }
  OPENSSL_cleanse(ss, sizeof(*ss));
  OPENSSL_free(ss);
}

int SSL_set_session(SSL *s, SSL_SESSION *session) {
  if (s->session == session) {
    return 1;
  }

  if (s->session != NULL) {
    SSL_SESSION_free(s->session);
  }
  s->session = session;
  if (session != NULL) {
    SSL_SESSION_up_ref(session);
    s->verify_result = session->verify_result;
  }

  return 1;
}

long SSL_SESSION_set_timeout(SSL_SESSION *s, long t) {
  if (s == NULL) {
    return 0;
  }

  s->timeout = t;
  return 1;
}

long SSL_SESSION_get_timeout(const SSL_SESSION *s) {
  if (s == NULL) {
    return 0;
  }

  return s->timeout;
}

long SSL_SESSION_get_time(const SSL_SESSION *s) {
  if (s == NULL) {
    return 0;
  }

  return s->time;
}

long SSL_SESSION_set_time(SSL_SESSION *s, long t) {
  if (s == NULL) {
    return 0;
  }

  s->time = t;
  return t;
}

X509 *SSL_SESSION_get0_peer(SSL_SESSION *s) { return s->peer; }

int SSL_SESSION_set1_id_context(SSL_SESSION *s, const uint8_t *sid_ctx,
                                unsigned int sid_ctx_len) {
  if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
    OPENSSL_PUT_ERROR(SSL, SSL_SESSION_set1_id_context,
                      SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
    return 0;
  }

  s->sid_ctx_length = sid_ctx_len;
  memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);

  return 1;
}

long SSL_CTX_set_timeout(SSL_CTX *s, long t) {
  long l;
  if (s == NULL) {
    return 0;
  }

  l = s->session_timeout;
  s->session_timeout = t;
  return l;
}

long SSL_CTX_get_timeout(const SSL_CTX *s) {
  if (s == NULL) {
    return 0;
  }

  return s->session_timeout;
}

typedef struct timeout_param_st {
  SSL_CTX *ctx;
  long time;
  LHASH_OF(SSL_SESSION) * cache;
} TIMEOUT_PARAM;

static void timeout_doall_arg(SSL_SESSION *sess, void *void_param) {
  TIMEOUT_PARAM *param = void_param;

  if (param->time == 0 ||
      param->time > (sess->time + sess->timeout)) {
    /* timeout */
    /* The reason we don't call SSL_CTX_remove_session() is to
     * save on locking overhead */
    (void) lh_SSL_SESSION_delete(param->cache, sess);
    SSL_SESSION_list_remove(param->ctx, sess);
    sess->not_resumable = 1;
    if (param->ctx->remove_session_cb != NULL) {
      param->ctx->remove_session_cb(param->ctx, sess);
    }
    SSL_SESSION_free(sess);
  }
}

void SSL_CTX_flush_sessions(SSL_CTX *s, long t) {
  TIMEOUT_PARAM tp;

  tp.ctx = s;
  tp.cache = s->sessions;
  if (tp.cache == NULL) {
    return;
  }
  tp.time = t;
  CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
  lh_SSL_SESSION_doall_arg(tp.cache, timeout_doall_arg, &tp);
  CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
}

int ssl_clear_bad_session(SSL *s) {
  if (s->session != NULL && !(s->shutdown & SSL_SENT_SHUTDOWN) &&
      !SSL_in_init(s)) {
    SSL_CTX_remove_session(s->ctx, s->session);
    return 1;
  }

  return 0;
}

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

  if (s->next == (SSL_SESSION *)&ctx->session_cache_tail) {
    /* last element in list */
    if (s->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 = s->prev;
      s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail);
    }
  } else {
    if (s->prev == (SSL_SESSION *)&ctx->session_cache_head) {
      /* first element in list */
      ctx->session_cache_head = s->next;
      s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head);
    } else { /* middle of list */
      s->next->prev = s->prev;
      s->prev->next = s->next;
    }
  }
  s->prev = s->next = NULL;
}

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

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

void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
                             int (*cb)(struct ssl_st *ssl, SSL_SESSION *sess)) {
  ctx->new_session_cb = cb;
}

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

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

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

void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
                             SSL_SESSION *(*cb)(struct ssl_st *ssl,
                                                uint8_t *data, int len,
                                                int *copy)) {
  ctx->get_session_cb = cb;
}

SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl, uint8_t *data,
                                                      int len, int *copy) {
  return ctx->get_session_cb;
}

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

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

void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509,
                                                        EVP_PKEY **pkey)) {
  ctx->client_cert_cb = cb;
}

int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509,
                                                EVP_PKEY **pkey) {
  return ctx->client_cert_cb;
}

void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx,
                               void (*cb)(SSL *ssl, EVP_PKEY **pkey)) {
  ctx->channel_id_cb = cb;
}

void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey) {
  return ctx->channel_id_cb;
}

IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
