
    Xif#                     N   S r SSKrSSKrSSKJr  SSKrSSKrSSKJr  Sr	Sr
\R                  " S\R                  5      r\R                  " S\R                  5      r\R                  " \5      r\R                  " S	\R                  5      rS
 rS rSS jrS\	4S jrSS jrS rg)z/Helper functions for getting mTLS cert and key.    N)path)
exceptionsz,~/.secureConnect/context_aware_metadata.jsoncert_provider_commands:   -----BEGIN CERTIFICATE-----.+-----END CERTIFICATE-----?
?sH   -----BEGIN [A-Z ]*PRIVATE KEY-----.+-----END [A-Z ]*PRIVATE KEY-----?
?s6   -----BEGIN PASSPHRASE-----(.+)-----END PASSPHRASE-----c                     [         R                  " U 5      n [         R                  " U 5      (       d  [        R	                  SU 5        gU $ )zChecks for context aware metadata. If it exists, returns the absolute path;
otherwise returns None.

Args:
    metadata_path (str): context aware metadata path.

Returns:
    str: absolute path if exists and None otherwise.
z0%s is not found, skip client SSL authentication.N)r   
expanduserexists_LOGGERdebug)metadata_paths    M/app/.venv/lib/python3.13/site-packages/google/auth/transport/_mtls_helper.py_check_dca_metadata_pathr   1   s9     OOM2M;;}%%H-X    c                      [        U 5       n[        R                  " U5      nSSS5        U$ ! , (       d  f       W$ = f! [         a  n[        R
                  " U5      nXCeSnAff = f)zLoads context aware metadata from the given path.

Args:
    metadata_path (str): context aware metadata path.

Returns:
    Dict[str, str]: The metadata.

Raises:
    google.auth.exceptions.ClientCertError: If failed to parse metadata as JSON.
N)openjsonload
ValueErrorr   ClientCertError)r   fmetadata
caught_excnew_excs        r   _read_dca_metadata_filer   B   sa    &- Ayy|H ! O !  O	  &,,Z8%&s.   A  .A  
=A  A   
A'
A""A'Fc                     [         R                  " U [         R                  [         R                  S9nUR                  5       u  p4UR                  S:w  a#  [
        R                  " SUR                  -  5      e[        R                  " [        U5      n[        U5      S:w  a  [
        R                  " S5      e[        R                  " [        U5      n[        U5      S:w  a  [
        R                  " S5      e[        R                  " [        U5      n	U(       a`  [        U	5      S:w  a  [
        R                  " S5      eS	US   ;  a  [
        R                  " S
5      eUS   US   U	S   R                  5       4$ S	US   ;   a  [
        R                  " S5      e[        U	5      S:  a  [
        R                  " S5      eUS   US   S4$ ! [         a  n[
        R                  " U5      nXeeSnAff = f)a  Run the provided command, and return client side mTLS cert, key and
passphrase.

Args:
    command (List[str]): cert provider command.
    expect_encrypted_key (bool): If encrypted private key is expected.

Returns:
    Tuple[bytes, bytes, bytes]: client certificate bytes in PEM format, key
        bytes in PEM format and passphrase bytes.

Raises:
    google.auth.exceptions.ClientCertError: if problems occurs when running
        the cert provider command or generating cert, key and passphrase.
)stdoutstderrNr   z5Cert provider command returns non-zero status code %s   z,Client SSL certificate is missing or invalidz$Client SSL key is missing or invalidz Passphrase is missing or invalids	   ENCRYPTEDz!Encrypted private key is expectedz%Encrypted private key is not expectedzPassphrase is not expected)
subprocessPopenPIPEcommunicateOSErrorr   r   
returncoderefindall_CERT_REGEXlen
_KEY_REGEX_PASSPHRASE_REGEXstrip)
commandexpect_encrypted_keyprocessr   r   r   r   
cert_match	key_matchpassphrase_matchs
             r   _run_cert_provider_commandr1   X   s    &""JOOJOO
 !,,. Q((CgFXFXX
 	

 K0J
:!(()WXX

:v.I
9~(()OPPzz"3V< A%,,-OPPy|+,,-PQQ!}il,<Q,?,E,E,GGGy|#(()PQQ
q (()EFFa=)A,,,=  &,,Z8%&s   AG
 

G1G,,G1c                     [        U5      nU(       ac  [        U5      n[        U;  a  [        R                  " S5      eU[           nU (       a  SU;  a  UR                  S5        [        X@S9u  pVnSXVU4$ g)a  Returns the client side certificate, private key and passphrase.

Args:
    generate_encrypted_key (bool): If set to True, encrypted private key
        and passphrase will be generated; otherwise, unencrypted private key
        will be generated and passphrase will be None.
    context_aware_metadata_path (str): The context_aware_metadata.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.
z"Cert provider command is not foundz--with_passphrase)r,   T)FNNN)r   r   _CERT_PROVIDER_COMMANDr   r   appendr1   )generate_encrypted_keycontext_aware_metadata_pathr   metadata_jsonr+   certkey
passphrases           r   get_client_ssl_credentialsr;      s    * --HIM/>!6,,-QRR 67!&9&HNN./ !;!
: T
**"r   c                 J    U (       a  U " 5       u  pSX4$ [        SS9u  p1p$X1U4$ )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.
TF)r5   )r;   )client_cert_callbackr8   r9   has_cert_s        r   get_client_cert_and_keyr@      s5    ( (*	T7uUHC3r   c                 z    SSK Jn  UR                  UR                  XS9nUR	                  UR                  U5      $ )a  A helper function to decrypt the private key with the given passphrase.
google-auth library doesn't support passphrase protected private key for
mutual TLS channel. This helper function can be used to decrypt the
passphrase protected private key in order to estalish mutual TLS channel.

For example, if you have a function which produces client cert, passphrase
protected private key and passphrase, you can convert it to a client cert
callback function accepted by google-auth::

    from google.auth.transport import _mtls_helper

    def your_client_cert_function():
        return cert, encrypted_key, passphrase

    # callback accepted by google-auth for mutual TLS channel.
    def client_cert_callback():
        cert, encrypted_key, passphrase = your_client_cert_function()
        decrypted_key = _mtls_helper.decrypt_private_key(encrypted_key,
            passphrase)
        return cert, decrypted_key

Args:
    key (bytes): The private key bytes in PEM format.
    passphrase (bytes): The passphrase bytes.

Returns:
    bytes: The decrypted private key in PEM format.

Raises:
    ImportError: If pyOpenSSL is not installed.
    OpenSSL.crypto.Error: If there is any problem decrypting the private key.
r   )crypto)r:   )OpenSSLrB   load_privatekeyFILETYPE_PEMdump_privatekey)r9   r:   rB   pkeys       r   decrypt_private_keyrH      s@    B  !!&"5"5s!RD !!&"5"5t<<r   )F)N)__doc__r   loggingosr   r$   r   google.authr   CONTEXT_AWARE_METADATA_PATHr3   compileDOTALLr&   r(   	getLogger__name__r	   r)   r   r   r1   r;   r@   rH    r   r   <module>rS      s    6    	  "L 0 jjCRYY ZZQII

 

H
% JJ=ryy 
",3-n ! ;(#V8'=r   