o
    PJBe\?                     @  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   k/home/www/facesmatcher.com/frenv/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
   ZCFDictionaryCreater   ZkCFTypeDictionaryKeyCallBacksZkCFTypeDictionaryValueCallBacks)r   Zdictionary_sizekeysvaluesZcf_keysZ	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   ZCFStringCreateWithCStringr   r   kCFStringEncodingUTF8)r"   Z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)r(   Zcf_arritemr&   er   r   r   _create_cfstring_arrayY   s0   

r6   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#   castZPOINTERZc_void_pr   ZCFStringGetCStringPtrr   r%   Zcreate_string_bufferZCFStringGetCStringOSErrorr7   decode)r7   Zvalue_as_void_pstringbufferresultr   r   r   _cf_string_to_unicodex   s   


r@   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   ZSecCopyErrorMessageStringr@   r   r0   r2   r3   )rA   rC   Zcf_error_stringoutputr   r   r   _assert_no_error   s   

rH   
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   r*   zUnable to build cert object!)replace_PEM_CERTS_REfinditerr2   r3   r   r+   r   r#   r,   r-   r   r   ZSecCertificateCreateWithDatar0   r/   	Exception)rI   Z	der_certsZ
cert_arrayZ	der_bytesZcertdatacertr   r   r   _cert_array_from_pem   s@   






rU   r4   r
   boolc                 C     t  }t| |kS )z=
    Returns True if a given CFTypeRef is a certificate.
    )r   ZSecCertificateGetTypeIDr   CFGetTypeIDr4   expectedr   r   r   _is_cert      r[   c                 C  rW   )z;
    Returns True if a given CFTypeRef is an identity.
    )r   ZSecIdentityGetTypeIDr   rX   rY   r   r   r   _is_identity   r\   r]   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   r9   F)osurandomrK   	b16encoder<   tempfilemkdtemppathjoinencoder   r   ZSecKeychainCreater   r#   r,   rH   )Zrandom_bytesfilenamepasswordZtempdirectoryZkeychain_pathkeychainstatusr   r   r   _temporary_keychain   s   
rm   rk   r   rf   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   Z
CFArrayRefr   ZSecItemImportr#   r,   rH   ZCFArrayGetCountrangeZCFArrayGetValueAtIndexr:   r
   r[   ZCFRetainappendr]   r0   )rk   rf   certificates
identitiesZresult_arrayfZraw_filedataZfiledatar?   Zresult_countindexr4   r   r   r   _load_items_from_file	  sR   	








ry   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   rf   r   r   r   r   f  r   z*_load_client_cert_chain.<locals>.<genexpr>r   )ry   extendr   ZSecIdentityRefZ SecIdentityCreateWithCertificater#   r,   rH   rt   r   r0   popr+   r   r-   	itertoolschainr/   )rk   rz   ru   rv   Zfiltered_paths	file_pathZnew_identitiesZ	new_certsZnew_identityrl   Ztrust_chainr4   objr   r   r   _load_client_cert_chainB  s:    


r   )r      )   r   )r   r   )r   r   )r   r   )Z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   Zver_majZver_minZseverity_fatalZdescription_unknown_camsgZmsg_lenZ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         r`   
   i  r         iiiiiiiiiiiiiiiiiii iQi,iRN),__name__
__module____qualname____doc__Z"kSSLSessionOptionBreakOnServerAuthZkSSLProtocol2ZkSSLProtocol3ZkTLSProtocol1ZkTLSProtocol11ZkTLSProtocol12ZkTLSProtocol13ZkTLSProtocolMaxSupportedZkSSLClientSideZkSSLStreamTypeZkSecFormatPEMSequenceZkSecTrustResultInvalidZkSecTrustResultProceedZkSecTrustResultDenyZkSecTrustResultUnspecifiedZ&kSecTrustResultRecoverableTrustFailureZ kSecTrustResultFatalTrustFailureZkSecTrustResultOtherErrorZerrSSLProtocolZerrSSLWouldBlockZerrSSLClosedGracefulZerrSSLClosedNoNotifyZerrSSLClosedAbortZerrSSLXCertChainInvalidZerrSSLCryptoZerrSSLInternalZerrSSLCertExpiredZerrSSLCertNotYetValidZerrSSLUnknownRootCertZerrSSLNoRootCertZerrSSLHostNameMismatchZerrSSLPeerHandshakeFailZerrSSLPeerUserCancelledZerrSSLWeakPeerEphemeralDHKeyZerrSSLServerAuthCompletedZerrSSLRecordOverflowZerrSecVerifyFailedZerrSecNoTrustSettingsZerrSecItemNotFoundZerrSecInvalidTrustSettingsr   r   r   r   r     sT    r   )r   r   r   r   )r   r   r   r   )r"   r   r   r	   )r(   r)   r   r   )r7   r	   r   r8   r{   )rA   rB   rC   rD   r   rE   )rI   r   r   r   )r4   r
   r   rV   )r   r^   )rk   r   rf   rn   r   ro   )rk   r   rz   r8   r   r   )r   rn   r   r   ))r   
__future__r   rK   r#   r~   ra   rer2   r   rd   typingZbindingsr   r   r   r   r   r	   r
   r   r   r   compileDOTALLrQ   r   r!   r'   r6   r@   rH   rU   r[   r]   rm   ry   r   r   r   r   r   r   r   r   <module>   sH    	0



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