
    Ϫf                       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 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+m,Z, ddl-m.Z. ddl/m0Z0m1Z1 ddl2m3Z3m4Z4 ddl5m6Z6 	 ddl7m8Z8m9Z9  ejz                          ej|                          ej~                         dZ@ddddZAej                  ZBej                  ZC G d deD      ZE G d deD      ZF G d  d!eD      ZG G d" d#eD      ZH G d$ d%e4      ZI G d& d'eD      ZJd( ZK G d) d*      ZLd,d+ZMy# e:$ r ddl7m;Z8m<Z9 Y w xY w)-z0
Handling of RSA, DSA, ECDSA, and Ed25519 keys.
    )annotationsN)	b64encodedecodebytesencodebytes)md5sha256)Any)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)NamedConstantNames)_mutuallyExclusiveArguments)decode_dss_signatureencode_dss_signature)decode_rfc6979_signatureencode_rfc6979_signature)s   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__     8/usr/lib/python3/dist-packages/twisted/conch/ssh/keys.pyr(   r(   D   s    r/   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.   r/   r0   r2   r2   L       r/   r2   c                      e Zd ZdZy)EncryptedKeyErrorzb
    Raised when an encrypted key is presented to fromString/fromFile without
    a password.
    Nr)   r.   r/   r0   r5   r5   S   r3   r/   r5   c                      e Zd ZdZy)BadFingerPrintFormatzS
    Raises when unsupported fingerprint formats are presented to fingerprint.
    Nr)   r.   r/   r0   r7   r7   Z   s    r/   r7   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{twisted.python.constants.NamedConstant}

    @cvar SHA256_BASE64: Named constant representing fingerprint format
        generated using sha256[RFC4634] algorithm in base64 encoding
    @type SHA256_BASE64: L{twisted.python.constants.NamedConstant}
    N)r*   r+   r,   r-   r    MD5_HEXSHA256_BASE64r.   r/   r0   r9   r9   `   s    
 oG!OMr/   r9   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.   r/   r0   r=   r=   q   r3   r/   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     r0   	<genexpr>z'_normalizePassphrase.<locals>.<genexpr>   s      C1{##A&$.Cs   "$NFKCzUTF-8)
isinstancestranyr=   rA   	normalizeencode
passphrases    r0   _normalizePassphraserN   x   sM    & *c" C
CC /00$$VZ8??HHr/   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-d0d,Z.d- Z/y)6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typerM   fs        r0   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)
rG   rH   rK   rN   _guessStringTyper(   getattrupper__code__co_argcount)rV   datarX   rM   methods        r0   rT   zKey.fromString   s    . dC ;;w'D)*5
<''-D< 9$BCCTZZ\N;TB> :4&ABB??&&!+!"566$<$
++r/   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(  r)t        j                  |      \  }
}| j                  |
      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      ssh-ed25519unknown blob type: )r   getNSgetMPr   RSAPublicNumbers
public_keyr   r   DSAPublicNumbersDSAParameterNumbers_curveTabler   EllipticCurvePublicKeyfrom_encoded_point_fromEd25519Componentsr(   )rV   blobkeyTyperestenrk   rl   rm   ro   as              r0   _fromString_BLOBzKey._fromString_BLOB   s?   D T*j dA.JAq$s++Aq1<<_=NOPP
"%||D!4Aq!Q$$3+B+BQ!q+Q*_./ 
 #))<<(&,,tQ*?*B 
 &ll4(GAt--a00 3G9=>>r/   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
        rg      r   r   drk   rl   rh      ro   rm   rk   rl   xr^   asciizECDSA curve name z does not match key type )encodedPointcurveprivateValuerr   N    )krs   )r   rt   ru   _fromRSAComponents_fromDSAComponentsrz   
_secToNistnamerK   r(   _fromECEncodedPointr}   )rV   r~   r   r   r   r   r   urk   rl   rm   ro   r   r   	curveNamer   r   combinedr   s                      r0   _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=>>r/   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-sha2rq   )
startswithr   r   r   splitr   )rV   rd   r~   s      r0   _fromString_PUBLIC_OPENSSHzKey._fromString_PUBLIC_OPENSSHa  sK      ??=)*41BCDD4::<?+##D))r/   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
        r/   rq      openssh-key-v1 z"unknown OpenSSH private key formatN   !Lri   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   rt   structunpackr5   r   AESintbcryptkdfr   r   CTRr   	decryptorupdatefinalizer   )rV   rd   rM   lineskeyListcipherr   
kdfOptionsr   r   _encPrivKeyListalgorithmClass	blockSizekeySizeivSizesaltroundsdecKeyr   privKeyListcheck1check2s                          r0   _fromPrivateOpenSSH_v1zKey._fromPrivateOpenSSH_v1v  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<<r/   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   	TypeErrorr5   
ValueErrorr(   )rV   rd   rM   r   kindkeys         r0   _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   )rV   rd   rM   s      r0   _fromString_PRIVATE_OPENSSHzKey._fromString_PRIVATE_OPENSSH  sO    , ::<""$Q'3/:=--dJ?? ..tZ@@r/   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
        rq   r   r   
   public-keyN   dsa   y   g   p   qro   rm   rk   rl      rsa-pkcs1-sha1   n   er   r   unknown lsh key type )	r   parser   r   ru   NSr   r   r(   rV   rd   sexpkdr   s        r0   _fromString_PUBLIC_LSHzKey._fromString_PUBLIC_LSH%  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Cr/   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-keyrq   Nr   r   r   r   r   r      xr   	   rsa-pkcs1r   r   r      dr   r   )	r   r   r   ru   r   r   r   r   r(   r   s        r0   _fromString_PRIVATE_LSHzKey._fromString_PRIVATE_LSHE  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Cr/   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
        rh   r   rg   r   r   r   rk   rl   r   r   )r   rt   ru   r   r   r(   )rV   rd   r   rk   rl   rm   ro   r   r   r   r   r   s               r0   _fromString_AGENTV3zKey._fromString_AGENTV3k  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';<<r/   c                   |j                  d      s|j                  d      ry|j                  d      ry|j                  d      ry|j                  d      ry	|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
   -----BEGINprivate_openssh   {
public_lsh   (private_lshs      ssh-s
      ecdsa-s      ssh-ed25519r   rq   ri   agentv3r~   N)r   r   rt   ru   )rV   rd   ignoredr   counts        r0   r_   zKey._guessStringType  s     ??7#t~'F#__]+$__T"__T" OO3489=>"LL.MGTE
 &T 2  qy  ?r/   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   )rk   rl   r   dmp1dmq1iqmppublic_numbers)	r   rv   rw   r   RSAPrivateNumbersrsa_crt_dmp1rsa_crt_dmq1rsa_crt_iqmpprivate_key)
rV   r   r   r   rk   rl   r   publicNumbers	keyObjectprivateNumberss
             r0   r   zKey._fromRSAComponents  s    6 ,,qA69%001BCI 22%%a+%%a+%%a+,N '22?3DEI9~r/   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.
        rj   rn   )r   r  )r   rx   ry   rw   r   DSAPrivateNumbersr  )	rV   ro   rk   rl   rm   r   r  r	  r
  s	            r0   r   zKey._fromDSAComponents  sq    . ,,3#:#:Q!q#I
 9%001BCI 22Q}UN&22?3DEI9~r/   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   ro   r   )private_valuer  )r   EllipticCurvePublicNumbersrz   rw   r   EllipticCurvePrivateNumbersr  )rV   r   ro   r   r   r  r	  r
  s           r0   _fromECComponentszKey._fromECComponents  so    $ 551K.
 %001BCI;;*=N '22?3DEI9~r/   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|   rz   derive_private_keyr   )rV   r   r   r   r	  s        r0   r   zKey._fromECEncodedPoint,  sW      11DDE"LI --k%0/2CI 9~r/   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)rV   r   r   r	  s       r0   r}   zKey._fromEd25519ComponentsH  sK     #'8'@IJJ9(::1=I)<<Q?I9~r/   c                    || _         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.
        N)
_keyObject)selfr	  s     r0   __init__zKey.__init___  s     $r/   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.
        )rG   rP   rX   rd   NotImplemented)r  others     r0   __eq__z
Key.__eq__i  sA     eS!99;%**,.N499;%**,3NN!!r/   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.
        ECr   r\   z<Elliptic Curve Public Key (Nz bits)z<Elliptic Curve Private Key (z	
curve:
	
z:
	z>
< z
Public KeyzPrivate Keyz (zattr :Ed25519ri       02xr   	>)rX   rd   decodeisPublicsorteditemsr   sizeappendr   MPr   ordr   r   )r  rd   r   outr   vr   bymorD   s              r0   __repr__zKey.__repr__r  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##r/   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.
        )
rG   r  r   RSAPublicKeyr   DSAPublicKeyr   r{   r   r  r  s    r0   r0  zKey.isPublic  sA     OO    ))((	
 	
r/   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.
        )r0  rP   r  rw   r@  s    r0   publicz
Key.public  s*     ==?Kt11344r/   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: )r9   r;   r   r   r   r~   digestr:   r   r   r   binasciihexlifyr7   )r  formatr   s      r0   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: )rG   r  r   r>  RSAPrivateKeyr   r?  DSAPrivateKeyr   r{   EllipticCurvePrivateKeyr   r  r  RuntimeErrorr@  s    r0   rX   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Nr/   c                    | 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#  r   r   rg   rh   rr   )rK  rL  r)  )rX   r   r  r   r   rK   r@  s    r0   sshTypezKey.sshType  sd     99;$DOO,A,A,F,F,M,Mg,V!WW
 "!) iik	 r/   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}
        rK  )   rsa-sha2-512   rsa-sha2-256rg   )rX   rR  r@  s    r0   supportedSignatureAlgorithmsz Key.supportedSignatureAlgorithms  s'     99;%AALLN##r/   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t        j                         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  N))rK  rg   )rK  rU  )rK  rT  )rL  rh   )r)  rr   )	rX   rR  r3  r   SHA256SHA384SHA512SHA1get)r  signatureTyper   s      r0   _getHashAlgorithmzKey._getHashAlgorithm  s     99;$.))+c>!==?*^!==?*!==?* &,[[]*0--/*0--/%+[[]-3]]_ c499;./0r/   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)  rX  )r  rX   r   key_sizer@  s    r0   r3  zKey.size:  sV     ??"YY[D ??((111YY[I%'''r/   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   ro   rm   rk   rl   r  )r   ro   r   r   r   )r   r   zUnexpected key type: )&rG   r  r   r>  r  r   r   rM  private_numbersr   rk   rl   r  r   r?  ro   rp   rm   rN  r   r   r{   rR  rO  r  r   r  public_bytesr   EncodingRawPublicFormatr  rw   private_bytesPrivateFormatNoEncryptionrP  )r  rsa_pub_numbersrsa_priv_numbersdsa_pub_numbersdsa_priv_numbersec_pub_numbersec_priv_numberss          r0   rd   zKey.dataI  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Ir/   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}
        rK  rg   r   r   rL  rh   rk   rl   rm   ro   r#     r   r   N   r   r)  rr   r   unknown key type: )rX   rd   r   r   r5  r  r   ra  r
   r   r(   )r  rX   rd   
byteLengths       r0   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::r/   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
        rK  rk   rl   rg   r   r   r   rL  rh   rm   ro   r   r#  r   rs  Nr   r)  rr   r   r   ru  )rX   rd   r   r  r   r   r5  r  rw   rd  r   re  X962rg  UncompressedPointr(   )r  rX   rd   r  encPubs        r0   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::r/   extracommentrM   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_ru  )subtyper}  rM   )warningswarnDeprecationWarningr0  rG   rH   rK   rN   r`   ra   r(   )r  rX   r|  r  r}  rM   re   s          r0   toStringzKey.toString$  s    Z MMI # }}"
