o
    >h                     @  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.   v/var/www/vedio/testing/chatpythonscript.ninositsolution.com/env/lib/python3.10/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-8)
isinstancestranyr7   r9   	normalizeencode
passphraser.   r.   r/   _normalizePassphrasex   s
   
rF   c                   @  s  e Zd ZdZed]ddZed]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dd Zed^ddZed_ddZed_dd Zed_d!d"Zed_d#d$Zd%d& Zd`d+d,Zdad.d/Zd0d1 Zd2d3 Zejfd4d5Zdbd7d8Zd9d: Zd;d< Z d=d> Z!d?d@ Z"dcdBdCZ#dDdE Z$dFdG Z%e&dHdIgdHdJggd^dKdLZ'd_dMdNZ(d]dOdPZ)d_dQdRZ*dddSdTZ+dUdV Z,dWdX Z-d_dYdZZ.d[d\ Z/dS )e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 _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 rt |\}}| |}
|drd|
_|
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-rsarS      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: )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`   ra   rc   	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rt |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
        r[      r}   r|   dr_   r`   r\      rc   ra   r_   r`   xrS   asciiz.ECDSA curve name %r does not match key type %r)rg   rh   privateValueri   N    )krk   )r   rl   rm   _fromRSAComponents_fromDSAComponentsrr   
_secToNistnamerC   r(   ru   rw   )rL   ry   rz   r{   r}   r|   r   ur_   r`   ra   rc   r   rh   	curveNamer   r   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-sha2re   )rx   r   r   r   splitr   )rL   rY   ry   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rt|\}}t	
d|dd	 d
 }tj|||| |dd}ntd|t|| d
krtdt||d| t||||  t d }|||  }n|dkrtd|f |}t	
d|dd	 d
 }t	
d|d	d d
 }||krt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
            re      openssh-key-v1 z"unknown OpenSSH private key formatN   !Lr]   r   zDonly OpenSSH private key files containing a single key are supportedrS      none0Passphrase must be provided for an encrypted key)s
   aes128-ctrs
   aes192-ctr
   aes256-ctr   r      zunknown encryption type    bcryptT)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   joinrx   r(   lenr   rl   structunpackr2   r   AESintbcryptkdfr   r   CTRr   	decryptorupdatefinalizer   )rL   rY   rE   lineskeyListcipherr   
kdfOptionsr{   r}   _encPrivKeyListalgorithmClass	blockSizekeySizeivSizesaltroundsdecKeyr   privKeyListcheck1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   rY   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   OPENSSH)r   r   r   r   )rL   rY   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
        re   r   r   
   public-keyN   dsa   y   g   p   qrc   ra   r_   r`      rsa-pkcs1-sha1   n   er}   r|   unknown lsh key type )	r   parser   r   rm   NSr   r   r(   rL   rY   sexp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rt|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-keyre   Nr   r   r   r   r   r      xr   	   rsa-pkcs1r   r   r      dr   r   )	r   r   r   rm   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   r[   r}   r|   r   r_   r`   r   r   )r   rl   rm   r   r   r(   )rL   rY   rz   r_   r`   ra   rc   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-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
   -----BEGINprivate_openssh   {
public_lsh   (private_lshs      ssh-s
      ecdsa-s      ssh-ed25519s&      "sk-ecdsa-sha2-nistp256@openssh.coms      sk-ssh-ed25519@openssh.comr   re   r]   agentv3ry   N)rx   r(   r   rl   rm   )rL   rY   ignoredr{   countr.   r.   r/   rT     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   dmp1dmq1iqmppublic_numbers)	r   rn   ro   r   RSAPrivateNumbersrsa_crt_dmp1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^   rb   N)r   r   )r   rp   rq   ro   r   DSAPrivateNumbersr   )	rL   rc   r_   r`   ra   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   rc   rh   N)private_valuer   )r   EllipticCurvePublicNumbersrr   ro   r   EllipticCurvePrivateNumbersr   )rL   r   rc   rh   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   rs   rt   rr   derive_private_keyr   )rL   rg   rh   r   r~   r.   r.   r/   ru   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(   from_public_bytesfrom_private_bytes)rL   r   r   r~   r.   r.   r/   rw   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)
