
DY~1                @   sX  d  d l  Z  d  d l Z d  d l m Z d  d l m Z m Z d  d l m Z m	 Z	 d  d l
 m Z d  d l m Z d  d l m Z d  d l m Z m Z m Z m Z d  d	 l m Z m Z m Z m Z m Z  m! Z" m# Z$ m% Z& m' Z( d  d
 l) m* Z* m+ Z+ m, Z, m- Z- m. Z. m/ Z/ y
 e0 Z1 Wn( e2 k
 rHGd d   d e3  Z1 Yn Xy
 e4 Z5 Wn( e2 k
 r}Gd d   d e3  Z5 Yn Xe j6 Z6 e j7 Z7 e j8 Z8 e j9 Z9 e j: Z: e j; Z; e j< Z= e j> Z? d Z@ d ZA d ZB d ZC d ZD d ZE e jF ZG e jH ZI e jJ ZK e jL ZM e jN ZO e jP ZQ e jR ZS e jT ZU e jV ZW e jX ZY e jZ Z[ e j\ Z] e j^ Z_ e j` Za e jb Zc e jd Ze e jf Zg e jh Zi e jj Zk e jl Zm e jn Zo e jp Zq e jr Zs e jt Zu e jv Zw e jx Zy e jz Z{ e j| Z} e j~ Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j re j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z e j Z d d d d d g Z d g Z d Z d Z Gd d   d e  Z e e e  Z e  e  Z Gd d    d  e  Z Gd! d"   d" e  Z Gd# d$   d$ e  Z Gd% d&   d& e  Z Gd' d(   d( e  Z Gd) d*   d* e3  Z Gd+ d,   d, e  Z Gd- d.   d. e  Z Gd/ d0   d0 e  Z Gd1 d2   d2 e  Z Gd3 d4   d4 e  Z Gd5 d6   d6 e  Z d7 d8   Z d9 d:   Z d; d<   Z e e j d=  Z e e j d>  Z e e j d?  Z Gd@ dA   dA e3  Z GdB dC   dC e3  Z e e e dD e  Z GdE dF   dF e3  Z e e e dG e  Z e j   d S)H    N)platform)wrapspartial)countchain)WeakValueDictionary)	errorcode)
deprecated)binary_typeinteger_typesint2byte
indexbytes)	UNSPECIFIEDexception_from_error_queueffilibmake_assertnativepath_stringtext_to_bytes_and_warnno_zero_allocator)FILETYPE_PEM_PassphraseHelperPKeyX509NameX509	X509Storec               @   s   e  Z d  Z d S)_memoryviewN)__name__
__module____qualname__ r!   r!   -/usr/lib/python3/dist-packages/OpenSSL/SSL.pyr   !   s   r   c               @   s   e  Z d  Z d S)_bufferN)r   r   r    r!   r!   r!   r"   r#   '   s   r#                     z"/etc/ssl/certs/ca-certificates.crtz /etc/pki/tls/certs/ca-bundle.crtz/etc/ssl/ca-bundle.pemz/etc/pki/tls/cacert.pemz1/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pemz/etc/ssl/certss$   /opt/pyca/cryptography/openssl/certss'   /opt/pyca/cryptography/openssl/cert.pemc               @   s   e  Z d  Z d Z d S)Errorz4
    An error occurred in an `OpenSSL.SSL` API.
    N)r   r   r    __doc__r!   r!   r!   r"   r*      s   r*   c               @   s   e  Z d  Z d S)WantReadErrorN)r   r   r    r!   r!   r!   r"   r,      s   r,   c               @   s   e  Z d  Z d S)WantWriteErrorN)r   r   r    r!   r!   r!   r"   r-      s   r-   c               @   s   e  Z d  Z d S)WantX509LookupErrorN)r   r   r    r!   r!   r!   r"   r.      s   r.   c               @   s   e  Z d  Z d S)ZeroReturnErrorN)r   r   r    r!   r!   r!   r"   r/      s   r/   c               @   s   e  Z d  Z d S)SysCallErrorN)r   r   r    r!   r!   r!   r"   r0      s   r0   c               @   s.   e  Z d  Z d Z d d   Z d d   Z d S)_CallbackExceptionHelpera  
    A base class for wrapper classes that allow for intelligent exception
    handling in OpenSSL callbacks.

    :ivar list _problems: Any exceptions that occurred while executing in a
        context where they could not be raised in the normal way.  Typically
        this is because OpenSSL has called into some Python code and requires a
        return value.  The exceptions are saved to be raised later when it is
        possible to do so.
    c             C   s   g  |  _  d  S)N)	_problems)selfr!   r!   r"   __init__   s    z!_CallbackExceptionHelper.__init__c             C   s?   |  j  r; y t   Wn t k
 r( Yn X|  j  j d   d S)z
        Raise an exception from the OpenSSL error queue or that was previously
        captured whe running a callback.
        r   N)r2   _raise_current_errorr*   pop)r3   r!   r!   r"   raise_if_problem   s    	z)_CallbackExceptionHelper.raise_if_problemN)r   r   r    r+   r4   r7   r!   r!   r!   r"   r1      s   
r1   c               @   s"   e  Z d  Z d Z d d   Z d S)_VerifyHelperz^
    Wrap a callback such that it can be used as a certificate verification
    callback.
    c                sG   t  j   t       f d d    } t j d |   _ d  S)Nc       
         s   t  j t   } t j |  | _ t j |  } t j |  } t j   } t j | |  } t	 j
 | } y   | | | | |   } Wn9 t k
 r }	 z  j j |	  d SWYd  d  }	 ~	 Xn" X| r t j | t j  d Sd Sd  S)Nr   r$   )r   __new___libZX509_STORE_CTX_get_current_cert_x509ZX509_STORE_CTX_get_errorZX509_STORE_CTX_get_error_depthZ"SSL_get_ex_data_X509_STORE_CTX_idxZX509_STORE_CTX_get_ex_data
Connection_reverse_mapping	Exceptionr2   appendZX509_STORE_CTX_set_errorZ	X509_V_OK)
okZ	store_ctxcertZerror_numberZerror_depthindexsslZ
connectionresulte)callbackr3   r!   r"   wrapper   s"    z'_VerifyHelper.__init__.<locals>.wrapperzint (*)(int, X509_STORE_CTX *))r1   r4   r   _ffirF   )r3   rF   rG   r!   )rF   r3   r"   r4      s    !z_VerifyHelper.__init__N)r   r   r    r+   r4   r!   r!   r!   r"   r8      s   r8   c               @   s"   e  Z d  Z d Z d d   Z d S)_NpnAdvertiseHelperzT
    Wrap a callback such that it can be used as an NPN advertisement callback.
    c                sG   t  j   t       f d d    } t j d |   _ d  S)Nc                s   y t  j |  }   |  } d j t j d d   | D   } t j d t |   t j d |  g | _ | j d d | d <| j d | d <d SWn9 t	 k
 r } z  j
 j |  d SWYd  d  } ~ Xn Xd  S)	N    c             s   s'   |  ] } t  t |   | f Vq d  S)N)r   len).0pr!   r!   r"   	<genexpr>  s    z@_NpnAdvertiseHelper.__init__.<locals>.wrapper.<locals>.<genexpr>zunsigned int *zunsigned char[]r   r$   r%   )r<   r=   joinr   from_iterablerH   newrK   _npn_advertise_callback_argsr>   r2   r?   )rC   outoutlenargconnprotosprotostrrE   )rF   r3   r!   r"   rG     s    z-_NpnAdvertiseHelper.__init__.<locals>.wrapperz>int (*)(SSL *, const unsigned char **, unsigned int *, void *))r1   r4   r   rH   rF   )r3   rF   rG   r!   )rF   r3   r"   r4      s
    !z_NpnAdvertiseHelper.__init__N)r   r   r    r+   r4   r!   r!   r!   r"   rI      s   rI   c               @   s"   e  Z d  Z d Z d d   Z d S)_NpnSelectHelperzP
    Wrap a callback such that it can be used as an NPN selection callback.
    c                sG   t  j   t       f d d    } t j d |   _ d  S)Nc                s*  y t  j |  } t j | |  d  d   } g  } xN | r t | d  }	 | d |	 d  }
 | j |
  | |	 d d   } q5 W  | |  } t j d t |   t j d |  g | _ | j d d | d <| j d | d <d SWn9 t	 k
 r%} z  j
 j |  d SWYd  d  } ~ Xn Xd  S)Nr   r$   zunsigned char *zunsigned char[]r%   )r<   r=   rH   bufferr   r?   rQ   rK   _npn_select_callback_argsr>   r2   )rC   rS   rT   in_inlenrU   rV   instr	protolistlprotooutstrrE   )rF   r3   r!   r"   rG   +  s$    	z*_NpnSelectHelper.__init__.<locals>.wrapperz^int (*)(SSL *, unsigned char **, unsigned char *, const unsigned char *, unsigned int, void *))r1   r4   r   rH   rF   )r3   rF   rG   r!   )rF   r3   r"   r4   (  s
    !"z_NpnSelectHelper.__init__N)r   r   r    r+   r4   r!   r!   r!   r"   rY   #  s   rY   c               @   s"   e  Z d  Z d Z d d   Z d S)_ALPNSelectHelperzQ
    Wrap a callback such that it can be used as an ALPN selection callback.
    c                sG   t  j   t       f d d    } t j d |   _ d  S)Nc                sE  yt  j |  } t j | |  d  d   } g  } xN | r t | d  }	 | d |	 d  }
 | j |
  | |	 d d   } q5 W  | |  } t | t  s t d   t j	 d t
 |   t j	 d |  g | _ | j d d | d <| j d | d <d SWn9 t k
 r@} z  j j |  d SWYd  d  } ~ Xn Xd  S)Nr   r$   z'ALPN callback must return a bytestring.zunsigned char *zunsigned char[]r%   )r<   r=   rH   rZ   r   r?   
isinstance_binary_type	TypeErrorrQ   rK   _alpn_select_callback_argsr>   r2   )rC   rS   rT   r\   r]   rU   rV   r^   r_   Zencoded_lenra   rb   rE   )rF   r3   r!   r"   rG   \  s(    	z+_ALPNSelectHelper.__init__.<locals>.wrapperz^int (*)(SSL *, unsigned char **, unsigned char *, const unsigned char *, unsigned int, void *))r1   r4   r   rH   rF   )r3   rF   rG   r!   )rF   r3   r"   r4   Y  s
    !$z_ALPNSelectHelper.__init__N)r   r   r    r+   r4   r!   r!   r!   r"   rc   T  s   rc   c               @   s"   e  Z d  Z d Z d d   Z d S)_OCSPServerCallbackHelpera  
    Wrap a callback such that it can be used as an OCSP callback for the server
    side.

    Annoyingly, OpenSSL defines one OCSP callback but uses it in two different
    ways. For servers, that callback is expected to retrieve some OCSP data and
    hand it to OpenSSL, and may return only SSL_TLSEXT_ERR_OK,
    SSL_TLSEXT_ERR_FATAL, and SSL_TLSEXT_ERR_NOACK. For clients, that callback
    is expected to check the OCSP data, and returns a negative value on error,
    0 if the response is not acceptable, or positive if it is. These are
    mutually exclusive return code behaviours, and they mean that we need two
    helpers so that we always return an appropriate error code if the user's
    code throws an exception.

    Given that we have to have two helpers anyway, these helpers are a bit more
    helpery than most: specifically, they hide a few more of the OpenSSL
    functions so that the user has an easier time writing these callbacks.

    This helper implements the server side.
    c                sG   t  j   t       f d d    } t j d |   _ d  S)Nc                s   y t  j |  } | t j k r1 t j |  } n d  }   | |  } t | t  sa t d   | sk d St |  } t	 j
 |  } | t j | |  d  d   <t	 j |  | |  d SWn9 t k
 r } z  j j |  d SWYd  d  } ~ Xn Xd  S)Nz'OCSP callback must return a bytestring.r&   r   r%   )r<   r=   rH   NULLfrom_handlerd   re   rf   rK   r:   ZOPENSSL_mallocrZ   ZSSL_set_tlsext_status_ocsp_respr>   r2   r?   )rC   cdatarV   data	ocsp_dataZocsp_data_lengthZdata_ptrrE   )rF   r3   r!   r"   rG     s&    	z3_OCSPServerCallbackHelper.__init__.<locals>.wrapperzint (*)(SSL *, void *))r1   r4   r   rH   rF   )r3   rF   rG   r!   )rF   r3   r"   r4     s    !,z"_OCSPServerCallbackHelper.__init__N)r   r   r    r+   r4   r!   r!   r!   r"   rh     s   rh   c               @   s"   e  Z d  Z d Z d d   Z d S)_OCSPClientCallbackHelpera  
    Wrap a callback such that it can be used as an OCSP callback for the client
    side.

    Annoyingly, OpenSSL defines one OCSP callback but uses it in two different
    ways. For servers, that callback is expected to retrieve some OCSP data and
    hand it to OpenSSL, and may return only SSL_TLSEXT_ERR_OK,
    SSL_TLSEXT_ERR_FATAL, and SSL_TLSEXT_ERR_NOACK. For clients, that callback
    is expected to check the OCSP data, and returns a negative value on error,
    0 if the response is not acceptable, or positive if it is. These are
    mutually exclusive return code behaviours, and they mean that we need two
    helpers so that we always return an appropriate error code if the user's
    code throws an exception.

    Given that we have to have two helpers anyway, these helpers are a bit more
    helpery than most: specifically, they hide a few more of the OpenSSL
    functions so that the user has an easier time writing these callbacks.

    This helper implements the client side.
    c                sG   t  j   t       f d d    } t j d |   _ d  S)Nc       	         s   y t  j |  } | t j k r1 t j |  } n d  } t j d  } t j |  |  } | d k  rm d } n  t j | d |  d  d   }   | | |  } t	 t
 |   SWn9 t k
 r } z  j j |  d SWYd  d  } ~ Xn Xd  S)Nzunsigned char **r   rJ   r$   )r<   r=   rH   ri   rj   rQ   r:   ZSSL_get_tlsext_status_ocsp_resprZ   intboolr>   r2   r?   )	rC   rk   rV   rl   Zocsp_ptrZocsp_lenrm   ZvalidrE   )rF   r3   r!   r"   rG     s    	 z3_OCSPClientCallbackHelper.__init__.<locals>.wrapperzint (*)(SSL *, void *))r1   r4   r   rH   rF   )r3   rF   rG   r!   )rF   r3   r"   r4     s    !z"_OCSPClientCallbackHelper.__init__N)r   r   r    r+   r4   r!   r!   r!   r"   rn     s   rn   c             C   s   d  } t  |  t  s< t |  d d   } | d  k	 r< |   }  t  |  t  rQ |  } t  | t  so t d   n | d k  r t d | f   | S)Nfilenoz3argument must be an int, or have a fileno() method.r   z1file descriptor cannot be a negative integer (%i))rd   r   getattrrf   
ValueError)objfdmethr!   r!   r"   _asFileDescriptor
  s    	rx   c             C   s   t  j t j |    S)z
    Return a string describing the version of OpenSSL in use.

    :param type: One of the SSLEAY_ constants defined in this module.
    )rH   stringr:   SSLeay_version)typer!   r!   r"   rz     s    rz   c                s      f d d   } | S)a  
    Builds a decorator that ensures that functions that rely on OpenSSL
    functions that are not present in this build raise NotImplementedError,
    rather than AttributeError coming out of cryptography.

    :param flag: A cryptography flag that guards the functions, e.g.
        ``Cryptography_HAS_NEXTPROTONEG``.
    :param error: The string to be used in the exception if the flag is false.
    c                s0    s( t  |     f d d    } | S|  Sd  S)Nc                 s   t      d  S)N)NotImplementedError)argskwargs)errorr!   r"   explode2  s    z<_make_requires.<locals>._requires_decorator.<locals>.explode)r   )funcr   )r   flagr!   r"   _requires_decorator0  s    z+_make_requires.<locals>._requires_decoratorr!   )r   r   r   r!   )r   r   r"   _make_requires&  s    
	r   zNPN not availablezALPN not availablezSNI not availablec               @   s   e  Z d  Z d S)SessionN)r   r   r    r!   r!   r!   r"   r   K  s   r   c               @   s  e  Z d  Z d Z e d e d e d e d e d e	 d i Z
 e d d	   e
 j   D  Z
 d
 d   Z d d d  Z d d   Z d d d  Z d d   Z d d   Z d d   Z d d   Z e d d  Z d d   Z d d    Z d! d"   Z e d# d$  Z d% d&   Z d' d(   Z d) d*   Z d+ d,   Z d- d.   Z  d/ d0   Z! d1 d2   Z" d3 d4   Z# d5 d6   Z$ d7 d8   Z% d9 d:   Z& d; d<   Z' d= d>   Z( d? d@   Z) dA dB   Z* dC dD   Z+ dE dF   Z, dG dH   Z- dI dJ   Z. dK dL   Z/ dM dN   Z0 dO dP   Z1 dQ dR   Z2 e3 dS dT    Z4 e5 dU dV    Z6 e5 dW dX    Z7 e8 dY dZ    Z9 e8 d[ d\    Z: d] d^   Z; d d_ d`  Z< d da db  Z= d S)cContextzn
    :class:`OpenSSL.SSL.Context` instances define the parameters for setting
    up new SSL connections.
    ZSSLv2_methodZSSLv3_methodZSSLv23_methodZTLSv1_methodZTLSv1_1_methodZTLSv1_2_methodc             c   sB   |  ]8 \ } } t  t | d   d  k	 r | t  t |  f Vq d  S)N)rs   r:   )rL   Z