gs#nnW-G)*5
DJJL>:DA> 24&9::gw:NNr/   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#  r/          
)rX   r  rd  r   re  OpenSSHrg  r   r   r~   replacerR  )r  r}  b64Datas      r0   _toPublicOpenSSHzKey._toPublicOpenSSHf  s     99;$,,!**22M4N4N4V4V  	
 eg diik*225#>G%/$6@GGIIr/   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   r/   ri   r   rq      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}  rM   r   
cipherNamekdfNamer   r   r   r   r   r   checkr   padByteencKeyr  r   r~   r  ir   s                         r0   _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   rj  BestAvailableEncryptionrX   r  rh  re  PEMri  TraditionalOpenSSLr   )r  rM   r  s      r0   _toPrivateOpenSSH_PEMzKey._toPrivateOpenSSH_PEM  s     %224I%==jII99;)#??00&&**++>>  99;)+++W r/   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}  rM   r  rL   zunknown subtype )r0  r  rX   r  r  r   )r  r  r}  rM   s       r0   _toString_OPENSSHzKey._toString_OPENSSH  s    & ==?(((99_TYY[I5M,,W,TT_5 0---DD/y9::r/   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}
        rK  r   r   r   r   ri   Nr   r   rL  r   r   rk   r   rl   r   rm   r   ro   r   r   r  r/      }r   r   r   r      arq      b   cr   r   ')rd   rX   r0  r   r  r   r5  r(   r   r  r   r  )r  kwargsrd   rX   keyDatark   rl   r  s           r0   _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"=>>r/   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}
        rK  r   r   r   r   rk   rl   rL  rm   ro   r   r/   N)	rd   r0  rX   r   r   rR  r   mapr5  )r  r  rd   valuess       r0   _toString_AGENTV3zKey._toString_AGENTV3I  s     yy{}}yy{e#IIIIII %s)T#YS	49d3iP99T\\^,sxxFIIv8N/OOO r/   c                l   | j                         }|| j                         }| j                  |      }|t        d| d| d      |dk(  rF| j                  j                  |t        j                         |      }t        j                  |      }n|dk(  rX| j                  j                  ||      }t        |      \  }}t        j                  t        |d      t        |d      z         }n.|dk(  r| j                  j                  |t        j                  |            }	t        |	      \  }}t        |      }
t        |      }t        |
d         t        u rt        |
d         }n|
d   }|d	z  rd
|
z   }
t        |d         t        u rt        |d         }n|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 )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.
        zpublic key signature algorithm z is not defined for z keysrK  rL     r#  r          r)  )rX   rR  r_  r2   r  signr   PKCS1v15r   r   r#   r   r   ECDSArH   r6  )r  rd   r^  r   hashAlgorithmsigretrs	signaturerR   sbrcompscomps                 r0   r  zKey.sign_  s     ))+ 
 !LLNM..}= ,1- A&iu. 
 e//&&tW-=-=-?OC))C.C//&&t];C)#.FQ
 ))LB/,q"2EEFC_,,T288M3JKI))4FQaBaB BqE{c!BqE