_keyObjectrv   )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.
        )r?   rG   rN   rY   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 }	qt|dk r|	dd }	|d|	  |sqk|d d |d< d
|S )z@
        Return a pretty representation of this object.
        ECrh   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]       02xr   	>)rN   rY   decodeisPublicsorteditemsr    sizeappendr   MPr   ordr   r   )r  rY   r   outr   vr   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.
        )
r?   r  r   RSAPublicKeyr   DSAPublicKeyr   rs   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.
        )r  rG   r  ro   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: )r4   r6   r    r   r   ry   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: )r?   r  r   r%  RSAPrivateKeyr   r&  DSAPrivateKeyr   rs   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  rf   rj   r   r   r[   r\   ri   )r1  r2  r  )rv   rN   r   r  rh   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}
        r1  )   rsa-sha2-512   rsa-sha2-256r[   )rN   r7  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  ))r1  r[   )r1  r9  )r1  r8  )r2  r\   )	rN   r7  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   rh   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rd| 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   rc   ra   r_   r`   r   )r   rc   r   rh   r   )r   r   zUnexpected key type: )&r?   r  r   r%  r   r}   r|   r3  private_numbersr   r_   r`   r   r   r&  rc   rd   ra   r4  r   r   rs   r7  r5  r   r   r   public_bytesr   EncodingRawPublicFormatr  ro   private_bytesPrivateFormatNoEncryptionr6  )r  rsa_pub_numbersrsa_priv_numbersdsa_pub_numbersdsa_priv_numbersec_pub_numbersec_priv_numbersr.   r.   r/   rY   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rt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}
        r1  r[   r|   r}   r2  r\   r_   r`   ra   rc   r     r   rh   N   r   r  ri   r   unknown key type: )rN   rY   r   r   r  r  rh   rC  r   r   r(   )r  rN   rY   
byteLengthr.   r.   r/   ry     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rt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
        r1  r_   r`   r[   r}   r|   r   r2  r\   ra   rc   r   r  rh   rT  Nr   r  ri   r   r   rV  )rN   rY   r   r   r   r   r  r  ro   rF  r   rG  X962rI  UncompressedPointr(   )r  rN   rY   r   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}
        NzThe 'extra' argument to twisted.conch.ssh.keys.Key.toString was deprecated in Twisted 20.3.0; use 'comment' or 'passphrase' instead.r   )
stacklevelrQ   
_toString_rV  )subtyper]  rE   )warningswarnDeprecationWarningr  r?   r@   rC   rF   rU   rV   r(   )r  rN   r\  r`  r]  rE   rZ   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          
)rN   r  rF  r   rG  OpenSSHrI  r   r   ry   replacer7  )r  r]  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|rt||	|| 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   re      Nr   r   rf  s#   -----BEGIN OPENSSH PRIVATE KEY-----c                   s   g | ]
} ||d   qS )@   r.   )r;   iri  r.   r/   r,    s    z,Key._toPrivateOpenSSH_v1.<locals>.<listcomp>rm  s!   -----END OPENSSH PRIVATE KEY-----)r   r   
block_sizer   secureRandomr   r   r   packr[  r   bytesr   r   r   r   r   r   	encryptorr   r   ry   r   rh  ranger   )r  r]  rE   r   
cipherNamekdfNamer   r   r   r   r   r   checkr   padByteencKeyrt  r   ry   r   r.   ro  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 instead)r   rL  BestAvailableEncryptionrN   r  rJ  rG  PEMrK  TraditionalOpenSSLr   )r  rE   rt  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}
        )r]  v1Nr  )r]  rE   r}  rD   zunknown subtype )r  rj  rN   r{  r  r   )r  r`  r]  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}
        r1  r   r   r   r}   r]   Nr   r|   r2  r   r   r_   r   r`   r   ra   r   rc   r   r   rf  r      }r   r   r   r      are      b   cr   r   ')rY   rN   r  r   rr  r   r  r(   r   rh  r   r   )r  kwargsrY   rN   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}
        r1  r|   r   r}   r   r_   r`   r2  ra   rc   r   r   N)	rY   r  rN   r   r   r7  r   mapr  )r  r  rY   valuesr.   r.   r/   _toString_AGENTV3x  s   " zKey._toString_AGENTV3c                 C  s  |   }|du r|  }| |}|du r td| d| d|dkr4| j|t |}t	|}n|dkrS| j||}t
