U
    g|Y                     @   s  d dl Z d dlmZ d dlmZmZmZmZmZ 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mZmZmZ d
ZW n6 ek
r   dZ
d\ZZZZZd\ZZZZdZY nX d dlmZ d dlmZ d dlm Z  d dl!m"Z" d dl#m$Z$ erd dl%m&Z& edd Z'edd Z(G dd deZ)G dd deZ*G dd deZ+G dd deZ,G d d! d!eZ-G d"d# d#e-Z.G d$d% d%e-Z/dS )&    N)	b64decode)TYPE_CHECKINGOptionalSequenceTupleno_type_check)default_backend)MGF1OAEP)Cipher)AES)CBC)SHA1SHA256SHA512HashT)NNNNN)NNNNF)TelegramObject)parse_sequence_arg)TextEncoding)JSONDict)PassportDecryptionError)Botc           
      C   s   t stdtt t d}|| |  | }|dd |dd  }}tt|t	|t d}|
 }|||  }tt t d}|| | }	|	|krtd|	 d| ||d d S )	a  
    Decrypt per telegram docs at https://core.telegram.org/passport.

    Args:
        secret (:obj:`str` or :obj:`bytes`): The encryption secret, either as bytes or as a
            base64 encoded string.
        hash (:obj:`str` or :obj:`bytes`): The hash, either as bytes or as a
            base64 encoded string.
        data (:obj:`str` or :obj:`bytes`): The data to decrypt, either as bytes or as a
            base64 encoded string.
        file (:obj:`bool`): Force data to be treated as raw data, instead of trying to
            b64decode it.

    Raises:
        :class:`PassportDecryptionError`: Given hash does not match hash of decrypted data.

    Returns:
        :obj:`bytes`: The decrypted data as bytes.

    cTo use Telegram Passports, PTB must be installed via `pip install "python-telegram-bot[passport]"`.)backendN    0   zHashes are not equal! z != r   )CRYPTO_INSTALLEDRuntimeErrorr   r   r   updatefinalizer   r   r   	decryptorr   r   )
secrethashdatadigestZsecret_hash_hashkeyZinit_vectorcipherr    	data_hash r(   B/tmp/pip-unpacked-wheel-swnnwir2/telegram/_passport/credentials.pydecrypt2   s"    
r*   c                 C   s   t t| ||tjS )zPDecrypts data using secret and hash and then decodes utf-8 string and loads json)jsonloadsr*   decoder   ZUTF_8)r!   r"   r#   r(   r(   r)   decrypt_jsonc   s    r.   c                       s^   e Zd ZdZdZddeeeee d fddZe	e
dd	d
Ze	ddddZ  ZS )EncryptedCredentialsaD  Contains data required for decrypting and authenticating EncryptedPassportElement. See the
    Telegram Passport Documentation for a complete description of the data decryption and
    authentication processes.

    Objects of this class are comparable in terms of equality. Two objects of this class are
    considered equal, if their :attr:`data`, :attr:`hash` and :attr:`secret` are equal.

    Note:
        This object is decrypted only when originating from
        :attr:`telegram.PassportData.decrypted_credentials`.

    Args:
        data (:class:`telegram.Credentials` | :obj:`str`): Decrypted data with unique user's
            nonce, data hashes and secrets used for EncryptedPassportElement decryption and
            authentication or base64 encrypted data.
        hash (:obj:`str`): Base64-encoded data hash for data authentication.
        secret (:obj:`str`): Decrypted or encrypted secret used for decryption.

    Attributes:
        data (:class:`telegram.Credentials` | :obj:`str`): Decrypted data with unique user's
            nonce, data hashes and secrets used for EncryptedPassportElement decryption and
            authentication or base64 encrypted data.
        hash (:obj:`str`): Base64-encoded data hash for data authentication.
        secret (:obj:`str`): Decrypted or encrypted secret used for decryption.

    )_decrypted_data_decrypted_secretr#   r"   r!   N
api_kwargs)r#   r"   r!   r3   c                   sJ   t  j|d || _|| _|| _| j| j| jf| _d | _d | _|   d S Nr2   )	super__init__r#   r"   r!   Z	_id_attrsr1   r0   _freeze)selfr#   r"   r!   r3   	__class__r(   r)   r6      s    zEncryptedCredentials.__init__)returnc              
   C   s|   | j dkrvtstdz2|  jt| jtt	t
 dt
 dd| _ W n, tk
