
    Vh                       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 	 ddl8m9Z9m:Z:  ej|                          ej~                          ej                         dZAddddZBe j                  ZCe j                  ZD G d deE      ZF G d deE      ZG G d  d!eE      ZH G d" d#eE      ZI G d$ d%e      ZJ G d& d'eE      ZKd( ZL G d) d*      ZMd,d+ZNy# e;$ r ddl8m<Z9m=Z: Y w xY w)-z0
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y)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__     F/home/dcms/DCMS/lib/python3.12/site-packages/twisted/conch/ssh/keys.pyr)   r)   D   s    r0   r)   c                      e Zd ZdZy)BadSignatureAlgorithmErrorzi
    Raised when a public key signature algorithm name isn't defined for this
    public key format.
    Nr*   r/   r0   r1   r3   r3   L       r0   r3   c                      e Zd ZdZy)EncryptedKeyErrorzb
    Raised when an encrypted key is presented to fromString/fromFile without
    a password.
    Nr*   r/   r0   r1   r6   r6   S   r4   r0   r6   c                      e Zd ZdZy)BadFingerPrintFormatzS
    Raises when unsupported fingerprint formats are presented to fingerprint.
    Nr*   r/   r0   r1   r8   r8   Z   s    r0   r8   c                  ,    e Zd ZdZ e       Z e       Zy)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/   r0   r1   r:   r:   `   s    
 oG!OMr0   r:   c                      e Zd ZdZy)PassphraseNormalizationErrorz
    Raised when a passphrase contains Unicode characters that cannot be
    normalized using the available Unicode character database.
    Nr*   r/   r0   r1   r>   r>   q   r4   r0   r>   c                    t        | t              rAt        d | D              r
t               t	        j
                  d|       j                  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              3  L   K   | ]  }t        j                  |      d k(    yw)CnN)unicodedatacategory).0cs     r1   	<genexpr>z'_normalizePassphrase.<locals>.<genexpr>   s      C1{##A&$.Cs   "$NFKCzUTF-8)
isinstancestranyr>   rB   	normalizeencode
passphrases    r1   _normalizePassphraserO   x   sM    & *c" C
CC /00$$VZ8??HHr0   c                     e Zd ZdZed.d       Zed.d       Zed        Zed        Zed        Z	ed        Z
ed	        Zed
        Zed        Zed        Zed        Zed        Zed/d       Zed0d       Zed0d       Zed0d       Zed0d       Zd Zd1dZd2dZd Zd Zej8                  fdZd3dZd Zd Z d Z!d Z"d4dZ#d  Z$d! Z% e&d"d#gd"d$gg      d/d%       Z'd0d&Z(d.d'Z)d0d(Z*d5d)Z+d* Z,d+ Z-d0d6d,Z.d- Z/y)7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                    t        |d      5 }| j                  |j                         ||      cddd       S # 1 sw Y   yxY w)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typerN   fs        r1   fromFilezKey.fromFile   s;    $ (D! 	>Q>>!&&(D*=	> 	> 	>s	   !8Ac                j   t        |t              r|j                  d      }t        |      }|| j	                  |      }|t        d|      t        | d|j                          d      }|t        d|       |j                  j                  dk(  r|rt        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)
rH   rI   rL   rO   _guessStringTyper)   getattrupper__code__co_argcount)rW   datarY   rN   methods        r1   rU   zKey.fromString   s    . dC ;;w'D)*5
<''-D< 9$BCCTZZ\N;TB> :4&ABB??&&!+!"566$<$
++r0   c           
     ^   t        j                  |      \  }}|dk(  rMt        j                  |d      \  }}} | t        j                  ||      j                  t                           S |dk(  rft        j                  |d      \  }}}}	} | t        j                  |	t        j                  |||            j                  t                           S |t        v rD | t        j                  j                  t        |   t        j                  |d      d               S |dk(  r3| j                  t        j                  |d      d   d	
      }
d|
_        |
S |dv rCt        j                  |      \  }}| j!                  |      }
|j#                  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-rsar_      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)   )rW   blobkeyTyperestenrl   rm   rn   rp   	keyObjectas               r1   _fromString_BLOBzKey._fromString_BLOB   s   D T*j dA.JAq$s++Aq1<<_=NOPPj %||D!4Aq!Q$$3+B+BQ!q+Q*_./  k!))<<(&,,tQ*?*B  ;;//#\\$215, 0 I !IMEEll4(GAt2215I!!*- $	/y9::r0   c                   t        j                  |      \  }}|dk(  r4t        j                  |d      \  }}}}}}	}| j                  |||||	      S |dk(  r3t        j                  |d      \  }}	}
}}}| j	                  ||
||	|      S |t
        v rt
        |   }t        j                  |d      \  }}	}|t        |j                  j                  d         k7  rt        d	|d
|      t        j                  |      \  }}| j                  |	||      S |dk(  r2t        j                  |d      \  }}}|dd }| j                  ||      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
        rh      r   r   drl   rm   ri      rp   rn   rl   rm   xr_   asciizECDSA curve name z does not match key type )rt   ru   privateValuerv   N    )krx   )r   ry   rz   _fromRSAComponents_fromDSAComponentsr   
_secToNistnamerL   r)   r   r   )rW   r   r   r   r   r   r   url   rm   rn   rp   r   ru   	curveNamer   r   combinedr   s                      r1   _fromString_PRIVATE_BLOBzKey._fromString_PRIVATE_BLOB$  s   \ T*j %+\\$%:"Aq!Q1d))Aa1)BB
""(,,tQ"7Aq!Q4))Aa1)BB#(E!'dA!6Iq$Juzz'8'8'ABB!!*G5  "(d!3L$**gL +   & !'T1 5Ax"A--a1-55 3G9=>>r0   c                    |j                  d      r | t        |t                           S t        |j	                         d         }| j                  |      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-sha2rr   )r   r   r   r   splitr   )rW   re   r   s      r1   _fromString_PUBLIC_OPENSSHzKey._fromString_PUBLIC_OPENSSHo  sK      ??=)*41BCDD4::<?+##D))r0   c           	        |j                         j                         }t        dj                  |dd             }|j	                  d      st        d      |t        d      d }t        j                  |d      \  }}}}t        j                  d|dd	       d
   }	|	dk7  rt        d      t        j                  |d	d d      \  }
}}
|dk7  r/|st        d      |dv r&t        j                  }d}t        |dd       dz  }|}nt        d|      |dk(  rRt        j                  |      \  }}t        j                  d|dd	       d
   }t        j                   ||||z   |d      }nt        d|      t        |      |z  d
k7  rt        d      t#         ||d|       t%        j&                  ||||z          t)                     j+                         }|j-                  |      |j/                         z   }n|dk7  rt        d|d      |}t        j                  d|dd	       d
   }t        j                  d|d	d       d
   }||k7  rt        d||fz        | j1                  |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
        r0   rr      openssh-key-v1 z"unknown OpenSSH private key formatN   !Lrj   r   zDonly OpenSSH private key files containing a single key are supportedr_      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 z but no cipherz#check values do not match: %d != %d)strip
splitlinesr   joinr   r)   lenr   ry   structunpackr6   r   AESintbcryptkdfr   r   CTRr   	decryptorupdatefinalizer   )rW   re   rN   lineskeyListcipherr   
kdfOptionsr   r   _encPrivKeyListalgorithmClass	blockSizekeySizeivSizesaltroundsdecKeyr   privKeyListcheck1check2s                          r1   _fromPrivateOpenSSH_v1zKey._fromPrivateOpenSSH_v1  s   : 

'')chhuQr{34!!"56BCC#1245(.Wa(@%ZMM$Ra)!,6- 
  &||DHa8>1W'I  FF!+	fQqk*a/"!$<VJ"GHHi#\\*5
dtT"1X6q9f$&* "$5cW"=>>N#i/A5!-00vhw/0		&7V+;<=') ik	 
 $**>:Y=O=O=QQKg~!GJL  )Kt[!_5a8t[1%56q9VCvvFVVWW++KO<<r0   c                   |j                         j                         }|d   dd }|sd}|dv r	 t        ||t                     } | |      S t        d|       # t        $ r t        d      t        $ r t        d      w xY w)	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   	TypeErrorr6   
ValueErrorr)   )rW   re   rN   r   kindkeys         r1   _fromPrivateOpenSSH_PEMzKey._fromPrivateOpenSSH_PEM  s    J 

'')Qx3 J**L*4_=NO s8O 1$899  'F   L!"JKKLs   A (Bc                    |j                         j                         d   dd dk(  r| j                  ||      S | j                  ||      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   )rW   re   rN   s      r1   _fromString_PRIVATE_OPENSSHzKey._fromString_PRIVATE_OPENSSH  sO    , ::<""$Q'3/:=--dJ?? ..tZ@@r0   c                   t        j                  t        |dd             }|d   dk(  sJ i }|d   dd D ]3  \  }}t        j                  t        j
                  |            d   ||<   5 |d   d   dk(  r!| j                  |d   |d   |d	   |d
         S |d   d   dk(  r| j                  |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
        rr   r   r   
   public-keyN   dsa   y   g   p   qrp   rn   rl   rm      rsa-pkcs1-sha1   n   er   r   unknown lsh key type )	r   parser   r   rz   NSr   r   r)   rW   re   sexpkdr   s        r1   _fromString_PUBLIC_LSHzKey._fromString_PUBLIC_LSH3  s    " {{;tAbz23Aw-'''q'!"+ 	8JD$||FIIdO4Q7BtH	871:))T(bh"T(bh *   !WQZ,,))BtH4)AA 5d1gaj\BCCr0   c                X   t        j                  |      }|d   dk(  sJ i }|d   dd D ]3  \  }}t        j                  t        j                  |            d   ||<   5 |d   d   dk(  rCt        |      dk(  sJ t        |             | j                  |d   |d   |d	   |d
   |d         S |d   d   dk(  r_t        |      dk(  sJ t        |             |d	   |d
   kD  r|d
   |d	   c|d	<   |d
<   | j                  |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-keyrr   Nr   r   r   r   r   r      xr   	   rsa-pkcs1r   r   r      dr   r   )	r   r   r   rz   r   r   r   r   r)   r   s        r1   _fromString_PRIVATE_LSHzKey._fromString_PRIVATE_LSHS  sp   " {{4 Aw.(((q'!"+ 	8JD$||FIIdO4Q7BtH	871:r7a<(R(<))T(bh"T(bh"T( *   !WQZ<'r7a<(R(<$x"T("%'Xr$x"4"T())T(bh"T(bh"T( *  
  5d1gaj\BCCr0   c                   t        j                  |      \  }}|dk(  rt        j                  |      \  }}t        j                  |      \  }}t        j                  |      \  }}t        j                  |      \  }}t        j                  |      \  }}| j                  |||||      S |dk(  rt        j                  |      \  }}t        j                  |      \  }	}t        j                  |      \  }
}t        j                  |      \  }}t        j                  |      \  }}t        j                  |      \  }}| j	                  |
||	|||      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
        ri   r   rh   r   r   r   rl   rm   r   r   )r   ry   rz   r   r   r)   )rW   re   r   rl   rm   rn   rp   r   r   r   r   r   s               r1   _fromString_AGENTV3zKey._fromString_AGENTV3y  s9   < T*j ll4(GAtll4(GAtll4(GAtll4(GAtll4(GAt))Aa1)BB
"ll4(GAtll4(GAtll4(GAtll4(GAtll4(GAtll4(GAt))Aa1Q)GG 1';<<r0   c                   |j                  d      s|j                  d      ry|j                  d      s|j                  d      rt        d      |j                  d      s|j                  d      ry|j                  d	      ry
|j                  d      ry|j                  d      ry|j                  d      sD|j                  d      s3|j                  d      s"|j                  d      s|j                  d      rCt        j                  |      \  }}d}|r |dz  }t        j                  |      \  }}|r |dkD  ryyy)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   rr   rj   agentv3r   N)r   r)   r   ry   rz   )rW   re   ignoredr   counts        r1   r`   zKey._guessStringType  s)    ??7#t~'F# ??=>$//&C
 HII??45:
 $??=)$??4 ??4   OO3489=>QRLM"LL.MGTE
 &T 2  qy  Nr0   c                Z   t        j                  ||      }||j                  t                     }nqt        j                  |||t        j
                  ||      t        j                  ||      t        j                  ||      |      }	|	j                  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   )rl   rm   r   dmp1dmq1iqmppublic_numbers)	r   r{   r|   r   RSAPrivateNumbersrsa_crt_dmp1rsa_crt_dmq1rsa_crt_iqmpprivate_key)