|\}}t	t|dt|d }nm|dkr| j|t|}	t
|	\}}t|}
t|}t |
d	 tu r~t|
d	 }n|
d	 }|d
@ rd|
 }
t |d	 tu rt|d	 }n|d	 }|d
@ rd| }t	t	|
t	| }n|dkrt	| j|}t	|| S )a  
        Sign some data with this key.

        SECSH-TRANS RFC 4253 Section 6.6.

        @type data: L{bytes}
        @param data: The data to sign.

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

        @rtype: L{bytes}
        @return: A signature for the given data.
        Nzpublic key signature algorithm z is not defined for z keysr1  r2     r  r          r  )rN   r7  rB  r1   r  signr   PKCS1v15r   r   r"   r   r   ECDSAr@   r  )r  rY   rA  rz   hashAlgorithmsigretrs	signaturerH   sbrcompscompr.   r.   r/   r    sH   
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rt|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\   NFr1  r   r2  r  bigr  rS   r  T)r   r   r   rl   rB  rN   r  r  ro   r   r  r   
from_bytesr#   r   r  verifyr   )r  r  rY   rA  r  rz   r   argsconcatenatedSignaturer  r  rstrsstrr{   r.   r.   r/   r    s\   


z
Key.verify)NN)NNNN)N)r  r  r	  r
  )r	  r@   )r	  r0  )r	  rD  )NNN)0r*   r+   r,   r-   classmethodrP   rJ   r   r   r   r   r   r   r   r   r   rT   r   r   r   ru   rw   r  r  r$  r  r(  r4   r5   r/  rN   r7  r:  rB  r  rY   ry   r[  r!   rd  rj  r{  r  r  r  r  r  r  r.   r.   r.   r/   rG      s    '
F
J

X
8


%
0
4,"

	,
(!
L<S
<

>
R
LrG      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)ignoreExistingDirectoryi  )public_exponentrC  r   )encodingr.  encryption_algorithmrH   N)passwordr   )parentmakedirsexistsr   generate_private_keyr   rJ  r   rG  r}  rK  r~  rL  
setContentrI   r   rK   rG   )locationr   
privateKeypemkeyFiler.   r.   r/   _getPersistentRSAKey!  s"   
$r  )r  )Or-   
__future__r   r*  r   r9   ra  base64r   r   r   hashlibr   r   typingr   r   
constantlyr	   r
   cryptographyr   cryptography.exceptionsr   cryptography.hazmat.backendsr   cryptography.hazmat.primitivesr   r   )cryptography.hazmat.primitives.asymmetricr   r   r   r   r   &cryptography.hazmat.primitives.ciphersr   r   r   ,cryptography.hazmat.primitives.serializationr   r   typing_extensionsr   twisted.conch.sshr   r   twisted.conch.ssh.commonr   twisted.pythonr   twisted.python.compatr   r    twisted.python.deprecater!   /cryptography.hazmat.primitives.asymmetric.utilsr"   r#   ImportErrorr$   r%   	SECP256R1	SECP384R1	SECP521R1rr   r   r   r  	Exceptionr(   r1   r2   r3   r4   r7   rF   rG   r  r.   r.   r.   r/   <module>   sz   	             