U
    P|j‡þ  ã                   @  s,  d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	m
Z
 ddlmZmZ ddlm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 ddlmZmZm Z m!Z!m"Z" ddl#m$Z$m%Z%m&Z& ddl'm(Z(m)Z) ddl*m+Z+ ddl,m-Z-m.Z. ddl/m0Z0 ddl1m2Z2 ddl3m4Z4m5Z5 ddl6m7Z7 zddl8m9Z9m:Z: W n& e;k
�rv   ddl8m<Z9m=Z: Y nX e >¡ e ?¡ e @¡ dœZAddddœZBe jCZCe jDZDG dd„ deEƒZFG dd„ deEƒZGG d d!„ d!eEƒZHG d"d#„ d#eEƒZIG d$d%„ d%eƒZJG d&d'„ d'eEƒZKd(d)„ ZLG d*d+„ d+ƒZMd/d-d.„ZNdS )0z0
Handling of RSA, DSA, ECDSA, and Ed25519 keys.
é    )ÚannotationsN)Ú	b64encodeÚdecodebytesÚencodebytes)Úmd5Úsha256)ÚAny)ÚNamedConstantÚNames)Úutils)ÚInvalidSignature)Údefault_backend)ÚhashesÚserialization)ÚdsaÚecÚed25519ÚpaddingÚrsa)ÚCipherÚ
algorithmsÚmodes)Úload_pem_private_keyÚload_ssh_public_key)ÚLiteral)ÚcommonÚsexpy)Úint_to_bytes)Ú	randbytes)Ú	iterbytesÚnativeString)Ú_mutuallyExclusiveArguments)Údecode_dss_signatureÚencode_dss_signature)Údecode_rfc6979_signatureÚencode_rfc6979_signature)ó   ecdsa-sha2-nistp256s   ecdsa-sha2-nistp384s   ecdsa-sha2-nistp521s   nistp256s   nistp384s   nistp521)s	   secp256r1s	   secp384r1s	   secp521r1c                   @  s   e Zd ZdZdS )ÚBadKeyErrorzj
    Raised when a key isn't what we expected from it.

    XXX: we really need to check for bad keys
    N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r-   r-   ú:/tmp/pip-unpacked-wheel-audpp6lv/twisted/conch/ssh/keys.pyr'   D   s   r'   c                   @  s   e Zd ZdZdS )ÚBadSignatureAlgorithmErrorzi
    Raised when a public key signature algorithm name isn't defined for this
    public key format.
    Nr(   r-   r-   r-   r.   r/   L   s   r/   c                   @  s   e Zd ZdZdS )ÚEncryptedKeyErrorzb
    Raised when an encrypted key is presented to fromString/fromFile without
    a password.
    Nr(   r-   r-   r-   r.   r0   S   s   r0   c                   @  s   e Zd ZdZdS )ÚBadFingerPrintFormatzS
    Raises when unsupported fingerprint formats are presented to fingerprint.
    Nr(   r-   r-   r-   r.   r1   Z   s   r1   c                   @  s   e Zd ZdZeƒ Zeƒ ZdS )ÚFingerprintFormatsaÈ  
    Constants representing the supported formats of key fingerprints.

    @cvar MD5_HEX: Named constant representing fingerprint format generated
        using md5[RFC1321] algorithm in hexadecimal encoding.
    @type MD5_HEX: L{constantly.NamedConstant}

    @cvar SHA256_BASE64: Named constant representing fingerprint format
        generated using sha256[RFC4634] algorithm in base64 encoding
    @type SHA256_BASE64: L{constantly.NamedConstant}
    N)r)   r*   r+   r,   r	   ÚMD5_HEXÚSHA256_BASE64r-   r-   r-   r.   r2   `   s   r2   c                   @  s   e Zd ZdZdS )ÚPassphraseNormalizationErrorzŒ
    Raised when a passphrase contains Unicode characters that cannot be
    normalized using the available Unicode character database.
    Nr(   r-   r-   r-   r.   r5   q   s   r5   c                 C  s<   t | tƒr4tdd„ | D ƒƒr"tƒ ‚t d| ¡ d¡S | S dS )aî  
    Normalize a passphrase, which may be Unicode.

    If the passphrase is Unicode, this follows the requirements of U{NIST
    800-63B, section
    5.1.1.2<https://pages.nist.gov/800-63-3/sp800-63b.html#memsecretver>}
    for Unicode characters in memorized secrets: it applies the
    Normalization Process for Stabilized Strings using NFKC normalization.
    The passphrase is then encoded using UTF-8.

    @type passphrase: L{bytes} or L{unicode} or L{None}
    @param passphrase: The passphrase to normalize.

    @return: The normalized passphrase, if any.
    @rtype: L{bytes} or L{None}
    @raises PassphraseNormalizationError: if the passphrase is Unicode and
    cannot be normalized using the available Unicode character database.
    c                 s  s   | ]}t  |¡d kV  qdS )ÚCnN)ÚunicodedataÚcategory)Ú.0Úcr-   r-   r.   Ú	<genexpr>Ž   s     z'_normalizePassphrase.<locals>.<genexpr>ÚNFKCzUTF-8N)Ú
isinstanceÚstrÚanyr5   r7   Ú	normalizeÚencode©Ú
passphraser-   r-   r.   Ú_normalizePassphrasex   s
    
rD   c                   @  sì  e Zd ZdZed`dd„ƒZedadd„ƒZedd„ ƒZed	d
„ ƒZedd„ ƒZ	edd„ ƒZ
edd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedbdd„ƒZedcdd„ƒZedddd „ƒZeded!d"„ƒZedfd#d$„ƒZd%d&„ Zd'd(d)œd*d+„Zd,d-œd.d/„Zd0d1„ Zd2d3„ Zejfd4d5„Zd6d-œd7d8„Zd9d:„ Zd;d<„ Z d=d>„ Z!d?d@„ Z"dAd-œdBdC„Z#dDdE„ Z$dFdG„ Z%e&dHdIgdHdJggƒdgdKdL„ƒZ'dhdMdN„Z(didOdP„Z)djdQdR„Z*dkdSdT„Z+dUdV„ Z,dWdX„ Z-dldYdZdYd[œd\d]„Z.d^d_„ Z/dS )mÚKeyau  
    An object representing a key.  A key can be either a public or
    private key.  A public key can verify a signature; a private key can
    create or verify a signature.  To generate a string that can be stored
    on disk, use the toString method.  If you have a private key, but want
    the string representation of the public key, use Key.public().toString().
    Nc              
   C  s4   t |dƒ� }|  | ¡ ||¡W  5 Q R £ S Q R X dS )aâ  
        Load a key from a file.

        @param filename: The path to load key data from.

        @type type: L{str} or L{None}
        @param type: A string describing the format the key data is in, or
        L{None} to attempt detection of the type.

        @type passphrase: L{bytes} or L{None}
        @param passphrase: The passphrase the key is encrypted with, or L{None}
        if there is no encryption.

        @rtype: L{Key}
        @return: The loaded key.
        ÚrbN)ÚopenÚ
