Tests for SSL certs for federation connections
Add some tests for bad certificates for federation and .well-known connections
This commit is contained in:
parent
efe7b3176e
commit
e016681221
|
@ -13,28 +13,124 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
import os.path
|
import os.path
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from zope.interface import implementer
|
||||||
|
|
||||||
from OpenSSL import SSL
|
from OpenSSL import SSL
|
||||||
|
from OpenSSL.SSL import Connection
|
||||||
|
from twisted.internet.interfaces import IOpenSSLServerConnectionCreator
|
||||||
|
|
||||||
|
|
||||||
def get_test_cert_file():
|
def get_test_ca_cert_file():
|
||||||
"""get the path to the test cert"""
|
"""Get the path to the test CA cert
|
||||||
|
|
||||||
# the cert file itself is made with:
|
The keypair is generated with:
|
||||||
#
|
|
||||||
# openssl req -x509 -newkey rsa:4096 -keyout server.pem -out server.pem -days 36500 \
|
openssl genrsa -out ca.key 2048
|
||||||
# -nodes -subj '/CN=testserv'
|
openssl req -new -x509 -key ca.key -days 3650 -out ca.crt \
|
||||||
return os.path.join(os.path.dirname(__file__), 'server.pem')
|
-subj '/CN=synapse test CA'
|
||||||
|
"""
|
||||||
|
return os.path.join(os.path.dirname(__file__), "ca.crt")
|
||||||
|
|
||||||
|
|
||||||
class ServerTLSContext(object):
|
def get_test_key_file():
|
||||||
"""A TLS Context which presents our test cert."""
|
"""get the path to the test key
|
||||||
|
|
||||||
def __init__(self):
|
The key file is made with:
|
||||||
self.filename = get_test_cert_file()
|
|
||||||
|
|
||||||
def getContext(self):
|
openssl genrsa -out server.key 2048
|
||||||
|
"""
|
||||||
|
return os.path.join(os.path.dirname(__file__), "server.key")
|
||||||
|
|
||||||
|
|
||||||
|
cert_file_count = 0
|
||||||
|
|
||||||
|
CONFIG_TEMPLATE = b"""\
|
||||||
|
[default]
|
||||||
|
basicConstraints = CA:FALSE
|
||||||
|
keyUsage=nonRepudiation, digitalSignature, keyEncipherment
|
||||||
|
subjectAltName = %(sanentries)b
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def create_test_cert_file(sanlist):
|
||||||
|
"""build an x509 certificate file
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sanlist: list[bytes]: a list of subjectAltName values for the cert
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: the path to the file
|
||||||
|
"""
|
||||||
|
global cert_file_count
|
||||||
|
csr_filename = "server.csr"
|
||||||
|
cnf_filename = "server.%i.cnf" % (cert_file_count,)
|
||||||
|
cert_filename = "server.%i.crt" % (cert_file_count,)
|
||||||
|
cert_file_count += 1
|
||||||
|
|
||||||
|
# first build a CSR
|
||||||
|
subprocess.run(
|
||||||
|
[
|
||||||
|
"openssl",
|
||||||
|
"req",
|
||||||
|
"-new",
|
||||||
|
"-key",
|
||||||
|
get_test_key_file(),
|
||||||
|
"-subj",
|
||||||
|
"/",
|
||||||
|
"-out",
|
||||||
|
csr_filename,
|
||||||
|
],
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# now a config file describing the right SAN entries
|
||||||
|
sanentries = b",".join(sanlist)
|
||||||
|
with open(cnf_filename, "wb") as f:
|
||||||
|
f.write(CONFIG_TEMPLATE % {b"sanentries": sanentries})
|
||||||
|
|
||||||
|
# finally the cert
|
||||||
|
ca_key_filename = os.path.join(os.path.dirname(__file__), "ca.key")
|
||||||
|
ca_cert_filename = get_test_ca_cert_file()
|
||||||
|
subprocess.run(
|
||||||
|
[
|
||||||
|
"openssl",
|
||||||
|
"x509",
|
||||||
|
"-req",
|
||||||
|
"-in",
|
||||||
|
csr_filename,
|
||||||
|
"-CA",
|
||||||
|
ca_cert_filename,
|
||||||
|
"-CAkey",
|
||||||
|
ca_key_filename,
|
||||||
|
"-set_serial",
|
||||||
|
"1",
|
||||||
|
"-extfile",
|
||||||
|
cnf_filename,
|
||||||
|
"-out",
|
||||||
|
cert_filename,
|
||||||
|
],
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
return cert_filename
|
||||||
|
|
||||||
|
|
||||||
|
@implementer(IOpenSSLServerConnectionCreator)
|
||||||
|
class TestServerTLSConnectionFactory(object):
|
||||||
|
"""An SSL connection creator which returns connections which present a certificate
|
||||||
|
signed by our test CA."""
|
||||||
|
|
||||||
|
def __init__(self, sanlist):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
sanlist: list[bytes]: a list of subjectAltName values for the cert
|
||||||
|
"""
|
||||||
|
self._cert_file = create_test_cert_file(sanlist)
|
||||||
|
|
||||||
|
def serverConnectionForTLS(self, tlsProtocol):
|
||||||
ctx = SSL.Context(SSL.TLSv1_METHOD)
|
ctx = SSL.Context(SSL.TLSv1_METHOD)
|
||||||
ctx.use_certificate_file(self.filename)
|
ctx.use_certificate_file(self._cert_file)
|
||||||
ctx.use_privatekey_file(self.filename)
|
ctx.use_privatekey_file(get_test_key_file())
|
||||||
return ctx
|
return Connection(ctx, None)
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDCjCCAfKgAwIBAgIJAPwHIHgH/jtjMA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV
|
||||||
|
BAMMD3N5bmFwc2UgdGVzdCBDQTAeFw0xOTA2MTAxMTI2NDdaFw0yOTA2MDcxMTI2
|
||||||
|
NDdaMBoxGDAWBgNVBAMMD3N5bmFwc2UgdGVzdCBDQTCCASIwDQYJKoZIhvcNAQEB
|
||||||
|
BQADggEPADCCAQoCggEBAOZOXCKuylf9jHzJXpU2nS+XEKrnGPgs2SAhQKrzBxg3
|
||||||
|
/d8KT2Zsfsj1i3G7oGu7B0ZKO6qG5AxOPCmSMf9/aiSHFilfSh+r8rCpJyWMev2c
|
||||||
|
/w/xmhoFHgn+H90NnqlXvWb5y1YZCE3gWaituQSaa93GPKacRqXCgIrzjPUuhfeT
|
||||||
|
uwFQt4iyUhMNBYEy3aw4IuIHdyBqi4noUhR2ZeuflLJ6PswdJ8mEiAvxCbBGPerq
|
||||||
|
idhWcZwlo0fKu4u1uu5B8TnTsMg2fJgL6c5olBG90Urt22gA6anfP5W/U1ZdVhmB
|
||||||
|
T3Rv5SJMkGyMGE6sEUetLFyb2GJpgGD7ePkUCZr+IMMCAwEAAaNTMFEwHQYDVR0O
|
||||||
|
BBYEFLg7nTCYsvQXWTyS6upLc0YTlIwRMB8GA1UdIwQYMBaAFLg7nTCYsvQXWTyS
|
||||||
|
6upLc0YTlIwRMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADqx
|
||||||
|
GX4Ul5OGQlcG+xTt4u3vMCeqGo8mh1AnJ7zQbyRmwjJiNxJVX+/EcqFSTsmkBNoe
|
||||||
|
xdYITI7Z6dyoiKw99yCZDE7gALcyACEU7r0XY7VY/hebAaX6uLaw1sZKKAIC04lD
|
||||||
|
KgCu82tG85n60Qyud5SiZZF0q1XVq7lbvOYVdzVZ7k8Vssy5p9XnaLJLMggYeOiX
|
||||||
|
psHIQjvYGnTTEBZZHzWOrc0WGThd69wxTOOkAbCsoTPEwZL8BGUsdtLWtvhp452O
|
||||||
|
npvaUBzKg39R5X3KTdhB68XptiQfzbQkd3FtrwNuYPUywlsg55Bxkv85n57+xDO3
|
||||||
|
D9YkgUqEp0RGUXQgCsQ=
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpgIBAAKCAQEA5k5cIq7KV/2MfMlelTadL5cQqucY+CzZICFAqvMHGDf93wpP
|
||||||
|
Zmx+yPWLcbuga7sHRko7qobkDE48KZIx/39qJIcWKV9KH6vysKknJYx6/Zz/D/Ga
|
||||||
|
GgUeCf4f3Q2eqVe9ZvnLVhkITeBZqK25BJpr3cY8ppxGpcKAivOM9S6F95O7AVC3
|
||||||
|
iLJSEw0FgTLdrDgi4gd3IGqLiehSFHZl65+Usno+zB0nyYSIC/EJsEY96uqJ2FZx
|
||||||
|
nCWjR8q7i7W67kHxOdOwyDZ8mAvpzmiUEb3RSu3baADpqd8/lb9TVl1WGYFPdG/l
|
||||||
|
IkyQbIwYTqwRR60sXJvYYmmAYPt4+RQJmv4gwwIDAQABAoIBAQCFuFG+wYYy+MCt
|
||||||
|
Y65LLN6vVyMSWAQjdMbM5QHLQDiKU1hQPIhFjBFBVXCVpL9MTde3dDqYlKGsk3BT
|
||||||
|
ItNs6eoTM2wmsXE0Wn4bHNvh7WMsBhACjeFP4lDCtI6DpvjMkmkidT8eyoIL1Yu5
|
||||||
|
aMTYa2Dd79AfXPWYIQrJowfhBBY83KuW5fmYnKKDVLqkT9nf2dgmmQz85RgtNiZC
|
||||||
|
zFkIsNmPqH1zRbcw0wORfOBrLFvsMc4Tt8EY5Wz3NnH8Zfgf8Q3MgARH1yspz3Vp
|
||||||
|
B+EYHbsK17xZ+P59KPiX3yefvyYWEUjFF7ymVsVnDxLugYl4pXwWUpm19GxeDvFk
|
||||||
|
cgBUD5OBAoGBAP7lBdCp6lx6fYtxdxUm3n4MMQmYcac4qZdeBIrvpFMnvOBBuixl
|
||||||
|
eavcfFmFdwgAr8HyVYiu9ynac504IYvmtYlcpUmiRBbmMHbvLQEYHl7FYFKNz9ej
|
||||||
|
2ue4oJE3RsPdLsD3xIlc+xN8oT1j0knyorwsHdj0Sv77eZzZS9XZZfJzAoGBAOdO
|
||||||
|
CibYmoNqK/mqDHkp6PgsnbQGD5/CvPF/BLUWV1QpHxLzUQQeoBOQW5FatHe1H5zi
|
||||||
|
mbq3emBefVmsCLrRIJ4GQu4vsTMfjcpGLwviWmaK6pHbGPt8IYeEQ2MNyv59EtA2
|
||||||
|
pQy4dX7/Oe6NLAR1UEQjXmCuXf+rxnxF3VJd1nRxAoGBANb9eusl9fusgSnVOTjJ
|
||||||
|
AQ7V36KVRv9hZoG6liBNwo80zDVmms4JhRd1MBkd3mkMkzIF4SkZUnWlwLBSANGM
|
||||||
|
dX/3eZ5i1AVwgF5Am/f5TNxopDbdT/o1RVT/P8dcFT7s1xuBn+6wU0F7dFBgWqVu
|
||||||
|
lt4aY85zNrJcj5XBHhqwdDGLAoGBAIksPNUAy9F3m5C6ih8o/aKAQx5KIeXrBUZq
|
||||||
|
v43tK+kbYfRJHBjHWMOBbuxq0G/VmGPf9q9GtGqGXuxZG+w+rYtJx1OeMQZShjIZ
|
||||||
|
ITl5CYeahrXtK4mo+fF2PMh3m5UE861LWuKKWhPwpJiWXC5grDNcjlHj1pcTdeip
|
||||||
|
PjHkuJPhAoGBAIh35DptqqdicOd3dr/+/m2YQywY8aSpMrR0bC06aAkscD7oq4tt
|
||||||
|
s/jwl0UlHIrEm/aMN7OnGIbpfkVdExfGKYaa5NRlgOwQpShwLufIo/c8fErd2zb8
|
||||||
|
K3ptlwBxMrayMXpS3DP78r83Z0B8/FSK2guelzdRJ3ftipZ9io1Gss1C
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -17,12 +17,14 @@ import logging
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
|
|
||||||
import treq
|
import treq
|
||||||
|
from service_identity import VerificationError
|
||||||
from zope.interface import implementer
|
from zope.interface import implementer
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.internet._sslverify import ClientTLSOptions, OpenSSLCertificateOptions
|
from twisted.internet._sslverify import ClientTLSOptions, OpenSSLCertificateOptions
|
||||||
from twisted.internet.protocol import Factory
|
from twisted.internet.protocol import Factory
|
||||||
from twisted.protocols.tls import TLSMemoryBIOFactory
|
from twisted.protocols.tls import TLSMemoryBIOFactory
|
||||||
|
from twisted.web._newclient import ResponseNeverReceived
|
||||||
from twisted.web.http import HTTPChannel
|
from twisted.web.http import HTTPChannel
|
||||||
from twisted.web.http_headers import Headers
|
from twisted.web.http_headers import Headers
|
||||||
from twisted.web.iweb import IPolicyForHTTPS
|
from twisted.web.iweb import IPolicyForHTTPS
|
||||||
|
@ -37,13 +39,29 @@ from synapse.http.federation.srv_resolver import Server
|
||||||
from synapse.util.caches.ttlcache import TTLCache
|
from synapse.util.caches.ttlcache import TTLCache
|
||||||
from synapse.util.logcontext import LoggingContext
|
from synapse.util.logcontext import LoggingContext
|
||||||
|
|
||||||
from tests.http import ServerTLSContext
|
from tests.http import TestServerTLSConnectionFactory, get_test_ca_cert_file
|
||||||
from tests.server import FakeTransport, ThreadedMemoryReactorClock
|
from tests.server import FakeTransport, ThreadedMemoryReactorClock
|
||||||
from tests.unittest import TestCase
|
from tests.unittest import TestCase
|
||||||
from tests.utils import default_config
|
from tests.utils import default_config
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
test_server_connection_factory = None
|
||||||
|
|
||||||
|
|
||||||
|
def get_connection_factory():
|
||||||
|
# this needs to happen once, but not until we are ready to run the first test
|
||||||
|
global test_server_connection_factory
|
||||||
|
if test_server_connection_factory is None:
|
||||||
|
test_server_connection_factory = TestServerTLSConnectionFactory(sanlist=[
|
||||||
|
b'DNS:testserv',
|
||||||
|
b'DNS:target-server',
|
||||||
|
b'DNS:xn--bcher-kva.com',
|
||||||
|
b'IP:1.2.3.4',
|
||||||
|
b'IP:::1',
|
||||||
|
])
|
||||||
|
return test_server_connection_factory
|
||||||
|
|
||||||
|
|
||||||
class MatrixFederationAgentTests(TestCase):
|
class MatrixFederationAgentTests(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -53,12 +71,11 @@ class MatrixFederationAgentTests(TestCase):
|
||||||
|
|
||||||
self.well_known_cache = TTLCache("test_cache", timer=self.reactor.seconds)
|
self.well_known_cache = TTLCache("test_cache", timer=self.reactor.seconds)
|
||||||
|
|
||||||
# for now, we disable cert verification for the test, since the cert we
|
|
||||||
# present will not be trusted. We should do better here, though.
|
|
||||||
config_dict = default_config("test", parse=False)
|
config_dict = default_config("test", parse=False)
|
||||||
config_dict["federation_verify_certificates"] = False
|
config_dict["federation_custom_ca_list"] = [get_test_ca_cert_file()]
|
||||||
config_dict["trusted_key_servers"] = []
|
# config_dict["trusted_key_servers"] = []
|
||||||
config = HomeServerConfig()
|
|
||||||
|
self._config = config = HomeServerConfig()
|
||||||
config.parse_config_dict(config_dict)
|
config.parse_config_dict(config_dict)
|
||||||
|
|
||||||
self.agent = MatrixFederationAgent(
|
self.agent = MatrixFederationAgent(
|
||||||
|
@ -77,7 +94,7 @@ class MatrixFederationAgentTests(TestCase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# build the test server
|
# build the test server
|
||||||
server_tls_protocol = _build_test_server()
|
server_tls_protocol = _build_test_server(get_connection_factory())
|
||||||
|
|
||||||
# now, tell the client protocol factory to build the client protocol (it will be a
|
# now, tell the client protocol factory to build the client protocol (it will be a
|
||||||
# _WrappingProtocol, around a TLSMemoryBIOProtocol, around an
|
# _WrappingProtocol, around a TLSMemoryBIOProtocol, around an
|
||||||
|
@ -328,6 +345,88 @@ class MatrixFederationAgentTests(TestCase):
|
||||||
self.reactor.pump((0.1,))
|
self.reactor.pump((0.1,))
|
||||||
self.successResultOf(test_d)
|
self.successResultOf(test_d)
|
||||||
|
|
||||||
|
def test_get_hostname_bad_cert(self):
|
||||||
|
"""
|
||||||
|
Test the behaviour when the certificate on the server doesn't match the hostname
|
||||||
|
"""
|
||||||
|
self.mock_resolver.resolve_service.side_effect = lambda _: []
|
||||||
|
self.reactor.lookups["testserv1"] = "1.2.3.4"
|
||||||
|
|
||||||
|
test_d = self._make_get_request(b"matrix://testserv1/foo/bar")
|
||||||
|
|
||||||
|
# Nothing happened yet
|
||||||
|
self.assertNoResult(test_d)
|
||||||
|
|
||||||
|
# No SRV record lookup yet
|
||||||
|
self.mock_resolver.resolve_service.assert_not_called()
|
||||||
|
|
||||||
|
# there should be an attempt to connect on port 443 for the .well-known
|
||||||
|
clients = self.reactor.tcpClients
|
||||||
|
self.assertEqual(len(clients), 1)
|
||||||
|
(host, port, client_factory, _timeout, _bindAddress) = clients[0]
|
||||||
|
self.assertEqual(host, '1.2.3.4')
|
||||||
|
self.assertEqual(port, 443)
|
||||||
|
|
||||||
|
# fonx the connection
|
||||||
|
client_factory.clientConnectionFailed(None, Exception("nope"))
|
||||||
|
|
||||||
|
# attemptdelay on the hostnameendpoint is 0.3, so takes that long before the
|
||||||
|
# .well-known request fails.
|
||||||
|
self.reactor.pump((0.4,))
|
||||||
|
|
||||||
|
# now there should be a SRV lookup
|
||||||
|
self.mock_resolver.resolve_service.assert_called_once_with(
|
||||||
|
b"_matrix._tcp.testserv1"
|
||||||
|
)
|
||||||
|
|
||||||
|
# we should fall back to a direct connection
|
||||||
|
self.assertEqual(len(clients), 2)
|
||||||
|
(host, port, client_factory, _timeout, _bindAddress) = clients[1]
|
||||||
|
self.assertEqual(host, '1.2.3.4')
|
||||||
|
self.assertEqual(port, 8448)
|
||||||
|
|
||||||
|
# make a test server, and wire up the client
|
||||||
|
http_server = self._make_connection(client_factory, expected_sni=b'testserv1')
|
||||||
|
|
||||||
|
# there should be no requests
|
||||||
|
self.assertEqual(len(http_server.requests), 0)
|
||||||
|
|
||||||
|
# ... and the request should have failed
|
||||||
|
e = self.failureResultOf(test_d, ResponseNeverReceived)
|
||||||
|
failure_reason = e.value.reasons[0]
|
||||||
|
self.assertIsInstance(failure_reason.value, VerificationError)
|
||||||
|
|
||||||
|
def test_get_ip_address_bad_cert(self):
|
||||||
|
"""
|
||||||
|
Test the behaviour when the server name contains an explicit IP, but
|
||||||
|
the server cert doesn't cover it
|
||||||
|
"""
|
||||||
|
# there will be a getaddrinfo on the IP
|
||||||
|
self.reactor.lookups["1.2.3.5"] = "1.2.3.5"
|
||||||
|
|
||||||
|
test_d = self._make_get_request(b"matrix://1.2.3.5/foo/bar")
|
||||||
|
|
||||||
|
# Nothing happened yet
|
||||||
|
self.assertNoResult(test_d)
|
||||||
|
|
||||||
|
# Make sure treq is trying to connect
|
||||||
|
clients = self.reactor.tcpClients
|
||||||
|
self.assertEqual(len(clients), 1)
|
||||||
|
(host, port, client_factory, _timeout, _bindAddress) = clients[0]
|
||||||
|
self.assertEqual(host, '1.2.3.5')
|
||||||
|
self.assertEqual(port, 8448)
|
||||||
|
|
||||||
|
# make a test server, and wire up the client
|
||||||
|
http_server = self._make_connection(client_factory, expected_sni=None)
|
||||||
|
|
||||||
|
# there should be no requests
|
||||||
|
self.assertEqual(len(http_server.requests), 0)
|
||||||
|
|
||||||
|
# ... and the request should have failed
|
||||||
|
e = self.failureResultOf(test_d, ResponseNeverReceived)
|
||||||
|
failure_reason = e.value.reasons[0]
|
||||||
|
self.assertIsInstance(failure_reason.value, VerificationError)
|
||||||
|
|
||||||
def test_get_no_srv_no_well_known(self):
|
def test_get_no_srv_no_well_known(self):
|
||||||
"""
|
"""
|
||||||
Test the behaviour when the server name has no port, no SRV, and no well-known
|
Test the behaviour when the server name has no port, no SRV, and no well-known
|
||||||
|
@ -585,6 +684,49 @@ class MatrixFederationAgentTests(TestCase):
|
||||||
self.reactor.pump((0.1,))
|
self.reactor.pump((0.1,))
|
||||||
self.successResultOf(test_d)
|
self.successResultOf(test_d)
|
||||||
|
|
||||||
|
def test_get_well_known_unsigned_cert(self):
|
||||||
|
"""Test the behaviour when the .well-known server presents a cert
|
||||||
|
not signed by a CA
|
||||||
|
"""
|
||||||
|
|
||||||
|
# we use the same test server as the other tests, but use an agent
|
||||||
|
# with _well_known_tls_policy left to the default, which will not
|
||||||
|
# trust it (since the presented cert is signed by a test CA)
|
||||||
|
|
||||||
|
self.mock_resolver.resolve_service.side_effect = lambda _: []
|
||||||
|
self.reactor.lookups["testserv"] = "1.2.3.4"
|
||||||
|
|
||||||
|
agent = MatrixFederationAgent(
|
||||||
|
reactor=self.reactor,
|
||||||
|
tls_client_options_factory=ClientTLSOptionsFactory(self._config),
|
||||||
|
_srv_resolver=self.mock_resolver,
|
||||||
|
_well_known_cache=self.well_known_cache,
|
||||||
|
)
|
||||||
|
|
||||||
|
test_d = agent.request(b"GET", b"matrix://testserv/foo/bar")
|
||||||
|
|
||||||
|
# Nothing happened yet
|
||||||
|
self.assertNoResult(test_d)
|
||||||
|
|
||||||
|
# there should be an attempt to connect on port 443 for the .well-known
|
||||||
|
clients = self.reactor.tcpClients
|
||||||
|
self.assertEqual(len(clients), 1)
|
||||||
|
(host, port, client_factory, _timeout, _bindAddress) = clients[0]
|
||||||
|
self.assertEqual(host, '1.2.3.4')
|
||||||
|
self.assertEqual(port, 443)
|
||||||
|
|
||||||
|
http_proto = self._make_connection(
|
||||||
|
client_factory, expected_sni=b"testserv",
|
||||||
|
)
|
||||||
|
|
||||||
|
# there should be no requests
|
||||||
|
self.assertEqual(len(http_proto.requests), 0)
|
||||||
|
|
||||||
|
# and there should be a SRV lookup instead
|
||||||
|
self.mock_resolver.resolve_service.assert_called_once_with(
|
||||||
|
b"_matrix._tcp.testserv"
|
||||||
|
)
|
||||||
|
|
||||||
def test_get_hostname_srv(self):
|
def test_get_hostname_srv(self):
|
||||||
"""
|
"""
|
||||||
Test the behaviour when there is a single SRV record
|
Test the behaviour when there is a single SRV record
|
||||||
|
@ -918,11 +1060,17 @@ def _check_logcontext(context):
|
||||||
raise AssertionError("Expected logcontext %s but was %s" % (context, current))
|
raise AssertionError("Expected logcontext %s but was %s" % (context, current))
|
||||||
|
|
||||||
|
|
||||||
def _build_test_server():
|
def _build_test_server(connection_creator):
|
||||||
"""Construct a test server
|
"""Construct a test server
|
||||||
|
|
||||||
This builds an HTTP channel, wrapped with a TLSMemoryBIOProtocol
|
This builds an HTTP channel, wrapped with a TLSMemoryBIOProtocol
|
||||||
|
|
||||||
|
Args:
|
||||||
|
connection_creator (IOpenSSLServerConnectionCreator): thing to build
|
||||||
|
SSL connections
|
||||||
|
sanlist (list[bytes]): list of the SAN entries for the cert returned
|
||||||
|
by the server
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
TLSMemoryBIOProtocol
|
TLSMemoryBIOProtocol
|
||||||
"""
|
"""
|
||||||
|
@ -931,7 +1079,7 @@ def _build_test_server():
|
||||||
server_factory.log = _log_request
|
server_factory.log = _log_request
|
||||||
|
|
||||||
server_tls_factory = TLSMemoryBIOFactory(
|
server_tls_factory = TLSMemoryBIOFactory(
|
||||||
ServerTLSContext(), isClient=False, wrappedFactory=server_factory
|
connection_creator, isClient=False, wrappedFactory=server_factory
|
||||||
)
|
)
|
||||||
|
|
||||||
return server_tls_factory.buildProtocol(None)
|
return server_tls_factory.buildProtocol(None)
|
||||||
|
@ -944,7 +1092,8 @@ def _log_request(request):
|
||||||
|
|
||||||
@implementer(IPolicyForHTTPS)
|
@implementer(IPolicyForHTTPS)
|
||||||
class TrustingTLSPolicyForHTTPS(object):
|
class TrustingTLSPolicyForHTTPS(object):
|
||||||
"""An IPolicyForHTTPS which doesn't do any certificate verification"""
|
"""An IPolicyForHTTPS which checks that the certificate belongs to the
|
||||||
|
right server, but doesn't check the certificate chain."""
|
||||||
|
|
||||||
def creatorForNetloc(self, hostname, port):
|
def creatorForNetloc(self, hostname, port):
|
||||||
certificateOptions = OpenSSLCertificateOptions()
|
certificateOptions = OpenSSLCertificateOptions()
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpAIBAAKCAQEAvUAWLOE6TEp3FYSfEnJMwYtJg3KIW5BjiAOOvFVOVQfJ5eEa
|
||||||
|
vzyJ1Z+8DUgLznFnUkAeD9GjPvP7awl3NPJKLQSMkV5Tp+ea4YyV+Aa4R7flROEa
|
||||||
|
zCGvmleydZw0VqN1atVZ0ikEoglM/APJQd70ec7KSR3QoxaV2/VNCHmyAPdP+0WI
|
||||||
|
llV54VXX1CZrWSHaCSn1gzo3WjnGbxTOCQE5Z4k5hqJAwLWWhxDv+FX/jD38Sq3H
|
||||||
|
gMFNpXJv6FYwwaKU8awghHdSY/qlBPE/1rU83vIBFJ3jW6I1WnQDfCQ69of5vshK
|
||||||
|
N4v4hok56ScwdUnk8lw6xvJx1Uav/XQB9qGh4QIDAQABAoIBAQCHLO5p8hotAgdb
|
||||||
|
JFZm26N9nxrMPBOvq0ucjEX4ucnwrFaGzynGrNwa7TRqHCrqs0/EjS2ryOacgbL0
|
||||||
|
eldeRy26SASLlN+WD7UuI7e+6DXabDzj3RHB+tGuIbPDk+ZCeBDXVTsKBOhdQN1v
|
||||||
|
KNkpJrJjCtSsMxKiWvCBow353srJKqCDZcF5NIBYBeDBPMoMbfYn5dJ9JhEf+2h4
|
||||||
|
0iwpnWDX1Vqf46pCRa0hwEyMXycGeV2CnfJSyV7z52ZHQrvkz8QspSnPpnlCnbOE
|
||||||
|
UAvc8kZ5e8oZE7W+JfkK38vHbEGM1FCrBmrC/46uUGMRpZfDferGs91RwQVq/F0n
|
||||||
|
JN9hLzsBAoGBAPh2pm9Xt7a4fWSkX0cDgjI7PT2BvLUjbRwKLV+459uDa7+qRoGE
|
||||||
|
sSwb2QBqmQ1kbr9JyTS+Ld8dyUTsGHZK+YbTieAxI3FBdKsuFtcYJO/REN0vik+6
|
||||||
|
fMaBHPvDHSU2ioq7spZ4JBFskzqs38FvZ0lX7aa3fguMk8GMLnofQ8QxAoGBAML9
|
||||||
|
o5sJLN9Tk9bv2aFgnERgfRfNjjV4Wd99TsktnCD04D1GrP2eDSLfpwFlCnguck6b
|
||||||
|
jxikqcolsNhZH4dgYHqRNj+IljSdl+sYZiygO6Ld0XU+dEFO86N3E9NzZhKcQ1at
|
||||||
|
85VdwNPCS7JM2fIxEvS9xfbVnsmK6/37ZZ5iI7yxAoGBALw2vRtJGmy60pojfd1A
|
||||||
|
hibhAyINnlKlFGkSOI7zdgeuRTf6l9BTIRclvTt4hJpFgzM6hMWEbyE94hJoupsZ
|
||||||
|
bm443o/LCWsox2VI05p6urhD6f9znNWKkiyY78izY+elqksvpjgfqEresaTYAeP5
|
||||||
|
LQe9KNSK2VuMUP1j4G04M9BxAoGAWe8ITZJuytZOgrz/YIohqPvj1l2tcIYA1a6C
|
||||||
|
7xEFSMIIxtpZIWSLZIFJEsCakpHBkPX4iwIveZfmt/JrM1JFTWK6ZZVGyh/BmOIZ
|
||||||
|
Bg4lU1oBqJTUo+aZQtTCJS29b2n5OPpkNYkXTdP4e9UsVKNDvfPlYZJneUeEzxDr
|
||||||
|
bqCPIRECgYA544KMwrWxDQZg1dsKWgdVVKx80wEFZAiQr9+0KF6ch6Iu7lwGJHFY
|
||||||
|
iI6O85paX41qeC/Fo+feIWJVJU2GvG6eBsbO4bmq+KSg4NkABJSYxodgBp9ftNeD
|
||||||
|
jo1tfw+gudlNe5jXHu7oSX93tqGjR4Cnlgan/KtfkB96yHOumGmOhQ==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -1,81 +0,0 @@
|
||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
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
|
|
||||||
KILVFsq3cQC+bEnoM4eVbjEQkGs1RQ==
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
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
|
|
||||||
-----END CERTIFICATE-----
|
|
Loading…
Reference in New Issue