rW   r   r   r   rl   rm   r   publicNumbersr   privateNumberss
             r1   r   zKey._fromRSAComponents  s    6 ,,qA69%001BCI 22%%a+%%a+%%a+,N '22?3DEI9~r0   c                   t        j                  |t        j                  |||            }||j                  t	                     }n0t        j
                  ||      }|j                  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.
        rk   ro   )r   r  )r   r}   r~   r|   r   DSAPrivateNumbersr  )	rW   rp   rl   rm   rn   r   r  r   r  s	            r1   r   zKey._fromDSAComponents  sq    . ,,3#:#:Q!q#I
 9%001BCI 22Q}UN&22?3DEI9~r0   c                    t        j                  ||t        |         }||j                  t	                     }n0t        j
                  ||      }|j                  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   rp   ru   )private_valuer  )r   EllipticCurvePublicNumbersr   r|   r   EllipticCurvePrivateNumbersr  )rW   r   rp   ru   r   r  r   r  s           r1   _fromECComponentszKey._fromECComponents/  so    $ 551K.
 %001BCI;;*=N '22?3DEI9~r0   c                    |(t         j                  j                  t        |   |      }n&t        j                  |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}
        )r   r   r   r   derive_private_keyr   )rW   rt   ru   r   r   s        r1   r   zKey._fromECEncodedPointO  sW      11DDE"LI --k%0/2CI 9~r0   c                    t         t        t        d      |t         j                  |      }nt        j	                  |      } | |      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}
        z)Ed25519 keys not supported on this system)Ed25519PublicKeyEd25519PrivateKeyr)   from_public_bytesfrom_private_bytes)rW   r   r   r   s       r1   r   zKey._fromEd25519Componentsk  sK     #'8'@IJJ9(::1=I)<<Q?I9~r0   c                     || _         d| _        y)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)
