o
    Òó·i‡þ  ã                   @  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;y¹   ddl8m<Z9m=Z: Y nw 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                   @  ó   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.   ú\C:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\twisted/conch/ssh/keys.pyr(   D   ó    r(   c                   @  r'   )ÚBadSignatureAlgorithmErrorzi
    Raised when a public key signature algorithm name isn't defined for this
    public key format.
    Nr)   r.   r.   r.   r/   r1   L   r0   r1   c                   @  r'   )ÚEncryptedKeyErrorzb
    Raised when an encrypted key is presented to fromString/fromFile without
    a password.
    Nr)   r.   r.   r.   r/   r2   S   r0   r2   c                   @  r'   )ÚBadFingerPrintFormatzS
    Raises when unsupported fingerprint formats are presented to fingerprint.
    Nr)   r.   r.   r.   r/   r3   Z   r0   r3   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/   r4   `   s    
r4   c                   @  r'   )ÚPassphraseNormalizationErrorzŒ
    Raised when a passphrase contains Unicode characters that cannot be
    normalized using the available Unicode character database.
    Nr)   r.   r.   r.   r/   r7   q   r0   r7   c                 C  s8   t | tƒrtdd„ | D ƒƒrtƒ ‚t d| ¡ d¡S | 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Úanyr7   r9   Ú	normalizeÚencode©Ú
passphraser.   r.   r/   Ú_normalizePassphrasex   s
   
rF   c                   @  sÒ  e Zd ZdZedad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dcdd „ƒZedcd!d"„ƒZedcd#d$„ƒZd%d&„ Zddd+d,„Zded.d/„Zd0d1„ Zd2d3„ Zejfd4d5„Zdfd7d8„Zd9d:„ Zd;d<„ Z d=d>„ Z!d?d@„ Z"dgdBdC„Z#dDdE„ Z$dFdG„ Z%e&dHdIgdHdJggƒdbdKdL„ƒZ'dcdMdN„Z(dadOdP„Z)dcdQdR„Z*dhdSdT„Z+dUdV„ Z,dWdX„ Z-dcdid]d^„Z.d_d`„ Z/dS )jÚ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  s@   t |dƒ�}|  | ¡ ||¡W  d  ƒ S 1 sw   Y  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ÚtyperE   Úfr.   r.   r/   ÚfromFile    s   $ÿzKey.fromFilec                 C  sš   t |tƒr
| d¡}t|ƒ}|du r|  |¡}|du r"td|›�ƒ‚t| d| ¡ › �dƒ}|du r8td|› �ƒ‚|jj	dkrH|rDtdƒ‚||ƒS |||ƒ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@   rC   rF   Ú_guessStringTyper(   ÚgetattrÚupperÚ__code__Úco_argcount)rL   ÚdatarN   rE   Úmethodr.   r.   r/   rJ   µ   s   



zKey.fromStringc                 C  s  t  |¡\}}|dkr t  |d¡\}}}| t ||¡ tƒ ¡ƒS |dkrBt  |d¡\}}}}	}| tj|	tj	|||d�d� tƒ ¡ƒS |t
v rW| tj t
| t  |d¡d ¡ƒS |dkrm| jt  |d¡d d	d
�}
d|
_|
S |dv r‡t  |¡\}}|  |¡}
| d¡r…d|
_|
S td|› �ƒ‚)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-rsarR   ó   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(   )rL   ÚblobÚkeyTypeÚrestÚeÚnr^   r_   r`   rb   Ú	keyObjectÚar.   r.   r/   Ú_fromString_BLOBÝ   s@   "ÿýÿÿþ

zKey._fromString_BLOBc                 C  s  t  |¡\}}|dkr"t  |d¡\}}}}}}	}| j|||||	d�S |dkr<t  |d¡\}}	}
}}}| j||
||	|d�S |tv rnt| }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|› �ƒ‚)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
        rZ   é   ©r|   r{   Údr^   r_   r[   é   ©rb   r`   r^   r_   ÚxrR   Úasciiz.ECDSA curve name %r does not match key type %r)rf   rg   ÚprivateValuerh   Né    )Úkrj   )r   rk   rl   Ú_fromRSAComponentsÚ_fromDSAComponentsrq   Ú
