result = Curl_vtls_apple_verify(cf, data, peer, chain->num_certs,
gtls_chain_get_der, chain, NULL, 0);
*pverified = !result;
- if(*pverified)
- infof(data, " SSL certificate verified by Apple SecTrust.");
return result;
}
#endif /* USE_APPLE_SECTRUST */
sizeof(error_buffer)));
}
else {
- infof(data, "SSL reusing session with ALPN '%s'",
- scs->alpn ? scs->alpn : "-");
- octx->reused_session = TRUE;
+ if(conn_cfg->verifypeer &&
+ (SSL_get_verify_result(octx->ssl) != X509_V_OK)) {
+ /* Session was from unverified connection, cannot reuse here */
+ SSL_set_session(octx->ssl, NULL);
+ infof(data, "SSL session not peer verified, not reusing");
+ }
+ else {
+ infof(data, "SSL reusing session with ALPN '%s'",
+ scs->alpn ? scs->alpn : "-");
+ octx->reused_session = TRUE;
+ infof(data, "SSL verify result: %lx",
+ SSL_get_verify_result(octx->ssl));
#ifdef HAVE_OPENSSL_EARLYDATA
- if(ssl_config->earlydata && scs->alpn &&
- SSL_SESSION_get_max_early_data(ssl_session) &&
- !cf->conn->connect_only &&
- (SSL_version(octx->ssl) == TLS1_3_VERSION)) {
- bool do_early_data = FALSE;
- if(sess_reuse_cb) {
- result = sess_reuse_cb(cf, data, &alpns, scs, &do_early_data);
- if(result) {
- SSL_SESSION_free(ssl_session);
- return result;
+ if(ssl_config->earlydata && scs->alpn &&
+ SSL_SESSION_get_max_early_data(ssl_session) &&
+ !cf->conn->connect_only &&
+ (SSL_version(octx->ssl) == TLS1_3_VERSION)) {
+ bool do_early_data = FALSE;
+ if(sess_reuse_cb) {
+ result = sess_reuse_cb(cf, data, &alpns, scs, &do_early_data);
+ if(result) {
+ SSL_SESSION_free(ssl_session);
+ return result;
+ }
+ }
+ if(do_early_data) {
+ /* We only try the ALPN protocol the session used before,
+ * otherwise we might send early data for the wrong protocol */
+ Curl_alpn_restrict_to(&alpns, scs->alpn);
}
}
- if(do_early_data) {
- /* We only try the ALPN protocol the session used before,
- * otherwise we might send early data for the wrong protocol */
- Curl_alpn_restrict_to(&alpns, scs->alpn);
- }
- }
#else
- (void)ssl_config;
- (void)sess_reuse_cb;
+ (void)ssl_config;
+ (void)sess_reuse_cb;
#endif
+ }
}
SSL_SESSION_free(ssl_session);
}
if(!chain.num_certs &&
(conn_config->verifypeer || conn_config->verifyhost)) {
- failf(data, "SSL: could not get peer certificate");
- result = CURLE_PEER_FAILED_VERIFICATION;
+ if(!octx->reused_session) {
+ failf(data, "SSL: could not get peer certificate chain");
+ result = CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else {
+ /* when session was reused, there is no peer cert chain */
+ *pverified = FALSE;
+ return CURLE_OK;
+ }
}
else {
#ifdef HAVE_BORINGSSL_LIKE
ossl_verify = SSL_get_verify_result(octx->ssl);
ssl_config->certverifyresult = ossl_verify;
+ infof(data, "OpenSSL verify result: %lx", ossl_verify);
verified = (ossl_verify == X509_V_OK);
if(verified)
if not client.exists():
pytest.skip(f'example client not built: {client.name}')
r = client.run(args=[
- '-n', f'{count}', '-P', f'{pause_offset}', '-V', proto, url
+ '-n', f'{count}', '-P', f'{pause_offset}',
+ '-C', env.ca.cert_file, '-V', proto, url
])
r.check_exit_code(0)
srcfile = os.path.join(httpd.docs_dir, docname)
pytest.skip(f'example client not built: {client.name}')
r = client.run(args=[
'-n', f'{count}', '-m', f'{max_parallel}',
- '-P', f'{pause_offset}', '-V', proto, url
+ '-P', f'{pause_offset}', '-C', env.ca.cert_file,
+ '-V', proto, url
])
r.check_exit_code(0)
srcfile = os.path.join(httpd.docs_dir, docname)
pytest.skip(f'example client not built: {client.name}')
r = client.run(args=[
'-n', f'{count}', '-m', f'{max_parallel}', '-a',
+ '-C', env.ca.cert_file,
'-P', f'{pause_offset}', '-V', proto, url
])
r.check_exit_code(0)
pytest.skip(f'example client not built: {client.name}')
r = client.run(args=[
'-n', f'{count}', '-m', f'{max_parallel}', '-a',
+ '-C', env.ca.cert_file,
'-A', f'{abort_offset}', '-V', proto, url
])
r.check_exit_code(42) # CURLE_ABORTED_BY_CALLBACK
pytest.skip(f'example client not built: {client.name}')
r = client.run(args=[
'-n', f'{count}', '-m', f'{max_parallel}', '-a',
+ '-C', env.ca.cert_file,
'-F', f'{fail_offset}', '-V', proto, url
])
r.check_exit_code(23) # CURLE_WRITE_ERROR
if not client.exists():
pytest.skip(f'example client not built: {client.name}')
r = client.run(args=[
- '-n', f'{count}', '-P', f'{pause_offset}', '-V', proto, url
+ '-n', f'{count}', '-P', f'{pause_offset}',
+ '-C', env.ca.cert_file, '-V', proto, url
])
r.check_exit_code(0)
srcfile = os.path.join(httpd.docs_dir, docname)
pytest.skip(f'example client not built: {client.name}')
r = client.run(args=[
'-n', f'{count}',
+ '-C', env.ca.cert_file,
'-e', # use TLS earlydata
'-f', # forbid reuse of connections
'-r', f'{env.domain1}:{port}:127.0.0.1',
r = client.run(args=[
'-n', f'{count}',
'-m', f'{max_parallel}',
+ '-C', env.ca.cert_file,
'-x', # always use a fresh connection
'-M', str(max_host_conns), # limit conns per host
'-r', f'{env.domain1}:{port}:127.0.0.1',
r = client.run(args=[
'-n', f'{count}',
'-m', f'{max_parallel}',
+ '-C', env.ca.cert_file,
'-x', # always use a fresh connection
'-T', str(max_total_conns), # limit total connections
'-r', f'{env.domain1}:{port}:127.0.0.1',
pytest.skip(f'example client not built: {client.name}')
r = client.run(args=[
'-n', f'{count}', '-m', f'{count}',
- '-P', f'{pause_offset}', '-V', proto, url
+ '-P', f'{pause_offset}', '-C', env.ca.cert_file,
+ '-V', proto, url
])
r.check_exit_code(0)
pytest.skip(f'example client not built: {client.name}')
r = client.run(args=[
'-n', f'{count}',
+ '-C', env.ca.cert_file,
'-e', # use TLS earlydata
'-f', # forbid reuse of connections
'-r', f'{env.domain1}:{caddy.port}:127.0.0.1',
if not env.have_h3():
pytest.skip("h3 not supported")
if not env.curl_uses_lib('quictls') and \
- not (env.curl_uses_lib('openssl') and env.curl_uses_lib('ngtcp2')) and \
+ not env.curl_uses_lib('openssl') and \
not env.curl_uses_lib('gnutls') and \
not env.curl_uses_lib('wolfssl'):
pytest.skip("QUIC session reuse not implemented")
r = client.run(args=[
'-n', f'{count}',
'-f', # forbid reuse of connections
+ '-C', env.ca.cert_file,
'-r', f'{env.domain1}:{env.port_for("h3")}:127.0.0.1',
'-V', 'h3', url
])
if not client.exists():
pytest.skip(f'example client not built: {client.name}')
r = client.run(args=[
- '-n', f'{count}', '-f', '-V', proto, url
+ '-n', f'{count}', '-f', '-C', env.ca.cert_file,
+ '-V', proto, url
])
r.check_exit_code(0)
shutdowns = [line for line in r.trace_lines
pytest.skip(f'example client not built: {client.name}')
r = client.run(args=[
'-n', f'{count}', # that many transfers
+ '-C', env.ca.cert_file,
'-f', # forbid conn reuse
'-m', '10', # max parallel
'-T', '5', # max total conns at a time
static int setup_hx_download(CURL *curl, const char *url, struct transfer_d *t,
long http_version, struct curl_slist *host,
CURLSH *share, int use_earlydata,
- int fresh_connect)
+ int fresh_connect, char *cafile)
{
curl_easy_setopt(curl, CURLOPT_SHARE, share);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, http_version);
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+ if(cafile)
+ curl_easy_setopt(curl, CURLOPT_CAINFO, cafile);
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "");
curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, (long)(128 * 1024));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_write_d_cb);
size_t max_host_conns = 0;
size_t max_total_conns = 0;
int fresh_connect = 0;
+ char *cafile = NULL;
CURLcode result = CURLE_OK;
(void)URL;
- while((ch = cgetopt(test_argc, test_argv, "aefhm:n:xA:F:M:P:r:T:V:"))
+ while((ch = cgetopt(test_argc, test_argv, "aefhm:n:xA:C:F:M:P:r:T:V:"))
!= -1) {
const char *opt = coptarg;
curl_off_t num;
if(!curlx_str_number(&opt, &num, LONG_MAX))
abort_offset = (size_t)num;
break;
+ case 'C':
+ curlx_free(cafile);
+ cafile = curlx_strdup(coptarg);
+ break;
case 'F':
if(!curlx_str_number(&opt, &num, LONG_MAX))
fail_offset = (size_t)num;
t->curl = curl_easy_init();
if(!t->curl ||
setup_hx_download(t->curl, url, t, http_version, host, share,
- use_earlydata, fresh_connect)) {
+ use_earlydata, fresh_connect, cafile)) {
curl_mfprintf(stderr, "[t-%zu] FAILED setup\n", i);
result = (CURLcode)1;
goto cleanup;
t->curl = curl_easy_init();
if(!t->curl ||
setup_hx_download(t->curl, url, t, http_version, host, share,
- use_earlydata, fresh_connect)) {
+ use_earlydata, fresh_connect, cafile)) {
curl_mfprintf(stderr, "[t-%zu] FAILED setup\n", i);
result = (CURLcode)1;
goto cleanup;
optcleanup:
curlx_free(resolve);
+ curlx_free(cafile);
return result;
}