fromStringÚread)ÚclsÚfilenameÚtyperC   Úfr-   r-   r.   ÚfromFile    s    zKey.fromFilec                 C  sž   t |tƒr| d¡}t|ƒ}|dkr.|  |¡}|dkrDtd|›�ƒ‚t| d| ¡ › �dƒ}|dkrptd|› �ƒ‚|jj	dkr�|rˆtdƒ‚||ƒS |||ƒS dS )a   
        Return a Key object corresponding to the string data.
        type is optionally the type of string, matching a _fromString_*
        method.  Otherwise, the _guessStringType() classmethod will be used
        to guess a type.  If the key is encrypted, passphrase is used as
        the decryption key.

        @type data: L{bytes}
        @param data: The key data.

        @type type: L{str} or L{None}
        @param type: A string describing the format the key data is in, or
        L{None} to attempt detection of the type.

        @type passphrase: L{bytes} or L{None}
        @param passphrase: The passphrase the key is encrypted with, or L{None}
        if there is no encryption.

        @rtype: L{Key}
        @return: The loaded key.
        úutf-8Nzcannot guess the type of Z_fromString_zno _fromString method for é   zkey not encrypted)
r=   r>   rA   rD   Ú_guessStringTyper'   ÚgetattrÚupperÚ__code__Úco_argcount)rJ   ÚdatarL   rC   Úmethodr-   r-   r.   rH   µ   s    


zKey.fromStringc                 C  s$  t  |¡\}}|dkr@t  |d¡\}}}| t ||¡ tƒ ¡ƒS |dkr„t  |d¡\}}}}	}| tj|	tj	|||d�d� tƒ ¡ƒS |t
kr®| tj t
| t  |d¡d ¡ƒS |dkrÚ| jt  |d¡d d	d
�}
d|
_|
S |dk�rt  |¡\}}|  |¡}
| d¡�rd|
_|
S td|› �ƒ‚dS )a„  
        Return a public key object corresponding to this public key blob.
        The format of a RSA public key blob is::
            string 'ssh-rsa'
            integer e
            integer n

        The format of a DSA public key blob is::
            string 'ssh-dss'
            integer p
            integer q
            integer g
            integer y

        The format of ECDSA-SHA2-* public key blob is::
            string 'ecdsa-sha2-[identifier]'
            integer x
            integer y

            identifier is the standard NIST curve name.

        The format of an Ed25519 public key blob is::
            string 'ssh-ed25519'
            string a

        @type blob: L{bytes}
        @param blob: The key data.

        @return: A new key.
        @rtype: L{twisted.conch.ssh.keys.Key}
        @raises BadKeyError: if the key type (the first string) is unknown.
        ó   ssh-rsarP   ó   ssh-dssé   ©ÚpÚqÚg©ÚyÚparameter_numbersé   ó"   sk-ecdsa-sha2-nistp256@openssh.comr&   )ÚencodedPointÚcurveT)ó   ssh-ed25519ó   sk-ssh-ed25519@openssh.coms   sk-ssh-úunknown blob type: N)r   ÚgetNSÚgetMPr   ÚRSAPublicNumbersÚ
public_keyr   r   ÚDSAPublicNumbersÚDSAParameterNumbersÚ_curveTabler   ÚEllipticCurvePublicKeyÚfrom_encoded_pointÚ_fromECEncodedPointÚ_skÚ_fromEd25519ComponentsÚ
startswithr'   )rJ   ÚblobÚkeyTypeÚrestÚeÚnr\   r]   r^   r`   Ú	keyObjectÚar-   r-   r.   Ú_fromString_BLOBÝ   sF    " ÿþÿ ÿÿþ

zKey._fromString_BLOBc                 C  s$  t  |¡\}}|dkrDt  |d¡\}}}}}}	}| j|||||	d�S |dkrxt  |d¡\}}	}
}}}| j||
||	|d�S |tkrÜt| }t  |d¡\}}	}|t|j d¡ kr¾t	d	||f ƒ‚t  |¡\}}| j
|	||d
�S |dk�rt  |d¡\}}}|dd… }| j||d�S t	d|› �ƒ‚dS )a6  
        Return a private key object corresponding to this private key blob.
        The blob formats are as follows:

        RSA keys::
            string 'ssh-rsa'
            integer n
            integer e
            integer d
            integer u
            integer p
            integer q

        DSA keys::
            string 'ssh-dss'
            integer p
            integer q
            integer g
            integer y
            integer x

        EC keys::
            string 'ecdsa-sha2-[identifier]'
            string identifier
            string q
            integer privateValue

            identifier is the standard NIST curve name.

        Ed25519 keys::
            string 'ssh-ed25519'
            string a
            string k || a


        @type blob: L{bytes}
        @param blob: The key data.

        @return: A new key.
        @rtype: L{twisted.conch.ssh.keys.Key}
        @raises BadKeyError: if
            * the key type (the first string) is unknown
            * the curve name of an ECDSA key does not match the key type
        rX   é   ©rz   ry   Údr\   r]   rY   é   ©r`   r^   r\   r]   ÚxrP   Úasciiz.ECDSA curve name %r does not match key type %r)rd   re   ÚprivateValuerf   Né    )Úkrh   )r   ri   rj   Ú_fromRSAComponentsÚ_fromDSAComponentsro   Ú
_secToNistÚnamerA   r'   rr   rt   )rJ   rv   rw   rx   rz   ry   r€   Úur\   r]   r^   r`   rƒ   re   Z	curveNamer…   r|   Zcombinedr‡   r-   r-   r.   Ú_fromString_PRIVATE_BLOB$  s6    .ÿÿ  ÿ
zKey._fromString_PRIVATE_BLOBc                 C  s4   |  d¡r| t|tƒ ƒƒS t| ¡ d ƒ}|  |¡S )a”  
        Return a public key object corresponding to this OpenSSH public key
        string.  The format of an OpenSSH public key string is::
            <key type> <base64-encoded public key blob>

        @type data: L{bytes}
        @param data: The key data.

        @return: A new key.
        @rtype: L{twisted.conch.ssh.keys.Key}
        @raises BadKeyError: if the blob type is unknown.
        s
   ecdsa-sha2rb   )ru   r   r   r   Úsplitr}   )rJ   rV   rv   r-   r-   r.   Ú_fromString_PUBLIC_OPENSSHo  s    
zKey._fromString_PUBLIC_OPENSSHc                 C  s  |  ¡  ¡ }td |dd… ¡ƒ}| d¡s4tdƒ‚|tdƒd… }t |d¡\}}}}t	 
d|dd	… ¡d
 }	|	dkr€tdƒ‚t |d	d… d¡\}
}}
|dk�r¢|s°tdƒ‚|dkrÜtj}d}t|dd… ƒd }|}ntd|›�ƒ‚|dk�r4t |¡\}}t	 
d|dd	… ¡d
 }tj|||| |dd�}ntd|›�ƒ‚t|ƒ| d
k�r\tdƒ‚t||d|… ƒt |||| … ¡tƒ d� ¡ }| |¡| ¡  }n|dk�rºtd|f ƒ‚|}t	 
d|dd	… ¡d
 }t	 