_secToNistÚnamerC   r(   rt   rv   )rL   rx   ry   rz   r|   r{   r‚   Úur^   r_   r`   rb   r…   rg   Z	curveNamer‡   r~   Zcombinedr‰   r.   r.   r/   Ú_fromString_PRIVATE_BLOB$  s2   .ÿÿÿ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-sha2rd   N)rw   r   r   r   Úsplitr   )rL   rX   rx   r.   r.   r/   Ú_fromString_PUBLIC_OPENSSHo  s   

zKey._fromString_PUBLIC_OPENSSHc                 C  s  |  ¡  ¡ }td |dd… ¡ƒ}| d¡stdƒ‚|tdƒd… }t |d¡\}}}}t	 
d|dd	… ¡d
 }	|	dkr@tdƒ‚t |d	d… d¡\}
}}
|dkrÎ|sWtdƒ‚|dv rmtj}d}t|dd… ƒd }|}ntd|›�ƒ‚|dkr˜t |¡\}}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
        ó    rd   éÿÿÿÿó   openssh-key-v1 z"unknown OpenSSH private key formatNé   ú!Lr\   r   zDonly OpenSSH private key files containing a single key are supportedrR   ó   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   Újoinrw   r(   Úlenr   rk   ÚstructÚunpackr2   r   ÚAESÚintÚbcryptÚkdfr   r   ÚCTRr   Ú	decryptorÚupdateÚfinalizer�   )rL   rX   rE   ÚlinesZkeyListÚcipherr¨   Ú
kdfOptionsrz   r|   Ú_ÚencPrivKeyListZalgorithmClassÚ	blockSizeÚkeySizeÚivSizeÚsaltÚroundsZdecKeyrª   ÚprivKeyListZcheck1Zcheck2r.   r.   r/   Ú_fromPrivateOpenSSH_v1„  sl   
ÿÿú	ýüÿzKey._fromPrivateOpenSSH_v1c                 C  s~   |  ¡  ¡ }|d dd… }|sd}|dv r8zt||tƒ ƒ}W | |ƒS  ty-   tdƒ‚ ty7   tdƒ‚w td|› �ƒ‚)	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   Ú	TypeErrorr2   Ú
ValueErrorr(   )rL   rX   rE   r­   ÚkindÚkeyr.   r.   r/   Ú_fromPrivateOpenSSH_PEMÝ  s    %úÿÿzKey._fromPrivateOpenSSH_PEMc                 C  s4   |  ¡  ¡ d dd… dkr|  ||¡S |  ||¡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À   )rL   rX   rE   r.   r.   r/   Ú_fromString_PRIVATE_OPENSSH  s   zKey._fromString_PRIVATE_OPENSSHc                 C  sÊ   t  t|dd… ƒ¡}|d dksJ ‚i }|d dd… D ]\}}t t |¡¡d ||< q|d d dkrG| j|d |d |d	 |d
 d�S |d d dkrZ| j|d |d d�S td|d d › �ƒ‚)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
        rd   r“   r   ó
   public-keyNó   dsaó   yó   gó   pó   q©rb   r`   r^   r_   ó   rsa-pkcs1-sha1ó   nó   e©r|   r{   úunknown lsh key type )	r   Úparser   r   rl   ÚNSr‹   rŠ   r(   ©rL   rX   ZsexpZkdr�   r.   r.   r/   Ú_fromString_PUBLIC_LSH3  s   ÿzKey._fromString_PUBLIC_LSHc                 C  s0  t  |¡}|d dksJ ‚i }|d dd… D ]\}}t t |¡¡d ||< q|d d dkrPt|ƒdks<J t|ƒƒ‚| j|d |d |d	 |d
 |d d�S |d d dkr�t|ƒdksdJ t|ƒƒ‚|d	 |d
 kry|d
 |d	 |d	< |d