_keyObjectr   )selfr   s     r1   __init__zKey.__init__  s     $r0   c                    t        |t              rD| j                         |j                         k(  xr! | j                         |j                         k(  S t        S )zN
        Return True if other represents an object with the same key.
        )rH   rQ   rY   re   NotImplemented)r   others     r1   __eq__z
Key.__eq__  sA     eS!99;%**,.N499;%**,3NN!!r0   c                   | j                         dk(  r| j                         }|d   j                  d      }| j                         r
d|dd  d}n	d|dd  d}t	        |j                               D ]  \  }}|dk(  r	|d	| z  }|d
| d| z  }  |dz   S dt        | j                               d| j                         xr dxs dd| j                         dg}t	        | j                         j                               D ]  \  }}|j                  d| d       | j                         dk(  r|nt        j                  |      dd }|sK|dd }|dd }d}	t        |      D ]  }
|	t        |
      ddz   }	 t        |      dk  r|	dd }	|j                  d|	z          |rX |d   dz   |d<   d
j                  |      S )z@
        Return a pretty representation of this object.
        ECru   r]   z<Elliptic Curve Public Key (Nz bits)z<Elliptic Curve Private Key (z	
curve:
	
z:
	z>
< z
Public KeyzPrivate Keyz (zattr :Ed25519rj       02xr   	>)rY   re   decodeisPublicsorteditemsr!   sizeappendr   MPr    ordr   r   )r   re   r   outr   vr   bymorE   s              r1   __repr__zKey.__repr__  s    99;$99;D=''0D}}4T"#YKvF5d23i[Gtzz|, ,1<\$00CRs%s++C	, ; ( !-MMO4EEIIK	E tyy{0023 +1uQCq\*))+2Q		!QR8H3BABCBA&q\ 13q6#,a 0011v{crFLL* + b	CE"I99U##r0   c                    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.
        )