d|d	d… ¡d
 }||k�rtd||f ƒ‚|  |dd… ¡S )a*  
        Return a private key object corresponding to this OpenSSH private key
        string, in the "openssh-key-v1" format introduced in OpenSSH 6.5.

        The format of an openssh-key-v1 private key string is::
            -----BEGIN OPENSSH PRIVATE KEY-----
            <base64-encoded SSH protocol string>
            -----END OPENSSH PRIVATE KEY-----

        The SSH protocol string is as described in
        U{PROTOCOL.key<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.key>}.

        @type data: L{bytes}
        @param data: The key data.

        @type passphrase: L{bytes} or L{None}
        @param passphrase: The passphrase the key is encrypted with, or L{None}
        if it is not encrypted.

        @return: A new key.
        @rtype: L{twisted.conch.ssh.keys.Key}
        @raises BadKeyError: if
            * a passphrase is provided for an unencrypted key
            * the SSH protocol encoding is incorrect
        @raises EncryptedKeyError: if
            * a passphrase is not provided for an encrypted key
        ó    rb   éÿÿÿÿó   openssh-key-v1 z"unknown OpenSSH private key formatNé   ú!LrZ   r   zDonly OpenSSH private key files containing a single key are supportedrP   ó   noneú0Passphrase must be provided for an encrypted key)s
   aes128-ctrs
   aes192-ctró
   aes256-ctré   r~   é   zunknown encryption type ó   bcryptT)Zignore_few_roundszunknown KDF type zbad padding©Úbackendz*private key specifies KDF %r but no cipherz#check values do not match: %d != %d)ÚstripÚ
splitlinesr   Újoinru   r'   Úlenr   ri   ÚstructÚunpackr0   r   ÚAESÚintÚbcryptÚkdfr   r   ÚCTRr   Ú	decryptorÚupdateÚfinalizer�   )rJ   rV   rC   ÚlinesZkeyListÚcipherr¦   Ú
kdfOptionsrx   rz   Ú_ÚencPrivKeyListZalgorithmClassÚ	blockSizeÚkeySizeÚivSizeÚsaltÚroundsZdecKeyr¨   ÚprivKeyListZcheck1Zcheck2r-   r-   r.   Ú_fromPrivateOpenSSH_v1„  sh    
ÿ
ÿ
ú	ý

ÿ
zKey._fromPrivateOpenSSH_v1c                 C  s�   |  ¡  ¡ }|d dd… }|s$d}|dkr~zt||tƒ ƒ}W n6 tk
rZ   tdƒ‚Y n tk
rt   tdƒ‚Y nX | |ƒS td|› �ƒ‚dS )	aÉ  
        Return a private key object corresponding to this OpenSSH private key
        string, in the old PEM-based format.

        The format of a PEM-based OpenSSH private key string is::
            -----BEGIN <key type> PRIVATE KEY-----
            [Proc-Type: 4,ENCRYPTED
            DEK-Info: DES-EDE3-CBC,<initialization value>]
            <base64-encoded ASN.1 structure>
            ------END <key type> PRIVATE KEY------

        The ASN.1 structure of a RSA key is::
            (0, n, e, d, p, q)

        The ASN.1 structure of a DSA key is::
            (0, p, q, g, y, x)

        The ASN.1 structure of a ECDSA key is::
            (ECParameters, OID, NULL)

        @type data: L{bytes}
        @param data: The key data.

        @type passphrase: L{bytes} or L{None}
        @param passphrase: The passphrase the key is encrypted with, or L{None}
        if it is not encrypted.

        @return: A new key.
        @rtype: L{twisted.conch.ssh.keys.Key}
        @raises BadKeyError: if
            * a passphrase is provided for an unencrypted key
            * the ASN.1 encoding is incorrect
        @raises EncryptedKeyError: if
            * a passphrase is not provided for an encrypted key
        r   é   éïÿÿÿN)s   ECs   RSAs   DSAr–   z&Failed to decode key (Bad Passphrase?)úunknown key type )r�   rž   r   r   Ú	TypeErrorr0   Ú
ValueErrorr'   )rJ   rV   rC   r«   ÚkindÚkeyr-   r-   r.   Ú_fromPrivateOpenSSH_PEMÝ  s    %ÿzKey._fromPrivateOpenSSH_PEMc                 C  s8   |  ¡  ¡ d dd… dkr(|  ||¡S |  ||¡S dS )aø  
        Return a private key object corresponding to this OpenSSH private key
        string.  If the key is encrypted, passphrase MUST be provided.
        Providing a passphrase for an unencrypted key is an error.

        @type data: L{bytes}
        @param data: The key data.

        @type passphrase: L{bytes} or L{None}
        @param passphrase: The passphrase the key is encrypted with, or L{None}
        if it is not encrypted.

        @return: A new key.
        @rtype: L{twisted.conch.ssh.keys.Key}
        @raises BadKeyError: if
            * a passphrase is provided for an unencrypted key
            * the encoding is incorrect
        @raises EncryptedKeyError: if
            * a passphrase is not provided for an encrypted key
        r   r·   r¸   s   OPENSSHN)r�   rž   r¶   r¾   )rJ   rV   rC   r-   r-   r.   Ú_fromString_PRIVATE_OPENSSH  s    zKey._fromString_PRIVATE_OPENSSHc                 C  sÎ   t  t|dd… ƒ¡}|d dks&t‚i }|d dd… D ] \}}t t |¡¡d ||< q:|d d dkrŽ| j|d |d |d	 |d
 d�S |d d dkr´| j|d |d d�S t	d|d d › �ƒ‚dS )a  
        Return a public key corresponding to this LSH public key string.
        The LSH public key string format is::
            <s-expression: ('public-key', (<key type>, (<name, <value>)+))>

        The names for a RSA (key type 'rsa-pkcs1-sha1') key are: n, e.
        The names for a DSA (key type 'dsa') key are: y, g, p, q.

        @type data: L{bytes}
        @param data: The key data.

        @return: A new key.
        @rtype: L{twisted.conch.ssh.keys.Key}
        @raises BadKeyError: if the key type is unknown
        rb   r‘   r   ó
   public-keyNó   dsaó   yó   gó   pó   q©r`   r^   r\   r]   ó   rsa-pkcs1-sha1ó   nó   e©rz   ry   úunknown lsh key type )
r   Úparser   ÚAssertionErrorr   rj   ÚNSr‰   rˆ   r'   ©rJ   rV   ZsexpZkdr‹   r-   r-   r.   Ú_fromString_PUBLIC_LSH3  s       ÿzKey._fromString_PUBLIC_LSHc                 C  s6  t  |¡}|d dkst‚i }|d dd… D ] \}}t t |¡¡d ||< q.|d d dkr t|ƒdksxtt|ƒƒ‚| j|d |d |d	 |d
 |d d�S |d d dk�rt|ƒdksÊtt|ƒƒ‚|d	 |d
 krô|d
 |d	  |d	< |d
< | j|d |d |d |d	 |d
 d�S t	d|d d › �ƒ‚dS )a+  
        Return a private key corresponding to this LSH private key string.
        The LSH private key string format is::
            <s-expression: ('private-key', (<key type>, (<name>, <value>)+))>

        The names for a RSA (key type 'rsa-pkcs1-sha1') key are: n, e, d, p, q.
        The names for a DSA (key type 'dsa') key are: y, g, p, q, x.

        @type data: L{bytes}
        @param data: The key data.

        @return: A new key.
        @rtype: L{twisted.conch.ssh.keys.Key}
        @raises BadKeyError: if the key type is unknown
        r   ó   private-keyrb   NrÁ   r�   rÂ   rÃ   rÄ   rÅ   ó   xr‚   ó	   rsa-pkcs1r™   rÈ   rÉ   ó   dr   rË   )
r   rÌ   rÍ   r   rj   rÎ   r    r‰   rˆ   r'   rÏ   r-   r-   r.   Ú_fromString_PRIVATE_LSHS  s4    
    ÿ    ÿzKey._fromString_PRIVATE_LSHc                 C  sô   t  |¡\}}|dkrpt  |¡\}}t  |¡\}}t  |¡\}}t  |¡\}}t  |¡\}}| j|||||d�S |dkrât  |¡\}}t  |¡\}	}t  |¡\}
}t  |¡\}}t  |¡\}}t  |¡\}}| j|
||	|||d�S td|› �ƒ‚dS )aß  
        Return a private key object corresponsing to the Secure Shell Key
        Agent v3 format.

        The SSH Key Agent v3 format for a RSA key is::
            string 'ssh-rsa'
            integer e
            integer d
            integer n
            integer u
            integer p
            integer q

        The SSH Key Agent v3 format for a DSA key is::
            string 'ssh-dss'
            integer p
            integer q
            integer g
            integer y
            integer x

        @type data: L{bytes}
        @param data: The key data.

        @return: A new key.
        @rtype: L{twisted.conch.ssh.keys.Key}
        @raises BadKeyError: if the key type (the first string) is unknown
        rY   r‚   rX   ©rz   ry   r€   r\   r]   rŒ   r¹   N)r   ri   rj   r‰   rˆ   r'   )rJ   rV   rw   r\   r]   r^   r`   rƒ   ry   r€   rz   rŒ   r-   r-   r.   Ú_fromString_AGENTV3y  s"    zKey._fromString_AGENTV3c                 C  sê   |  d¡s|  d¡rdS |  d¡s,|  d¡r4tdƒ‚|  d¡sH|  d¡rLdS |  d	¡rZd
