ó
h#ñ]c           @   sì   d  Z  d d l Z d d l Z d d l Z d d l Z d d l Z d d l Z d d l Z d d l m	 Z	 m
 Z
 m Z e j d e j ƒ Z d „  Z d „  Z d „  Z d d	 „ Z d
 „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d S(   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   (   t   Securityt   CoreFoundationt   CFConsts;   -----BEGIN CERTIFICATE-----
(.*?)
-----END CERTIFICATE-----c         C   s   t  j t  j |  t |  ƒ ƒ S(   sv   
    Given a bytestring, create a CFData object from it. This CFData object must
    be CFReleased by the caller.
    (   R   t   CFDataCreatet   kCFAllocatorDefaultt   len(   t
   bytestring(    (    s_   /data/av2000/b2b/venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pyt   _cf_data_from_bytes   s    c         C   sw   t  |  ƒ } d „  |  Dƒ } d „  |  Dƒ } t j | | Œ  } t j | | Œ  } t j t j | | | t j t j ƒ S(   sK   
    Given a list of Python tuples, create an associated CFDictionary.
    c         s   s   |  ] } | d  Vq d S(   i    N(    (   t   .0t   t(    (    s_   /data/av2000/b2b/venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pys	   <genexpr>,   s    c         s   s   |  ] } | d  Vq d S(   i   N(    (   R   R	   (    (    s_   /data/av2000/b2b/venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pys	   <genexpr>-   s    (   R   R   t	   CFTypeReft   CFDictionaryCreateR   t   kCFTypeDictionaryKeyCallBackst   kCFTypeDictionaryValueCallBacks(   t   tuplest   dictionary_sizet   keyst   valuest   cf_keyst	   cf_values(    (    s_   /data/av2000/b2b/venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pyt   _cf_dictionary_from_tuples%   s    c         C   s¬   t  j |  t  j t  j ƒ ƒ } t j | t j ƒ } | d k rŠ t  j	 d ƒ } t j
 | | d t j ƒ } | s~ t d ƒ ‚ n  | j } n  | d k	 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.
    i   s'   Error copying C string from CFStringRefs   utf-8N(   t   ctypest   castt   POINTERt   c_void_pR   t   CFStringGetCStringPtrR   t   kCFStringEncodingUTF8t   Nonet   create_string_buffert   CFStringGetCStringt   OSErrort   valuet   decode(   R   t   value_as_void_pt   stringt   buffert   result(    (    s_   /data/av2000/b2b/venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pyt   _cf_string_to_unicode;   s"    c         C   sˆ   |  d k r d St  j |  d ƒ } t | ƒ } t j | ƒ | d k sS | d k r` d |  } n  | d k rx t j } n  | | ƒ ‚ d S(   s[   
    Checks the return code and throws an exception if there is an error to
    report
    i    Nu    u   OSStatus %s(   R    t   SecCopyErrorMessageStringR   R%   R   t	   CFReleaset   sslt   SSLError(   t   errort   exception_classt   cf_error_stringt   output(    (    s_   /data/av2000/b2b/venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pyt   _assert_no_errorX   s    c         C   sO  |  j  d d ƒ }  g  t j |  ƒ D] } t j | j d ƒ ƒ ^ q" } | s^ t j d ƒ ‚ n  t j	 t j
 d t j t j ƒ ƒ } | sš t j d ƒ ‚ n  y x‰ | D] } t | ƒ } | sÎ t j d ƒ ‚ n  t j t j
 | ƒ } t j | ƒ | st j d ƒ ‚ n  t j | | ƒ t j | ƒ q¤ WWn t k
 rJt j | ƒ n X| 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   
i   s   No root certificates specifiedi    s   Unable to allocate memory!s   Unable to build cert object!(   t   replacet   _PEM_CERTS_REt   finditert   base64t	   b64decodet   groupR(   R)   R   t   CFArrayCreateMutableR   R   t   byreft   kCFTypeArrayCallBacksR   R    t   SecCertificateCreateWithDataR'   t   CFArrayAppendValuet	   Exception(   t
   pem_bundlet   matcht	   der_certst
   cert_arrayt	   der_bytest   certdatat   cert(    (    s_   /data/av2000/b2b/venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pyt   _cert_array_from_pemm   s4    1c         C   s   t  j ƒ  } t j |  ƒ | k S(   s=   
    Returns True if a given CFTypeRef is a certificate.
    (   R    t   SecCertificateGetTypeIDR   t   CFGetTypeID(   t   itemt   expected(    (    s_   /data/av2000/b2b/venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pyt   _is_cert›   s    c         C   s   t  j ƒ  } t j |  ƒ | k S(   s;   
    Returns True if a given CFTypeRef is an identity.
    (   R    t   SecIdentityGetTypeIDR   RD   (   RE   RF   (    (    s_   /data/av2000/b2b/venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pyt   _is_identity£   s    c          C   sµ   t  j d ƒ }  t j |  d  ƒ j d ƒ } t j |  d ƒ } t j ƒ  } t  j j | | ƒ j	 d ƒ } t
 j ƒ  } t
 j | t | ƒ | t d t j | ƒ ƒ } t | ƒ | | f S(   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(   i   s   utf-8N(   t   ost   urandomR2   t	   b16encodeR    t   tempfilet   mkdtempt   patht   joint   encodeR    t   SecKeychainReft   SecKeychainCreateR   t   FalseR   R   R6   R.   (   t   random_bytest   filenamet   passwordt   tempdirectoryt   keychain_patht   keychaint   status(    (    s_   /data/av2000/b2b/venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pyt   _temporary_keychain«   s    	
c         C   sk  g  } g  } d } t | d ƒ  } | j ƒ  } Wd QXzt j t j | t | ƒ ƒ } t j ƒ  } t j	 | d d d d d |  t
 j | ƒ ƒ } t | ƒ t j | ƒ }	 x t |	 ƒ D] }
 t j | |
 ƒ } t
 j | t j ƒ } t | ƒ rt j | ƒ | j | ƒ q¶ t | ƒ r¶ t j | ƒ | j | ƒ q¶ q¶ WWd | rSt j | ƒ n  t j | ƒ X| | f S(   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.
    t   rbNi    (   R   t   opent   readR   R   R   R   t
   CFArrayRefR    t   SecItemImportR   R6   R.   t   CFArrayGetCountt   ranget   CFArrayGetValueAtIndexR   R
   RG   t   CFRetaint   appendRI   R'   (   RZ   RO   t   certificatest
   identitiest   result_arrayt   ft   raw_filedatat   filedataR$   t   result_countt   indexRE   (    (    s_   /data/av2000/b2b/venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pyt   _load_items_from_fileÓ   sH    
c         G   sK  g  } g  } d „  | Dƒ } zý x= | D]5 } t  |  | ƒ \ } } | j | ƒ | j | ƒ q& W| sÃ t j ƒ  } t j |  | d t j | ƒ ƒ } t | ƒ | j | ƒ t	 j
 | j d ƒ ƒ n  t	 j t	 j d t j t	 j ƒ ƒ }	 x* t j | | ƒ D] }
 t	 j |	 |
 ƒ qú W|	 SWd x' t j | | ƒ D] } t	 j
 | ƒ q/WXd S(   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.
    c         s   s   |  ] } | r | Vq d  S(   N(    (   R   RO   (    (    s_   /data/av2000/b2b/venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pys	   <genexpr>2  s    i    N(   Ro   t   extendR    t   SecIdentityReft    SecIdentityCreateWithCertificateR   R6   R.   Rf   R   R'   t   popR5   R   R7   t	   itertoolst   chainR9   (   RZ   t   pathsRg   Rh   t	   file_patht   new_identitiest	   new_certst   new_identityR[   t   trust_chainRE   t   obj(    (    s_   /data/av2000/b2b/venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pyt   _load_client_cert_chain  s6     
(   t   __doc__R2   R   Rt   t   reRJ   R(   RM   t   bindingsR    R   R   t   compilet   DOTALLR0   R   R   R%   R   R.   RB   RG   RI   R\   Ro   R}   (    (    (    s_   /data/av2000/b2b/venv/lib/python2.7/site-packages/urllib3/contrib/_securetransport/low_level.pyt   <module>	   s(   	
			.			(	;