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;
|
||||
}
|
||||
(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;
|
||||
}
|
||||
default:
|
||||
|
||||
@ -836,7 +836,7 @@ static CURLcode bearssl_connect_step3(struct Curl_cfilter *cf,
|
||||
ret = Curl_ssl_session_create((unsigned char *)session, sizeof(*session),
|
||||
(int)session->version,
|
||||
connssl->negotiated.alpn,
|
||||
0, -1, 0, &sc_session);
|
||||
0, 0, &sc_session);
|
||||
if(!ret) {
|
||||
ret = Curl_ssl_scache_put(cf, data, connssl->peer.scache_key,
|
||||
sc_session);
|
||||
|
||||
@ -720,7 +720,7 @@ CURLcode Curl_gtls_cache_session(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
const char *ssl_peer_key,
|
||||
gnutls_session_t session,
|
||||
int lifetime_secs,
|
||||
curl_off_t valid_until,
|
||||
const char *alpn,
|
||||
unsigned char *quic_tp,
|
||||
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,
|
||||
Curl_glts_get_ietf_proto(session),
|
||||
alpn, 0, lifetime_secs, earlydata_max,
|
||||
alpn, valid_until, earlydata_max,
|
||||
qtp_clone, quic_tp_len,
|
||||
&sc_session);
|
||||
/* 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;
|
||||
return Curl_gtls_cache_session(cf, data, connssl->peer.scache_key,
|
||||
session, -1,
|
||||
connssl->negotiated.alpn, NULL, 0);
|
||||
session, 0, connssl->negotiated.alpn,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
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,
|
||||
const char *ssl_peer_key,
|
||||
gnutls_session_t session,
|
||||
int lifetime_secs,
|
||||
curl_off_t valid_until,
|
||||
const char *alpn,
|
||||
unsigned char *quic_tp,
|
||||
size_t quic_tp_len);
|
||||
|
||||
@ -1173,7 +1173,7 @@ mbed_new_session(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
#endif
|
||||
result = Curl_ssl_session_create(sdata, slen,
|
||||
ietf_tls_id,
|
||||
connssl->negotiated.alpn, 0, -1, 0,
|
||||
connssl->negotiated.alpn, 0, 0,
|
||||
&sc_session);
|
||||
sdata = NULL; /* call took ownership */
|
||||
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,
|
||||
ietf_tls_id, alpn, 0,
|
||||
ietf_tls_id, alpn,
|
||||
(curl_off_t)time(NULL) +
|
||||
SSL_SESSION_get_timeout(session), 0,
|
||||
&sc_session);
|
||||
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->ietf_tls_id = 0;
|
||||
s->time_received = 0;
|
||||
s->lifetime_secs = 0;
|
||||
s->valid_until = 0;
|
||||
Curl_safefree(s->alpn);
|
||||
}
|
||||
|
||||
@ -124,20 +123,18 @@ static void cf_ssl_scache_sesssion_ldestroy(void *udata, void *s)
|
||||
CURLcode
|
||||
Curl_ssl_session_create(unsigned char *sdata, size_t sdata_len,
|
||||
int ietf_tls_id, const char *alpn,
|
||||
curl_off_t time_received, long lifetime_secs,
|
||||
size_t earlydata_max,
|
||||
curl_off_t valid_until, size_t earlydata_max,
|
||||
struct Curl_ssl_session **psession)
|
||||
{
|
||||
return Curl_ssl_session_create2(sdata, sdata_len, ietf_tls_id, alpn,
|
||||
time_received, lifetime_secs,
|
||||
earlydata_max, NULL, 0, psession);
|
||||
valid_until, earlydata_max,
|
||||
NULL, 0, psession);
|
||||
}
|
||||
|
||||
CURLcode
|
||||
Curl_ssl_session_create2(unsigned char *sdata, size_t sdata_len,
|
||||
int ietf_tls_id, const char *alpn,
|
||||
curl_off_t time_received, long lifetime_secs,
|
||||
size_t earlydata_max,
|
||||
curl_off_t valid_until, size_t earlydata_max,
|
||||
unsigned char *quic_tp, size_t quic_tp_len,
|
||||
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->time_received = time_received;
|
||||
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->valid_until = valid_until;
|
||||
s->earlydata_max = earlydata_max;
|
||||
s->sdata = sdata;
|
||||
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,
|
||||
curl_off_t now)
|
||||
{
|
||||
return (s->lifetime_secs > 0 &&
|
||||
(s->time_received + s->lifetime_secs) < now);
|
||||
return (s->valid_until > 0) && (s->valid_until < now);
|
||||
}
|
||||
|
||||
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;
|
||||
CURLcode result = CURLE_OUT_OF_MEMORY;
|
||||
curl_off_t now = (curl_off_t)time(NULL);
|
||||
curl_off_t max_lifetime;
|
||||
|
||||
if(!scache || !scache->peer_count) {
|
||||
Curl_ssl_session_destroy(s);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if(!s->time_received)
|
||||
s->time_received = now;
|
||||
if(s->lifetime_secs < 0)
|
||||
s->lifetime_secs = scache->default_lifetime_secs;
|
||||
if(s->valid_until <= 0)
|
||||
s->valid_until = now + 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)) {
|
||||
CURL_TRC_CF(data, cf, "[SCACHE] add, session already expired");
|
||||
@ -761,9 +753,9 @@ out:
|
||||
}
|
||||
else
|
||||
CURL_TRC_CF(data, cf, "[SCACHE] added session for %s [proto=0x%x, "
|
||||
"lifetime=%d, alpn=%s, earlydata=%zu, quic_tp=%s], "
|
||||
"peer has %zu sessions now",
|
||||
ssl_peer_key, s->ietf_tls_id, s->lifetime_secs, s->alpn,
|
||||
"valid_secs=%" FMT_OFF_T ", alpn=%s, earlydata=%zu, "
|
||||
"quic_tp=%s], peer has %zu sessions now",
|
||||
ssl_peer_key, s->ietf_tls_id, s->valid_until - now, s->alpn,
|
||||
s->earlydata_max, s->quic_tp ? "yes" : "no",
|
||||
Curl_llist_count(&peer->sessions));
|
||||
return result;
|
||||
@ -826,9 +818,8 @@ CURLcode Curl_ssl_scache_take(struct Curl_cfilter *cf,
|
||||
if(s) {
|
||||
*ps = s;
|
||||
CURL_TRC_CF(data, cf, "[SCACHE] took session for %s [proto=0x%x, "
|
||||
"lifetime=%d, alpn=%s, earlydata=%zu, quic_tp=%s], "
|
||||
"%zu sessions remain",
|
||||
ssl_peer_key, s->ietf_tls_id, s->lifetime_secs, s->alpn,
|
||||
"alpn=%s, earlydata=%zu, quic_tp=%s], %zu sessions remain",
|
||||
ssl_peer_key, s->ietf_tls_id, s->alpn,
|
||||
s->earlydata_max, s->quic_tp ? "yes" : "no",
|
||||
Curl_llist_count(&peer->sessions));
|
||||
}
|
||||
|
||||
@ -118,8 +118,7 @@ CURLcode Curl_ssl_scache_add_obj(struct Curl_cfilter *cf,
|
||||
struct Curl_ssl_session {
|
||||
const unsigned char *sdata; /* session ticket data, plain bytes */
|
||||
size_t sdata_len; /* number of bytes in sdata */
|
||||
curl_off_t time_received; /* seconds since EPOCH ticket was received */
|
||||
int lifetime_secs; /* ticket lifetime (-1 unknown) */
|
||||
curl_off_t valid_until; /* seconds since EPOCH until ticket expires */
|
||||
int ietf_tls_id; /* TLS protocol identifier negotiated */
|
||||
char *alpn; /* APLN TLS negotiated protocol string */
|
||||
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 ietf_tls_id IETF protocol version, e.g. 0x304 for TLSv1.3
|
||||
* @param alpn ALPN protocol selected or NULL
|
||||
* @param time_received seconds since EPOCH session was received, pass 0
|
||||
* to have the value set to time of call
|
||||
* @param lifetime_secs seconds of announced lifetime, <0 if unknown.
|
||||
* values longer than 1 week will be capped as
|
||||
* required by RFC 8446
|
||||
* @param valid_until seconds since EPOCH when session expires, pass 0
|
||||
* in case this is not known.
|
||||
* @param psession on return the scached session instance created
|
||||
*/
|
||||
CURLcode
|
||||
Curl_ssl_session_create(unsigned char *sdata, size_t sdata_len,
|
||||
int ietf_tls_id, const char *alpn,
|
||||
curl_off_t time_received, long lifetime_secs,
|
||||
curl_off_t valid_until,
|
||||
size_t earlydata_max,
|
||||
struct Curl_ssl_session **psession);
|
||||
|
||||
@ -153,7 +149,7 @@ Curl_ssl_session_create(unsigned char *sdata, size_t sdata_len,
|
||||
CURLcode
|
||||
Curl_ssl_session_create2(unsigned char *sdata, size_t sdata_len,
|
||||
int ietf_tls_id, const char *alpn,
|
||||
curl_off_t time_received, long lifetime_secs,
|
||||
curl_off_t valid_until,
|
||||
size_t earlydata_max,
|
||||
unsigned char *quic_tp, size_t quic_tp_len,
|
||||
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,
|
||||
ietf_tls_id, alpn, 0,
|
||||
ietf_tls_id, alpn,
|
||||
(curl_off_t)time(NULL) +
|
||||
wolfSSL_SESSION_get_timeout(session), 0,
|
||||
&sc_session);
|
||||
sdata = NULL; /* took ownership of sdata */
|
||||
|
||||
@ -212,6 +212,8 @@ class TestCaddy:
|
||||
|
||||
@pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3'])
|
||||
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():
|
||||
pytest.skip("h3 not supported")
|
||||
count = 2
|
||||
|
||||
Loading…
Reference in New Issue
Block a user