< | j|d |d |d |d	 |d
 d�S td|d d › �ƒ‚)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-keyrd   NrÃ   rƒ   rÄ   rÅ   rÆ   rÇ   ó   xr„   ó	   rsa-pkcs1r›   rÊ   rË   ó   dr�   rÍ   )	r   rÎ   r   rl   rÏ   r¢   r‹   rŠ   r(   rÐ   r.   r.   r/   Ú_fromString_PRIVATE_LSHS  s$   
ÿÿzKey._fromString_PRIVATE_LSHc                 C  sð   t  |¡\}}|dkr8t  |¡\}}t  |¡\}}t  |¡\}}t  |¡\}}t  |¡\}}| j|||||d�S |dkrqt  |¡\}}t  |¡\}	}t  |¡\}
}t  |¡\}}t  |¡\}}t  |¡\}}| j|
||	|||d�S td|› �ƒ‚)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
        r[   r„   rZ   ©r|   r{   r‚   r^   r_   rŽ   r»   N)r   rk   rl   r‹   rŠ   r(   )rL   rX   ry   r^   r_   r`   rb   r…   r{   r‚   r|   rŽ   r.   r.   r/   Ú_fromString_AGENTV3y  s"   zKey._fromString_AGENTV3c                 C  sì   |  d¡s
|  d¡rdS |  d¡s|  d¡rtdƒ‚|  d¡s$|  d¡r&dS |  d	¡r-d
S |  d¡r4dS |  d¡r;dS |  d¡sT|  d¡sT|  d¡sT|  d¡sT|  d¡rtt |¡\}}d}|rl|d7 }t |¡\}}|s_|dkrrd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   rd   r\   Zagentv3rx   N)rw   r(   r   rk   rl   )rL   rX   Zignoredrz   Úcountr.   r.   r/   rS   ª  sH   	ÿÿ


ÿþýüûþñzKey._guessStringTypec           
   
   C  sn   t j||d�}|du r| tƒ ¡}| |ƒS 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.
        )r{   r|   N)r^   r_   r‚   Zdmp1Zdmq1ÚiqmpÚpublic_numbers)	r   rm   rn   r   ZRSAPrivateNumbersZrsa_crt_dmp1Zrsa_crt_dmq1Úrsa_crt_iqmpÚprivate_key)
rL   r|   r{   r‚   r^   r_   rŽ   ÚpublicNumbersr}   ÚprivateNumbersr.   r.   r/   rŠ   ß  s   õ


ù	zKey._fromRSAComponentsc           	      C  sX   t j|t j|||d�d�}|du r| tƒ ¡}| |ƒS 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]   ra   N)r…   rÞ   )r   ro   rp   rn   r   ZDSAPrivateNumbersrà   )	rL   rb   r^   r_   r`   r…   rá   r}   râ   r.   r.   r/   r‹     s   ÿýzKey._fromDSAComponentsc                 C  sR   t j||t| d�}|du r| tƒ ¡}| |ƒS 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…   rb   rg   N)Úprivate_valuerÞ   )r   ZEllipticCurvePublicNumbersrq   rn   r   ZEllipticCurvePrivateNumbersrà   )rL   r…   rb   rg   r‡   rá   r}   râ   r.   r.   r/   Ú_fromECComponents/  s   
ÿûÿzKey._fromECComponentsc                 C  s>   |du rt j t| |¡}| |ƒS 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   rr   rs   rq   Zderive_private_keyr   )rL   rf   rg   r‡   r}   r.   r.   r/   rt   O  s   ÿüÿzKey._fromECEncodedPointc                 C  sD   t du stdu rtdƒ‚|du rt  |¡}| |ƒS 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)rL   r~   r‰   r}   r.   r.   r/   rv   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)Ú
_keyObjectru   )Úselfr}   r.   r.   r/   Ú__init__‚  s   
zKey.__init__ÚotherÚobjectÚreturnÚboolc                 C  s.   t |tƒr|  ¡ | ¡ ko|  ¡ | ¡ kS tS )zN
        Return True if other represents an object with the same key.
        N)r?   rG   rN   rX   ÚNotImplemented)ré   rë   r.   r.   r/   Ú__eq__�  s   
 z
Key.__eq__r@   c                 C  sš  |   ¡ dkrO|  ¡ }|d  d¡}|  ¡ r d|dd… › d�}n
d|dd… › d�}t| ¡ ƒD ]\}}|dkr@|d	|› �7 }q0|d
|› d|› �7 }q0|d S dt|   ¡ ƒ|  ¡ r[dp\d|  ¡ f g}t|  ¡  ¡ ƒD ]T\}}| d|› d�¡ |   ¡ dkr€|nt	 
|¡dd… }|r¿|dd… }|dd… }d}	t|ƒD ]}
|	t|
ƒd›d� }	q�t|ƒdk r¶|	dd… }	| d|	 ¡ |s‹qk|d d |d< d
 |¡S )z@
        Return a pretty representation of this object.
        ÚECrg   rQ   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 ú:ÚEd25519r\   é   Ú Z02xr“   ú	ú>)rN   rX   ÚdecodeÚisPublicÚsortedÚitemsr    ÚsizeÚappendr   ÚMPr   Úordr¢   r¡   )ré   rX   r�   Úoutr‰   Úvr­   ZbyÚmÚor<   r.   r.   r/   Ú__repr__–  sD   
ýÿÿ"ø€	
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.
        N)
