Skip to content

Commit

Permalink
Fix SSL tests failing due to old weak MDs
Browse files Browse the repository at this point in the history
Had to drop pytest-localserver, since it's broken and upstream is gone.
  • Loading branch information
Hugo Osvaldo Barrera committed Jun 20, 2021
1 parent 59b6e24 commit 1f6cc6f
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 13 deletions.
3 changes: 2 additions & 1 deletion .builds/archlinux.yaml
Expand Up @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Expand Up @@ -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
==============
Expand Down
3 changes: 2 additions & 1 deletion test-requirements.txt
@@ -1,4 +1,5 @@
hypothesis>=5.0.0,<7.0.0
pytest
pytest-cov
pytest-localserver
pytest-httpserver
trustme
26 changes: 26 additions & 0 deletions tests/system/conftest.py
@@ -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
52 changes: 41 additions & 11 deletions tests/system/utils/test_main.py
Expand Up @@ -4,6 +4,8 @@
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
Expand Down Expand Up @@ -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",
],
@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)

# 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)),
)
assert "Fingerprints did not match" in str(excinfo.value)


@pytest.mark.skipif(
_fingerprints_broken(), reason="https://github.com/shazow/urllib3/issues/529"
)
def test_request_ssl_fingerprints(httpsserver, fingerprint):
httpsserver.serve_content("") # we need to serve something
@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", httpsserver.url, verify=False, verify_fingerprint=fingerprint)
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)),
)
Expand Down

0 comments on commit 1f6cc6f

Please sign in to comment.