Skip to content

Commit bc84491

Browse files
authored
Revert "Upgrade vendored truststore to 0.9.0" (#12671)
This reverts commit 8547b52.
1 parent 8547b52 commit bc84491

File tree

6 files changed

+36
-52
lines changed

6 files changed

+36
-52
lines changed

news/truststore.vendor.rst

-1
This file was deleted.

src/pip/_vendor/truststore/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@
1010
del _api, _sys # type: ignore[name-defined] # noqa: F821
1111

1212
__all__ = ["SSLContext", "inject_into_ssl", "extract_from_ssl"]
13-
__version__ = "0.9.0"
13+
__version__ = "0.8.0"

src/pip/_vendor/truststore/_api.py

+16-23
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
import platform
33
import socket
44
import ssl
5-
import sys
65
import typing
76

7+
import _ssl # type: ignore[import]
8+
89
from ._ssl_constants import (
910
_original_SSLContext,
1011
_original_super_SSLContext,
@@ -48,7 +49,7 @@ def extract_from_ssl() -> None:
4849
try:
4950
import pip._vendor.urllib3.util.ssl_ as urllib3_ssl
5051

51-
urllib3_ssl.SSLContext = _original_SSLContext # type: ignore[assignment]
52+
urllib3_ssl.SSLContext = _original_SSLContext
5253
except ImportError:
5354
pass
5455

@@ -170,13 +171,16 @@ def cert_store_stats(self) -> dict[str, int]:
170171
@typing.overload
171172
def get_ca_certs(
172173
self, binary_form: typing.Literal[False] = ...
173-
) -> list[typing.Any]: ...
174+
) -> list[typing.Any]:
175+
...
174176

175177
@typing.overload
176-
def get_ca_certs(self, binary_form: typing.Literal[True] = ...) -> list[bytes]: ...
178+
def get_ca_certs(self, binary_form: typing.Literal[True] = ...) -> list[bytes]:
179+
...
177180

178181
@typing.overload
179-
def get_ca_certs(self, binary_form: bool = ...) -> typing.Any: ...
182+
def get_ca_certs(self, binary_form: bool = ...) -> typing.Any:
183+
...
180184

181185
def get_ca_certs(self, binary_form: bool = False) -> list[typing.Any] | list[bytes]:
182186
raise NotImplementedError()
@@ -272,23 +276,6 @@ def verify_mode(self, value: ssl.VerifyMode) -> None:
272276
)
273277

274278

