Fix SSL tests failing due to old weak MDs

Had to drop pytest-localserver, since it's broken and upstream is gone.
This commit is contained in:
Hugo Osvaldo Barrera 2021-06-14 19:58:20 +02:00
parent 59b6e24795
commit 1f6cc6f8be
5 changed files with 75 additions and 14 deletions

View file

@ -17,7 +17,8 @@ packages:
# Test dependencies:
- python-hypothesis
- python-pytest-cov
- python-pytest-localserver
- python-pytest-httpserver
- python-trustme
sources:
- https://github.com/pimutils/vdirsyncer
environment:

View file

@ -18,6 +18,9 @@ Version 0.19.0
- Add a new "showconfig" status. This prints *some* configuration values as
JSON. This is intended to be used by external tools and helpers that interact
with ``vdirsyncer``.
- Update TLS-related tests that were failing due to weak MDs.
- ``pytest-httpserver`` and ``trustme`` are now required for tests.
- ``pytest-localserver`` is no longer required for tests.
Version 0.18.0
==============

View file

@ -1,4 +1,5 @@
hypothesis>=5.0.0,<7.0.0
pytest
pytest-cov
pytest-localserver
pytest-httpserver
trustme

26
tests/system/conftest.py Normal file
View file

@ -0,0 +1,26 @@
import ssl
import pytest
import trustme
@pytest.fixture(scope="session")
def ca():
return trustme.CA()
@pytest.fixture(scope="session")
def localhost_cert(ca):
return ca.issue_cert("localhost")
@pytest.fixture(scope="session")
def httpserver_ssl_context(localhost_cert):
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
crt = localhost_cert.cert_chain_pems[0]
key = localhost_cert.private_key_pem
with crt.tempfile() as crt_file, key.tempfile() as key_file:
context.load_cert_chain(crt_file, key_file)
return context

View file

@ -4,6 +4,8 @@ import sys
import click_log
import pytest
import requests
from cryptography import x509
from cryptography.hazmat.primitives import hashes
from vdirsyncer import http
from vdirsyncer import utils
@ -38,27 +40,55 @@ def _fingerprints_broken():
return broken_urllib3
def fingerprint_of_cert(cert, hash=hashes.SHA256):
return x509.load_pem_x509_certificate(cert.bytes()).fingerprint(hash()).hex()
@pytest.mark.skipif(
_fingerprints_broken(), reason="https://github.com/shazow/urllib3/issues/529"
)
@pytest.mark.parametrize(
"fingerprint",
[
"94:FD:7A:CB:50:75:A4:69:82:0A:F8:23:DF:07:FC:69:3E:CD:90:CA",
"19:90:F7:23:94:F2:EF:AB:2B:64:2D:57:3D:25:95:2D",
],
)
def test_request_ssl_fingerprints(httpsserver, fingerprint):
httpsserver.serve_content("") # we need to serve something
@pytest.mark.parametrize("hash_algorithm", [hashes.MD5, hashes.SHA256])
def test_request_ssl_leaf_fingerprint(httpserver, localhost_cert, hash_algorithm):
fingerprint = fingerprint_of_cert(localhost_cert.cert_chain_pems[0], hash_algorithm)
http.request("GET", httpsserver.url, verify=False, verify_fingerprint=fingerprint)
# We have to serve something:
httpserver.expect_request("/").respond_with_data("OK")
url = f"https://{httpserver.host}:{httpserver.port}/"
http.request("GET", url, verify=False, verify_fingerprint=fingerprint)
with pytest.raises(requests.exceptions.ConnectionError) as excinfo:
http.request("GET", httpsserver.url, verify_fingerprint=fingerprint)
http.request("GET", url, verify_fingerprint=fingerprint)
with pytest.raises(requests.exceptions.ConnectionError) as excinfo:
http.request(
"GET",
httpsserver.url,
url,
verify=False,
verify_fingerprint="".join(reversed(fingerprint)),
)
assert "Fingerprints did not match" in str(excinfo.value)
@pytest.mark.skipif(
_fingerprints_broken(), reason="https://github.com/shazow/urllib3/issues/529"
)
@pytest.mark.xfail(reason="Not implemented")
@pytest.mark.parametrize("hash_algorithm", [hashes.MD5, hashes.SHA256])
def test_request_ssl_ca_fingerprint(httpserver, ca, hash_algorithm):
fingerprint = fingerprint_of_cert(ca.cert_pem)
# We have to serve something:
httpserver.expect_request("/").respond_with_data("OK")
url = f"https://{httpserver.host}:{httpserver.port}/"
http.request("GET", url, verify=False, verify_fingerprint=fingerprint)
with pytest.raises(requests.exceptions.ConnectionError) as excinfo:
http.request("GET", url, verify_fingerprint=fingerprint)
with pytest.raises(requests.exceptions.ConnectionError) as excinfo:
http.request(
"GET",
url,
verify=False,
verify_fingerprint="".join(reversed(fingerprint)),
)