identifiernamer!   r!   r"   rN   ]  s   	zContext.<genexpr>c             C   s  t  | t  s t d   y |  j | } Wn t k
 rL t d   Yn X|   } t | t j k  t	 j
 |  } t | t j k  t j | t	 j  } y& t	 j | d  } t | d k  Wn t k
 r Yn X| |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _  |  j! t	 j"  d S)zo
        :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
            TLSv1_METHOD.
        zmethod must be an integerzNo such protocolr$   N)#rd   r   rf   _methodsKeyErrorrt   _openssl_assertrH   ri   r:   ZSSL_CTX_newgcZSSL_CTX_freeZSSL_CTX_set_ecdh_autoAttributeError_context_passphrase_helper_passphrase_callback_passphrase_userdata_verify_helper_verify_callback_info_callback_tlsext_servername_callback	_app_data_npn_advertise_helper_npn_advertise_callback_npn_select_helper_npn_select_callback_alpn_select_helper_alpn_select_callback_ocsp_helper_ocsp_callback
_ocsp_dataset_modeZSSL_MODE_ENABLE_PARTIAL_WRITE)r3   methodZmethod_funcZ
method_objcontextresr!   r!   r"   r4   a  sF    																			zContext.__init__Nc             C   sq   | d k r t  j } n t |  } | d k r< t  j } n t |  } t j |  j | |  } | sm t   d S)aX  
        Let SSL know where we can find trusted certificates for the certificate
        chain

        :param cafile: In which file we can find the certificates (``bytes`` or
            ``unicode``).
        :param capath: In which directory we can find the certificates
            (``bytes`` or ``unicode``).

        :return: None
        N)rH   ri   _path_stringr:   ZSSL_CTX_load_verify_locationsr   r5   )r3   cafilecapathZload_resultr!   r!   r"   load_verify_locations  s    zContext.load_verify_locationsc                s:   t        f d d    } t t | d d d d S)Nc                s     |  |  j   S)N)r   )sizeZverifyuserdata)rF   r3   r!   r"   rG     s    z'Context._wrap_callback.<locals>.wrapperZ	more_argsTtruncate)r   r   r   )r3   rF   rG   r!   )rF   r3   r"   _wrap_callback  s    !zContext._wrap_callbackc             C   s\   t  |  s t d   |  j |  |  _ |  j j |  _ t j |  j |  j  | |  _	 d S)z
        Set the passphrase callback

        :param callback: The Python callback to use
        :param userdata: (optional) A Python object which will be given as
                         argument to the callback
        :return: None
        zcallback must be callableN)