r?   rè   r   ÚRSAPublicKeyr   ÚDSAPublicKeyr   rr   r   ræ   ©ré   r.   r.   r/   rû   Â  s   üþzKey.isPublicc                 C  s   |   ¡ r| S t| j ¡ ƒ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û   rG   rè   rn   r	  r.   r.   r/   ÚpublicÒ  s   	z
Key.publicc                 C  sb   |t ju rttt|  ¡ ƒ ¡ ƒƒS |t ju r*td dd„ t	t
|  ¡ ƒ ¡ ƒD ƒ¡ƒS td|› �ƒ‚)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)r;   r…   r.   r.   r/   Ú
<listcomp>  s    z#Key.fingerprint.<locals>.<listcomp>z Unsupported fingerprint format: N)r4   r6   r    r   r   rx   Údigestr5   r¡   r   r   r3   )ré   Úformatr.   r.   r/   Úfingerprintà  s   

ÿÿzKey.fingerprintú&Literal['RSA', 'DSA', 'EC', 'Ed25519']c                 C  sp   t | jtjtjfƒrdS t | jtjtjfƒrdS t | jtj	tj
fƒr$dS t | jtjtjfƒr0dS td| j›�ƒ‚)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   rr   ÚEllipticCurvePrivateKeyr   ræ   rç   ÚRuntimeErrorr	  r.   r.   r/   rN     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ñ   re   ri   rÙ   r†   rZ   r[   rh   )r  r  rõ   N)ru   rN   rŒ   rè   rg   r�   rC   r	  r.   r.   r/   ÚsshType  s   ÿýüzKey.sshTypec                 C  s   |   ¡ dkr
g d¢S |  ¡ g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-256rZ   N)rN   r  r	  r.   r.   r/   ÚsupportedSignatureAlgorithms@  s   
z Key.supportedSignatureAlgorithmsc                 C  sŒ   |   ¡ dkr&||  ¡ kr$|  ¡ }|dkrt ¡ S |dkr t ¡ S t ¡ S dS |   ¡ dkr0t ¡ 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  rZ   )r  r  )r  r  )r  r[   )	rN   r  rþ   r   ÚSHA256ÚSHA384ÚSHA512ÚSHA1Úget)ré   ÚsignatureTyper³   r.   r.   r/   Ú_getHashAlgorithmL  s$   üûzKey._getHashAlgorithmc                 C  s<   | j du rdS |  ¡ dkr| j jjS |  ¡ dkrd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è   rN   rg   Úkey_sizer	  r.   r.   r/   rþ   i  s   

zKey.sizeúdict[str, Any]c              	   C  s¼  t | jtjƒr| j ¡ }|j|jdœS t | jtjƒr5| j ¡ }|jj|jj|j	|j
|jt |j|j
¡dœS t | jtjƒrO| j ¡ }|j|jj|jj
|jjdœS t | jtjƒro| 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ƒrŸ| j ¡ }|jj|jj|j|  ¡ dœS t | jtjƒr³d| 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› �ƒ‚)z_
        Return the values of the public key as a dictionary.

        @rtype: L{dict}
        rÌ   r×   rÈ   )r…   rb   r`   r^   r_   rã   )r…   rb   r‡   rg   r~   )r~   r‰   zUnexpected key type: N)&r?   rè   r   r  rÞ   r|   r{   r  Zprivate_numbersr‚   r^   r_   rß   r   r  rb   rc   r`   r  r…   r   rr   r  r  rä   r   ræ   Úpublic_bytesr   ÚEncodingZRawÚPublicFormatrç   rn   Ú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/   rX   x  st   
