/* an alternative name matched */
;
else if(dNSName || iPAddress) {
- infof(data, " subjectAltName does not match %s", peer->dispname);
+ infof(data, " subjectAltName does not match %s %s",
+ peer->is_ip_address? "ip address" : "host name", peer->dispname);
failf(data, "SSL: no alternative certificate subject name matches "
- "target host name '%s'", peer->dispname);
+ "target %s '%s'",
+ peer->is_ip_address? "ip address" : "host name", peer->dispname);
result = CURLE_PEER_FAILED_VERIFICATION;
}
else {
@pytest.mark.skipif(condition=not Env.curl_has_feature('HTTPS-proxy'),
reason='curl lacks HTTPS-proxy support')
@pytest.mark.parametrize("proto", ['http/1.1', 'h2'])
- @pytest.mark.skipif(condition=not Env.have_nghttpx(), reason="no nghttpx available")
- def test_10_02_proxys_down(self, env: Env, httpd, nghttpx_fwd, proto, repeat):
+ def test_10_02_proxys_down(self, env: Env, httpd, proto, repeat):
if proto == 'h2' and not env.curl_uses_lib('nghttp2'):
pytest.skip('only supported with nghttp2')
curl = CurlClient(env=env)
extra_args=x2_args)
r2.check_response(count=2, http_status=200)
assert r2.total_connects == 2
+
+ # download via https: proxy (no tunnel) using IP address
+ @pytest.mark.skipif(condition=not Env.curl_has_feature('HTTPS-proxy'),
+ reason='curl lacks HTTPS-proxy support')
+ @pytest.mark.skipif(condition=Env.curl_uses_lib('bearssl'), reason="ip address cert verification not supported")
+ @pytest.mark.parametrize("proto", ['http/1.1', 'h2'])
+ def test_10_14_proxys_ip_addr(self, env: Env, httpd, proto, repeat):
+ if proto == 'h2' and not env.curl_uses_lib('nghttp2'):
+ pytest.skip('only supported with nghttp2')
+ curl = CurlClient(env=env)
+ url = f'http://localhost:{env.http_port}/data.json'
+ xargs = curl.get_proxy_args(proto=proto, use_ip=True)
+ r = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True,
+ extra_args=xargs)
+ r.check_response(count=1, http_status=200,
+ protocol='HTTP/2' if proto == 'h2' else 'HTTP/1.1')
+
#
###########################################################################
#
+import ipaddress
import os
import re
from datetime import timedelta, datetime
valid_from: timedelta = timedelta(days=-1),
valid_to: timedelta = timedelta(days=89),
client: bool = False,
+ check_valid: bool = True,
sub_specs: Optional[List['CertificateSpec']] = None):
self._name = name
self.domains = domains
self.valid_from = valid_from
self.valid_to = valid_to
self.sub_specs = sub_specs
+ self.check_valid = check_valid
@property
def name(self) -> Optional[str]:
creds = None
if self._store:
creds = self._store.load_credentials(
- name=spec.name, key_type=key_type, single_file=spec.single_file, issuer=self)
+ name=spec.name, key_type=key_type, single_file=spec.single_file,
+ issuer=self, check_valid=spec.check_valid)
if creds is None:
creds = TestCA.create_credentials(spec=spec, issuer=self, key_type=key_type,
valid_from=spec.valid_from, valid_to=spec.valid_to)
def load_credentials(self, name: str, key_type=None,
single_file: bool = False,
- issuer: Optional[Credentials] = None):
+ issuer: Optional[Credentials] = None,
+ check_valid: bool = False):
cert_file = self.get_cert_file(name=name, key_type=key_type)
pkey_file = cert_file if single_file else self.get_pkey_file(name=name, key_type=key_type)
comb_file = self.get_combined_file(name=name, key_type=key_type)
if os.path.isfile(cert_file) and os.path.isfile(pkey_file):
cert = self.load_pem_cert(cert_file)
pkey = self.load_pem_pkey(pkey_file)
+ if check_valid and \
+ ((cert.not_valid_after < datetime.now()) or
+ (cert.not_valid_before > datetime.now())):
+ return None
creds = Credentials(name=name, cert=cert, pkey=pkey, issuer=issuer)
creds.set_store(self)
creds.set_files(cert_file, pkey_file, comb_file)
@staticmethod
def _add_leaf_usages(csr: Any, domains: List[str], issuer: Credentials) -> Any:
+ names = []
+ for name in domains:
+ try:
+ names.append(x509.IPAddress(ipaddress.ip_address(name)))
+ except:
+ names.append(x509.DNSName(name))
+
return csr.add_extension(
x509.BasicConstraints(ca=False, path_length=None),
critical=True,
x509.SubjectKeyIdentifier).value),
critical=False
).add_extension(
- x509.SubjectAlternativeName([x509.DNSName(domain) for domain in domains]),
- critical=True,
+ x509.SubjectAlternativeName(names), critical=True,
).add_extension(
x509.ExtendedKeyUsage([
ExtendedKeyUsageOID.SERVER_AUTH,
return os.makedirs(path)
def get_proxy_args(self, proto: str = 'http/1.1',
- proxys: bool = True, tunnel: bool = False):
+ proxys: bool = True, tunnel: bool = False,
+ use_ip: bool = False):
+ proxy_name = '127.0.0.1' if use_ip else self.env.proxy_domain
if proxys:
pport = self.env.pts_port(proto) if tunnel else self.env.proxys_port
xargs = [
- '--proxy', f'https://{self.env.proxy_domain}:{pport}/',
- '--resolve', f'{self.env.proxy_domain}:{pport}:127.0.0.1',
+ '--proxy', f'https://{proxy_name}:{pport}/',
+ '--resolve', f'{proxy_name}:{pport}:127.0.0.1',
'--proxy-cacert', self.env.ca.cert_file,
]
if proto == 'h2':
xargs.append('--proxy-http2')
else:
xargs = [
- '--proxy', f'http://{self.env.proxy_domain}:{self.env.proxy_port}/',
- '--resolve', f'{self.env.proxy_domain}:{self.env.proxy_port}:127.0.0.1',
+ '--proxy', f'http://{proxy_name}:{self.env.proxy_port}/',
+ '--resolve', f'{proxy_name}:{self.env.proxy_port}:127.0.0.1',
]
if tunnel:
xargs.append('--proxytunnel')
import subprocess
import sys
from configparser import ConfigParser, ExtendedInterpolation
+from datetime import timedelta
from typing import Optional
import pytest
self.cert_specs = [
CertificateSpec(domains=[self.domain1, 'localhost'], key_type='rsa2048'),
CertificateSpec(domains=[self.domain2], key_type='rsa2048'),
- CertificateSpec(domains=[self.proxy_domain], key_type='rsa2048'),
+ CertificateSpec(domains=[self.proxy_domain, '127.0.0.1'], key_type='rsa2048'),
CertificateSpec(name="clientsX", sub_specs=[
CertificateSpec(name="user1", client=True),
]),