o
    tl~i\?                     @  s>  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dejZdIddZdJddZdKddZdLddZdMddZ	dNdOd$d%ZdPd(d)Z dQd-d.Z!dQd/d0Z"dRd2d3Z#dSd9d:Z$dTd<d=Z%d>d?d@dAdBdCZ&dUdEdFZ'G dGdH dHZ(dS )Va  
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                 C  s   t 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    r   q/var/www/newdalilibackend/backend/venv/lib/python3.10/site-packages/urllib3/contrib/_securetransport/low_level.py_cf_data_from_bytes)   s   r   tuples#list[tuple[typing.Any, typing.Any]]r   c                 C  sZ   t | }dd | D }dd | D }tj| | }tj| | }ttj|||tjtjS )zK
    Given a list of Python tuples, create an associated CFDictionary.
    c                 s      | ]}|d  V  qdS )r   Nr   .0tr   r   r   	<genexpr><       z-_cf_dictionary_from_tuples.<locals>.<genexpr>c                 s  r   )r   Nr   r   r   r   r   r   =   r   )r   r   r
   CFDictionaryCreater   kCFTypeDictionaryKeyCallBackskCFTypeDictionaryValueCallBacks)r   dictionary_sizekeysvaluescf_keys	cf_valuesr   r   r   _cf_dictionary_from_tuples3   s   r'   py_bstrr	   c                 C  s    t | }t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_strr   r   r   _cfstrK   s   
r/   lstlist[bytes]r   c              
   C  s   d}z7t t jdtt j}|std| D ]}t|}|s#tdzt || W t 	| qt 	| w W |S  t
yU } z|rHt 	| td| dd}~ww )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)r0   cf_arritemr.   er   r   r   _create_cfstring_arrayY   s0   

r?   value
str | Nonec                 C  sn   t | t t j}t|tj}|du r,t d}t	||dtj}|s)t
d|j}|dur5|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   r,   create_string_bufferCFStringGetCStringOSErrorr@   decode)r@   value_as_void_pstringbufferresultr   r   r   _cf_string_to_unicodex   s   


rO   errorintexception_classtype[BaseException] | NoneNonec                 C  sZ   | dkrdS t | d}t|}t| |du s|dkr"d|  }|du r)tj}||)z[
    Checks the return code and throws an exception if there is an error to
    report
    r   N z	OSStatus )r   SecCopyErrorMessageStringrO   r   r8   r:   r;   )rP   rR   cf_error_stringoutputr   r   r   _assert_no_error   s   

rY   
pem_bundler   c                 C  s   |  dd} dd t| D }|stdttjdt	tj
}|s*tdz1|D ]+}t|}|s:tdttj|}t| |sMtdt|| t| q-W |S  tyh   t|  w )	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                 S  s   g | ]
}t |d qS )r   )base64	b64decodegroup)r   matchr   r   r   
<listcomp>   s    z(_cert_array_from_pem.<locals>.<listcomp>zNo root certificates specifiedr   r2   zUnable to build cert object!)replace_PEM_CERTS_REfinditerr:   r;   r   r3   r   r)   r4   r5   r   r   SecCertificateCreateWithDatar8   r7   	Exception)rZ   	der_certs
cert_array	der_bytescertdatacertr   r   r   _cert_array_from_pem   s@   






rk   r=   r
   boolc                 C     t  }t| |kS )z=
    Returns True if a given CFTypeRef is a certificate.
    )r   SecCertificateGetTypeIDr   CFGetTypeIDr=   expectedr   r   r   _is_cert      rr   c                 C  rm   )z;
    Returns True if a given CFTypeRef is an identity.
    )r   SecIdentityGetTypeIDr   ro   rp   r   r   r   _is_identity   rs   ru   tuple[SecKeychainRef, str]c               
   C  s   t d} t| dd d}t| dd }t }t j||	d}t
 }t
|t||ddt|}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   rB   F)osurandomr\   	b16encoderJ   tempfilemkdtemppathjoinencoder   r   SecKeychainCreater   r)   r4   rY   )random_bytesfilenamepasswordtempdirectorykeychain_pathkeychainstatusr   r   r   _temporary_keychain   s   
r   r   r   r~   str'tuple[list[CFTypeRef], list[CFTypeRef]]c                 C  s*  g }g }d}t |d}| }W d   n1 sw   Y  zhttj|t|}t }t|ddddd| t	
|}t| t|}	t|	D ],}
t||
}t	|tj}t|rht| || qJt|rvt| || qJW |rt| t| ||fS |rt| t| w )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)   r4   rY   CFArrayGetCountrangeCFArrayGetValueAtIndexrC   r
   rr   CFRetainappendru   r8   )r   r~   certificates
identitiesresult_arrayfraw_filedatafiledatarN   result_countindexr=   r   r   r   _load_items_from_file	  sR   	








r   pathsc              
   G  s   g }g }dd |D }ze|D ]}t | |\}}|| || q|sEt }t| |d t|}	t|	 || t	
|d t	t	jdtt	j}
t||D ]}t	|
| qW|
W t||D ]}t	
| qhS t||D ]}t	
| qww )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                 s  s    | ]}|r|V  qd S Nr   )r   r~   r   r   r   r   f  r   z*_load_client_cert_chain.<locals>.<genexpr>r   )r   extendr   SecIdentityRef SecIdentityCreateWithCertificater)   r4   rY   r   r   r8   popr3   r   r5   	itertoolschainr7   )r   r   r   r   filtered_paths	file_pathnew_identities	new_certsnew_identityr   trust_chainr=   objr   r   r   _load_client_cert_chainB  s:    


r   )r      )   r   )r   r   )r   r   )r   r   )SSLv2SSLv3TLSv1zTLSv1.1zTLSv1.2versionc           	      C  sH   t |  \}}d}d}td||}t|}d}td||||| }|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recordr   r   r   _build_tls_unknown_ca_alert  s   r   c                   @  s   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         rx   
   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     sT    r   )r   r   r   r   )r   r   r   r   )r(   r   r   r	   )r0   r1   r   r   )r@   r	   r   rA   r   )rP   rQ   rR   rS   r   rT   )rZ   r   r   r   )r=   r
   r   rl   )r   rv   )r   r   r~   r   r   r   )r   r   r   rA   r   r   )r   r   r   r   ))r   
__future__r   r\   r)   r   ry   rer:   r   r|   typingbindingsr   r   r   r   r   r	   r
   r   r   r   compileDOTALLrb   r   r'   r/   r?   rO   rY   rk   rr   ru   r   r   r   r   r   r   r   r   r   r   <module>   sH    	0







.


#
9L
	