mbedtls: handle session as blobs

Use mbedtls_ssl_session_load() and mbedtls_ssl_session_save() to convert
TLS sessions to byte blobs for the session cache.

Fix a skip message to better indicate why the test is skipped for
mbedtls.

Closes #15398
This commit is contained in:
Stefan Eissing 2024-10-24 13:38:15 +02:00 committed by Daniel Stenberg
parent 3722ed0376
commit 30f66c8ba4
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 49 additions and 28 deletions

View File

@ -885,18 +885,27 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
/* Check if there is a cached ID we can/should use here! */ /* Check if there is a cached ID we can/should use here! */
if(ssl_config->primary.cache_session) { if(ssl_config->primary.cache_session) {
void *old_session = NULL; void *sdata = NULL;
size_t slen = 0;
Curl_ssl_sessionid_lock(data); Curl_ssl_sessionid_lock(data);
if(!Curl_ssl_getsessionid(cf, data, &connssl->peer, if(!Curl_ssl_getsessionid(cf, data, &connssl->peer,
&old_session, NULL, NULL)) { &sdata, &slen, NULL) && slen) {
ret = mbedtls_ssl_set_session(&backend->ssl, old_session); mbedtls_ssl_session session;
mbedtls_ssl_session_init(&session);
ret = mbedtls_ssl_session_load(&session, sdata, slen);
if(ret) { if(ret) {
Curl_ssl_sessionid_unlock(data); failf(data, "error loading cached session: -0x%x", -ret);
failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret);
return CURLE_SSL_CONNECT_ERROR;
} }
infof(data, "mbedTLS reusing session"); else {
ret = mbedtls_ssl_set_session(&backend->ssl, &session);
if(ret)
failf(data, "error setting session: -0x%x", -ret);
else
infof(data, "SSL reusing session ID");
}
mbedtls_ssl_session_free(&session);
} }
Curl_ssl_sessionid_unlock(data); Curl_ssl_sessionid_unlock(data);
} }
@ -1116,11 +1125,10 @@ pinnedpubkey_error:
return CURLE_OK; return CURLE_OK;
} }
static void mbedtls_session_free(void *sessionid, size_t idsize) static void mbedtls_session_free(void *session, size_t slen)
{ {
(void)idsize; (void)slen;
mbedtls_ssl_session_free(sessionid); free(session);
free(sessionid);
} }
static CURLcode static CURLcode
@ -1135,29 +1143,42 @@ mbed_new_session(struct Curl_cfilter *cf, struct Curl_easy *data)
DEBUGASSERT(backend); DEBUGASSERT(backend);
if(ssl_config->primary.cache_session) { if(ssl_config->primary.cache_session) {
int ret; int ret;
mbedtls_ssl_session *our_ssl_sessionid; mbedtls_ssl_session session;
unsigned char *sdata = NULL;
size_t slen = 0;
our_ssl_sessionid = malloc(sizeof(mbedtls_ssl_session)); mbedtls_ssl_session_init(&session);
if(!our_ssl_sessionid) ret = mbedtls_ssl_get_session(&backend->ssl, &session);
return CURLE_OUT_OF_MEMORY;
mbedtls_ssl_session_init(our_ssl_sessionid);
ret = mbedtls_ssl_get_session(&backend->ssl, our_ssl_sessionid);
if(ret) { if(ret) {
if(ret != MBEDTLS_ERR_SSL_ALLOC_FAILED) if(ret != MBEDTLS_ERR_SSL_ALLOC_FAILED)
mbedtls_ssl_session_free(our_ssl_sessionid); mbedtls_ssl_session_free(&session);
free(our_ssl_sessionid);
failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret); failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret);
return CURLE_SSL_CONNECT_ERROR; return CURLE_SSL_CONNECT_ERROR;
} }
/* If there is already a matching session in the cache, delete it */ mbedtls_ssl_session_save(&session, NULL, 0, &slen);
if(!slen) {
failf(data, "failed to serialize session: length is 0");
}
else {
sdata = malloc(slen);
if(sdata) {
ret = mbedtls_ssl_session_save(&session, sdata, slen, &slen);
if(ret) {
failf(data, "failed to serialize session: -0x%x", -ret);
}
else {
Curl_ssl_sessionid_lock(data); Curl_ssl_sessionid_lock(data);
result = Curl_ssl_set_sessionid(cf, data, &connssl->peer, NULL, result = Curl_ssl_set_sessionid(cf, data, &connssl->peer, NULL,
our_ssl_sessionid, 0, sdata, slen, mbedtls_session_free);
mbedtls_session_free);
Curl_ssl_sessionid_unlock(data); Curl_ssl_sessionid_unlock(data);
if(!result)
sdata = NULL;
}
}
}
mbedtls_ssl_session_free(&session);
free(sdata);
} }
return result; return result;
} }

View File

@ -143,7 +143,7 @@ class TestSSLUse:
if env.curl_uses_lib('bearssl'): if env.curl_uses_lib('bearssl'):
pytest.skip("BearSSL does not support cert verification with IP addresses") pytest.skip("BearSSL does not support cert verification with IP addresses")
if env.curl_uses_lib('mbedtls'): if env.curl_uses_lib('mbedtls'):
pytest.skip("mbedTLS does not support cert verification with IP addresses") pytest.skip("mbedTLS does use IP addresses in SNI")
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")
curl = CurlClient(env=env) curl = CurlClient(env=env)