
    Dgb6                         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Zddl	m
Z
mZmZ  ej        dej                  Zd Zd Zd Zd	 Zd
 ZddZd Zd Zd Zd Zd Zd ZddddddZ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   )CFConstCoreFoundationSecuritys;   -----BEGIN CERTIFICATE-----
(.*?)
-----END CERTIFICATE-----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)
bytestrings    _/var/www/sysmax/venv/lib/python3.11/site-packages/urllib3/contrib/_securetransport/low_level.py_cf_data_from_bytesr      s)    
 &*JJ      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   	CFTypeRefCFDictionaryCreater	   kCFTypeDictionaryKeyCallBackskCFTypeDictionaryValueCallBacks)tuplesdictionary_sizekeysvaluescf_keys	cf_valuess         r   _cf_dictionary_from_tuplesr!   %   s     &kkO "!&!!!D##F###F'/9DAG)O;fEI,*46  r   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)py_bstrc_strcf_strs      r   _cfstrr*   ;   s;    
 OG$$E5*% F
 Mr   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          $ r2}|rt          j	        |           t          j        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MemoryErrorr*   CFArrayAppendValue	CFReleaseBaseExceptionsslSSLError)lstcf_arritemr)   es        r   _create_cfstring_arrayr:   I   s)    FB4.L=>>
 

  	<:;;; 	1 	1DD\\F @!">???11&&AAA(0000(0000	1  B B B 	-$V,,,llQQ@AAAB Ms0   A1B: 6B B:  B66B: :
C6-C11C6c                 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   r&   create_string_bufferCFStringGetCStringOSErrorvaluedecode)rD   value_as_void_pstringbufferresults        r   _cf_string_to_unicoderJ   h   s     k%)H)HIIO16 F ~,T222VT7+H
 
  	ECDDDw''Mr   c                     | dk    rdS t          j        | d          }t          |          }t          j        |           ||dk    rd| z  }|t
          j        } ||          )z[
    Checks the return code and throws an exception if there is an error to
    report
    r   N zOSStatus %s)r   SecCopyErrorMessageStringrJ   r   r2   r4   r5   )errorexception_classcf_error_stringoutputs       r   _assert_no_errorrR      sv    
 zz8EEO"?33F_---~3%',
/&
!
!!r   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   r,   zUnable to build cert object!)replace_PEM_CERTS_REfinditerr4   r5   r   r-   r	   r#   r.   r/   r   r   SecCertificateCreateWithDatar2   r1   	Exception)
pem_bundle	der_certs
cert_array	der_bytescertdatacerts         r   _cert_array_from_pemrf      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!c                 X    t          j                    }t          j        |           |k    S )z=
    Returns True if a given CFTypeRef is a certificate.
    )r   SecCertificateGetTypeIDr   CFGetTypeIDr8   expecteds     r   _is_certrl      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   ri   rj   s     r   _is_identityro      s(     ,..H%d++x77r   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   r<   F)osurandomrV   	b16encoderE   tempfilemkdtemppathjoinencoder   SecKeychainRefSecKeychainCreater
   r#   r.   rR   )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   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.   rR   CFArrayGetCountrangeCFArrayGetValueAtIndexr=   r   rl   CFRetainappendro   r2   )r   rx   certificates
identitiesresult_arrayfraw_filedatafiledatarI   result_countindexr8   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#c                 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   rx   s     r   r   z*_load_client_cert_chain.<locals>.<genexpr>R  s'      ,,dt,T,,,,,,r   r   )r   extendr   SecIdentityRef SecIdentityCreateWithCertificater#   r.   rR   r   r   r2   popr-   r	   r/   	itertoolschainr1   )r   pathsr   r   	file_pathnew_identities	new_certsnew_identityr   trust_chainr8   objs               r   _load_client_cert_chainr   .  s   @ LJ -,e,,,E"* 	+ 	+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.2c                     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
   )	version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   r   )__doc__rV   r#   r   rs   rer4   r   rv   bindingsr   r   r   compileDOTALLr\   r   r!   r*   r:   rJ   rR   rf   rl   ro   r   r   r   r   r   r   r   r   <module>r      s          				 				 



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