
    Ld\?                    P   d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlmZmZmZmZmZmZmZmZmZmZ  ej        dej                  Zd<dZd=dZd>dZd?dZd@dZ	 dAdBdZdCd"Z dDd&Z!dDd'Z"dEd)Z#dFd/Z$dGd1Z%d2d3d4d5d6d7Z&dHd9Z' G d: d;          Z(dS )Ia  
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.
    )annotationsN   )
CFArrayCFConstCFDataCFDictionaryCFMutableArrayCFString	CFTypeRefCoreFoundationSecKeychainRefSecuritys;   -----BEGIN CERTIFICATE-----
(.*?)
-----END CERTIFICATE-----
bytestringbytesreturnr   c                \    t          j        t           j        | t          |                     S )zv
    Given a bytestring, create a CFData object from it. This CFData object must
    be CFReleased by the caller.
    )r   CFDataCreatekCFAllocatorDefaultlen)r   s    PF:\djangOuth\env\Lib\site-packages\urllib3/contrib/_securetransport/low_level.py_cf_data_from_bytesr   )   s)    
 &*JJ      tuples#list[tuple[typing.Any, typing.Any]]r   c                   t          |           }d | D             }d | D             }t          j        |z  | }t          j        |z  | }t          j        t          j        |||t          j        t          j                  S )zK
    Given a list of Python tuples, create an associated CFDictionary.
    c              3  &   K   | ]}|d          V  dS )r   N .0ts     r   	<genexpr>z-_cf_dictionary_from_tuples.<locals>.<genexpr><   s&      !!QAaD!!!!!!r   c              3  &   K   | ]}|d          V  dS )r   Nr   r   s     r   r!   z-_cf_dictionary_from_tuples.<locals>.<genexpr>=   s&      ##qad######r   )r   r   r   CFDictionaryCreater   kCFTypeDictionaryKeyCallBackskCFTypeDictionaryValueCallBacks)r   dictionary_sizekeysvaluescf_keys	cf_valuess         r   _cf_dictionary_from_tuplesr+   3   s     &kkO "!&!!!D##F###F'/9DAG)O;fEI,*46  r   py_bstrr
   c                    t          j        |           }t          j        t          j        |t
          j                  }|S )zi
    Given a Python binary data, create a CFString.
    The string must be CFReleased by the caller.
    )ctypesc_char_pr   CFStringCreateWithCStringr   r   kCFStringEncodingUTF8)r,   c_strcf_strs      r   _cfstrr4   K   s;    
 OG$$E5*% F
 Mr   lstlist[bytes]r	   c                   d}	 t          j        t           j        dt          j        t           j                            }|st          d          | D ]e}t          |          }|st          d          	 t          j        ||           t          j	        |           M# t          j	        |           w xY wn@# t          $ r3}|rt          j	        |           t          j        d|           dd}~ww xY w|S )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MemoryErrorr4   CFArrayAppendValue	CFReleaseBaseExceptionsslSSLError)r5   cf_arritemr3   es        r   _create_cfstring_arrayrE   Y   s-    FG4.L=>>
 

  	<:;;; 	1 	1DD\\F @!">???11&&AAA(0000(0000	1  G G G 	-$V,,,l;;;<<$FG Ms0   A1B: 6B B:  B66B: :
C7.C22C7value
str | Nonec                r   t          j        | t          j        t           j                            }t	          j        |t          j                  }|Mt          j        d          }t	          j	        ||dt          j                  }|st          d          |j        }||                    d          }|S )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.
    Ni   z'Error copying C string from CFStringRefutf-8)r.   castPOINTERc_void_pr   CFStringGetCStringPtrr   r1   create_string_bufferCFStringGetCStringOSErrorrF   decode)rF   value_as_void_pstringbufferresults        r   _cf_string_to_unicoderV   x   s     k%)H)HIIO16 F ~,T222VT7+H
 
  	ECDDDw''Mr   errorintexception_classtype[BaseException] | NoneNonec                    | dk    rdS t          j        | d          }t          |          }t          j        |           ||dk    rd|  }|t
          j        } ||          )z[
    Checks the return code and throws an exception if there is an error to
    report
    r   N z	OSStatus )r   SecCopyErrorMessageStringrV   r   r>   r@   rA   )rW   rY   cf_error_stringoutputs       r   _assert_no_errorra      sy     zz8EEO"?33F_---~2$U$$,
