U
    h                     @   sZ   d Z ddlmZ ddlmZmZ ddlmZmZ ddl	m
Z
 ddlmZ G dd	 d	Zd
S )z3
This module holds the CdnDecrypter utility class.
    )sha256   )GetCdnFileRequestReuploadCdnFileRequest)CdnFileReuploadNeededCdnFile)
AESModeCTR)CdnFileTamperedErrorc                   @   s8   e Zd ZdZdd Zedd Zdd Zedd	 Zd
S )CdnDecrypterz
    Used when downloading a file results in a 'FileCdnRedirect' to
    both prepare the redirect, decrypt the file as it downloads, and
    ensure the file hasn't been tampered. https://core.telegram.org/cdn
    c                 C   s   || _ || _|| _|| _dS )a.  
        Initializes the CDN decrypter.

        :param cdn_client: a client connected to a CDN.
        :param file_token: the token of the file to be used.
        :param cdn_aes: the AES CTR used to decrypt the file.
        :param cdn_file_hashes: the hashes the decrypted file must match.
        N)client
file_tokencdn_aescdn_file_hashes)self
cdn_clientr   r   r    r   @/tmp/pip-unpacked-wheel-c81u5j2r/telethon/crypto/cdndecrypter.py__init__   s    	zCdnDecrypter.__init__c                    s   t |j|jdd td d}t||j||j}|t|j|jd j|jd j	dI dH }t
|tr| t|j|jdI dH  | }n*|j|j|_|jd}||j| ||fS )a9  
        Prepares a new CDN decrypter.

        :param client: a TelegramClient connected to the main servers.
        :param cdn_client: a new client connected to the CDN.
        :param cdn_redirect: the redirect file object that caused this call.
        :return: (CdnDecrypter, first chunk file data)
        N      )keyZivr   )r   offsetlimit)r   request_token)r   Zencryption_keyZencryption_ivbytesr
   r   r   r   r   r   
isinstancer   r   r   get_filer   encryptpopcheck)r   r   Zcdn_redirectr   	decryptercdn_filecdn_hashr   r   r   prepare_decrypter    s2    
  



zCdnDecrypter.prepare_decrypterc                 C   sZ   | j rJ| j d}| t| j|j|j}| j|j	|_	| 
|j	| ntt	d}|S )z
        Calls GetCdnFileRequest and decrypts its bytes.
        Also ensures that the file hasn't been tampered.

        :return: the CdnFile result.
        r   )r   r   r   r   r   r   r   r   r   r   r   r   )r   r"   r!   r   r   r   r   L   s      zCdnDecrypter.get_filec                 C   s   t |  |jkrt dS )z
        Checks the integrity of the given data.
        Raises CdnFileTamperedError if the integrity check fails.

        :param data: the data to be hashed.
        :param cdn_hash: the expected hash.
        N)r   digesthashr	   )datar"   r   r   r   r   _   s    	zCdnDecrypter.checkN)	__name__
__module____qualname____doc__r   staticmethodr#   r   r   r   r   r   r   r
      s   
+r
   N)r*   hashlibr   Ztl.functions.uploadr   r   Ztl.types.uploadr   r   Zcryptor   errorsr	   r
   r   r   r   r   <module>   s   