Fix #125660: Extensions fail to sync HTTPS repositories on WIN32
Workaround: `[ASN1] nested asn1 error` error when making HTTPS connections on systems with certificates that OpenSSL cannot parse are installed. This is a general issue with Python, resolve by applying a proposed fix [0] to the extensions Python process at run-time. (this doesn't impact Blender's Python run-time). The down side is HTTPS connections will only work for extensions on systems with this problem so this needs to be resolved by Python long term. While any changes to Python's SSL checks is worth avoiding, this simply skips SSL certificates in the windows store that OpenSSL can't parse instead of failing all SSL connections. See related issues: - https://github.com/python/cpython/issues/79846 - https://github.com/openssl/openssl/issues/25023 [0]: https://github.com/python/cpython/pull/91740 Ref !124943.
This commit is contained in:
@@ -142,6 +142,45 @@ ${body}
|
||||
'''
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Workarounds
|
||||
|
||||
def _worlaround_win32_ssl_cert_failure() -> None:
|
||||
# Applies workaround by `pukkandan` on GITHUB at run-time:
|
||||
# See: https://github.com/python/cpython/pull/91740
|
||||
import ssl
|
||||
|
||||
class SSLContext_DUMMY(ssl.SSLContext):
|
||||
def _load_windows_store_certs(self, storename: str, purpose: ssl.Purpose) -> bytearray:
|
||||
# WIN32 only.
|
||||
enum_certificates = getattr(ssl, "enum_certificates", None)
|
||||
assert callable(enum_certificates)
|
||||
certs = bytearray()
|
||||
try:
|
||||
for cert, encoding, trust in enum_certificates(storename):
|
||||
try:
|
||||
self.load_verify_locations(cadata=cert)
|
||||
except ssl.SSLError:
|
||||
# warnings.warn("Bad certificate in Windows certificate store")
|
||||
pass
|
||||
else:
|
||||
# CA certs are never PKCS#7 encoded
|
||||
if encoding == "x509_asn":
|
||||
if trust is True or purpose.oid in trust:
|
||||
certs.extend(cert)
|
||||
except PermissionError:
|
||||
# warnings.warn("unable to enumerate Windows certificate store")
|
||||
pass
|
||||
# NOTE(@ideasman42): Python never uses this return value internally.
|
||||
# Keep it for consistency.
|
||||
return certs
|
||||
|
||||
ssl.SSLContext._load_windows_store_certs = SSLContext_DUMMY._load_windows_store_certs # type: ignore
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Argument Overrides
|
||||
|
||||
class _ArgsDefaultOverride:
|
||||
__slots__ = (
|
||||
"build_valid_tags",
|
||||
@@ -155,6 +194,7 @@ class _ArgsDefaultOverride:
|
||||
ARG_DEFAULTS_OVERRIDE = _ArgsDefaultOverride()
|
||||
del _ArgsDefaultOverride
|
||||
|
||||
|
||||
# Standard out may be communicating with a parent process,
|
||||
# arbitrary prints are NOT acceptable.
|
||||
|
||||
@@ -4978,6 +5018,9 @@ def msglog_from_args(args: argparse.Namespace) -> MessageLogger:
|
||||
raise Exception("Unknown output!")
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Main Function
|
||||
|
||||
def main(
|
||||
argv: Optional[List[str]] = None,
|
||||
args_internal: bool = True,
|
||||
@@ -4999,6 +5042,9 @@ def main(
|
||||
sys.stdout.write("{:s}\n".format(VERSION))
|
||||
return 0
|
||||
|
||||
if sys.platform == "win32":
|
||||
_worlaround_win32_ssl_cert_failure()
|
||||
|
||||
parser = argparse_create(
|
||||
args_internal=args_internal,
|
||||
args_extra_subcommands_fn=args_extra_subcommands_fn,
|
||||
|
||||
Reference in New Issue
Block a user