1 t|r\BqE{c!BqE
1t|r\))FIIbMFIIbM9:C	!))DOO0067Cyy'#--r/   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.
        (   rh   NFrK  r   rL  r  bigr#  r^   r)  T)r   r   r   rt   r_  rX   r  r0  rw   r   r  r   
from_bytesr$   r   r  verifyr   )r  r  rd   r^  r  r   r   argsconcatenatedSignaturer  r  rstrsstrr   s                 r0   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  rH   )r  z&Literal['RSA', 'DSA', 'EC', 'Ed25519'])r  zdict[str, Any])NNN)0r*   r+   r,   r-   classmethodrZ   rT   r   r   r   r   r   r   r   r   r   r_   r   r   r  r   r}   r  r!  r<  r0  rB  r9   r:   rI  rX   rR  rV  r_  r3  rd   r~   r{  r"   r  r  r  r  r  r  r  r  r  r.   r/   r0   rP   rP      s*    > >( %, %,N 6? 6?p H? H?T * *( V= V=p 6: 6:p A A8 D D> #D #DJ .= .=`  > * *X    D  >  6  ,$"*$X
 5 "4!;!; &TPO.0
$06(JJX:;xQ;f !i l#	
:O:OxJ4<)|8;:P?dP,J.XDr/   rP   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_exponentra  r   )encodingrH  encryption_algorithmrR   N)passwordr   )parentmakedirsexistsr   generate_private_keyr   rh  r   re  r  ri  r  rj  
setContentrS   r   rU   rP   )locationr   
privateKeypemkeyFiles        r0   _getPersistentRSAKeyr    s      OOt< ??--!G_=N

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

 :	  s   	9DD)i   )Nr-   
__future__r   rF  r   rA   r  base64r   r   r   hashlibr   r   typingr	   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   r   twisted.conch.sshr   r   twisted.conch.ssh.commonr   twisted.pythonr   twisted.python.compatr   r   twisted.python.constantsr    r!   twisted.python.deprecater"   /cryptography.hazmat.primitives.asymmetric.utilsr#   r$   ImportErrorr%   r&   	SECP256R1	SECP384R1	SECP521R1rz   r   r  r  	Exceptionr(   r2   r5   r7   r9   r=   rN   rP   r  r.   r/   r0   <module>r     s9  
 #     6 6     4 8 @ T T L L  + 1 $ 9 9 @	 )BLLN(BLLN(BLLN 
 ++ -- )  	 9 $ $"9 >X Xv2(O6   s    E EE