Skip to content

Commit

Permalink
tls session storage
Browse files Browse the repository at this point in the history
- add session with destructor callback
- remove vtls `session_free` method
- let `Curl_ssl_addsessionid()` take ownership
  of session object, freeing it also on failures
- change tls backend use
  • Loading branch information
icing committed Apr 16, 2024
1 parent a1ecd0b commit 5efa280
Show file tree
Hide file tree
Showing 13 changed files with 157 additions and 187 deletions.
3 changes: 3 additions & 0 deletions lib/urldata.h
Expand Up @@ -345,13 +345,16 @@ struct ssl_general_config {
int ca_cache_timeout; /* Certificate store cache timeout (seconds) */
};

typedef void Curl_ssl_sessionid_dtor(void *sessionid, size_t idsize);

/* information stored about one single SSL session */
struct Curl_ssl_session {
char *name; /* host name for which this ID was used */
char *conn_to_host; /* host name for the connection (may be NULL) */
const char *scheme; /* protocol scheme used */
void *sessionid; /* as returned from the SSL layer */
size_t idsize; /* if known, otherwise 0 */
Curl_ssl_sessionid_dtor *sessionid_free; /* free `sessionid` callback */
long age; /* just a number, the higher the more recent */
int remote_port; /* remote port */
int conn_to_port; /* remote port for the connection (may be -1) */
Expand Down
5 changes: 2 additions & 3 deletions lib/vquic/curl_ngtcp2.c
Expand Up @@ -1928,9 +1928,8 @@ static int quic_ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
ctx = cf? cf->ctx : NULL;
data = cf? CF_DATA_CURRENT(cf) : NULL;
if(cf && data && ctx) {
CURLcode result = Curl_ossl_add_session(cf, data, &ctx->peer,
ssl_sessionid);
return result? 0 : 1;
Curl_ossl_add_session(cf, data, &ctx->peer, ssl_sessionid);
return 1;
}
return 0;
}
Expand Down
24 changes: 11 additions & 13 deletions lib/vtls/bearssl.c
Expand Up @@ -873,6 +873,12 @@ static CURLcode bearssl_connect_step2(struct Curl_cfilter *cf,
return ret;
}

static void bearssl_session_free(void *sessionid, size_t idsize)
{
(void)idsize;
free(sessionid);
}

static CURLcode bearssl_connect_step3(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
Expand All @@ -896,7 +902,6 @@ static CURLcode bearssl_connect_step3(struct Curl_cfilter *cf,

if(ssl_config->primary.sessionid) {
bool incache;
bool added = FALSE;
void *oldsession;
br_ssl_session_parameters *session;

Expand All @@ -909,13 +914,12 @@ static CURLcode bearssl_connect_step3(struct Curl_cfilter *cf,
&oldsession, NULL));
if(incache)
Curl_ssl_delsessionid(data, oldsession);
ret = Curl_ssl_addsessionid(cf, data, &connssl->peer, session, 0, &added);

ret = Curl_ssl_addsessionid(cf, data, &connssl->peer, session, 0,
bearssl_session_free);
Curl_ssl_sessionid_unlock(data);
if(!added)
free(session);
if(ret) {
return CURLE_OUT_OF_MEMORY;
}
if(ret)
return ret;
}

connssl->connecting_state = ssl_connect_done;
Expand Down Expand Up @@ -1174,11 +1178,6 @@ static void bearssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
}
}

static void bearssl_session_free(void *ptr)
{
free(ptr);
}

