<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css"
        integrity="sha512-SzlrxWUlpfuzQ+pcUCosxcglQRNAq/DZjVsC0lE40xsADsfeQoEypE+enwcOiGjk/bSuGGKHEyjSoQ1zVisanQ=="
        crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
</html>
U
    ÀÒ.e´.  ã                   @   s´   d 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 e dej¡Zdd„ Zdd	„ Zd
d„ Zddd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )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é   )ÚSecurityÚCoreFoundationÚCFConsts;   -----BEGIN CERTIFICATE-----
(.*?)
-----END CERTIFICATE-----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)Z
bytestring© r	   úZ/usr/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.pyÚ_cf_data_from_bytes   s
      ÿ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   s   | ]}|d  V  qdS )r   Nr	   ©Ú.0Útr	   r	   r
   Ú	<genexpr>,   s     z-_cf_dictionary_from_tuples.<locals>.<genexpr>c                 s   s   | ]}|d  V  qdS )r   Nr	   r   r	   r	   r
   r   -   s     )r   r   Ú	CFTypeRefZCFDictionaryCreater   ZkCFTypeDictionaryKeyCallBacksZkCFTypeDictionaryValueCallBacks)ZtuplesZdictionary_sizeÚkeysÚvaluesZcf_keysZ	cf_valuesr	   r	   r
   Ú_cf_dictionary_from_tuples%   s    úr   c                 C   sn   t  | t  t j¡¡}t |tj¡}|dkrXt  d¡}t 	||dtj¡}|sRt
dƒ‚|j}|dk	rj| 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)ÚctypesÚcastZPOINTERZc_void_pr   ZCFStringGetCStringPtrr   ZkCFStringEncodingUTF8Zcreate_string_bufferZCFStringGetCStringÚOSErrorÚvalueÚdecode)r   Zvalue_as_void_pÚstringÚbufferÚresultr	   r	   r
   Ú_cf_string_to_unicode;   s&     ÿ
   ÿ
r   c                 C   s\   | dkrdS t  | d¡}t|ƒ}t |¡ |dks:|dkrBd|  }|dkrPtj}||ƒ‚dS )z[
    Checks the return code and throws an exception if there is an error to
    report
    r   NÚ zOSStatus %s)r   ZSecCopyErrorMessageStringr   r   Ú	CFReleaseÚsslÚSSLError)ÚerrorZexception_classZcf_error_stringÚoutputr	   r	   r
   Ú_assert_no_errorT   s    
r$   c                 C   sØ   |   dd¡} dd„ t | ¡D ƒ}|s.t d¡‚t tjdt 	tj
¡¡}|sTt d¡‚z`|D ]V}t|ƒ}|stt d¡‚t tj|¡}t |¡ |sšt d¡‚t ||¡ t |¡ qZW n tk
rÒ   t |¡ Y nX |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                 S   s   g | ]}t  | d ¡¡‘qS )r   )Úbase64Z	b64decodeÚgroup)r   Úmatchr	   r	   r
   Ú
<listcomp>q   s    z(_cert_array_from_pem.<locals>.<listcomp>zNo root certificates specifiedr   zUnable to allocate memory!zUnable to build cert object!)ÚreplaceÚ_PEM_CERTS_REÚfinditerr    r!   r   ÚCFArrayCreateMutabler   r   ÚbyrefÚkCFTypeArrayCallBacksr   r   ZSecCertificateCreateWithDatar   ÚCFArrayAppendValueÚ	Exception)Z
pem_bundleZ	der_certsZ
cert_arrayZ	der_bytesZcertdataZcertr	   r	   r
   Ú_cert_array_from_pemi   s<    ÿ

ý

 ÿ

r2   c                 C   s   t  ¡ }t | ¡|kS )z=
    Returns True if a given CFTypeRef is a certificate.
    )r   ZSecCertificateGetTypeIDr   ÚCFGetTypeID©ÚitemZexpectedr	   r	   r
   Ú_is_cert–   s    r6   c                 C   s   t  ¡ }t | ¡|kS )z;
    Returns True if a given CFTypeRef is an identity.
    )r   ZSecIdentityGetTypeIDr   r3   r4   r	   r	   r
   Ú_is_identityž   s    r7   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é   r   F)ÚosÚurandomr&   Z	b16encoder   ÚtempfileZmkdtempÚpathÚjoinÚencoder   ZSecKeychainRefZSecKeychainCreater   r   r.   r$   )Zrandom_bytesÚfilenameZpasswordZtempdirectoryZkeychain_pathÚkeychainÚstatusr	   r	   r
   Ú_temporary_keychain¦   s     
     ÿrC   c                 C   s   g }g }d}t |dƒ}| ¡ }W 5 Q R X z²t tj|t|ƒ¡}t ¡ }t 	|ddddd| t
 |¡¡}t|ƒ t |¡}	t|	ƒD ]X}
t ||
¡}t
 |tj¡}t|ƒr¼t |¡ | |¡ q€t|ƒr€t |¡ | |¡ q€W 5 |rìt |¡ t |¡ X ||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   r   Z
CFArrayRefr   ZSecItemImportr   r.   r$   ZCFArrayGetCountÚrangeZCFArrayGetValueAtIndexr   r   r6   ZCFRetainÚappendr7   )rA   r=   ÚcertificatesÚ
identitiesZresult_arrayÚfZraw_filedataZfiledatar   Zresult_countÚindexr5   r	   r	   r
   Ú_load_items_from_fileÉ   sJ      ÿø




rM   c              
   G   sê   g }g }dd„ |D ƒ}z°|D ]&}t| |ƒ\}}| |¡ | |¡ q|sŠt ¡ }t | |d t	 
|¡¡}	t|	ƒ | |¡ t | d¡¡ t tjdt	 
tj¡¡}
t  ||¡D ]}t |
|¡ q®|
W ¢S t  ||¡D ]}t |¡ qÔX dS )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   $  s      z*_load_client_cert_chain.<locals>.<genexpr>r   N)Ú	itertoolsÚchainr   r   rM   Úextendr   ZSecIdentityRefZ SecIdentityCreateWithCertificater   r.   r$   rH   Úpopr-   r   r/   r0   )rA   ÚpathsrI   rJ   ÚobjZ	file_pathZnew_identitiesZ	new_certsZnew_identityrB   Ztrust_chainr5   r	   r	   r
   Ú_load_client_cert_chain   s8     
  ÿ

ýrT   )N)Ú__doc__r&   r   rN   Úrer:   r    r<   Zbindingsr   r   r   ÚcompileÚDOTALLr+   r   r   r   r$   r2   r6   r7   rC   rM   rT   r	   r	   r	   r
   Ú<module>   s,   	 ÿ

-#7