diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 0643ba046e..f2987ea944 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -4220,14 +4220,11 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
lerr = SSL_get_verify_result(octx->ssl);
if(lerr != X509_V_OK) {
ssl_config->certverifyresult = lerr;
- msnprintf(error_buffer, sizeof(error_buffer),
- "SSL certificate problem: %s",
- X509_verify_cert_error_string(lerr));
+ failf(data, "SSL certificate problem: %s",
+ X509_verify_cert_error_string(lerr));
}
- else {
+ else
failf(data, "%s", "SSL certificate verification failed");
- return result;
- }
}
#if defined(SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED)
/* SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED is only available on
@@ -4278,7 +4275,6 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%d ",
extramsg[0] ? extramsg : SSL_ERROR_to_str(detail),
connssl->peer.hostname, connssl->peer.port);
- return result;
}
return result;
diff --git a/tests/http/test_17_ssl_use.py b/tests/http/test_17_ssl_use.py
index f129b11018..883d4a5f6f 100644
--- a/tests/http/test_17_ssl_use.py
+++ b/tests/http/test_17_ssl_use.py
@@ -366,3 +366,27 @@ class TestSSLUse:
])
assert r.exit_code == 0, f'{r}'
assert r.json, f'{r}'
+
+ # connect to an expired certificate
+ @pytest.mark.parametrize("proto", ['http/1.1', 'h2'])
+ def test_17_14_expired_cert(self, env: Env, proto):
+ if proto == 'h3' and not env.have_h3():
+ pytest.skip("h3 not supported")
+ curl = CurlClient(env=env)
+ url = f'https://{env.expired_domain}:{env.port_for(proto)}/'
+ r = curl.http_get(url=url, alpn_proto=proto)
+ assert r.exit_code == 60, f'{r}' # peer failed verification
+ exp_trace = None
+ match_trace = None
+ if env.curl_uses_lib('openssl') or env.curl_uses_lib('quictls'):
+ exp_trace = r'.*SSL certificate problem: certificate has expired$'
+ elif env.curl_uses_lib('gnutls'):
+ exp_trace = r'.*server verification failed: certificate has expired\..*'
+ elif env.curl_uses_lib('wolfssl'):
+ exp_trace = r'.*server verification failed: certificate has expired\.$'
+ if exp_trace is not None:
+ for line in r.trace_lines:
+ if re.match(exp_trace, line):
+ match_trace = line
+ break
+ assert match_trace, f'Did not find "{exp_trace}" in trace\n{r.dump_logs()}'
diff --git a/tests/http/testenv/env.py b/tests/http/testenv/env.py
index 4eb0eb7653..5360c46055 100644
--- a/tests/http/testenv/env.py
+++ b/tests/http/testenv/env.py
@@ -32,6 +32,7 @@ import socket
import subprocess
import tempfile
from configparser import ConfigParser, ExtendedInterpolation
+from datetime import timedelta
from typing import Optional
from .certs import CertificateSpec, Credentials, TestCA
@@ -143,11 +144,14 @@ class EnvConfig:
self.domain2 = f"two.{self.tld}"
self.ftp_domain = f"ftp.{self.tld}"
self.proxy_domain = f"proxy.{self.tld}"
+ self.expired_domain = f"expired.{self.tld}"
self.cert_specs = [
CertificateSpec(domains=[self.domain1, self.domain1brotli, 'localhost', '127.0.0.1'], key_type='rsa2048'),
CertificateSpec(domains=[self.domain2], key_type='rsa2048'),
CertificateSpec(domains=[self.ftp_domain], key_type='rsa2048'),
CertificateSpec(domains=[self.proxy_domain, '127.0.0.1'], key_type='rsa2048'),
+ CertificateSpec(domains=[self.expired_domain], key_type='rsa2048',
+ valid_from=timedelta(days=-100), valid_to=timedelta(days=-10)),
CertificateSpec(name="clientsX", sub_specs=[
CertificateSpec(name="user1", client=True),
]),
@@ -502,6 +506,10 @@ class Env:
def proxy_domain(self) -> str:
return self.CONFIG.proxy_domain
+ @property
+ def expired_domain(self) -> str:
+ return self.CONFIG.expired_domain
+
@property
def http_port(self) -> int:
return self.CONFIG.ports['http']
diff --git a/tests/http/testenv/httpd.py b/tests/http/testenv/httpd.py
index f3ca46f133..414f358ee2 100644
--- a/tests/http/testenv/httpd.py
+++ b/tests/http/testenv/httpd.py
@@ -219,6 +219,9 @@ class Httpd:
domain2 = self.env.domain2
creds2 = self.env.get_credentials(domain2)
assert creds2 # convince pytype this isn't None
+ exp_domain = self.env.expired_domain
+ exp_creds = self.env.get_credentials(exp_domain)
+ assert exp_creds # convince pytype this isn't None
proxy_domain = self.env.proxy_domain
proxy_creds = self.env.get_credentials(proxy_domain)
assert proxy_creds # convince pytype this isn't None
@@ -346,6 +349,22 @@ class Httpd:
'',
'',
])
+ conf.extend([ # https host for expired domain
+ f'',
+ f' ServerName {exp_domain}',
+ ' Protocols h2 http/1.1',
+ ' SSLEngine on',
+ f' SSLCertificateFile {exp_creds.cert_file}',
+ f' SSLCertificateKeyFile {exp_creds.pkey_file}',
+ f' DocumentRoot "{self._docs_dir}/expired"',
+ ])
+ conf.extend(self._curltest_conf(exp_domain))
+ if exp_domain in self._extra_configs:
+ conf.extend(self._extra_configs[exp_domain])
+ conf.extend([
+ '',
+ '',
+ ])
conf.extend([ # http forward proxy
f'',
f' ServerName {proxy_domain}',