o
    i#                     @   s.  d dl mZ d dlmZmZmZmZmZmZ d dl	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 G d
d deZdedefddZeddefddefgZd dedee defddZd dedee defddZ				d!dee deeeef  dee dededefddZdS )"    )hexlify)cast
NamedTupleUnionDictAnyOptional)x509)hashesserialization)RSAPrivateKey)default_backend   )validate_tenant_id)ClientCredentialBasec                       s<   e Zd ZdZd
dededee deddf
 fdd	Z  ZS )CertificateCredentiala  Authenticates as a service principal using a certificate.

    The certificate must have an RSA private key, because this credential signs assertions using RS256. See
    `Microsoft Entra ID documentation
    <https://learn.microsoft.com/entra/identity-platform/certificate-credentials#register-your-certificate-with-microsoft-identity-platform>`__
    for more information on configuring certificate authentication.

    :param str tenant_id: ID of the service principal's tenant. Also called its "directory" ID.
    :param str client_id: The service principal's client ID
    :param str certificate_path: Optional path to a certificate file in PEM or PKCS12 format, including the private
        key. If not provided, **certificate_data** is required.

    :keyword str authority: Authority of a Microsoft Entra endpoint, for example "login.microsoftonline.com",
        the authority for Azure Public Cloud (which is the default). :class:`~azure.identity.AzureAuthorityHosts`
        defines authorities for other clouds.
    :keyword bytes certificate_data: The bytes of a certificate in PEM or PKCS12 format, including the private key
    :keyword password: The certificate's password. If a unicode string, it will be encoded as UTF-8. If the certificate
        requires a different encoding, pass appropriately encoded bytes instead.
    :paramtype password: str or bytes
    :keyword bool send_certificate_chain: If True, the credential will send the public certificate chain in the x5c
        header of each token request's JWT. This is required for Subject Name/Issuer (SNI) authentication. Defaults to
        False.
    :keyword cache_persistence_options: Configuration for persistent token caching. If unspecified, the credential
        will cache tokens in memory.
    :paramtype cache_persistence_options: ~azure.identity.TokenCachePersistenceOptions
    :keyword bool disable_instance_discovery: Determines whether or not instance discovery is performed when attempting
        to authenticate. Setting this to true will completely disable both instance discovery and authority validation.
        This functionality is intended for use in scenarios where the metadata endpoint cannot be reached, such as in
        private clouds or Azure Stack. The process of instance discovery entails retrieving authority metadata from
        https://login.microsoft.com/ to validate the authority. By setting this to **True**, the validation of the
        authority is disabled. As a result, it is crucial to ensure that the configured authority host is valid and
        trustworthy.
    :keyword List[str] additionally_allowed_tenants: Specifies tenants in addition to the specified "tenant_id"
        for which the credential may acquire tokens. Add the wildcard value "*" to allow the credential to
        acquire tokens for any tenant the application can access.

    .. admonition:: Example:

        .. literalinclude:: ../samples/credential_creation_code_snippets.py
            :start-after: [START create_certificate_credential]
            :end-before: [END create_certificate_credential]
            :language: python
            :dedent: 4
            :caption: Create a CertificateCredential.
    N	tenant_id	client_idcertificate_pathkwargsreturnc                    s:   t | t|fi |}tt| jd|||d| d S )N)r   client_credentialr    )r   get_client_credentialsuperr   __init__)selfr   r   r   r   r   	__class__r   ^/home/app/Keep/.python/lib/python3.10/site-packages/azure/identity/_credentials/certificate.pyr   @   s   
zCertificateCredential.__init__N)	__name__
__module____qualname____doc__strr   r   r   __classcell__r   r   r   r   r      s    0.r   	pem_bytesr   c                 C   s>   |  d}d}| |}| ||t| d  }d| S )zExtract a certificate chain from a PEM file's bytes, removing line breaks.

    :param bytes pem_bytes: The PEM file's bytes
    :return: The certificate chain
    :rtype: bytes
    s   -----BEGIN CERTIFICATE-----s   -----END CERTIFICATE-----       )indexrindexlenjoin
splitlines)r'   startfooterendchainr   r   r   extract_cert_chainJ   s
   
	
r3   _Cert)private_keyr   fingerprintNcertificate_datapasswordc                 C   s:   t j| |t d}t| t }|t }t| ||S )Nbackend)	r   Zload_pem_private_keyr   r	   Zload_pem_x509_certificater6   r
   SHA1r4   )r7   r8   r5   certr6   r   r   r   load_pem_certificate^   s   r=   c              
      s   ddl m m}m}m} z|j| |t d\}}}W n ty+ } ztd|d }~ww |s2td|s8td| j	|j
| }	|	g fdd|g| D  }
d|
}|t }t|||S )	Nr   )EncodingNoEncryptionpkcs12PrivateFormatr9   z9Failed to deserialize certificate in PEM or PKCS12 formatz,The certificate must include its private keyc                    s   g | ]}|  jqS r   )public_bytesPEM).0cr>   r   r   
<listcomp>x   s    z+load_pkcs12_certificate.<locals>.<listcomp>r)   )Z,cryptography.hazmat.primitives.serializationr>   r?   r@   rA   Zload_key_and_certificatesr   
ValueErrorZprivate_bytesrC   ZPKCS8r-   r6   r
   r;   r4   )r7   r8   r?   r@   rA   r5   r<   Zadditional_certsex	key_bytesZpem_sectionsr'   r6   r   rF   r   load_pkcs12_certificatee   s$   

rK   Fr   send_certificate_chain_c           
   
   K   s  | r"|rt dt| d}| }W d   n1 sw   Y  n|s(t d|r4t|tr4|d}td|}d|v rCt||}nt||}d}t|j	t
sTt d|jt|jdd	}|rf||d
< |rzt|j}|d|d< W |S  t y }	 zt d|	d}	~	ww |S )a  Load a certificate from a filesystem path or bytes, return it as a dict suitable for msal.ClientApplication.

    :param str certificate_path: Path to a PEM or PKCS12 certificate file.
    :param bytes password: The certificate's password, if any.
    :param bytes certificate_data: The PEM or PKCS12 certificate's bytes.
    :param bool send_certificate_chain: Whether to send the certificate chain. Defaults to False.

    :return: The certificate as a dict
    :rtype: dict
    zHPlease specify either "certificate_path" or "certificate_data", not bothrbNzZCertificateCredential requires a value for either "certificate_path" or "certificate_data"zutf-8zOptional[bytes]s
   -----BEGINzNThe certificate must have an RSA private key because RS256 is used for signing)r5   Z
thumbprintZ
passphraseZpublic_certificatezMalformed certificate)rH   openread
isinstancer%   encoder   r=   rK   r5   r   r'   r   r6   decoder3   )
r   r8   r7   rL   rM   fr<   r   r2   rI   r   r   r   r      s@   






r   r    )NNNF)binasciir   typingr   r   r   r   r   r   Zcryptographyr	   Zcryptography.hazmat.primitivesr
   r   Z-cryptography.hazmat.primitives.asymmetric.rsar   Zcryptography.hazmat.backendsr   	_internalr   Z _internal.client_credential_baser   r   bytesr3   r4   r=   rK   r%   boolr   r   r   r   r   <module>   s<    9