vtls: only remember the expiry timestamp in session cache
Instead of receive and lifetime, keep only the eppch seconds when a session expires. Closes #15861
This commit is contained in:
parent
c2d37463b9
commit
8a66c11a29
@ -2232,7 +2232,7 @@ static int quic_gtls_handshake_cb(gnutls_session_t session, unsigned int htype,
|
|||||||
quic_tp_len = (size_t)tplen;
|
quic_tp_len = (size_t)tplen;
|
||||||
}
|
}
|
||||||
(void)Curl_gtls_cache_session(cf, data, ctx->peer.scache_key,
|
(void)Curl_gtls_cache_session(cf, data, ctx->peer.scache_key,
|
||||||
session, -1, "h3", quic_tp, quic_tp_len);
|
session, 0, "h3", quic_tp, quic_tp_len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -836,7 +836,7 @@ static CURLcode bearssl_connect_step3(struct Curl_cfilter *cf,
|
|||||||
ret = Curl_ssl_session_create((unsigned char *)session, sizeof(*session),
|
ret = Curl_ssl_session_create((unsigned char *)session, sizeof(*session),
|
||||||
(int)session->version,
|
(int)session->version,
|
||||||
connssl->negotiated.alpn,
|
connssl->negotiated.alpn,
|
||||||
0, -1, 0, &sc_session);
|
0, 0, &sc_session);
|
||||||
if(!ret) {
|
if(!ret) {
|
||||||
ret = Curl_ssl_scache_put(cf, data, connssl->peer.scache_key,
|
ret = Curl_ssl_scache_put(cf, data, connssl->peer.scache_key,
|
||||||
sc_session);
|
sc_session);
|
||||||
|
|||||||
@ -720,7 +720,7 @@ CURLcode Curl_gtls_cache_session(struct Curl_cfilter *cf,
|
|||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
const char *ssl_peer_key,
|
const char *ssl_peer_key,
|
||||||
gnutls_session_t session,
|
gnutls_session_t session,
|
||||||
int lifetime_secs,
|
curl_off_t valid_until,
|
||||||
const char *alpn,
|
const char *alpn,
|
||||||
unsigned char *quic_tp,
|
unsigned char *quic_tp,
|
||||||
size_t quic_tp_len)
|
size_t quic_tp_len)
|
||||||
@ -765,7 +765,7 @@ CURLcode Curl_gtls_cache_session(struct Curl_cfilter *cf,
|
|||||||
|
|
||||||
result = Curl_ssl_session_create2(sdata, sdata_len,
|
result = Curl_ssl_session_create2(sdata, sdata_len,
|
||||||
Curl_glts_get_ietf_proto(session),
|
Curl_glts_get_ietf_proto(session),
|
||||||
alpn, 0, lifetime_secs, earlydata_max,
|
alpn, valid_until, earlydata_max,
|
||||||
qtp_clone, quic_tp_len,
|
qtp_clone, quic_tp_len,
|
||||||
&sc_session);
|
&sc_session);
|
||||||
/* call took ownership of `sdata` and `qtp_clone` */
|
/* call took ownership of `sdata` and `qtp_clone` */
|
||||||
@ -800,8 +800,8 @@ static CURLcode cf_gtls_update_session_id(struct Curl_cfilter *cf,
|
|||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
return Curl_gtls_cache_session(cf, data, connssl->peer.scache_key,
|
return Curl_gtls_cache_session(cf, data, connssl->peer.scache_key,
|
||||||
session, -1,
|
session, 0, connssl->negotiated.alpn,
|
||||||
connssl->negotiated.alpn, NULL, 0);
|
NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gtls_handshake_cb(gnutls_session_t session, unsigned int htype,
|
static int gtls_handshake_cb(gnutls_session_t session, unsigned int htype,
|
||||||
|
|||||||
@ -110,7 +110,7 @@ CURLcode Curl_gtls_cache_session(struct Curl_cfilter *cf,
|
|||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
const char *ssl_peer_key,
|
const char *ssl_peer_key,
|
||||||
gnutls_session_t session,
|
gnutls_session_t session,
|
||||||
int lifetime_secs,
|
curl_off_t valid_until,
|
||||||
const char *alpn,
|
const char *alpn,
|
||||||
unsigned char *quic_tp,
|
unsigned char *quic_tp,
|
||||||
size_t quic_tp_len);
|
size_t quic_tp_len);
|
||||||
|
|||||||
@ -1173,7 +1173,7 @@ mbed_new_session(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||||||
#endif
|
#endif
|
||||||
result = Curl_ssl_session_create(sdata, slen,
|
result = Curl_ssl_session_create(sdata, slen,
|
||||||
ietf_tls_id,
|
ietf_tls_id,
|
||||||
connssl->negotiated.alpn, 0, -1, 0,
|
connssl->negotiated.alpn, 0, 0,
|
||||||
&sc_session);
|
&sc_session);
|
||||||
sdata = NULL; /* call took ownership */
|
sdata = NULL; /* call took ownership */
|
||||||
if(!result)
|
if(!result)
|
||||||
|
|||||||
@ -2902,7 +2902,8 @@ CURLcode Curl_ossl_add_session(struct Curl_cfilter *cf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = Curl_ssl_session_create(der_session_buf, der_session_size,
|
result = Curl_ssl_session_create(der_session_buf, der_session_size,
|
||||||
ietf_tls_id, alpn, 0,
|
ietf_tls_id, alpn,
|
||||||
|
(curl_off_t)time(NULL) +
|
||||||
SSL_SESSION_get_timeout(session), 0,
|
SSL_SESSION_get_timeout(session), 0,
|
||||||
&sc_session);
|
&sc_session);
|
||||||
der_session_buf = NULL; /* took ownership of sdata */
|
der_session_buf = NULL; /* took ownership of sdata */
|
||||||
|
|||||||
@ -109,8 +109,7 @@ static void cf_ssl_scache_clear_session(struct Curl_ssl_session *s)
|
|||||||
}
|
}
|
||||||
s->quic_tp_len = 0;
|
s->quic_tp_len = 0;
|
||||||
s->ietf_tls_id = 0;
|
s->ietf_tls_id = 0;
|
||||||
s->time_received = 0;
|
s->valid_until = 0;
|
||||||
s->lifetime_secs = 0;
|
|
||||||
Curl_safefree(s->alpn);
|
Curl_safefree(s->alpn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,20 +123,18 @@ static void cf_ssl_scache_sesssion_ldestroy(void *udata, void *s)
|
|||||||
CURLcode
|
CURLcode
|
||||||
Curl_ssl_session_create(unsigned char *sdata, size_t sdata_len,
|
Curl_ssl_session_create(unsigned char *sdata, size_t sdata_len,
|
||||||
int ietf_tls_id, const char *alpn,
|
int ietf_tls_id, const char *alpn,
|
||||||
curl_off_t time_received, long lifetime_secs,
|
curl_off_t valid_until, size_t earlydata_max,
|
||||||
size_t earlydata_max,
|
|
||||||
struct Curl_ssl_session **psession)
|
struct Curl_ssl_session **psession)
|
||||||
{
|
{
|
||||||
return Curl_ssl_session_create2(sdata, sdata_len, ietf_tls_id, alpn,
|
return Curl_ssl_session_create2(sdata, sdata_len, ietf_tls_id, alpn,
|
||||||
time_received, lifetime_secs,
|
valid_until, earlydata_max,
|
||||||
earlydata_max, NULL, 0, psession);
|
NULL, 0, psession);
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLcode
|
CURLcode
|
||||||
Curl_ssl_session_create2(unsigned char *sdata, size_t sdata_len,
|
Curl_ssl_session_create2(unsigned char *sdata, size_t sdata_len,
|
||||||
int ietf_tls_id, const char *alpn,
|
int ietf_tls_id, const char *alpn,
|
||||||
curl_off_t time_received, long lifetime_secs,
|
curl_off_t valid_until, size_t earlydata_max,
|
||||||
size_t earlydata_max,
|
|
||||||
unsigned char *quic_tp, size_t quic_tp_len,
|
unsigned char *quic_tp, size_t quic_tp_len,
|
||||||
struct Curl_ssl_session **psession)
|
struct Curl_ssl_session **psession)
|
||||||
{
|
{
|
||||||
@ -157,16 +154,7 @@ Curl_ssl_session_create2(unsigned char *sdata, size_t sdata_len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
s->ietf_tls_id = ietf_tls_id;
|
s->ietf_tls_id = ietf_tls_id;
|
||||||
s->time_received = time_received;
|
s->valid_until = valid_until;
|
||||||
if(lifetime_secs < 0)
|
|
||||||
lifetime_secs = -1; /* unknown */
|
|
||||||
else if((s->ietf_tls_id == CURL_IETF_PROTO_TLS1_3) &&
|
|
||||||
(lifetime_secs > CURL_SCACHE_MAX_13_LIFETIME_SEC))
|
|
||||||
lifetime_secs = CURL_SCACHE_MAX_13_LIFETIME_SEC;
|
|
||||||
else if(lifetime_secs > CURL_SCACHE_MAX_12_LIFETIME_SEC)
|
|
||||||
lifetime_secs = CURL_SCACHE_MAX_12_LIFETIME_SEC;
|
|
||||||
|
|
||||||
s->lifetime_secs = (int)lifetime_secs;
|
|
||||||
s->earlydata_max = earlydata_max;
|
s->earlydata_max = earlydata_max;
|
||||||
s->sdata = sdata;
|
s->sdata = sdata;
|
||||||
s->sdata_len = sdata_len;
|
s->sdata_len = sdata_len;
|
||||||
@ -272,8 +260,7 @@ static void cf_scache_session_remove(struct Curl_ssl_scache_peer *peer,
|
|||||||
static bool cf_scache_session_expired(struct Curl_ssl_session *s,
|
static bool cf_scache_session_expired(struct Curl_ssl_session *s,
|
||||||
curl_off_t now)
|
curl_off_t now)
|
||||||
{
|
{
|
||||||
return (s->lifetime_secs > 0 &&
|
return (s->valid_until > 0) && (s->valid_until < now);
|
||||||
(s->time_received + s->lifetime_secs) < now);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cf_scache_peer_remove_expired(struct Curl_ssl_scache_peer *peer,
|
static void cf_scache_peer_remove_expired(struct Curl_ssl_scache_peer *peer,
|
||||||
@ -715,16 +702,21 @@ static CURLcode cf_scache_peer_add_session(struct Curl_cfilter *cf,
|
|||||||
struct Curl_ssl_scache_peer *peer = NULL;
|
struct Curl_ssl_scache_peer *peer = NULL;
|
||||||
CURLcode result = CURLE_OUT_OF_MEMORY;
|
CURLcode result = CURLE_OUT_OF_MEMORY;
|
||||||
curl_off_t now = (curl_off_t)time(NULL);
|
curl_off_t now = (curl_off_t)time(NULL);
|
||||||
|
curl_off_t max_lifetime;
|
||||||
|
|
||||||
if(!scache || !scache->peer_count) {
|
if(!scache || !scache->peer_count) {
|
||||||
Curl_ssl_session_destroy(s);
|
Curl_ssl_session_destroy(s);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!s->time_received)
|
if(s->valid_until <= 0)
|
||||||
s->time_received = now;
|
s->valid_until = now + scache->default_lifetime_secs;
|
||||||
if(s->lifetime_secs < 0)
|
|
||||||
s->lifetime_secs = scache->default_lifetime_secs;
|
max_lifetime = (s->ietf_tls_id == CURL_IETF_PROTO_TLS1_3) ?
|
||||||
|
CURL_SCACHE_MAX_13_LIFETIME_SEC :
|
||||||
|
CURL_SCACHE_MAX_12_LIFETIME_SEC;
|
||||||
|
if(s->valid_until > (now + max_lifetime))
|
||||||
|
s->valid_until = now + max_lifetime;
|
||||||
|
|
||||||
if(cf_scache_session_expired(s, now)) {
|
if(cf_scache_session_expired(s, now)) {
|
||||||
CURL_TRC_CF(data, cf, "[SCACHE] add, session already expired");
|
CURL_TRC_CF(data, cf, "[SCACHE] add, session already expired");
|
||||||
@ -761,9 +753,9 @@ out:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
CURL_TRC_CF(data, cf, "[SCACHE] added session for %s [proto=0x%x, "
|
CURL_TRC_CF(data, cf, "[SCACHE] added session for %s [proto=0x%x, "
|
||||||
"lifetime=%d, alpn=%s, earlydata=%zu, quic_tp=%s], "
|
"valid_secs=%" FMT_OFF_T ", alpn=%s, earlydata=%zu, "
|
||||||
"peer has %zu sessions now",
|
"quic_tp=%s], peer has %zu sessions now",
|
||||||
ssl_peer_key, s->ietf_tls_id, s->lifetime_secs, s->alpn,
|
ssl_peer_key, s->ietf_tls_id, s->valid_until - now, s->alpn,
|
||||||
s->earlydata_max, s->quic_tp ? "yes" : "no",
|
s->earlydata_max, s->quic_tp ? "yes" : "no",
|
||||||
Curl_llist_count(&peer->sessions));
|
Curl_llist_count(&peer->sessions));
|
||||||
return result;
|
return result;
|
||||||
@ -826,9 +818,8 @@ CURLcode Curl_ssl_scache_take(struct Curl_cfilter *cf,
|
|||||||
if(s) {
|
if(s) {
|
||||||
*ps = s;
|
*ps = s;
|
||||||
CURL_TRC_CF(data, cf, "[SCACHE] took session for %s [proto=0x%x, "
|
CURL_TRC_CF(data, cf, "[SCACHE] took session for %s [proto=0x%x, "
|
||||||
"lifetime=%d, alpn=%s, earlydata=%zu, quic_tp=%s], "
|
"alpn=%s, earlydata=%zu, quic_tp=%s], %zu sessions remain",
|
||||||
"%zu sessions remain",
|
ssl_peer_key, s->ietf_tls_id, s->alpn,
|
||||||
ssl_peer_key, s->ietf_tls_id, s->lifetime_secs, s->alpn,
|
|
||||||
s->earlydata_max, s->quic_tp ? "yes" : "no",
|
s->earlydata_max, s->quic_tp ? "yes" : "no",
|
||||||
Curl_llist_count(&peer->sessions));
|
Curl_llist_count(&peer->sessions));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,8 +118,7 @@ CURLcode Curl_ssl_scache_add_obj(struct Curl_cfilter *cf,
|
|||||||
struct Curl_ssl_session {
|
struct Curl_ssl_session {
|
||||||
const unsigned char *sdata; /* session ticket data, plain bytes */
|
const unsigned char *sdata; /* session ticket data, plain bytes */
|
||||||
size_t sdata_len; /* number of bytes in sdata */
|
size_t sdata_len; /* number of bytes in sdata */
|
||||||
curl_off_t time_received; /* seconds since EPOCH ticket was received */
|
curl_off_t valid_until; /* seconds since EPOCH until ticket expires */
|
||||||
int lifetime_secs; /* ticket lifetime (-1 unknown) */
|
|
||||||
int ietf_tls_id; /* TLS protocol identifier negotiated */
|
int ietf_tls_id; /* TLS protocol identifier negotiated */
|
||||||
char *alpn; /* APLN TLS negotiated protocol string */
|
char *alpn; /* APLN TLS negotiated protocol string */
|
||||||
size_t earlydata_max; /* max 0-RTT data supported by peer */
|
size_t earlydata_max; /* max 0-RTT data supported by peer */
|
||||||
@ -134,17 +133,14 @@ struct Curl_ssl_session {
|
|||||||
* @param sdata_len amount of session data bytes
|
* @param sdata_len amount of session data bytes
|
||||||
* @param ietf_tls_id IETF protocol version, e.g. 0x304 for TLSv1.3
|
* @param ietf_tls_id IETF protocol version, e.g. 0x304 for TLSv1.3
|
||||||
* @param alpn ALPN protocol selected or NULL
|
* @param alpn ALPN protocol selected or NULL
|
||||||
* @param time_received seconds since EPOCH session was received, pass 0
|
* @param valid_until seconds since EPOCH when session expires, pass 0
|
||||||
* to have the value set to time of call
|
* in case this is not known.
|
||||||
* @param lifetime_secs seconds of announced lifetime, <0 if unknown.
|
|
||||||
* values longer than 1 week will be capped as
|
|
||||||
* required by RFC 8446
|
|
||||||
* @param psession on return the scached session instance created
|
* @param psession on return the scached session instance created
|
||||||
*/
|
*/
|
||||||
CURLcode
|
CURLcode
|
||||||
Curl_ssl_session_create(unsigned char *sdata, size_t sdata_len,
|
Curl_ssl_session_create(unsigned char *sdata, size_t sdata_len,
|
||||||
int ietf_tls_id, const char *alpn,
|
int ietf_tls_id, const char *alpn,
|
||||||
curl_off_t time_received, long lifetime_secs,
|
curl_off_t valid_until,
|
||||||
size_t earlydata_max,
|
size_t earlydata_max,
|
||||||
struct Curl_ssl_session **psession);
|
struct Curl_ssl_session **psession);
|
||||||
|
|
||||||
@ -153,7 +149,7 @@ Curl_ssl_session_create(unsigned char *sdata, size_t sdata_len,
|
|||||||
CURLcode
|
CURLcode
|
||||||
Curl_ssl_session_create2(unsigned char *sdata, size_t sdata_len,
|
Curl_ssl_session_create2(unsigned char *sdata, size_t sdata_len,
|
||||||
int ietf_tls_id, const char *alpn,
|
int ietf_tls_id, const char *alpn,
|
||||||
curl_off_t time_received, long lifetime_secs,
|
curl_off_t valid_until,
|
||||||
size_t earlydata_max,
|
size_t earlydata_max,
|
||||||
unsigned char *quic_tp, size_t quic_tp_len,
|
unsigned char *quic_tp, size_t quic_tp_len,
|
||||||
struct Curl_ssl_session **psession);
|
struct Curl_ssl_session **psession);
|
||||||
|
|||||||
@ -431,7 +431,8 @@ CURLcode Curl_wssl_cache_session(struct Curl_cfilter *cf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = Curl_ssl_session_create(sdata, sdata_len,
|
result = Curl_ssl_session_create(sdata, sdata_len,
|
||||||
ietf_tls_id, alpn, 0,
|
ietf_tls_id, alpn,
|
||||||
|
(curl_off_t)time(NULL) +
|
||||||
wolfSSL_SESSION_get_timeout(session), 0,
|
wolfSSL_SESSION_get_timeout(session), 0,
|
||||||
&sc_session);
|
&sc_session);
|
||||||
sdata = NULL; /* took ownership of sdata */
|
sdata = NULL; /* took ownership of sdata */
|
||||||
|
|||||||
@ -212,6 +212,8 @@ class TestCaddy:
|
|||||||
|
|
||||||
@pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3'])
|
@pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3'])
|
||||||
def test_08_08_earlydata(self, env: Env, httpd, caddy, proto):
|
def test_08_08_earlydata(self, env: Env, httpd, caddy, proto):
|
||||||
|
if not env.curl_uses_lib('gnutls'):
|
||||||
|
pytest.skip('TLS earlydata only implemented in GnuTLS')
|
||||||
if proto == 'h3' and not env.have_h3():
|
if proto == 'h3' and not env.have_h3():
|
||||||
pytest.skip("h3 not supported")
|
pytest.skip("h3 not supported")
|
||||||
count = 2
|
count = 2
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user