S |  d¡rhdS |  d¡rvdS |  d¡s¨|  d¡s¨|  d¡s¨|  d¡s¨|  d¡ræt |¡\}}d}|rÖ|d7 }t |¡\}}qº|dkrâdS dS dS )z¢
        Guess the type of key in data.  The types map to _fromString_*
        methods.

        @type data: L{bytes}
        @param data: The key data.
        s   ssh-ó   ecdsa-sha2-Zpublic_opensshs   sk-ecdsa-sha2-nistp256-cert-v01s   sk-ssh-ed25519-cert-v01z(certificate based keys are not supporteds   sk-ecdsa-sha2-nistp256s   sk-ssh-ed25519s
   -----BEGINZprivate_opensshó   {Z
public_lshó   (Zprivate_lshs      ssh-s
      ecdsa-s      ssh-ed25519s&      "sk-ecdsa-sha2-nistp256@openssh.coms      sk-ssh-ed25519@openssh.comr   rb   rZ   Zagentv3rv   N)ru   r'   r   ri   rj   )rJ   rV   Zignoredrx   Úcountr-   r-   r.   rQ   ª  sD    	ÿÿ


ÿþýüûzKey._guessStringTypec           
   
   C  sh   t j||d�}|dkr$| tƒ ¡}n<t j|||t  ||¡t  ||¡t  ||¡|d�}	|	 tƒ ¡}| |ƒS )aÔ  
        Build a key from RSA numerical components.

        @type n: L{int}
        @param n: The 'n' RSA variable.

        @type e: L{int}
        @param e: The 'e' RSA variable.

        @type d: L{int} or L{None}
        @param d: The 'd' RSA variable (optional for a public key).

        @type p: L{int} or L{None}
        @param p: The 'p' RSA variable (optional for a public key).

        @type q: L{int} or L{None}
        @param q: The 'q' RSA variable (optional for a public key).

        @type u: L{int} or L{None}
        @param u: The 'u' RSA variable. Ignored, as its value is determined by
        p and q.

        @rtype: L{Key}
        @return: An RSA key constructed from the values as given.
        )ry   rz   N)r\   r]   r€   Zdmp1Zdmq1ÚiqmpÚpublic_numbers)	r   rk   rl   r   ZRSAPrivateNumbersZrsa_crt_dmp1Zrsa_crt_dmq1Úrsa_crt_iqmpÚprivate_key)