callablerf   r   r   rF   r   r:   ZSSL_CTX_set_default_passwd_cbr   r   )r3   rF   r   r!   r!   r"   set_passwd_cb  s    	zContext.set_passwd_cbc             C   s   t  j |  j  } t | d k  t j t  j    j d  } t j t  j    j d  } |  j	 | |  s t j t  j
    } t j t  j    } | t k r | t k r |  j t t  d S)z[
        Use the platform-specific CA certificate locations

        :return: None
        r$   asciiN)r:   Z SSL_CTX_set_default_verify_pathsr   r   rH   ry   ZX509_get_default_cert_dir_envdecodeZX509_get_default_cert_file_env_check_env_vars_setZX509_get_default_cert_dirZX509_get_default_cert_file_CRYPTOGRAPHY_MANYLINUX1_CA_DIR _CRYPTOGRAPHY_MANYLINUX1_CA_FILE_fallback_default_verify_paths_CERTIFICATE_FILE_LOCATIONS_CERTIFICATE_PATH_LOCATIONS)r3   
set_resultdir_env_varfile_env_varZdefault_dirZdefault_filer!   r!   r"   set_default_verify_paths  s     
		z Context.set_default_verify_pathsc             C   s.   t  j j |  d k	 p- t  j j |  d k	 S)zp
        Check to see if the default cert dir/file environment vars are present.

        :return: bool
        N)osenvironget)r3   r   r   r!   r!   r"   r     s    zContext._check_env_vars_setc             C   si   x. | D]& } t  j j |  r |  j |  Pq Wx1 | D]) } t  j j |  r8 |  j d |  Pq8 Wd S)aW  
        Default verify paths are based on the compiled version of OpenSSL.
        However, when pyca/cryptography is compiled as a manylinux1 wheel
        that compiled location can potentially be wrong. So, like Go, we
        will try a predefined set of paths and attempt to load roots
        from there.

        :return: None
        N)r   pathisfiler   isdir)r3   Z	file_pathZdir_pathr   r   r!   r!   r"   r     s    
z&Context._fallback_default_verify_pathsc             C   s2   t  |  } t j |  j |  } | s. t   d S)z
        Load a certificate chain from a file

        :param certfile: The name of the certificate chain file (``bytes`` or
            ``unicode``).

        :return: None
        N)r   r:   Z"SSL_CTX_use_certificate_chain_filer   r5   )r3   certfilerD   r!   r!   r"   use_certificate_chain_file  s
    	z"Context.use_certificate_chain_filec             C   sP   t  |  } t | t  s' t d   t j |  j | |  } | sL t   d S)z
        Load a certificate from a file

        :param certfile: The name of the certificate file (``bytes`` or
            ``unicode``).
        :param filetype: (optional) The encoding of the file, default is PEM

        :return: None
        zfiletype must be an integerN)r   rd   r   rf   r:   ZSSL_CTX_use_certificate_filer   r5   )r3   r   filetype