/&
!
!!r   
pem_bundler   c                   |                      dd          } d t                              |           D             }|st          j        d          t          j        t
          j        dt          j	        t
          j
                            }|st          j        d          	 |D ]}t          |          }|st          j        d          t          j        t
          j        |          }t          j        |           |st          j        d          t          j        ||           t          j        |           n## t           $ r t          j        |            w xY w|S )z
    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   
   
c                \    g | ])}t          j        |                    d                     *S )r   )base64	b64decodegroup)r   matchs     r   
<listcomp>z(_cert_array_from_pem.<locals>.<listcomp>   s:       -2Q((  r   zNo root certificates specifiedr   r8   zUnable to build cert object!)replace_PEM_CERTS_REfinditerr@   rA   r   r9   r   r.   r:   r;   r   r   SecCertificateCreateWithDatar>   r=   	Exception)rb   	der_certs
cert_array	der_bytescertdatacerts         r   _cert_array_from_pemru      s    ##GU33J 6C6L6LZ6X6X  I  =l;<<<4*	^9:: J
  9l7888" 	+ 	+I*955H Al#?@@@82H D $X... Cl#ABBB-j$???$T****	+     	 ,,, s   $BE  E!rC   r   boolc                X    t          j                    }t          j        |           |k    S )z=
    Returns True if a given CFTypeRef is a certificate.
    )r   SecCertificateGetTypeIDr   CFGetTypeIDrC   expecteds     r   _is_certr|      s(     /11H%d++x77r   c                X    t          j                    }t          j        |           |k    S )z;
    Returns True if a given CFTypeRef is an identity.
    )r   SecIdentityGetTypeIDr   ry   rz   s     r   _is_identityr      s(     ,..H%d++x77r   tuple[SecKeychainRef, str]c            
        t          j        d          } t          j        | dd                                       d          }t          j        | dd                   }t          j                    }t           j                            ||          	                    d          }t          j                    }t          j        |t          |          |ddt          j        |                    }t!          |           ||fS )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   rI   F)osurandomrf   	b16encoderQ   tempfilemkdtemppathjoinencoder   r   SecKeychainCreater   r.   r:   ra   )random_bytesfilenamepasswordtempdirectorykeychain_pathkeychainstatuss          r   _temporary_keychainr      s    " :b>>LRaR 01188AAHQRR 011H$&&MGLL99@@IIM &((H's8}}htV\(=S=S F V ]""r   r   r   r   str'tuple[list[CFTypeRef], list[CFTypeRef]]c                   g }g }d}t          |d          5 }|                                }ddd           n# 1 swxY w Y   	 t          j        t          j        |t          |                    }t          j                    }t          j        |ddddd| t          j
        |                    }t          |           t          j        |          }	t          |	          D ]}
t          j        ||
          }t          j        |t          j                  }t#          |          r*t          j        |           |                    |           ot)          |          r)t          j        |           |                    |           	 |rt          j        |           t          j        |           n/# |rt          j        |           t          j        |           w xY w||fS )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.   r:   ra   CFArrayGetCountrangeCFArrayGetValueAtIndexrJ   r   r|   CFRetainappendr   r>   )r   r   certificates