rJ   rz   ry   r€   r\   r]   rŒ   ÚpublicNumbersr{   ÚprivateNumbersr-   r-   r.   rˆ   ß  s    


ù	zKey._fromRSAComponentsc           	      C  sR   t j|t j|||d�d�}|dkr0| tƒ ¡}nt j||d�}| tƒ ¡}| |ƒS )a   
        Build a key from DSA numerical components.

        @type y: L{int}
        @param y: The 'y' DSA variable.

        @type p: L{int}
        @param p: The 'p' DSA variable.

        @type q: L{int}
        @param q: The 'q' DSA variable.

        @type g: L{int}
        @param g: The 'g' DSA variable.

        @type x: L{int} or L{None}
        @param x: The 'x' DSA variable (optional for a public key)

        @rtype: L{Key}
        @return: A DSA key constructed from the values as given.
        r[   r_   N)rƒ   rÝ   )r   rm   rn   rl   r   ZDSAPrivateNumbersrß   )	rJ   r`   r\   r]   r^   rƒ   rà   r{   rá   r-   r-   r.   r‰     s     ÿzKey._fromDSAComponentsc                 C  sL   t j||t| d�}|dkr*| tƒ ¡}nt j||d�}| tƒ ¡}| |ƒS )a«  
        Build a key from EC components.

        @param x: The affine x component of the public point used for verifying.
        @type x: L{int}

        @param y: The affine y component of the public point used for verifying.
        @type y: L{int}

        @param curve: NIST name of elliptic curve.
        @type curve: L{bytes}

        @param privateValue: The private value.
        @type privateValue: L{int}
        ©rƒ   r`   re   N)Úprivate_valuerÝ   )r   ZEllipticCurvePublicNumbersro   rl   r   ZEllipticCurvePrivateNumbersrß   )rJ   rƒ   r`   re   r…   rà   r{   rá   r-   r-   r.   Ú_fromECComponents/  s      ÿ ÿzKey._fromECComponentsc                 C  s8   |dkrt j t| |¡}nt  |t| tƒ ¡}| |ƒS )aa  
        Build a key from an EC encoded point.

        @param encodedPoint: The public point encoded as in SEC 1 v2.0
        section 2.3.3.
        @type encodedPoint: L{bytes}

        @param curve: NIST name of elliptic curve.
        @type curve: L{bytes}

        @param privateValue: The private value.
        @type privateValue: L{int}
        N)r   rp   rq   ro   Zderive_private_keyr   )rJ   rd   re   r…   r{   r-   r-   r.   rr   O  s     ÿ  ÿzKey._fromECEncodedPointc                 C  s>   t dkstdkrtdƒ‚|dkr,t  |¡}n
t |¡}| |ƒS )a  Build a key from Ed25519 components.

        @param a: The Ed25519 public key, as defined in RFC 8032 section
            5.1.5.
        @type a: L{bytes}

        @param k: The Ed25519 private key, as defined in RFC 8032 section
            5.1.5.
        @type k: L{bytes}
        Nz)Ed25519 keys not supported on this system)ÚEd25519PublicKeyÚEd25519PrivateKeyr'   Zfrom_public_bytesZfrom_private_bytes)rJ   r|   r‡   r{   r-   r-   r.   rt   k  s    
zKey._fromEd25519Componentsc                 C  s   || _ d| _dS )zä
        Initialize with a private or public
        C{cryptography.hazmat.primitives.asymmetric} key.

        @param keyObject: Low level key.
        @type keyObject: C{cryptography.hazmat.primitives.asymmetric} key.
        FN)Ú
_keyObjectrs   )Úselfr{   r-   r-   r.   Ú__init__‚  s    zKey.__init__ÚobjectÚbool)ÚotherÚreturnc                 C  s2   t |tƒr*|  ¡ | ¡ ko(|  ¡ | ¡ kS tS dS )zN
        Return True if other represents an object with the same key.
        N)r=   rE   rL   rV   ÚNotImplemented)rè   rì   r-   r-   r.   Ú__eq__�  s    
 z
Key.__eq__r>   )rí   c                 C  s¤  |   ¡ dkrž|  ¡ }|d  d¡}|  ¡ r@d|dd… › d�}nd|dd… › d�}t| ¡ ƒD ]4\}}|dkr€|d	|› �7 }q`|d
|› d|› �7 }q`|d S dt|   ¡ ƒ|  ¡ r¶dp¸d|  ¡ f g}t|  ¡  ¡ ƒD ]®\}}| d|› d�¡ |   ¡ dk�r|nt	 
|¡dd… }|rÖ|dd… }|dd… }d}	t|ƒD ]}
|	t|
ƒd›d� }	�q<t|ƒdk �rr|	dd… }	| d|	 ¡ �qqÖ|d d |d< d
 |¡S dS )z@
        Return a pretty representation of this object.
        ÚECre   rO   z<Elliptic Curve Public Key (éýÿÿÿNz bits)z<Elliptic Curve Private Key (z	
curve:
	Ú
z:
	z>
z<%s %s (%s bits)z
Public KeyzPrivate Keyzattr ú:ÚEd25519rZ   é   Ú Z02xr‘   ú	ú>)rL   rV   ÚdecodeÚisPublicÚsortedÚitemsr    ÚsizeÚappendr   ÚMPr   Úordr    rŸ   )rè   rV   r‹   Úoutr‡   Úvr«   ZbyÚmÚor:   r-   r-   r.   Ú__repr__–  s@    
ýÿÿ$zKey.__repr__c                 C  s   t | jtjtjtjtj	fƒS )zl
        Check if this instance is a public key.

        @return: C{True} if this is a public key.
        )
r=   rç   r   ÚRSAPublicKeyr   ÚDSAPublicKeyr   rp   r   rå   ©rè   r-   r-   r.   rú   Â  s    üþzKey.isPublicc                 C  s   |   ¡ r| S t| j ¡ ƒS dS )zä
        Returns a version of this key containing only the public key data.
        If this is a public key, this may or may not be the same object
        as self.

        @rtype: L{Key}
        @return: A public key.
        N)rú   rE   rç   rl   r  r-   r-   r.   ÚpublicÒ  s    	z
Key.publicc                 C  sf   |t jkr"ttt|  ¡ ƒ ¡ ƒƒS |t jkrTtd dd„ t	t
|  ¡ ƒ ¡ ƒD ƒ¡ƒS td|› �ƒ‚dS )aO  
        The fingerprint of a public key consists of the output of the
        message-digest algorithm in the specified format.
        Supported formats include L{FingerprintFormats.MD5_HEX} and
        L{FingerprintFormats.SHA256_BASE64}

        The input to the algorithm is the public key data as specified by [RFC4253].

        The output of sha256[RFC4634] algorithm is presented to the
        user in the form of base64 encoded sha256 hashes.
        Example: C{US5jTUa0kgX5ZxdqaGF0yGRu8EgKXHNmoT8jHKo1StM=}

        The output of the MD5[RFC1321](default) algorithm is presented to the user as
        a sequence of 16 octets printed as hexadecimal with lowercase letters
        and separated by colons.
        Example: C{c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87}

        @param format: Format for fingerprint generation. Consists
            hash function and representation format.
            Default is L{FingerprintFormats.MD5_HEX}

        @since: 8.2

        @return: the user presentation of this L{Key}'s fingerprint, as a
        string.

        @rtype: L{str}
        ó   :c                 S  s   g | ]}t  |¡‘qS r-   )ÚbinasciiÚhexlify)r9   rƒ   r-   r-   r.   Ú
<listcomp>  s     z#Key.fingerprint.<locals>.<listcomp>z Unsupported fingerprint format: N)r2   r4   r    r   r   rv   Údigestr3   rŸ   r   r   r1   )rè   Úformatr-   r-   r.   Úfingerprintà  s    

ÿÿzKey.fingerprintz(Literal[('RSA', 'DSA', 'EC', 'Ed25519')]c                 C  st   t | jtjtjfƒrdS t | jtjtjfƒr0dS t | jtj	tj
fƒrHdS t | jtjtjfƒr`dS td| j›�ƒ‚dS )zÓ
        Return the type of the object we wrap.  Currently this can only be
        'RSA', 'DSA', 'EC', or 'Ed25519'.

        @rtype: L{str}
        @raises RuntimeError: If the object type is unknown.
        ÚRSAÚDSArð   rô   zunknown type of object: N)r=   rç   r   r  ÚRSAPrivateKeyr   r  ÚDSAPrivateKeyr   rp   ÚEllipticCurvePrivateKeyr   rå   ræ   ÚRuntimeErrorr  r-   r-   r.   rL     s     
ÿ 
ÿzKey.typec                 C  sR   | j r|  ¡ dkrdS dS |  ¡ dkr>dt| jjj d¡  S dddd	œ|  ¡  S )
aÇ  
        Get the type of the object we wrap as defined in the SSH protocol,
        defined in RFC 4253, Section 6.6 and RFC 8332, section 4 (this is a
        public key format name, not a public key algorithm name). Currently
        this can only be b'ssh-rsa', b'ssh-dss', b'ecdsa-sha2-[identifier]'
        or b'ssh-ed25519'.

        identifier is the standard NIST curve name

        @return: The key type format.
        @rtype: L{bytes}
        rð   rc   rg   rØ   r„   rX   rY   rf   )r  r  rô   )rs   rL   rŠ   rç   re   r‹   rA   r  r-   r-   r.   ÚsshType  s    ÿýüzKey.sshTypec                 C  s$   |   ¡ dkrdddgS |  ¡ gS dS )zÀ
        Get the public key signature algorithms supported by this key.

        @return: A list of supported public key signature algorithm names.
        @rtype: L{list} of L{bytes}
        r  ó   rsa-sha2-512ó   rsa-sha2-256rX   N)rL   r  r  r-   r-   r.   ÚsupportedSignatureAlgorithms@  s    