rH   r  r   RSAPublicKeyr   DSAPublicKeyr   r   r   r  r   s    r1   r4  zKey.isPublic  sA     OO    ))((	
 	
r0   c                l    | j                         r| S t        | j                  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.
        )r4  rQ   r  r|   rD  s    r1   publicz
Key.public  s*     ==?Kt11344r0   c           
        |t         j                  u r9t        t        t	        | j                               j                                     S |t         j                  u rit        dj                  t        t        | j                               j                               D cg c]  }t        j                  |       c}            S t        d|       c c}w )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}
           :z Unsupported fingerprint format: )r:   r<   r!   r   r   r   digestr;   r   r    r   binasciihexlifyr8   )r   formatr   s      r1   fingerprintzKey.fingerprint  s    : '555	&*=*D*D*F GHH)111		2;C		<L<S<S<U2VWQX%%a(W  ')I&'RSS	 Xs    Cc                   t        | j                  t        j                  t        j                  f      ryt        | j                  t
        j                  t
        j                  f      ryt        | j                  t        j                  t        j                  f      ryt        | j                  t        j                  t        j                  f      ry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: )rH   r  r   rB  RSAPrivateKeyr   rC  DSAPrivateKeyr   r   EllipticCurvePrivateKeyr   r  r  RuntimeErrorrD  s    r1   rY   zKey.type  s     doo(8(8#:K:K'LM#*:*:C<M<M)NOOOb779S9ST
 OOg668Q8QR
 !9$//9LMNNr0   c                
   | j                   r| j                         dk(  ryy| j                         dk(  r9dt        | j                  j                  j
                  j                  d         z   S dddd	| j                            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'  rs   rw   r   r   rh   ri   rv   )rO  rP  r-  )r   rY   r   r  ru   r   rL   rD  s    r1   sshTypezKey.sshType  s     88yy{d"<
 199;$DOO,A,A,F,F,M,Mg,V!WW
 %
 ))+	 	r0   c                R    | j                         dk(  rg dS | j                         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}
        rO  )   rsa-sha2-512   rsa-sha2-256rh   )rY   rV  rD  s    r1   supportedSignatureAlgorithmsz Key.supportedSignatureAlgorithms@  s'     99;%AALLN##r0   c                &   | j                         dk(  rj|| j                         k(  rV| j                         }|dk  rt        j                         S |dk  rt        j
                         S t        j                         S y| j                         dk(  rt        j                         S t        j                         t        j                         t        j                         t        j                         dj                  | j                         |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-  ))rO  rh   )rO  rY  )rO  rX  )rP  ri   )	rY   rV  r7  r   SHA256SHA384SHA512SHA1get)r   signatureTyper   s      r1   _getHashAlgorithmzKey._getHashAlgorithmL  s     99;$.))+c>!==?*^!==?*!==?*99;)#==?" "(&,mmo&,mmo!'	

 #tyy{M*
