U Őd_.@sdZddlZddlZddlZddlZddlZddlZddlZddlm Z m Z m Z e dej ZddZdd Zd d Zdd d ZddZddZddZddZddZddZdS)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)SecurityCoreFoundationCFConsts;-----BEGIN CERTIFICATE----- (.*?) -----END CERTIFICATE-----cCsttj|t|S)zv Given a bytestring, create a CFData object from it. This CFData object must be CFReleased by the caller. )r CFDataCreatekCFAllocatorDefaultlen)Z bytestringr qC:\Users\aemmanux\AppData\Local\Temp\pip-target-bnng1y30\lib\python\urllib3/contrib/_securetransport/low_level.py_cf_data_from_bytess r cCsZt|}dd|D}dd|D}tj||}tj||}ttj|||tjtjS)zK Given a list of Python tuples, create an associated CFDictionary. css|]}|dVqdS)rNr .0tr r r ,sz-_cf_dictionary_from_tuples..css|]}|dVqdS)rNr r r r r r-s)rr CFTypeRefZCFDictionaryCreaterZkCFTypeDictionaryKeyCallBacksZkCFTypeDictionaryValueCallBacks)ZtuplesZdictionary_sizekeysvaluesZcf_keysZ cf_valuesr r r _cf_dictionary_from_tuples%srcCsnt|ttj}t|tj}|dkrXtd}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 CFStringRefutf-8) ctypescastPOINTERc_void_prZCFStringGetCStringPtrrZkCFStringEncodingUTF8create_string_bufferZCFStringGetCStringOSErrorvaluedecode)rZvalue_as_void_pstringbufferresultr 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 rNz OSStatus %s)rZSecCopyErrorMessageStringr r CFReleasesslSSLError)errorZexception_classZcf_error_stringoutputr r r _assert_no_errorTs  r'cCs|dd}ddt|D}|s.tdttjdt tj }|sTtdz`|D]V}t |}|sttdt tj|}t||stdt||t|qZWntk rt|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|dqS)r)base64 b64decodegroup)r matchr r r qsz(_cert_array_from_pem..zNo root certificates specifiedrzUnable to allocate memory!zUnable to build cert object!)replace _PEM_CERTS_REfinditerr#r$rCFArrayCreateMutablerrbyrefkCFTypeArrayCallBacksr rZSecCertificateCreateWithDatar"CFArrayAppendValue Exception)Z pem_bundleZ der_certsZ cert_arrayZ der_bytesZcertdatacertr r r _cert_array_from_pemis<        r7cCst}t||kS)z= Returns True if a given CFTypeRef is a certificate. )rZSecCertificateGetTypeIDr CFGetTypeIDitemexpectedr r r _is_certsr<cCst}t||kS)z; Returns True if a given CFTypeRef is an identity. )rZSecIdentityGetTypeIDrr8r9r r r _is_identitysr=c Cstd}t|ddd}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. (NrF)osurandomr) b16encodertempfilemkdtemppathjoinencoderZSecKeychainRefZSecKeychainCreaterrr2r')Z random_bytesfilenamepasswordZ tempdirectoryZ keychain_pathkeychainstatusr r r _temporary_keychains  rLc Csg}g}d}t|d}|}W5QRXzttj|t|}t}t |ddddd|t |}t |t |} t| D]X} t|| } t | tj} t| rt| || qt| rt| || qW5|rt|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. Nrbr)openreadrr"rrrZ CFArrayRefrZ SecItemImportrr2r'ZCFArrayGetCountrangeZCFArrayGetValueAtIndexrrr<ZCFRetainappendr=) rJrE certificates identitiesZ result_arrayfZ raw_filedataZfiledatarZ result_countindexr:r r r _load_items_from_filesJ          rVc Gsg}g}dd|D}z|D]&}t||\}}||||q|st}t||dt |} t | | |t| dttjdt tj} t||D]} t| | q| WSt||D]}t|qXdS)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) itertoolschainrr"rVextendrZSecIdentityRefZ SecIdentityCreateWithCertificaterr2r'rQpopr1rr3r4) rJpathsrRrSobj file_pathZnew_identitiesZ new_certsZ new_identityrKZ trust_chainr:r r r _load_client_cert_chains8     r^)N)__doc__r)rrWrer@r#rCZbindingsrrrcompileDOTALLr/r rr r'r7r<r=rLrVr^r r r r s,   -#7