þ
ù	
ü
û
ý
üÿÿ
ÿýüzKey.datac                 C  s  |   ¡ }|  ¡ }|dkrt d¡t |d ¡ t |d ¡ S |dkrDt d¡t |d ¡ t |d ¡ t |d	 ¡ t |d
 ¡ S |dkrx| 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|› �ƒ‚)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  rZ   r{   r|   r  r[   r^   r_   r`   rb   rñ   é   r›   rg   éøÿÿÿNó   r…   rõ   rh   r~   úunknown key type: )rN   rX   r   rÏ   r   rè   rg   r%  r   r   r(   )ré   rN   rX   Z
byteLengthr.   r.   r/   rx   Ä  s@    &ÿþýüÿÿÿþÿþÿ	zKey.blobc                 C  s€  |   ¡ }|  ¡ }|dkrCt |d |d ¡}t d¡t |d ¡ t |d ¡ t |d ¡ t |¡ t |d ¡ t |d ¡ S |dkrot 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r¹t d¡t |d ¡ t |d |d  ¡ S td|› �ƒ‚)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_   rZ   r|   r{   r‚   r  r[   r`   rb   r…   rñ   rg   r.  Nr‡   rõ   rh   r~   r‰   r0  )rN   rX   r   rß   r   rÏ   r   rè   rn   r'  r   r(  ZX962r)  ZUncompressedPointr(   )ré   rN   rX   rÝ   ZencPubr.   r.   r/   ÚprivateBlob   sh   )ÿþýüûúÿ	ÿþýüûÿ
þÿþýÿÿþÿzKey.privateBlobÚextraÚcommentrE   c                 C  s€   |durt jdtdd� |  ¡ r|}n|}t|tƒr| d¡}t|ƒ}t| d| 	¡ › �dƒ}|du r9t
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•   )Ú
stacklevelrQ   Z
_toString_r0  )Úsubtyper3  rE   )ÚwarningsÚwarnÚDeprecationWarningrû   r?   r@   rC   rF   rT   rU   r(   )ré   rN   r2  r5  r3  rE   rY   r.   r.   r/   ÚtoStringS  s    -û

zKey.toStringc                 C  sn   |   ¡ dkr|s
d}| j tjjtjj¡d |  ¡ S t|  	¡ ƒ 
dd¡}|s)d}|  ¡ 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’   ó    ó   
N)rN   rè   r'  r   r(  ZOpenSSHr)  rŸ   r   rx   Úreplacer  )ré   r3  Úb64Datar.   r.   r/   Ú_toPublicOpenSSH•  s    
ÿýüúzKey._toPublicOpenSSHc                   s¨  |r%t 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 }t
|ƒ| sI|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’   r\   r   rd   éÿ   Nr�   r”   r;  s#   -----BEGIN OPENSSH PRIVATE KEY-----c                   s   g | ]
}ˆ ||d  … ‘qS )é@   r.   )r;   Úi©r=  r.   r/   r  è  s    z,Key._toPrivateOpenSSH_v1.<locals>.<listcomp>rA  s!   -----END OPENSSH PRIVATE KEY-----)r   r¥   Ú
block_sizer   ZsecureRandomr   rÏ   r£   Úpackr1  r¢   Úbytesr§   r¨   r   r   r©   r   Ú	encryptorr«   r¬   rx   r   r<  Úranger¡   )ré   r3  rE   r®   Z
cipherNameZkdfNamer²   r³   r´   rµ   r¶   r¯   Úcheckr·   ZpadByteZencKeyrG  r±   rx   r­   r.   rC  r/   Ú_toPrivateOpenSSH_v1¯  sl   


þýüÿþý
üûúÿ	ÿþÿzKey._toPrivateOpenSSH_v1c                 C  sT   |st  ¡ }nt  |¡}|  ¡ dkr| j t jjt jj	|¡S |  ¡ dks&J ‚t
dƒ‚)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BestAvailableEncryptionrN   rè   r*  r(  ÚPEMr+  ÚTraditionalOpenSSLr½   )ré   rE   rG  r.   r.   r/   Ú_toPrivateOpenSSH_PEMí  s   


ýÿzKey._toPrivateOpenSSH_PEMc                 C  sh   |   ¡ r
| j|d�S |dks|du r|  ¡ dkr| j||d�S |du s'|dkr-| j|d�S td|› �ƒ‚)	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}
        )r3  Zv1Nrõ   )r3  rE   rK  rD   zunknown subtype )rû   r>  rN   rJ  rM  r½   )ré   r5  r3  rE   r.   r.   r/   Ú_toString_OPENSSH	  s   zKey._toString_OPENSSHc                 K  s¨  |   ¡ }|  ¡ }|  ¡ rƒ|dkr2t dddt |d ¡dd… gdt |d	 ¡dd… gggg¡}nE|d
krpt 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�rLt 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#�ƒ‚)$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Ê   r|   r\   NrË   r{   r  rÃ   rÆ   r^   rÇ   r_   rÅ   r`   rÄ   rb   r»   rÚ   r;  r’   ó   }rÒ   rÔ   rÕ   r‚   ó   ard   ó   bó   crÓ   r…   ú')rX   rN   rû   r   rE  r   r   r(   r   r<  r   rß   )ré   ÚkwargsrX   rN   ZkeyDatar^   r_   rÝ   r.   r.   r/   Ú_toString_LSH&  sv   ýþÿÿûþÿÿ
  ÷þÿÿ
