U oÏ a´.ã@s´dZddlZddlZddlZddlZddlZddlZddlZddlm Z m Z m Z e  dej ¡Zdd„Zdd „Zd d „Zdd d „Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„ZdS)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-----cCst tj|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 úwC:\Users\vtejo\AppData\Local\Temp\pip-unpacked-wheel-6mt8ur68\pip\_vendor\urllib3\contrib\_securetransport\low_level.pyÚ_cf_data_from_bytess ÿr cCsZt|ƒ}dd„|Dƒ}dd„|Dƒ}tj||Ž}tj||Ž}t tj|||tjtj¡S)zK Given a list of Python tuples, create an associated CFDictionary. css|]}|dVqdS)rNr ©Ú.0Útr r r Ú ,sz-_cf_dictionary_from_tuples..css|]}|dVqdS)rNr r r r r r-s)rrÚ CFTypeRefZCFDictionaryCreaterZkCFTypeDictionaryKeyCallBacksZkCFTypeDictionaryValueCallBacks)ZtuplesZdictionary_sizeÚkeysÚvaluesZcf_keysZ cf_valuesr r r Ú_cf_dictionary_from_tuples%súrcCsnt |t tj¡¡}t |tj¡}|dkrXt d¡}t  ||dtj¡}|sRt dƒ‚|j }|dk 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. Niz'Error copying C string from CFStringRefúutf-8) ÚctypesÚcastÚPOINTERÚc_void_prZCFStringGetCStringPtrrZkCFStringEncodingUTF8Úcreate_string_bufferZCFStringGetCStringÚOSErrorÚvalueÚdecode)rZvalue_as_void_pÚstringÚbufferÚresultr r r Ú_cf_string_to_unicode;s&ÿ ÿ r cCs\|dkr dSt |d¡}t|ƒ}t |¡|dks:|dkrBd|}|dkrPtj}||ƒ‚dS)z[ Checks the return code and throws an exception if there is an error to report rNÚz OSStatus %s)rZSecCopyErrorMessageStringr rÚ CFReleaseÚsslÚSSLError)ÚerrorZexception_classZcf_error_stringÚoutputr r r Ú_assert_no_errorTs  r'cCsØ| dd¡}dd„t |¡Dƒ}|s.t d¡‚t tjdt  tj ¡¡}|sTt d¡‚z`|D]V}t |ƒ}|stt d¡‚t   tj|¡}t |¡|sšt d¡‚t ||¡t |¡qZWntk rÒt |¡YnX|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 ó cSsg|]}t | d¡¡‘qS)r)Úbase64Ú b64decodeÚgroup)r Úmatchr r r Ú qsz(_cert_array_from_pem..zNo root certificates specifiedrzUnable to allocate memory!zUnable to build cert object!)ÚreplaceÚ _PEM_CERTS_REÚfinditerr#r$rÚCFArrayCreateMutablerrÚbyrefÚkCFTypeArrayCallBacksr rZSecCertificateCreateWithDatar"ÚCFArrayAppendValueÚ Exception)Z pem_bundleZ der_certsZ cert_arrayZ der_bytesZcertdataÚcertr r r Ú_cert_array_from_pemis< ÿ  ý  ÿ   r7cCst ¡}t |¡|kS)z= Returns True if a given CFTypeRef is a certificate. )rZSecCertificateGetTypeIDrÚ CFGetTypeID©ÚitemÚexpectedr r r Ú_is_cert–sr<cCst ¡}t |¡|kS)z; Returns True if a given CFTypeRef is an identity. )rZSecIdentityGetTypeIDrr8r9r r r Ú _is_identityžsr=c Cs†t d¡}t |dd…¡ d¡}t |dd…¡}t ¡}tj ||¡  d¡}t   ¡}t   |t |ƒ|ddt |¡¡}t|ƒ||fS)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érF)ÚosÚurandomr)Ú b16encoderÚtempfileÚmkdtempÚpathÚjoinÚencoderZSecKeychainRefZSecKeychainCreaterrr2r')Z random_bytesÚfilenameÚpasswordZ tempdirectoryZ keychain_pathÚkeychainÚstatusr r r Ú_temporary_keychain¦s  ÿrLc Csg}g}d}t|dƒ}| ¡}W5QRXz²t tj|t|ƒ¡}t ¡}t  |ddddd|t   |¡¡}t |ƒt  |¡} t| ƒD]X} t || ¡} t  | tj¡} t| ƒr¼t | ¡| | ¡q€t| ƒr€t | ¡| | ¡q€W5|rìt |¡t |¡X||fS)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Úreadrr"rrrZ CFArrayRefrZ SecItemImportrr2r'ZCFArrayGetCountÚrangeZCFArrayGetValueAtIndexrrr<ZCFRetainÚappendr=) rJrEÚ certificatesÚ identitiesZ result_arrayÚfZ raw_filedataZfiledatarZ result_countÚindexr:r r r Ú_load_items_from_fileÉsJ ÿø         rVc Gsêg}g}dd„|Dƒ}z°|D]&}t||ƒ\}}| |¡| |¡q|sŠt ¡}t ||dt   |¡¡} t | ƒ|  |¡t |  d¡¡t tjdt   tj¡¡} t ||¡D]} t | | ¡q®| W¢St ||¡D]}t |¡qÔXdS)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. css|]}|r|VqdS)Nr )r rEr r r r$sz*_load_client_cert_chain..rN)Ú itertoolsÚchainrr"rVÚextendrZSecIdentityRefZ SecIdentityCreateWithCertificaterr2r'rQÚpopr1rr3r4) rJÚpathsrRrSÚobjÚ file_pathZnew_identitiesZ new_certsZ new_identityrKZ trust_chainr:r r r Ú_load_client_cert_chains8   ÿ  ýr^)N)Ú__doc__r)rrWÚrer@r#rCZbindingsrrrÚcompileÚDOTALLr/r rr r'r7r<r=rLrVr^r r r r Ús, ÿ  -#7