U
    Øccv(  ã                   @   s¶   d Z ddl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 ddlmZ ed	d
ƒ\ZZZZZdd„ ed	d
ƒD ƒ\ZZZZZG dd„ deƒZG dd„ deƒZdS )zÒ
Variant on `KexGroup1 <paramiko.kex_group1.KexGroup1>` where the prime "p" and
generator "g" are provided by the server.  A bit more work is required on the
client side, and a **lot** more on the server side.
é    N)Úsha1Úsha256)Úutil)ÚDEBUG)ÚMessage)Úbyte_chrÚbyte_ordÚ	byte_mask)ÚSSHExceptioné   é#   c                 C   s   g | ]}t |ƒ‘qS © )r   )Ú.0Úcr   r   ú4/tmp/pip-unpacked-wheel-rglolp_m/paramiko/kex_gex.pyÚ
<listcomp>1   s     r   c                   @   sj   e Zd ZdZdZdZdZeZdd„ Z	ddd	„Z
d
d„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )ÚKexGexz"diffie-hellman-group-exchange-sha1é   é    i   c                 C   s4   || _ d | _d | _d | _d | _d | _d | _d| _d S )NF)Ú	transportÚpÚqÚgÚxÚeÚfÚ	old_style)Úselfr   r   r   r   Ú__init__<   s    zKexGex.__init__Fc                 C   sŒ   | j jr| j  tt¡ d S tƒ }|rB| t¡ | | j	¡ d| _
n.| t¡ | | j¡ | | j	¡ | | j¡ | j  |¡ | j  t¡ d S )NT)r   Zserver_modeÚ_expect_packetÚ_MSG_KEXDH_GEX_REQUESTÚ_MSG_KEXDH_GEX_REQUEST_OLDr   Úadd_byteÚc_MSG_KEXDH_GEX_REQUEST_OLDÚadd_intÚpreferred_bitsr   Úc_MSG_KEXDH_GEX_REQUESTÚmin_bitsÚmax_bitsÚ_send_messageÚ_MSG_KEXDH_GEX_GROUP)r   Z_test_old_styleÚmr   r   r   Ú	start_kexF   s"     ÿ

zKexGex.start_kexc                 C   st   |t kr|  |¡S |tkr$|  |¡S |tkr6|  |¡S |tkrH|  |¡S |tkrZ|  	|¡S d}t
| | j|¡ƒ‚d S )Nz*KexGex {} asked to handle packet type {:d})r    Ú_parse_kexdh_gex_requestr*   Ú_parse_kexdh_gex_groupÚ_MSG_KEXDH_GEX_INITÚ_parse_kexdh_gex_initÚ_MSG_KEXDH_GEX_REPLYÚ_parse_kexdh_gex_replyr!   Ú_parse_kexdh_gex_request_oldr
   ÚformatÚname)r   Úptyper+   Úmsgr   r   r   Ú
parse_next]   s    




zKexGex.parse_nextc                 C   sš   | j d d }t |d¡}t|d ƒ}t|ƒ}d}|d@ sL|dK }|dL }q2t |¡}t|d |ƒ|dd …  }t |d¡}|dkrL||k rLqqL|| _	d S )Né   é   r   éÿ   é€   )
r   r   Zdeflate_longr   ÚlenÚosÚurandomr	   Zinflate_longr   )r   r   ZqnormZqhbyteZ
byte_countZqmaskZx_bytesr   r   r   r   Ú_generate_xm   s    

zKexGex._generate_xc                 C   sî   |  ¡ }|  ¡ }|  ¡ }|| jkr(| j}|| jk r8| j}||krD|}||k rP|}|| _|| _|| _| j ¡ }|d kr|tdƒ‚| j td 	|||¡¡ | 
|||¡\| _| _tƒ }| t¡ | | j¡ | | j¡ | j |¡ | j t¡ d S )Nú-Can't do server-side gex with no modulus packzPicking p ({} <= {} <= {} bits))Úget_intr(   r'   r%   r   Ú_get_modulus_packr
   Ú_logr   r4   Úget_modulusr   r   r   r"   Úc_MSG_KEXDH_GEX_GROUPÚ	add_mpintr)   r   r/   )r   r+   ZminbitsZpreferredbitsZmaxbitsÚpackr   r   r   r-      s@    


  ÿþ