+	,r0   c                    | j                   y| j                         dk(  r | j                   j                  j                  S | j                         dk(  ry| j                   j                  S )zv
        Return the size of the object we wrap.

        @return: The size of the key.
        @rtype: L{int}
        r   r'  r-  r\  )r  rY   ru   key_sizerD  s    r1   r7  zKey.sizei  sV     ??"YY[D ??((111YY[I%'''r0   c           	     R	   t        | j                  t        j                        r3| j                  j	                         }|j
                  |j                  dS t        | j                  t        j                        r| j                  j                         }|j                  j
                  |j                  j                  |j                  |j                  |j                  t        j                  |j                  |j                        dS t        | j                  t        j                        rg| j                  j	                         }|j                  |j                   j"                  |j                   j                  |j                   j                  dS t        | j                  t        j$                        r| j                  j                         }|j&                  |j                  j                  |j                  j                   j"                  |j                  j                   j                  |j                  j                   j                  dS t        | j                  t(        j*                        rB| j                  j	                         }|j&                  |j                  | j-                         dS t        | j                  t(        j.                        ra| j                  j                         }|j                  j&                  |j                  j                  |j0                  | j-                         dS t        | j                  t2        j4                        rNd| j                  j7                  t8        j:                  j<                  t8        j>                  j<                        iS t        | j                  t2        j@                        r| j                  jC                         j7                  t8        j:                  j<                  t8        j>                  j<                        | j                  jE                  t8        j:                  j<                  t8        jF                  j<                  t9        jH                               dS tK        d	| j                         )
z_
        Return the values of the public key as a dictionary.

        @rtype: L{dict}
        r   r   r   )r   rp   rn   rl   rm   r  )r   rp   r   ru   r   )r   r   zUnexpected key type: )&rH   r  r   rB  r  r   r   rQ  private_numbersr   rl   rm   r  r   rC  rp   rq   rn   rR  r   r   r   rV  rS  r  r   r  public_bytesr   EncodingRawPublicFormatr  r|   private_bytesPrivateFormatNoEncryptionrT  )r   rsa_pub_numbersrsa_priv_numbersdsa_pub_numbersdsa_priv_numbersec_pub_numbersec_priv_numberss          r1   re   zKey.datax  sr    doos'7'78"oo<<>O$&&$&&  ):):;#>>@%4466%4466%''%''%''%%&6&8&8:J:L:LM  )9)9:"oo<<>O$&&$6688$6688$6688	  ):):;#>>@%''%4466%44FFHH%44FFHH%44FFHH  )B)BC!__;;=N#%%#%% 
 )C)CD"oo==?O$3355$3355 / = =	  )A)ABT__11!**..0J0J0N0N 
 )B)BC__//1>>!**..0J0J0N0N __22!**..!//33!..0		 	 !6t6GHIIr0   c                   | j                         }| j                         }|dk(  rGt        j                  d      t        j                  |d         z   t        j                  |d         z   S |dk(  ryt        j                  d      t        j                  |d         z   t        j                  |d         z   t        j                  |d	         z   t        j                  |d
         z   S |dk(  r| j
                  j                  j                  dz   dz  }t        j                  |d         t        j                  |d   dd       z   t        j                  dt        j                  |d   |      z   t        j                  |d
   |      z         z   S |dk(  r.t        j                  d      t        j                  |d         z   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}
        rO  rh   r   r   rP  ri   rl   rm   rn   rp   r'     r   ru   N   r   r-  rv   r   unknown key type: )rY   re   r   r   r9  r  ru   re  r   r   r)   )r   rY   re   
