aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/pip/_vendor/truststore/_macos.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/pip/_vendor/truststore/_macos.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are hereHEADmaster
Diffstat (limited to '.venv/lib/python3.12/site-packages/pip/_vendor/truststore/_macos.py')
-rw-r--r--.venv/lib/python3.12/site-packages/pip/_vendor/truststore/_macos.py571
1 files changed, 571 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/pip/_vendor/truststore/_macos.py b/.venv/lib/python3.12/site-packages/pip/_vendor/truststore/_macos.py
new file mode 100644
index 00000000..34503077
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/pip/_vendor/truststore/_macos.py
@@ -0,0 +1,571 @@
+import contextlib
+import ctypes
+import platform
+import ssl
+import typing
+from ctypes import (
+ CDLL,
+ POINTER,
+ c_bool,
+ c_char_p,
+ c_int32,
+ c_long,
+ c_uint32,
+ c_ulong,
+ c_void_p,
+)
+from ctypes.util import find_library
+
+from ._ssl_constants import _set_ssl_context_verify_mode
+
+_mac_version = platform.mac_ver()[0]
+_mac_version_info = tuple(map(int, _mac_version.split(".")))
+if _mac_version_info < (10, 8):
+ raise ImportError(
+ f"Only OS X 10.8 and newer are supported, not {_mac_version_info[0]}.{_mac_version_info[1]}"
+ )
+
+_is_macos_version_10_14_or_later = _mac_version_info >= (10, 14)
+
+
+def _load_cdll(name: str, macos10_16_path: str) -> CDLL:
+ """Loads a CDLL by name, falling back to known path on 10.16+"""
+ try:
+ # Big Sur is technically 11 but we use 10.16 due to the Big Sur
+ # beta being labeled as 10.16.
+ path: str | None
+ if _mac_version_info >= (10, 16):
+ path = macos10_16_path
+ else:
+ path = find_library(name)
+ if not path:
+ raise OSError # Caught and reraised as 'ImportError'
+ return CDLL(path, use_errno=True)
+ except OSError:
+ raise ImportError(f"The library {name} failed to load") from None
+
+
+Security = _load_cdll(
+ "Security", "/System/Library/Frameworks/Security.framework/Security"
+)
+CoreFoundation = _load_cdll(
+ "CoreFoundation",
+ "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation",
+)
+
+Boolean = c_bool
+CFIndex = c_long
+CFStringEncoding = c_uint32
+CFData = c_void_p
+CFString = c_void_p
+CFArray = c_void_p
+CFMutableArray = c_void_p
+CFError = c_void_p
+CFType = c_void_p
+CFTypeID = c_ulong
+CFTypeRef = POINTER(CFType)
+CFAllocatorRef = c_void_p
+
+OSStatus = c_int32
+
+CFErrorRef = POINTER(CFError)
+CFDataRef = POINTER(CFData)
+CFStringRef = POINTER(CFString)
+CFArrayRef = POINTER(CFArray)
+CFMutableArrayRef = POINTER(CFMutableArray)
+CFArrayCallBacks = c_void_p
+CFOptionFlags = c_uint32
+
+SecCertificateRef = POINTER(c_void_p)
+SecPolicyRef = POINTER(c_void_p)
+SecTrustRef = POINTER(c_void_p)
+SecTrustResultType = c_uint32
+SecTrustOptionFlags = c_uint32
+
+try:
+ Security.SecCertificateCreateWithData.argtypes = [CFAllocatorRef, CFDataRef]
+ Security.SecCertificateCreateWithData.restype = SecCertificateRef
+
+ Security.SecCertificateCopyData.argtypes = [SecCertificateRef]
+ Security.SecCertificateCopyData.restype = CFDataRef
+
+ Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p]
+ Security.SecCopyErrorMessageString.restype = CFStringRef
+
+ Security.SecTrustSetAnchorCertificates.argtypes = [SecTrustRef, CFArrayRef]
+ Security.SecTrustSetAnchorCertificates.restype = OSStatus
+
+ Security.SecTrustSetAnchorCertificatesOnly.argtypes = [SecTrustRef, Boolean]
+ Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus
+
+ Security.SecPolicyCreateRevocation.argtypes = [CFOptionFlags]
+ Security.SecPolicyCreateRevocation.restype = SecPolicyRef
+
+ Security.SecPolicyCreateSSL.argtypes = [Boolean, CFStringRef]
+ Security.SecPolicyCreateSSL.restype = SecPolicyRef
+
+ Security.SecTrustCreateWithCertificates.argtypes = [
+ CFTypeRef,
+ CFTypeRef,
+ POINTER(SecTrustRef),
+ ]
+ Security.SecTrustCreateWithCertificates.restype = OSStatus
+
+ Security.SecTrustGetTrustResult.argtypes = [
+ SecTrustRef,
+ POINTER(SecTrustResultType),
+ ]
+ Security.SecTrustGetTrustResult.restype = OSStatus
+
+ Security.SecTrustEvaluate.argtypes = [
+ SecTrustRef,
+ POINTER(SecTrustResultType),
+ ]
+ Security.SecTrustEvaluate.restype = OSStatus
+
+ Security.SecTrustRef = SecTrustRef # type: ignore[attr-defined]
+ Security.SecTrustResultType = SecTrustResultType # type: ignore[attr-defined]
+ Security.OSStatus = OSStatus # type: ignore[attr-defined]
+
+ kSecRevocationUseAnyAvailableMethod = 3
+ kSecRevocationRequirePositiveResponse = 8
+
+ CoreFoundation.CFRelease.argtypes = [CFTypeRef]
+ CoreFoundation.CFRelease.restype = None
+
+ CoreFoundation.CFGetTypeID.argtypes = [CFTypeRef]
+ CoreFoundation.CFGetTypeID.restype = CFTypeID
+
+ CoreFoundation.CFStringCreateWithCString.argtypes = [
+ CFAllocatorRef,
+ c_char_p,
+ CFStringEncoding,
+ ]
+ CoreFoundation.CFStringCreateWithCString.restype = CFStringRef
+
+ CoreFoundation.CFStringGetCStringPtr.argtypes = [CFStringRef, CFStringEncoding]
+ CoreFoundation.CFStringGetCStringPtr.restype = c_char_p
+
+ CoreFoundation.CFStringGetCString.argtypes = [
+ CFStringRef,
+ c_char_p,
+ CFIndex,
+ CFStringEncoding,
+ ]
+ CoreFoundation.CFStringGetCString.restype = c_bool
+
+ CoreFoundation.CFDataCreate.argtypes = [CFAllocatorRef, c_char_p, CFIndex]
+ CoreFoundation.CFDataCreate.restype = CFDataRef
+
+ CoreFoundation.CFDataGetLength.argtypes = [CFDataRef]
+ CoreFoundation.CFDataGetLength.restype = CFIndex
+
+ CoreFoundation.CFDataGetBytePtr.argtypes = [CFDataRef]
+ CoreFoundation.CFDataGetBytePtr.restype = c_void_p
+
+ CoreFoundation.CFArrayCreate.argtypes = [
+ CFAllocatorRef,
+ POINTER(CFTypeRef),
+ CFIndex,
+ CFArrayCallBacks,
+ ]
+ CoreFoundation.CFArrayCreate.restype = CFArrayRef
+
+ CoreFoundation.CFArrayCreateMutable.argtypes = [
+ CFAllocatorRef,
+ CFIndex,
+ CFArrayCallBacks,
+ ]
+ CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef
+
+ CoreFoundation.CFArrayAppendValue.argtypes = [CFMutableArrayRef, c_void_p]
+ CoreFoundation.CFArrayAppendValue.restype = None
+
+ CoreFoundation.CFArrayGetCount.argtypes = [CFArrayRef]
+ CoreFoundation.CFArrayGetCount.restype = CFIndex
+
+ CoreFoundation.CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex]
+ CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p
+
+ CoreFoundation.CFErrorGetCode.argtypes = [CFErrorRef]
+ CoreFoundation.CFErrorGetCode.restype = CFIndex
+
+ CoreFoundation.CFErrorCopyDescription.argtypes = [CFErrorRef]
+ CoreFoundation.CFErrorCopyDescription.restype = CFStringRef
+
+ CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll( # type: ignore[attr-defined]
+ CoreFoundation, "kCFAllocatorDefault"
+ )
+ CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll( # type: ignore[attr-defined]
+ CoreFoundation, "kCFTypeArrayCallBacks"
+ )
+
+ CoreFoundation.CFTypeRef = CFTypeRef # type: ignore[attr-defined]
+ CoreFoundation.CFArrayRef = CFArrayRef # type: ignore[attr-defined]
+ CoreFoundation.CFStringRef = CFStringRef # type: ignore[attr-defined]
+ CoreFoundation.CFErrorRef = CFErrorRef # type: ignore[attr-defined]
+
+except AttributeError as e:
+ raise ImportError(f"Error initializing ctypes: {e}") from None
+
+# SecTrustEvaluateWithError is macOS 10.14+
+if _is_macos_version_10_14_or_later:
+ try:
+ Security.SecTrustEvaluateWithError.argtypes = [
+ SecTrustRef,
+ POINTER(CFErrorRef),
+ ]
+ Security.SecTrustEvaluateWithError.restype = c_bool
+ except AttributeError as e:
+ raise ImportError(f"Error initializing ctypes: {e}") from None
+
+
+def _handle_osstatus(result: OSStatus, _: typing.Any, args: typing.Any) -> typing.Any:
+ """
+ Raises an error if the OSStatus value is non-zero.
+ """
+ if int(result) == 0:
+ return args
+
+ # Returns a CFString which we need to transform
+ # into a UTF-8 Python string.
+ error_message_cfstring = None
+ try:
+ error_message_cfstring = Security.SecCopyErrorMessageString(result, None)
+
+ # First step is convert the CFString into a C string pointer.
+ # We try the fast no-copy way first.
+ error_message_cfstring_c_void_p = ctypes.cast(
+ error_message_cfstring, ctypes.POINTER(ctypes.c_void_p)
+ )
+ message = CoreFoundation.CFStringGetCStringPtr(
+ error_message_cfstring_c_void_p, CFConst.kCFStringEncodingUTF8
+ )
+
+ # Quoting the Apple dev docs:
+ #
+ # "A pointer to a C string or NULL if the internal
+ # storage of theString does not allow this to be
+ # returned efficiently."
+ #
+ # So we need to get our hands dirty.
+ if message is None:
+ buffer = ctypes.create_string_buffer(1024)
+ result = CoreFoundation.CFStringGetCString(
+ error_message_cfstring_c_void_p,
+ buffer,
+ 1024,
+ CFConst.kCFStringEncodingUTF8,
+ )
+ if not result:
+ raise OSError("Error copying C string from CFStringRef")
+ message = buffer.value
+
+ finally:
+ if error_message_cfstring is not None:
+ CoreFoundation.CFRelease(error_message_cfstring)
+
+ # If no message can be found for this status we come
+ # up with a generic one that forwards the status code.
+ if message is None or message == "":
+ message = f"SecureTransport operation returned a non-zero OSStatus: {result}"
+
+ raise ssl.SSLError(message)
+
+
+Security.SecTrustCreateWithCertificates.errcheck = _handle_osstatus # type: ignore[assignment]
+Security.SecTrustSetAnchorCertificates.errcheck = _handle_osstatus # type: ignore[assignment]
+Security.SecTrustSetAnchorCertificatesOnly.errcheck = _handle_osstatus # type: ignore[assignment]
+Security.SecTrustGetTrustResult.errcheck = _handle_osstatus # type: ignore[assignment]
+Security.SecTrustEvaluate.errcheck = _handle_osstatus # type: ignore[assignment]
+
+
+class CFConst:
+ """CoreFoundation constants"""
+
+ kCFStringEncodingUTF8 = CFStringEncoding(0x08000100)
+
+ errSecIncompleteCertRevocationCheck = -67635
+ errSecHostNameMismatch = -67602
+ errSecCertificateExpired = -67818
+ errSecNotTrusted = -67843
+
+
+def _bytes_to_cf_data_ref(value: bytes) -> CFDataRef: # type: ignore[valid-type]
+ return CoreFoundation.CFDataCreate( # type: ignore[no-any-return]
+ CoreFoundation.kCFAllocatorDefault, value, len(value)
+ )
+
+
+def _bytes_to_cf_string(value: bytes) -> CFString:
+ """
+ Given a Python binary data, create a CFString.
+ The string must be CFReleased by the caller.
+ """
+ c_str = ctypes.c_char_p(value)
+ cf_str = CoreFoundation.CFStringCreateWithCString(
+ CoreFoundation.kCFAllocatorDefault,
+ c_str,
+ CFConst.kCFStringEncodingUTF8,
+ )
+ return cf_str # type: ignore[no-any-return]
+
+
+def _cf_string_ref_to_str(cf_string_ref: CFStringRef) -> str | None: # type: ignore[valid-type]
+ """
+ Creates a Unicode string from a CFString object. Used entirely for error
+ reporting.
+ Yes, it annoys me quite a lot that this function is this complex.
+ """
+
+ string = CoreFoundation.CFStringGetCStringPtr(
+ cf_string_ref, CFConst.kCFStringEncodingUTF8
+ )
+ if string is None:
+ buffer = ctypes.create_string_buffer(1024)
+ result = CoreFoundation.CFStringGetCString(
+ cf_string_ref, buffer, 1024, CFConst.kCFStringEncodingUTF8
+ )
+ if not result:
+ raise OSError("Error copying C string from CFStringRef")
+ string = buffer.value
+ if string is not None:
+ string = string.decode("utf-8")
+ return string # type: ignore[no-any-return]
+
+
+def _der_certs_to_cf_cert_array(certs: list[bytes]) -> CFMutableArrayRef: # type: ignore[valid-type]
+ """Builds a CFArray of SecCertificateRefs from a list of DER-encoded certificates.
+ Responsibility of the caller to call CoreFoundation.CFRelease on the CFArray.
+ """
+ cf_array = CoreFoundation.CFArrayCreateMutable(
+ CoreFoundation.kCFAllocatorDefault,
+ 0,
+ ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks),
+ )
+ if not cf_array:
+ raise MemoryError("Unable to allocate memory!")
+
+ for cert_data in certs:
+ cf_data = None
+ sec_cert_ref = None
+ try:
+ cf_data = _bytes_to_cf_data_ref(cert_data)
+ sec_cert_ref = Security.SecCertificateCreateWithData(
+ CoreFoundation.kCFAllocatorDefault, cf_data
+ )
+ CoreFoundation.CFArrayAppendValue(cf_array, sec_cert_ref)
+ finally:
+ if cf_data:
+ CoreFoundation.CFRelease(cf_data)
+ if sec_cert_ref:
+ CoreFoundation.CFRelease(sec_cert_ref)
+
+ return cf_array # type: ignore[no-any-return]
+
+
+@contextlib.contextmanager
+def _configure_context(ctx: ssl.SSLContext) -> typing.Iterator[None]:
+ check_hostname = ctx.check_hostname
+ verify_mode = ctx.verify_mode
+ ctx.check_hostname = False
+ _set_ssl_context_verify_mode(ctx, ssl.CERT_NONE)
+ try:
+ yield
+ finally:
+ ctx.check_hostname = check_hostname
+ _set_ssl_context_verify_mode(ctx, verify_mode)
+
+
+def _verify_peercerts_impl(
+ ssl_context: ssl.SSLContext,
+ cert_chain: list[bytes],
+ server_hostname: str | None = None,
+) -> None:
+ certs = None
+ policies = None
+ trust = None
+ try:
+ # Only set a hostname on the policy if we're verifying the hostname
+ # on the leaf certificate.
+ if server_hostname is not None and ssl_context.check_hostname:
+ cf_str_hostname = None
+ try:
+ cf_str_hostname = _bytes_to_cf_string(server_hostname.encode("ascii"))
+ ssl_policy = Security.SecPolicyCreateSSL(True, cf_str_hostname)
+ finally:
+ if cf_str_hostname:
+ CoreFoundation.CFRelease(cf_str_hostname)
+ else:
+ ssl_policy = Security.SecPolicyCreateSSL(True, None)
+
+ policies = ssl_policy
+ if ssl_context.verify_flags & ssl.VERIFY_CRL_CHECK_CHAIN:
+ # Add explicit policy requiring positive revocation checks
+ policies = CoreFoundation.CFArrayCreateMutable(
+ CoreFoundation.kCFAllocatorDefault,
+ 0,
+ ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks),
+ )
+ CoreFoundation.CFArrayAppendValue(policies, ssl_policy)
+ CoreFoundation.CFRelease(ssl_policy)
+ revocation_policy = Security.SecPolicyCreateRevocation(
+ kSecRevocationUseAnyAvailableMethod
+ | kSecRevocationRequirePositiveResponse
+ )
+ CoreFoundation.CFArrayAppendValue(policies, revocation_policy)
+ CoreFoundation.CFRelease(revocation_policy)
+ elif ssl_context.verify_flags & ssl.VERIFY_CRL_CHECK_LEAF:
+ raise NotImplementedError("VERIFY_CRL_CHECK_LEAF not implemented for macOS")
+
+ certs = None
+ try:
+ certs = _der_certs_to_cf_cert_array(cert_chain)
+
+ # Now that we have certificates loaded and a SecPolicy
+ # we can finally create a SecTrust object!
+ trust = Security.SecTrustRef()
+ Security.SecTrustCreateWithCertificates(
+ certs, policies, ctypes.byref(trust)
+ )
+
+ finally:
+ # The certs are now being held by SecTrust so we can
+ # release our handles for the array.
+ if certs:
+ CoreFoundation.CFRelease(certs)
+
+ # If there are additional trust anchors to load we need to transform
+ # the list of DER-encoded certificates into a CFArray.
+ ctx_ca_certs_der: list[bytes] | None = ssl_context.get_ca_certs(
+ binary_form=True
+ )
+ if ctx_ca_certs_der:
+ ctx_ca_certs = None
+ try:
+ ctx_ca_certs = _der_certs_to_cf_cert_array(ctx_ca_certs_der)
+ Security.SecTrustSetAnchorCertificates(trust, ctx_ca_certs)
+ finally:
+ if ctx_ca_certs:
+ CoreFoundation.CFRelease(ctx_ca_certs)
+
+ # We always want system certificates.
+ Security.SecTrustSetAnchorCertificatesOnly(trust, False)
+
+ # macOS 10.13 and earlier don't support SecTrustEvaluateWithError()
+ # so we use SecTrustEvaluate() which means we need to construct error
+ # messages ourselves.
+ if _is_macos_version_10_14_or_later:
+ _verify_peercerts_impl_macos_10_14(ssl_context, trust)
+ else:
+ _verify_peercerts_impl_macos_10_13(ssl_context, trust)
+ finally:
+ if policies:
+ CoreFoundation.CFRelease(policies)
+ if trust:
+ CoreFoundation.CFRelease(trust)
+
+
+def _verify_peercerts_impl_macos_10_13(
+ ssl_context: ssl.SSLContext, sec_trust_ref: typing.Any
+) -> None:
+ """Verify using 'SecTrustEvaluate' API for macOS 10.13 and earlier.
+ macOS 10.14 added the 'SecTrustEvaluateWithError' API.
+ """
+ sec_trust_result_type = Security.SecTrustResultType()
+ Security.SecTrustEvaluate(sec_trust_ref, ctypes.byref(sec_trust_result_type))
+
+ try:
+ sec_trust_result_type_as_int = int(sec_trust_result_type.value)
+ except (ValueError, TypeError):
+ sec_trust_result_type_as_int = -1
+
+ # Apple doesn't document these values in their own API docs.
+ # See: https://github.com/xybp888/iOS-SDKs/blob/master/iPhoneOS13.0.sdk/System/Library/Frameworks/Security.framework/Headers/SecTrust.h#L84
+ if (
+ ssl_context.verify_mode == ssl.CERT_REQUIRED
+ and sec_trust_result_type_as_int not in (1, 4)
+ ):
+ # Note that we're not able to ignore only hostname errors
+ # for macOS 10.13 and earlier, so check_hostname=False will
+ # still return an error.
+ sec_trust_result_type_to_message = {
+ 0: "Invalid trust result type",
+ # 1: "Trust evaluation succeeded",
+ 2: "User confirmation required",
+ 3: "User specified that certificate is not trusted",
+ # 4: "Trust result is unspecified",
+ 5: "Recoverable trust failure occurred",
+ 6: "Fatal trust failure occurred",
+ 7: "Other error occurred, certificate may be revoked",
+ }
+ error_message = sec_trust_result_type_to_message.get(
+ sec_trust_result_type_as_int,
+ f"Unknown trust result: {sec_trust_result_type_as_int}",
+ )
+
+ err = ssl.SSLCertVerificationError(error_message)
+ err.verify_message = error_message
+ err.verify_code = sec_trust_result_type_as_int
+ raise err
+
+
+def _verify_peercerts_impl_macos_10_14(
+ ssl_context: ssl.SSLContext, sec_trust_ref: typing.Any
+) -> None:
+ """Verify using 'SecTrustEvaluateWithError' API for macOS 10.14+."""
+ cf_error = CoreFoundation.CFErrorRef()
+ sec_trust_eval_result = Security.SecTrustEvaluateWithError(
+ sec_trust_ref, ctypes.byref(cf_error)
+ )
+ # sec_trust_eval_result is a bool (0 or 1)
+ # where 1 means that the certs are trusted.
+ if sec_trust_eval_result == 1:
+ is_trusted = True
+ elif sec_trust_eval_result == 0:
+ is_trusted = False
+ else:
+ raise ssl.SSLError(
+ f"Unknown result from Security.SecTrustEvaluateWithError: {sec_trust_eval_result!r}"
+ )
+
+ cf_error_code = 0
+ if not is_trusted:
+ cf_error_code = CoreFoundation.CFErrorGetCode(cf_error)
+
+ # If the error is a known failure that we're
+ # explicitly okay with from SSLContext configuration
+ # we can set is_trusted accordingly.
+ if ssl_context.verify_mode != ssl.CERT_REQUIRED and (
+ cf_error_code == CFConst.errSecNotTrusted
+ or cf_error_code == CFConst.errSecCertificateExpired
+ ):
+ is_trusted = True
+
+ # If we're still not trusted then we start to
+ # construct and raise the SSLCertVerificationError.
+ if not is_trusted:
+ cf_error_string_ref = None
+ try:
+ cf_error_string_ref = CoreFoundation.CFErrorCopyDescription(cf_error)
+
+ # Can this ever return 'None' if there's a CFError?
+ cf_error_message = (
+ _cf_string_ref_to_str(cf_error_string_ref)
+ or "Certificate verification failed"
+ )
+
+ # TODO: Not sure if we need the SecTrustResultType for anything?
+ # We only care whether or not it's a success or failure for now.
+ sec_trust_result_type = Security.SecTrustResultType()
+ Security.SecTrustGetTrustResult(
+ sec_trust_ref, ctypes.byref(sec_trust_result_type)
+ )
+
+ err = ssl.SSLCertVerificationError(cf_error_message)
+ err.verify_message = cf_error_message
+ err.verify_code = cf_error_code
+ raise err
+ finally:
+ if cf_error_string_ref:
+ CoreFoundation.CFRelease(cf_error_string_ref)