a
    fi                     @   s   d Z ddlZddlZddlmZ ddlmZmZmZm	Z	m
Z
mZmZmZmZ ddlmZ ddlmZmZmZmZ ddlmZ dd	lmZ dd
lmZmZmZ dd ZdddZdS )z
This module contains several functions that authenticate the client machine
with Telegram's servers, effectively creating an authorization key.
    N)sha1   )	ResPQPQInnerDataServerDHParamsFailServerDHParamsOkServerDHInnerDataClientDHInnerDataDhGenOk
DhGenRetry	DhGenFail)helpers)AESAuthKeyFactorizationrsa)SecurityError)BinaryReader)ReqPqMultiRequestReqDHParamsRequestSetClientDHParamsRequestc           $   
      s&  t jtdddd}| t|I dH }t|ts@J d| |j|krRt	dt
|j}t|\}}t|t| }}t jtdd	dd}ttt||||j|j|d
}d\}}	|jD ] }
t|
|}|dur|
}	 qq|du r |jD ]&}
tj|
|dd}|dur|
}	 q q|du rJt	dddd |jD | t|j|j|||	|dI dH }t|ttfsJ d| |j|jkrt	d|j|jkrt	dt|trt jt|jdd	dd dd d	dd}|j|krt	dt|tsJ d| t|j|\}}t |j!d dkrHt	dt"#|j!||}t$|:}|%d |& }t|t'sJ d| W d   n1 s0    Y  |j|jkrt	d|j|jkrt	dt
|j(dd}|j)}t
|j*dd}|j+t t,,  }t
tddd}t-|||}t-|||}d |  k rR|d  k s\n t	d!d |  k rx|d  k sn t	d!d |  k r|d  k sn t	d"d#d$ }||  kr|| ksn t	d%||  kr|| ksn t	d&tt.|j|jdt|d'}t| | }t"/|||}| t0|j|j|d(I dH }t1t2t3f}t||sxJ d)| |j4j5}|j|jkrt	d*||j|jkrt	d+|t6t|} d |7t8| }!| 9||!}"t:|d,|!}#|#|"krt	d-t|t1st;d.| | |fS )/z
    Executes the authentication process with the Telegram servers.

    :param sender: a connected `MTProtoPlainSender`.
    :return: returns a (authorization key, time offset) tuple.
       bigT)signedNzStep 1 answer was %sz Step 1 invalid nonce from server    little)pqpqnonceserver_nonce	new_nonce)NN)Zuse_oldz6Step 2 could not find a valid key for fingerprints: {}z, c                 S   s   g | ]}t |qS  )str).0fr"   r"   S/home/ec2-user/.local/lib/python3.9/site-packages/telethon/network/authenticator.py
<listcomp>G       z%do_authentication.<locals>.<listcomp>)r   r    r   r   Zpublic_key_fingerprintencrypted_datazStep 2.1 answer was %sz Step 2 invalid nonce from serverz'Step 2 invalid server nonce from server      z(Step 2 invalid DH fail nonce from serverzStep 2.2 answer was %sr   zStep 3 AES block size mismatchzStep 3 answer was %sz(Step 3 Invalid nonce in encrypted answerz/Step 3 Invalid server nonce in encrypted answerF      z#g_a is not within (1, dh_prime - 1)z#g_b is not within (1, dh_prime - 1)r   i  z7g_a is not within (2^{2048-64}, dh_prime - 2^{2048-64})z7g_b is not within (2^{2048-64}, dh_prime - 2^{2048-64}))r   r    Zretry_idg_b)r   r    r)   zStep 3.1 answer was %sz#Step 3 invalid {} nonce from serverz*Step 3 invalid {} server nonce from serverznew_nonce_hash{}zStep 3 invalid new nonce hashzStep 3.2 answer was %s)<int
from_bytesosurandomsendr   
isinstancer   r   r   get_intr   r   Z	factorizer   Zget_byte_arraybytesr   r    Zserver_public_key_fingerprintsZencryptformatjoinr   r   r   r   to_bytesdigestnew_nonce_hashr   Zgenerate_key_data_from_noncelenZencrypted_answerr   Zdecrypt_iger   readZtgread_objectr   dh_primegg_aZserver_timetimepowr	   Zencrypt_iger   r
   r   r   	__class____name__r   indextypeZcalc_new_nonce_hashgetattrAssertionError)$Zsenderr   Zres_pqr   r   r   r!   Zpq_inner_dataZcipher_textZtarget_fingerprintfingerprintZserver_dh_paramsZnnhkeyZivZplain_text_answerreaderZserver_dh_innerr>   r?   r@   Ztime_offsetbr.   ZgabZsafety_rangeZclient_dh_innerZclient_dh_inner_hashedZclient_dh_encryptedZdh_genZnonce_typesnameZauth_keyZnonce_numberr;   Zdh_hashr"   r"   r&   do_authentication   s    







$

rN   Tc                 C   s   t j| d|dS )a8  
    Gets the specified integer from its byte array.
    This should be used by this module alone, as it works with big endian.

    :param byte_array: the byte array representing th integer.
    :param signed: whether the number is signed or not.
    :return: the integer representing the given byte array.
    r   )	byteorderr   )r/   r0   )Z
byte_arrayr   r"   r"   r&   r5      s    	r5   )T) __doc__r1   rA   hashlibr   Ztl.typesr   r   r   r   r   r	   r
   r   r    r   Zcryptor   r   r   r   errorsr   
extensionsr   Ztl.functionsr   r   r   rN   r5   r"   r"   r"   r&   <module>   s   , 6