275-
# Python 3.13+ makes get_unverified_chain() a public API that only returns DER
276-
# encoded certificates. We detect whether we need to call public_bytes() for 3.10->3.12
277-
# Pre-3.13 returned None instead of an empty list from get_unverified_chain()
278-
if sys.version_info >= (3, 13):
279-
280-
def _get_unverified_chain_bytes(sslobj: ssl.SSLObject) -> list[bytes]:
281-
unverified_chain = sslobj.get_unverified_chain() or () # type: ignore[attr-defined]
282-
return [cert for cert in unverified_chain]
283-
284-
else:
285-
import _ssl # type: ignore[import-not-found]
286-
287-
def _get_unverified_chain_bytes(sslobj: ssl.SSLObject) -> list[bytes]:
288-
unverified_chain = sslobj.get_unverified_chain() or () # type: ignore[attr-defined]
289-
return [cert.public_bytes(_ssl.ENCODING_DER) for cert in unverified_chain]
290-
291-
292279
def _verify_peercerts(
293280
sock_or_sslobj: ssl.SSLSocket | ssl.SSLObject, server_hostname: str | None
294281
) -> None:
@@ -303,7 +290,13 @@ def _verify_peercerts(
303290
except AttributeError:
304291
pass
305292

306-
cert_bytes = _get_unverified_chain_bytes(sslobj)
293+
# SSLObject.get_unverified_chain() returns 'None'
294+
# if the peer sends no certificates. This is common
295+
# for the server-side scenario.
296+
unverified_chain: typing.Sequence[_ssl.Certificate] = (
297+
sslobj.get_unverified_chain() or () # type: ignore[attr-defined]
298+
)
299+
cert_bytes = [cert.public_bytes(_ssl.ENCODING_DER) for cert in unverified_chain]
307300
_verify_peercerts_impl(
308301
sock_or_sslobj.context, cert_bytes, server_hostname=server_hostname
309302
)

src/pip/_vendor/truststore/_macos.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ def _load_cdll(name: str, macos10_16_path: str) -> CDLL:
9696
Security.SecTrustSetAnchorCertificatesOnly.argtypes = [SecTrustRef, Boolean]
9797
Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus
9898

99+
Security.SecTrustEvaluate.argtypes = [SecTrustRef, POINTER(SecTrustResultType)]
100+
Security.SecTrustEvaluate.restype = OSStatus
101+
99102
Security.SecPolicyCreateRevocation.argtypes = [CFOptionFlags]
100103
Security.SecPolicyCreateRevocation.restype = SecPolicyRef
101104

@@ -256,7 +259,6 @@ def _handle_osstatus(result: OSStatus, _: typing.Any, args: typing.Any) -> typin
256259

257260
Security.SecTrustCreateWithCertificates.errcheck = _handle_osstatus # type: ignore[assignment]
258261
Security.SecTrustSetAnchorCertificates.errcheck = _handle_osstatus # type: ignore[assignment]
259-
Security.SecTrustSetAnchorCertificatesOnly.errcheck = _handle_osstatus # type: ignore[assignment]
260262
Security.SecTrustGetTrustResult.errcheck = _handle_osstatus # type: ignore[assignment]
261263

262264

@@ -415,21 +417,21 @@ def _verify_peercerts_impl(
415417
CoreFoundation.CFRelease(certs)
416418

417419
# If there are additional trust anchors to load we need to transform
418-
# the list of DER-encoded certificates into a CFArray.
420+
# the list of DER-encoded certificates into a CFArray. Otherwise
421+
# pass 'None' to signal that we only want system / fetched certificates.
419422
ctx_ca_certs_der: list[bytes] | None = ssl_context.get_ca_certs(
420423
binary_form=True
421424
)
422425
if ctx_ca_certs_der:
423426
ctx_ca_certs = None
424427
try:
425-
ctx_ca_certs = _der_certs_to_cf_cert_array(ctx_ca_certs_der)
428+
ctx_ca_certs = _der_certs_to_cf_cert_array(cert_chain)
426429
Security.SecTrustSetAnchorCertificates(trust, ctx_ca_certs)
427430
finally:
428431
if ctx_ca_certs:
429432
CoreFoundation.CFRelease(ctx_ca_certs)
430-
431-
# We always want system certificates.
432-
Security.SecTrustSetAnchorCertificatesOnly(trust, False)
433+
else:
434+
Security.SecTrustSetAnchorCertificates(trust, None)
433435

434436
cf_error = CoreFoundation.CFErrorRef()
435437
sec_trust_eval_result = Security.SecTrustEvaluateWithError(

src/pip/_vendor/truststore/_windows.py

+10-20
Original file line numberDiff line numberDiff line change
@@ -325,12 +325,6 @@ def _verify_peercerts_impl(
325325
server_hostname: str | None = None,
326326
) -> None:
327327
"""Verify the cert_chain from the server using Windows APIs."""
328-
329-
# If the peer didn't send any certificates then
330-
# we can't do verification. Raise an error.
331-
if not cert_chain:
332-
raise ssl.SSLCertVerificationError("Peer sent no certificates to verify")
333-
334328
pCertContext = None
335329
hIntermediateCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, None, 0, None)
336330
try:
@@ -381,7 +375,7 @@ def _verify_peercerts_impl(
381375
server_hostname,
382376
chain_flags=chain_flags,
383377
)
384-
except ssl.SSLCertVerificationError as e:
378+
except ssl.SSLCertVerificationError:
385379
# If that fails but custom CA certs have been added
386380
# to the SSLContext using load_verify_locations,
387381
# try verifying using a custom chain engine
@@ -390,19 +384,15 @@ def _verify_peercerts_impl(
390384
binary_form=True
391385
)
392386
if custom_ca_certs:
393-
try:
394-
_verify_using_custom_ca_certs(
395-
ssl_context,
396-
custom_ca_certs,
397-
hIntermediateCertStore,
398-
pCertContext,
399-
pChainPara,
400-
server_hostname,
401-
chain_flags=chain_flags,
402-
)
403-
# Raise the original error, not the new error.
404-
except ssl.SSLCertVerificationError:
405-
raise e from None
387+
_verify_using_custom_ca_certs(
388+
ssl_context,
389+
custom_ca_certs,
390+
hIntermediateCertStore,
391+
pCertContext,
392+
pChainPara,
393+
server_hostname,
394+
chain_flags=chain_flags,
395+
)
406396
else:
407397
raise
408398
finally:

src/pip/_vendor/vendor.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ setuptools==69.1.1
2020
six==1.16.0
2121
tenacity==8.2.3
2222
tomli==2.0.1
23-
truststore==0.9.0
23+
truststore==0.8.0
2424
webencodings==0.5.1

0 commit comments

Comments
 (0)