use_resultr!   r!   r"   use_certificate_file  s    
zContext.use_certificate_filec             C   sD   t  | t  s t d   t j |  j | j  } | s@ t   d S)zs
        Load a certificate from a X509 object

        :param cert: The X509 object
        :return: None
        zcert must be an X509 instanceN)rd   r   rf   r:   ZSSL_CTX_use_certificater   r;   r5   )r3   rA   r   r!   r!   r"   use_certificate3  s
    zContext.use_certificatec             C   s`   t  | t  s t d   t j | j  } t j |  j |  } | s\ t j |  t	   d S)z
        Add certificate to chain

        :param certobj: The X509 certificate object to add to the chain
        :return: None
        z certobj must be an X509 instanceN)
rd   r   rf   r:   X509_dupr;   ZSSL_CTX_add_extra_chain_certr   	X509_freer5   )r3   Zcertobjcopy
add_resultr!   r!   r"   add_extra_chain_certA  s    zContext.add_extra_chain_certc             C   s*   |  j  d  k	 r |  j  j t  t   d  S)N)r   r7   r*   r5   )r3   r!   r!   r"   _raise_passphrase_exceptionR  s    z#Context._raise_passphrase_exceptionc             C   sh   t  |  } | t k r! t } n t | t  s< t d   t j |  j | |  } | sd |  j	   d S)z
        Load a private key from a file

        :param keyfile: The name of the key file (``bytes`` or ``unicode``)
        :param filetype: (optional) The encoding of the file, default is PEM

        :return: None
        zfiletype must be an integerN)
r   _UNSPECIFIEDr   rd   r   rf   r:   ZSSL_CTX_use_PrivateKey_filer   r   )r3   Zkeyfiler   r   r!   r!   r"   use_privatekey_fileX  s    		zContext.use_privatekey_filec             C   sG   t  | t  s t d   t j |  j | j  } | sC |  j   d S)zs
        Load a private key from a PKey object

        :param pkey: The PKey object
        :return: None
        zpkey must be a PKey instanceN)rd   r   rf   r:   ZSSL_CTX_use_PrivateKeyr   Z_pkeyr   )r3   Zpkeyr   r!   r!   r"   use_privatekeym  s
    zContext.use_privatekeyc             C   s   t  j |  j  s t   d S)z
        Check that the private key and certificate match up

        :return: None (raises an exception if something's wrong)
        N)r:   ZSSL_CTX_check_private_keyr   r5   )r3   r!   r!   r"   check_privatekey{  s    zContext.check_privatekeyc             C   sB   t  j t d |   } t | t j k  t  j |  j |  d S)a%  
        Load the trusted certificates that will be sent to the client.  Does
        not actually imply any of the certificates are trusted; that must be
        configured separately.

        :param bytes cafile: The path to a certificates file in PEM format.
        :return: None
        r   N)r:   ZSSL_load_client_CA_file_text_to_bytes_and_warnr   rH   ri   SSL_CTX_set_client_CA_listr   )r3   r   Zca_listr!   r!   r"   load_client_ca  s    	zContext.load_client_cac             C   s;   t  d |  } t t j |  j | t |   d k  d S)aV  
        Set the session id to *buf* within which a session can be reused for
        this Context object.  This is needed when doing session resumption,
        because there is no way for a stored session to know which Context
        object it is associated with.

        :param bytes buf: The session id.

        :returns: None
        bufr$   N)r   r   r:   ZSSL_CTX_set_session_id_contextr   rK   )r3   r   r!   r!   r"   set_session_id  s    zContext.set_session_idc             C   s.   t  | t  s t d   t j |  j |  S)z
        Enable/disable session caching and specify the mode used.

        :param mode: One or more of the SESS_CACHE_* flags (combine using
            bitwise or)
        :returns: The previously set caching mode.
        zmode must be an integer)rd   r   rf   r:   ZSSL_CTX_set_session_cache_moder   )r3   moder!   r!   r"   set_session_cache_mode  s    zContext.set_session_cache_modec             C   s   t  j |  j  S)z:
        :returns: The currently used cache mode.
        )r:   ZSSL_CTX_get_session_cache_moder   )r3   r!   r!   r"   get_session_cache_mode  s    zContext.get_session_cache_modec             C   sn   t  | t  s t d   t |  s3 t d   t |  |  _ |  j j |  _ t j	 |  j
 | |  j  d S)aG  
        Set the verify mode and verify callback

        :param mode: The verify mode, this is either VERIFY_NONE or
                     VERIFY_PEER combined with possible other flags
        :param callback: The Python callback to use
        :return: None

        See SSL_CTX_set_verify(3SSL) for further details.
        zmode must be an integerzcallback must be callableN)rd   r   rf   r   r8   r   rF   r   r:   ZSSL_CTX_set_verifyr   )r3   r   rF   r!   r!   r"   
set_verify  s    zContext.set_verifyc             C   s2   t  | t  s t d   t j |  j |  d S)zz
        Set the verify depth

        :param depth: An integer specifying the verify depth
        :return: None
        zdepth must be an integerN)rd   r   rf   r:   ZSSL_CTX_set_verify_depthr   )r3   Zdepthr!   r!   r"   set_verify_depth  s    zContext.set_verify_depthc             C   s   t  j |  j  S)zG
        Get the verify mode

        :return: The verify mode
        )r:   ZSSL_CTX_get_verify_moder   )r3   r!   r!   r"   get_verify_mode  s    zContext.get_verify_modec             C   s   t  j |  j  S)zI
        Get the verify depth

        :return: The verify depth
        )r:   ZSSL_CTX_get_verify_depthr   )r3   r!   r!   r"   get_verify_depth  s    zContext.get_verify_depthc             C   s   t  |  } t j | d  } | t j k r4 t   t j | t j  } t j | t j t j t j  } t j | t j	  } t j
 |  j |  d S)z
        Load parameters for Ephemeral Diffie-Hellman

        :param dhfile: The file to load EDH parameters from (``bytes`` or
            ``unicode``).

        :return: None
           rN)r   r:   ZBIO_new_filerH   ri   r5   r   ZBIO_freeZPEM_read_bio_DHparamsZDH_freeZSSL_CTX_set_tmp_dhr   )r3   ZdhfilebioZdhr!   r!   r"   load_tmp_dh  s    	!zContext.load_tmp_dhc             C   s   t  j |  j | j    d S)a  
        Select a curve to use for ECDHE key exchange.

        :param curve: A curve object to use as returned by either
            :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
            :py:meth:`OpenSSL.crypto.get_elliptic_curves`.

        :return: None
        N)r:   ZSSL_CTX_set_tmp_ecdhr   Z
_to_EC_KEY)r3   Zcurver!   r!   r"   set_tmp_ecdh  s    
zContext.set_tmp_ecdhc             C   sM   t  d |  } t | t  s* t d   t t j |  j |  d k  d S)z
        Set the list of ciphers to be used in this context.

        See the OpenSSL manual for more information (e.g.
        :manpage:`ciphers(1)`).

        :param bytes cipher_list: An OpenSSL cipher string.
        :return: None
        cipher_listz"cipher_list must be a byte string.r$   N)r   rd   bytesrf   r   r:   ZSSL_CTX_set_cipher_listr   )r3   r   r!   r!   r"   set_cipher_list  s
    
zContext.set_cipher_listc             C   s   t  j   } t | t j k  y x | D] } t | t  sZ t d t |  j	 f   t  j
 | j  } t | t j k  t  j | |  } | s) t  j |  t   q) WWn t  j |    Yn Xt  j |  j |  d S)a?  
        Set the list of preferred client certificate signers for this server
        context.

        This list of certificate authorities will be sent to the client when
        the server requests a client certificate.

        :param certificate_authorities: a sequence of X509Names.
        :return: None
        z3client CAs must be X509Name objects, not %s objectsN)r:   Zsk_X509_NAME_new_nullr   rH   ri   rd   r   rf   r{   r   X509_NAME_dup_nameZsk_X509_NAME_pushX509_NAME_freer5   Zsk_X509_NAME_freer   r   )r3   Zcertificate_authoritiesZ
name_stackZca_namer   Zpush_resultr!   r!   r"   set_client_ca_list  s$    zContext.set_client_ca_listc             C   sG   t  | t  s t d   t j |  j | j  } t | d k  d S)aI  
        Add the CA certificate to the list of preferred signers for this
        context.

        The list of certificate authorities will be sent to the client when the
        server requests a client certificate.

        :param certificate_authority: certificate authority's X509 certificate.
        :return: None
        z.certificate_authority must be an X509 instancer$   N)rd   r   rf   r:   ZSSL_CTX_add_client_CAr   r;   r   )r3   Zcertificate_authorityr   r!   r!   r"   add_client_caA  s
    zContext.add_client_cac             C   s.   t  | t  s t d   t j |  j |  S)z
        Set session timeout

        :param timeout: The timeout in seconds
        :return: The previous session timeout
        ztimeout must be an integer)rd   r   rf   r:   ZSSL_CTX_set_timeoutr   )r3   Ztimeoutr!   r!   r"   set_timeoutS  s    zContext.set_timeoutc             C   s   t  j |  j  S)zO
        Get the session timeout

        :return: The session timeout
        )r:   ZSSL_CTX_get_timeoutr   )r3   r!   r!   r"   get_timeout_  s    zContext.get_timeoutc                sM   t       f d d    } t j d |  |  _ t j |  j |  j  d S)zr
        Set the info callback

        :param callback: The Python callback to use
        :return: None
        c                s     t  j |  | |  d  S)N)r<   r=   )rC   ZwhereZreturn_code)rF   r!   r"   rG   n  s    z*Context.set_info_callback.<locals>.wrapperzvoid (*)(const SSL *, int, int)N)r   rH   rF   r   r:   ZSSL_CTX_set_info_callbackr   )r3   rF   rG   r!   )rF   r"   set_info_callbackg  s    zContext.set_info_callbackc             C   s   |  j  S)zo
        Get the application data (supplied via set_app_data())

        :return: The application data
        )r   )r3   r!   r!   r"   get_app_datau  s    zContext.get_app_datac             C   s   | |  _  d S)z
        Set the application data (will be returned from get_app_data())

        :param data: Any Python object
        :return: None
        N)r   )r3   rl   r!   r!   r"   set_app_data}  s    zContext.set_app_datac             C   sA   t  j |  j  } | t j k r% d St j t  } | | _ | S)z
        Get the certificate store for the context.

        :return: A X509Store object or None if it does not have one.
        N)r:   ZSSL_CTX_get_cert_storer   rH   ri   r   r9   Z_store)r3   ZstoreZpystorer!   r!   r"   get_cert_store  s    	zContext.get_cert_storec             C   s.   t  | t  s t d   t j |  j |  S)z
        Add options. Options set before are not cleared!

        :param options: The options to add.
        :return: The new option bitmask.
        zoptions must be an integer)rd   r   rf   r:   ZSSL_CTX_set_optionsr   )r3   Zoptionsr!   r!   r"   set_options  s    zContext.set_optionsc             C   s.   t  | t  s t d   t j |  j |  S)z
        Add modes via bitmask. Modes set before are not cleared!

        :param mode: The mode to add.
        :return: The new mode bitmask.
        zmode must be an integer)rd   r   rf   r:   ZSSL_CTX_set_moder   )r3   r   r!   r!   r"   r     s    zContext.set_modec                sM   t       f d d    } t j d |  |  _ t j |  j |  j  d S)z
        Specify a callback function to be called when clients specify a server
        name.

        :param callback: The callback function.  It will be invoked with one
            argument, the Connection instance.
        c                s     t  j |   d S)Nr   )r<   r=   )rC   ZalertrU   )rF   r!   r"   rG     s    z7Context.set_tlsext_servername_callback.<locals>.wrapperz#int (*)(const SSL *, int *, void *)N)r   rH   rF   r   r:   Z&SSL_CTX_set_tlsext_servername_callbackr   )r3   rF   rG   r!   )rF   r"   set_tlsext_servername_callback  s
    	z&Context.set_tlsext_servername_callbackc             C   s>   t  |  |  _ |  j j |  _ t j |  j |  j t j  d S)a  
        Specify a callback function that will be called when offering `Next
        Protocol Negotiation
        <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.

        :param callback: The callback function.  It will be invoked with one
            argument, the Connection instance.  It should return a list of
            bytestrings representing the advertised protocols, like
            ``[b'http/1.1', b'spdy/2']``.
        N)	rI   r   rF   r   r:   Z%SSL_CTX_set_next_protos_advertised_cbr   rH   ri   )r3   rF   r!   r!   r"   set_npn_advertise_callback  s    z"Context.set_npn_advertise_callbackc             C   s>   t  |  |  _ |  j j |  _ t j |  j |  j t j  d S)a  
        Specify a callback function that will be called when a server offers
        Next Protocol Negotiation options.

        :param callback: The callback function.  It will be invoked with two
            arguments: the Connection, and a list of offered protocols as
            bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``.  It should return
            one of those bytestrings, the chosen protocol.
        N)	rY   r   rF   r   r:   Z SSL_CTX_set_next_proto_select_cbr   rH   ri   )r3   rF   r!   r!   r"   set_npn_select_callback  s    zContext.set_npn_select_callbackc             C   sW   d j  t j d d   | D   } t j d |  } t j |  j | t |   d S)ag  
        Specify the clients ALPN protocol list.

        These protocols are offered to the server during protocol negotiation.

        :param protos: A list of the protocols to be offered to the server.
            This list should be a Python list of bytestrings representing the
            protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
        rJ   c             s   s'   |  ] } t  t |   | f Vq d  S)N)r   rK   )rL   rM   r!   r!   r"   rN     s    z*Context.set_alpn_protos.<locals>.<genexpr>zunsigned char[]N)	rO   r   rP   rH   rQ   r:   ZSSL_CTX_set_alpn_protosr   rK   )r3   rW   rX   	input_strr!   r!   r"   set_alpn_protos  s    zContext.set_alpn_protosc             C   s>   t  |  |  _ |  j j |  _ t j |  j |  j t j  d S)ab  
        Set the callback to handle ALPN protocol choice.

        :param callback: The callback function.  It will be invoked with two
            arguments: the Connection, and a list of offered protocols as
            bytestrings, e.g ``[b'http/1.1', b'spdy/2']``.  It should return
            one of those bytestrings, the chosen protocol.
        N)	rc   r   rF   r   r:   ZSSL_CTX_set_alpn_select_cbr   rH   ri   )r3   rF   r!   r!   r"   set_alpn_select_callback  s    
