Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/truststore/_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,12 @@ def _verify_peercerts(
pass

cert_bytes = _get_unverified_chain_bytes(sslobj)

# If the peer didn't send any certificates then
# we can't do verification. Raise an error.
if not cert_bytes:
raise ssl.SSLCertVerificationError("Peer sent no certificates to verify")

_verify_peercerts_impl(
sock_or_sslobj.context, cert_bytes, server_hostname=server_hostname
)
3 changes: 2 additions & 1 deletion src/truststore/_macos.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,8 @@ def _verify_peercerts_impl(
cert_chain: list[bytes],
server_hostname: str | None = None,
) -> None:
certs = None
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

certs = None defined below, too.

"""Verify the cert_chain from the server using macOS APIs."""

policies = None
trust = None
try:
Expand Down
5 changes: 0 additions & 5 deletions src/truststore/_windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,11 +327,6 @@ def _verify_peercerts_impl(
) -> None:
"""Verify the cert_chain from the server using Windows APIs."""

# If the peer didn't send any certificates then
# we can't do verification. Raise an error.
if not cert_chain:
raise ssl.SSLCertVerificationError("Peer sent no certificates to verify")

pCertContext = None
hIntermediateCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, None, 0, None)
try:
Expand Down
27 changes: 27 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from pytest_httpserver import HTTPServer

import truststore
import truststore._api as api
from tests import SSLContextAdapter
from tests.conftest import decorator_requires_internet

Expand Down Expand Up @@ -452,3 +453,29 @@ def test_macos_10_7_import_error():
importlib.reload(truststore._macos)

assert str(e.value) == "Only OS X 10.8 and newer are supported, not 10.7"


@pytest.mark.parametrize("empty_value", [None, []])
def test_verify_peercerts_no_cert_chain_raises(monkeypatch, empty_value):
# Simulate no certs returned from peer
monkeypatch.setattr(api, "_get_unverified_chain_bytes", lambda sslobj: empty_value)

# Track whether impl gets called (it shouldn't)
called = False

def fake_impl(*args, **kwargs):
nonlocal called
called = True

monkeypatch.setattr(api, "_verify_peercerts_impl", fake_impl)

class DummySSLObject:
def __init__(self):
self.context = object()

sslobj = DummySSLObject()

with pytest.raises(ssl.SSLCertVerificationError, match="Peer sent no certificates"):
api._verify_peercerts(sslobj, server_hostname="example.com")

assert called is False
Loading