diff options
author | Haibo Huang <hhb@google.com> | 2020-01-07 14:06:17 -0800 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2020-01-07 14:06:17 -0800 |
commit | 075127a8369bc1c63816bf19c9cfadbd0e8ea894 (patch) | |
tree | 16c7c1622f6e5897972a8abb75e049de64b09c0d | |
parent | 715174bb0a0268957c65576005b56ed59b1a630c (diff) | |
parent | cd49a07c9cd64170e3758a3240902c5bb5bfac5e (diff) | |
download | platform_external_python_httplib2-075127a8369bc1c63816bf19c9cfadbd0e8ea894.tar.gz platform_external_python_httplib2-075127a8369bc1c63816bf19c9cfadbd0e8ea894.tar.bz2 platform_external_python_httplib2-075127a8369bc1c63816bf19c9cfadbd0e8ea894.zip |
Upgrade python/httplib2 to v0.15.0
am: cd49a07c9c
Change-Id: Ia6a048a662f9820c04a8a1af9db9e35c154de534
-rw-r--r-- | CHANGELOG | 11 | ||||
-rw-r--r-- | METADATA | 6 | ||||
-rw-r--r-- | python2/httplib2/__init__.py | 80 | ||||
-rw-r--r-- | python3/httplib2/__init__.py | 35 | ||||
-rwxr-xr-x | script/generate-tls | 61 | ||||
-rwxr-xr-x | setup.py | 2 | ||||
-rw-r--r-- | tests/__init__.py | 79 | ||||
-rw-r--r-- | tests/test_external.py | 129 | ||||
-rw-r--r-- | tests/test_http.py | 49 | ||||
-rw-r--r-- | tests/test_https.py | 203 | ||||
-rw-r--r-- | tests/test_other.py | 21 | ||||
-rw-r--r-- | tests/tls/ca.key | 27 | ||||
-rw-r--r-- | tests/tls/ca.pem | 20 | ||||
-rw-r--r-- | tests/tls/ca.srl | 1 | ||||
-rw-r--r-- | tests/tls/ca_unused.pem | 20 | ||||
-rw-r--r-- | tests/tls/client.crt | 20 | ||||
-rw-r--r-- | tests/tls/client.key | 27 | ||||
-rw-r--r-- | tests/tls/client.pem | 47 | ||||
-rw-r--r-- | tests/tls/client_chain.pem | 67 | ||||
-rw-r--r-- | tests/tls/client_encrypted.crt | 20 | ||||
-rw-r--r-- | tests/tls/client_encrypted.key | 30 | ||||
-rw-r--r-- | tests/tls/client_encrypted.pem | 50 | ||||
-rw-r--r-- | tests/tls/server.crt | 20 | ||||
-rw-r--r-- | tests/tls/server.key | 27 | ||||
-rw-r--r-- | tests/tls/server.pem | 47 | ||||
-rw-r--r-- | tests/tls/server_chain.pem | 67 |
26 files changed, 955 insertions, 211 deletions
@@ -1,3 +1,14 @@ +0.15.0 + + python2: regression in connect() error handling + https://github.com/httplib2/httplib2/pull/150 + + add support for password protected certificate files + https://github.com/httplib2/httplib2/pull/143 + + feature: Http.close() to clean persistent connections and sensitive data + https://github.com/httplib2/httplib2/pull/149 + 0.14.0 Python3: PROXY_TYPE_SOCKS5 with str user/pass raised TypeError @@ -9,10 +9,10 @@ third_party { type: GIT value: "https://github.com/httplib2/httplib2.git" } - version: "v0.14.0" + version: "v0.15.0" last_upgrade_date { year: 2019 - month: 9 - day: 26 + month: 12 + day: 23 } } diff --git a/python2/httplib2/__init__.py b/python2/httplib2/__init__.py index 98228e3..c8302eb 100644 --- a/python2/httplib2/__init__.py +++ b/python2/httplib2/__init__.py @@ -19,7 +19,7 @@ __contributors__ = [ "Alex Yu", ] __license__ = "MIT" -__version__ = '0.14.0' +__version__ = '0.15.0' import base64 import calendar @@ -76,7 +76,7 @@ if ssl is not None: def _ssl_wrap_socket( - sock, key_file, cert_file, disable_validation, ca_certs, ssl_version, hostname + sock, key_file, cert_file, disable_validation, ca_certs, ssl_version, hostname, key_password ): if disable_validation: cert_reqs = ssl.CERT_NONE @@ -90,11 +90,16 @@ def _ssl_wrap_socket( context.verify_mode = cert_reqs context.check_hostname = cert_reqs != ssl.CERT_NONE if cert_file: - context.load_cert_chain(cert_file, key_file) + if key_password: + context.load_cert_chain(cert_file, key_file, key_password) + else: + context.load_cert_chain(cert_file, key_file) if ca_certs: context.load_verify_locations(ca_certs) return context.wrap_socket(sock, server_hostname=hostname) else: + if key_password: + raise NotSupportedOnThisPlatform("Certificate with password is not supported.") return ssl.wrap_socket( sock, keyfile=key_file, @@ -106,7 +111,7 @@ def _ssl_wrap_socket( def _ssl_wrap_socket_unsupported( - sock, key_file, cert_file, disable_validation, ca_certs, ssl_version, hostname + sock, key_file, cert_file, disable_validation, ca_certs, ssl_version, hostname, key_password ): if not disable_validation: raise CertificateValidationUnsupported( @@ -114,6 +119,8 @@ def _ssl_wrap_socket_unsupported( "the ssl module installed. To avoid this error, install " "the ssl module, or explicity disable validation." ) + if key_password: + raise NotSupportedOnThisPlatform("Certificate with password is not supported.") ssl_sock = socket.ssl(sock, key_file, cert_file) return httplib.FakeSocket(sock, ssl_sock) @@ -978,8 +985,13 @@ class Credentials(object): class KeyCerts(Credentials): """Identical to Credentials except that name/password are mapped to key/cert.""" + def add(self, key, cert, domain, password): + self.credentials.append((domain.lower(), key, cert, password)) - pass + def iter(self, domain): + for (cdomain, key, cert, password) in self.credentials: + if cdomain == "" or domain == cdomain: + yield (key, cert, password) class AllHosts(object): @@ -1150,7 +1162,6 @@ class HTTPConnectionWithTimeout(httplib.HTTPConnection): raise ProxiesUnavailableError( "Proxy support missing but proxy use was requested!" ) - msg = "getaddrinfo returns an empty list" if self.proxy_info and self.proxy_info.isgood(): use_proxy = True proxy_type, proxy_host, proxy_port, proxy_rdns, proxy_user, proxy_pass, proxy_headers = ( @@ -1164,7 +1175,9 @@ class HTTPConnectionWithTimeout(httplib.HTTPConnection): host = self.host port = self.port - + + socket_err = None + for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res try: @@ -1206,7 +1219,8 @@ class HTTPConnectionWithTimeout(httplib.HTTPConnection): self.sock.connect((self.host, self.port) + sa[2:]) else: self.sock.connect(sa) - except socket.error as msg: + except socket.error as e: + socket_err = e if self.debuglevel > 0: print("connect fail: (%s, %s)" % (self.host, self.port)) if use_proxy: @@ -1229,7 +1243,7 @@ class HTTPConnectionWithTimeout(httplib.HTTPConnection): continue break if not self.sock: - raise socket.error(msg) + raise socket_err or socket.error("getaddrinfo returns an empty list") class HTTPSConnectionWithTimeout(httplib.HTTPSConnection): @@ -1253,10 +1267,19 @@ class HTTPSConnectionWithTimeout(httplib.HTTPSConnection): ca_certs=None, disable_ssl_certificate_validation=False, ssl_version=None, + key_password=None, ): - httplib.HTTPSConnection.__init__( - self, host, port=port, key_file=key_file, cert_file=cert_file, strict=strict - ) + if key_password: + httplib.HTTPSConnection.__init__(self, host, port=port, strict=strict) + self._context.load_cert_chain(cert_file, key_file, key_password) + self.key_file = key_file + self.cert_file = cert_file + self.key_password = key_password + else: + httplib.HTTPSConnection.__init__( + self, host, port=port, key_file=key_file, cert_file=cert_file, strict=strict + ) + self.key_password = None self.timeout = timeout self.proxy_info = proxy_info if ca_certs is None: @@ -1317,7 +1340,6 @@ class HTTPSConnectionWithTimeout(httplib.HTTPSConnection): def connect(self): "Connect to a host on a given (SSL) port." - msg = "getaddrinfo returns an empty list" if self.proxy_info and self.proxy_info.isgood(): use_proxy = True proxy_type, proxy_host, proxy_port, proxy_rdns, proxy_user, proxy_pass, proxy_headers = ( @@ -1331,7 +1353,9 @@ class HTTPSConnectionWithTimeout(httplib.HTTPSConnection): host = self.host port = self.port - + + socket_err = None + address_info = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM) for family, socktype, proto, canonname, sockaddr in address_info: try: @@ -1366,6 +1390,7 @@ class HTTPSConnectionWithTimeout(httplib.HTTPSConnection): self.ca_certs, self.ssl_version, self.host, + self.key_password, ) if self.debuglevel > 0: print("connect: (%s, %s)" % (self.host, self.port)) @@ -1413,7 +1438,8 @@ class HTTPSConnectionWithTimeout(httplib.HTTPSConnection): raise except (socket.timeout, socket.gaierror): raise - except socket.error as msg: + except socket.error as e: + socket_err = e if self.debuglevel > 0: print("connect fail: (%s, %s)" % (self.host, self.port)) if use_proxy: @@ -1436,7 +1462,7 @@ class HTTPSConnectionWithTimeout(httplib.HTTPSConnection): continue break if not self.sock: - raise socket.error(msg) + raise socket_err or socket.error("getaddrinfo returns an empty list") SCHEME_TO_CONNECTION = { @@ -1515,7 +1541,10 @@ class AppEngineHttpsConnection(httplib.HTTPSConnection): ca_certs=None, disable_ssl_certificate_validation=False, ssl_version=None, + key_password=None, ): + if key_password: + raise NotSupportedOnThisPlatform("Certificate with password is not supported.") httplib.HTTPSConnection.__init__( self, host, @@ -1649,6 +1678,16 @@ class Http(object): # Keep Authorization: headers on a redirect. self.forward_authorization_headers = False + def close(self): + """Close persistent connections, clear sensitive data. + Not thread-safe, requires external synchronization against concurrent requests. + """ + existing, self.connections = self.connections, {} + for _, c in existing.iteritems(): + c.close() + self.certificates.clear() + self.clear_credentials() + def __getstate__(self): state_dict = copy.copy(self.__dict__) # In case request is augmented by some foreign object such as @@ -1680,10 +1719,10 @@ class Http(object): any time a request requires authentication.""" self.credentials.add(name, password, domain) - def add_certificate(self, key, cert, domain): + def add_certificate(self, key, cert, domain, password=None): """Add a key and cert that will be used any time a request requires authentication.""" - self.certificates.add(key, cert, domain) + self.certificates.add(key, cert, domain, password) def clear_credentials(self): """Remove all the names and passwords @@ -1925,7 +1964,7 @@ class Http(object): a string that contains the response entity body. """ conn_key = '' - + try: if headers is None: headers = {} @@ -1958,6 +1997,7 @@ class Http(object): ca_certs=self.ca_certs, disable_ssl_certificate_validation=self.disable_ssl_certificate_validation, ssl_version=self.ssl_version, + key_password=certs[0][2], ) else: conn = self.connections[conn_key] = connection_type( @@ -2140,7 +2180,7 @@ class Http(object): conn = self.connections.pop(conn_key, None) if conn: conn.close() - + if self.force_exception_to_status_code: if isinstance(e, HttpLib2ErrorWithResponse): response = e.response diff --git a/python3/httplib2/__init__.py b/python3/httplib2/__init__.py index 4312f30..d8c3d34 100644 --- a/python3/httplib2/__init__.py +++ b/python3/httplib2/__init__.py @@ -15,7 +15,7 @@ __contributors__ = [ "Alex Yu", ] __license__ = "MIT" -__version__ = '0.14.0' +__version__ = '0.15.0' import base64 import calendar @@ -175,7 +175,7 @@ DEFAULT_TLS_VERSION = getattr(ssl, "PROTOCOL_TLS", None) or getattr( def _build_ssl_context( disable_ssl_certificate_validation, ca_certs, cert_file=None, key_file=None, - maximum_version=None, minimum_version=None, + maximum_version=None, minimum_version=None, key_password=None, ): if not hasattr(ssl, "SSLContext"): raise RuntimeError("httplib2 requires Python 3.2+ for ssl.SSLContext") @@ -207,7 +207,7 @@ def _build_ssl_context( context.load_verify_locations(ca_certs) if cert_file: - context.load_cert_chain(cert_file, key_file) + context.load_cert_chain(cert_file, key_file, key_password) return context @@ -959,8 +959,13 @@ class Credentials(object): class KeyCerts(Credentials): """Identical to Credentials except that name/password are mapped to key/cert.""" + def add(self, key, cert, domain, password): + self.credentials.append((domain.lower(), key, cert, password)) - pass + def iter(self, domain): + for (cdomain, key, cert, password) in self.credentials: + if cdomain == "" or domain == cdomain: + yield (key, cert, password) class AllHosts(object): @@ -1245,6 +1250,7 @@ class HTTPSConnectionWithTimeout(http.client.HTTPSConnection): disable_ssl_certificate_validation=False, tls_maximum_version=None, tls_minimum_version=None, + key_password=None, ): self.disable_ssl_certificate_validation = disable_ssl_certificate_validation @@ -1257,15 +1263,17 @@ class HTTPSConnectionWithTimeout(http.client.HTTPSConnection): context = _build_ssl_context( self.disable_ssl_certificate_validation, self.ca_certs, cert_file, key_file, maximum_version=tls_maximum_version, minimum_version=tls_minimum_version, + key_password=key_password, ) super(HTTPSConnectionWithTimeout, self).__init__( host, port=port, - key_file=key_file, - cert_file=cert_file, timeout=timeout, context=context, ) + self.key_file = key_file + self.cert_file = cert_file + self.key_password = key_password def connect(self): """Connect to a host on a given (SSL) port.""" @@ -1476,6 +1484,16 @@ class Http(object): # Keep Authorization: headers on a redirect. self.forward_authorization_headers = False + def close(self): + """Close persistent connections, clear sensitive data. + Not thread-safe, requires external synchronization against concurrent requests. + """ + existing, self.connections = self.connections, {} + for _, c in existing.items(): + c.close() + self.certificates.clear() + self.clear_credentials() + def __getstate__(self): state_dict = copy.copy(self.__dict__) # In case request is augmented by some foreign object such as @@ -1507,10 +1525,10 @@ class Http(object): any time a request requires authentication.""" self.credentials.add(name, password, domain) - def add_certificate(self, key, cert, domain): + def add_certificate(self, key, cert, domain, password=None): """Add a key and cert that will be used any time a request requires authentication.""" - self.certificates.add(key, cert, domain) + self.certificates.add(key, cert, domain, password) def clear_credentials(self): """Remove all the names and passwords @@ -1782,6 +1800,7 @@ a string that contains the response entity body. disable_ssl_certificate_validation=self.disable_ssl_certificate_validation, tls_maximum_version=self.tls_maximum_version, tls_minimum_version=self.tls_minimum_version, + key_password=certs[0][2], ) else: conn = self.connections[conn_key] = connection_type( diff --git a/script/generate-tls b/script/generate-tls new file mode 100755 index 0000000..8c96f1e --- /dev/null +++ b/script/generate-tls @@ -0,0 +1,61 @@ +#!/bin/bash +set -eu + +target_dir="${1:-.}" +days=3650 +rsa_bits=2048 +org="httplib2-test" +server_cn="localhost" +subj_prefix="/C=ZZ/ST=./L=./O=$org/OU=." + +main() { + cd "$target_dir" + gen + check +} + +check() { + echo "- check keys" >&2 + openssl rsa -in ca.key -check -noout + openssl rsa -in client.key -check -noout + openssl rsa -in client_encrypted.key -check -noout -passin pass:12345 + openssl rsa -in server.key -check -noout + + echo "- check certs" >&2 + for f in *.pem ; do + openssl x509 -in "$f" -checkend 3600 -noout + done +} + +gen() { + echo "- generate keys, if absent" >&2 + [[ -f ca.key ]] || openssl genrsa -out ca.key $rsa_bits + [[ -f client.key ]] || openssl genrsa -out client.key $rsa_bits + [[ -f client_encrypted.key ]] || openssl rsa -in client.key -out client_encrypted.key -aes128 -passout pass:12345 + [[ -f server.key ]] || openssl genrsa -out server.key $rsa_bits + + echo "- generate CA" >&2 + openssl req -batch -new -nodes -x509 -days $days -subj "$subj_prefix/CN=$org-CA" -key ca.key -out ca.pem + openssl req -batch -new -nodes -x509 -days $days -subj "$subj_prefix/CN=$org-CA-unused" -key ca.key -out ca_unused.pem + + echo "- generate client cert" >&2 + openssl req -batch -new -nodes -out tmp.csr -key client.key -subj "$subj_prefix/CN=$org-client" + openssl x509 -req -in tmp.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out client.crt -days $days -serial -fingerprint + cat client.crt client.key >client.pem + cat client.crt ca.pem client.key >client_chain.pem + + echo "- generate encrypted client cert" >&2 + openssl req -batch -new -nodes -out tmp.csr -key client_encrypted.key -passin pass:12345 -subj "$subj_prefix/CN=$org-client-enc" + openssl x509 -req -in tmp.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out client_encrypted.crt -days $days -serial -fingerprint + cat client_encrypted.crt client_encrypted.key >client_encrypted.pem + + echo "- generate server cert" >&2 + openssl req -batch -new -nodes -out tmp.csr -key server.key -subj "$subj_prefix/CN=$server_cn" + openssl x509 -req -in tmp.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out server.crt -days $days -serial -fingerprint + cat server.crt server.key >server.pem + cat server.crt ca.pem server.key >server_chain.pem + + rm tmp.csr +} + +main @@ -4,7 +4,7 @@ import setuptools.command.test import sys pkgdir = {"": "python%s" % sys.version_info[0]} -VERSION = '0.14.0' +VERSION = '0.15.0' # `python setup.py test` uses existing Python environment, no virtualenv, no pip. diff --git a/tests/__init__.py b/tests/__init__.py index 28959d3..496652b 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -14,6 +14,7 @@ import re import shutil import six import socket +import ssl import struct import sys import threading @@ -23,6 +24,18 @@ import zlib from six.moves import http_client, queue +DUMMY_URL = "http://127.0.0.1:1" +DUMMY_HTTPS_URL = "https://127.0.0.1:2" + +tls_dir = os.path.join(os.path.dirname(__file__), "tls") +CA_CERTS = os.path.join(tls_dir, "ca.pem") +CA_UNUSED_CERTS = os.path.join(tls_dir, "ca_unused.pem") +CLIENT_PEM = os.path.join(tls_dir, "client.pem") +CLIENT_ENCRYPTED_PEM = os.path.join(tls_dir, "client_encrypted.pem") +SERVER_PEM = os.path.join(tls_dir, "server.pem") +SERVER_CHAIN = os.path.join(tls_dir, "server_chain.pem") + + @contextlib.contextmanager def assert_raises(exc_type): def _name(t): @@ -261,9 +274,29 @@ class MockHTTPBadStatusConnection(object): @contextlib.contextmanager -def server_socket(fun, request_count=1, timeout=5): +def server_socket(fun, request_count=1, timeout=5, scheme="", tls=None): + """Base socket server for tests. + Likely you want to use server_request or other higher level helpers. + All arguments except fun can be passed to other server_* helpers. + + :param fun: fun(client_sock, tick) called after successful accept(). + :param request_count: test succeeds after exactly this number of requests, triggered by tick(request) + :param timeout: seconds. + :param scheme: affects yielded value + "" - build normal http/https URI. + string - build normal URI using supplied scheme. + None - yield (addr, port) tuple. + :param tls: + None (default) - plain HTTP. + True - HTTPS with reasonable defaults. Likely you want httplib2.Http(ca_certs=tests.CA_CERTS) + string - path to custom server cert+key PEM file. + callable - function(context, listener, skip_errors) -> ssl_wrapped_listener + """ gresult = [None] gcounter = [0] + tls_skip_errors = [ + "TLSV1_ALERT_UNKNOWN_CA", + ] def tick(request): gcounter[0] += 1 @@ -276,7 +309,13 @@ def server_socket(fun, request_count=1, timeout=5): def server_socket_thread(srv): try: while gcounter[0] < request_count: - client, _ = srv.accept() + try: + client, _ = srv.accept() + except ssl.SSLError as e: + if e.reason in tls_skip_errors: + return + raise + try: client.settimeout(timeout) fun(client, tick) @@ -299,18 +338,36 @@ def server_socket(fun, request_count=1, timeout=5): print(traceback.format_exc(), file=sys.stderr) gresult[0] = e + bind_hostname = "localhost" server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - server.bind(("localhost", 0)) + server.bind((bind_hostname, 0)) try: server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) except socket.error as ex: print("non critical error on SO_REUSEADDR", ex) server.listen(10) server.settimeout(timeout) + server_port = server.getsockname()[1] + if tls is True: + tls = SERVER_CHAIN + if tls: + context = ssl_context() + if callable(tls): + context.load_cert_chain(SERVER_CHAIN) + server = tls(context, server, tls_skip_errors) + else: + context.load_cert_chain(tls) + server = context.wrap_socket(server, server_side=True) + if scheme == "": + scheme = "https" if tls else "http" + t = threading.Thread(target=server_socket_thread, args=(server,)) t.daemon = True t.start() - yield u"http://{0}:{1}/".format(*server.getsockname()) + if scheme is None: + yield (bind_hostname, server_port) + else: + yield u"{scheme}://{host}:{port}/".format(scheme=scheme, host=bind_hostname, port=server_port) server.close() t.join() if gresult[0] is not None: @@ -329,11 +386,12 @@ def server_yield(fun, **kwargs): if request is None: break i += 1 - request.client_addr = sock.getsockname() + request.client_sock = sock request.number = i q.put(request) response = six.next(g) sock.sendall(response) + request.client_sock = None if not tick(request): break @@ -349,10 +407,11 @@ def server_request(request_handler, **kwargs): if request is None: break i += 1 - request.client_addr = sock.getsockname() + request.client_sock = sock request.number = i response = request_handler(request=request) sock.sendall(response) + request.client_sock = None if not tick(request): break @@ -685,3 +744,11 @@ def deflate_compress(bs): def deflate_decompress(bs): return zlib.decompress(bs, -zlib.MAX_WBITS) + + +def ssl_context(protocol=None): + """Workaround for old SSLContext() required protocol argument. + """ + if sys.version_info < (3, 5, 3): + return ssl.SSLContext(ssl.PROTOCOL_SSLv23) + return ssl.SSLContext() diff --git a/tests/test_external.py b/tests/test_external.py deleted file mode 100644 index 0628d96..0000000 --- a/tests/test_external.py +++ /dev/null @@ -1,129 +0,0 @@ -"""These tests rely on replies from public internet services - -TODO: reimplement with local stubs -""" -import httplib2 -import os -import pytest -import ssl -import sys -import tests - - -def test_get_301_via_https(): - # Google always redirects to http://google.com - http = httplib2.Http() - response, content = http.request("https://code.google.com/apis/", "GET") - assert response.status == 200 - assert response.previous.status == 301 - - -def test_get_via_https(): - # Test that we can handle HTTPS - http = httplib2.Http() - response, content = http.request("https://google.com/adsense/", "GET") - assert response.status == 200 - - -def test_get_via_https_spec_violation_on_location(): - # Test that we follow redirects through HTTPS - # even if they violate the spec by including - # a relative Location: header instead of an - # absolute one. - http = httplib2.Http() - response, content = http.request("https://google.com/adsense", "GET") - assert response.status == 200 - assert response.previous is not None - - -def test_get_via_https_key_cert(): - # At this point I can only test - # that the key and cert files are passed in - # correctly to httplib. It would be nice to have - # a real https endpoint to test against. - http = httplib2.Http(timeout=2) - http.add_certificate("akeyfile", "acertfile", "bitworking.org") - try: - http.request("https://bitworking.org", "GET") - except AttributeError: - assert http.connections["https:bitworking.org"].key_file == "akeyfile" - assert http.connections["https:bitworking.org"].cert_file == "acertfile" - except IOError: - # Skip on 3.2 - pass - - try: - http.request("https://notthere.bitworking.org", "GET") - except httplib2.ServerNotFoundError: - assert http.connections["https:notthere.bitworking.org"].key_file is None - assert http.connections["https:notthere.bitworking.org"].cert_file is None - except IOError: - # Skip on 3.2 - pass - - -def test_ssl_invalid_ca_certs_path(): - # Test that we get an ssl.SSLError when specifying a non-existent CA - # certs file. - http = httplib2.Http(ca_certs="/nosuchfile") - with tests.assert_raises(IOError): - http.request("https://www.google.com/", "GET") - - -@pytest.mark.xfail( - sys.version_info <= (3,), - reason=( - "FIXME: for unknown reason Python 2.7.10 validates www.google.com " - "against dummy CA www.example.com" - ), -) -def test_ssl_wrong_ca(): - # Test that we get a SSLHandshakeError if we try to access - # https://www.google.com, using a CA cert file that doesn't contain - # the CA Google uses (i.e., simulating a cert that's not signed by a - # trusted CA). - other_ca_certs = os.path.join( - os.path.dirname(os.path.abspath(httplib2.__file__)), "test", "other_cacerts.txt" - ) - assert os.path.exists(other_ca_certs) - http = httplib2.Http(ca_certs=other_ca_certs) - http.follow_redirects = False - with tests.assert_raises(ssl.SSLError): - http.request("https://www.google.com/", "GET") - - -def test_sni_hostname_validation(): - # TODO: make explicit test server with SNI validation - http = httplib2.Http() - http.request("https://google.com/", method="GET") - - -@pytest.mark.skipif( - os.environ.get("TRAVIS_PYTHON_VERSION") in ("2.7", "pypy"), - reason="Python 2.7 doesn't support TLS min/max" -) -def test_min_tls_version(): - # skip on Python versions that don't support TLS min - if not hasattr(ssl.SSLContext(), 'minimum_version'): - return - # BadSSL server that supports max TLS 1.1, - # forcing 1.2 should always fail - http = httplib2.Http(tls_minimum_version="TLSv1_2") - with tests.assert_raises(ssl.SSLError): - http.request("https://tls-v1-1.badssl.com:1011/") - - -@pytest.mark.skipif( - os.environ.get("TRAVIS_PYTHON_VERSION") in ("2.7", "pypy"), - reason="Python 2.7 doesn't support TLS min/max" -) -def test_max_tls_version(): - # skip on Python versions that don't support TLS max - if not hasattr(ssl.SSLContext(), 'maximum_version'): - return - # Google supports TLS 1.2+, confirm we can force down to 1.0 - # this may break whenever Google disables TLSv1 - http = httplib2.Http(tls_maximum_version="TLSv1") - http.request("https://google.com") - _, tls_ver, _ = http.connections['https:google.com'].sock.cipher() - assert tls_ver == "TLSv1.0" diff --git a/tests/test_http.py b/tests/test_http.py index 9bd9ee0..97b52dc 100644 --- a/tests/test_http.py +++ b/tests/test_http.py @@ -10,12 +10,8 @@ import os import pytest from six.moves import http_client, urllib import socket -import ssl import tests -DUMMY_URL = "http://127.0.0.1:1" -DUMMY_HTTPS_URL = "https://127.0.0.1:2" - def _raise_connection_refused_exception(*args, **kwargs): raise socket.error(errno.ECONNREFUSED, "Connection refused.") @@ -25,9 +21,9 @@ def test_connection_type(): http = httplib2.Http() http.force_exception_to_status_code = False response, content = http.request( - DUMMY_URL, connection_type=tests.MockHTTPConnection + tests.DUMMY_URL, connection_type=tests.MockHTTPConnection ) - assert response["content-location"] == DUMMY_URL + assert response["content-location"] == tests.DUMMY_URL assert content == b"the body" @@ -38,7 +34,7 @@ def test_bad_status_line_retry(): http.force_exception_to_status_code = False try: response, content = http.request( - DUMMY_URL, connection_type=tests.MockHTTPBadStatusConnection + tests.DUMMY_URL, connection_type=tests.MockHTTPBadStatusConnection ) except http_client.BadStatusLine: assert tests.MockHTTPBadStatusConnection.num_calls == 2 @@ -71,7 +67,7 @@ def test_connection_refused_raises_exception(mock_socket_connect): http = httplib2.Http() http.force_exception_to_status_code = False with tests.assert_raises(socket.error): - http.request(DUMMY_URL) + http.request(tests.DUMMY_URL) @pytest.mark.skipif( @@ -84,7 +80,7 @@ def test_connection_refused_returns_response(mock_socket_connect): mock_socket_connect.side_effect = _raise_connection_refused_exception http = httplib2.Http() http.force_exception_to_status_code = True - response, content = http.request(DUMMY_URL) + response, content = http.request(tests.DUMMY_URL) content = content.lower() assert response["content-type"] == "text/plain" assert ( @@ -647,38 +643,3 @@ content""" assert response.status == 200 assert content == b"content" assert response["link"], "link1, link2" - - -@pytest.mark.skipif( - os.environ.get("TRAVIS_PYTHON_VERSION") in ("2.7", "pypy"), - reason="Python 2.7 doesn't support TLS min/max" -) -def test_set_min_tls_version(): - # Test setting minimum TLS version - # We expect failure on Python < 3.7 or OpenSSL < 1.1 - expect_success = hasattr(ssl.SSLContext(), 'minimum_version') - try: - http = httplib2.Http(tls_minimum_version="TLSv1_2") - http.request(DUMMY_HTTPS_URL) - except RuntimeError: - assert not expect_success - except socket.error: - assert expect_success - - -@pytest.mark.skipif( - os.environ.get("TRAVIS_PYTHON_VERSION") in ("2.7", "pypy"), - reason="Python 2.7 doesn't support TLS min/max" -) -def test_set_max_tls_version(): - # Test setting maximum TLS version - # We expect RuntimeError on Python < 3.7 or OpenSSL < 1.1 - # We expect socket error otherwise - expect_success = hasattr(ssl.SSLContext(), 'maximum_version') - try: - http = httplib2.Http(tls_maximum_version="TLSv1_2") - http.request(DUMMY_HTTPS_URL) - except RuntimeError: - assert not expect_success - except socket.error: - assert expect_success diff --git a/tests/test_https.py b/tests/test_https.py new file mode 100644 index 0000000..39d7d59 --- /dev/null +++ b/tests/test_https.py @@ -0,0 +1,203 @@ +import httplib2 +import pytest +from six.moves import urllib +import socket +import ssl +import tests + + +def test_get_via_https(): + # Test that we can handle HTTPS + http = httplib2.Http(ca_certs=tests.CA_CERTS) + with tests.server_const_http(tls=True) as uri: + response, _ = http.request(uri, "GET") + assert response.status == 200 + + +def test_get_301_via_https(): + http = httplib2.Http(ca_certs=tests.CA_CERTS) + glocation = [""] # nonlocal kind of trick, maybe redundant + + def handler(request): + if request.uri == "/final": + return tests.http_response_bytes(body=b"final") + return tests.http_response_bytes(status="301 goto", headers={"location": glocation[0]}) + + with tests.server_request(handler, request_count=2, tls=True) as uri: + glocation[0] = urllib.parse.urljoin(uri, "/final") + response, content = http.request(uri, "GET") + assert response.status == 200 + assert content == b"final" + assert response.previous.status == 301 + assert response.previous["location"] == glocation[0] + + +def test_get_301_via_https_spec_violation_on_location(): + # Test that we follow redirects through HTTPS + # even if they violate the spec by including + # a relative Location: header instead of an absolute one. + http = httplib2.Http(ca_certs=tests.CA_CERTS) + + def handler(request): + if request.uri == "/final": + return tests.http_response_bytes(body=b"final") + return tests.http_response_bytes(status="301 goto", headers={"location": "/final"}) + + with tests.server_request(handler, request_count=2, tls=True) as uri: + response, content = http.request(uri, "GET") + assert response.status == 200 + assert content == b"final" + assert response.previous.status == 301 + + +def test_invalid_ca_certs_path(): + http = httplib2.Http(ca_certs="/nosuchfile") + with tests.server_const_http(request_count=0, tls=True) as uri: + with tests.assert_raises(IOError): + http.request(uri, "GET") + + +def test_not_trusted_ca(): + # Test that we get a SSLHandshakeError if we try to access + # server using a CA cert file that doesn't contain server's CA. + http = httplib2.Http(ca_certs=tests.CA_UNUSED_CERTS) + with tests.server_const_http(tls=True) as uri: + try: + http.request(uri, "GET") + assert False, "expected CERTIFICATE_VERIFY_FAILED" + except ssl.SSLError as e: + assert e.reason == "CERTIFICATE_VERIFY_FAILED" + except httplib2.SSLHandshakeError: # Python2 + pass + + +@pytest.mark.skipif( + not hasattr(tests.ssl_context(), "minimum_version"), + reason="ssl doesn't support TLS min/max", +) +def test_set_min_tls_version(): + # Test setting minimum TLS version + # We expect failure on Python < 3.7 or OpenSSL < 1.1 + expect_success = hasattr(ssl.SSLContext(), 'minimum_version') + try: + http = httplib2.Http(tls_minimum_version="TLSv1_2") + http.request(tests.DUMMY_HTTPS_URL) + except RuntimeError: + assert not expect_success + except socket.error: + assert expect_success + + +@pytest.mark.skipif( + not hasattr(tests.ssl_context(), "maximum_version"), + reason="ssl doesn't support TLS min/max", +) +def test_set_max_tls_version(): + # Test setting maximum TLS version + # We expect RuntimeError on Python < 3.7 or OpenSSL < 1.1 + # We expect socket error otherwise + expect_success = hasattr(ssl.SSLContext(), 'maximum_version') + try: + http = httplib2.Http(tls_maximum_version="TLSv1_2") + http.request(tests.DUMMY_HTTPS_URL) + except RuntimeError: + assert not expect_success + except socket.error: + assert expect_success + + +@pytest.mark.skipif( + not hasattr(tests.ssl_context(), "minimum_version"), + reason="ssl doesn't support TLS min/max", +) +def test_min_tls_version(): + def setup_tls(context, server, skip_errors): + skip_errors.append("WRONG_VERSION_NUMBER") + context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_1) + context.load_cert_chain(tests.SERVER_CHAIN) + return context.wrap_socket(server, server_side=True) + + http = httplib2.Http(ca_certs=tests.CA_CERTS, tls_minimum_version="TLSv1_2") + with tests.server_const_http(tls=setup_tls) as uri: + try: + http.request(uri) + assert False, "expected SSLError" + except ssl.SSLError as e: + assert e.reason in ("UNSUPPORTED_PROTOCOL", "VERSION_TOO_LOW") + + +@pytest.mark.skipif( + not hasattr(tests.ssl_context(), "maximum_version"), + reason="ssl doesn't support TLS min/max", +) +def test_max_tls_version(): + http = httplib2.Http(ca_certs=tests.CA_CERTS, tls_maximum_version="TLSv1") + with tests.server_const_http(tls=True) as uri: + http.request(uri) + _, tls_ver, _ = http.connections.popitem()[1].sock.cipher() + assert tls_ver == "TLSv1.0" + + +def test_client_cert_verified(): + cert_log = [] + + def setup_tls(context, server, skip_errors): + context.load_verify_locations(cafile=tests.CA_CERTS) + context.verify_mode = ssl.CERT_REQUIRED + return context.wrap_socket(server, server_side=True) + + def handler(request): + cert_log.append(request.client_sock.getpeercert()) + return tests.http_response_bytes() + + http = httplib2.Http(ca_certs=tests.CA_CERTS) + with tests.server_request(handler, tls=setup_tls) as uri: + uri_parsed = urllib.parse.urlparse(uri) + http.add_certificate(tests.CLIENT_PEM, tests.CLIENT_PEM, uri_parsed.netloc) + http.request(uri) + + assert len(cert_log) == 1 + # TODO extract serial from tests.CLIENT_PEM + assert cert_log[0]["serialNumber"] == "E2AA6A96D1BF1AEC" + + +def test_client_cert_password_verified(): + cert_log = [] + + def setup_tls(context, server, skip_errors): + context.load_verify_locations(cafile=tests.CA_CERTS) + context.verify_mode = ssl.CERT_REQUIRED + return context.wrap_socket(server, server_side=True) + + def handler(request): + cert_log.append(request.client_sock.getpeercert()) + return tests.http_response_bytes() + + http = httplib2.Http(ca_certs=tests.CA_CERTS) + with tests.server_request(handler, tls=setup_tls) as uri: + uri_parsed = urllib.parse.urlparse(uri) + http.add_certificate(tests.CLIENT_ENCRYPTED_PEM, tests.CLIENT_ENCRYPTED_PEM, + uri_parsed.netloc, password="12345") + http.request(uri) + + assert len(cert_log) == 1 + # TODO extract serial from tests.CLIENT_PEM + assert cert_log[0]["serialNumber"] == "E2AA6A96D1BF1AED" + + +@pytest.mark.skipif( + not hasattr(tests.ssl_context(), "set_servername_callback"), + reason="SSLContext.set_servername_callback is not available", +) +def test_sni_set_servername_callback(): + sni_log = [] + + def setup_tls(context, server, skip_errors): + context.set_servername_callback(lambda _sock, hostname, _context: sni_log.append(hostname)) + return context.wrap_socket(server, server_side=True) + + http = httplib2.Http(ca_certs=tests.CA_CERTS) + with tests.server_const_http(tls=setup_tls) as uri: + uri_parsed = urllib.parse.urlparse(uri) + http.request(uri) + assert sni_log == [uri_parsed.hostname] diff --git a/tests/test_other.py b/tests/test_other.py index f87cfbd..0f450ab 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -232,3 +232,24 @@ def test_http_443_forced_https(): assert len(m.call_args) > 0, "expected Http._request() call" conn = m.call_args[0][0] assert isinstance(conn, httplib2.HTTPConnectionWithTimeout) + + +def test_close(): + http = httplib2.Http() + assert len(http.connections) == 0 + with tests.server_const_http() as uri: + http.request(uri) + assert len(http.connections) == 1 + http.close() + assert len(http.connections) == 0 + + +def test_connect_exception_type(): + # This autoformatting PR actually changed the behavior of error handling: + # https://github.com/httplib2/httplib2/pull/105/files#diff-c6669c781a2dee1b2d2671cab4e21c66L985 + # potentially changing the type of the error raised by connect() + # https://github.com/httplib2/httplib2/pull/150 + http = httplib2.Http() + with mock.patch("httplib2.socket.socket.connect", side_effect=socket.timeout("foo")): + with tests.assert_raises(socket.timeout): + http.request(tests.DUMMY_URL) diff --git a/tests/tls/ca.key b/tests/tls/ca.key new file mode 100644 index 0000000..cc1bb1a --- /dev/null +++ b/tests/tls/ca.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAxBKerwr0M3230xWKMvxB20+AR9SojbQIN2/8EI9pbSrjmlTH +PFXWf02q2Ll0GPbcnSKOMnAARptVCkxEfkDGPN03Ux0jjGu2MrwZHURXM2gHsQn3 +3Gj3HCreFLMxIqMFfGeB9T0VxurgUek/+bR85QBVNE9GrQfrAN8O+ScOpCOENh5r +lYc/QscH/S0QJvttbGAZFP1bB/Xjltwd6fF3rZgCfTJ88B2UIcEVt+X/kc/0QByP +PACAnCaE4cB2q+SJVEMYP6BLDVvCPRO53UC8cqsLfpKUz73two/No4PhMHwCPspC ++wKlAD3+GWmsatz0rRysm7V0GghCGe+T5JHsGwIDAQABAoIBAE+7KqAPmkIeC1Rg +2/PjtHwUFhwfk/MblIPGm/+38a0c1bT6aJJWbYUS9jhvIZDNQeT8GkrUVKhhnfE0 +Fl4oxPQXGNpJbR0657o11xiZo8QZt5b8cLhGTsY7gFd2jrKBDEgMZ0JsdqCO/m0Q +pp1KEcelnQBKhHj0UVHnYtVaVo/T0ciS06l0urxpXBW2Bcg5lP/KzBD9md9UJrPU +9oPM2snMlBTGKH79eTZu4eyKWOMIK+0vSLBnJkAZtNjvitftEs+a0AvVSF+uXbow +sz7WUpm+BR2wTKikfNMa5nNaLUCdE3sB/1fHQeT7reLEfIVrIfHCyNHi2X0xwWBP +n9U/Q1ECgYEA/qT9JhIZsy1HjHNliFhfW1lBMLRZdiQwyQeoV0N1aMy68rV3kDqr +z8qIaHRt2zCgbKgEhB2WRuIL57mXK3WRhk3KP5LEG0wKr7n58iiTtipH/I/04rTG +RAcYUIR8gDpvd0P1YUJ4dSMqPLDP13+ikA8C3EfL78nxMeCdhyuBA0cCgYEAxR3Q +Smjkcs8pckl04qOZnnGRpKg/Hmu2wIg2WNisI97t35B0dkZhTOGfsCuMOWJixzEp +35ZgUzWUd3ACrgZQcxUYlBAdo849QE7lx1Nys8kouPEjbVsRH8Fs1JJkEiVYhoWV +8JfVzv6Mb95ZBGlvYsiq6p9hT0mLykDNt0xG8o0CgYBOHj1O1ZSuxABEFQ6b0kiG +lI4MK/eZ56ZTtZauFpLJMK1VUdg5Fdapaz+Hk9gzuuosCys/gHgejLAMSYIXofyf +z/Nwp0yj9yL8H7iO0mXmJ3hoAZ2lgsGkEu0hnlM3XzXcx6taR/L+NGh7r95DBPPQ +79n3y8rDaBcnLvoEgpMUdwKBgQCBN6Qdw1lO8gMHiqP3FqxTs7t4J1sJRC9PU3vd +Dlz6Pt/NGNNf3Y9XaOjYAhQwYhDC57W9fsSyh4NGMMVw8261onS0S0RC56Y7i/0R +h+C/fvUVF+7Td0loedIwH68+PgEkXloGmGJvCWtiwm20eLGuHkH9AHI4Gcxrz8OL +j5NK2QKBgCYKtCqB1rXp4k4KcHYQBSmbIN9aEzd4OqjYtzvrYv8wE8ooRim8dd55 +xRRh1r6Nx7+/KoXg7FgaLbDex4dGeCExjvXLmtJNOj0QwJwID84ZhmzjvL26sY8F +rrt4XPaZv8/5T5kiXE2Mtp3LyIPlq0tRXepdyltrTFPfX3HR+ph2 +-----END RSA PRIVATE KEY----- diff --git a/tests/tls/ca.pem b/tests/tls/ca.pem new file mode 100644 index 0000000..1c05e64 --- /dev/null +++ b/tests/tls/ca.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRDCCAiwCCQC5E5PSm8flUjANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQGEwJa +WjEKMAgGA1UECAwBLjEKMAgGA1UEBwwBLjEWMBQGA1UECgwNaHR0cGxpYjItdGVz +dDEKMAgGA1UECwwBLjEZMBcGA1UEAwwQaHR0cGxpYjItdGVzdC1DQTAeFw0xOTA5 +MjYxNTAzMzRaFw0yOTA5MjMxNTAzMzRaMGQxCzAJBgNVBAYTAlpaMQowCAYDVQQI +DAEuMQowCAYDVQQHDAEuMRYwFAYDVQQKDA1odHRwbGliMi10ZXN0MQowCAYDVQQL +DAEuMRkwFwYDVQQDDBBodHRwbGliMi10ZXN0LUNBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAxBKerwr0M3230xWKMvxB20+AR9SojbQIN2/8EI9pbSrj +mlTHPFXWf02q2Ll0GPbcnSKOMnAARptVCkxEfkDGPN03Ux0jjGu2MrwZHURXM2gH +sQn33Gj3HCreFLMxIqMFfGeB9T0VxurgUek/+bR85QBVNE9GrQfrAN8O+ScOpCOE +Nh5rlYc/QscH/S0QJvttbGAZFP1bB/Xjltwd6fF3rZgCfTJ88B2UIcEVt+X/kc/0 +QByPPACAnCaE4cB2q+SJVEMYP6BLDVvCPRO53UC8cqsLfpKUz73two/No4PhMHwC +PspC+wKlAD3+GWmsatz0rRysm7V0GghCGe+T5JHsGwIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQB4b+DWt0An4YoXj7lb/+N7FVr2m5UVyBI+bbEGI/qsql/Ixiaef69M +jej7n5ucUx8GBql62W0c3/E3qZFfo49ngH1WC5gkKQH9V4jGZui5CUfmNE6WepQ/ +vL6eKXUp7RoJ/hWVhGm1uV3OShF+EN0t2wZttYg4lip0FjrY8tRWdjw5yu61wWVu +WuHxTzKiHe9emjhhUBgnWRnNeYPTRs0xM2Awv5KYPq2cmrjGbSz3mYDkBpbiJUp4 +pM9g8qLmsDO2yrlVF659D08+5zkmMbyqnn84X0n3SM3Yn0ayZOmbNHiXoAzklZNP +7xiyxMEAfVQOITsvSDG2PzbZlGGtbaka +-----END CERTIFICATE----- diff --git a/tests/tls/ca.srl b/tests/tls/ca.srl new file mode 100644 index 0000000..ad8d416 --- /dev/null +++ b/tests/tls/ca.srl @@ -0,0 +1 @@ +E2AA6A96D1BF1AEE diff --git a/tests/tls/ca_unused.pem b/tests/tls/ca_unused.pem new file mode 100644 index 0000000..4c4291a --- /dev/null +++ b/tests/tls/ca_unused.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDUjCCAjoCCQC47jeQyttLgzANBgkqhkiG9w0BAQsFADBrMQswCQYDVQQGEwJa +WjEKMAgGA1UECAwBLjEKMAgGA1UEBwwBLjEWMBQGA1UECgwNaHR0cGxpYjItdGVz +dDEKMAgGA1UECwwBLjEgMB4GA1UEAwwXaHR0cGxpYjItdGVzdC1DQS11bnVzZWQw +HhcNMTkwOTI2MTUwMzM0WhcNMjkwOTIzMTUwMzM0WjBrMQswCQYDVQQGEwJaWjEK +MAgGA1UECAwBLjEKMAgGA1UEBwwBLjEWMBQGA1UECgwNaHR0cGxpYjItdGVzdDEK +MAgGA1UECwwBLjEgMB4GA1UEAwwXaHR0cGxpYjItdGVzdC1DQS11bnVzZWQwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEEp6vCvQzfbfTFYoy/EHbT4BH +1KiNtAg3b/wQj2ltKuOaVMc8VdZ/TarYuXQY9tydIo4ycABGm1UKTER+QMY83TdT +HSOMa7YyvBkdRFczaAexCffcaPccKt4UszEiowV8Z4H1PRXG6uBR6T/5tHzlAFU0 +T0atB+sA3w75Jw6kI4Q2HmuVhz9Cxwf9LRAm+21sYBkU/VsH9eOW3B3p8XetmAJ9 +MnzwHZQhwRW35f+Rz/RAHI88AICcJoThwHar5IlUQxg/oEsNW8I9E7ndQLxyqwt+ +kpTPve3Cj82jg+EwfAI+ykL7AqUAPf4Zaaxq3PStHKybtXQaCEIZ75PkkewbAgMB +AAEwDQYJKoZIhvcNAQELBQADggEBAFbeSPQgXJxfHc1m8wJ4eSW470gXjHZD82uH +sZTj6v+UZlYzVUgDt+KEdZpoIP8C0prhez+scB6YcwiwP5iHfH3AB51jVoQvKAFt +4TNKt9LvOuOzGKk9LmO41xYO6KjAOWuoERdYtBR0h0CyOm756iHwO0bQEELiePfU +hB7o9SlVg0aMcWtbrGBLGBy6HE0p3Oiq/ny0G8r/gshnHvLku6JOxg0XJGDi3LuG +ezBF0HFwK56NaB2syDtQRCT7I5yqLBK2AlwhcbZat07vLFPeDyw4Omh6COJ/tQsU +qIcVJ6kS7VJejjWQD8z5CybYDnmBJJqXW4ixUs8wu0l3miaBdiM= +-----END CERTIFICATE----- diff --git a/tests/tls/client.crt b/tests/tls/client.crt new file mode 100644 index 0000000..9430e27 --- /dev/null +++ b/tests/tls/client.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSDCCAjACCQDiqmqW0b8a7DANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJa +WjEKMAgGA1UECAwBLjEKMAgGA1UEBwwBLjEWMBQGA1UECgwNaHR0cGxpYjItdGVz +dDEKMAgGA1UECwwBLjEZMBcGA1UEAwwQaHR0cGxpYjItdGVzdC1DQTAeFw0xOTA5 +MjYxNTAzMzRaFw0yOTA5MjMxNTAzMzRaMGgxCzAJBgNVBAYTAlpaMQowCAYDVQQI +DAEuMQowCAYDVQQHDAEuMRYwFAYDVQQKDA1odHRwbGliMi10ZXN0MQowCAYDVQQL +DAEuMR0wGwYDVQQDDBRodHRwbGliMi10ZXN0LWNsaWVudDCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALtXT//Esar+MDk6Gcj3KDLAyTU7jPqUx4S83LNI +GumuBmOg7oe16SSM//NUFhCHiHr4IzeqDOD2Dq1aM661Ta2EINHvpG+9BEkCWkFr +q4eh0pfocsvU64dtd26TCk9Q4Qqaj4t4HSYYv1hz8UFh5RNLVjgtbR7OQ37Oumcg +jRGnelV/ck6u5BvN/fKK7p/W6hPcO9OjJDAmlVNZVPtP2ki6Lv/Q87x34X+1/Qb1 +LILUOG5mdfCTmf2tYh9bXqZmqoidTY4O7/JiPuT0+1056Ja8bDGYSFXPvvqd1aEW +nGA22MEzd74w9A4tIieCRHlGGOSf0AGsVTmHKRf5bpQjaCsCAwEAATANBgkqhkiG +9w0BAQUFAAOCAQEAi/X3QjpzPap9IhpHqvgFirsEepruz8lCk+Zo6A/+DP/PocII +/8jWdIV87RDDkkaVGvWOywZyUNN1RAfrt/jGCW8xgCaSGWRab10QIW8DGhbP6FTz +7xcBnQzcoc1gggZBcwOjkRuefW2zkgGIJo5XxHlBfo3T9nX4086Py/b+VoAmcIlm +Y/LNHxtIyDDiOgGK9x7+IqEXQuo/p2z5oFubj/hyNJhXaYU2u7nNMXICYY/eY4vX +GgZ44lGZ2YR7NwzqM5UHNXr7/VJzgxWwAgyZUT8DdnjkZY4wLt1JJas5n3oldBsA ++og2cMk0oOsiFAwHAwE7St4oFY0ivKDhttf7WQ== +-----END CERTIFICATE----- diff --git a/tests/tls/client.key b/tests/tls/client.key new file mode 100644 index 0000000..9a442b8 --- /dev/null +++ b/tests/tls/client.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAu1dP/8Sxqv4wOToZyPcoMsDJNTuM+pTHhLzcs0ga6a4GY6Du +h7XpJIz/81QWEIeIevgjN6oM4PYOrVozrrVNrYQg0e+kb70ESQJaQWurh6HSl+hy +y9Trh213bpMKT1DhCpqPi3gdJhi/WHPxQWHlE0tWOC1tHs5Dfs66ZyCNEad6VX9y +Tq7kG8398orun9bqE9w706MkMCaVU1lU+0/aSLou/9DzvHfhf7X9BvUsgtQ4bmZ1 +8JOZ/a1iH1tepmaqiJ1Njg7v8mI+5PT7XTnolrxsMZhIVc+++p3VoRacYDbYwTN3 +vjD0Di0iJ4JEeUYY5J/QAaxVOYcpF/lulCNoKwIDAQABAoIBAQCtzBeUYWauCni0 +bnlDXj91rjI7504nneTm+MsKq6cECQU2YjNHxXRQC1rb47NAjGwKIK+TUXf3L254 +VglCWEKC6eQEvvxfCQyzqrIOpRORlYeok+YDwTjr/5rgAxt6b78GtlLbAYiRMj45 +kf5MOMRqvOZ04XetL4+gUarOR3131L38ysReluabsCXkgIH9kZHmgOW2El4lmoHp +CQpvMkJWyoVZvDbjLi0JoEljHGpfdWNdcllHP4dbNSQtfgG3VXXFgKqWQ8ZiY2U1 +y5SxHaeAjKHBUoGeinox/Myzan3xCysZb+gi5UxcrE7dn5lSB2/AMBymYShI/2qi +UWq64JeJAoGBAPLtHRIcbRn53IhXGwcdFAn7JUSzKvr+gUfJiyfbw28CDWVRgTce +JN+FzTuW92Iwm3ppBKmJ5PcZZnqt7VTtWfLvP126YaGctqZHSWiD9oK3EzDJEWIO +trpMlJkeB+IQlvYMCiC+G+6XFBCdB7X3X1D9Y9z11Kf/arx24bB/ByVlAoGBAMVs +YZRL9idgwgU4LMOqaPkU99de4wzYF44joZrp3Eme3dC9sdHrDtDy6OpiQu4zP+Ax +5cws6M6txd5meAh2YwRhJBmGUYIQuhhNKQjhoeovw0tbtXO9rAHPegXPqg8xwzY9 +Ntc/WlfwM0O7ROfOq4r9erWBn0B7xspxRMH+LIZPAoGBALVW326XnbHYXRHBxEFJ +KZ5Rxf5EqP74YVVPU/uLB5akN4+8ifK1I91fqlajWUQI+Ocl4f8VGsCCS4ekshfF +nnHEus6ixSK5M3dom5nTeH8XXtH6JmnGhg0IAZ1TV5sfuzEsx5qtj3hJewbz0b+6 +S4LPxG47bGWEOw84xzzTdmgpAoGAGj87heTHeBrEEL+UK/tW826XOLnzw7xi/VG9 +ZYQb9mm5ocvmfTscACmbT7X6ogKMRnk7zPZXiUrPGK9U3AMpTObBTudtpLYml56C +ixy8Uw9Ajp9Fs3qPCLqVxXoDaPu7sVVYGivhDfnwRtv54Du40MS8cK8oBgGuvzFp +68SoFL8CgYAY7KvTfTKk4oWWeclmwEoe04woV7J6XuB7OnbxYpKpiGh4juN1E6wo +n9UhAVzO6cAfK/ZuhTkDtvJSsXtQ1xElZLMIG1Yb7yikRyO73EHRUpHon3Gah+79 +MM6uZReiEdkx/hMthL45jP85hfVM89M7LYj9SBoxY2xpuzN+HmiezQ== +-----END RSA PRIVATE KEY----- diff --git a/tests/tls/client.pem b/tests/tls/client.pem new file mode 100644 index 0000000..f12775f --- /dev/null +++ b/tests/tls/client.pem @@ -0,0 +1,47 @@ +-----BEGIN CERTIFICATE----- +MIIDSDCCAjACCQDiqmqW0b8a7DANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJa +WjEKMAgGA1UECAwBLjEKMAgGA1UEBwwBLjEWMBQGA1UECgwNaHR0cGxpYjItdGVz +dDEKMAgGA1UECwwBLjEZMBcGA1UEAwwQaHR0cGxpYjItdGVzdC1DQTAeFw0xOTA5 +MjYxNTAzMzRaFw0yOTA5MjMxNTAzMzRaMGgxCzAJBgNVBAYTAlpaMQowCAYDVQQI +DAEuMQowCAYDVQQHDAEuMRYwFAYDVQQKDA1odHRwbGliMi10ZXN0MQowCAYDVQQL +DAEuMR0wGwYDVQQDDBRodHRwbGliMi10ZXN0LWNsaWVudDCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALtXT//Esar+MDk6Gcj3KDLAyTU7jPqUx4S83LNI +GumuBmOg7oe16SSM//NUFhCHiHr4IzeqDOD2Dq1aM661Ta2EINHvpG+9BEkCWkFr +q4eh0pfocsvU64dtd26TCk9Q4Qqaj4t4HSYYv1hz8UFh5RNLVjgtbR7OQ37Oumcg +jRGnelV/ck6u5BvN/fKK7p/W6hPcO9OjJDAmlVNZVPtP2ki6Lv/Q87x34X+1/Qb1 +LILUOG5mdfCTmf2tYh9bXqZmqoidTY4O7/JiPuT0+1056Ja8bDGYSFXPvvqd1aEW +nGA22MEzd74w9A4tIieCRHlGGOSf0AGsVTmHKRf5bpQjaCsCAwEAATANBgkqhkiG +9w0BAQUFAAOCAQEAi/X3QjpzPap9IhpHqvgFirsEepruz8lCk+Zo6A/+DP/PocII +/8jWdIV87RDDkkaVGvWOywZyUNN1RAfrt/jGCW8xgCaSGWRab10QIW8DGhbP6FTz +7xcBnQzcoc1gggZBcwOjkRuefW2zkgGIJo5XxHlBfo3T9nX4086Py/b+VoAmcIlm +Y/LNHxtIyDDiOgGK9x7+IqEXQuo/p2z5oFubj/hyNJhXaYU2u7nNMXICYY/eY4vX +GgZ44lGZ2YR7NwzqM5UHNXr7/VJzgxWwAgyZUT8DdnjkZY4wLt1JJas5n3oldBsA ++og2cMk0oOsiFAwHAwE7St4oFY0ivKDhttf7WQ== +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAu1dP/8Sxqv4wOToZyPcoMsDJNTuM+pTHhLzcs0ga6a4GY6Du +h7XpJIz/81QWEIeIevgjN6oM4PYOrVozrrVNrYQg0e+kb70ESQJaQWurh6HSl+hy +y9Trh213bpMKT1DhCpqPi3gdJhi/WHPxQWHlE0tWOC1tHs5Dfs66ZyCNEad6VX9y +Tq7kG8398orun9bqE9w706MkMCaVU1lU+0/aSLou/9DzvHfhf7X9BvUsgtQ4bmZ1 +8JOZ/a1iH1tepmaqiJ1Njg7v8mI+5PT7XTnolrxsMZhIVc+++p3VoRacYDbYwTN3 +vjD0Di0iJ4JEeUYY5J/QAaxVOYcpF/lulCNoKwIDAQABAoIBAQCtzBeUYWauCni0 +bnlDXj91rjI7504nneTm+MsKq6cECQU2YjNHxXRQC1rb47NAjGwKIK+TUXf3L254 +VglCWEKC6eQEvvxfCQyzqrIOpRORlYeok+YDwTjr/5rgAxt6b78GtlLbAYiRMj45 +kf5MOMRqvOZ04XetL4+gUarOR3131L38ysReluabsCXkgIH9kZHmgOW2El4lmoHp +CQpvMkJWyoVZvDbjLi0JoEljHGpfdWNdcllHP4dbNSQtfgG3VXXFgKqWQ8ZiY2U1 +y5SxHaeAjKHBUoGeinox/Myzan3xCysZb+gi5UxcrE7dn5lSB2/AMBymYShI/2qi +UWq64JeJAoGBAPLtHRIcbRn53IhXGwcdFAn7JUSzKvr+gUfJiyfbw28CDWVRgTce +JN+FzTuW92Iwm3ppBKmJ5PcZZnqt7VTtWfLvP126YaGctqZHSWiD9oK3EzDJEWIO +trpMlJkeB+IQlvYMCiC+G+6XFBCdB7X3X1D9Y9z11Kf/arx24bB/ByVlAoGBAMVs +YZRL9idgwgU4LMOqaPkU99de4wzYF44joZrp3Eme3dC9sdHrDtDy6OpiQu4zP+Ax +5cws6M6txd5meAh2YwRhJBmGUYIQuhhNKQjhoeovw0tbtXO9rAHPegXPqg8xwzY9 +Ntc/WlfwM0O7ROfOq4r9erWBn0B7xspxRMH+LIZPAoGBALVW326XnbHYXRHBxEFJ +KZ5Rxf5EqP74YVVPU/uLB5akN4+8ifK1I91fqlajWUQI+Ocl4f8VGsCCS4ekshfF +nnHEus6ixSK5M3dom5nTeH8XXtH6JmnGhg0IAZ1TV5sfuzEsx5qtj3hJewbz0b+6 +S4LPxG47bGWEOw84xzzTdmgpAoGAGj87heTHeBrEEL+UK/tW826XOLnzw7xi/VG9 +ZYQb9mm5ocvmfTscACmbT7X6ogKMRnk7zPZXiUrPGK9U3AMpTObBTudtpLYml56C +ixy8Uw9Ajp9Fs3qPCLqVxXoDaPu7sVVYGivhDfnwRtv54Du40MS8cK8oBgGuvzFp +68SoFL8CgYAY7KvTfTKk4oWWeclmwEoe04woV7J6XuB7OnbxYpKpiGh4juN1E6wo +n9UhAVzO6cAfK/ZuhTkDtvJSsXtQ1xElZLMIG1Yb7yikRyO73EHRUpHon3Gah+79 +MM6uZReiEdkx/hMthL45jP85hfVM89M7LYj9SBoxY2xpuzN+HmiezQ== +-----END RSA PRIVATE KEY----- diff --git a/tests/tls/client_chain.pem b/tests/tls/client_chain.pem new file mode 100644 index 0000000..e2427d7 --- /dev/null +++ b/tests/tls/client_chain.pem @@ -0,0 +1,67 @@ +-----BEGIN CERTIFICATE----- +MIIDSDCCAjACCQDiqmqW0b8a7DANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJa +WjEKMAgGA1UECAwBLjEKMAgGA1UEBwwBLjEWMBQGA1UECgwNaHR0cGxpYjItdGVz +dDEKMAgGA1UECwwBLjEZMBcGA1UEAwwQaHR0cGxpYjItdGVzdC1DQTAeFw0xOTA5 +MjYxNTAzMzRaFw0yOTA5MjMxNTAzMzRaMGgxCzAJBgNVBAYTAlpaMQowCAYDVQQI +DAEuMQowCAYDVQQHDAEuMRYwFAYDVQQKDA1odHRwbGliMi10ZXN0MQowCAYDVQQL +DAEuMR0wGwYDVQQDDBRodHRwbGliMi10ZXN0LWNsaWVudDCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALtXT//Esar+MDk6Gcj3KDLAyTU7jPqUx4S83LNI +GumuBmOg7oe16SSM//NUFhCHiHr4IzeqDOD2Dq1aM661Ta2EINHvpG+9BEkCWkFr +q4eh0pfocsvU64dtd26TCk9Q4Qqaj4t4HSYYv1hz8UFh5RNLVjgtbR7OQ37Oumcg +jRGnelV/ck6u5BvN/fKK7p/W6hPcO9OjJDAmlVNZVPtP2ki6Lv/Q87x34X+1/Qb1 +LILUOG5mdfCTmf2tYh9bXqZmqoidTY4O7/JiPuT0+1056Ja8bDGYSFXPvvqd1aEW +nGA22MEzd74w9A4tIieCRHlGGOSf0AGsVTmHKRf5bpQjaCsCAwEAATANBgkqhkiG +9w0BAQUFAAOCAQEAi/X3QjpzPap9IhpHqvgFirsEepruz8lCk+Zo6A/+DP/PocII +/8jWdIV87RDDkkaVGvWOywZyUNN1RAfrt/jGCW8xgCaSGWRab10QIW8DGhbP6FTz +7xcBnQzcoc1gggZBcwOjkRuefW2zkgGIJo5XxHlBfo3T9nX4086Py/b+VoAmcIlm +Y/LNHxtIyDDiOgGK9x7+IqEXQuo/p2z5oFubj/hyNJhXaYU2u7nNMXICYY/eY4vX +GgZ44lGZ2YR7NwzqM5UHNXr7/VJzgxWwAgyZUT8DdnjkZY4wLt1JJas5n3oldBsA ++og2cMk0oOsiFAwHAwE7St4oFY0ivKDhttf7WQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDRDCCAiwCCQC5E5PSm8flUjANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQGEwJa +WjEKMAgGA1UECAwBLjEKMAgGA1UEBwwBLjEWMBQGA1UECgwNaHR0cGxpYjItdGVz +dDEKMAgGA1UECwwBLjEZMBcGA1UEAwwQaHR0cGxpYjItdGVzdC1DQTAeFw0xOTA5 +MjYxNTAzMzRaFw0yOTA5MjMxNTAzMzRaMGQxCzAJBgNVBAYTAlpaMQowCAYDVQQI +DAEuMQowCAYDVQQHDAEuMRYwFAYDVQQKDA1odHRwbGliMi10ZXN0MQowCAYDVQQL +DAEuMRkwFwYDVQQDDBBodHRwbGliMi10ZXN0LUNBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAxBKerwr0M3230xWKMvxB20+AR9SojbQIN2/8EI9pbSrj +mlTHPFXWf02q2Ll0GPbcnSKOMnAARptVCkxEfkDGPN03Ux0jjGu2MrwZHURXM2gH +sQn33Gj3HCreFLMxIqMFfGeB9T0VxurgUek/+bR85QBVNE9GrQfrAN8O+ScOpCOE +Nh5rlYc/QscH/S0QJvttbGAZFP1bB/Xjltwd6fF3rZgCfTJ88B2UIcEVt+X/kc/0 +QByPPACAnCaE4cB2q+SJVEMYP6BLDVvCPRO53UC8cqsLfpKUz73two/No4PhMHwC +PspC+wKlAD3+GWmsatz0rRysm7V0GghCGe+T5JHsGwIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQB4b+DWt0An4YoXj7lb/+N7FVr2m5UVyBI+bbEGI/qsql/Ixiaef69M +jej7n5ucUx8GBql62W0c3/E3qZFfo49ngH1WC5gkKQH9V4jGZui5CUfmNE6WepQ/ +vL6eKXUp7RoJ/hWVhGm1uV3OShF+EN0t2wZttYg4lip0FjrY8tRWdjw5yu61wWVu +WuHxTzKiHe9emjhhUBgnWRnNeYPTRs0xM2Awv5KYPq2cmrjGbSz3mYDkBpbiJUp4 +pM9g8qLmsDO2yrlVF659D08+5zkmMbyqnn84X0n3SM3Yn0ayZOmbNHiXoAzklZNP +7xiyxMEAfVQOITsvSDG2PzbZlGGtbaka +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAu1dP/8Sxqv4wOToZyPcoMsDJNTuM+pTHhLzcs0ga6a4GY6Du +h7XpJIz/81QWEIeIevgjN6oM4PYOrVozrrVNrYQg0e+kb70ESQJaQWurh6HSl+hy +y9Trh213bpMKT1DhCpqPi3gdJhi/WHPxQWHlE0tWOC1tHs5Dfs66ZyCNEad6VX9y +Tq7kG8398orun9bqE9w706MkMCaVU1lU+0/aSLou/9DzvHfhf7X9BvUsgtQ4bmZ1 +8JOZ/a1iH1tepmaqiJ1Njg7v8mI+5PT7XTnolrxsMZhIVc+++p3VoRacYDbYwTN3 +vjD0Di0iJ4JEeUYY5J/QAaxVOYcpF/lulCNoKwIDAQABAoIBAQCtzBeUYWauCni0 +bnlDXj91rjI7504nneTm+MsKq6cECQU2YjNHxXRQC1rb47NAjGwKIK+TUXf3L254 +VglCWEKC6eQEvvxfCQyzqrIOpRORlYeok+YDwTjr/5rgAxt6b78GtlLbAYiRMj45 +kf5MOMRqvOZ04XetL4+gUarOR3131L38ysReluabsCXkgIH9kZHmgOW2El4lmoHp +CQpvMkJWyoVZvDbjLi0JoEljHGpfdWNdcllHP4dbNSQtfgG3VXXFgKqWQ8ZiY2U1 +y5SxHaeAjKHBUoGeinox/Myzan3xCysZb+gi5UxcrE7dn5lSB2/AMBymYShI/2qi +UWq64JeJAoGBAPLtHRIcbRn53IhXGwcdFAn7JUSzKvr+gUfJiyfbw28CDWVRgTce +JN+FzTuW92Iwm3ppBKmJ5PcZZnqt7VTtWfLvP126YaGctqZHSWiD9oK3EzDJEWIO +trpMlJkeB+IQlvYMCiC+G+6XFBCdB7X3X1D9Y9z11Kf/arx24bB/ByVlAoGBAMVs +YZRL9idgwgU4LMOqaPkU99de4wzYF44joZrp3Eme3dC9sdHrDtDy6OpiQu4zP+Ax +5cws6M6txd5meAh2YwRhJBmGUYIQuhhNKQjhoeovw0tbtXO9rAHPegXPqg8xwzY9 +Ntc/WlfwM0O7ROfOq4r9erWBn0B7xspxRMH+LIZPAoGBALVW326XnbHYXRHBxEFJ +KZ5Rxf5EqP74YVVPU/uLB5akN4+8ifK1I91fqlajWUQI+Ocl4f8VGsCCS4ekshfF +nnHEus6ixSK5M3dom5nTeH8XXtH6JmnGhg0IAZ1TV5sfuzEsx5qtj3hJewbz0b+6 +S4LPxG47bGWEOw84xzzTdmgpAoGAGj87heTHeBrEEL+UK/tW826XOLnzw7xi/VG9 +ZYQb9mm5ocvmfTscACmbT7X6ogKMRnk7zPZXiUrPGK9U3AMpTObBTudtpLYml56C +ixy8Uw9Ajp9Fs3qPCLqVxXoDaPu7sVVYGivhDfnwRtv54Du40MS8cK8oBgGuvzFp +68SoFL8CgYAY7KvTfTKk4oWWeclmwEoe04woV7J6XuB7OnbxYpKpiGh4juN1E6wo +n9UhAVzO6cAfK/ZuhTkDtvJSsXtQ1xElZLMIG1Yb7yikRyO73EHRUpHon3Gah+79 +MM6uZReiEdkx/hMthL45jP85hfVM89M7LYj9SBoxY2xpuzN+HmiezQ== +-----END RSA PRIVATE KEY----- diff --git a/tests/tls/client_encrypted.crt b/tests/tls/client_encrypted.crt new file mode 100644 index 0000000..6301dd5 --- /dev/null +++ b/tests/tls/client_encrypted.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDTDCCAjQCCQDiqmqW0b8a7TANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJa +WjEKMAgGA1UECAwBLjEKMAgGA1UEBwwBLjEWMBQGA1UECgwNaHR0cGxpYjItdGVz +dDEKMAgGA1UECwwBLjEZMBcGA1UEAwwQaHR0cGxpYjItdGVzdC1DQTAeFw0xOTA5 +MjYxNTAzMzRaFw0yOTA5MjMxNTAzMzRaMGwxCzAJBgNVBAYTAlpaMQowCAYDVQQI +DAEuMQowCAYDVQQHDAEuMRYwFAYDVQQKDA1odHRwbGliMi10ZXN0MQowCAYDVQQL +DAEuMSEwHwYDVQQDDBhodHRwbGliMi10ZXN0LWNsaWVudC1lbmMwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7V0//xLGq/jA5OhnI9ygywMk1O4z6lMeE +vNyzSBrprgZjoO6HtekkjP/zVBYQh4h6+CM3qgzg9g6tWjOutU2thCDR76RvvQRJ +AlpBa6uHodKX6HLL1OuHbXdukwpPUOEKmo+LeB0mGL9Yc/FBYeUTS1Y4LW0ezkN+ +zrpnII0Rp3pVf3JOruQbzf3yiu6f1uoT3DvToyQwJpVTWVT7T9pIui7/0PO8d+F/ +tf0G9SyC1DhuZnXwk5n9rWIfW16mZqqInU2ODu/yYj7k9PtdOeiWvGwxmEhVz776 +ndWhFpxgNtjBM3e+MPQOLSIngkR5Rhjkn9ABrFU5hykX+W6UI2grAgMBAAEwDQYJ +KoZIhvcNAQEFBQADggEBAKiBTMX/FwUusM4PIsmGqXisOBo6LEf2YtfzQrtxw4eY +eWeKsi3aM2GquCqh0R7loEW+yQoxPEBaNeOBeN3v8sdhTu+9NjK31tWCYr7jvEa5 +TqjlUUMD1176YBQ8axI51lVcaBIoRdvf8nXm7idvp82eBBXQtnREjd8oKcEz7v4x +ECJ+RWGJTEIWXq3fuVvBAJeopNVz+Utt61DCxziKbu+ndv0kQeXZ7KPFiBnARcEi +7GvTeHUA0cbpHrNY0ob7ozcjGiPwW5HPi+DYZYfRm2PqI9vowmKt9By+8Uz03K3L +XMZkGJ28uoo37Rbjs8+pMVDdHoUrm6hZTkw5XGgsA6I= +-----END CERTIFICATE----- diff --git a/tests/tls/client_encrypted.key b/tests/tls/client_encrypted.key new file mode 100644 index 0000000..747b1fb --- /dev/null +++ b/tests/tls/client_encrypted.key @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,84B979083590A865DF5700455C62AEAF + +Q2vQ9vhIV6C3aL4Uk9XIqtsgdN9VN+Ep3mDY7FKbycrcZgDnXbZ5ys50cF8TyJZx +ITYV5ms9MjjUi1cj3hhUfQSu1bJ+gKGWpxHD1Cxub9XLcGJrjfGomO0r5lNe4YZf +of4qc+XpoY+dZTHyFuKn44LiynAG0esqexNc7BcqbGSw6cjm6exvDWbmz0svy2RO +TTfea6oh2+CiHUWqIbjIEoK/tJXXzUq9LwEMGdvyQX5KJDLmsWdxejnqsMmSDBH4 +Bm5ax7AIcO4SE1AdYzzDNI11bZXyQu1UWtgL3D4sDo4iwbHzq9CFXSI21tgwW3WT +LK3Pbt6IAJctwNZozwWDT9c0r226WZv/lYk4bkhvGDuLFMgMwjmW24i4VuU7giiv +sna6jJNk0gQ0XCWiIgtjhrH8noefj07SPb5miXQjhbCvz3F5TqGobWS6xSCX+KMF +LfjJdG5f6QHfnzm+fmIuc/JdcHMCf/2q3bvHuTOoYoJXMY9kcKS5PXckADsQkzmM +2AeoegO8x25ClHRBSOgwee9tkrD5VTX3uK92/rnnt3KUiS8Rdf6jbYpJg2rvCTAd +NF6GCCp+YNw3o7a5IehhhwXWKh0BK02e6IPU9Z6KFTX8LGFOPy8BIghyNILPpfeC +Ir2WWr8asfBLvwy5Pj6Wzfvu6EPC6H0RIxzhTTfaZ0KZR3ZN1Fwd49FNql50UeHH +M5x1vzi4JuRak4z22+uL3GEdkBs/PAoVMfctHTMEiDrH3mgYrEj5yhCgUjJhMP6w +dk6gUaXcPZ6JymUtrZsjcc3cXDD6Vn6i1SH2e9rMf9/QBKGZH3ufkBJ9s0HVsacq +bHg63+BGhmLXFcnEimGVY86py8TfQfuirFOEURoYJMUTCl046GV11AJeF0L+EOUH +nst2Z9l86vCH+7sdVPsVG8jFaeOunr50VkCu/ephGsUSHjNRVagsVOSojknMyNki +D13Oolykusq9zuHMBBRceNRoAHLSk02aHiuwlvQmAVaSJxIebtFZJmG1asXMSK/M +iYjLNb7P+fjpvxYwk1bxXTyTToHLsmvDeGyMj3EhrEh83o/Xoo+bac7OW+l18wWw +N5b5Jcrj0e/O08+dJ5UBXGJ36V5WENTdOjctFTRtZhggkvB1QBZLa1g9khxz0VEw +q0yGYCmjMK2YxpJhH+FAprUM+0Ei9IxIjDY295CEOrKkeJGb9+A8CWLoCi8z0zAc +vQU/uaQsK1BKamKGmu7x+xCyoLSprzNlPjipJttUqkE00kFX9sBJZXW/rI+fQRJI +sYn9UqNp/ay00uswwcoFLAnX7YdKiJrB5jaR5oyLFXpIPQa76594iRcf+9XkD9Ca +KlscDNVnfSW7bkp7LJ+Rm6+OKWCSjglL8uIyBEzoNFCyiEnnzebE+jwvVBaDlbPd +xMwMzU8vHsb9dYd7RMdd+YBIxngzyJiVl6Zpfy9B74vhL+ndyWKZg2Rsunlrcms7 +YIVg/LuAfgH4jXg38yzHHEkArGZg5TFaGUD8rJwMIPil6LOQ4D+jK8/fcV9bhBuH +LzBJ4gtPwUnvYqsaiIAeGi2EVllW0Ka+aTTzM1Yascl2q9WROvutAT0zz0M6smpO +-----END RSA PRIVATE KEY----- diff --git a/tests/tls/client_encrypted.pem b/tests/tls/client_encrypted.pem new file mode 100644 index 0000000..578aa7f --- /dev/null +++ b/tests/tls/client_encrypted.pem @@ -0,0 +1,50 @@ +-----BEGIN CERTIFICATE----- +MIIDTDCCAjQCCQDiqmqW0b8a7TANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJa +WjEKMAgGA1UECAwBLjEKMAgGA1UEBwwBLjEWMBQGA1UECgwNaHR0cGxpYjItdGVz +dDEKMAgGA1UECwwBLjEZMBcGA1UEAwwQaHR0cGxpYjItdGVzdC1DQTAeFw0xOTA5 +MjYxNTAzMzRaFw0yOTA5MjMxNTAzMzRaMGwxCzAJBgNVBAYTAlpaMQowCAYDVQQI +DAEuMQowCAYDVQQHDAEuMRYwFAYDVQQKDA1odHRwbGliMi10ZXN0MQowCAYDVQQL +DAEuMSEwHwYDVQQDDBhodHRwbGliMi10ZXN0LWNsaWVudC1lbmMwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7V0//xLGq/jA5OhnI9ygywMk1O4z6lMeE +vNyzSBrprgZjoO6HtekkjP/zVBYQh4h6+CM3qgzg9g6tWjOutU2thCDR76RvvQRJ +AlpBa6uHodKX6HLL1OuHbXdukwpPUOEKmo+LeB0mGL9Yc/FBYeUTS1Y4LW0ezkN+ +zrpnII0Rp3pVf3JOruQbzf3yiu6f1uoT3DvToyQwJpVTWVT7T9pIui7/0PO8d+F/ +tf0G9SyC1DhuZnXwk5n9rWIfW16mZqqInU2ODu/yYj7k9PtdOeiWvGwxmEhVz776 +ndWhFpxgNtjBM3e+MPQOLSIngkR5Rhjkn9ABrFU5hykX+W6UI2grAgMBAAEwDQYJ +KoZIhvcNAQEFBQADggEBAKiBTMX/FwUusM4PIsmGqXisOBo6LEf2YtfzQrtxw4eY +eWeKsi3aM2GquCqh0R7loEW+yQoxPEBaNeOBeN3v8sdhTu+9NjK31tWCYr7jvEa5 +TqjlUUMD1176YBQ8axI51lVcaBIoRdvf8nXm7idvp82eBBXQtnREjd8oKcEz7v4x +ECJ+RWGJTEIWXq3fuVvBAJeopNVz+Utt61DCxziKbu+ndv0kQeXZ7KPFiBnARcEi +7GvTeHUA0cbpHrNY0ob7ozcjGiPwW5HPi+DYZYfRm2PqI9vowmKt9By+8Uz03K3L +XMZkGJ28uoo37Rbjs8+pMVDdHoUrm6hZTkw5XGgsA6I= +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,84B979083590A865DF5700455C62AEAF + +Q2vQ9vhIV6C3aL4Uk9XIqtsgdN9VN+Ep3mDY7FKbycrcZgDnXbZ5ys50cF8TyJZx +ITYV5ms9MjjUi1cj3hhUfQSu1bJ+gKGWpxHD1Cxub9XLcGJrjfGomO0r5lNe4YZf +of4qc+XpoY+dZTHyFuKn44LiynAG0esqexNc7BcqbGSw6cjm6exvDWbmz0svy2RO +TTfea6oh2+CiHUWqIbjIEoK/tJXXzUq9LwEMGdvyQX5KJDLmsWdxejnqsMmSDBH4 +Bm5ax7AIcO4SE1AdYzzDNI11bZXyQu1UWtgL3D4sDo4iwbHzq9CFXSI21tgwW3WT +LK3Pbt6IAJctwNZozwWDT9c0r226WZv/lYk4bkhvGDuLFMgMwjmW24i4VuU7giiv +sna6jJNk0gQ0XCWiIgtjhrH8noefj07SPb5miXQjhbCvz3F5TqGobWS6xSCX+KMF +LfjJdG5f6QHfnzm+fmIuc/JdcHMCf/2q3bvHuTOoYoJXMY9kcKS5PXckADsQkzmM +2AeoegO8x25ClHRBSOgwee9tkrD5VTX3uK92/rnnt3KUiS8Rdf6jbYpJg2rvCTAd +NF6GCCp+YNw3o7a5IehhhwXWKh0BK02e6IPU9Z6KFTX8LGFOPy8BIghyNILPpfeC +Ir2WWr8asfBLvwy5Pj6Wzfvu6EPC6H0RIxzhTTfaZ0KZR3ZN1Fwd49FNql50UeHH +M5x1vzi4JuRak4z22+uL3GEdkBs/PAoVMfctHTMEiDrH3mgYrEj5yhCgUjJhMP6w +dk6gUaXcPZ6JymUtrZsjcc3cXDD6Vn6i1SH2e9rMf9/QBKGZH3ufkBJ9s0HVsacq +bHg63+BGhmLXFcnEimGVY86py8TfQfuirFOEURoYJMUTCl046GV11AJeF0L+EOUH +nst2Z9l86vCH+7sdVPsVG8jFaeOunr50VkCu/ephGsUSHjNRVagsVOSojknMyNki +D13Oolykusq9zuHMBBRceNRoAHLSk02aHiuwlvQmAVaSJxIebtFZJmG1asXMSK/M +iYjLNb7P+fjpvxYwk1bxXTyTToHLsmvDeGyMj3EhrEh83o/Xoo+bac7OW+l18wWw +N5b5Jcrj0e/O08+dJ5UBXGJ36V5WENTdOjctFTRtZhggkvB1QBZLa1g9khxz0VEw +q0yGYCmjMK2YxpJhH+FAprUM+0Ei9IxIjDY295CEOrKkeJGb9+A8CWLoCi8z0zAc +vQU/uaQsK1BKamKGmu7x+xCyoLSprzNlPjipJttUqkE00kFX9sBJZXW/rI+fQRJI +sYn9UqNp/ay00uswwcoFLAnX7YdKiJrB5jaR5oyLFXpIPQa76594iRcf+9XkD9Ca +KlscDNVnfSW7bkp7LJ+Rm6+OKWCSjglL8uIyBEzoNFCyiEnnzebE+jwvVBaDlbPd +xMwMzU8vHsb9dYd7RMdd+YBIxngzyJiVl6Zpfy9B74vhL+ndyWKZg2Rsunlrcms7 +YIVg/LuAfgH4jXg38yzHHEkArGZg5TFaGUD8rJwMIPil6LOQ4D+jK8/fcV9bhBuH +LzBJ4gtPwUnvYqsaiIAeGi2EVllW0Ka+aTTzM1Yascl2q9WROvutAT0zz0M6smpO +-----END RSA PRIVATE KEY----- diff --git a/tests/tls/server.crt b/tests/tls/server.crt new file mode 100644 index 0000000..e29537a --- /dev/null +++ b/tests/tls/server.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPTCCAiUCCQDiqmqW0b8a7jANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJa +WjEKMAgGA1UECAwBLjEKMAgGA1UEBwwBLjEWMBQGA1UECgwNaHR0cGxpYjItdGVz +dDEKMAgGA1UECwwBLjEZMBcGA1UEAwwQaHR0cGxpYjItdGVzdC1DQTAeFw0xOTA5 +MjYxNTAzMzRaFw0yOTA5MjMxNTAzMzRaMF0xCzAJBgNVBAYTAlpaMQowCAYDVQQI +DAEuMQowCAYDVQQHDAEuMRYwFAYDVQQKDA1odHRwbGliMi10ZXN0MQowCAYDVQQL +DAEuMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCu9WJEGBARCdyqt+/ip53p+S7N0lKGv0w75LfqVldIQGYMAf9xSMcb +PSTds9rYq8g7XaehNJ628w0hWnHDEU1x28ULMlL22p91inEmWANyi+flCopgUgPe +sQkc+kcXUVv+/Of8eclIXCxni67J8fK7nH/48ML+qdWes9nrtMRB5z/2mC7sc53x +4faJdOpCx13CaHvYPIHJfT7d7haTDBGLVCSC90tB5WvK7E1hIoIddqwrthWopRcS +iSmQfJZmKPgPTtnVX1r3meLEVcdLcZ9OO8r1buUrBdB5Z25K5r0nCYzAk4AyJ1pq +8tjajMwsunbLFOQ6X9DNRCVOG0XDpu0ZAgMBAAEwDQYJKoZIhvcNAQEFBQADggEB +AGVLrbXSANOMZpWevPJUMoZMJ4H26q9+tJ4kVi36ufQOaRBJ19lc73wt/5CL1Zzx +uHBWJSMkUXn3CIXjyV9QsP3YF94yG9LghIKI/0Z+DK5j1TomplS13DZ+JuUIbogZ +gwTXy/EuAxynUO+iyLD3c7/rJO94luWd2Ct9ljv9Kza7LxeEjKloBeGxddWgeU7/ +OdkPzLmvCxAsK/Wk4LAKG0p3ZwIqLdusMl6TBpStntLhh98M5xQXoozmRo8bBlp5 +kjItngdSWKWyXalw93SGEoPhe7u6fAxMBBuEpAtF5DS+mzTHB/wbJz1FuD3f973J +4MeDFTIHtkTp/lYrbSmWvzU= +-----END CERTIFICATE----- diff --git a/tests/tls/server.key b/tests/tls/server.key new file mode 100644 index 0000000..9a1f1dd --- /dev/null +++ b/tests/tls/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEArvViRBgQEQncqrfv4qed6fkuzdJShr9MO+S36lZXSEBmDAH/ +cUjHGz0k3bPa2KvIO12noTSetvMNIVpxwxFNcdvFCzJS9tqfdYpxJlgDcovn5QqK +YFID3rEJHPpHF1Fb/vzn/HnJSFwsZ4uuyfHyu5x/+PDC/qnVnrPZ67TEQec/9pgu +7HOd8eH2iXTqQsddwmh72DyByX0+3e4WkwwRi1QkgvdLQeVryuxNYSKCHXasK7YV +qKUXEokpkHyWZij4D07Z1V9a95nixFXHS3GfTjvK9W7lKwXQeWduSua9JwmMwJOA +MidaavLY2ozMLLp2yxTkOl/QzUQlThtFw6btGQIDAQABAoIBAFyq69lVRW1A4/go +ZI6QaTu8F+Y8OCnWuPIgOqmMAb7rHSHPDRVbjtoGkLg8wvVwRyXqfRcNX+NW6OV5 +mjfPuk1MMhm0Fe1Z7ou7QCMnCuxo3fKamqBZ0GLrMgB/L5hSJ3/vRJCdkNcauwo9 +Gd8sn3xvb/jSzPVFzze32vzVSf39NSxcLRGnMb1Y/1U5jA7Bc+XbPb1fvWJ9ZJec +o5wz0VLNWgYEt3dnvWZOf1ONx50ROwlKFOPhdYg/IQxzkWxOu6ZcleJrJsf5eCvj +o2Ogm6bWMhTO73MYjHD0+hR6xl3g/vIBe+N4e4LmnI7BBQRe9SKrazqBt35/5Zs5 +IKFDPAECgYEA5M2sI7dnbHK1Ur+AIGEan3sWtbXOvg0xihCXRojE5oSKC5BFf5ny +LvZ/VcszhjFv6ruUunXtN8qXJ8n3QQQXyuEeKpkGCvJqE8inREKSTexLj06niU1r +w4XyyEvIckz42sv2k0mwH7qCIwAMkAQtqnM/ue2aCuyKKP5OLqqlSskCgYEAw8E/ +3zWbLwtWb6VtyaSv9/xHL71SXkxpY9FIc7MFhQLnvR6ZgZS42fXopeo04Byx6cZ3 +3QM8UPYE77H0ch3r1HdZIIXLw2aX8SnZtHtchU50cdmhCV51D6dk/bftxgncFzxp +nHRwoPhJTXF/y0+jNP8m5Tn5YgxzJ9Sec7WuZ9ECgYEAnFqURMADNA/bKxXkR7wz +xkIGDdyU0DkR3mhiB/hUnbZ641YOuBkKb99Qut8mcZB9C2puQ1Fs7tBJpQ4WId7b +J2/Y/oEdqQNpS+W1sCbR9eAA7ohwYpp+htmVRBzNeJZzBImXEaWsbrI0VhilfRDt +5+nj5Xmh588mxsapxKgmVkkCgYEAhJiaEy/UdgFQA0AjJbsQFwIjlgq/iHBp0tso +IHba/kYBgvD/Oe7rZ3hSplAGkOfe+2McPfC7InwCy/nWgpYR8FEHZig65ZjQwuJ+ +POpyuTlzVsr7ccUxtfDFT7cOsF5tXq/lOb0FrYOA45xF3AmNm5BZYFvsuKWGOyyi +R+6AvIECgYAXQ8Ud5GX0aXm8cRbwLStamooBreeCKQ9plLnXdqiwkjoeqhdHcWzh +M4Cws86fbRSWESqvY3NVJCA5Na9HN0/LH/UlxN8tfrEfv1al/2UXN8zIL1a1uVfK +H9CtL9znc7mJKBODBxDXgdC+QHMdtGwGU5QYTVwlPEBbdM/2JwgBfw== +-----END RSA PRIVATE KEY----- diff --git a/tests/tls/server.pem b/tests/tls/server.pem new file mode 100644 index 0000000..83277c1 --- /dev/null +++ b/tests/tls/server.pem @@ -0,0 +1,47 @@ +-----BEGIN CERTIFICATE----- +MIIDPTCCAiUCCQDiqmqW0b8a7jANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJa +WjEKMAgGA1UECAwBLjEKMAgGA1UEBwwBLjEWMBQGA1UECgwNaHR0cGxpYjItdGVz +dDEKMAgGA1UECwwBLjEZMBcGA1UEAwwQaHR0cGxpYjItdGVzdC1DQTAeFw0xOTA5 +MjYxNTAzMzRaFw0yOTA5MjMxNTAzMzRaMF0xCzAJBgNVBAYTAlpaMQowCAYDVQQI +DAEuMQowCAYDVQQHDAEuMRYwFAYDVQQKDA1odHRwbGliMi10ZXN0MQowCAYDVQQL +DAEuMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCu9WJEGBARCdyqt+/ip53p+S7N0lKGv0w75LfqVldIQGYMAf9xSMcb +PSTds9rYq8g7XaehNJ628w0hWnHDEU1x28ULMlL22p91inEmWANyi+flCopgUgPe +sQkc+kcXUVv+/Of8eclIXCxni67J8fK7nH/48ML+qdWes9nrtMRB5z/2mC7sc53x +4faJdOpCx13CaHvYPIHJfT7d7haTDBGLVCSC90tB5WvK7E1hIoIddqwrthWopRcS +iSmQfJZmKPgPTtnVX1r3meLEVcdLcZ9OO8r1buUrBdB5Z25K5r0nCYzAk4AyJ1pq +8tjajMwsunbLFOQ6X9DNRCVOG0XDpu0ZAgMBAAEwDQYJKoZIhvcNAQEFBQADggEB +AGVLrbXSANOMZpWevPJUMoZMJ4H26q9+tJ4kVi36ufQOaRBJ19lc73wt/5CL1Zzx +uHBWJSMkUXn3CIXjyV9QsP3YF94yG9LghIKI/0Z+DK5j1TomplS13DZ+JuUIbogZ +gwTXy/EuAxynUO+iyLD3c7/rJO94luWd2Ct9ljv9Kza7LxeEjKloBeGxddWgeU7/ +OdkPzLmvCxAsK/Wk4LAKG0p3ZwIqLdusMl6TBpStntLhh98M5xQXoozmRo8bBlp5 +kjItngdSWKWyXalw93SGEoPhe7u6fAxMBBuEpAtF5DS+mzTHB/wbJz1FuD3f973J +4MeDFTIHtkTp/lYrbSmWvzU= +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEArvViRBgQEQncqrfv4qed6fkuzdJShr9MO+S36lZXSEBmDAH/ +cUjHGz0k3bPa2KvIO12noTSetvMNIVpxwxFNcdvFCzJS9tqfdYpxJlgDcovn5QqK +YFID3rEJHPpHF1Fb/vzn/HnJSFwsZ4uuyfHyu5x/+PDC/qnVnrPZ67TEQec/9pgu +7HOd8eH2iXTqQsddwmh72DyByX0+3e4WkwwRi1QkgvdLQeVryuxNYSKCHXasK7YV +qKUXEokpkHyWZij4D07Z1V9a95nixFXHS3GfTjvK9W7lKwXQeWduSua9JwmMwJOA +MidaavLY2ozMLLp2yxTkOl/QzUQlThtFw6btGQIDAQABAoIBAFyq69lVRW1A4/go +ZI6QaTu8F+Y8OCnWuPIgOqmMAb7rHSHPDRVbjtoGkLg8wvVwRyXqfRcNX+NW6OV5 +mjfPuk1MMhm0Fe1Z7ou7QCMnCuxo3fKamqBZ0GLrMgB/L5hSJ3/vRJCdkNcauwo9 +Gd8sn3xvb/jSzPVFzze32vzVSf39NSxcLRGnMb1Y/1U5jA7Bc+XbPb1fvWJ9ZJec +o5wz0VLNWgYEt3dnvWZOf1ONx50ROwlKFOPhdYg/IQxzkWxOu6ZcleJrJsf5eCvj +o2Ogm6bWMhTO73MYjHD0+hR6xl3g/vIBe+N4e4LmnI7BBQRe9SKrazqBt35/5Zs5 +IKFDPAECgYEA5M2sI7dnbHK1Ur+AIGEan3sWtbXOvg0xihCXRojE5oSKC5BFf5ny +LvZ/VcszhjFv6ruUunXtN8qXJ8n3QQQXyuEeKpkGCvJqE8inREKSTexLj06niU1r +w4XyyEvIckz42sv2k0mwH7qCIwAMkAQtqnM/ue2aCuyKKP5OLqqlSskCgYEAw8E/ +3zWbLwtWb6VtyaSv9/xHL71SXkxpY9FIc7MFhQLnvR6ZgZS42fXopeo04Byx6cZ3 +3QM8UPYE77H0ch3r1HdZIIXLw2aX8SnZtHtchU50cdmhCV51D6dk/bftxgncFzxp +nHRwoPhJTXF/y0+jNP8m5Tn5YgxzJ9Sec7WuZ9ECgYEAnFqURMADNA/bKxXkR7wz +xkIGDdyU0DkR3mhiB/hUnbZ641YOuBkKb99Qut8mcZB9C2puQ1Fs7tBJpQ4WId7b +J2/Y/oEdqQNpS+W1sCbR9eAA7ohwYpp+htmVRBzNeJZzBImXEaWsbrI0VhilfRDt +5+nj5Xmh588mxsapxKgmVkkCgYEAhJiaEy/UdgFQA0AjJbsQFwIjlgq/iHBp0tso +IHba/kYBgvD/Oe7rZ3hSplAGkOfe+2McPfC7InwCy/nWgpYR8FEHZig65ZjQwuJ+ +POpyuTlzVsr7ccUxtfDFT7cOsF5tXq/lOb0FrYOA45xF3AmNm5BZYFvsuKWGOyyi +R+6AvIECgYAXQ8Ud5GX0aXm8cRbwLStamooBreeCKQ9plLnXdqiwkjoeqhdHcWzh +M4Cws86fbRSWESqvY3NVJCA5Na9HN0/LH/UlxN8tfrEfv1al/2UXN8zIL1a1uVfK +H9CtL9znc7mJKBODBxDXgdC+QHMdtGwGU5QYTVwlPEBbdM/2JwgBfw== +-----END RSA PRIVATE KEY----- diff --git a/tests/tls/server_chain.pem b/tests/tls/server_chain.pem new file mode 100644 index 0000000..d590275 --- /dev/null +++ b/tests/tls/server_chain.pem @@ -0,0 +1,67 @@ +-----BEGIN CERTIFICATE----- +MIIDPTCCAiUCCQDiqmqW0b8a7jANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJa +WjEKMAgGA1UECAwBLjEKMAgGA1UEBwwBLjEWMBQGA1UECgwNaHR0cGxpYjItdGVz +dDEKMAgGA1UECwwBLjEZMBcGA1UEAwwQaHR0cGxpYjItdGVzdC1DQTAeFw0xOTA5 +MjYxNTAzMzRaFw0yOTA5MjMxNTAzMzRaMF0xCzAJBgNVBAYTAlpaMQowCAYDVQQI +DAEuMQowCAYDVQQHDAEuMRYwFAYDVQQKDA1odHRwbGliMi10ZXN0MQowCAYDVQQL +DAEuMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCu9WJEGBARCdyqt+/ip53p+S7N0lKGv0w75LfqVldIQGYMAf9xSMcb +PSTds9rYq8g7XaehNJ628w0hWnHDEU1x28ULMlL22p91inEmWANyi+flCopgUgPe +sQkc+kcXUVv+/Of8eclIXCxni67J8fK7nH/48ML+qdWes9nrtMRB5z/2mC7sc53x +4faJdOpCx13CaHvYPIHJfT7d7haTDBGLVCSC90tB5WvK7E1hIoIddqwrthWopRcS +iSmQfJZmKPgPTtnVX1r3meLEVcdLcZ9OO8r1buUrBdB5Z25K5r0nCYzAk4AyJ1pq +8tjajMwsunbLFOQ6X9DNRCVOG0XDpu0ZAgMBAAEwDQYJKoZIhvcNAQEFBQADggEB +AGVLrbXSANOMZpWevPJUMoZMJ4H26q9+tJ4kVi36ufQOaRBJ19lc73wt/5CL1Zzx +uHBWJSMkUXn3CIXjyV9QsP3YF94yG9LghIKI/0Z+DK5j1TomplS13DZ+JuUIbogZ +gwTXy/EuAxynUO+iyLD3c7/rJO94luWd2Ct9ljv9Kza7LxeEjKloBeGxddWgeU7/ +OdkPzLmvCxAsK/Wk4LAKG0p3ZwIqLdusMl6TBpStntLhh98M5xQXoozmRo8bBlp5 +kjItngdSWKWyXalw93SGEoPhe7u6fAxMBBuEpAtF5DS+mzTHB/wbJz1FuD3f973J +4MeDFTIHtkTp/lYrbSmWvzU= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDRDCCAiwCCQC5E5PSm8flUjANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQGEwJa +WjEKMAgGA1UECAwBLjEKMAgGA1UEBwwBLjEWMBQGA1UECgwNaHR0cGxpYjItdGVz +dDEKMAgGA1UECwwBLjEZMBcGA1UEAwwQaHR0cGxpYjItdGVzdC1DQTAeFw0xOTA5 +MjYxNTAzMzRaFw0yOTA5MjMxNTAzMzRaMGQxCzAJBgNVBAYTAlpaMQowCAYDVQQI +DAEuMQowCAYDVQQHDAEuMRYwFAYDVQQKDA1odHRwbGliMi10ZXN0MQowCAYDVQQL +DAEuMRkwFwYDVQQDDBBodHRwbGliMi10ZXN0LUNBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAxBKerwr0M3230xWKMvxB20+AR9SojbQIN2/8EI9pbSrj +mlTHPFXWf02q2Ll0GPbcnSKOMnAARptVCkxEfkDGPN03Ux0jjGu2MrwZHURXM2gH +sQn33Gj3HCreFLMxIqMFfGeB9T0VxurgUek/+bR85QBVNE9GrQfrAN8O+ScOpCOE +Nh5rlYc/QscH/S0QJvttbGAZFP1bB/Xjltwd6fF3rZgCfTJ88B2UIcEVt+X/kc/0 +QByPPACAnCaE4cB2q+SJVEMYP6BLDVvCPRO53UC8cqsLfpKUz73two/No4PhMHwC +PspC+wKlAD3+GWmsatz0rRysm7V0GghCGe+T5JHsGwIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQB4b+DWt0An4YoXj7lb/+N7FVr2m5UVyBI+bbEGI/qsql/Ixiaef69M +jej7n5ucUx8GBql62W0c3/E3qZFfo49ngH1WC5gkKQH9V4jGZui5CUfmNE6WepQ/ +vL6eKXUp7RoJ/hWVhGm1uV3OShF+EN0t2wZttYg4lip0FjrY8tRWdjw5yu61wWVu +WuHxTzKiHe9emjhhUBgnWRnNeYPTRs0xM2Awv5KYPq2cmrjGbSz3mYDkBpbiJUp4 +pM9g8qLmsDO2yrlVF659D08+5zkmMbyqnn84X0n3SM3Yn0ayZOmbNHiXoAzklZNP +7xiyxMEAfVQOITsvSDG2PzbZlGGtbaka +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEArvViRBgQEQncqrfv4qed6fkuzdJShr9MO+S36lZXSEBmDAH/ +cUjHGz0k3bPa2KvIO12noTSetvMNIVpxwxFNcdvFCzJS9tqfdYpxJlgDcovn5QqK +YFID3rEJHPpHF1Fb/vzn/HnJSFwsZ4uuyfHyu5x/+PDC/qnVnrPZ67TEQec/9pgu +7HOd8eH2iXTqQsddwmh72DyByX0+3e4WkwwRi1QkgvdLQeVryuxNYSKCHXasK7YV +qKUXEokpkHyWZij4D07Z1V9a95nixFXHS3GfTjvK9W7lKwXQeWduSua9JwmMwJOA +MidaavLY2ozMLLp2yxTkOl/QzUQlThtFw6btGQIDAQABAoIBAFyq69lVRW1A4/go +ZI6QaTu8F+Y8OCnWuPIgOqmMAb7rHSHPDRVbjtoGkLg8wvVwRyXqfRcNX+NW6OV5 +mjfPuk1MMhm0Fe1Z7ou7QCMnCuxo3fKamqBZ0GLrMgB/L5hSJ3/vRJCdkNcauwo9 +Gd8sn3xvb/jSzPVFzze32vzVSf39NSxcLRGnMb1Y/1U5jA7Bc+XbPb1fvWJ9ZJec +o5wz0VLNWgYEt3dnvWZOf1ONx50ROwlKFOPhdYg/IQxzkWxOu6ZcleJrJsf5eCvj +o2Ogm6bWMhTO73MYjHD0+hR6xl3g/vIBe+N4e4LmnI7BBQRe9SKrazqBt35/5Zs5 +IKFDPAECgYEA5M2sI7dnbHK1Ur+AIGEan3sWtbXOvg0xihCXRojE5oSKC5BFf5ny +LvZ/VcszhjFv6ruUunXtN8qXJ8n3QQQXyuEeKpkGCvJqE8inREKSTexLj06niU1r +w4XyyEvIckz42sv2k0mwH7qCIwAMkAQtqnM/ue2aCuyKKP5OLqqlSskCgYEAw8E/ +3zWbLwtWb6VtyaSv9/xHL71SXkxpY9FIc7MFhQLnvR6ZgZS42fXopeo04Byx6cZ3 +3QM8UPYE77H0ch3r1HdZIIXLw2aX8SnZtHtchU50cdmhCV51D6dk/bftxgncFzxp +nHRwoPhJTXF/y0+jNP8m5Tn5YgxzJ9Sec7WuZ9ECgYEAnFqURMADNA/bKxXkR7wz +xkIGDdyU0DkR3mhiB/hUnbZ641YOuBkKb99Qut8mcZB9C2puQ1Fs7tBJpQ4WId7b +J2/Y/oEdqQNpS+W1sCbR9eAA7ohwYpp+htmVRBzNeJZzBImXEaWsbrI0VhilfRDt +5+nj5Xmh588mxsapxKgmVkkCgYEAhJiaEy/UdgFQA0AjJbsQFwIjlgq/iHBp0tso +IHba/kYBgvD/Oe7rZ3hSplAGkOfe+2McPfC7InwCy/nWgpYR8FEHZig65ZjQwuJ+ +POpyuTlzVsr7ccUxtfDFT7cOsF5tXq/lOb0FrYOA45xF3AmNm5BZYFvsuKWGOyyi +R+6AvIECgYAXQ8Ud5GX0aXm8cRbwLStamooBreeCKQ9plLnXdqiwkjoeqhdHcWzh +M4Cws86fbRSWESqvY3NVJCA5Na9HN0/LH/UlxN8tfrEfv1al/2UXN8zIL1a1uVfK +H9CtL9znc7mJKBODBxDXgdC+QHMdtGwGU5QYTVwlPEBbdM/2JwgBfw== +-----END RSA PRIVATE KEY----- |