z Key.supportedSignatureAlgorithmsc                 C  sŽ   |   ¡ dkrN||  ¡ krJ|  ¡ }|dkr0t ¡ S |dkr@t ¡ S t ¡ S ndS |   ¡ dkrbt ¡ S t ¡ t ¡ t ¡ t ¡ dœ |   ¡ |f¡S )zµ
        Return a hash algorithm for this key type given an SSH signature
        algorithm name, or L{None} if no such hash algorithm is defined for
        this key type.
        rð   é   i€  Nrô   ))r  rX   )r  r  )r  r  )r  rY   )	rL   r  rý   r   ÚSHA256ÚSHA384ÚSHA512ÚSHA1Úget)rè   ÚsignatureTyper±   r-   r-   r.   Ú_getHashAlgorithmL  s$    
ü
ûzKey._getHashAlgorithmc                 C  s<   | j dkrdS |  ¡ dkr$| j jjS |  ¡ dkr4dS | j jS )zv
        Return the size of the object we wrap.

        @return: The size of the key.
        @rtype: L{int}
        Nr   rð   rô   r  )rç   rL   re   Úkey_sizer  r-   r-   r.   rý   i  s    

zKey.sizezdict[str, Any]c              	   C  sÈ  t | jtjƒr&| j ¡ }|j|jdœS t | jtjƒrj| j ¡ }|jj|jj|j	|j
|jt |j|j
¡dœS t | jtjƒrž| j ¡ }|j|jj|jj
|jjdœS t | jtjƒrÞ| j ¡ }|j|jj|jjj|jjj
|jjjdœS t | jtjƒ�r| j ¡ }|j|j|  ¡ dœS t | jtjƒ�rB| j ¡ }|jj|jj|j|  ¡ dœS t | jtjƒ�rld| j tjjtjj¡iS t | jtj ƒ�r´| j !¡  tjjtjj¡| j "tjjtj#jt $¡ ¡dœS t%d	| j› �ƒ‚d
S )z_
        Return the values of the public key as a dictionary.

        @rtype: L{dict}
        rÊ   rÖ   rÆ   )rƒ   r`   r^   r\   r]   râ   )rƒ   r`   r…   re   r|   )r|   r‡   zUnexpected key type: N)&r=   rç   r   r  rÝ   rz   ry   r  Zprivate_numbersr€   r\   r]   rÞ   r   r  r`   ra   r^   r  rƒ   r   rp   r  r  rã   r   rå   Úpublic_bytesr   ÚEncodingZRawÚPublicFormatræ   rl   Úprivate_bytesÚPrivateFormatÚNoEncryptionr  )rè   Zrsa_pub_numbersZrsa_priv_numbersZdsa_pub_numbersZdsa_priv_numbersZec_pub_numbersZec_priv_numbersr-   r-   r.   rV   x  sz    
þ
ù	
ü
û
ý
ü  ÿÿ
 ÿýüzKey.datac                 C  s$  |   ¡ }|  ¡ }|dkr>t d¡t |d ¡ t |d ¡ S |dkrˆt d¡t |d ¡ t |d ¡ t |d	 ¡ t |d
 ¡ S |dkrð| jjjd d }t |d ¡t |d dd… ¡ t dt 	|d |¡ t 	|d
 |¡ ¡ S |dk�rt d¡t |d ¡ S t
d|› �ƒ‚dS )a•  
        Return the public key blob for this key. The blob is the
        over-the-wire format for public keys.

        SECSH-TRANS RFC 4253 Section 6.6.

        RSA keys::
            string 'ssh-rsa'
            integer e
            integer n

        DSA keys::
            string 'ssh-dss'
            integer p
            integer q
            integer g
            integer y

        EC keys::
            string 'ecdsa-sha2-[identifier]'
            integer x
            integer y

            identifier is the standard NIST curve name

        Ed25519 keys::
            string 'ssh-ed25519'
            string a

        @rtype: L{bytes}
        r  rX   ry   rz   r  rY   r\   r]   r^   r`   rð   é   r™   re   éøÿÿÿNó   rƒ   rô   rf   r|   úunknown key type: )rL   rV   r   rÎ   rÿ   rç   re   r#  r   r   r'   )rè   rL   rV   Z
byteLengthr-   r-   r.   rv   Ä  s@     &ÿþýüÿÿÿþÿþÿ	
zKey.blobc                 C  sˆ  |   ¡ }|  ¡ }|dkr†t |d |d ¡}t d¡t |d ¡ t |d ¡ t |d ¡ t |¡ t |d ¡ t |d ¡ S |dkrÞt d	¡t |d ¡ t |d ¡ t |d
 ¡ t |d ¡ t |d ¡ S |dk�r>| j ¡  	t