úþÿÿzKey._toString_LSHc                 K  s˜   |   ¡ }|  ¡ sJ|  ¡ dkr#|d |d |d |d |d |d f}n|  ¡ dkr:|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  r{   r‚   r|   rŽ   r^   r_   r  r`   rb   r…   r’   N)	rX   rû   rN   r   rÏ   r  r¡   Úmapr   )ré   rT  rX   Úvaluesr.   r.   r/   Ú_toString_AGENTV3x  s   ú" ôzKey._toString_AGENTV3rX   rF  r#  úbytes | Nonec                 C  sR  |   ¡ }|du r|  ¡ }|  |¡}|du r td|›d|› d�ƒ‚|dkr4| j |t ¡ |¡}t 	|¡}nn|dkrS| j ||¡}t
|ƒ\}}t 	t|dƒt|dƒ ¡}nO|dkr•| j |t |¡¡}	t
|	ƒ\}}t|ƒ}
t|ƒ}|
d	 }|d
@ r{d|
 }
|d	 }|d
@ r‡d| }t 	t 	|
¡t 	|¡ ¡}n|dkr¢t 	| 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õ   )rN   r  r$  r1   rè   Úsignr   ÚPKCS1v15r   rÏ   r"   r   r   ÚECDSA)ré   rX   r#  ry   ÚhashAlgorithmÚsigÚretÚrÚsÚ	signaturerH   ZsbZrcompZscompr.   r.   r/   r]  Ž  s@   
ÿÿzKey.signc                 C  s¶  t |ƒdkrdt |¡}}nt |¡\}}|  |¡}|du r!dS |  ¡ }|dkrB| j}|  ¡ s4| ¡ }t |¡d |t	 
¡ |f}n†|dkrwt |¡d }t |dd… d	¡}	t |dd… d	¡}
t|	|
ƒ}| j}|  ¡ sq| ¡ }|||f}nQ|d
kr°t |¡d }t |d¡\}}}t |d	¡}	t |d	¡}
t|	|
ƒ}| j}|  ¡ s§| ¡ }||t |¡f}n|dkrÈ| j}|  ¡ s¿| ¡ }t |¡d |f}z|j|Ž  W dS  tyÚ   Y dS w )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.
        é(   r[   NFr  r   r  rZ  Úbigrñ   rR   rõ   T)r¢   r   rÏ   rk   r$  rN   rè   rû   rn   r   r^  r¦   Ú
from_bytesr#   r   r_  Úverifyr   )ré   re  rX   r#  r`  ry   r‰   ÚargsZconcatenatedSignaturerc  rd  ZrstrZsstrrz   r.   r.   r/   ri  Ï  s\   
ü

ýÿz
Key.verify)NN)NNNN)N)rë   rì   rí   rî   )rí   r@   )rí   r  )rí   r&  )NNN)rX   rF  r#  rY  rí   rF  )0r*   r+   r,   r-   ÚclassmethodrP   rJ   r   r�   r‘   r¸   rÀ   rÁ   rÑ   rÖ   rØ   rS   rŠ   r‹   rå   rt   rv   rê   rð   r  rû   r
  r4   r5   r  rN   r  r  r$  rþ   rX   rx   r1  r!   r9  r>  rJ  rM  rN  rU  rX  r]  ri  r.   r.   r.   r/   rG   —   s€    '
F
J

X
8


%
0
4,"

	,
(!
L<Sþÿ
<

>
RArG   é   c                 C  sœ   |   ¡ jdd� |  ¡ s(tjd|tƒ d�}|jtjj	tj
jt ¡ d�}|  |¡ |  d¡�}tj| ¡ dtƒ d�}t|ƒW  d  ƒ S 1 sGw   Y  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_algorithmrH   N)Úpasswordrž   )ÚparentÚmakedirsÚexistsr   Zgenerate_private_keyr   r*  r   r(  rK  r+  rL  r,  Z
setContentrI   r   rK   rG   )Úlocationr³   Z
privateKeyZpemZkeyFiler.   r.   r/   Ú_getPersistentRSAKey  s"   ÿý
ÿ$ürs  )rl  )Or-   Ú
__future__r   r  r£   r9   r6  Ú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	SECP521R1rq   rŒ   ræ   rç   Ú	Exceptionr(   r1   r2   r3   r4   r7   rF   rG   rs  r.   r.   r.   r/   Ú<module>   sz   ÿ	ýý             