byteLengths       r1   r   zKey.blob  s   @ yy{yy{5=99Z(699T#Y+??&))DQTIBVVVU]		*%))DI&'))DI&' ))DI&' ))DI&	' T\////881<BJ		$w-())DM"#./0))((cJ?@((cJ?@ Y99^,vyyc/CCC 24&9::r0   c                F   | j                         }| j                         }|dk(  rt        j                  |d   |d         }t	        j
                  d      t	        j                  |d         z   t	        j                  |d         z   t	        j                  |d         z   t	        j                  |      z   t	        j                  |d         z   t	        j                  |d         z   S |dk(  rt	        j
                  d	      t	        j                  |d         z   t	        j                  |d         z   t	        j                  |d
         z   t	        j                  |d         z   t	        j                  |d         z   S |dk(  r| j                  j                         j                  t        j                  j                  t        j                  j                        }t	        j
                  |d         t	        j
                  |d   dd       z   t	        j
                  |      z   t	        j                  |d         z   S |dk(  rMt	        j
                  d      t	        j
                  |d         z   t	        j
                  |d   |d   z         z   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
        rO  rl   rm   rh   r   r   r   rP  ri   rn   rp   r   r'  ru   rw  Nr   r-  rv   r   r   ry  )rY   re   r   r  r   r   r9  r  r|   rh  r   ri  X962rk  UncompressedPointr)   )r   rY   re   r  encPubs        r1   privateBlobzKey.privateBlob   sZ   R yy{yy{5=##DItCy9D		*%))DI&'))DI&' ))DI&' ))D/	"
 ))DI&' ))DI&' U]		*%))DI&'))DI&' ))DI&' ))DI&	'
 ))DI&' T\__//1>>&&++**<<F
 		$w-())DM"#./0))F#$ ))D012 Y		.)))DI&'))DIS	123  24&9::r0   extracommentrN   c                2   |1t        j                  dt        d       | j                         r|}n|}t	        |t
              r|j                  d      }t        |      }t        | d|j                          d      }|t        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   )
stacklevelr]   
_toString_ry  )subtyper  rN   )warningswarnDeprecationWarningr4  rH   rI   rL   rO   ra   rb   r)   )r   rY   r  r  r  rN   rf   s          r1   toStringzKey.toStringS  s    Z MMI # }}"
gs#nnW-G)*5
DJJL>:DA> 24&9::gw:NNr0   c                   | j                         dk(  rd|sd}| j                  j                  t        j                  j
                  t        j                  j
                        dz   |z   j                         S t        | j                               j                  dd      }|sd}| j                         dz   |z   dz   |z   j                         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'  r0          
)rY   r  rh  r   ri  OpenSSHrk  r   r   r   replacerV  )r   r  b64Datas      r1   _toPublicOpenSSHzKey._toPublicOpenSSH  s     99;$,,!**22M4N4N4V4V  	
 eg diik*225#>G%/$6@GGIIr0   c           	        |rkt         j                  }d}d}|j                  dz  }d}|}t        j                  |      }	d}
t        j                  |	      t        j                  d|
      z   }nd}d}d}d}t        j                  d	      }||z   | j                         z   t        j                  |xs d      z   }d
}t        |      |z  r&|dz  }|t        |dz  f      z  }t        |      |z  r&|rt        j                  |	z   d      }t         |d|       t        j                   ||||z          t#                     j%                         }|j'                  |      |j)                         z   }n|}dt        j                  |      z   t        j                  |      z   t        j                  |      z   t        j                  dd      z   t        j                  | j+                               z   t        j                  |      z   }t-        |      j/                  dd      }dgt1        d
t        |      d      D cg c]
  }|||dz     c}z   dgz   }dj3                  |      dz   S c c}w )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   r0   rj   r   rr      Nr   r   r  s#   -----BEGIN OPENSSH PRIVATE KEY-----@   s!   -----END OPENSSH PRIVATE KEY-----)r   r   
