3
nf\/ @ s d Z ddlZddlZddlZddlZddlZddlZddlZddlm Z m
Z
mZ ejdej
Zdd Zdd Zd
d Zddd
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 )SecurityCoreFoundationCFConsts; -----BEGIN CERTIFICATE-----
(.*?)
-----END CERTIFICATE-----c C s t jt j| t| S )zv
Given a bytestring, create a CFData object from it. This CFData object must
be CFReleased by the caller.
)r CFDataCreatekCFAllocatorDefaultlen)Z
bytestring r /usr/lib/python3.6/low_level.py_cf_data_from_bytes s r c C sZ t | }dd | D }dd | D }tj| | }tj| | }tjtj|||tjtjS )zK
Given a list of Python tuples, create an associated CFDictionary.
c s s | ]}|d V qdS )r Nr ).0tr r r
, s z-_cf_dictionary_from_tuples..c s s | ]}|d V qdS )r Nr )r r
r r r
r - s )r r CFTypeRefZCFDictionaryCreater ZkCFTypeDictionaryKeyCallBacksZkCFTypeDictionaryValueCallBacks)ZtuplesZdictionary_sizekeysvaluesZcf_keysZ cf_valuesr r r
_cf_dictionary_from_tuples% s r c C sn t j| t jt j}tj|tj}|dkrXt jd}tj ||dtj}|sRt
d|j}|dk rj|jd}|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.
Ni z'Error copying C string from CFStringRefzutf-8)
ctypescastZPOINTERZc_void_pr ZCFStringGetCStringPtrr ZkCFStringEncodingUTF8Zcreate_string_bufferZCFStringGetCStringOSErrorvaluedecode)r Zvalue_as_void_pstringbufferresultr r r
_cf_string_to_unicode; s"
r c C s\ | dkrdS t j| d}t|}tj| |dks:|dkrBd| }|dkrPtj}||dS )z[
Checks the return code and throws an exception if there is an error to
report
r N zOSStatus %s)r ZSecCopyErrorMessageStringr r CFReleasesslSSLError)errorZexception_classZcf_error_stringoutputr r r
_assert_no_errorX s
r" c C s | j dd} dd tj| D }|s.tjdtjtjdtj tj
}|sTtjdydx^|D ]V}t|}|svtjdtj
tj|}tj| |stjdtj|| tj| q\W W n tk
r tj| Y nX |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
c S s g | ]}t j|jd qS )r )base64Z b64decodegroup)r matchr r r
v s z(_cert_array_from_pem..zNo root certificates specifiedr zUnable to allocate memory!zUnable to build cert object!)replace
_PEM_CERTS_REfinditerr r r CFArrayCreateMutabler r byrefkCFTypeArrayCallBacksr r ZSecCertificateCreateWithDatar CFArrayAppendValue Exception)Z
pem_bundleZ der_certsZ
cert_arrayZ der_bytesZcertdataZcertr r r
_cert_array_from_pemm s4
r0 c C s t j }tj| |kS )z=
Returns True if a given CFTypeRef is a certificate.
)r ZSecCertificateGetTypeIDr CFGetTypeID)itemexpectedr r r
_is_cert s r4 c C s t j }tj| |kS )z;
Returns True if a given CFTypeRef is an identity.
)r ZSecIdentityGetTypeIDr r1 )r2 r3 r r r
_is_identity s r5 c C s t jd} tj| dd jd}tj| dd }tj }t jj||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.
( N zutf-8F)osurandomr$ Z b16encoder tempfileZmkdtemppathjoinencoder ZSecKeychainRefZSecKeychainCreater r r, r" )Zrandom_bytesfilenameZpasswordZ
tempdirectoryZ
keychain_pathkeychainstatusr r r
_temporary_keychain s
rA c C s g }g }d}t |d}|j }W dQ R X ztjtj|t|}tj }tj|ddddd| t j
|}t| tj|} xdt
| D ]X}
tj||
}t j|tj}t|rtj| |j| qt|rtj| |j| qW W d|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 )openreadr r r r Z
CFArrayRefr Z
SecItemImportr r, r" ZCFArrayGetCountrangeZCFArrayGetValueAtIndexr r r4 ZCFRetainappendr5 r )r? r; certificates
identitiesZresult_arrayfZraw_filedataZfiledatar Zresult_countindexr2 r r r
_load_items_from_file sH
rK c G s g }g }dd |D }zx.|D ]&}t | |\}}|j| |j| qW |stj }tj| |d tj|}t| |j| t j
|jd t jt j
dtjt j} x tj||D ]}
t j| |
qW | S xtj||D ]}t j
| qW X dS )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.
c s s | ]}|r|V qd S )Nr )r r; r r r
r 2 s z*_load_client_cert_chain..r N)rK extendr ZSecIdentityRefZ SecIdentityCreateWithCertificater r, r" rF r r popr+ r r- itertoolschainr. )r? pathsrG rH Z file_pathZnew_identitiesZ new_certsZnew_identityr@ Ztrust_chainr2 objr r r
_load_client_cert_chain s6
rR )N)__doc__r$ r rN rer8 r r: Zbindingsr r r compileDOTALLr) r r r r" r0 r4 r5 rA rK rR r r r r
s(
.(;