jjt
jj¡}t |d ¡t |d dd… ¡ t |¡ t |d ¡ S |dk�rvt d¡t |d ¡ t |d |d  ¡ S td|› �ƒ‚dS )a1  
        Return the private key blob for this key. The blob is the
        over-the-wire format for private keys:

        Specification in OpenSSH PROTOCOL.agent

        RSA keys::

            string 'ssh-rsa'
            integer n
            integer e
            integer d
            integer u
            integer p
            integer q

        DSA keys::

            string 'ssh-dss'
            integer p
            integer q
            integer g
            integer y
            integer x

        EC keys::

            string 'ecdsa-sha2-[identifier]'
            integer x
            integer y
            integer privateValue

            identifier is the NIST standard curve name.

        Ed25519 keys::

            string 'ssh-ed25519'
            string a
            string k || a
        r  r\   r]   rX   rz   ry   r€   r  rY   r^   r`   rƒ   rð   re   r+  Nr…   rô   rf   r|   r‡   r-  )rL   rV   r   rÞ   r   rÎ   rÿ   rç   rl   r$  r   r%  ZX962r&  ZUncompressedPointr'   )rè   rL   rV   rÜ   ZencPubr-   r-   r.   ÚprivateBlob   sh    )ÿþýüûúÿ	ÿþýüûÿ

þÿþýÿ
ÿþÿzKey.privateBlobÚextraÚcommentrC   c                 C  s€   |dk	r*t jdtdd� |  ¡ r&|}n|}t|tƒr>| d¡}t|ƒ}t| d| 	¡ › �dƒ}|dkrrt
d|› �ƒ‚||||d�S )	a  
        Create a string representation of this key.  If the key is a private
        key and you want the representation of its public key, use
        C{key.public().toString()}.  type maps to a _toString_* method.

        @param type: The type of string to emit.  Currently supported values
            are C{'OPENSSH'}, C{'LSH'}, and C{'AGENTV3'}.
        @type type: L{str}

        @param extra: Any extra data supported by the selected format which
            is not part of the key itself.  For public OpenSSH keys, this is
            a comment.  For private OpenSSH keys, this is a passphrase to
            encrypt with.  (Deprecated since Twisted 20.3.0; use C{comment}
            or C{passphrase} as appropriate instead.)
        @type extra: L{bytes} or L{unicode} or L{None}

        @param subtype: A subtype of the requested C{type} to emit.  Only
            supported for private OpenSSH keys, for which the currently
            supported subtypes are C{'PEM'} and C{'v1'}.  If not given, an
            appropriate default is used.
        @type subtype: L{str} or L{None}

        @param comment: A comment to include with the key.  Only supported
            for OpenSSH keys.

            Present since Twisted 20.3.0.

        @type comment: L{bytes} or L{unicode} or L{None}

        @param passphrase: A passphrase to encrypt the key with.  Only
            supported for private OpenSSH keys.

            Present since Twisted 20.3.0.

        @type passphrase: L{bytes} or L{unicode} or L{None}

        @rtype: L{bytes}
        Nz„The 'extra' argument to twisted.conch.ssh.keys.Key.toString was deprecated in Twisted 20.3.0; use 'comment' or 'passphrase' instead.r“   )Ú
stacklevelrO   Z
_toString_r-  )Úsubtyper0  rC   )ÚwarningsÚwarnÚDeprecationWarningrú   r=   r>   rA   rD   rR   rS   r'   )rè   rL   r/  r2  r0  rC   rW   r-   r-   r.   ÚtoStringS  s     -û

zKey.toStringc                 C  sn   |   ¡ dkr6|sd}| j tjjtjj¡d |  ¡ S t|  	¡ ƒ 
dd¡}|sRd}|  ¡ d | d |  ¡ S )a  
        Return a public OpenSSH key string.

        See _fromString_PUBLIC_OPENSSH for the string format.

        @type comment: L{bytes} or L{None}
        @param comment: A comment to include with the key, or L{None} to
        omit the comment.
        rð   r�   ó    ó   
)rL   rç   r$  r   r%  ZOpenSSHr&  r�   r   rv   Úreplacer  )rè   r0  Úb64Datar-   r-   r.   Ú_toPublicOpenSSH•  s     
 ÿýüÿzKey._toPublicOpenSSHc                   s   |rJt j}d}d}|jd }d}|}t |¡}	d}
t |	¡t d|
¡ }nd}d}d}d}t d	¡}|| |  	¡  t |p|d¡ }d
}t
|ƒ| r®|d7 }|t|d@ fƒ7 }q†|�rt ||	|| d¡}t||d|… ƒt |||| … ¡tƒ d� ¡ }| |¡| ¡  }n|}dt |¡ t |¡ t |¡ t dd¡ t |  ¡ ¡ t |¡ }t|ƒ dd¡‰ dg‡ fdd„td
t
ˆ ƒdƒD ƒ dg }d |¡d S )aP  
        Return a private OpenSSH key string, in the "openssh-key-v1" format
        introduced in OpenSSH 6.5.

        See _fromPrivateOpenSSH_v1 for the string format.

        @type passphrase: L{bytes} or L{None}
        @param passphrase: The passphrase to encrypt the key with, or L{None}
        if it is not encrypted.
        r—   rš   r™   r†   éd   r”   r•   r�   rZ   r   rb   éÿ   Nr›   r’   r8  s#   -----BEGIN OPENSSH PRIVATE KEY-----c                   s   g | ]}ˆ ||d  … ‘qS )é@   r-   )r9   Úi©r:  r-   r.   r  è  s     z,Key._toPrivateOpenSSH_v1.<locals>.<listcomp>r>  s!   -----END OPENSSH PRIVATE KEY-----)r   r£   Ú
block_sizer   ZsecureRandomr   rÎ   r¡   Úpackr.  r    Úbytesr¥   r¦   r   r   r§   r   Ú	encryptorr©   rª   rv   r   r9  ÚrangerŸ   )rè   r0  rC   r¬   Z
cipherNameZkdfNamer°   r±   r²   r³   r´   r­   Úcheckrµ   ZpadByteZencKeyrD  r¯   rv   r«   r-   r@  r.   Ú_toPrivateOpenSSH_v1¯  sf    


ý
ÿþý
üûúÿ	ÿþÿzKey._toPrivateOpenSSH_v1c                 C  sX   |st  ¡ }n
t  |¡}|  ¡ dkr<| j t jjt jj	|¡S |  ¡ dksLt
‚tdƒ‚dS )a,  
        Return a private OpenSSH key string, in the old PEM-based format.

        See _fromPrivateOpenSSH_PEM for the string format.

        @type passphrase: L{bytes} or L{None}
        @param passphrase: The passphrase to encrypt the key with, or L{None}
        if it is not encrypted.
        rô   zBcannot serialize Ed25519 key to OpenSSH PEM format; use v1 insteadN)r   r)  ZBestAvailableEncryptionrL   rç   r'  r%  ÚPEMr(  ÚTraditionalOpenSSLrÍ   r»   )rè   rC   rD  r-   r-   r.   Ú_toPrivateOpenSSH_PEMí  s    


ýÿzKey._toPrivateOpenSSH_PEMc                 C  sl   |   ¡ r| j|d�S |dks0|dkr>|  ¡ dkr>| j||d�S |dksN|dkrZ| j|d�S td|› �ƒ‚dS )	ar  
        Return a public or private OpenSSH string.  See
        L{_fromString_PUBLIC_OPENSSH} and L{_fromPrivateOpenSSH_PEM} for the
        string formats.

        @param subtype: A subtype to emit.  Only supported for private keys,
            for which the currently supported subtypes are C{'PEM'} and C{'v1'}.
            If not given, an appropriate default is used.
        @type subtype: L{str} or L{None}

        @param comment: Comment for a public key.
        @type comment: L{bytes}

        @param passphrase: Passphrase for a private key.
        @type passphrase: L{bytes}

        @rtype: L{bytes}
        )r0  Zv1Nrô   )r0  rC   rH  rB   zunknown subtype )rú   r;  rL   rG  rJ  r»   )rè   r2  r0  rC   r-   r-   r.   Ú_toString_OPENSSH	  s    zKey._toString_OPENSSHc                 K  s®  |   ¡ }|  ¡ }|  ¡ �r|dkrft dddt |d ¡dd… gdt |d	 ¡dd… gggg¡}nŠ|d
krât dddt |d ¡dd… gdt |d ¡dd… gdt |d ¡dd… gdt |d ¡dd… gggg¡}ntd|› �ƒ‚dt|ƒ 	dd¡ d S |dk�r|d |d  }}t
 ||¡}t dddt |d ¡dd… gdt |d	 ¡dd… gdt |d ¡dd… gdt |¡dd… gdt |¡dd… gdt |d |d  ¡dd… gdt |d |d  ¡dd… gd t |¡dd… gg	gg¡S |d
k�ršt dddt |d ¡dd… gdt |d ¡dd… gdt |d ¡dd… gdt |d ¡dd… gd!t |d" ¡dd… gggg¡S td|› d#�ƒ‚dS )$z¤
        Return a public or private LSH key.  See _fromString_PUBLIC_LSH and
        _fromString_PRIVATE_LSH for the key formats.

        @rtype: L{bytes}
        r  rÀ   rÇ   rÈ   rz   rZ   NrÉ   ry   r  rÁ   rÄ   r\   rÅ   r]   rÃ   r^   rÂ   r`   r¹   rÙ   r8  r�   ó   }rÑ   rÓ   rÔ   r€   ó   arb   ó   bó   crÒ   rƒ   ú')rV   rL   rú   r   rB  r   rÿ   r'   r   r9  r   rÞ   )rè   ÚkwargsrV   rL   ZkeyDatar\   r]   rÜ   r-   r-   r.   Ú_toString_LSH&  sv    