z Context.set_alpn_select_callbackc             C   s   | |  _  | j |  _ | d k r0 t j |  _ n t j |  |  _ t j |  j	 |  j  } t
 | d k  t j |  j	 |  j  } t
 | d k  d S)z
        This internal helper does the common work for
        ``set_ocsp_server_callback`` and ``set_ocsp_client_callback``, which is
        almost all of it.
        Nr$   )r   rF   r   rH   ri   r   Z
new_handler:   ZSSL_CTX_set_tlsext_status_cbr   r   ZSSL_CTX_set_tlsext_status_arg)r3   helperrl   rcr!   r!   r"   _set_ocsp_callback  s    	zContext._set_ocsp_callbackc             C   s    t  |  } |  j | |  d S)a  
        Set a callback to provide OCSP data to be stapled to the TLS handshake
        on the server side.

        :param callback: The callback function. It will be invoked with two
            arguments: the Connection, and the optional arbitrary data you have
            provided. The callback must return a bytestring that contains the
            OCSP data to staple to the handshake. If no OCSP data is available
            for this connection, return the empty bytestring.
        :param data: Some opaque data that will be passed into the callback
            function when called. This can be used to avoid needing to do
            complex data lookups or to keep track of what context is being
            used. This parameter is optional.
        N)rh   r   )r3   rF   rl   r   r!   r!   r"   set_ocsp_server_callback  s    z Context.set_ocsp_server_callbackc             C   s    t  |  } |  j | |  d S)a  
        Set a callback to validate OCSP data stapled to the TLS handshake on
        the client side.

        :param callback: The callback function. It will be invoked with three
            arguments: the Connection, a bytestring containing the stapled OCSP
            assertion, and the optional arbitrary data you have provided. The
            callback must return a boolean that indicates the result of
            validating the OCSP data: ``True`` if the OCSP data is valid and
            the certificate can be trusted, or ``False`` if either the OCSP
            data is invalid or the certificate has been revoked.
        :param data: Some opaque data that will be passed into the callback
            function when called. This can be used to avoid needing to do
            complex data lookups or to keep track of what context is being
            used. This parameter is optional.
        N)rn   r   )r3   rF   rl   r   r!   r!   r"   set_ocsp_client_callback,  s    z Context.set_ocsp_client_callback)>r   r   r    r+   SSLv2_METHODSSLv3_METHODSSLv23_METHODTLSv1_METHODTLSv1_1_METHODTLSv1_2_METHODr   dictitemsr4   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   _requires_snir   _requires_npnr   r   _requires_alpnr   r   r   r   r   r!   r!   r!   r"   r   O  sl   	2'	#	r   z4ContextType has been deprecated, use Context insteadc               @   s  e  Z d  Z d Z e   Z d d d  Z d d   Z d d   Z d	 d
   Z	 d d   Z
 e d d    Z e d d    Z d d   Z d d d  Z e Z d d d  Z d d d  Z e Z d d d d  Z d d   Z d d   Z d  d!   Z d" d#   Z d$ d%   Z d& d'   Z d( d)   Z d* d+   Z d, d-   Z d. d/   Z d0 d1   Z d2 d3   Z  d4 d5   Z! d6 d7   Z" d8 d9   Z# d: d;   Z$ d< d=   Z% d> d?   Z& d@ dA   Z' dB dC   Z( dD dE   Z) dF dG   Z* dH dI   Z+ dJ dK   Z, dL dM   Z- dN dO   Z. dP dQ   Z/ dR dS   Z0 dT dU   Z1 dV dW   Z2 dX dY   Z3 dZ d[   Z4 d\ d]   Z5 d^ d_   Z6 d` da   Z7 db dc   Z8 dd de   Z9 df dg   Z: dh di   Z; dj dk   Z< e= dl dm    Z> e? dn do    Z@ e? dp dq    ZA dr ds   ZB d S)tr<   z
    Nc             C   s_  t  | t  s t d   t j | j  } t j | t j  |  _	 | |  _ d |  _
 d |  _ d |  _ d |  _ |  |  j |  j	 <| d k rd |  _ t j t j    |  _ t |  j t j k  t j t j    |  _ t |  j t j k  t j |  j	 |  j |  j  nI d |  _ d |  _ | |  _ t j |  j	 t |  j   } t | d k  d S)z
        Create a new Connection object, using the given OpenSSL.SSL.Context
        instance and socket.

        :param context: An SSL Context to use for this connection
        :param socket: The socket to use for transport layer
        z"context must be a Context instanceNr$   )rd   r   rf   r:   ZSSL_newr   rH   r   ZSSL_free_sslr   rR   r[   rg   r=   _socketZBIO_newZ	BIO_s_mem	_into_sslr   ri   	_from_sslZSSL_set_bioZ
SSL_set_fdrx   )r3   r   socketrC   r   r!   r!   r"   r4   L  s.    									zConnection.__init__c             C   sB   |  j  d k r. t d |  j j | f   n t |  j  |  Sd S)zy
        Look up attributes on the wrapped socket object if they are not found
        on the Connection object.
        Nz!'%s' object has no attribute '%s')r  r   	__class__r   rs   )r3   r   r!   r!   r"   __getattr__}  s    zConnection.__getattr__c             C   s  |  j  j d  k	 r" |  j  j j   |  j  j d  k	 rD |  j  j j   |  j  j d  k	 rf |  j  j j   |  j  j d  k	 r |  j  j j   |  j  j d  k	 r |  j  j j   t j | |  } | t j	 k r t
    n | t j k r t    n | t j k rt    n | t j k r(t    n | t j k rt j   d k r| d k  rt d k rtt j   d } n	 t j } | d k rt | t j |    t d d   qt   n | t j k rn t   d  S)Nr   win32r$   zUnexpected EOFro   )r   r   r7   r   r   r   r   r:   ZSSL_get_errorZSSL_ERROR_WANT_READr,   ZSSL_ERROR_WANT_WRITEr-   ZSSL_ERROR_ZERO_RETURNr/   ZSSL_ERROR_WANT_X509_LOOKUPr.   ZSSL_ERROR_SYSCALLZERR_peek_errorr   rH   Zgetwinerrorerrnor0   r   r   r5   ZSSL_ERROR_NONE)r3   rC   rD   r   r  r!   r!   r"   _raise_ssl_error  s@    	
zConnection._raise_ssl_errorc             C   s   |  j  S)z%
        Get session context
        )r   )r3   r!   r!   r"   get_context  s    zConnection.get_contextc             C   s>   t  | t  s t d   t j |  j | j  | |  _ d S)z
        Switch this connection to a new session context

        :param context: A :py:class:`Context` instance giving the new session
            context to use.
        z"context must be a Context instanceN)rd   r   rf   r:   ZSSL_set_SSL_CTXr  r   )r3   r   r!   r!   r"   set_context  s    zConnection.set_contextc             C   s8   t  j |  j t  j  } | t j k r+ d St j |  S)z
        Retrieve the servername extension value if provided in the client hello
        message, or None if there wasn't one.

        :return: A byte string giving the server name or :py:data:`None`.
        N)r:   ZSSL_get_servernamer  ZTLSEXT_NAMETYPE_host_namerH   ri   ry   )r3   r   r!   r!   r"   get_servername  s
    zConnection.get_servernamec             C   sM   t  | t  s t d   n d | k r6 t d   t j |  j |  d S)z
        Set the value of the servername extension to send in the client hello.

        :param name: A byte string giving the name.
        zname must be a byte strings    zname must not contain NUL byteN)rd   r   rf   r:   ZSSL_set_tlsext_host_namer  )r3   r   r!   r!   r"   set_tlsext_host_name  s
    zConnection.set_tlsext_host_namec             C   s   t  j |  j  S)z
        Get the number of bytes that can be safely read from the connection

        :return: The number of bytes available in the receive buffer.
        )r:   ZSSL_pendingr  )r3   r!   r!   r"   pending  s    zConnection.pendingr   c             C   s   t  d |  } t | t  r* | j   } t | t  rE t |  } t | t  s` t d   t |  d k r~ t	 d   t
 j |  j | t |   } |  j |  j |  | S)a  
        Send data on the connection. NOTE: If you get one of the WantRead,
        WantWrite or WantX509Lookup exceptions on this, you have to call the
        method again with the SAME buffer.

        :param buf: The string, buffer or memoryview to send
        :param flags: (optional) Included for compatibility with the socket
                      API, the value is ignored
        :return: The number of bytes written
        r   z0data must be a memoryview, buffer or byte stringiz,Cannot send more than 2**31-1 bytes at once.)r   rd   r   tobytesr#   strr   rf   rK   rt   r:   	SSL_writer  r  )r3   r   flagsrD   r!   r!   r"   send  s    zConnection.sendc             C   s   t  d |  } t | t  r* | j   } t | t  rE t |  } t | t  s` t d   t |  } d } t	 j
 d |  } xV | r t j |  j | | t | d   } |  j |  j |  | | 7} | | 8} q Wd S)a  
        Send "all" data on the connection. This calls send() repeatedly until
        all data is sent. If an error occurs, it's impossible to tell how much
        data has been sent.

        :param buf: The string, buffer or memoryview to send
        :param flags: (optional) Included for compatibility with the socket
                      API, the value is ignored
        :return: The number of bytes written
        r   z/buf must be a memoryview, buffer or byte stringr   zchar[]iN)r   rd   r   r  r#   r  r   rf   rK   rH   rQ   r:   r  r  minr  )r3   r   r  Zleft_to_sendZ
