/*
* Copyright 1995-2017 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 <stdio.h>
#include <openssl/rand.h>
#include <openssl/engine.h>
#include "internal/refcount.h"
#include "ssl_locl.h"
#include "statem/statem_locl.h"
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_get_session() and SSL_get1_session() are problematic in TLS1.3 because,
* unlike in earlier protocol versions, the session ticket may not have been
* sent yet even though a handshake has finished. The session ticket data could
* come in sometime later...or even change if multiple session ticket messages
* are sent from the server. The preferred way for applications to obtain
* a resumable session is to use SSL_CTX_sess_set_new_cb().
*/
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 */
{
SSL_SESSION *sess;
/*
* Need to lock this all up rather than just use CRYPTO_add so that
* somebody doesn't free ssl->session between when we check it's non-null
* and when we up the reference count.
*/
CRYPTO_THREAD_read_lock(ssl->lock);
sess = ssl->session;
if (sess)
SSL_SESSION_up_ref(sess);
CRYPTO_THREAD_unlock(ssl->lock);
return sess;
}
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;
if (!OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL))
return NULL;
ss = OPENSSL_zalloc(sizeof(*ss));
if (ss == NULL) {
SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
}
ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
ss->references = 1;
ss->timeout = 60 * 5 + 4; /* 5 minute timeout by default */
ss->time = (unsigned long)time(NULL);
ss->lock <