ýþÿÿûþÿÿ
  ÷þÿÿ
úþÿÿzKey._toString_LSHc                 K  s˜   |   ¡ }|  ¡ s”|  ¡ dkrF|d |d |d |d |d |d f}n.|  ¡ dkrt|d |d |d	 |d
 |d f}t |  ¡ ¡d ttj|ƒ¡ S dS )zŒ
        Return a private Secure Shell Agent v3 key.  See
        _fromString_AGENTV3 for the key format.

        @rtype: L{bytes}
        r  ry   r€   rz   rŒ   r\   r]   r  r^   r`   rƒ   r�   N)	rV   rú   rL   r   rÎ   r  rŸ   Úmaprÿ   )rè   rQ  rV   Úvaluesr-   r-   r.   Ú_toString_AGENTV3x  s    ú"zKey._toString_AGENTV3rC  zbytes | None)rV   r!  rí   c                 C  sX  |   ¡ }|dkr|  ¡ }|  |¡}|dkr@td|›d|› d�ƒ‚|dkrh| j |t ¡ |¡}t 	|¡}nâ|dkr¦| j ||¡}t
|ƒ\}}t 	t|dƒt|dƒ ¡}n¤|dk�r.| j |t |¡¡}	t
|	ƒ\}}t|ƒ}
t|ƒ}|
d	 }|d
@ rød|
 }
|d	 }|d
@ �rd| }t 	t 	|
¡t 	|¡ ¡}n|dk�rJt 	| j |¡¡}t 	|¡| S )aM  
        Sign some data with this key.

        SECSH-TRANS RFC 4253 Section 6.6.

        @param data: The data to sign.

        @param signatureType: The SSH public key algorithm name to sign this
            data with, or L{None} to use a reasonable default for the key.

        @return: A signature for the given data.
        Nzpublic key signature algorithm z is not defined for z keysr  r  é   rð   r   é€   ó    rô   )rL   r  r"  r/   rç   Úsignr   ÚPKCS1v15r   rÎ   r"   r   r   ÚECDSA)rè   rV   r!  rw   ÚhashAlgorithmÚsigÚretÚrÚsÚ	signaturerF   ZsbZrcompZscompr-   r-   r.   rY  Ž  s<    
ÿ


zKey.signc                 C  sÊ  t |ƒdkrdt |¡ }}nt |¡\}}|  |¡}|dkrBdS |  ¡ }|dkr†| j}|  ¡ sh| ¡ }t |¡d |t	 
¡ |f}�n|dkrðt |¡d }t |dd… d	¡}	t |dd… d	¡}
t|	|
ƒ}| j}|  ¡ sä| ¡ }|||f}nª|d
k�rft |¡d }t |d¡\}}}t |d	¡}	t |d	¡}
t|	|
ƒ}| j}|  ¡ �sT| ¡ }||t |¡f}n4|dk�rš| j}|  ¡ �sˆ| ¡ }t |¡d |f}z|j|Ž  W n tk
�rÀ   Y dS X dS dS )a  
        Verify a signature using this key.

        @type signature: L{bytes}
        @param signature: The signature to verify.

        @type data: L{bytes}
        @param data: The signed data.

        @rtype: L{bool}
        @return: C{True} if the signature is valid.
        é(   rY   NFr  r   r  rV  Úbigrð   rP   rô   T)r    r   rÎ   ri   r"  rL   rç   rú   rl   r   rZ  r¤   Ú
from_bytesr#   r   r[  Úverifyr   )rè   ra  rV   r!  r\  rw   r‡   ÚargsZconcatenatedSignaturer_  r`  ZrstrZsstrrx   r-   r-   r.   re  Ï  sZ    
ü





z
Key.verify)NN)NN)NNNN)N)N)N)N)NNNN)N)NN)N)NNN)N)0r)   r*   r+   r,   ÚclassmethodrN   rH   r}   r�   r�   r¶   r¾   r¿   rÐ   rÕ   r×   rQ   rˆ   r‰   rä   rr   rt   ré   rï   r  rú   r	  r2   r3   r  rL   r  r  r"  rý   rV   rv   r.  r!   r6  r;  rG  rJ  rK  rR  rU  rY  re  r-   r-   r-   r.   rE   —   s~   '
F
J

X
8


%
0
4,"	,(!L<Sþÿ<

>

RArE   é   c              
   C  s�   |   ¡ jdd� |  ¡ sPtjd|tƒ d�}|jtjj	tj
jt ¡ d�}|  |¡ |  d¡�,}tj| ¡ dtƒ d�}t|ƒW  5 Q R £ S Q R X dS )	a¿  
    This function returns a persistent L{Key}.

    The key is loaded from a PEM file in C{location}. If it does not exist, a
    key with the key size of C{keySize} is generated and saved.

    @param location: Where the key is stored.
    @type location: L{twisted.python.filepath.FilePath}

    @param keySize: The size of the key, if it needs to be generated.
    @type keySize: L{int}

    @returns: A persistent key.
    @rtype: L{Key}
    T)ZignoreExistingDirectoryi  )Zpublic_exponentr#  rœ   )Úencodingr  Zencryption_algorithmrF   N)Úpasswordrœ   )ÚparentÚmakedirsÚexistsr   Zgenerate_private_keyr   r'  r   r%  rH  r(  rI  r)  Z
setContentrG   r   rI   rE   )Úlocationr±   Z
privateKeyZpemZkeyFiler-   r-   r.   Ú_getPersistentRSAKey  s(      ÿý
  ÿro  )rh  )Or,   Ú
__future__r   r  r¡   r7   r3  Úbase64r   r   r   Úhashlibr   r   Útypingr   r¥   Z
constantlyr	   r
   Zcryptographyr   Zcryptography.exceptionsr   Zcryptography.hazmat.backendsr   Zcryptography.hazmat.primitivesr   r   Z)cryptography.hazmat.primitives.asymmetricr   r   r   r   r   Z&cryptography.hazmat.primitives.ciphersr   r   r   Z,cryptography.hazmat.primitives.serializationr   r   Ztyping_extensionsr   Ztwisted.conch.sshr   r   Ztwisted.conch.ssh.commonr   Ztwisted.pythonr   Ztwisted.python.compatr   r    Ztwisted.python.deprecater!   Z/cryptography.hazmat.primitives.asymmetric.utilsr"   r#   ÚImportErrorr$   r%   Z	SECP256R1Z	SECP384R1Z	SECP521R1ro   rŠ   rå   ræ   Ú	Exceptionr'   r/   r0   r1   r2   r5   rD   rE   ro  r-   r-   r-   r.   Ú<module>   sv   ýý             