#define TLS13_SUPPORT
#endif
+#if defined(TLS13_SUPPORT) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+#define HAS_SESSION_TICKETS
+#endif
+
#if defined(THREADING_SUPPORT)
static mbedtls_entropy_context ts_entropy;
break;
#endif
default:
- failf(data, "mbedTLS: unsupported minimum TLS version value");
+ failf(data, "mbedTLS: unsupported minimum TLS version value: %x",
+ conn_config->version);
return CURLE_SSL_CONNECT_ERROR;
}
return CURLE_SSL_CONNECT_ERROR;
}
+#ifdef MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED
+ /* New in mbedTLS 3.6.1, need to enable, default is now disabled */
+ mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(&backend->config,
+ MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED);
+#endif
+
/* Always let mbedTLS verify certificates, if verifypeer or verifyhost are
* disabled we clear the corresponding error flags in the verify callback
* function. That is also where we log verification errors. */
}
static CURLcode
-mbed_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
+mbed_new_session(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- CURLcode retcode = CURLE_OK;
struct ssl_connect_data *connssl = cf->ctx;
struct mbed_ssl_backend_data *backend =
(struct mbed_ssl_backend_data *)connssl->backend;
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
+ CURLcode result = CURLE_OK;
- DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
DEBUGASSERT(backend);
-
if(ssl_config->primary.cache_session) {
int ret;
mbedtls_ssl_session *our_ssl_sessionid;
/* If there is already a matching session in the cache, delete it */
Curl_ssl_sessionid_lock(data);
- retcode = Curl_ssl_set_sessionid(cf, data, &connssl->peer, NULL,
- our_ssl_sessionid, 0,
- mbedtls_session_free);
+ result = Curl_ssl_set_sessionid(cf, data, &connssl->peer, NULL,
+ our_ssl_sessionid, 0,
+ mbedtls_session_free);
Curl_ssl_sessionid_unlock(data);
- if(retcode)
- return retcode;
}
-
- connssl->connecting_state = ssl_connect_done;
-
- return CURLE_OK;
+ return result;
}
static ssize_t mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data,
struct mbed_ssl_backend_data *backend =
(struct mbed_ssl_backend_data *)connssl->backend;
int ret = -1;
- ssize_t len = -1;
(void)data;
DEBUGASSERT(backend);
if(ret <= 0) {
CURL_TRC_CF(data, cf, "mbedtls_ssl_read(len=%zu) -> -0x%04X",
buffersize, -ret);
- if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
- return 0;
- *curlcode = ((ret == MBEDTLS_ERR_SSL_WANT_READ)
-#ifdef TLS13_SUPPORT
- || (ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
+ switch(ret) {
+#ifdef HAS_SESSION_TICKETS
+ case MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET:
+ mbed_new_session(cf, data);
+ FALLTHROUGH();
#endif
- ) ? CURLE_AGAIN : CURLE_RECV_ERROR;
- if(*curlcode != CURLE_AGAIN) {
+ case MBEDTLS_ERR_SSL_WANT_READ:
+ *curlcode = CURLE_AGAIN;
+ ret = -1;
+ break;
+ case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
+ *curlcode = CURLE_OK;
+ ret = 0;
+ break;
+ default: {
char errorbuf[128];
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
failf(data, "ssl_read returned: (-0x%04X) %s", -ret, errorbuf);
+ *curlcode = CURLE_RECV_ERROR;
+ ret = -1;
+ break;
+ }
}
- return -1;
}
-
- len = ret;
-
- return len;
+ return (ssize_t)ret;
}
static size_t mbedtls_version(char *buffer, size_t size)
} /* repeat step2 until all transactions are done. */
if(ssl_connect_3 == connssl->connecting_state) {
- retcode = mbed_connect_step3(cf, data);
- if(retcode)
- return retcode;
+ /* For tls1.3 we get notified about new sessions */
+#if MBEDTLS_VERSION_NUMBER >= 0x03020000
+ struct ssl_connect_data *ctx = cf->ctx;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)ctx->backend;
+
+ if(mbedtls_ssl_get_version_number(&backend->ssl) <=
+ MBEDTLS_SSL_VERSION_TLS1_2) {
+#else
+ { /* no TLSv1.3 supported here */
+#endif
+ retcode = mbed_new_session(cf, data);
+ if(retcode)
+ return retcode;
+ }
+ connssl->connecting_state = ssl_connect_done;
}
if(ssl_connect_done == connssl->connecting_state) {
exp_resumed = 'Initial' # Rustls does not support sessions, TODO
if env.curl_uses_lib('bearssl') and tls_max == '1.3':
pytest.skip('BearSSL does not support TLSv1.3')
- if env.curl_uses_lib('mbedtls') and tls_max == '1.3':
+ if env.curl_uses_lib('mbedtls') and tls_max == '1.3' and \
+ not env.curl_lib_version_at_least('mbedtls', '3.6.0'):
pytest.skip('mbedtls TLSv1.3 session resume not working in 3.6.0')
- curl = CurlClient(env=env)
+ run_env = os.environ.copy()
+ run_env['CURL_DEBUG'] = 'ssl'
+ curl = CurlClient(env=env, run_env=run_env)
# tell the server to close the connection after each request
urln = f'https://{env.authority_for(env.domain1, proto)}/curltest/sslinfo?'\
f'id=[0-{count-1}]&close'
djson = json.load(f)
assert djson['HTTPS'] == 'on', f'{i}: {djson}'
if i == 0:
- assert djson['SSL_SESSION_RESUMED'] == 'Initial', f'{i}: {djson}'
+ assert djson['SSL_SESSION_RESUMED'] == 'Initial', f'{i}: {djson}\n{r.dump_logs()}'
else:
- assert djson['SSL_SESSION_RESUMED'] == exp_resumed, f'{i}: {djson}'
+ assert djson['SSL_SESSION_RESUMED'] == exp_resumed, f'{i}: {djson}\n{r.dump_logs()}'
# use host name with trailing dot, verify handshake
@pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3'])
if tls_proto == 'TLSv1.3':
pytest.skip('BearSSL does not support TLSv1.3')
tls_proto = 'TLSv1.2'
+ elif env.curl_uses_lib('mbedtls') and not env.curl_lib_version_at_least('mbedtls', '3.6.0'):
+ if tls_proto == 'TLSv1.3':
+ pytest.skip('mbedTLS < 3.6.0 does not support TLSv1.3')
elif env.curl_uses_lib('sectransp'): # not in CI, so untested
if tls_proto == 'TLSv1.3':
pytest.skip('Secure Transport does not support TLSv1.3')