o bV@sdZddlZddlZddlZddlZddlZddlmZmZm Z ddl m Z m Z ddl Z ddlmZddlmZddlmZddlmZmZdd lmZmZmZmZmZdd lmZmZm Z dd l!m"Z"m#Z#dd l$m%Z&m'Z(dd l)m*Z*ddl+m,Z,ddl-m.Z.m/Z/ddl0m1Z1ddl2m3Z3ddl4m5Z5m6Z6ddl7m8Z8m9Z9ddl:m;Z;z ddlZ>Wne?yddlYnweBeCeDdZEddddZFGdddeGZHGdddeGZIGd d!d!eGZJGd"d#d#e9ZKGd$d%d%eGZLd&d'ZMGd(d)d)ZNd-d+d,ZOdS).z0 Handling of RSA, DSA, ECDSA, and Ed25519 keys. N) b64encode decodebytes encodebytes)md5sha256)utils)InvalidSignature)default_backend)hashes serialization)dsaeced25519paddingrsa)Cipher algorithmsmodes)load_pem_private_keyload_ssh_public_key)decoderencoder) PyAsn1Error)univ)commonsexpy) int_to_bytes) randbytes) iterbytes nativeString) NamedConstantNames)_mutuallyExclusiveArguments)decode_dss_signatureencode_dss_signature)decode_rfc6979_signatureencode_rfc6979_signature)secdsa-sha2-nistp256secdsa-sha2-nistp384secdsa-sha2-nistp521snistp256snistp384snistp521)s secp256r1s secp384r1s secp521r1c@eZdZdZdS) BadKeyErrorzj Raised when a key isn't what we expected from it. XXX: we really need to check for bad keys N__name__ __module__ __qualname____doc__r.r.8/usr/lib/python3/dist-packages/twisted/conch/ssh/keys.pyr(Fr(c@r')EncryptedKeyErrorzb Raised when an encrypted key is presented to fromString/fromFile without a password. Nr)r.r.r.r/r1Nr0r1c@r')BadFingerPrintFormatzS Raises when unsupported fingerprint formats are presented to fingerprint. Nr)r.r.r.r/r2Ur0r2c@seZdZdZeZeZdS)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.r.r/r3[s r3c@r')PassphraseNormalizationErrorz Raised when a passphrase contains Unicode characters that cannot be normalized using the available Unicode character database. Nr)r.r.r.r/r6lr0r6cCs8t|trtdd|Drttd|dS|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} 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. css|] }t|dkVqdS)CnN) unicodedatacategory).0cr.r.r/ sz'_normalizePassphrase..NFKCzUTF-8) isinstancestranyr6r8 normalizeencode passphraser.r.r/_normalizePassphrasess rEc@seZdZdZedTddZedTddZeddZed d Zed d Z ed dZ eddZ eddZ eddZ eddZeddZeddZedUddZedVddZedVdd ZedVd!d"ZedVd#d$Zd%d&Zd'ed(efd)d*Zd(efd+d,Zd-d.Zd/d0Zejfd1d2Z d3d4Z!d5d6Z"d7d8Z#d9d:Z$d;d<Z%d=d>Z&e'd?d@gd?dAggdUdBdCZ(dVdDdEZ)dTdFdGZ*dVdHdIZ+dWdJdKZ,dLdMZ-dNdOZ.dPdQZ/dRdSZ0dS)XKeyau 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(). NcCs@t|d}||||WdS1swYdS)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 fromStringread)clsfilenametyperDfr.r.r/fromFiles $z Key.fromFilecCst|tr |d}t|}|dur||}|dur"td|t|d|d}|dur8td||jj dkrH|rDtd||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-8Nzcannot guess the type of _fromString_zno _fromString method for zkey not encrypted) r>r?rBrE_guessStringTyper(getattrupper__code__ co_argcount)rKdatarMrDmethodr.r.r/rIs     zKey.fromStringc Cst|\}}|dkr t|d\}}}|t||tS|dkrBt|d\}}}} }|tj| tj |||ddtS|t vrW|t j t |t|ddS|dkrgt|\} }|| Std |) 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-rsarRssh-dsspqgyparameter_numbers ssh-ed25519unknown blob type: )rgetNSgetMPrRSAPublicNumbers public_keyr r DSAPublicNumbersDSAParameterNumbers _curveTabler EllipticCurvePublicKeyfrom_encoded_point_fromEd25519Componentsr() rKblobkeyTyperestenr^r_r`rbar.r.r/_fromString_BLOBs," zKey._fromString_BLOBcCst|\}}|dkr"t|d\}}}}}} }|j||||| dS|dkr @type data: L{bytes} @param data: The key data. @return: A new key. @rtype: L{twisted.conch.ssh.keys.Key} @raises BadKeyError: if the blob type is unknown. s ecdsa-sha2rd) startswithrr rsplitrw)rKrXrqr.r.r/_fromString_PUBLIC_OPENSSH\s  zKey._fromString_PUBLIC_OPENSSHcCs|}td|dd}|dstd|tdd}t|d\}}}}t d|dd d } | dkr@td t|d dd \} } } |d kr|sWt d|dvrmt j } d} t|ddd}| }ntd||dkrt|\}}t d|dd d }tj|||||dd}ntd|t| | d krtdt| |d|t||||td}|| |}n |d krtd|f| }t d|dd d }t d|d dd }||krtd||f||ddS)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----- -----END OPENSSH PRIVATE KEY----- The SSH protocol string is as described in U{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 rdopenssh-key-v1z"unknown OpenSSH private key formatN!Lr\rzDonly OpenSSH private key files containing a single key are supportedrRnone0Passphrase must be provided for an encrypted key)s aes128-ctrs aes192-ctr aes256-ctrrxunknown encryption type bcryptT)ignore_few_roundszunknown KDF type z bad paddingbackendz*private key specifies KDF %r but no cipherz#check values do not match: %d != %d)strip splitlinesrjoinrr(lenrrgstructunpackr1rAESintbcryptkdfrrCTRr decryptorupdatefinalizer)rKrXrDlineskeyListcipherr kdfOptionsrsru_encPrivKeyListalgorithmClass blockSizekeySizeivSizesaltroundsdecKeyr privKeyListcheck1check2r.r.r/_fromPrivateOpenSSH_v1qsl   zKey._fromPrivateOpenSSH_v1c s@|}|ddd}|ddr|stdz|ddd\}}|d d\}WntyAtd |dw|d vr_tj }t |d dd } t dkr^tdn|dkrstj }d} t dkrrtdntd|t tfddtdt dD} t|| dd } t| || dd } | | d| } td|dd}t|| t| td}|||}t|dd}|d| }n d|dd}t|}z t|d}Wnty }ztd|d}~ww|dkr|t||tS|dkr`t |dkr+|d}t |dkr6td d!d|dd"D\}}}}}}}}|t j!||||||t j"||d#d$#tS|d%krd&d|ddD\}}}}}t |dkrtd'|t$j%|t$j&|t$j'|||d(d)d*j#tdStd+|),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 PRIVATE KEY----- [Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,] ------END 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 rdProc-Type: 4,ENCRYPTEDrrR ,zinvalid DEK-info )s AES-128-CBCs AES-256-CBC-rrzAES encrypted key with a bad IVs DES-EDE3-CBCrzDES encrypted key with a bad IVrc3s&|]}t||ddVqdS)rRrNrr:iivdatar.r/r< s$z.Key._fromPrivateOpenSSH_PEM..Nrrrrz(Failed to decode key (Bad Passphrase?): sECsRSArxz!RSA key failed to decode properlycs|]}t|VqdSNrr:valuer.r.r/r<- rtrur^r_rzdmp1dmq1iqmppublic_numberssDSAcsrrrrr.r.r/r<:rz!DSA key failed to decode properlyr]rar}runknown key type )(rrrr1rrstrip ValueErrorr(rrrr TripleDESbytes bytearrayrangerdigestrrrrCBCr rrrord berDecoderdecoderrrRSAPrivateNumbersri private_keyr DSAPrivateNumbersrkrl)rKrXrDrkindr cipherIVInforrrivbabbrb64DatarkeyData removeLen decodedKey asn1Errorrurtrzr^r_rrrr`rbr}r.rr/_fromPrivateOpenSSH_PEMs %      &   zKey._fromPrivateOpenSSH_PEMcCs4|ddddkr|||S|||S)a Return a private key object corresponding to this OpenSSH private key string. If the key is encrypted, passphrase MUST be provided. Providing a passphrase for an unencrypted key is an error. @type data: L{bytes} @param data: The key data. @type passphrase: L{bytes} or L{None} @param passphrase: The passphrase the key is encrypted with, or L{None} if it is not encrypted. @return: A new key. @rtype: L{twisted.conch.ssh.keys.Key} @raises BadKeyError: if * a passphrase is provided for an unencrypted key * the encoding is incorrect @raises EncryptedKeyError: if * a passphrase is not provided for an encrypted key rrrsOPENSSH)rrrr)rKrXrDr.r.r/_fromString_PRIVATE_OPENSSHHs  zKey._fromString_PRIVATE_OPENSSHcCstt|dd}|ddksJi}|dddD]\}}tt|d||<q|dddkrG|j|d|d|d |d d S|ddd krZ|j|d |ddStd|dd)a Return a public key corresponding to this LSH public key string. The LSH public key string format is:: , ()+))> 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 rdrr public-keyNdsaygpqrbr`r^r_rsa-pkcs1-sha1nerurtunknown lsh key type ) rparserrrhNSrrr(rKrXsexpkdrr.r.r/_fromString_PUBLIC_LSHeszKey._fromString_PUBLIC_LSHcCs0t|}|ddks Ji}|dddD]\}}tt|d||<q|dddkrPt|dks, (, )+))> 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-keyrdNrr{rrrrxr| rsa-pkcs1rrrdryr) rrrrhrrrrr(rr.r.r/_fromString_PRIVATE_LSHs$ zKey._fromString_PRIVATE_LSHc Cst|\}}|dkr8t|\}}t|\}}t|\}}t|\}}t|\}}|j|||||dS|dkrqt|\}}t|\} }t|\} }t|\} }t|\}}t|\}}|j| || ||| dStd|)a Return a private key object corresponsing to the Secure Shell Key Agent v3 format. The SSH Key Agent v3 format for a RSA key is:: string 'ssh-rsa' integer e integer d integer n integer u integer p integer q The SSH Key Agent v3 format for a DSA key is:: string 'ssh-dss' integer p integer q integer g integer y integer x @type data: L{bytes} @param data: The key data. @return: A new key. @rtype: L{twisted.conch.ssh.keys.Key} @raises BadKeyError: if the key type (the first string) is unknown r[r|rZrurtrzr^r_rr)rrgrhrrr() rKrXrrr^r_r`rbr}rtrzrurr.r.r/_fromString_AGENTV3s"zKey._fromString_AGENTV3cCs|ds |dr dS|drdS|drdS|dr!d S|d s0|d s0|d rPt|\}}d }|rH|d7}t|\}}|s;|dkrNdSdSdS)z Guess the type of key in data. The types map to _fromString_* methods. @type data: L{bytes} @param data: The key data. sssh- ecdsa-sha2-public_opensshs -----BEGINprivate_openssh{ public_lsh( private_lshsssh-s ecdsa-s ssh-ed25519rrdr\agentv3rqN)rrrgrh)rKrXignoredrscountr.r.r/rSs0    zKey._guessStringTypec Csntj||d}|dur|t}||Stj|||t||t||t|||d} | t}||S)a Build a key from RSA numerical components. @type n: L{int} @param n: The 'n' RSA variable. @type e: L{int} @param e: The 'e' RSA variable. @type d: L{int} or L{None} @param d: The 'd' RSA variable (optional for a public key). @type p: L{int} or L{None} @param p: The 'p' RSA variable (optional for a public key). @type q: L{int} or L{None} @param q: The 'q' RSA variable (optional for a public key). @type u: L{int} or L{None} @param u: The 'u' RSA variable. Ignored, as its value is determined by p and q. @rtype: L{Key} @return: An RSA key constructed from the values as given. rNr) rrirjr r rsa_crt_dmp1 rsa_crt_dmq1 rsa_crt_iqmpr) rKrurtrzr^r_r publicNumbers keyObjectprivateNumbersr.r.r/rs      zKey._fromRSAComponentsc CsXtj|tj|||dd}|dur|t}||Stj||d}|t}||S)a Build a key from DSA numerical components. @type y: L{int} @param y: The 'y' DSA variable. @type p: L{int} @param p: The 'p' DSA variable. @type q: L{int} @param q: The 'q' DSA variable. @type g: L{int} @param g: The 'g' DSA variable. @type x: L{int} or L{None} @param x: The 'x' DSA variable (optional for a public key) @rtype: L{Key} @return: A DSA key constructed from the values as given. r]raNr)r rkrlrjr rr) rKrbr^r_r`r}rrrr.r.r/r)s  zKey._fromDSAComponentscCsRtj||t|d}|dur|t}||Stj||d}|t}||S)a Build a key from EC components. @param x: The affine x component of the public point used for verifying. @type x: L{int} @param y: The affine y component of the public point used for verifying. @type y: L{int} @param curve: NIST name of elliptic curve. @type curve: L{bytes} @param privateValue: The private value. @type privateValue: L{int} r}rbrN) private_valuer)r EllipticCurvePublicNumbersrmrjr EllipticCurvePrivateNumbersr)rKr}rbrrrrrr.r.r/_fromECComponentsLs   zKey._fromECComponentscCs>|durtjt||}||St|t|t}||S)aa Build a key from an EC encoded point. @param encodedPoint: The public point encoded as in SEC 1 v2.0 section 2.3.3. @type encodedPoint: L{bytes} @param curve: NIST name of elliptic curve. @type curve: L{bytes} @param privateValue: The private value. @type privateValue: L{int} N)r rnrormderive_private_keyr )rKrrrrr.r.r/rls zKey._fromECEncodedPointcCs0|durtj|}||Stj|}||S)aBuild 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} N)rEd25519PublicKeyfrom_public_bytesEd25519PrivateKeyfrom_private_bytes)rKrvrrr.r.r/rps   zKey._fromEd25519ComponentscCs ||_dS)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)selfrr.r.r/__init__s z Key.__init__otherreturncCs.t|tr||ko||kStS)zN Return True if other represents an object with the same key. )r>rFrMrXNotImplemented)r&r(r.r.r/__eq__s  z Key.__eq__c Cs|dkrO|}|dd}|r d|ddd}n d|ddd}t|D]\}}|dkr@|d |7}q0|d |d |7}q0|d Sd t||r[dp\d|fg}t|D]T\}}|d|d|dkr|nt |dd}|r|dd}|dd}d} t |D] } | t | dd} qt |dkr| dd} |d| |sqk|dd|d<d |S)z@ Return a pretty representation of this object. ECrrPz z<%s %s (%s bits)z Public Keyz Private Keyzattr :Ed25519r\02xr >)rMrXrisPublicsorteditemsrsizeappendrMPrrrr) r&rXroutrvrbymor;r.r.r/__repr__sD  "      z Key.__repr__cCst|jtjtjtjtj fS)zl Check if this instance is a public key. @return: C{True} if this is a public key. ) r>r%r RSAPublicKeyr DSAPublicKeyr rnrr!r&r.r.r/r6sz Key.isPubliccCs|r|St|jS)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. )r6rFr%rjrDr.r.r/publics z Key.publiccCsb|tjurttt|S|tjur*tdddt t |DSt d|)aO The fingerprint of a public key consists of the output of the message-digest algorithm in the specified format. Supported formats include L{FingerprintFormats.MD5_HEX} and L{FingerprintFormats.SHA256_BASE64} The input to the algorithm is the public key data as specified by [RFC4253]. The output of sha256[RFC4634] algorithm is presented to the user in the form of base64 encoded sha256 hashes. Example: C{US5jTUa0kgX5ZxdqaGF0yGRu8EgKXHNmoT8jHKo1StM=} The output of the MD5[RFC1321](default) algorithm is presented to the user as a sequence of 16 octets printed as hexadecimal with lowercase letters and separated by colons. Example: C{c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87} @param format: Format for fingerprint generation. Consists hash function and representation format. Default is L{FingerprintFormats.MD5_HEX} @since: 8.2 @return: the user presentation of this L{Key}'s fingerprint, as a string. @rtype: L{str} :cSsg|]}t|qSr.)binasciihexlifyr:r}r.r.r/ sz#Key.fingerprint..z Unsupported fingerprint format: ) r3r5rrrrqrr4rrrr2)r&formatr.r.r/ fingerprints  zKey.fingerprintcCspt|jtjtjfr dSt|jtjtjfrdSt|jtj tj fr$dSt|jt j t j fr0dStd|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. RSADSAr,r0zunknown type of object: )r>r%rrB RSAPrivateKeyr rC DSAPrivateKeyr rnEllipticCurvePrivateKeyrr!r# RuntimeErrorrDr.r.r/rM!szKey.typecCs8|dkrdt|jjjdSdddd|S)aK Get the type of the object we wrap as defined in the SSH protocol, defined in RFC 4253, Section 6.6. Currently this can only be b'ssh-rsa', b'ssh-dss' or b'ecdsa-sha2-[identifier]'. identifier is the standard NIST curve name @return: The key type format. @rtype: L{bytes} r,r r~rZr[re)rMrNr0)rMrr%rrrBrDr.r.r/sshType8s z Key.sshTypecCs<|jdurdS|dkr|jjjS|dkrdS|jjS)zv Return the size of the object we wrap. @return: The size of the key. @rtype: L{int} Nrr,r0)r%rMrkey_sizerDr.r.r/r9Ns    zKey.sizec Cst|jtjr|j}|j|jdSt|jtjr5|j}|jj|jj|j |j |j t |j |j dSt|jt jrO|j}|j|jj|jj |jj dSt|jt jro|j}|j|jj|jjj|jjj |jjj dSt|jtjr|j}|j|j|dSt|jtjr|j}|jj|jj|j|dSt|jtjrd|jtjjtjjiSt|jtj r|j!tjjtjj|j"tjjtj#jt$dSt%d |j) z_ Return the values of the public key as a dictionary. @rtype: L{dict} rr r)r}rbr`r^r_r)r}rbrrrv)rvrzUnexpected key type: )&r>r%rrBrrurtrOprivate_numbersrzr^r_rr rCrbrcr`rPr}r rnrSrQrrr! public_bytesr EncodingRaw PublicFormatr#rj private_bytes PrivateFormat NoEncryptionrR)r&numbersr.r.r/rX]st          zKey.datacCs|}|}|dkrtdt|dt|dS|dkrDtdt|dt|dt|d t|d S|d krx|jjjd d }t|dt|dddtdt |d|t |d |S|dkrtdt|dSt 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} rMrZrtrurNr[r^r_r`rbr,rrNr}r0rervunknown key type: ) rMrXrrr;r%rrUrrr()r&rMrX byteLengthr.r.r/rqs@ &      zKey.blobcCs|}|}|dkrCt|d|d}tdt|dt|dt|dt|t|dt|dS|dkrotd t|dt|dt|d t|d t|d S|d kr|j t j j t j j}t|dt|dddt|t|dS|dkrtdt|dt|d|dStd|)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 rMr^r_rZrurtrzrNr[r`rbr}r,rr`Nrr0rervrrb)rMrXrrrrr;r%rjrWr rXX962rZUncompressedPointr()r&rMrXrencPubr.r.r/ privateBlobsh)               zKey.privateBlobextracommentrDcCs|durtjdtdd|r|}n|}t|tr|d}t|}t|d| d}|dur9t d|||||dS) 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) stacklevelrP _toString_rb)subtyperirD) warningswarnDeprecationWarningr6r>r?rBrErTrUr()r&rMrhrlrirDrYr.r.r/toString8s -  z Key.toStringcCsn|dkr|s d}|jtjjtjjd|St|  dd}|s)d}| d|d|S)a Return a public OpenSSH key string. See _fromString_PUBLIC_OPENSSH for the string format. @type comment: L{bytes} or L{None} @param comment: A comment to include with the key, or L{None} to omit the comment. r,rr ) rMr%rWr rXOpenSSHrZrrrqreplacerS)r&rirr.r.r/_toPublicOpenSSHzs  zKey._toPublicOpenSSHcs|r%tj}d}d}|jd}d}|}t|} d} t| td| } nd}d}d}d} td } | | | t|p>d} d }t | |r\|d 7}| t |d @f7} t | |sI|rt || ||d}t||d |t||||td}|| |}n| }dt|t|t| tdd t|t|}t|dddgfddtd t dDdg}d|dS)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. rrrrdrrrr\rrdNrrrqs#-----BEGIN OPENSSH PRIVATE KEY-----cg|] }||dqS@r.rrr.r/rJz,Key._toPrivateOpenSSH_v1..rys!-----END OPENSSH PRIVATE KEY-----)rr block_sizer secureRandomrrrpackrgrrrrrrrr encryptorrrrqrrsrr)r&rirDr cipherNamekdfNamerrrrrrcheckrpadByteencKeyrrrqrr.rzr/_toPrivateOpenSSH_v1sl         zKey._toPrivateOpenSSH_v1c sl|dkr|s t}nt|}|jtjjtjj |S|dkr(t d| }d d| ddfg}|dkrm|d |d }}t||}d |d |d |d|||d|d|d|d|f }nd |d |d |d|d|df}t} tt|D] \} } | | t| qt | } |rtd} d ddt| D}| d}|d|d|dt|| }t||| }||dd}dt| d}| t|f|7} t t!"|t#$| t%d&}|'| |(} t)| *dd|fddt+d tdD7}|d d| ddfd |S) a, Return a private OpenSSH key string, in the old PEM-based format. See _fromPrivateOpenSSH_PEM for the string format. @type passphrase: L{bytes} or L{None} @param passphrase: The passphrase to encrypt the key with, or L{None} if it is not encrypted. r,r0zBcannot serialize Ed25519 key to OpenSSH PEM format; use v1 insteadrs -----BEGIN r~s PRIVATE KEY-----rMr^r_rrurtrzrdr`rbr}rr2cSsg|]}t|dqS)02X)rrIr.r.r/rJ sz-Key._toPrivateOpenSSH_PEM..rsDEK-Info: DES-EDE3-CBC,rqNrrcrwrxr.rrzr.r/rJr{rys -----END ),rMr r]BestAvailableEncryptionr%r[rXPEMr\TraditionalOpenSSLrrXrrBrrrSequencezip itertoolsrsetComponentByPositionInteger berEncoderrr}rr:rrrrrrrrrr rrrrrsr)r&rDrrXrr^r_robjData asn1Sequenceindexrasn1DatarhexivrrrpadLenr.rzr/_toPrivateOpenSSH_PEMsv      $     " zKey._toPrivateOpenSSH_PEMcCsh|r |j|dS|dks|dur|dkr|j||dS|dus'|dkr-|j|dStd|) 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} )riv1Nr0)rirDrrCzunknown subtype )r6rtrMrrr)r&rlrirDr.r.r/_toString_OPENSSH!s  zKey._toString_OPENSSHcKs|}|}|r|dkr2tdddt|dddgdt|d ddgggg}nE|d krptdd d t|d ddgdt|dddgdt|dddgdt|dddgggg}ntd|dt| dddS|dkr|d |d}}t ||}tdddt|dddgdt|d ddgdt|dddgd t|ddgdt|ddgdt|d|dddgdt|d|dddgd t|ddgg ggS|d krLtdd d t|d ddgdt|dddgdt|dddgdt|dddgd!t|d"ddggggStd|d#)$z Return a public or private LSH key. See _fromString_PUBLIC_LSH and _fromString_PRIVATE_LSH for the key formats. @rtype: L{bytes} rMrrrrur\NrrtrNrrr^rr_rr`rrbrrrqr}rrrrzardbcrr}') rXrMr6rr~rr;r(rrsrr)r&kwargsrXrMrr^r_rr.r.r/ _toString_LSH>sv      zKey._toString_LSHcKs|}|sJ|dkr#|d|d|d|d|d|df}n|dkr:|d|d|d |d |d f}t|d ttj|Sd S)z Return a private Secure Shell Agent v3 key. See _fromString_AGENTV3 for the key format. @rtype: L{bytes} rMrtrzrurr^r_rNr`rbr}rN) rXr6rMrrrSrmapr;)r&rrXvaluesr.r.r/_toString_AGENTV3s  " zKey._toString_AGENTV3cCs|}|dkr|j|tt}t|}n|dkr;|j|t}t |\}}tt |dt |d}n|dkr| }|dkrLt }n |dkrUt }nt}|j|t|} t | \}}t |} t |} t| dturt| d} n| d} | d@rd | } t| dturt| d} n| d} | d@rd | } tt| t| }n |d krt|j|}t||S) z Sign some data with this key. SECSH-TRANS RFC 4253 Section 6.6. @type data: L{bytes} @param data: The data to sign. @rtype: L{bytes} @return: A signature for the given data. rMrNr,rTrr0)rMr%signrPKCS1v15r SHA1rrr#rr9SHA256SHA384SHA512r ECDSAr?rrS)r&rXrrsigretrsrhashSize signaturerGsbrcompscompr.r.r/rsB      zKey.signcCst|dkrdt|}}nt|\}}||krdS|}|dkrA|j}|s1|}t|d|t t f}n|dkrxt|d}t |ddd }t |ddd } t|| }|j}|sp|}||t f}nk|d krt|d}t|d \} } } t | d }t | d } t|| }|j}|s|}|} | d krt }n | d krt }nt }||t|f}n|dkr|j}|s|}t|d|f}z|j|WdStyYdSw)a Verify a signature using this key. @type signature: L{bytes} @param signature: The signature to verify. @type data: L{bytes} @param data: The signed data. @rtype: L{bool} @return: C{True} if the signature is valid. (r[FrMrrNNrbigr,rRrTrr0T)rrrrgrSrMr%r6rjrrr rr from_bytesr$r9rrrr rverifyr)r&rrX signatureTyperrrargsconcatenatedSignaturerrrstrsstrrsrrr.r.r/rsf           z Key.verify)NN)NNNNr)NNN)1r*r+r,r- classmethodrOrIrwrrrrrrrr rSrrrrrpr'objectboolr+r?rAr6rEr3r4rLrMrSr9rXrqrgr"rprtrrrrrrrr.r.r.r/rFs|  ' 8 J  X }   % 0  , "     ,(L<S  <  > OR BrFcCs|jdd|s(tjd|td}|jtjj tj j t d}| ||d}tj|dtd}t|WdS1sGwYdS) 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_exponentrUr)encodingrKencryption_algorithmrGN)passwordr)parentmakedirsexistsrgenerate_private_keyr r[r rXrr\rr] setContentrHrrJrF)locationr privateKeypemkeyFiler.r.r/_getPersistentRSAKey5s"   $r)r)Pr-rGrrr8rmbase64rrrhashlibrrr cryptographyrcryptography.exceptionsrcryptography.hazmat.backendsr cryptography.hazmat.primitivesr r )cryptography.hazmat.primitives.asymmetricr r rrr&cryptography.hazmat.primitives.ciphersrrr,cryptography.hazmat.primitives.serializationrrpyasn1.codec.berrrrr pyasn1.errorr pyasn1.typertwisted.conch.sshrrtwisted.conch.ssh.commonrtwisted.pythonrtwisted.python.compatrrtwisted.python.constantsr r!twisted.python.deprecater"/cryptography.hazmat.primitives.asymmetric.utilsr#r$ ImportErrorr%r& SECP256R1 SECP384R1 SECP521R1rmr Exceptionr(r1r2r3r6rErFrr.r.r.r/sv          0