rt } zt||W 5 d}~X Y nX | j S )z
        :obj:`bytes`: Lazily decrypt and return secret.

        Raises:
            telegram.error.PassportDecryptionError: Decryption failed. Usually due to bad
                private/public key but can also suggest malformed/tampered data.
        Nr   )	algorithm)Zmgfr<   label)r1   r   r   get_botZprivate_keyr*   r   r!   r
   r	   r   
ValueErrorr   )r8   	exceptionr(   r(   r)   decrypted_secret   s    	



z%EncryptedCredentials.decrypted_secretCredentialsc                 C   s8   | j dkr2tt| jt| jt| j|  | _ | j S )a~  
        :class:`telegram.Credentials`: Lazily decrypt and return credentials data. This object
            also contains the user specified nonce as
            `decrypted_data.nonce`.

        Raises:
            telegram.error.PassportDecryptionError: Decryption failed. Usually due to bad
                private/public key but can also suggest malformed/tampered data.
        N)	r0   rB   de_jsonr.   rA   r   r"   r#   r>   )r8   r(   r(   r)   decrypted_data   s    
z#EncryptedCredentials.decrypted_data)__name__
__module____qualname____doc__	__slots__strr   r   r6   propertybytesrA   rD   __classcell__r(   r(   r9   r)   r/   i   s   r/   c                       s`   e Zd ZdZdZdddeee d fddZe	dee ed	 ed  d
 fddZ
  ZS )rB   z
    Attributes:
        secure_data (:class:`telegram.SecureData`): Credentials for encrypted data
        nonce (:obj:`str`): Bot-specified nonce
    )noncesecure_dataNr2   
SecureData)rO   rN   r3   c                   s&   t  j|d || _|| _|   d S r4   )r5   r6   rO   rN   r7   )r8   rO   rN   r3   r9   r(   r)   r6      s    zCredentials.__init__r   r#   botr;   c                    s:   |  |}|sdS tj|d|d|d< t j||dS ),See :meth:`telegram.TelegramObject.de_json`.NrO   rR   r#   rR   )_parse_datarP   rC   getr5   clsr#   rR   r9   r(   r)   rC      s
    
zCredentials.de_json)N)rE   rF   rG   rH   rI   rJ   r   r   r6   classmethodrC   rM   r(   r(   r9   r)   rB      s     rB   c                       s   e Zd ZdZdZddded ed ed ed ed ed ed ed ed ed ed ee d fddZedee ed	 ed  d
 fddZ	  Z
S )rP   a  
    This object represents the credentials that were used to decrypt the encrypted data.
    All fields are optional and depend on fields that were requested.

    Args:
        personal_details (:class:`telegram.SecureValue`, optional): Credentials for encrypted
            personal details.
        passport (:class:`telegram.SecureValue`, optional): Credentials for encrypted passport.
        internal_passport (:class:`telegram.SecureValue`, optional): Credentials for encrypted
            internal passport.
        driver_license (:class:`telegram.SecureValue`, optional): Credentials for encrypted
            driver license.
        identity_card (:class:`telegram.SecureValue`, optional): Credentials for encrypted ID card
        address (:class:`telegram.SecureValue`, optional): Credentials for encrypted
            residential address.
        utility_bill (:class:`telegram.SecureValue`, optional): Credentials for encrypted
            utility bill.
        bank_statement (:class:`telegram.SecureValue`, optional): Credentials for encrypted
            bank statement.
        rental_agreement (:class:`telegram.SecureValue`, optional): Credentials for encrypted
            rental agreement.
        passport_registration (:class:`telegram.SecureValue`, optional): Credentials for encrypted
            registration from internal passport.
        temporary_registration (:class:`telegram.SecureValue`, optional): Credentials for encrypted
            temporary registration.

    Attributes:
        personal_details (:class:`telegram.SecureValue`): Optional. Credentials for encrypted
            personal details.
        passport (:class:`telegram.SecureValue`): Optional. Credentials for encrypted passport.
        internal_passport (:class:`telegram.SecureValue`): Optional. Credentials for encrypted
            internal passport.
        driver_license (:class:`telegram.SecureValue`): Optional. Credentials for encrypted
            driver license.
        identity_card (:class:`telegram.SecureValue`): Optional. Credentials for encrypted ID card
        address (:class:`telegram.SecureValue`): Optional. Credentials for encrypted
            residential address.
        utility_bill (:class:`telegram.SecureValue`): Optional. Credentials for encrypted
            utility bill.
        bank_statement (:class:`telegram.SecureValue`): Optional. Credentials for encrypted
            bank statement.
        rental_agreement (:class:`telegram.SecureValue`): Optional. Credentials for encrypted
            rental agreement.
        passport_registration (:class:`telegram.SecureValue`): Optional. Credentials for encrypted
            registration from internal passport.
        temporary_registration (:class:`telegram.SecureValue`): Optional. Credentials for encrypted
            temporary registration.
    )addressbank_statementdriver_licenseidentity_cardinternal_passportpassportpassport_registrationpersonal_detailsrental_agreementtemporary_registrationutility_billNr2   SecureValue)rb   r`   r_   r]   r^   r[   re   r\   rc   ra   rd   r3   c                   s\   t  j|d || _|
| _|	| _|| _|| _|| _|| _|| _	|| _
|| _|| _|   d S r4   )r5   r6   rd   ra   rc   r\   re   r[   r^   r]   r_   r`   rb   r7   )r8   rb   r`   r_   r]   r^   r[   re   r\   rc   ra   rd   r3   r9   r(   r)   r6   :  s    zSecureData.__init__r   rQ   c                    s*  |  |}|sdS tj|d|d|d< tj|d|d|d< tj|d|d|d< tj|d|d|d< tj|d|d|d< tj|d|d|d< tj|d	|d|d	< tj|d
|d|d
< tj|d|d|d< tj|d|d|d< tj|d|d|d< t j||dS )rS   Nrd   rT   ra   rc   r\   re   r[   r^   r]   r_   r`   rb   rU   )rV   rf   rC   rW   r5   rX   r9   r(   r)   rC   [  s*    
 
 
zSecureData.de_json)NNNNNNNNNNN)N)rE   rF   rG   rH   rI   r   r   r6   rZ   rC   rM   r(   r(   r9   r)   rP      sH   1           !  rP   c                
       s   e Zd ZdZdZddded ed ed ed eed  eed  ee d fdd	Ze	dee ed
 ed  d fddZ
  ZS )rf   a?  
    This object represents the credentials that were used to decrypt the encrypted value.
    All fields are optional and depend on the type of field.

    Args:
        data (:class:`telegram.DataCredentials`, optional): Credentials for encrypted Telegram
            Passport data. Available for "personal_details", "passport", "driver_license",
            "identity_card", "identity_passport" and "address" types.
        front_side (:class:`telegram.FileCredentials`, optional): Credentials for encrypted
            document's front side. Available for "passport", "driver_license", "identity_card"
            and "internal_passport".
        reverse_side (:class:`telegram.FileCredentials`, optional): Credentials for encrypted
            document's reverse side. Available for "driver_license" and "identity_card".
        selfie (:class:`telegram.FileCredentials`, optional): Credentials for encrypted selfie
            of the user with a document. Can be available for "passport", "driver_license",
            "identity_card" and "internal_passport".
        translation (List[:class:`telegram.FileCredentials`], optional): Credentials for an
            encrypted translation of the document. Available for "passport", "driver_license",
            "identity_card", "internal_passport", "utility_bill", "bank_statement",
            "rental_agreement", "passport_registration" and "temporary_registration".
        files (List[:class:`telegram.FileCredentials`], optional): Credentials for encrypted
            files. Available for "utility_bill", "bank_statement", "rental_agreement",
            "passport_registration" and "temporary_registration" types.

    Attributes:
        data (:class:`telegram.DataCredentials`): Optional. Credentials for encrypted Telegram
            Passport data. Available for "personal_details", "passport", "driver_license",
            "identity_card", "identity_passport" and "address" types.
        front_side (:class:`telegram.FileCredentials`): Optional. Credentials for encrypted
            document's front side. Available for "passport", "driver_license", "identity_card"
            and "internal_passport".
        reverse_side (:class:`telegram.FileCredentials`): Optional. Credentials for encrypted
            document's reverse side. Available for "driver_license" and "identity_card".
        selfie (:class:`telegram.FileCredentials`): Optional. Credentials for encrypted selfie
            of the user with a document. Can be available for "passport", "driver_license",
            "identity_card" and "internal_passport".
        translation (Tuple[:class:`telegram.FileCredentials`]): Optional. Credentials for an
            encrypted translation of the document. Available for "passport", "driver_license",
            "identity_card", "internal_passport", "utility_bill", "bank_statement",
            "rental_agreement", "passport_registration" and "temporary_registration".

            .. versionchanged:: 20.0
                |tupleclassattrs|

        files (Tuple[:class:`telegram.FileCredentials`]): Optional. Credentials for encrypted
            files. Available for "utility_bill", "bank_statement", "rental_agreement",
            "passport_registration" and "temporary_registration" types.

            .. versionchanged:: 20.0

                * |tupleclassattrs|
                * |alwaystuple|

    )r#   files
front_sidereverse_sideselfietranslationNr2   DataCredentialsFileCredentials)r#   rh   ri   rj   rg   rk   r3   c                   sF   t  j|d || _|| _|| _|| _t|| _t|| _| 	  d S r4   )
r5   r6   r#   rh   ri   rj   r   rg   rk   r7   )r8   r#   rh   ri   rj   rg   rk   r3   r9   r(   r)   r6     s    

zSecureValue.__init__r   rQ   c                    s   |  |}|sdS tj|d|d|d< tj|d|d|d< tj|d|d|d< tj|d|d|d< tj|d|d|d< tj|d|d|d< t j||d	S )
rS   Nr#   rT   rh   ri   rj   rg   rk   rU   )rV   rl   rC   rW   rm   Zde_listr5   rX   r9   r(   r)   rC     s    
zSecureValue.de_json)NNNNNN)N)rE   rF   rG   rH   rI   r   r   r   r6   rZ   rC   rM   r(   r(   r9   r)   rf   x  s4   7      	

  rf   c                       s8   e Zd ZdZdZddeeee d fddZ  Z	S )_CredentialsBasez3Base class for DataCredentials and FileCredentials.)r'   	file_hashr"   r!   Nr2   r"   r!   r3   c             	      sB   t  j|d |  " || _|| _| j| _| j| _W 5 Q R X d S r4   )r5   r6   Z	_unfrozenr"   r!   ro   r'   )r8   r"   r!   r3   r9   r(   r)   r6     s    
z_CredentialsBase.__init__
rE   rF   rG   rH   rI   rJ   r   r   r6   rM   r(   r(   r9   r)   rn     s   rn   c                       s8   e Zd ZdZdZddeeee d fddZ  Z	S )rl   al  
    These credentials can be used to decrypt encrypted data from the data field in
    EncryptedPassportData.

    Args:
        data_hash (:obj:`str`): Checksum of encrypted data
        secret (:obj:`str`): Secret of encrypted data

    Attributes:
        hash (:obj:`str`): Checksum of encrypted data
        secret (:obj:`str`): Secret of encrypted data
    r(   Nr2   )r'   r!   r3   c                   s   t  j|||d |   d S Nrp   r5   r6   r7   )r8   r'   r!   r3   r9   r(   r)   r6     s    zDataCredentials.__init__rq   r(   r(   r9   r)   rl     s   rl   c                       s8   e Zd ZdZdZddeeee d fddZ  Z	S )rm   a  
    These credentials can be used to decrypt encrypted files from the front_side,
    reverse_side, selfie and files fields in EncryptedPassportData.

    Args:
        file_hash (:obj:`str`): Checksum of encrypted file
        secret (:obj:`str`): Secret of encrypted file

    Attributes:
        hash (:obj:`str`): Checksum of encrypted file
        secret (:obj:`str`): Secret of encrypted file
    r(   Nr2   )ro   r!   r3   c                   s   t  j|||d |   d S rr   rs   )r8   ro   r!   r3   r9   r(   r)   r6     s    zFileCredentials.__init__rq   r(   r(   r9   r)   rm     s   rm   )0r+   base64r   typingr   r   r   r   r   Zcryptography.hazmat.backendsr   Z1cryptography.hazmat.primitives.asymmetric.paddingr	   r
   Z&cryptography.hazmat.primitives.ciphersr   Z1cryptography.hazmat.primitives.ciphers.algorithmsr   Z,cryptography.hazmat.primitives.ciphers.modesr   Z%cryptography.hazmat.primitives.hashesr   r   r   r   r   ImportErrorZtelegram._telegramobjectr   Ztelegram._utils.argumentparsingr   Ztelegram._utils.stringsr   Ztelegram._utils.typesr   Ztelegram.errorr   Ztelegramr   r*   r.   r/   rB   rP   rf   rn   rl   rm   r(   r(   r(   r)   <module>   sB   

0
k&~c