block_sizer   secureRandomr   r   r   packr  r   bytesr   r   r   r   r   r   	encryptorr   r   r   r   r  ranger   )r   r  rN   r   
cipherNamekdfNamer   r   r   r   r   r   checkr   padByteencKeyr  r   r   r  ir   s                         r1   _toPrivateOpenSSH_v1zKey._toPrivateOpenSSH_v1  sq      ^^F&JG))Q.IGF))&1DF46;;tV+DDJ JGIJ&&q)emd&6&6&88699W^PS;TT+*qLG5'D.!233K +* ZZ
D'F2BCHFvhw'(		&7V+;<=') ik	 
 '--k:Y=O=O=QQN(Nii
#$ii ! ii
#$ kk$"	#
 ii		$% ii'( 	 d#++E3734,1!S\2,FGqwq1r6"GH345 	
 zz% 5(( Hs   I/c                Z   |st        j                         }nt        j                  |      }| j                         dk7  rM| j                  j                  t         j                  j                  t         j                  j                  |      S | j                         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   rn  BestAvailableEncryptionrY   r  rl  ri  PEMrm  TraditionalOpenSSLr   )r   rN   r  s      r1   _toPrivateOpenSSH_PEMzKey._toPrivateOpenSSH_PEM  s     %224I%==jII99;)#??00&&**++>>  99;)+++W r0   c                    | j                         r| j                  |      S |dk(  s|&| j                         dk(  r| j                  ||      S ||dk(  r| j	                  |      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  v1r-  )r  rN   r  rM   zunknown subtype )r4  r  rY   r  r  r   )r   r  r  rN   s       r1   _toString_OPENSSHzKey._toString_OPENSSH	  s    & ==?(((99_TYY[I5M,,W,TT_5 0---DD/y9::r0   c                D   | j                         }| j                         }| j                         r|dk(  rRt        j                  dddt        j                  |d         dd gdt        j                  |d	         dd gggg      }n|d
k(  rt        j                  dddt        j                  |d         dd gdt        j                  |d         dd gdt        j                  |d         dd gdt        j                  |d         dd gggg      }nt        d|       dt        |      j                  dd      z   dz   S |dk(  r|d   |d   }}t        j                  ||      }t        j                  dddt        j                  |d         dd gdt        j                  |d	         dd gdt        j                  |d         dd gdt        j                  |      dd gdt        j                  |      dd gdt        j                  |d   |dz
  z        dd gdt        j                  |d   |dz
  z        dd gd t        j                  |      dd gg	gg      S |d
k(  rt        j                  dddt        j                  |d         dd gdt        j                  |d         dd gdt        j                  |d         dd gdt        j                  |d         dd gd!t        j                  |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}
        rO  r   r   r   r   rj   Nr   r   rP  r   r   rl   r   rm   r   rn   r   rp   r   r   r  r0      }r   r   r   r      arr      b   cr   r   ')re   rY   r4  r   r  r   r9  r)   r   r  r   r  )r   kwargsre   rY   keyDatarl   rm   r  s           r1   _toString_LSHzKey._toString_LSH&  se    yy{yy{==?u}** * 1!%vyyc';AB'? @!%vyyc';AB'? @	 ** * &!%vyyc';AB'? @!%vyyc';AB'? @!%vyyc';AB'? @!%vyyc';AB'? @	 "$5dV"<==+g.66ucBBTIIu}Cy$s)1''1-zz + ,!%vyyc';AB'? @!%vyyc';AB'? @!%vyyc';AB'? @!%vyy|AB'7 8!%vyy|AB'7 8!%vyyca!e1D'Eab'I J!%vyyca!e1D'Eab'I J!%vyyqr': ;
 $ zz + &!%vyyc';AB'? @!%vyyc';AB'? @!%vyyc';AB'? @!%vyyc';AB'? @!%vyyc';AB'? @
   "$5dV1"=>>r0   c                   | j                         }| j                         s| j                         dk(  r|d   |d   |d   |d   |d   |d   f}n)| j                         dk(  r|d   |d   |d	   |d
   |d   f}t        j                  | j                               dj                  t        t        j                              z   S y)z
        Return a private Secure Shell Agent v3 key.  See
        _fromString_AGENTV3 for the key format.

        @rtype: L{bytes}
        rO  r   r   r   r   rl   rm   rP  rn   rp   r   r0   N)	re   r4  rY   r   r   rV  r   mapr9  )r   r  re   valuess       r1   _toString_AGENTV3zKey._toString_AGENTV3x  s     yy{}}yy{e#IIIIII %s)T#YS	49d3iP99T\\^,sxxFIIv8N/OOO r0   c                   | j                         }|| j                         }| j                  |      }|t        d|d| d      |dk(  rF| j                  j                  |t        j                         |      }t        j                  |      }nD|dk(  rW| j                  j                  ||      }t        |      \  }}t        j                  t        |d      t        |d      z         }n|dk(  r| j                  j                  |t        j                  |            }	t        |	      \  }}t        |      }
t        |      }|
d   }|d	z  rd
|
z   }
|d   }|d	z  rd
|z   }t        j                  t        j                  |
      t        j                  |      z         }n3|dk(  r.t        j                  | j                  j                  |            }t        j                  |      z   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.
        zpublic key signature algorithm z is not defined for z keysrO  rP     r'  r          r-  )rY   rV  rc  r3   r  signr   PKCS1v15r   r   r#   r   r   ECDSA)r   re   rb  r   hashAlgorithmsigretrs	signaturerS   sbrcompscomps                 r1   r  zKey.sign  s    ))+ 
 !LLNM..}= ,1-1B C&iu. 
 e//&&tW-=-=-?OC))C.C//&&t];C)#.FQ
 ))LB/,q"2EEFC_,,T288M3JKI))4FQaBaBqEE t|r\qEEt|r\))FIIbMFIIbM9:C	!))DOO0067Cyy'#--r0   c                   t        |      dk(  rdt        j                  |      }}nt        j                  |      \  }}| j	                  |      }|y| j                         }|dk(  r\| j                  }| j                         s|j                         }t        j                  |      d   |t        j                         |f}n|dk(  rt        j                  |      d   }t        j                  |dd d	      }	t        j                  |dd d	      }
