U
    cc,                     @   s   d Z ddl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mZ 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 G dd deZG dd deZG dd deZdS )z
ECDSA keys
    )InvalidSignatureUnsupportedAlgorithm)default_backend)hashesserialization)ec)decode_dss_signatureencode_dss_signature)	four_byte)Message)PKey)SSHException)deflate_longc                   @   s   e Zd ZdZdd ZdS )_ECDSACurvez
    Represents a specific ECDSA Curve (nistp256, nistp384, etc).

    Handles the generation of the key format identifier and the selection of
    the proper hash function. Also grabs the proper curve from the 'ecdsa'
    package.
    c                 C   sT   || _ |j| _d| j  | _| jdkr.tj| _n| jdkrBtj| _ntj| _|| _	d S )Necdsa-sha2-   i  )
	nist_namekey_size
key_lengthkey_format_identifierr   SHA256hash_objectSHA384SHA512curve_class)selfr   r    r   5/tmp/pip-unpacked-wheel-rglolp_m/paramiko/ecdsakey.py__init__0   s    



z_ECDSACurve.__init__N)__name__
__module____qualname____doc__r   r   r   r   r   r   '   s   r   c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )_ECDSACurveSetz
    A collection to hold the ECDSA curves. Allows querying by oid and by key
    format identifier. The two ways in which ECDSAKey needs to be able to look
    up curves.
    c                 C   s
   || _ d S Necdsa_curves)r   r&   r   r   r   r   I   s    z_ECDSACurveSet.__init__c                 C   s   dd | j D S )Nc                 S   s   g | ]
}|j qS r   )r   ).0curver   r   r   
<listcomp>M   s     zA_ECDSACurveSet.get_key_format_identifier_list.<locals>.<listcomp>r%   r   r   r   r   get_key_format_identifier_listL   s    z-_ECDSACurveSet.get_key_format_identifier_listc                 C   s"   | j D ]}|j|kr|  S qd S r$   )r&   r   )r   r   r(   r   r   r   get_by_curve_classO   s    

z!_ECDSACurveSet.get_by_curve_classc                 C   s"   | j D ]}|j|kr|  S qd S r$   )r&   r   )r   r   r(   r   r   r   get_by_key_format_identifierT   s    

z+_ECDSACurveSet.get_by_key_format_identifierc                 C   s"   | j D ]}|j|kr|  S qd S r$   )r&   r   )r   r   r(   r   r   r   get_by_key_lengthY   s    

z _ECDSACurveSet.get_by_key_lengthN)	r   r    r!   r"   r   r+   r,   r-   r.   r   r   r   r   r#   B   s   r#   c                   @   s   e Zd ZdZeeejdeejdeej	dgZ
d+ddZed	d
 Zdd Zdd Zedd Zdd Zdd Zdd Zd,ddZdd Zd-ddZd.ddZee ddfdd Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* ZdS )/ECDSAKeyz\
    Representation of an ECDSA key which can be used to sign and verify SSH2
    data.
    Znistp256Znistp384Znistp521NTc                 C   sT  d | _ d | _d | _|d k	r*| || d S |d k	rB| || d S |d krZ|d k	rZt|}|d k	r|\| _| _ | jjj}| j	|| _
n| }	d}
|	|
r|	d t|
  }	| j|	| _
| j }dd |D }| j|||d | }|| j
jkr
td|| }ztj| j
 |}|| _ W n tk
rN   tdY nX d S )Nz-cert-v01@openssh.comc                 S   s   g | ]}d  |qS )z{}-cert-v01@openssh.com)format)r'   xr   r   r   r)      s    z%ECDSAKey.__init__.<locals>.<listcomp>)msgkey_typeZ	cert_typezCan't handle curve of type {}zInvalid public key)verifying_keysigning_keyZpublic_blob_from_private_key_from_private_key_filer   r(   	__class___ECDSA_CURVESr,   ecdsa_curveget_textendswithlenr-   r+   Z_check_type_and_load_certr   r   r0   
get_binaryr   ZEllipticCurvePublicKeyZfrom_encoded_pointr   
ValueError)r   r2   datafilenamepasswordvalsfile_objZvalidate_pointZc_classr3   suffixZ	key_typesZ
cert_typesZ	curvenameZ	pointinfokeyr   r   r   r   m   sZ    



   
zECDSAKey.__init__c                 C   s
   | j  S r$   )r9   r+   )clsr   r   r    supported_key_format_identifiers   s    z)ECDSAKey.supported_key_format_identifiersc                 C   s   | j }t }|| jj || jj | }|jjd d }t	|j
dd}d|t|  | }t	|jdd}d|t|  | }t| | }|| | S )N      F)Zadd_sign_padding    )r4   r   
add_stringr:   r   r   public_numbersr(   r   r   r1   r=   yr
   asbytes)r   rF   mZnumbersZkey_size_bytesZx_bytesZy_bytesZ	point_strr   r   r   rO      s    