static CURLcode bearssl_sha256sum(const unsigned char *input,
size_t inputlen,
unsigned char *sha256sum,
Expand Down Expand Up @@ -1211,7 +1210,6 @@ const struct Curl_ssl Curl_ssl_bearssl = {
bearssl_get_internals, /* get_internals */
bearssl_close, /* close_one */
Curl_none_close_all, /* close_all */
bearssl_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
Expand Down
33 changes: 15 additions & 18 deletions lib/vtls/gtls.c
Expand Up @@ -1371,6 +1371,12 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
return result;
}

static void gtls_sessionid_free(void *sessionid, size_t idsize)
{
(void)idsize;
free(sessionid);
}

static CURLcode gtls_verifyserver(struct Curl_cfilter *cf,
struct Curl_easy *data,
gnutls_session_t session)
Expand Down Expand Up @@ -1414,10 +1420,12 @@ static CURLcode gtls_verifyserver(struct Curl_cfilter *cf,
/* get the session ID data size */
gnutls_session_get_data(session, NULL, &connect_idsize);
connect_sessionid = malloc(connect_idsize); /* get a buffer for it */

if(connect_sessionid) {
if(!connect_sessionid) {
result = CURLE_OUT_OF_MEMORY;
goto out;
}
else {
bool incache;
bool added = FALSE;
void *ssl_sessionid;

/* extract session ID to the allocated buffer */
Expand All @@ -1432,19 +1440,14 @@ static CURLcode gtls_verifyserver(struct Curl_cfilter *cf,
Curl_ssl_delsessionid(data, ssl_sessionid);
}

/* store this session id */
/* store this session id, takes ownership */
result = Curl_ssl_addsessionid(cf, data, &connssl->peer,
connect_sessionid, connect_idsize,
&added);
gtls_sessionid_free);
Curl_ssl_sessionid_unlock(data);
if(!added)
free(connect_sessionid);
if(result) {
result = CURLE_OUT_OF_MEMORY;
}
if(result)
return result;
}
else
result = CURLE_OUT_OF_MEMORY;
}

out:
Expand Down Expand Up @@ -1734,11 +1737,6 @@ static ssize_t gtls_recv(struct Curl_cfilter *cf,
return ret;
}

static void gtls_session_free(void *ptr)
{
free(ptr);
}

static size_t gtls_version(char *buffer, size_t size)
{
return msnprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
Expand Down Expand Up @@ -1805,7 +1803,6 @@ const struct Curl_ssl Curl_ssl_gnutls = {
gtls_get_internals, /* get_internals */
gtls_close, /* close_one */
Curl_none_close_all, /* close_all */
gtls_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
Expand Down
26 changes: 10 additions & 16 deletions lib/vtls/mbedtls.c
Expand Up @@ -923,6 +923,13 @@ mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
return CURLE_OK;
}

static void mbedtls_session_free(void *sessionid, size_t idsize)
{
(void)idsize;
mbedtls_ssl_session_free(sessionid);
free(sessionid);
}

static CURLcode
mbed_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
{
Expand All @@ -939,7 +946,6 @@ mbed_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
int ret;
mbedtls_ssl_session *our_ssl_sessionid;
void *old_ssl_sessionid = NULL;
bool added = FALSE;

our_ssl_sessionid = malloc(sizeof(mbedtls_ssl_session));
if(!our_ssl_sessionid)
Expand All @@ -963,16 +969,11 @@ mbed_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
Curl_ssl_delsessionid(data, old_ssl_sessionid);

retcode = Curl_ssl_addsessionid(cf, data, &connssl->peer,
our_ssl_sessionid, 0, &added);
our_ssl_sessionid, 0,
mbedtls_session_free);
Curl_ssl_sessionid_unlock(data);
if(!added) {
mbedtls_ssl_session_free(our_ssl_sessionid);
free(our_ssl_sessionid);
}
if(retcode) {
failf(data, "failed to store ssl session");
if(retcode)
return retcode;
}
}

connssl->connecting_state = ssl_connect_done;
Expand Down Expand Up @@ -1065,12 +1066,6 @@ static ssize_t mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
return len;
}

static void mbedtls_session_free(void *ptr)
{
mbedtls_ssl_session_free(ptr);
free(ptr);
}