total_sentrl   rD   r!   r!   r"   sendall  s$    	
zConnection.sendallc             C   s   t  d |  } | d k	 rC | t j @rC t j |  j | |  } n t j |  j | |  } |  j |  j |  t j	 | |  d d  S)a  
        Receive data on the connection.

        :param bufsiz: The maximum number of bytes to read
        :param flags: (optional) The only supported flag is ``MSG_PEEK``,
            all other flags are ignored.
        :return: The string read from the Connection
        zchar[]N)
_no_zero_allocatorr  MSG_PEEKr:   SSL_peekr  SSL_readr  rH   rZ   )r3   bufsizr  r   rD   r!   r!   r"   recv,  s    	zConnection.recvc             C   s   | d k r t  |  } n t | t  |   } t d |  } | d k	 rs | t j @rs t j |  j | |  } n t j |  j | |  } |  j	 |  j |  y& t
 t j | |   | d |  <Wn. t k
 r t j | |  | d |  <Yn X| S)aW  
        Receive data on the connection and store the data into a buffer rather
        than creating a new string.

        :param buffer: The buffer to copy into.
        :param nbytes: (optional) The maximum number of bytes to read into the
            buffer. If not present, defaults to the size of the buffer. If
            larger than the size of the buffer, is reduced to the size of the
            buffer.
        :param flags: (optional) The only supported flag is ``MSG_PEEK``,
            all other flags are ignored.
        :return: The number of bytes read into the buffer.
        Nzchar[])rK   r  r  r  r  r:   r  r  r  r  
memoryviewrH   rZ   	NameError)r3   rZ   nbytesr  r   rD   r!   r!   r"   	recv_into>  s    &!zConnection.recv_intoc             C   s}   t  j |  rr t  j |  r* t    qy t  j |  rE t    qy t  j |  rc t d   qy t d   n t   d  S)NBIO_should_io_specialzunknown bio failure)	r:   ZBIO_should_retryZBIO_should_readr,   ZBIO_should_writer-   r$  rt   r5   )r3   r   rD   r!   r!   r"   _handle_bio_errorsg  s    zConnection._handle_bio_errorsc             C   s   |  j  d k r t d   t | t  s6 t d   t d |  } t j |  j  | |  } | d k r| |  j |  j  |  t j	 | |  d d  S)z
        When using non-socket connections this function reads the "dirty" data
        that would have traveled away on the network.

        :param bufsiz: The maximum number of bytes to read
        :return: The string read.
        NzConnection sock was not Nonezbufsiz must be an integerzchar[]r   )
r  rf   rd   r   r  r:   ZBIO_readr%  rH   rZ   )r3   r  r   rD   r!   r!   r"   bio_ready  s    zConnection.bio_readc             C   sk   t  d |  } |  j d k r* t d   t j |  j | t |   } | d k rg |  j |  j |  | S)z
        When using non-socket connections this function sends "dirty" data that
        would have traveled in on the network.

        :param buf: The string to put into the memory BIO.
        :return: The number of bytes written
        r   NzConnection sock was not Noner   )r   r  rf   r:   Z	BIO_writerK   r%  )r3   r   rD   r!   r!   r"   	bio_write  s    zConnection.bio_writec             C   s0   |  j    s, t t j |  j  d k  d Sd S)z
        Renegotiate the session.

        :return: True if the renegotiation can be started, False otherwise
        :rtype: bool
        r$   TF)renegotiate_pendingr   r:   ZSSL_renegotiater  )r3   r!   r!   r"   renegotiate  s    zConnection.renegotiatec             C   s)   t  j |  j  } |  j |  j |  d S)z
        Perform an SSL handshake (usually called after renegotiate() or one of
        set_*_state()). This can raise the same exceptions as send and recv.

        :return: None.
        N)r:   ZSSL_do_handshaker  r  )r3   rD   r!   r!   r"   do_handshake  s    zConnection.do_handshakec             C   s   t  j |  j  d k S)z
        Check if there's a renegotiation in progress, it will return False once
        a renegotiation is finished.

        :return: Whether there's a renegotiation in progress
        :rtype: bool
        r$   )r:   ZSSL_renegotiate_pendingr  )r3   r!   r!   r"   r(    s    zConnection.renegotiate_pendingc             C   s   t  j |  j  S)z
        Find out the total number of renegotiations.

        :return: The number of renegotiations.
        :rtype: int
        )r:   ZSSL_total_renegotiationsr  )r3   r!   r!   r"   total_renegotiations  s    zConnection.total_renegotiationsc             C   s    t  j |  j  |  j j |  S)z
        Connect to remote host and set up client-side SSL

        :param addr: A remote address
        :return: What the socket's connect method returns
        )r:   SSL_set_connect_stater  r  connect)r3   addrr!   r!   r"   r-    s    zConnection.connectc             C   s    |  j  j } |  j   | |  S)a  
        Connect to remote host and set up client-side SSL. Note that if the
        socket's connect_ex method doesn't return 0, SSL won't be initialized.

        :param addr: A remove address
        :return: What the socket's connect_ex method returns
        )r  
connect_exset_connect_state)r3   r.  r/  r!   r!   r"   r/    s    
zConnection.connect_exc             C   s;   |  j  j   \ } } t |  j |  } | j   | | f S)z
        Accept incoming connection and set up SSL on it

        :return: A (conn,addr) pair where conn is a Connection and addr is an
                 address
        )r  acceptr<   r   set_accept_state)r3   Zclientr.  rV   r!   r!   r"   r1    s    
