ó Eu\dc@s<dZddlZddlZddlZddlZddlZddlZddlZddlZddl m Z m Z m Z ej dejƒZd„Zd„Zd„Zd „Zd „Zdd „Zd „Zd „Zd„Zd„Zd„Zd„Zidd6dd6dd6dd6dd6Zd„ZdS( s¦ 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. iÿÿÿÿNi(tCFConsttCoreFoundationtSecuritys;-----BEGIN CERTIFICATE----- (.*?) -----END CERTIFICATE-----cCstjtj|t|ƒƒS(sv Given a bytestring, create a CFData object from it. This CFData object must be CFReleased by the caller. (Rt CFDataCreatetkCFAllocatorDefaulttlen(t bytestring((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pyt_cf_data_from_bytesscCswt|ƒ}d„|Dƒ}d„|Dƒ}tj||Œ}tj||Œ}tjtj|||tjtjƒS(sK Given a list of Python tuples, create an associated CFDictionary. css|]}|dVqdS(iN((t.0tt((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pys ,scss|]}|dVqdS(iN((RR ((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pys -s(RRt CFTypeReftCFDictionaryCreateRtkCFTypeDictionaryKeyCallBackstkCFTypeDictionaryValueCallBacks(ttuplestdictionary_sizetkeystvaluestcf_keyst cf_values((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pyt_cf_dictionary_from_tuples%s cCs.tj|ƒ}tjtj|tjƒ}|S(si Given a Python binary data, create a CFString. The string must be CFReleased by the caller. (tctypestc_char_pRtCFStringCreateWithCStringRRtkCFStringEncodingUTF8(tpy_bstrtc_strtcf_str((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pyt_cfstr;s  cCsàd}y”tjtjdtjtjƒƒ}|sBtdƒ‚nxT|D]L}t|ƒ}|sptdƒ‚nztj ||ƒWdtj |ƒXqIWWn?t k rÛ}|rÂtj |ƒnt j d|fƒ‚nX|S(sª 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. isUnable to allocate memory!NsUnable to allocate array: %s(tNoneRtCFArrayCreateMutableRRtbyreftkCFTypeArrayCallBackst MemoryErrorRtCFArrayAppendValuet CFReleaset BaseExceptiontssltSSLError(tlsttcf_arrtitemRte((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pyt_create_cfstring_arrayIs(  cCs¬tj|tjtjƒƒ}tj|tjƒ}|dkrŠtj dƒ}tj ||dtjƒ}|s~t dƒ‚n|j }n|dk r¨|j dƒ}n|S(s¨ 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. is'Error copying C string from CFStringRefsutf-8N(RtcasttPOINTERtc_void_pRtCFStringGetCStringPtrRRRtcreate_string_buffertCFStringGetCStringtOSErrortvaluetdecode(R3tvalue_as_void_ptstringtbuffertresult((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pyt_cf_string_to_unicodehs   cCsˆ|dkrdStj|dƒ}t|ƒ}tj|ƒ|dksS|dkr`d|}n|dkrxtj}n||ƒ‚dS(s[ Checks the return code and throws an exception if there is an error to report iNuu OSStatus %s(RtSecCopyErrorMessageStringRR9RR#R%R&(terrortexception_classtcf_error_stringtoutput((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pyt_assert_no_errors      cCsR|jddƒ}gtj|ƒD]}tj|jdƒƒ^q"}|s^tjdƒ‚ntj tj dt j tj ƒƒ}|sštjdƒ‚nyx‰|D]}t|ƒ}|sÎtjdƒ‚ntjtj |ƒ}tj|ƒ|stjdƒ‚ntj||ƒtj|ƒq¤WWn!tk rMtj|ƒ‚nX|S(s‚ 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 s isNo root certificates specifiedisUnable to allocate memory!sUnable to build cert object!(treplacet _PEM_CERTS_REtfinditertbase64t b64decodetgroupR%R&RRRRRR RRtSecCertificateCreateWithDataR#R"t Exception(t pem_bundletmatcht der_certst cert_arrayt der_bytestcertdatatcert((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pyt_cert_array_from_pem–s44     cCstjƒ}tj|ƒ|kS(s= Returns True if a given CFTypeRef is a certificate. (RtSecCertificateGetTypeIDRt CFGetTypeID(R)texpected((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pyt_is_certÄs cCstjƒ}tj|ƒ|kS(s; Returns True if a given CFTypeRef is an identity. (RtSecIdentityGetTypeIDRRQ(R)RR((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pyt _is_identityÌs cCsµtjdƒ}tj|d ƒjdƒ}tj|dƒ}tjƒ}tjj||ƒj dƒ}t j ƒ}t j |t |ƒ|tdtj|ƒƒ}t|ƒ||fS(s³ 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. i(isutf-8N(tosturandomRCt b16encodeR4ttempfiletmkdtemptpathtjointencodeRtSecKeychainReftSecKeychainCreateRtFalseRRRR?(t random_bytestfilenametpasswordt tempdirectoryt keychain_pathtkeychaintstatus((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pyt_temporary_keychainÔs  ' c Cskg}g}d}t|dƒ}|jƒ}WdQXztjtj|t|ƒƒ}tjƒ}tj |ddddd|t j |ƒƒ}t |ƒtj |ƒ} xt| ƒD]} tj|| ƒ} t j| tjƒ} t| ƒr tj| ƒ|j| ƒq¶t| ƒr¶tj| ƒ|j| ƒq¶q¶WWd|rStj|ƒntj|ƒX||fS(sÊ 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. trbNi(RtopentreadRRRRt CFArrayRefRt SecItemImportRRR?tCFArrayGetCounttrangetCFArrayGetValueAtIndexR,R RStCFRetaintappendRUR#( RfR[t certificatest identitiest result_arraytft raw_filedatatfiledataR8t result_counttindexR)((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pyt_load_items_from_file÷sB      c GsKg}g}d„|Dƒ}zýx=|D]5}t||ƒ\}}|j|ƒ|j|ƒq&W|sÃtjƒ}tj||dtj|ƒƒ}t|ƒ|j|ƒt j |j dƒƒnt j t j dtjt jƒƒ} x*tj||ƒD]} t j| | ƒqúW| SWdx'tj||ƒD]} t j | ƒq/WXdS(sü 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(N((RR[((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pys RsiN(R{textendRtSecIdentityReft SecIdentityCreateWithCertificateRRR?RrRR#tpopRRR t itertoolstchainR"( RftpathsRsRtt file_pathtnew_identitiest new_certst new_identityRgt trust_chainR)tobj((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pyt_load_client_cert_chain.s0      iitSSLv2itSSLv3tTLSv1sTLSv1.1sTLSv1.2c Csft|\}}d}d}tjd||ƒ}t|ƒ}d}tjd||||ƒ|}|S(s6 Builds a TLS alert record for an unknown CA. ii0s>BBis>BBBH(tTLS_PROTOCOL_VERSIONStstructtpackR( tversiontver_majtver_mintseverity_fataltdescription_unknown_catmsgtmsg_lentrecord_type_alerttrecord((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pyt_build_tls_unknown_ca_alert‚s (ii(ii(ii(ii(ii(t__doc__RCRR€RVtreR%RŽRYtbindingsRRRtcompiletDOTALLRARRRR+R9RR?RORSRURhR{R‰RR™(((sƒ/private/var/folders/49/mc35vj0j30g7w0ryjvyy2vz80000gs/T/pip-target-MP7kiJ/lib/python/urllib3/contrib/_securetransport/low_level.pyt s<              .   # 7 K