
    Z-"ib6                         S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	J
r
JrJr  \R                  " S\R                  5      rS rS rS rS	 rS
 rSS jrS rS rS rS rS rS rSSSSSS.rS rg)a  
Low-level helpers for the SecureTransport bindings.

These are Python functions that are not directly related to the high-level APIs
but are necessary to get them to work. They include a whole bunch of low-level
CoreFoundation messing about and memory management. The concerns in this module
are almost entirely about trying to avoid memory leaks and providing
appropriate and useful assistance to the higher-level code.
    N   )CFConstCoreFoundationSecuritys;   -----BEGIN CERTIFICATE-----
(.*?)
-----END CERTIFICATE-----c                 `    [         R                  " [         R                  U [        U 5      5      $ )zj
Given a bytestring, create a CFData object from it. This CFData object must
be CFReleased by the caller.
)r   CFDataCreatekCFAllocatorDefaultlen)
bytestrings    d/home/james-whalen/.local/lib/python3.13/site-packages/urllib3/contrib/_securetransport/low_level.py_cf_data_from_bytesr      s(    
 &&**JJ     c                    [        U 5      nS U  5       nS U  5       n[        R                  U-  " U6 n[        R                  U-  " U6 n[        R                  " [        R                  UUU[        R
                  [        R                  5      $ )zC
Given a list of Python tuples, create an associated CFDictionary.
c              3   *   #    U  H	  oS    v   M     g7f)r   N .0ts     r   	<genexpr>-_cf_dictionary_from_tuples.<locals>.<genexpr>,   s     !&QaD&   c              3   *   #    U  H	  oS    v   M     g7f)r   Nr   r   s     r   r   r   -   s     #FqdFr   )r
   r   	CFTypeRefCFDictionaryCreater	   kCFTypeDictionaryKeyCallBackskCFTypeDictionaryValueCallBacks)tuplesdictionary_sizekeysvaluescf_keys	cf_valuess         r   _cf_dictionary_from_tuplesr#   %   s     &kO "&!D#F#F''/9DAG))O;fEI,,**4466 r   c                     [         R                  " U 5      n[        R                  " [        R                  U[
        R                  5      nU$ )z]
Given a Python binary data, create a CFString.
The string must be CFReleased by the caller.
)ctypesc_char_pr   CFStringCreateWithCStringr	   r   kCFStringEncodingUTF8)py_bstrc_strcf_strs      r   _cfstrr,   ;   s>    
 OOG$E55**%%F
 Mr   c                 .   Sn [         R                  " [         R                  S[        R                  " [         R
                  5      5      nU(       d  [        S5      eU  HM  n[        U5      nU(       d  [        S5      e [         R                  " X5        [         R                  " U5        MO     U$ ! [         R                  " U5        f = f! [         a<  nU(       a  [         R                  " U5        [        R                  " SU< 35      eSnAff = f)z
Given a list of Python binary data, create an associated CFMutableArray.
The array must be CFReleased by the caller.

Raises an ssl.SSLError on failure.
Nr   Unable to allocate memory!zUnable to allocate array: )r   CFArrayCreateMutabler	   r%   byrefkCFTypeArrayCallBacksMemoryErrorr,   CFArrayAppendValue	CFReleaseBaseExceptionsslSSLError)lstcf_arritemr+   es        r   _create_cfstring_arrayr<   I   s     FB44..LL==>

 :;;DD\F!">??111&A((0  M ((0 B$$V,llQ@AABs0   A<C B3C 3CC 
D7DDc                    [         R                  " U [         R                  " [         R                  5      5      n[        R
                  " U[        R                  5      nUcZ  [         R                  " S5      n[        R                  " XS[        R                  5      nU(       d  [        S5      eUR                  nUb  UR                  S5      nU$ )z
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.
i   z'Error copying C string from CFStringRefutf-8)r%   castPOINTERc_void_pr   CFStringGetCStringPtrr   r(   create_string_bufferCFStringGetCStringOSErrorvaluedecode)rF   value_as_void_pstringbufferresults        r   _cf_string_to_unicoderL   h   s     kk%)HIO1166F ~,,T222T7+H+H
 CDDw'Mr   c                     U S:X  a  g[         R                  " U S5      n[        U5      n[        R                  " U5        Ub  US:X  a  SU -  nUc  [
        R                  nU" U5      e)zO
Checks the return code and throws an exception if there is an error to
report
r   N zOSStatus %s)r   SecCopyErrorMessageStringrL   r   r4   r6   r7   )errorexception_classcf_error_stringoutputs       r   _assert_no_errorrT      sg    
 z88EO"?3F_-~3%',,
&
!!r   c                 ~   U R                  SS5      n [        R                  U 5       Vs/ s H(  n[        R                  " UR                  S5      5      PM*     nnU(       d  [        R                  " S5      e[        R                  " [        R                  S[        R                  " [        R                  5      5      nU(       d  [        R                  " S5      e U H  n[        U5      nU(       d  [        R                  " S5      e[        R                   " [        R                  U5      n[        R"                  " U5        U(       d  [        R                  " S5      e[        R$                  " X65        [        R"                  " U5        M     U$ s  snf ! [&         a    [        R"                  " U5        e f = f)zv
Given a bundle of certs in PEM format, turns them into a CFArray of certs
that can be used to validate a cert chain.
s   
   
r   zNo root certificates specifiedr   r.   zUnable to build cert object!)replace_PEM_CERTS_REfinditerbase64	b64decodegroupr6   r7   r   r/   r	   r%   r0   r1   r   r   SecCertificateCreateWithDatar4   r3   	Exception)
pem_bundlematch	der_certs
cert_array	der_bytescertdatacerts          r   _cert_array_from_pemrf      sd    ##GU3J 7D6L6LZ6X6XUQ(6X   ll;<<44**	^99:J
 ll788"I*95Hll#?@@8822HD $$X.ll#ABB--j?$$T* #( G8   	  ,s   /FB5F "F<c                 ^    [         R                  " 5       n[        R                  " U 5      U:H  $ )z5
Returns True if a given CFTypeRef is a certificate.
)r   SecCertificateGetTypeIDr   CFGetTypeIDr:   expecteds     r   _is_certrl      s(     //1H%%d+x77r   c                 ^    [         R                  " 5       n[        R                  " U 5      U:H  $ )z3
Returns True if a given CFTypeRef is an identity.
)r   SecIdentityGetTypeIDr   ri   rj   s     r   _is_identityro      s(     ,,.H%%d+x77r   c            
         [         R                  " S5      n [        R                  " U SS 5      R	                  S5      n[        R                  " U SS 5      n[
        R                  " 5       n[         R                  R                  X15      R                  S5      n[        R                  " 5       n[        R                  " U[        U5      USS[        R                  " U5      5      n[!        U5        XS4$ )a  
This function creates a temporary Mac keychain that we can use to work with
credentials. This keychain uses a one-time password and a temporary file to
store the data. We expect to have one keychain per socket. The returned
SecKeychainRef must be freed by the caller, including calling
SecKeychainDelete.

Returns a tuple of the SecKeychainRef and the path to the temporary
directory that contains it.
(   N   r>   F)osurandomrZ   	b16encoderG   tempfilemkdtemppathjoinencoder   SecKeychainRefSecKeychainCreater
   r%   r0   rT   )random_bytesfilenamepasswordtempdirectorykeychain_pathkeychainstatuss          r   _temporary_keychainr      s    " ::b>LRa 0188AHQR 01H$$&MGGLL9@@IM &&(H''s8}htV\\(=SF V ""r   c                    / n/ nSn[        US5       nUR                  5       nSSS5         [        R                  " [        R                  W[        U5      5      n[        R                  " 5       n[        R                  " USSSSSU [        R                  " U5      5      n[        U5        [        R                  " U5      n	[        U	5       H  n
[        R                  " XJ5      n[        R                  " U[        R                   5      n[#        U5      (       a)  [        R$                  " U5        UR'                  U5        Mw  [)        U5      (       d  M  [        R$                  " U5        UR'                  U5        M     U(       a  [        R*                  " U5        [        R*                  " U5        X24$ ! , (       d  f       GN= f! U(       a  [        R*                  " U5        [        R*                  " W5        f = f)z
Given a single file, loads all the trust objects from it into arrays and
the keychain.
Returns a tuple of lists: the first list is a list of identities, the
second a list of certs.
Nrbr   )openreadr   r   r	   r
   
CFArrayRefr   SecItemImportr%   r0   rT   CFArrayGetCountrangeCFArrayGetValueAtIndexr?   r   rl   CFRetainappendro   r4   )r   rx   certificates
identitiesresult_arrayfraw_filedatafiledatarK   result_countindexr:   s               r   _load_items_from_filer      s    LJL	dD	Qvvx 
$+!....c,>O
 &002''LL&	
 	  &55lC<(E!88MD;;t^%=%=>D~~''-##D)d##''-!!$' ) $$\2  *%%S 
	H $$\2  *s   F8D&G
 +G
 8
G
5G?c                 t   / n/ nS U 5       n U H2  n[        X5      u  pVUR                  U5        UR                  U5        M4     U(       d  [        R                  " 5       n[        R                  " XS   [
        R                  " U5      5      n[        U5        UR                  U5        [        R                  " UR                  S5      5        [        R                  " [        R                  S[
        R                  " [        R                  5      5      n	[        R                   " X25       H  n
[        R"                  " X5        M     U	[        R                   " X25       H  n[        R                  " U5        M     $ ! [        R                   " X25       H  n[        R                  " U5        M     f = f)z
Load certificates and maybe keys from a number of files. Has the end goal
of returning a CFArray containing one SecIdentityRef, and then zero or more
SecCertificateRef objects, suitable for use as a client certificate trust
chain.
c              3   6   #    U  H  o(       d  M  Uv   M     g 7fNr   )r   rx   s     r   r   *_load_client_cert_chain.<locals>.<genexpr>R  s     ,edtTTes   
	r   )r   extendr   SecIdentityRef SecIdentityCreateWithCertificater%   r0   rT   r   r   r4   popr/   r	   r1   	itertoolschainr3   )r   pathsr   r   	file_pathnew_identities	new_certsnew_identityr   trust_chainr:   objs               r   _load_client_cert_chainr   .  sX   @ LJ -e,E"*I(=h(R%Nn-	*  #224L>>q/6<<+EF V$l+ $$\%5%5a%89 %99..LL==>

 OOJ=D --k@ >
 ??:<C$$S) =9??:<C$$S) =s   D?F 5F7)r      )   r   )r   r   )r   r   )r   r   )SSLv2SSLv3TLSv1zTLSv1.1zTLSv1.2c                     [         U    u  pSnSn[        R                  " SX45      n[        U5      nSn[        R                  " SXqX&5      U-   nU$ )z.
Builds a TLS alert record for an unknown CA.
r   0   z>BB   z>BBBH)TLS_PROTOCOL_VERSIONSstructpackr
   )	versionver_majver_minseverity_fataldescription_unknown_camsgmsg_lenrecord_type_alertrecords	            r   _build_tls_unknown_ca_alertr     sY     -W5GN!
++e^
DC#hG[["3gORUUFMr   r   )__doc__rZ   r%   r   rs   rer6   r   rv   bindingsr   r   r   compileDOTALLrX   r   r#   r,   r<   rL   rT   rf   rl   ro   r   r   r   r   r   r   r   r   <module>r      s       	 	 
   7 7 

Dbii
,>2"*+\88 #F4&nH*X  r   