zConnection.acceptc             C   s2   |  j  d k r t d   t j |  j d  d S)z
        When using non-socket connections this function signals end of
        data on the input for this connection.

        :return: None
        NzConnection sock was not Noner   )r  rf   r:   ZBIO_set_mem_eof_returnr  )r3   r!   r!   r"   bio_shutdown  s    zConnection.bio_shutdownc             C   sL   t  j |  j  } | d k  r4 |  j |  j |  n | d k rD d Sd Sd S)a  
        Send closure alert

        :return: True if the shutdown completed successfully (i.e. both sides
                 have sent closure alerts), false otherwise (i.e. you have to
                 wait for a ZeroReturnError on a recv() method call
        r   TFN)r:   ZSSL_shutdownr  r  )r3   rD   r!   r!   r"   shutdown  s    zConnection.shutdownc             C   s_   g  } xR t    D]G } t j |  j |  } | t j k r; P| j t t j |    q W| S)z
        Retrieve the list of ciphers used by the Connection object.

        :return: A list of native cipher strings.
        )	r   r:   ZSSL_get_cipher_listr  rH   ri   r?   _nativery   )r3   ZciphersirD   r!   r!   r"   get_cipher_list  s     zConnection.get_cipher_listc             C   s   t  j |  j  } | t j k r% g  Sg  } x t t  j |   D]n } t  j | |  } t  j |  } t	 | t j k  t
 j t
  } t j | t  j  | _ | j |  qA W| S)a  
        Get CAs whose certificates are suggested for client authentication.

        :return: If this is a server connection, a list of X509Names
            representing the acceptable CAs as set by
            :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
            :py:meth:`OpenSSL.SSL.Context.add_client_ca`.  If this is a client
            connection, the list of such X509Names sent by the server, or an
            empty list if that has not yet happened.
        )r:   ZSSL_get_client_CA_listr  rH   ri   rangeZsk_X509_NAME_numZsk_X509_NAME_valuer   r   r   r9   r   r   r   r?   )r3   Zca_namesrD   r6  r   r   Zpynamer!   r!   r"   get_client_ca_list  s    zConnection.get_client_ca_listc             C   s   t  d   d S)z
        The makefile() method is not implemented, since there is no dup
        semantics for SSL connections

        :raise: NotImplementedError
        z1Cannot make file object of OpenSSL.SSL.ConnectionN)r|   )r3   r!   r!   r"   makefile0  s    zConnection.makefilec             C   s   |  j  S)zM
        Get application data

        :return: The application data
        )r   )r3   r!   r!   r"   r   :  s    zConnection.get_app_datac             C   s   | |  _  d S)zh
        Set application data

        :param data - The application data
        :return: None
        N)r   )r3   rl   r!   r!   r"   r   B  s    zConnection.set_app_datac             C   s   t  j |  j  S)z
        Get shutdown state

        :return: The shutdown state, a bitvector of SENT_SHUTDOWN,
            RECEIVED_SHUTDOWN.
        )r:   ZSSL_get_shutdownr  )r3   r!   r!   r"   get_shutdownK  s    zConnection.get_shutdownc             C   s2   t  | t  s t d   t j |  j |  d S)z
        Set shutdown state

        :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
        :return: None
        zstate must be an integerN)rd   r   rf   r:   ZSSL_set_shutdownr  )r3   stater!   r!   r"   set_shutdownT  s    zConnection.set_shutdownc             C   s   t  j t j |  j   S)z
        Retrieve a verbose string detailing the state of the Connection.

        :return: A string representing the state
        :rtype: bytes
        )rH   ry   r:   ZSSL_state_string_longr  )r3   r!   r!   r"   get_state_string`  s    zConnection.get_state_stringc             C   s   t  j |  j  } | t j k r% d St  j |  j t j d  } | d k sR t  t d |  } t  j |  j | |  t j | |  d d  S)zi
        Get a copy of the server hello nonce.

        :return: A string representing the state
        Nr   zunsigned char[])	r:   SSL_get_sessionr  rH   ri   ZSSL_get_server_randomAssertionErrorr  rZ   )r3   sessionlengthoutpr!   r!   r"   server_randomi  s    zConnection.server_randomc             C   s   t  j |  j  } | t j k r% d St  j |  j t j d  } | d k sR t  t d |  } t  j |  j | |  t j | |  d d  S)zi
        Get a copy of the client hello nonce.

        :return: A string representing the state
        Nr   zunsigned char[])	r:   r?  r  rH   ri   ZSSL_get_client_randomr@  r  rZ   )r3   rA  rB  rC  r!   r!   r"   client_randomx  s    zConnection.client_randomc             C   s   t  j |  j  } | t j k r% d St  j | t j d  } | d k sO t  t d |  } t  j | | |  t j | |  d d  S)za
        Get a copy of the master key.

        :return: A string representing the state
        Nr   zunsigned char[])	r:   r?  r  rH   ri   ZSSL_SESSION_get_master_keyr@  r  rZ   )r3   rA  rB  rC  r!   r!   r"   
master_key  s    zConnection.master_keyc             O   s   |  j  j | |   S)z_
        See shutdown(2)

        :return: What the socket's shutdown() method returns
        )r  r4  )r3   r}   r~   r!   r!   r"   sock_shutdown  s    zConnection.sock_shutdownc             C   sP   t  j |  j  } | t j k rL t j t  } t j | t  j  | _	 | Sd S)zi
        Retrieve the other side's certificate (if any)

        :return: The peer's certificate
        N)
r:   ZSSL_get_peer_certificater  rH   ri   r   r9   r   r   r;   )r3   rA   pycertr!   r!   r"   get_peer_certificate  s    zConnection.get_peer_certificatec             C   s   t  j |  j  } | t j k r% d Sg  } xl t t  j |   D]U } t  j t  j | |   } t	 j
 t	  } t j | t  j  | _ | j |  qA W| S)z
        Retrieve the other side's certificate (if any)

        :return: A list of X509 instances giving the peer's certificate chain,
                 or None if it does not have one.
        N)r:   ZSSL_get_peer_cert_chainr  rH   ri   r8  Zsk_X509_numr   Zsk_X509_valuer   r9   r   r   r;   r?   )r3   Z
cert_stackrD   r6  rA   rH  r!   r!   r"   get_peer_cert_chain  s    zConnection.get_peer_cert_chainc             C   s   t  j |  j  S)z
        Checks if more data has to be read from the transport layer to complete
        an operation.

        :return: True iff more data has to be read
        )r:   ZSSL_want_readr  )r3   r!   r!   r"   	want_read  s    zConnection.want_readc             C   s   t  j |  j  S)z
        Checks if there is data to write to the transport layer to complete an
        operation.

        :return: True iff there is data to write
        )r:   ZSSL_want_writer  )r3   r!   r!   r"   
want_write  s    zConnection.want_writec             C   s   t  j |  j  d S)z
        Set the connection to work in server mode. The handshake will be
        handled automatically by read/write.

        :return: None
        N)r:   ZSSL_set_accept_stater  )r3   r!   r!   r"   r2    s    zConnection.set_accept_statec             C   s   t  j |  j  d S)z
        Set the connection to work in client mode. The handshake will be
        handled automatically by read/write.

        :return: None
        N)r:   r,  r  )r3   r!   r!   r"   r0    s    zConnection.set_connect_statec             C   sP   t  j |  j  } | t j k r% d St j t  } t j | t  j  | _	 | S)z
        Returns the Session currently used.

        @return: An instance of :py:class:`OpenSSL.SSL.Session` or
            :py:obj:`None` if no session exists.
        N)
r:   ZSSL_get1_sessionr  rH   ri   r   r9   r   ZSSL_SESSION_free_session)r3   rA  Z	pysessionr!   r!   r"   get_session  s    zConnection.get_sessionc             C   sD   t  | t  s t d   t j |  j | j  } | s@ t   d S)z
        Set the session to be used when the TLS/SSL connection is established.

        :param session: A Session instance representing the session to use.
        :returns: None
        z"session must be a Session instanceN)rd   r   rf   r:   ZSSL_set_sessionr  rM  r5   )r3   rA  rD   r!   r!   r"   set_session  s
    zConnection.set_sessionc             C   ss   t  j d d  } | |  j | d  } | d k r7 d St d |  } | |  j | |  t  j | |  d d  S)a  
        Helper to implement :py:meth:`get_finished` and
        :py:meth:`get_peer_finished`.

        :param function: Either :py:data:`SSL_get_finished`: or
            :py:data:`SSL_get_peer_finished`.

        :return: :py:data:`None` if the desired message has not yet been
            received, otherwise the contents of the message.
        :rtype: :py:class:`bytes` or :py:class:`NoneType`
        zchar[]r   N)rH   rQ   r  r  rZ   )r3   Zfunctionemptyr   r   r!   r!   r"   _get_finished_message  s    z Connection._get_finished_messagec             C   s   |  j  t j  S)a  
        Obtain the latest `handshake finished` message sent to the peer.

        :return: The contents of the message or :py:obj:`None` if the TLS
            handshake has not yet completed.
        :rtype: :py:class:`bytes` or :py:class:`NoneType`
        )rQ  r:   ZSSL_get_finished)r3   r!   r!   r"   get_finished$  s    zConnection.get_finishedc             C   s   |  j  t j  S)a
  
        Obtain the latest `handshake finished` message received from the peer.

        :return: The contents of the message or :py:obj:`None` if the TLS
            handshake has not yet completed.
        :rtype: :py:class:`bytes` or :py:class:`NoneType`
        )rQ  r:   ZSSL_get_peer_finished)r3   r!   r!   r"   get_peer_finished.  s    zConnection.get_peer_finishedc             C   sN   t  j |  j  } | t j k r% d St j t  j |   } | j d  Sd S)z
        Obtain the name of the currently used cipher.

        :returns: The name of the currently used cipher or :py:obj:`None`
            if no connection has been established.
        :rtype: :py:class:`unicode` or :py:class:`NoneType`
        Nzutf-8)r:   SSL_get_current_cipherr  rH   ri   ry   ZSSL_CIPHER_get_namer   )r3   cipherr   r!   r!   r"   get_cipher_name8  s
    zConnection.get_cipher_namec             C   s<   t  j |  j  } | t j k r% d St  j | t j  Sd S)a  
        Obtain the number of secret bits of the currently used cipher.

        :returns: The number of secret bits of the currently used cipher
            or :py:obj:`None` if no connection has been established.
        :rtype: :py:class:`int` or :py:class:`NoneType`
        N)r:   rT  r  rH   ri   ZSSL_CIPHER_get_bits)r3   rU  r!   r!   r"   get_cipher_bitsG  s    zConnection.get_cipher_bitsc             C   sN   t  j |  j  } | t j k r% d St j t  j |   } | j d  Sd S)a  
        Obtain the protocol version of the currently used cipher.

        :returns: The protocol name of the currently used cipher
            or :py:obj:`None` if no connection has been established.
        :rtype: :py:class:`unicode` or :py:class:`NoneType`
        Nzutf-8)r:   rT  r  rH   ri   ry   ZSSL_CIPHER_get_versionr   )r3   rU  versionr!   r!   r"   get_cipher_versionU  s
    zConnection.get_cipher_versionc             C   s(   t  j t j |  j   } | j d  S)a?  
        Obtain the protocol version of the current connection.

        :returns: The TLS version of the current connection, for example
            the value for TLS 1.2 would be ``TLSv1.2``or ``Unknown``
            for connections that were not successfully established.
        :rtype: :py:class:`unicode`
        zutf-8)rH   ry   r:   ZSSL_get_versionr  r   )r3   rX  r!   r!   r"   get_protocol_version_named  s    	z$Connection.get_protocol_version_namec             C   s   t  j |  j  } | S)z
        Obtain the protocol version of the current connection.

        :returns: The TLS version of the current connection, for example
            the value for TLS 1 would be 0x769.
        :rtype: :py:class:`int`
        )r:   ZSSL_versionr  )r3   rX  r!   r!   r"   get_protocol_versionp  s    zConnection.get_protocol_versionc             C   sV   t  j d  } t  j d  } t j |  j | |  t  j | d | d  d d  S)z>
        Get the protocol that was negotiated by NPN.
        zunsigned char **zunsigned int *r   N)rH   rQ   r:   ZSSL_get0_next_proto_negotiatedr  rZ   )r3   rl   data_lenr!   r!   r"   get_next_proto_negotiated{  s    z$Connection.get_next_proto_negotiatedc             C   sW   d j  t j d d   | D   } t j d |  } t j |  j | t |   d S)ah  
        Specify the client's ALPN protocol list.

        These protocols are offered to the server during protocol negotiation.

        :param protos: A list of the protocols to be offered to the server.
            This list should be a Python list of bytestrings representing the
            protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
        rJ   c             s   s'   |  ] } t  t |   | f Vq d  S)N)r   rK   )rL   rM   r!   r!   r"   rN     s    z-Connection.set_alpn_protos.<locals>.<genexpr>zunsigned char[]N)	rO   r   rP   rH   rQ   r:   ZSSL_set_alpn_protosr  rK   )r3   rW   rX   r   r!   r!   r"   r     s    zConnection.set_alpn_protosc             C   s`   t  j d  } t  j d  } t j |  j | |  | s> d St  j | d | d  d d  S)z?
        Get the protocol that was negotiated by ALPN.
        zunsigned char **zunsigned int *rJ   r   N)rH   rQ   r:   ZSSL_get0_alpn_selectedr  rZ   )r3   rl   r\  r!   r!   r"   get_alpn_proto_negotiated  s    z$Connection.get_alpn_proto_negotiatedc             C   s,   t  j |  j t  j  } t | d k  d S)a  
        Called to request that the server sends stapled OCSP data, if
        available. If this is not called on the client side then the server
        will not send OCSP data. Should be used in conjunction with
        :meth:`Context.set_ocsp_client_callback`.
        r$   N)r:   ZSSL_set_tlsext_status_typer  ZTLSEXT_STATUSTYPE_ocspr   )r3   r   r!   r!   r"   request_ocsp  s    zConnection.request_ocsp)Cr   r   r    r+   r   r=   r4   r
  r  r  r  r  r  r  r  r  writer  r  readr#  r%  r&  r'  r)  r*  r(  r+  r-  r/  r1  r3  r4  r7  r9  r:  r   r   r;  r=  r>  rD  rE  rF  rG  rI  rJ  rK  rL  r2  r0  rN  rO  rQ  rR  rS  rV  rW  rY  rZ  r[  r  r]  r  r   r^  r_  r!   r!   r!   r"   r<   G  sx   	1)$)

	

							"

