U
    /j                     @   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mZ ddl	m
Z
 ddlZddlZeeZejedddZdeeee ejdd	d
Zdd Zdd ZdddZdddZdS )z<
Helper functions for mTLS in async for discovery of certs.
    N)Optional)
exceptions)contentc              	   c   sV   t  \}}z,t|d}||  W 5 Q R X |V  W 5 tj|rPt| X dS )zCreates a temporary file with the given content.

    Args:
        content (bytes): The content to write to the file.

    Yields:
        str: The path to the temporary file.
    wbN)tempfilemkstempospathexistsremovefdopenwrite)r   fd	file_pathf r   B/tmp/pip-unpacked-wheel-l8yytoim/google/auth/aio/transport/mtls.py_create_temp_file"   s    
r   )
cert_bytes	key_bytes
passphrasereturnc                 C   s   t | }t |~}z<ttjj}|j|||d |W W  5 Q R  W  5 Q R  S  tjttt	t
fk
r } ztd|W 5 d}~X Y nX W 5 Q R X W 5 Q R X dS )a  Creates an SSLContext with the given client certificate and key.
    This function writes the certificate and key to temporary files so that
    ssl.create_default_context can load them, as the ssl module requires
    file paths for client certificates. These temporary files are deleted
    immediately after the SSL context is created.
    Args:
        cert_bytes (bytes): The client certificate content in PEM format.
        key_bytes (bytes): The client private key content in PEM format.
        passphrase (Optional[bytes]): The passphrase for the private key, if any.
    Returns:
        ssl.SSLContext: The configured SSL context with client certificate.

    Raises:
        google.auth.exceptions.TransportError: If there is an error loading the certificate.
    )certfilekeyfilepasswordz3Failed to load client certificate and key for mTLS.N)r   sslcreate_default_contextPurposeSERVER_AUTHload_cert_chainSSLErrorOSErrorIOError
ValueErrorRuntimeErrorr   ZTransportError)r   r   r   Z	cert_pathZkey_pathcontextexcr   r   r   make_client_cert_ssl_context8   s$      r'   c                    sR   zt j| f| I dH W S  tk
rL   t  }|jd| f| I dH  Y S X dS )zRun a blocking function in an executor to avoid blocking the event loop.

    This implements the non-blocking execution strategy for disk I/O operations.
    N)asyncioZ	to_threadAttributeErrorZget_running_loopZrun_in_executor)funcargsZloopr   r   r   _run_in_executorY   s
    r,   c                  C   s(   t jjjjddstddd } | S )a  Get a callback which returns the default client SSL credentials.

    Returns:
        Awaitable[Callable[[], Tuple[bytes, bytes]]]: A callback which returns the default
            client certificate bytes and private key bytes, both in PEM format.

    Raises:
        google.auth.exceptions.DefaultClientCertSourceError: If the default
            client SSL credentials don't exist or are malformed.
    F)Zinclude_context_awarez(Default client cert source doesn't existc               
      sX   zt  I d H \} }}W n8 tttfk
rN } zt|}||W 5 d }~X Y nX ||fS )N)get_client_cert_and_keyr!   r$   r#   r   MutualTLSChannelError)_r   r   Z
caught_excnew_excr   r   r   callbacky   s    
z,default_client_cert_source.<locals>.callback)googleauth	transportZmtlsZhas_default_client_cert_sourcer   r.   )r1   r   r   r   default_client_cert_sourceg   s    
	r5   c                    s6   t tjjjj| dI dH \}}|r2|r2d||dfS dS )a  Returns the client side certificate, private key and passphrase.

    We look for certificates and keys with the following order of priority:
        1. Certificate and key specified by certificate_config.json.
               Currently, only X.509 workload certificates are supported.

    Args:
        certificate_config_path (str): The certificate_config.json file path.

    Returns:
        Tuple[bool, bytes, bytes, bytes]:
            A boolean indicating if cert, key and passphrase are obtained, the
            cert bytes and key bytes both in PEM format, and passphrase bytes.

    Raises:
        google.auth.exceptions.ClientCertError: if problems occurs when getting
            the cert, key and passphrase.
    FNT)FNNN)r,   r2   r3   r4   Z_mtls_helperZ_get_workload_cert_and_key)Zcertificate_config_pathcertkeyr   r   r   get_client_ssl_credentials   s    
r8   c                    sb   | rD|  }z|I dH \}}W n t k
r8   |\}}Y nX d||fS t I dH \}}}}|||fS )a  Returns the client side certificate and private key. The function first
    tries to get certificate and key from client_cert_callback; if the callback
    is None or doesn't provide certificate and key, the function tries application
    default SSL credentials.

    Args:
        client_cert_callback (Optional[Callable[[], (bytes, bytes)]]): An
            optional callback which returns client certificate bytes and private
            key bytes both in PEM format.

    Returns:
        Tuple[bool, bytes, bytes]:
            A boolean indicating if cert and key are obtained, the cert bytes
            and key bytes both in PEM format.

    Raises:
        google.auth.exceptions.ClientCertError: if problems occurs when getting
            the cert and key.
    NT)	TypeErrorr8   )Zclient_cert_callbackresultr6   r7   Zhas_certr/   r   r   r   r-      s    
r-   )N)N)N)__doc__r(   
contextlibloggingr   r   r   typingr   Zgoogle.authr   Z"google.auth.transport._mtls_helperr2   Zgoogle.auth.transport.mtls	getLogger__name__Z_LOGGERcontextmanagerbytesr   
SSLContextr'   r,   r5   r8   r-   r   r   r   r   <module>   s2   
   ! 
#