zECDSAKey.asbytesc                 C   s   |   S r$   )rO   r*   r   r   r   __str__   s    zECDSAKey.__str__c                 C   s   |   | j j| j jfS r$   )get_namer4   rM   r1   rN   r*   r   r   r   _fields   s    

zECDSAKey._fieldsc                 C   s   | j jS r$   )r:   r   r*   r   r   r   rR      s    zECDSAKey.get_namec                 C   s   | j jS r$   )r:   r   r*   r   r   r   get_bits   s    zECDSAKey.get_bitsc                 C   s
   | j d k	S r$   )r5   r*   r   r   r   can_sign   s    zECDSAKey.can_signc                 C   sT   t | j }| j||}t|\}}t }|| jj	 || 
|| |S r$   )r   ECDSAr:   r   r5   signr   r   rL   r   
_sigencode)r   r@   	algorithmZecdsasigrsrP   r   r   r   sign_ssh_data   s    zECDSAKey.sign_ssh_datac                 C   st   |  | jjkrdS | }| |\}}t||}z | j||t	| j
  W n tk
rj   Y dS X dS d S )NFT)r;   r:   r   r>   
_sigdecoder	   r4   verifyr   rV   r   r   )r   r@   r2   rZ   ZsigRZsigS	signaturer   r   r   verify_ssh_sig   s    
  zECDSAKey.verify_ssh_sigc                 C   s   | j || jtjj|d d S N)rB   )Z_write_private_key_filer5   r   PrivateFormatTraditionalOpenSSL)r   rA   rB   r   r   r   write_private_key_file   s    zECDSAKey.write_private_key_filec                 C   s   | j || jtjj|d d S rb   )Z_write_private_keyr5   r   rc   rd   )r   rD   rB   r   r   r   write_private_key   s    zECDSAKey.write_private_keyc                 C   sT   |dk	r2| j |}|dkr*td|| }tj|t d}t||	 fdS )a  
        Generate a new private ECDSA key.  This factory function can be used to
        generate a new host key or authentication key.

        :param progress_func: Not used for this type of key.
        :returns: A new private key (`.ECDSAKey`) object
        NzUnsupported key length: {:d})backend)rC   )
r9   r.   r?   r0   r   r   Zgenerate_private_keyr   r/   
public_key)rG   r(   Zprogress_funcbitsZprivate_keyr   r   r   generate   s    	zECDSAKey.generatec                 C   s   |  d||}| | d S NZEC)Z_read_private_key_file_decode_key)r   rA   rB   r@   r   r   r   r7     s    zECDSAKey._from_private_key_filec                 C   s   |  d||}| | d S rk   )Z_read_private_keyrl   )r   rD   rB   r@   r   r   r   r6     s    zECDSAKey._from_private_keyc                 C   s*  |\}}|| j krbztj|d t d}W n6 ttttfk
r^ } ztt	|W 5 d }~X Y nX n|| j
krzXt|}| }| }| }d| }	| j|	}
|
stdt||
 t }W n. tk
r } ztt	|W 5 d }~X Y nX n
| | || _| | _|jj}| j|| _d S )N)rB   rg   r   zInvalid key curve identifier)Z_PRIVATE_KEY_FORMAT_ORIGINALr   Zload_der_private_keyr   r?   AssertionError	TypeErrorr   r   strZ_PRIVATE_KEY_FORMAT_OPENSSHr   r;   r>   	get_mpintr9   r-   r   Zderive_private_keyr   	ExceptionZ_got_bad_key_format_idr5   rh   r4   r(   r8   r,   r:   )r   r@   ZpkformatrF   er2   Z
curve_nameZverkeyZsigkeynamer(   r   r   r   r   rl     sJ    
  
 
   

zECDSAKey._decode_keyc                 C   s"   t  }|| || | S r$   )r   Z	add_mpintrO   )r   r[   r\   r2   r   r   r   rX   C  s    

zECDSAKey._sigencodec                 C   s    t |}| }| }||fS r$   )r   rp   )r   rZ   r2   r[   r\   r   r   r   r^   I  s    zECDSAKey._sigdecode)NNNNNNT)N)N)N)r   r    r!   r"   r#   r   r   Z	SECP256R1Z	SECP384R1Z	SECP521R1r9   r   classmethodrH   rO   rQ   propertyrS   rR   rT   rU   r]   ra   re   rf   rj   r7   r6   rl   rX   r^   r   r   r   r   r/   _   sF   



       
=





'r/   N)r"   Zcryptography.exceptionsr   r   Zcryptography.hazmat.backendsr   Zcryptography.hazmat.primitivesr   r   Z)cryptography.hazmat.primitives.asymmetricr   Z/cryptography.hazmat.primitives.asymmetric.utilsr   r	   Zparamiko.commonr
   Zparamiko.messager   Zparamiko.pkeyr   Zparamiko.ssh_exceptionr   Zparamiko.utilr   objectr   r#   r/   r   r   r   r   <module>   s   