o ?cb6@sdZddlZddlZddlZddlZddlZddlZddlZddlZddl m Z m Z m Z e dejZddZdd Zd d Zd d ZddZd&ddZddZddZddZddZddZddZddd d!d"d#Zd$d%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)CFConstCoreFoundationSecuritys;-----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 /private/var/folders/cw/wlscbxl13mj6wd668h7l9g9sllkg5j/T/pip-target-b31awkwq/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. cs|]}|dVqdS)rNr .0tr r r ,z-_cf_dictionary_from_tuples..csr )rNr r r r r r-r)rr CFTypeRefZCFDictionaryCreaterZkCFTypeDictionaryKeyCallBacksZkCFTypeDictionaryValueCallBacks)ZtuplesZdictionary_sizekeysvaluesZcf_keysZ cf_valuesr r r _cf_dictionary_from_tuples%srcCs t|}ttj|tj}|S)zi Given a Python binary data, create a CFString. The string must be CFReleased by the caller. )ctypesc_char_prZCFStringCreateWithCStringrrkCFStringEncodingUTF8)Zpy_bstrZc_strcf_strr r r _cfstr;s rc Csd}z7ttjdttj}|std|D]}t|}|s#tdz t||Wt |qt |wW|St yT}z|rHt |t d|fd}~ww)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. NrUnable to allocate memory!zUnable to allocate array: %s) rCFArrayCreateMutablerrbyrefkCFTypeArrayCallBacks MemoryErrorrCFArrayAppendValue CFRelease BaseExceptionsslSSLError)lstZcf_arritemrer r r _create_cfstring_arrayIs0   r(cCsnt|ttj}t|tj}|dur,td}t ||dtj}|s)t d|j }|dur5| 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) rcastZPOINTERZc_void_prZCFStringGetCStringPtrrrZcreate_string_bufferZCFStringGetCStringOSErrorvaluedecode)r,Zvalue_as_void_pstringbufferresultr r r _cf_string_to_unicodehs   r1cCsX|dkrdSt|d}t|}t||dus|dkr!d|}|dur(tj}||)z[ Checks the return code and throws an exception if there is an error to report rNz OSStatus %s)rZSecCopyErrorMessageStringr1rr!r#r$)errorZexception_classZcf_error_stringoutputr r r _assert_no_errors  r5cCs|dd}ddt|D}|stdttjdt tj }|s*tdz1|D]+}t |}|s:tdt tj|}t||sMtdt||t|q-W|Styht|w) 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)rmatchr r r sz(_cert_array_from_pem..zNo root certificates specifiedrrzUnable to build cert object!)replace _PEM_CERTS_REfinditerr#r$rrrrrrr rZSecCertificateCreateWithDatar!r Exception)Z pem_bundleZ der_certsZ cert_arrayZ der_bytesZcertdatacertr r r _cert_array_from_pems@          rAcCt}t||kS)z= Returns True if a given CFTypeRef is a certificate. )rZSecCertificateGetTypeIDr CFGetTypeIDr&expectedr r r _is_certrFcCrB)z; Returns True if a given CFTypeRef is an identity. )rZSecIdentityGetTypeIDrrCrDr r r _is_identityrGrHc 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. (Nr)F)osurandomr7 b16encoder-tempfilemkdtemppathjoinencoderZSecKeychainRefZSecKeychainCreaterrrr5)Z random_bytesfilenamepasswordZ tempdirectoryZ keychain_pathkeychainstatusr r r _temporary_keychains rWc Cs*g}g}d}t|d }|}Wdn1swYzhttj|t|}t}t|ddddd|t |}t |t |} t | D],} t|| } t | tj} t| rht| || qJt| rvt| || qJW|rt|t|||fS|rt|t|w)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)openreadrrrrZ CFArrayRefrZ SecItemImportrrr5ZCFArrayGetCountrangeZCFArrayGetValueAtIndexr*rrFZCFRetainappendrHr!) rUrP certificates identitiesZ result_arrayfZ raw_filedataZfiledatar0Z result_countindexr&r r r _load_items_from_filesR              rac Gsg}g}dd|D}ze|D]}t||\}}||||q|sEt}t||dt|}t|||t | dt t j dtt j} t||D]} t | | qW| Wt||D]} t | qhSt||D]} t | qww)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|VqdSNr )rrPr r r rRrz*_load_client_cert_chain..r)raextendrZSecIdentityRefZ SecIdentityCreateWithCertificaterrr5r\rr!poprrr itertoolschainr ) rUpathsr]r^ file_pathZnew_identitiesZ new_certsZ new_identityrVZ trust_chainr&objr r r _load_client_cert_chain.s:       rj)r)r)rlr)rlrk)rlrl)ZSSLv2SSLv3TLSv1zTLSv1.1zTLSv1.2c CsHt|\}}d}d}td||}t|}d}td|||||}|S)z6 Builds a TLS alert record for an unknown CA. rk0z>BBz>BBBH)TLS_PROTOCOL_VERSIONSstructpackr) versionZver_majZver_minZseverity_fatalZdescription_unknown_camsgZmsg_lenZrecord_type_alertrecordr r r _build_tls_unknown_ca_alerts rwrb)__doc__r7rrerKrer#rrrNZbindingsrrrcompileDOTALLr=r rrr(r1r5rArFrHrWrarjrqrwr r r r s@   .#7L