Skip to content

Commit d975630

Browse files
committed
test: validate that TLS v1.2 in the minimum required version
Signed-off-by: Norbert Biczo <[email protected]>
1 parent d772f78 commit d975630

File tree

1 file changed

+82
-56
lines changed

1 file changed

+82
-56
lines changed

test/test_http_adapter.py

Lines changed: 82 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import threading
44
import warnings
55
from http.server import HTTPServer, SimpleHTTPRequestHandler
6-
from ssl import PROTOCOL_TLS_SERVER, SSLContext
6+
from ssl import SSLContext, PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2
7+
from typing import Callable
78

89
import pytest
910
import urllib3
@@ -23,59 +24,84 @@
2324
"""
2425

2526

26-
def test_ssl_verification():
27-
# Disable warnings caused by the self-signed certificate.
28-
urllib3.disable_warnings()
29-
30-
# Load the certificate and the key files.
31-
cert = os.path.join(os.path.dirname(__file__), '../resources/test_ssl.crt')
32-
key = os.path.join(os.path.dirname(__file__), '../resources/test_ssl.key')
33-
34-
# Build the SSL context for the server.
35-
ssl_context = SSLContext(PROTOCOL_TLS_SERVER)
36-
ssl_context.load_cert_chain(certfile=cert, keyfile=key)
37-
38-
# Create and start the server on a separate thread.
39-
server = HTTPServer(('localhost', 3333), SimpleHTTPRequestHandler)
40-
server.socket = ssl_context.wrap_socket(server.socket, server_side=True)
41-
t = threading.Thread(target=server.serve_forever)
42-
t.start()
43-
44-
# We run everything in a big try-except-finally block to make sure we always
45-
# shutdown the HTTP server gracefully.
46-
try:
47-
service = BaseService(service_url='https://localhost:3333', authenticator=NoAuthAuthenticator())
48-
#
49-
# First call the server with the default configuration.
50-
# It should fail due to the self-signed SSL cert.
51-
assert service.disable_ssl_verification is False
52-
prepped = service.prepare_request('GET', url='/')
53-
with pytest.raises(SSLError, match="certificate verify failed: self-signed certificate"):
54-
res = service.send(prepped)
55-
56-
# Next configure it to validate by using our local certificate. Should raise no exception.
57-
res = service.send(prepped, verify=cert)
58-
assert res is not None
59-
60-
# Now disable the SSL verification. The request shouldn't raise any issue.
61-
service.set_disable_ssl_verification(True)
62-
assert service.disable_ssl_verification is True
63-
prepped = service.prepare_request('GET', url='/')
64-
res = service.send(prepped)
65-
assert res is not None
66-
67-
# Lastly, try with an external URL.
68-
# This test case is mainly here to reproduce the regression
69-
# in the `requests` package that was introduced in `2.32.3`.
70-
# More details on the issue can be found here: https://github.com/psf/requests/issues/6730
71-
service = BaseService(service_url='https://raw.githubusercontent.com', authenticator=NoAuthAuthenticator())
72-
assert service.disable_ssl_verification is False
73-
prepped = service.prepare_request('GET', url='/IBM/python-sdk-core/main/README.md')
27+
# Load the certificate and the key files.
28+
cert = os.path.join(os.path.dirname(__file__), '../resources/test_ssl.crt')
29+
key = os.path.join(os.path.dirname(__file__), '../resources/test_ssl.key')
30+
31+
32+
def _local_server(tls_version: int, port: int) -> Callable:
33+
def decorator(test_function: Callable) -> Callable:
34+
def inner():
35+
# Disable warnings caused by the self-signed certificate.
36+
urllib3.disable_warnings()
37+
38+
# Build the SSL context for the server.
39+
ssl_context = SSLContext(tls_version)
40+
ssl_context.load_cert_chain(certfile=cert, keyfile=key)
41+
42+
# Create and start the server on a separate thread.
43+
server = HTTPServer(('localhost', port), SimpleHTTPRequestHandler)
44+
server.socket = ssl_context.wrap_socket(server.socket, server_side=True)
45+
t = threading.Thread(target=server.serve_forever)
46+
t.start()
47+
48+
# We run everything in a big try-except-finally block to make sure we always
49+
# shutdown the HTTP server gracefully.
50+
try:
51+
test_function()
52+
except Exception: # pylint: disable=try-except-raise
53+
raise
54+
finally:
55+
server.shutdown()
56+
t.join()
57+
# Re-enable warnings.
58+
warnings.resetwarnings()
59+
60+
return inner
61+
62+
return decorator
63+
64+
65+
@_local_server(PROTOCOL_TLSv1_1, 3333)
66+
def test_tls_v1_1():
67+
service = BaseService(service_url='https://localhost:3333', authenticator=NoAuthAuthenticator())
68+
prepped = service.prepare_request('GET', url='/')
69+
# The following request should fail, because the server will try
70+
# to use TLS v1.1 but that's not allowed in our client.
71+
with pytest.raises(Exception) as exception:
72+
service.send(prepped, verify=cert)
73+
# Errors can be differ based on the Python version.
74+
assert exception.type is SSLError or exception.type is ConnectionError
75+
76+
77+
@_local_server(PROTOCOL_TLSv1_2, 3334)
78+
def test_tls_v1_2():
79+
service = BaseService(service_url='https://localhost:3334', authenticator=NoAuthAuthenticator())
80+
81+
# First call the server with the default configuration.
82+
# It should fail due to the self-signed SSL cert.
83+
assert service.disable_ssl_verification is False
84+
prepped = service.prepare_request('GET', url='/')
85+
with pytest.raises(SSLError, match='certificate verify failed: self-signed certificate'):
7486
res = service.send(prepped)
75-
assert res is not None
76-
except Exception: # pylint: disable=try-except-raise
77-
raise
78-
finally:
79-
server.shutdown()
80-
# Re-enable warnings.
81-
warnings.resetwarnings()
87+
88+
# Next configure it to validate by using our local certificate. Should raise no exception.
89+
res = service.send(prepped, verify=cert)
90+
assert res is not None
91+
92+
# Now disable the SSL verification. The request shouldn't raise any issue.
93+
service.set_disable_ssl_verification(True)
94+
assert service.disable_ssl_verification is True
95+
prepped = service.prepare_request('GET', url='/')
96+
res = service.send(prepped)
97+
assert res is not None
98+
99+
# Lastly, try with an external URL.
100+
# This test case is mainly here to reproduce the regression
101+
# in the `requests` package that was introduced in `2.32.3`.
102+
# More details on the issue can be found here: https://github.com/psf/requests/issues/6730
103+
service = BaseService(service_url='https://raw.githubusercontent.com', authenticator=NoAuthAuthenticator())
104+
assert service.disable_ssl_verification is False
105+
prepped = service.prepare_request('GET', url='/IBM/python-sdk-core/main/README.md')
106+
res = service.send(prepped)
107+
assert res is not None

0 commit comments

Comments
 (0)