r<   z:ConnectionType has been deprecated, use Connection instead)r   r  sysr   	functoolsr   r   	itertoolsr   r   weakrefr   r  r   Zcryptography.utilsr	   Zsixr
   re   r   r   r   ZOpenSSL._utilr   r   r   Z_exception_from_error_queuer   rH   r   r:   r   Z_make_assertr   r5  r   r   r   r   r   r  ZOpenSSL.cryptor   r   r   r   r   r   r   r   r!  objectrZ   r#   ZOPENSSL_VERSION_NUMBERZSSLEAY_VERSIONZSSLEAY_CFLAGSZSSLEAY_PLATFORMZ
SSLEAY_DIRZSSLEAY_BUILT_ONZSSL_SENT_SHUTDOWNZSENT_SHUTDOWNZSSL_RECEIVED_SHUTDOWNZRECEIVED_SHUTDOWNr   r   r   r   r   r   ZSSL_OP_NO_SSLv2ZOP_NO_SSLv2ZSSL_OP_NO_SSLv3ZOP_NO_SSLv3ZSSL_OP_NO_TLSv1ZOP_NO_TLSv1ZSSL_OP_NO_TLSv1_1ZOP_NO_TLSv1_1ZSSL_OP_NO_TLSv1_2ZOP_NO_TLSv1_2ZSSL_MODE_RELEASE_BUFFERSZMODE_RELEASE_BUFFERSZSSL_OP_SINGLE_DH_USEZOP_SINGLE_DH_USEZSSL_OP_SINGLE_ECDH_USEZOP_SINGLE_ECDH_USEZSSL_OP_EPHEMERAL_RSAZOP_EPHEMERAL_RSAZSSL_OP_MICROSOFT_SESS_ID_BUGZOP_MICROSOFT_SESS_ID_BUGZSSL_OP_NETSCAPE_CHALLENGE_BUGZOP_NETSCAPE_CHALLENGE_BUGZ'SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUGZ#OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUGZ"SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUGZOP_SSLREF2_REUSE_CERT_TYPE_BUGZ!SSL_OP_MICROSOFT_BIG_SSLV3_BUFFERZOP_MICROSOFT_BIG_SSLV3_BUFFERZSSL_OP_MSIE_SSLV2_RSA_PADDINGZOP_MSIE_SSLV2_RSA_PADDINGZSSL_OP_SSLEAY_080_CLIENT_DH_BUGZOP_SSLEAY_080_CLIENT_DH_BUGZSSL_OP_TLS_D5_BUGZOP_TLS_D5_BUGZSSL_OP_TLS_BLOCK_PADDING_BUGZOP_TLS_BLOCK_PADDING_BUGZ"SSL_OP_DONT_INSERT_EMPTY_FRAGMENTSZOP_DONT_INSERT_EMPTY_FRAGMENTSZSSL_OP_CIPHER_SERVER_PREFERENCEZOP_CIPHER_SERVER_PREFERENCEZSSL_OP_TLS_ROLLBACK_BUGZOP_TLS_ROLLBACK_BUGZSSL_OP_PKCS1_CHECK_1ZOP_PKCS1_CHECK_1ZSSL_OP_PKCS1_CHECK_2ZOP_PKCS1_CHECK_2ZSSL_OP_NETSCAPE_CA_DN_BUGZOP_NETSCAPE_CA_DN_BUGZ&SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUGZ"OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUGZSSL_OP_NO_COMPRESSIONZOP_NO_COMPRESSIONZSSL_OP_NO_QUERY_MTUZOP_NO_QUERY_MTUZSSL_OP_COOKIE_EXCHANGEZOP_COOKIE_EXCHANGEZSSL_OP_NO_TICKETZOP_NO_TICKETZ
SSL_OP_ALLZOP_ALLZSSL_VERIFY_PEERZVERIFY_PEERZSSL_VERIFY_FAIL_IF_NO_PEER_CERTZVERIFY_FAIL_IF_NO_PEER_CERTZSSL_VERIFY_CLIENT_ONCEZVERIFY_CLIENT_ONCEZSSL_VERIFY_NONEZVERIFY_NONEZSSL_SESS_CACHE_OFFZSESS_CACHE_OFFZSSL_SESS_CACHE_CLIENTZSESS_CACHE_CLIENTZSSL_SESS_CACHE_SERVERZSESS_CACHE_SERVERZSSL_SESS_CACHE_BOTHZSESS_CACHE_BOTHZSSL_SESS_CACHE_NO_AUTO_CLEARZSESS_CACHE_NO_AUTO_CLEARZ!SSL_SESS_CACHE_NO_INTERNAL_LOOKUPZSESS_CACHE_NO_INTERNAL_LOOKUPZ SSL_SESS_CACHE_NO_INTERNAL_STOREZSESS_CACHE_NO_INTERNAL_STOREZSSL_SESS_CACHE_NO_INTERNALZSESS_CACHE_NO_INTERNALZSSL_ST_CONNECTZSSL_ST_ACCEPTZSSL_ST_MASKZCryptography_HAS_SSL_STZSSL_ST_INITZSSL_ST_BEFOREZ	SSL_ST_OKZSSL_ST_RENEGOTIATEZSSL_CB_LOOPZSSL_CB_EXITZSSL_CB_READZSSL_CB_WRITEZSSL_CB_ALERTZSSL_CB_READ_ALERTZSSL_CB_WRITE_ALERTZSSL_CB_ACCEPT_LOOPZSSL_CB_ACCEPT_EXITZSSL_CB_CONNECT_LOOPZSSL_CB_CONNECT_EXITZSSL_CB_HANDSHAKE_STARTZSSL_CB_HANDSHAKE_DONEr   r   r   r   r>   r*   r5   r   r,   r-   r.   r/   r0   r1   r8   rI   rY   rc   rh   rn   rx   rz   r   ZCryptography_HAS_NEXTPROTONEGr  ZCryptography_HAS_ALPNr  Z Cryptography_HAS_TLSEXT_HOSTNAMEr  r   r   r   DeprecationWarningZContextTyper<   ZConnectionTypeZSSL_library_initr!   r!   r!   r"   <module>   s  "@.

																																																																									&)13H;	     u	