zKexGex._parse_kexdh_gex_requestc                 C   sÈ   |  ¡ | _| j| jkr| j| _| j| jk r2| j| _| j ¡ }|d krLtdƒ‚| j td 	| j¡¡ | 
| j| j| j¡\| _| _tƒ }| t¡ | | j¡ | | j¡ | j |¡ | j t¡ d| _d S )NrA   zPicking p (~ {} bits)T)rB   r%   r(   r'   r   rC   r
   rD   r   r4   rE   r   r   r   r"   rF   rG   r)   r   r/   r   )r   r+   rH   r   r   r   r3   ¥   s0    

 
ÿ  ÿ
z#KexGex._parse_kexdh_gex_request_oldc                 C   s¦   |  ¡ | _|  ¡ | _t | j¡}|dk s0|dkr>td |¡ƒ‚| j t	d |¡¡ |  
¡  t| j| j| jƒ| _tƒ }| t¡ | | j¡ | j |¡ | j t¡ d S )Nr   r   z<Server-generated gex p (don't ask) is out of range ({} bits)zGot server p ({} bits))Ú	get_mpintr   r   r   Ú
bit_lengthr
   r4   r   rD   r   r@   Úpowr   r   r   r"   Úc_MSG_KEXDH_GEX_INITrG   r)   r   r1   )r   r+   Zbitlenr   r   r   r.   À   s"    

ÿÿ
zKexGex._parse_kexdh_gex_groupc                 C   sz  |  ¡ | _| jdk s$| j| jd kr,tdƒ‚|  ¡  t| j| j| jƒ| _t| j| j| jƒ}| j	 
¡  ¡ }tƒ }| | j	j| j	j| j	j| j	j|¡ | js¢| | j¡ | | j¡ | jsÀ| | j¡ | | j¡ | | j¡ | | j¡ | | j¡ | |¡ |  | ¡ ¡ ¡ }| j	 ||¡ | j	 
¡  || j	j¡}tƒ }| t¡ | |¡ | | j¡ | |¡ | j	  |¡ | j	 !¡  d S )Nr9   zClient kex "e" is out of range)"rI   r   r   r
   r@   rK   r   r   r   r   Zget_server_keyÚasbytesr   ÚaddÚremote_versionÚlocal_versionÚremote_kex_initÚlocal_kex_initr   r$   r'   r%   r(   rG   Ú	hash_algoÚdigestÚ_set_K_HZsign_ssh_dataZhost_key_typer"   Úc_MSG_KEXDH_GEX_REPLYZ
add_stringr)   Ú_activate_outbound)r   r+   ÚKÚkeyÚhmÚHÚsigr   r   r   r0   Ô   sL    
û

 ÿ


zKexGex._parse_kexdh_gex_initc                 C   s  |  ¡ }| ¡ | _|  ¡ }| jdk s4| j| jd kr<tdƒ‚t| j| j| jƒ}tƒ }| | j	j
| j	j| j	j| j	j|¡ | jsˆ| | j¡ | | j¡ | js¦| | j¡ | | j¡ | | j¡ | | j¡ | | j¡ | |¡ | j	 ||  | ¡ ¡ ¡ ¡ | j	 ||¡ | j	 ¡  d S )Nr9   zServer kex "f" is out of range)Z
get_stringrI   r   r   r
   rK   r   r   rN   r   rP   rO   rR   rQ   r   r$   r'   r%   r(   rG   r   r   rU   rS   rM   rT   Z_verify_keyrW   )r   r+   Zhost_keyr\   rX   rZ   r   r   r   r2   ÿ   s6    
û
zKexGex._parse_kexdh_gex_replyN)F)Ú__name__Ú
__module__Ú__qualname__r5   r'   r(   r%   r   rS   r   r,   r8   r@   r-   r3   r.   r0   r2   r   r   r   r   r   4   s   

&+r   c                   @   s   e Zd ZdZeZdS )ÚKexGexSHA256z$diffie-hellman-group-exchange-sha256N)r]   r^   r_   r5   r   rS   r   r   r   r   r`     s   r`   )Ú__doc__r>   Úhashlibr   r   Zparamikor   Zparamiko.commonr   Zparamiko.messager   Zparamiko.py3compatr   r   r	   Zparamiko.ssh_exceptionr
   Úranger!   r*   r/   r1   r    r#   rF   rL   rV   r&   Úobjectr   r`   r   r   r   r   Ú<module>   s0   	ú	ú l