Merge pull request #903 from pimutils/fix-old-ssl-tests

Fix SSL tests failing due to old weak MDs
This commit is contained in:
Hugo Osvaldo Barrera 2021-06-26 13:01:17 +02:00 committed by GitHub
commit 25435ce11d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 14 deletions

View file

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

View file

@ -18,6 +18,9 @@ Version 0.19.0
- Add a new "showconfig" status. This prints *some* configuration values as - 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 JSON. This is intended to be used by external tools and helpers that interact
with ``vdirsyncer``. 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 Version 0.18.0
============== ==============

View file

@ -1,4 +1,5 @@
hypothesis>=5.0.0,<7.0.0 hypothesis>=5.0.0,<7.0.0
pytest pytest
pytest-cov 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 click_log
import pytest import pytest
import requests import requests
from cryptography import x509
from cryptography.hazmat.primitives import hashes
from vdirsyncer import http from vdirsyncer import http
from vdirsyncer import utils from vdirsyncer import utils
@ -38,27 +40,55 @@ def _fingerprints_broken():
return broken_urllib3 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( @pytest.mark.skipif(
_fingerprints_broken(), reason="https://github.com/shazow/urllib3/issues/529" _fingerprints_broken(), reason="https://github.com/shazow/urllib3/issues/529"
) )
@pytest.mark.parametrize( @pytest.mark.parametrize("hash_algorithm", [hashes.MD5, hashes.SHA256])
"fingerprint", def test_request_ssl_leaf_fingerprint(httpserver, localhost_cert, hash_algorithm):
[ fingerprint = fingerprint_of_cert(localhost_cert.cert_chain_pems[0], hash_algorithm)
"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
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: 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: with pytest.raises(requests.exceptions.ConnectionError) as excinfo:
http.request( http.request(
"GET", "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=False,
verify_fingerprint="".join(reversed(fingerprint)), verify_fingerprint="".join(reversed(fingerprint)),
) )