3 l_T@sddlmZmZmZddlZddlZddlZddlZddlZddl m Z ddl m Z ddl mZddlmZmZmZmZddlmZmZmZddlmZmZmZmZydd lmZd Z Wn e!k rd Z d d ZYnXyddl"m#Z$Wn"e!k r ddl"m%Z$YnXdZ&dZ'dZ(dZ)dZ*dZ+dZ,ej-dZ.dZ/dZ0dZ1dZ2dZ3dZ4dZ5dZ6ej-e0d e1ej7Z8e9e:e;d!dSZdfej=d"ej?dfd#Z@e)e*e+d$ZAejBd%ZCejBd&ZDd'd(ZEe0d)e1d)fd*d+ZFd,d-ZGd.d/ZHd0d1ZId2d3ZJd4d5ZKd6d7ZLd8d9ZMd:d;ZNGdd?d?eOZQGd@dAdAeOZRGdBdCdCeOZSGdDdEdEeOZTe'eQe(eRe&eTe)eSdFejUe*eSdGejVe+eSdHejWiZXdIdJZYdTdKdLZZdUdMdNZ[dVdOdPZ\dQdRZ]dS)W)absolute_importdivisionprint_functionN)utils)UnsupportedAlgorithm) _get_backend)dsaeced25519rsa)Cipher algorithmsmodes)Encoding NoEncryption PrivateFormat PublicFormat)kdfTFcOs tddS)NzNeed bcrypt module)r)argskwargsr/usr/lib64/python3.6/ssh.py _bcrypt_kdf!sr) encodebytes) encodestrings ssh-ed25519sssh-rsasssh-dsssecdsa-sha2-nistp256secdsa-sha2-nistp384secdsa-sha2-nistp521s-cert-v01@openssh.coms\A(\S+)[ \t]+(\S+)sopenssh-key-v1s#-----BEGIN OPENSSH PRIVATE KEY-----s!-----END OPENSSH PRIVATE KEY-----sbcryptsnones aes256-ctrHs(.*?) )s aes256-ctrs aes256-cbc)Z secp256r1Z secp384r1Z secp521r1s>Is>QcCs(|j}|jtkrtd|jt|jS)z3Return SSH key_type and curve_name for private key.z)Unsupported curve for ssh private key: %r)curvename_ECDSA_KEY_TYPE ValueError) public_keyrrrr_ecdsa_key_typeSs   r$ cCsdj|t||gS)N)join_base64_encode)dataprefixsuffixrrr_ssh_pem_encode]sr,cCs"| st||dkrtddS)zRequire data to be full blocksrzCorrupt data: missing paddingN)lenr")r)Z block_lenrrr_check_block_sizeasr.cCs|r tddS)z!All data should have been parsed.zCorrupt data: unparsed dataN)r")r)rrr _check_emptygsr/c CsT|s tdt|\}}}}t|||||d} t|| d||| |d|S)z$Generate key + iv and return cipher.zKey is password-protected.TN)r" _SSH_CIPHERSrr ) ciphernamepasswordsaltroundsbackendZalgoZkey_lenmodeZiv_lenZseedrrr _init_cipherms r7cCs6t|dkrtdtj|ddd|ddfS)ZUint32z Invalid dataNr)r-r"_U32unpack)r)rrr_get_u32ws r;cCs6t|dkrtdtj|ddd|ddfS)ZUint64z Invalid dataNr)r-r"_U64r:)r)rrr_get_u64~s r>cCs8t|\}}|t|kr td|d|||dfS)zBytes with u32 length prefixz Invalid dataN)r;r-r")r)nrrr _get_sshstrs  r@cCs8t|\}}|r(tj|ddkr(tdtj|d|fS)z Big integer.rz Invalid dataZbig)r@six indexbytesr"rZint_from_bytes)r)valrrr _get_mpints rEcCs4|dkrtd|sdS|jdd}tj||S)z!Storage format for signed bigint.rznegative mpint not allowedr&r<)r" bit_lengthrZ int_to_bytes)rDnbytesrrr _to_mpints rHc@sTeZdZdZdddZddZddZd d Zd d Zd dZ dddZ ddZ dS) _FragListz,Build recursive structure without data copy.NcCsg|_|r|jj|dS)N)flistextend)selfZinitrrr__init__sz_FragList.__init__cCs|jj|dS)zAdd plain bytesN)rJappend)rLrDrrrput_rawsz_FragList.put_rawcCs|jjtj|dS)zBig-endian uint32N)rJrNr9pack)rLrDrrrput_u32sz_FragList.put_u32cCsLt|tttfr,|jt||jj|n|j|j|jj |jdS)zBytes prefixed with u32 lengthN) isinstancebytes memoryview bytearrayrQr-rJrNsizerK)rLrDrrr put_sshstrs z_FragList.put_sshstrcCs|jt|dS)z*Big-endian bigint prefixed with u32 lengthN)rWrH)rLrDrrr put_mpintsz_FragList.put_mpintcCsttt|jS)zCurrent number of bytes)summapr-rJ)rLrrrrVsz_FragList.sizercCs6x0|jD]&}t|}|||}}||||<qW|S)zWrite into bytearray)rJr-)rLZdstbufposZfragZflenstartrrrrenders  z_FragList.rendercCs"tt|j}|j||jS)zReturn as bytes)rTrUrVr]tobytes)rLbufrrrr^s z_FragList.tobytes)N)r) __name__ __module__ __qualname____doc__rMrOrQrWrXrVr]r^rrrrrIs   rIc@s8eZdZdZddZddZddZdd Zd d Zd S) _SSHFormatRSAzhFormat for RSA keys. Public: mpint e, n Private: mpint n, e, d, iqmp, p, q cCs$t|\}}t|\}}||f|fS)zRSA public fields)rE)rLr)er?rrr get_publics  z_SSHFormatRSA.get_publiccCs0|j|\\}}}tj||}|j|}||fS)zMake RSA public key from data.)rfr RSAPublicNumbersr#)rLkey_typer)r5rer?public_numbersr#rrr load_publics  z_SSHFormatRSA.load_publiccCst|\}}t|\}}t|\}}t|\}}t|\}}t|\} }||f|kr\tdtj||} tj|| } tj||} tj|| || | || } | j|}||fS)zMake RSA private key from data.z Corrupt data: rsa field mismatch)rEr"r Z rsa_crt_dmp1Z rsa_crt_dmq1rgZRSAPrivateNumbers private_key)rLr) pubfieldsr5r?rediqmppqZdmp1Zdmq1riprivate_numbersrkrrr load_privates           z_SSHFormatRSA.load_privatecCs$|j}|j|j|j|jdS)zWrite RSA public keyN)rirXrer?)rLr#f_pubZpubnrrr encode_publics z_SSHFormatRSA.encode_publiccCsZ|j}|j}|j|j|j|j|j|j|j|j|j|j|j|jdS)zWrite RSA private keyN) rqrirXr?rermrnrorp)rLrkf_privrqrirrrencode_privates     z_SSHFormatRSA.encode_privateN) r`rarbrcrfrjrrrtrvrrrrrds rdc@s@eZdZdZddZddZddZdd Zd d Zd d Z dS) _SSHFormatDSAzhFormat for DSA keys. Public: mpint p, q, g, y Private: mpint p, q, g, y, x cCs@t|\}}t|\}}t|\}}t|\}}||||f|fS)zDSA public fields)rE)rLr)rorpgyrrrrfs     z_SSHFormatDSA.get_publicc CsL|j|\\}}}}}tj|||}tj||} |j| | j|} | |fS)zMake DSA public key from data.)rfrDSAParameterNumbersDSAPublicNumbers _validater#) rLrhr)r5rorprxryparameter_numbersrir#rrrrjs    z_SSHFormatDSA.load_publicc Cs||j|\\}}}}}t|\}}||||f|kr:tdtj|||} tj|| } |j| tj|| } | j|} | |fS)zMake DSA private key from data.z Corrupt data: dsa field mismatch) rfrEr"rrzr{r|ZDSAPrivateNumbersrk) rLr)rlr5rorprxryxr}rirqrkrrrrr's     z_SSHFormatDSA.load_privatecCsL|j}|j}|j||j|j|j|j|j|j|j|jdS)zWrite DSA public keyN)rir}r|rXrorprxry)rLr#rsrir}rrrrt5s    z_SSHFormatDSA.encode_publiccCs$|j|j||j|jjdS)zWrite DSA private keyN)rtr#rXrqr~)rLrkrurrrrv@sz_SSHFormatDSA.encode_privatecCs |j}|jjdkrtddS)Niz#SSH supports only 1024 bit DSA keys)r}rorFr")rLrir}rrrr|Esz_SSHFormatDSA._validateN) r`rarbrcrfrjrrrtrvr|rrrrrw s  rwc@s@eZdZdZddZddZddZdd Zd d Zd d Z dS)_SSHFormatECDSAzFormat for ECDSA keys. Public: str curve bytes point Private: str curve bytes point mpint secret cCs||_||_dS)N)ssh_curve_namer)rLrrrrrrMWsz_SSHFormatECDSA.__init__cCsNt|\}}t|\}}||jkr*tdtj|ddkrBtd||f|fS)zECDSA public fieldszCurve name mismatchrr8zNeed uncompressed point)r@rr"rBrCNotImplementedError)rLr)rpointrrrrf[s   z_SSHFormatECDSA.get_publiccCs.|j|\\}}}tjj|j|j}||fS)z Make ECDSA public key from data.)rfr EllipticCurvePublicKeyZfrom_encoded_pointrr^)rLrhr)r5 curve_namerr#rrrrjesz_SSHFormatECDSA.load_publiccCsJ|j|\\}}}t|\}}||f|kr2tdtj||j|}||fS)z!Make ECDSA private key from data.z"Corrupt data: ecdsa field mismatch)rfrEr"r Zderive_private_keyr)rLr)rlr5rrsecretrkrrrrrms   z_SSHFormatECDSA.load_privatecCs*|jtjtj}|j|j|j|dS)zWrite ECDSA public keyN) public_bytesrZX962rZUncompressedPointrWr)rLr#rsrrrrrtws  z_SSHFormatECDSA.encode_publiccCs,|j}|j}|j|||j|jdS)zWrite ECDSA private keyN)r#rqrtrXZ private_value)rLrkrur#rqrrrrvs z_SSHFormatECDSA.encode_privateN) r`rarbrcrMrfrjrrrtrvrrrrrKs   rc@s8eZdZdZddZddZddZdd Zd d Zd S) _SSHFormatEd25519z~Format for Ed25519 keys. Public: bytes point Private: bytes point bytes secret_and_point cCst|\}}|f|fS)zEd25519 public fields)r@)rLr)rrrrrfs z_SSHFormatEd25519.get_publiccCs(|j|\\}}tjj|j}||fS)z"Make Ed25519 public key from data.)rfr Ed25519PublicKeyZfrom_public_bytesr^)rLrhr)r5rr#rrrrjs z_SSHFormatEd25519.load_publicc Csb|j|\\}}t|\}}|dd}|dd}||ksF|f|krNtdtjj|}||fS)z#Make Ed25519 private key from data.Nrz$Corrupt data: ed25519 field mismatch)rfr@r"r Ed25519PrivateKeyZfrom_private_bytes) rLr)rlr5rZkeypairrZpoint2rkrrrrrs    z_SSHFormatEd25519.load_privatecCs|jtjtj}|j|dS)zWrite Ed25519 public keyN)rrRawrrW)rLr#rsraw_public_keyrrrrts z_SSHFormatEd25519.encode_publiccCsR|j}|jtjtjt}|jtjtj}t||g}|j |||j |dS)zWrite Ed25519 private keyN) r#Z private_bytesrrrrrrrIrtrW)rLrkrur#Zraw_private_keyrZ f_keypairrrrrvs   z _SSHFormatEd25519.encode_privateN) r`rarbrcrfrjrrrtrvrrrrrs  rsnistp256snistp384snistp521cCs6t|tst|j}|tkr&t|Std|dS)z"Return valid format or throw errorzUnsupported key type: %rN)rRrSrTr^ _KEY_FORMATSr)rhrrr_lookup_kformats   rcCsRtjd|t|}|dk r(tjd|tj|}|s>td|jd}|jd}t j t |||}|j t sztdt |tt d}t|\}}t|\}}t|\}}t|\} }| dkrtdt|\} }t| \} } t| } | j| \} } t| t|\}}t|||fttfkr|j}|tkrHtd||tkr^td|t|d }t||t|\}}t|\}}t|t|||j||}t |jj|}nd }t||t|\}}t|\}}||krtd t|\}}|| krtd | j|| |\}}t|\}}|tdt|krNtd |S)z.Load private key from OpenSSH custom encoding.r)Nr2zNot OpenSSH private key formatrzOnly one key supportedzUnsupported cipher: %rzUnsupported KDF: %rr<zCorrupt data: broken checksumzCorrupt data: key type mismatchzCorrupt data: invalid padding)r_check_bytesliker _check_bytes_PEM_RCsearchr"r\endbinascii a2b_base64rT startswith _SK_MAGICr-r@r;rrfr/_NONEr^r0r_BCRYPTr.r7Z decryptorupdaterr_PADDING)r)r2r5mZp1Zp2r1kdfnameZ kdfoptionsnkeysZpubdataZ pub_key_typekformatrlZedatablklenr3Zkbufr4ciphZck1Zck2rhrkcommentrrrload_ssh_private_keysl                            rcCs>|dk rtjd||r,t|tkr,tdt|tjrFt|j }n>t|t j rXt }n,t|t jrjt}nt|tjr|t}ntdt|}t}|rt}t|d}t}t}tjd} |j| |j|td} t||| || } nt}}d}d} d} tjd } d }t}|j||j |j |t| | g}|j||j!|||j||j"t#d||j$|t}|j"t%|j||j||j||j| |j||j||j$}|j$}t&t'||}|j(|||}| dk r| j)j*|||||dt+|d|}t'||||<|S) z3Serialize private key with OpenSSH custom encoding.Nr2zNPasswords longer than 72 bytes are not supported by OpenSSH private key formatzUnsupported key typerrr<rr8r&),rrr- _MAX_PASSWORDr"rRr ZEllipticCurvePrivateKeyr$r#r Z RSAPrivateKey_SSH_RSArZ DSAPrivateKey_SSH_DSAr r _SSH_ED25519rrI_DEFAULT_CIPHERr0r_DEFAULT_ROUNDSosurandomrWrQrr7rrtrvrOrrVrrTrUr]Z encryptorZ update_intor,)rkr2rhrZ f_kdfoptionsr1rrr4r3r5rrZcheckvalrZ f_public_keyZ f_secretsZf_mainZslenZmlenr_ZofsZtxtrrrserialize_ssh_private_keyst                         rc Cst|}tjd|tj|}|s*td|jd}}|jd}d}t|tt dkrrd}|dtt }t |}yt t j |}Wn"t t jfk rtdYnXt|\}}||krtd|rt|\} }|j|||\} }|rxt|\} }t|\} }t|\} }t|\}}t|\}}t|\}}t|\}}t|\}}t|\}}t|\}}t|\}}t|| S) z-Load public key from OpenSSH one-line format.r)zInvalid line formatrFNTzInvalid key format)rrr_SSH_PUBKEY_RCmatchr"group _CERT_SUFFIXr-rrTrr TypeErrorErrorr@rjr>r;r/)r)r5rrhZ orig_key_typeZkey_bodyZ with_certrZinner_key_typeZnoncer#serialZcctypeZkey_idZ principalsZ valid_afterZ valid_beforeZ crit_options extensionsZreservedZsig_keyZ signaturerrrload_ssh_public_keymsH                rcCst|tjrt|}n>t|tjr(t}n,t|tjr:t }nt|t j rLt }nt dt|}t}|j||j||tj|jj}dj|d|gS)z&One-line public key format for OpenSSHzUnsupported key typer& )rRr rr$r Z RSAPublicKeyrrZ DSAPublicKeyrr rrr"rrIrWrtrZ b2a_base64r^stripr')r#rhrrsZpubrrrserialize_ssh_public_keys       r)N)N)N)^Z __future__rrrrrrestructrBZ cryptographyrZcryptography.exceptionsrZcryptography.hazmat.backendsrZ)cryptography.hazmat.primitives.asymmetricrr r r Z&cryptography.hazmat.primitives.ciphersr r rZ,cryptography.hazmat.primitives.serializationrrrrZbcryptrrZ_bcrypt_supported ImportErrorbase64rr(rrrrZ_ECDSA_NISTP256Z_ECDSA_NISTP384Z_ECDSA_NISTP521rcompilerrZ _SK_STARTZ_SK_ENDrrrrrDOTALLrrTrUrangerZAESZCTRZCBCr0r!Structr9r=r$r,r.r/r7r;r>r@rErHobjectrIrdrwrrZ SECP256R1Z SECP384R1Z SECP521R1rrrrrrrrrrs          0>>=: J O +