Skip to content

Commit

Permalink
Skip TLS versions if disabled by OpenSSL config
Browse files Browse the repository at this point in the history
  • Loading branch information
sethmlarson committed Nov 5, 2020
1 parent 5eb604f commit 6dc3b68
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 36 deletions.
28 changes: 0 additions & 28 deletions test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,34 +268,6 @@ def wrapper(*args, **kwargs):
return wrapper


def requiresTLSv1():
"""Test requires TLSv1 available"""
return pytest.mark.skipif(
not hasattr(ssl, "PROTOCOL_TLSv1"), reason="Test requires TLSv1"
)


def requiresTLSv1_1():
"""Test requires TLSv1.1 available"""
return pytest.mark.skipif(
not hasattr(ssl, "PROTOCOL_TLSv1_1"), reason="Test requires TLSv1.1"
)


def requiresTLSv1_2():
"""Test requires TLSv1.2 available"""
return pytest.mark.skipif(
not hasattr(ssl, "PROTOCOL_TLSv1_2"), reason="Test requires TLSv1.2"
)


def requiresTLSv1_3():
"""Test requires TLSv1.3 available"""
return pytest.mark.skipif(
not getattr(ssl, "HAS_TLSv1_3", False), reason="Test requires TLSv1.3"
)


def resolvesLocalhostFQDN(test):
"""Test requires successful resolving of 'localhost.'"""

Expand Down
68 changes: 68 additions & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import collections
import contextlib
import platform
import socket
import ssl
import sys
import threading

Expand All @@ -10,6 +12,8 @@

from dummyserver.handlers import TestingApp
from dummyserver.server import HAS_IPV6, run_tornado_app
from dummyserver.testcase import HTTPSDummyServerTestCase
from urllib3.util import ssl_

from .tz_stub import stub_timezone_ctx

Expand Down Expand Up @@ -106,3 +110,67 @@ def stub_timezone(request):
"""
with stub_timezone_ctx(request.param):
yield


@pytest.fixture(scope="session")
def supported_tls_versions():
# We have to create an actual TLS connection
# to test if the TLS version is not disabled by
# OpenSSL config. Ubuntu 20.04 specifically
# disables TLSv1 and TLSv1.1.
tls_versions = set()

_server = HTTPSDummyServerTestCase()
_server._start_server()
for _ssl_version_name in (
"PROTOCOL_TLSv1",
"PROTOCOL_TLSv1_1",
"PROTOCOL_TLSv1_2",
"PROTOCOL_TLS",
):
_ssl_version = getattr(ssl, _ssl_version_name, 0)
if _ssl_version == 0:
continue
_sock = socket.create_connection((_server.host, _server.port))
try:
_sock = ssl_.ssl_wrap_socket(
_sock, cert_reqs=ssl.CERT_NONE, ssl_version=_ssl_version
)
except ssl.SSLError:
pass
else:
tls_versions.add(_sock.version())
_sock.close()
_server._stop_server()
return tls_versions


@pytest.fixture(scope="function")
def requires_tlsv1(supported_tls_versions):
"""Test requires TLSv1 available"""
if not hasattr(ssl, "PROTOCOL_TLSv1") or "TLSv1" not in supported_tls_versions:
pytest.skip("Test requires TLSv1")


@pytest.fixture(scope="function")
def requires_tlsv1_1(supported_tls_versions):
"""Test requires TLSv1.1 available"""
if not hasattr(ssl, "PROTOCOL_TLSv1_1") or "TLSv1.1" not in supported_tls_versions:
pytest.skip("Test requires TLSv1.1")


@pytest.fixture(scope="function")
def requires_tlsv1_2(supported_tls_versions):
"""Test requires TLSv1.2 available"""
if not hasattr(ssl, "PROTOCOL_TLSv1_2") or "TLSv1.2" not in supported_tls_versions:
pytest.skip("Test requires TLSv1.2")


@pytest.fixture(scope="function")
def requires_tlsv1_3(supported_tls_versions):
"""Test requires TLSv1.3 available"""
if (
not getattr(ssl, "HAS_TLSv1_3", False)
or "TLSv1.3" not in supported_tls_versions
):
pytest.skip("Test requires TLSv1.3")
12 changes: 4 additions & 8 deletions test/with_dummyserver/test_https.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
onlyPy279OrNewer,
requires_network,
requires_ssl_context_keyfile_password,
requiresTLSv1,
requiresTLSv1_1,
requiresTLSv1_2,
requiresTLSv1_3,
resolvesLocalhostFQDN,
)

Expand Down Expand Up @@ -823,25 +819,25 @@ def test_alpn_default(self):
assert r.data.decode("utf-8") == util.ALPN_PROTOCOLS[0]


@requiresTLSv1()
@pytest.mark.usefixtures("requires_tlsv1")
class TestHTTPS_TLSv1(TestHTTPS):
tls_protocol_name = "TLSv1"
certs = TLSv1_CERTS


@requiresTLSv1_1()
@pytest.mark.usefixtures("requires_tlsv1_1")
class TestHTTPS_TLSv1_1(TestHTTPS):
tls_protocol_name = "TLSv1.1"
certs = TLSv1_1_CERTS


@requiresTLSv1_2()
@pytest.mark.usefixtures("requires_tlsv1_2")
class TestHTTPS_TLSv1_2(TestHTTPS):
tls_protocol_name = "TLSv1.2"
certs = TLSv1_2_CERTS


@requiresTLSv1_3()
@pytest.mark.usefixtures("requires_tlsv1_3")
class TestHTTPS_TLSv1_3(TestHTTPS):
tls_protocol_name = "TLSv1.3"
certs = TLSv1_3_CERTS
Expand Down

0 comments on commit 6dc3b68

Please sign in to comment.