identitiesresult_arrayfraw_filedatafiledatarU   result_countindexrC   s               r   _load_items_from_filer   	  s,    LJL	dD		  Qvvxx                             $+!..c,>O>O
 
 &022'L&&	
 	
 	    &5lCC<(( 		( 		(E!8uMMD;t^%=>>D~~ ('---##D))))d## ('---!!$'''		(  	3$\222 ****  	3$\222 ****%%s   8<<EF7 7,G#pathsc                T   g }g }d |D             }	 |D ]?}t          | |          \  }}|                    |           |                    |           @|st          j                    }t          j        | |d         t          j        |                    }	t          |	           |                    |           t          j
        |                    d                     t          j        t          j        dt          j        t          j                            }
t          j        ||          D ]}t          j        |
|           |
t          j        ||          D ]}t          j
        |           S # t          j        ||          D ]}t          j
        |           w xY w)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     K   | ]}||V  	d S Nr   )r   r   s     r   r!   z*_load_client_cert_chain.<locals>.<genexpr>f  s'      55t5d555555r   r   )r   extendr   SecIdentityRef SecIdentityCreateWithCertificater.   r:   ra   r   r   r>   popr9   r   r;   	itertoolschainr=   )r   r   r   r   filtered_paths	file_pathnew_identities	new_certsnew_identityr   trust_chainrC   objs                r   _load_client_cert_chainr   B  s   @ LJ 65u555N"*' 	+ 	+I(=h	(R(R%NIn---	****  
	:#244L>,q/6<+E+E F V$$$l+++ $\%5%5a%8%8999 %9.L=>>
 

 OJ== 	A 	AD -k4@@@@?:|<< 	* 	*C$S))))	*9?:|<< 	* 	*C$S))))	*s   D:E9 9.F')r      )   r   )r   r   )r   r   )r   r   )SSLv2SSLv3TLSv1zTLSv1.1zTLSv1.2versionc                    t           |          \  }}d}d}t          j        d||          }t          |          }d}t          j        d||||          |z   }|S )z6
    Builds a TLS alert record for an unknown CA.
    r   0   z>BB   z>BBBH)TLS_PROTOCOL_VERSIONSstructpackr   )	r   ver_majver_minseverity_fataldescription_unknown_camsgmsg_lenrecord_type_alertrecords	            r   _build_tls_unknown_ca_alertr     sf     -W5GWN!
+e^-C
D
DC#hhG["3WgwOORUUFMr   c                      e Zd ZdZdZdZdZdZdZdZ	dZ
d	ZdZdZdZdZdZd
ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(d Z)d!Z*d"Z+d#S )$SecurityConstzU
    A class object that acts as essentially a namespace for Security constants.
    r   r   r         r   
   i  r         iiiiiiiiiiiiiiiiiii iQi,iRN),__name__
__module____qualname____doc__"kSSLSessionOptionBreakOnServerAuthkSSLProtocol2kSSLProtocol3kTLSProtocol1kTLSProtocol11kTLSProtocol12kTLSProtocol13kTLSProtocolMaxSupportedkSSLClientSidekSSLStreamTypekSecFormatPEMSequencekSecTrustResultInvalidkSecTrustResultProceedkSecTrustResultDenykSecTrustResultUnspecified&kSecTrustResultRecoverableTrustFailure kSecTrustResultFatalTrustFailurekSecTrustResultOtherErrorerrSSLProtocolerrSSLWouldBlockerrSSLClosedGracefulerrSSLClosedNoNotifyerrSSLClosedAborterrSSLXCertChainInvaliderrSSLCryptoerrSSLInternalerrSSLCertExpirederrSSLCertNotYetValiderrSSLUnknownRootCerterrSSLNoRootCerterrSSLHostNameMismatcherrSSLPeerHandshakeFailerrSSLPeerUserCancellederrSSLWeakPeerEphemeralDHKeyerrSSLServerAuthCompletederrSSLRecordOverflowerrSecVerifyFailederrSecNoTrustSettingserrSecItemNotFounderrSecInvalidTrustSettingsr   r   r   r   r     s         *+&MMMNNN"NN !"-.*'($ !N  #LN!!"###(  % "!'r   r   )r   r   r   r   )r   r   r   r   )r,   r   r   r
   )r5   r6   r   r	   )rF   r
   r   rG   r   )rW   rX   rY   rZ   r   r[   )rb   r   r   r   )rC   r   r   rv   )r   r   )r   r   r   r   r   r   )r   r   r   rG   r   r   )r   r   r   r   ))r   
__future__r   rf   r.   r   r   rer@   r   r   typingbindingsr   r   r   r   r	   r
   r   r   r   r   compileDOTALLrl   r   r+   r4   rE   rV   ra   ru   r|   r   r   r   r   r   r   r   r   r   r   <module>r     sr    # " " " " "       				 				 



                           
Dbi 
      0      >   4 ?C" " " " ".+ + + +\8 8 8 88 8 8 8 #  #  #  #F6& 6& 6& 6&rH* H* H* H*X      6( 6( 6( 6( 6( 6( 6( 6( 6( 6(r   