t        |	|
      }| j                  }| j                         s|j                         }|||f}n|d
k(  rt        j                  |      d   }t        j                  |d      \  }}}t        j                  |d	      }	t        j                  |d	      }
t        |	|
      }| j                  }| j                         s|j                         }||t        j                  |      f}nK|dk(  rF| j                  }| j                         s|j                         }t        j                  |      d   |f}	  j                     y# t"        $ r Y yw xY 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.
        (   ri   NFrO  r   rP  r  bigr'  r_   r-  T)r   r   r   ry   rc  rY   r  r4  r|   r   r  r   
from_bytesr$   r   r  verifyr   )r   r  re   rb  r  r   r   argsconcatenatedSignaturer  r  rstrsstrr   s                 r1   r  z
Key.verify  s$    y>R'1699Y3G9M'-||I'>$M9..}= ))+eA==?LLNY'*  "	D $*LL$;A$>!4Sb95AA4RS95AA,Q2IA==?LLNt]3D_$*LL$;A$>!%||,A1ED$tU+AtU+A,Q2IA==?LLNtRXXm%<=D	!A==?LLNLL+A.5D	AHHdO    		s   I! !	I-,I-)NN)NNNN)N)r$  objectreturnbool)r  rI   )r  z&Literal['RSA', 'DSA', 'EC', 'Ed25519'])r  zdict[str, Any])NNN)re   r  rb  zbytes | Noner  r  )0r+   r,   r-   r.   classmethodr[   rU   r   r   r   r   r   r   r   r   r   r`   r   r   r  r   r   r!  r%  r@  r4  rF  r:   r;   rM  rY   rV  rZ  rc  r7  re   r   r  r"   r  r  r  r  r  r  r  r  r  r/   r0   r1   rQ   rQ      s-    > >( %, %,N D; D;L H? H?T * *( V= V=p 6: 6:p A A8 D D> #D #DJ .= .=` 2 2h * *X    D  >  6  ,	"*$X
 5 "4!;!; &TPO.B
$,:(JJX:;xQ;f !i l#	
:O:OxJ4<)|8;:P?dP,?.BDr0   rQ   c                0   | j                         j                  d       | j                         st        j                  d|t                     }|j                  t        j                  j                  t        j                  j                  t        j                               }| j                  |       | j                  d      5 }t        j                  |j!                         dt                     }t#        |      cddd       S # 1 sw Y   yxY w)	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_exponentre  r   )encodingrL  encryption_algorithmrS   N)passwordr   )parentmakedirsexistsr   generate_private_keyr   rl  r   ri  r  rm  r  rn  
setContentrT   r   rV   rQ   )locationr   
privateKeypemkeyFiles        r1   _getPersistentRSAKeyr    s      OOt< ??--!G_=N

 &&"++// ..AA!.!;!;!= ' 
 	C  
t	 "77LLNT?3D

 :	  s   	9DD)i   )Or.   
__future__r   rJ  r   rB   r  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	SECP521R1r   r   r  r  	Exceptionr)   r3   r6   r8   r:   r>   rO   rQ   r  r/   r0   r1   <module>r     s9  
 #     6 6    +  4 8 @ T T L L & + 1 $ 9 @	 )BLLN(BLLN(BLLN 
 ++ -- )  	 9 $ $"9 >| |~3(W7   s    E EE