static size_t mbedtls_version(char *buffer, size_t size)
{
#ifdef MBEDTLS_VERSION_C
Expand Down Expand Up @@ -1349,7 +1344,6 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
mbedtls_get_internals, /* get_internals */
mbedtls_close, /* close_one */
mbedtls_close_all, /* close_all */
mbedtls_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
Expand Down
44 changes: 18 additions & 26 deletions lib/vtls/openssl.c
Expand Up @@ -2074,10 +2074,11 @@ static int ossl_shutdown(struct Curl_cfilter *cf,
return retval;
}

static void ossl_session_free(void *ptr)
static void ossl_session_free(void *sessionid, size_t idsize)
{
/* free the ID */
SSL_SESSION_free(ptr);
(void)idsize;
SSL_SESSION_free(sessionid);
}

/*
Expand Down Expand Up @@ -2939,17 +2940,16 @@ CURLcode Curl_ossl_add_session(struct Curl_cfilter *cf,
{
const struct ssl_config_data *config;
bool isproxy;
CURLcode result = CURLE_WRITE_ERROR;
bool added = FALSE;

if(!cf || !data)
return result;
goto out;

isproxy = Curl_ssl_cf_is_proxy(cf);

config = Curl_ssl_cf_get_config(cf, data);
if(config->primary.sessionid) {
bool incache;
bool added = FALSE;
void *old_ssl_sessionid = NULL;

Curl_ssl_sessionid_lock(data);
Expand All @@ -2958,29 +2958,23 @@ CURLcode Curl_ossl_add_session(struct Curl_cfilter *cf,
else
incache = !(Curl_ssl_getsessionid(cf, data, peer,
&old_ssl_sessionid, NULL));
if(incache) {
if(old_ssl_sessionid != ssl_sessionid) {
infof(data, "old SSL session ID is stale, removing");
Curl_ssl_delsessionid(data, old_ssl_sessionid);
incache = FALSE;
}
if(incache && (old_ssl_sessionid != ssl_sessionid)) {
infof(data, "old SSL session ID is stale, removing");
Curl_ssl_delsessionid(data, old_ssl_sessionid);
incache = FALSE;
}

if(!incache) {
if(!Curl_ssl_addsessionid(cf, data, peer, ssl_sessionid,
0 /* unknown size */, &added)) {
if(added) {
/* the session has been put into the session cache */
result = CURLE_OK;
}
}
else
failf(data, "failed to store ssl session");
if(!incache && !Curl_ssl_addsessionid(cf, data, peer, ssl_sessionid, 0,
ossl_session_free)) {
added = TRUE;
}
Curl_ssl_sessionid_unlock(data);
}

return result;
out:
if(!added)
ossl_session_free(ssl_sessionid, 0);
return CURLE_OK;
}

/* The "new session" callback must return zero if the session can be removed
Expand All @@ -2991,13 +2985,12 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
struct Curl_cfilter *cf;
struct Curl_easy *data;
struct ssl_connect_data *connssl;
CURLcode result;

cf = (struct Curl_cfilter*) SSL_get_app_data(ssl);
connssl = cf? cf->ctx : NULL;
data = connssl? CF_DATA_CURRENT(cf) : NULL;
result = Curl_ossl_add_session(cf, data, &connssl->peer, ssl_sessionid);
return result? 0 : 1;
Curl_ossl_add_session(cf, data, &connssl->peer, ssl_sessionid);
return 1;
}

static CURLcode load_cacert_from_memory(X509_STORE *store,
Expand Down Expand Up @@ -5288,7 +5281,6 @@ const struct Curl_ssl Curl_ssl_openssl = {
ossl_get_internals, /* get_internals */
ossl_close, /* close_one */
ossl_close_all, /* close_all */
ossl_session_free, /* session_free */
ossl_set_engine, /* set_engine */
ossl_set_engine_default, /* set_engine_default */
ossl_engines_list, /* engines_list */
Expand Down
2 changes: 1 addition & 1 deletion lib/vtls/openssl.h
Expand Up @@ -100,7 +100,7 @@ CURLcode Curl_ossl_ctx_configure(struct Curl_cfilter *cf,
SSL_CTX *ssl_ctx);

/*
* Add a new session to the cache.
* Add a new session to the cache. Takes ownership of the session.
*/
CURLcode Curl_ossl_add_session(struct Curl_cfilter *cf,
struct Curl_easy *data,
Expand Down
1 change: 0 additions & 1 deletion lib/vtls/rustls.c
Expand Up @@ -743,7 +743,6 @@ const struct Curl_ssl Curl_ssl_rustls = {
cr_get_internals, /* get_internals */
cr_close, /* close_one */
Curl_none_close_all, /* close_all */
Curl_none_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
Expand Down

0 comments on commit 5efa280

Please sign in to comment.