mirror of
https://github.com/element-hq/synapse.git
synced 2024-12-14 11:57:44 +00:00
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
6 changed files with 343 additions and 106 deletions
|
@ -13,28 +13,124 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import os.path
|
||||
import subprocess
|
||||
|
||||
from zope.interface import implementer
|
||||
|
||||
from OpenSSL import SSL
|
||||
from OpenSSL.SSL import Connection
|
||||
from twisted.internet.interfaces import IOpenSSLServerConnectionCreator
|
||||
|
||||
|
||||
def get_test_cert_file():
|
||||
"""get the path to the test cert"""
|
||||
def get_test_ca_cert_file():
|
||||
"""Get the path to the test CA cert
|
||||
|
||||
# the cert file itself is made with:
|
||||
#
|
||||
# openssl req -x509 -newkey rsa:4096 -keyout server.pem -out server.pem -days 36500 \
|
||||
# -nodes -subj '/CN=testserv'
|
||||
return os.path.join(os.path.dirname(__file__), 'server.pem')
|
||||
The keypair is generated with:
|
||||
|
||||
openssl genrsa -out ca.key 2048
|
||||
openssl req -new -x509 -key ca.key -days 3650 -out ca.crt \
|
||||
-subj '/CN=synapse test CA'
|
||||
"""
|
||||
return os.path.join(os.path.dirname(__file__), "ca.crt")
|
||||
|
||||
|
||||
class ServerTLSContext(object):
|
||||
"""A TLS Context which presents our test cert."""
|
||||
def get_test_key_file():
|
||||
"""get the path to the test key
|
||||
|
||||
def __init__(self):
|
||||
self.filename = get_test_cert_file()
|
||||
The key file is made with:
|
||||
|
||||
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.use_certificate_file(self.filename)
|
||||
ctx.use_privatekey_file(self.filename)
|
||||
return ctx
|
||||
ctx.use_certificate_file(self._cert_file)
|
||||
ctx.use_privatekey_file(get_test_key_file())
|
||||
return Connection(ctx, None)
|
||||
|
|
19
tests/http/ca.crt
Normal file
19
tests/http/ca.crt
Normal file
|
@ -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-----
|
27
tests/http/ca.key
Normal file
27
tests/http/ca.key
Normal file
|
@ -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
|
||||
|
||||
import treq
|
||||
from service_identity import VerificationError
|
||||
from zope.interface import implementer
|
||||
|
||||
from twisted.internet import defer
|
||||
from twisted.internet._sslverify import ClientTLSOptions, OpenSSLCertificateOptions
|
||||
from twisted.internet.protocol import Factory
|
||||
from twisted.protocols.tls import TLSMemoryBIOFactory
|
||||
from twisted.web._newclient import ResponseNeverReceived
|
||||
from twisted.web.http import HTTPChannel
|
||||
from twisted.web.http_headers import Headers
|
||||
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.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.unittest import TestCase
|
||||
from tests.utils import default_config
|
||||
|
||||
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):
|
||||
def setUp(self):
|
||||
|
@ -53,12 +71,11 @@ class MatrixFederationAgentTests(TestCase):
|
|||
|
||||
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["federation_verify_certificates"] = False
|
||||
config_dict["trusted_key_servers"] = []
|
||||
config = HomeServerConfig()
|
||||
config_dict["federation_custom_ca_list"] = [get_test_ca_cert_file()]
|
||||
# config_dict["trusted_key_servers"] = []
|
||||
|
||||
self._config = config = HomeServerConfig()
|
||||
config.parse_config_dict(config_dict)
|
||||
|
||||
self.agent = MatrixFederationAgent(
|
||||
|
@ -77,7 +94,7 @@ class MatrixFederationAgentTests(TestCase):
|
|||
"""
|
||||
|
||||
# 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
|
||||
# _WrappingProtocol, around a TLSMemoryBIOProtocol, around an
|
||||
|
@ -328,6 +345,88 @@ class MatrixFederationAgentTests(TestCase):
|
|||
self.reactor.pump((0.1,))
|
||||
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):
|
||||
"""
|
||||
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.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):
|
||||
"""
|
||||
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))
|
||||
|
||||
|
||||
def _build_test_server():
|
||||
def _build_test_server(connection_creator):
|
||||
"""Construct a test server
|
||||
|
||||
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:
|
||||
TLSMemoryBIOProtocol
|
||||
"""
|
||||
|
@ -931,7 +1079,7 @@ def _build_test_server():
|
|||
server_factory.log = _log_request
|
||||
|
||||
server_tls_factory = TLSMemoryBIOFactory(
|
||||
ServerTLSContext(), isClient=False, wrappedFactory=server_factory
|
||||
connection_creator, isClient=False, wrappedFactory=server_factory
|
||||
)
|
||||
|
||||
return server_tls_factory.buildProtocol(None)
|
||||
|
@ -944,7 +1092,8 @@ def _log_request(request):
|
|||
|
||||
@implementer(IPolicyForHTTPS)
|
||||
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):
|
||||
certificateOptions = OpenSSLCertificateOptions()
|
||||
|
|
27
tests/http/server.key
Normal file
27
tests/http/server.key
Normal file
|
@ -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-----
|
||||
MIIE/jCCAuagAwIBAgIJANFtVaGvJWZlMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNV
|
||||
BAMMCHRlc3RzZXJ2MCAXDTE5MDEyNzIyMDIzNloYDzIxMTkwMTAzMjIwMjM2WjAT
|
||||
MREwDwYDVQQDDAh0ZXN0c2VydjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
|
||||
ggIBAKAXjf/eUCAn6nTHtGfxRwvxrh9y292SKS9msKeDD3ouQHfgS9+rxgZaU5WN
|
||||
T5/2dpQksAoxq2YB8Q2v6sxfhU5ealPC67qIu2rCt5StEUwRLKua9DFrXmn7LzmC
|
||||
RjQIWZcxuW/o5FvEdMadwEbBJPhYrg+h7ByC3qNwhIUIRJNQq7XNzdzDUA0gNHIM
|
||||
sHkrjgrAh7fp1wpyTI0p22/gEn7d9whkiQ8kfrbOoLKmAUXWiIW3jS4nMKXGAd0l
|
||||
mUpimCR+cNNyTDhj8zH2TwFsTfXQoDNQ0xX0fsjV4SiXOs2vroVCPV43rhf92o7y
|
||||
VNvAKoB3h2IJPiwhSTTRJWwBSM13eDyPrnWHH5BvW3x+46OufLx2Z4zG1SAgEehB
|
||||
ylyPvpHnkWzspn25qvTw4VPIYjN7nVbWMbYr/v/kzXPEiqsD7uWxe7k5HzWzsj42
|
||||
D9RQCGIcD/P7jb9qI1qoS6Tq2qPesd8ty2cJu1n4mtE2pJLASLwXSUwDTbWK8R3Z
|
||||
4lX7bzg7ImOFc6YoetdAAMeuZLtKHizJNm9E2b2f6pYgPQp0OvZKOL8qdLcSenjg
|
||||
cNDjGuJPr/GHAQazK5egfloCR0vOe6VtaQcFvLHVJRBJMuk6rNqKgX2bW9GsuwW+
|
||||
uStjcPbneY8nl5T0cz92KV24VxSCPivP7px1dQCH4or+/3nPAgMBAAGjUzBRMB0G
|
||||
A1UdDgQWBBQcQZpzLzTk5KdS/Iz7sGCV7gTd/zAfBgNVHSMEGDAWgBQcQZpzLzTk
|
||||
5KdS/Iz7sGCV7gTd/zAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IC
|
||||
AQAr/Pgha57jqYsDDX1LyRrVdqoVBpLBeB7x/p9dKYm7S6tBTDFNMZ0SZyQP8VEG
|
||||
7UoC9/OQ9nCdEMoR7ZKpQsmipwcIqpXHS6l4YOkf5EEq5jpMgvlEesHmBJJeJew/
|
||||
FEPDl1bl8d0tSrmWaL3qepmwzA+2lwAAouWk2n+rLiP8CZ3jZeoTXFqYYrUlEqO9
|
||||
fHMvuWqTV4KCSyNY+GWCrnHetulgKHlg+W2J1mZnrCKcBhWf9C2DesTJO+JldIeM
|
||||
ornTFquSt21hZi+k3aySuMn2N3MWiNL8XsZVsAnPSs0zA+2fxjJkShls8Gc7cCvd
|
||||
a6XrNC+PY6pONguo7rEU4HiwbvnawSTngFFglmH/ImdA/HkaAekW6o82aI8/UxFx
|
||||
V9fFMO3iKDQdOrg77hI1bx9RlzKNZZinE2/Pu26fWd5d2zqDWCjl8ykGQRAfXgYN
|
||||
H3BjgyXLl+ao5/pOUYYtzm3ruTXTgRcy5hhL6hVTYhSrf9vYh4LNIeXNKnZ78tyG
|
||||
TX77/kU2qXhBGCFEUUMqUNV/+ITir2lmoxVjknt19M07aGr8C7SgYt6Rs+qDpMiy
|
||||
JurgvRh8LpVq4pHx1efxzxCFmo58DMrG40I0+CF3y/niNpOb1gp2wAqByRiORkds
|
||||
f0ytW6qZ0TpHbD6gOtQLYDnhx3ISuX+QYSekVwQUpffeWQ==
|
||||
-----END CERTIFICATE-----
|
Loading…
Reference in a new issue