U
    T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	 e
eZeejeejeejeejejZdd Zdd Zdd	 Zd
d Zdd Zdd ZG dd deZdS )z]
Code for configuring client side TLS to offload the signing operation to
signing libraries.
    N)
exceptionsc                 C   s   t tt d| t jS )NZintptr_t)ctypescastintcffiZFFIc_void_p)Zssl_ctx r   L/tmp/pip-unpacked-wheel-hwewmx0w/google/auth/transport/_custom_tls_signer.py_cast_ssl_ctx_to_void_p2   s    r
   c                 C   sX   t d|  tjdkr.tjdkr.tj| ddnt| }ttj	tj
g|j_tj|j_|S )Nzloading offload library from %s      ntr   winmode)_LOGGERdebugsysversion_infoosnamer   CDLLSIGN_CALLBACK_CTYPEc_char_pr   ConfigureSslContextargtypesc_intrestype)Zoffload_lib_pathlibr   r   r	   load_offload_lib7   s    	
r   c                 C   s   t d|  tjdkr.tjdkr.tj| ddnt| }tjtjtj	g|j
_tj	|j
_tjtjtj	tjtj	g|j_tj	|j_|S )Nzloading signer library from %sr   r   r   r   )r   r   r   r   r   r   r   r   r   r   GetCertPemForPythonr   r   SignForPython)Zsigner_lib_pathr   r   r   r	   load_signer_libO   s"    

r"   c                 C   s8   ddl m} t| |}|| }|| | S )Nr   )hashes)Zcryptography.hazmat.primitivesr#   r   	string_atZHashSHA256updatefinalize)Zto_be_signedZto_be_signed_lenr#   datahashr   r   r	   _compute_sha256_digestp   s
    
r*   c                    s    fdd}t |S )Nc                    s   t d t||}tjt| }d}t|}  |	t
|t|||}|dkr`dS ||d< t
|}	t|D ]}
|	|
 | |
< qxdS )Nzcalling sign callback...i  r      )r   r   r*   r   c_charlencreate_string_bufferr!   encodefrom_buffer	bytearrayrange)sigZsig_lenZtbsZtbs_lendigestZdigestArrayZsig_holder_lenZ
sig_holderZsignature_lenbsiconfig_file_path
signer_libr   r	   sign_callback|   s&    


z(get_sign_callback.<locals>.sign_callback)r   )r9   r8   r:   r   r7   r	   get_sign_callback{   s    r;   c                 C   sH   |  | d d}|dkr$tdt|}|  | || t|S )Nr   zfailed to get certificate)r    r/   r   MutualTLSChannelErrorr   r.   bytes)r9   r8   Zcert_lenZcert_holderr   r   r	   get_cert   s    

r>   c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
CustomTlsSignerc                 C   s   || _ d| _d| _dS )a  
        This class loads the offload and signer library, and calls APIs from
        these libraries to obtain the cert and a signing callback, and attach
        them to SSL context. The cert and the signing callback will be used
        for client authentication in TLS handshake.

        Args:
            enterprise_cert_file_path (str): the path to a enterprise cert JSON
                file. The file should contain the following field:

                    {
                        "libs": {
                            "ecp_client": "...",
                            "tls_offload": "..."
                        }
                    }
        N)_enterprise_cert_file_path_cert_sign_callback)selfZenterprise_cert_file_pathr   r   r	   __init__   s    zCustomTlsSigner.__init__c              
   C   s   z>t | jd(}t|}|d }|d }|d }W 5 Q R X W n> ttfk
r| } ztd|}t	|| W 5 d }~X Y nX t
|| _t|| _d S )NrlibsZ
ecp_clientZtls_offloadzenterprise cert file is invalid)openr@   jsonloadKeyError
ValueErrorr   r<   six
raise_fromr   _offload_libr"   _signer_lib)rC   fZenterprise_cert_jsonrF   Zsigner_libraryZoffload_libraryZ
caught_excnew_excr   r   r	   load_libraries   s    
 
zCustomTlsSigner.load_librariesc                 C   s$   t | j| j| _t| j| j| _d S )N)r>   rO   r@   rA   r;   rB   )rC   r   r   r	   set_up_custom_key   s
     z!CustomTlsSigner.set_up_custom_keyc                 C   s0   | j | jt| jt|jjs,t	
dd S )Nzfailed to configure SSL context)rN   r   rB   r   r   rA   r
   Z_ctx_contextr   r<   )rC   ctxr   r   r	   attach_to_ssl_context   s    

z%CustomTlsSigner.attach_to_ssl_contextN)__name__
__module____qualname__rD   rR   rS   rV   r   r   r   r	   r?      s   r?   )__doc__r   rH   loggingr   r   r   rL   Zgoogle.authr   	getLoggerrW   r   	CFUNCTYPEr   POINTERc_ubytec_size_tr   r
   r   r"   r*   r;   r>   objectr?   r   r   r   r	   <module>   s.   
	



!&