3 ]/@sdZddlZddlZddlZddlZddlZddlZddlZddlm Z m Z m Z ej 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-----cCstjtj|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 M/tmp/pip-build-el9acr48/urllib3/urllib3/contrib/_securetransport/low_level.py_cf_data_from_bytessr cCsZt|}dd|D}dd|D}tj||}tj||}tjtj|||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 r-s)rr CFTypeRefZCFDictionaryCreaterZkCFTypeDictionaryKeyCallBacksZkCFTypeDictionaryValueCallBacks)ZtuplesZdictionary_sizekeysvaluesZcf_keysZ cf_valuesr r r _cf_dictionary_from_tuples%srcCsntj|tjtj}tj|tj}|dkrXtjd}tj ||dtj}|sRt d|j }|dk rj|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. Niz'Error copying C string from CFStringRefzutf-8) ctypescastPOINTERc_void_prZCFStringGetCStringPtrrZkCFStringEncodingUTF8create_string_bufferZCFStringGetCStringOSErrorvaluedecode)rZvalue_as_void_pstringbufferresultr r r _cf_string_to_unicode;s"  rcCs\|dkr dStj|d}t|}tj||dks:|dkrBd|}|dkrPtj}||dS)z[ Checks the return code and throws an exception if there is an error to report rNz OSStatus %s)rZSecCopyErrorMessageStringrr CFReleasesslSSLError)errorZexception_classZcf_error_stringoutputr r r _assert_no_errorXs  r%c Cs|jdd}ddtj|D}|s.tjdtjtjdtj tj }|sTtjdydx^|D]V}t |}|svtjdt j tj|}tj||stjdtj||tj|q\WWntk rtj|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|]}tj|jdqS)r)base64 b64decodegroup)r matchr r r vsz(_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_pemms4         r5cCstj}tj||kS)z= Returns True if a given CFTypeRef is a certificate. )rZSecCertificateGetTypeIDr CFGetTypeID)itemexpectedr r r _is_certsr9cCstj}tj||kS)z; Returns True if a given CFTypeRef is an identity. )rZSecIdentityGetTypeIDrr6)r7r8r r r _is_identitysr:cCstjd}tj|ddjd}tj|dd}tj}tjj||j d}t j }t j |t ||ddtj|}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. (Nzutf-8F)osurandomr' b16encodertempfilemkdtemppathjoinencoderZSecKeychainRefZSecKeychainCreaterrr0r%)Z random_bytesfilenamepasswordZ tempdirectoryZ keychain_pathkeychainstatusr r r _temporary_keychains  rIc Csg}g}d}t|d}|j}WdQRXztjtj|t|}tj}tj|ddddd|t j |}t |tj |} xdt | D]X} tj|| } t j| tj} t| rtj| |j| qt| rtj| |j| qWWd|rtj|tj|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)openreadrrrrZ CFArrayRefrZ SecItemImportrr0r%ZCFArrayGetCountrangeZCFArrayGetValueAtIndexrrr9ZCFRetainappendr:r ) rGrB certificates identitiesZ result_arrayfZ raw_filedataZfiledatarZ result_countindexr7r r r _load_items_from_filesH         rSc Gsg}g}dd|D}zx.|D]&}t||\}}|j||j|qW|stj}tj||dtj|}t||j|t j |j dt j t j dtjt j} x tj||D]} t j| | qW| Sxtj||D]} t j | qWXdS)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 rBr r r r2sz*_load_client_cert_chain..rN)rSextendrZSecIdentityRefZ SecIdentityCreateWithCertificaterr0r%rNrr popr/rr1 itertoolschainr2) rGpathsrOrP file_pathZnew_identitiesZ new_certsZ new_identityrHZ trust_chainr7objr r r _load_client_cert_chains6      r[)N)__doc__r'rrVrer=r!r@ZbindingsrrrcompileDOTALLr-r rrr%r5r9r:rIrSr[r r r r  s(   .(;