3 l�_�T�@s�ddlmZmZmZddlZddlZddlZddlZddlZddl m Z ddl m Z ddl mZddlmZmZmZmZddlmZmZmZddlmZmZmZmZydd lmZd Z Wn e!k r�d Z d d �ZYnXyddl"m#Z$Wn"e!k �r ddl"m%Z$YnXdZ&dZ'dZ(dZ)dZ*dZ+dZ,ej-d�Z.dZ/dZ0dZ1dZ2dZ3dZ4dZ5dZ6ej-e0d e1ej7�Z8e9e:e;d!dS���Zdfej=d"ej?dfd#�Z@e)e*e+d$�ZAejBd%�ZCejBd&�ZDd'd(�ZEe0d)e1d)fd*d+�ZFd,d-�ZGd.d/�ZHd0d1�ZId2d3�ZJd4d5�ZKd6d7�ZLd8d9�ZMd:d;�ZNGdd?�d?eO�ZQGd@dA�dAeO�ZRGdBdC�dCeO�ZSGdDdE�dEeO�ZTe'eQ�e(eR�e&eT�e)eSdFejU��e*eSdGejV��e+eSdHejW��iZXdIdJ�ZYdTdKdL�ZZdUdMdN�Z[dVdOdP�Z\dQdR�Z]dS)W�)�absolute_import�division�print_functionN)�utils)�UnsupportedAlgorithm)� _get_backend)�dsa�ec�ed25519�rsa)�Cipher� algorithms�modes)�Encoding� NoEncryption� PrivateFormat� PublicFormat)�kdfTFcOs td��dS)NzNeed bcrypt module)r)�args�kwargs�r�/usr/lib64/python3.6/ssh.py� _bcrypt_kdf!sr)� encodebytes)� encodestrings ssh-ed25519sssh-rsasssh-dsssecdsa-sha2-nistp256secdsa-sha2-nistp384secdsa-sha2-nistp521s[email protected]\A(\S+)[ \t]+(\S+)sopenssh-key-v1s#-----BEGIN OPENSSH PRIVATE KEY-----s!-----END OPENSSH PRIVATE KEY-----sbcryptsnones aes256-ctr��Hs(.*?)�� )s aes256-ctrs aes256-cbc)Z secp256r1Z secp384r1Z secp521r1s>Is>QcCs(|j}|jtkrtd|j��t|jS)z3Return SSH key_type and curve_name for private key.z)Unsupported curve for ssh private key: %r)�curve�name�_ECDSA_KEY_TYPE� ValueError)� public_keyrrrr�_ecdsa_key_typeSs   r$� cCsdj|t|�|g�S)N�)�join�_base64_encode)�data�prefix�suffixrrr�_ssh_pem_encode]sr,cCs"| st|�|dkrtd��dS)zRequire data to be full blocksrzCorrupt data: missing paddingN)�lenr")r)Z block_lenrrr�_check_block_sizeasr.cCs|r td��dS)z!All data should have been parsed.zCorrupt data: unparsed dataN)r")r)rrr� _check_emptygsr/c CsT|s td��t|\}}}}t|||||d�} t|| d|��|| |d��|�S)z$Generate key + iv and return cipher.zKey is password-protected.TN)r"� _SSH_CIPHERSrr ) � ciphername�password�salt�rounds�backendZalgoZkey_len�modeZiv_lenZseedrrr� _init_cipherms r7cCs6t|�dkrtd��tj|dd��d|dd�fS)ZUint32�z Invalid dataNr)r-r"�_U32�unpack)r)rrr�_get_u32ws r;cCs6t|�dkrtd��tj|dd��d|dd�fS)ZUint64�z Invalid dataNr)r-r"�_U64r:)r)rrr�_get_u64~s r>cCs8t|�\}}|t|�kr td��|d|�||d�fS)zBytes with u32 length prefixz Invalid dataN)r;r-r")r)�nrrr� _get_sshstr�s  r@cCs8t|�\}}|r(tj|d�dkr(td��tj|d�|fS)z Big integer.r�z Invalid dataZbig)r@�six� indexbytesr"rZint_from_bytes)r)�valrrr� _get_mpint�s rEcCs4|dkrtd��|sdS|j�dd}tj||�S)z!Storage format for signed bigint.rznegative mpint not allowedr&r<)r"� bit_lengthrZ int_to_bytes)rD�nbytesrrr� _to_mpint�s rHc@sTeZdZdZddd�Zdd�Zdd�Zd d �Zd d �Zd d�Z ddd�Z dd�Z dS)� _FragListz,Build recursive structure without data copy.NcCsg|_|r|jj|�dS)N)�flist�extend)�selfZinitrrr�__init__�sz_FragList.__init__cCs|jj|�dS)zAdd plain bytesN)rJ�append)rLrDrrr�put_raw�sz_FragList.put_rawcCs|jjtj|��dS)zBig-endian uint32N)rJrNr9�pack)rLrDrrr�put_u32�sz_FragList.put_u32cCsLt|tttf�r,|jt|��|jj|�n|j|j��|jj |j�dS)zBytes prefixed with u32 lengthN) � isinstance�bytes� memoryview� bytearrayrQr-rJrN�sizerK)rLrDrrr� put_sshstr�s z_FragList.put_sshstrcCs|jt|��dS)z*Big-endian bigint prefixed with u32 lengthN)rWrH)rLrDrrr� put_mpint�sz_FragList.put_mpintcCsttt|j��S)zCurrent number of bytes)�sum�mapr-rJ)rLrrrrV�sz_FragList.sizercCs6x0|jD]&}t|�}|||}}||||�<qW|S)zWrite into bytearray)rJr-)rLZdstbuf�posZfragZflen�startrrr�render�s  z_FragList.rendercCs"tt|j���}|j|�|j�S)zReturn as bytes)rTrUrVr]�tobytes)rL�bufrrrr^�s z_FragList.tobytes)N)r) �__name__� __module__� __qualname__�__doc__rMrOrQrWrXrVr]r^rrrrrI�s   rIc@s8eZdZdZdd�Zdd�Zdd�Zdd �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_public�s  z_SSHFormatRSA.get_publiccCs0|j|�\\}}}tj||�}|j|�}||fS)zMake RSA public key from data.)rfr �RSAPublicNumbersr#)rL�key_typer)r5rer?�public_numbersr#rrr� load_public�s  z_SSHFormatRSA.load_publiccCs�t|�\}}t|�\}}t|�\}}t|�\}}t|�\}}t|�\} }||f|kr\td��tj||�} 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?re�d�iqmp�p�qZdmp1Zdmq1ri�private_numbersrkrrr� load_private�s           z_SSHFormatRSA.load_privatecCs$|j�}|j|j�|j|j�dS)zWrite RSA public keyN)rirXrer?)rLr#�f_pubZpubnrrr� encode_public�s z_SSHFormatRSA.encode_publiccCsZ|j�}|j}|j|j�|j|j�|j|j�|j|j�|j|j�|j|j�dS)zWrite RSA private keyN) rqrirXr?rermrnrorp)rLrk�f_privrqrirrr�encode_private�s     z_SSHFormatRSA.encode_privateN) r`rarbrcrfrjrrrtrvrrrrrd�s rdc@s@eZdZdZdd�Zdd�Zdd�Zdd �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)rorp�g�yrrrrfs     z_SSHFormatDSA.get_publicc CsL|j|�\\}}}}}tj|||�}tj||�} |j| �| j|�} | |fS)zMake DSA public key from data.)rfr�DSAParameterNumbers�DSAPublicNumbers� _validater#) rLrhr)r5rorprxry�parameter_numbersrir#rrrrjs    z_SSHFormatDSA.load_publicc Cs||j|�\\}}}}}t|�\}}||||f|kr:td��tj|||�} tj|| �} |j| �tj|| �} | j|�} | |fS)zMake DSA private key from data.z Corrupt data: dsa field mismatch) rfrEr"rrzr{r|ZDSAPrivateNumbersrk) rLr)rlr5rorprxry�xr}rirqrkrrrrr's     z_SSHFormatDSA.load_privatecCsL|j�}|j}|j|�|j|j�|j|j�|j|j�|j|j�dS)zWrite DSA public keyN)rir}r|rXrorprxry)rLr#rsrir}rrrrt5s    z_SSHFormatDSA.encode_publiccCs$|j|j�|�|j|j�j�dS)zWrite DSA private keyN)rtr#rXrqr~)rLrkrurrrrv@sz_SSHFormatDSA.encode_privatecCs |j}|jj�dkrtd��dS)Niz#SSH supports only 1024 bit DSA keys)r}rorFr")rLrir}rrrr|Esz_SSHFormatDSA._validateN) r`rarbrcrfrjrrrtrvr|rrrrrw s  rwc@s@eZdZdZdd�Zdd�Zdd�Zdd �Zd d �Zd d �Z dS)�_SSHFormatECDSAz�Format for ECDSA keys. Public: str curve bytes point Private: str curve bytes point mpint secret cCs||_||_dS)N)�ssh_curve_namer)rLr�rrrrrMWsz_SSHFormatECDSA.__init__cCsNt|�\}}t|�\}}||jkr*td��tj|d�dkrBtd��||f|fS)zECDSA public fieldszCurve name mismatchrr8zNeed uncompressed point)r@r�r"rBrC�NotImplementedError)rLr)r�pointrrrrf[s   z_SSHFormatECDSA.get_publiccCs.|j|�\\}}}tjj|j|j��}||fS)z Make ECDSA public key from data.)rfr �EllipticCurvePublicKeyZfrom_encoded_pointrr^)rLrhr)r5� curve_namer�r#rrrrjesz_SSHFormatECDSA.load_publiccCsJ|j|�\\}}}t|�\}}||f|kr2td��tj||j|�}||fS)z!Make ECDSA private key from data.z"Corrupt data: ecdsa field mismatch)rfrEr"r Zderive_private_keyr)rLr)rlr5r�r��secretrkrrrrrms   z_SSHFormatECDSA.load_privatecCs*|jtjtj�}|j|j�|j|�dS)zWrite ECDSA public keyN)� public_bytesrZX962rZUncompressedPointrWr�)rLr#rsr�rrrrtws  z_SSHFormatECDSA.encode_publiccCs,|j�}|j�}|j||�|j|j�dS)zWrite ECDSA private keyN)r#rqrtrXZ private_value)rLrkrur#rqrrrrvs z_SSHFormatECDSA.encode_privateN) r`rarbrcrMrfrjrrrtrvrrrrrKs   rc@s8eZdZdZdd�Zdd�Zdd�Zdd �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)r�rrrrf�s z_SSHFormatEd25519.get_publiccCs(|j|�\\}}tjj|j��}||fS)z"Make Ed25519 public key from data.)rfr �Ed25519PublicKeyZfrom_public_bytesr^)rLrhr)r5r�r#rrrrj�s z_SSHFormatEd25519.load_publicc Csb|j|�\\}}t|�\}}|dd�}|dd�}||ksF|f|krNtd��tjj|�}||fS)z#Make Ed25519 private key from data.Nrz$Corrupt data: ed25519 field mismatch)rfr@r"r �Ed25519PrivateKeyZfrom_private_bytes) rLr)rlr5r�Zkeypairr�Zpoint2rkrrrrr�s    z_SSHFormatEd25519.load_privatecCs|jtjtj�}|j|�dS)zWrite Ed25519 public keyN)r�r�RawrrW)rLr#rs�raw_public_keyrrrrt�s z_SSHFormatEd25519.encode_publiccCsR|j�}|jtjtjt��}|jtjtj�}t||g�}|j ||�|j |�dS)zWrite Ed25519 private keyN) r#Z private_bytesrr�rrr�rrIrtrW)rLrkrur#Zraw_private_keyr�Z f_keypairrrrrv�s   z _SSHFormatEd25519.encode_privateN) r`rarbrcrfrjrrrtrvrrrrr��s  r�snistp256snistp384snistp521cCs6t|t�st|�j�}|tkr&t|Std|��dS)z"Return valid format or throw errorzUnsupported key type: %rN)rRrSrTr^� _KEY_FORMATSr)rhrrr�_lookup_kformat�s   r�cCsRtjd|�t|�}|dk r(tjd|�tj|�}|s>td��|jd�}|jd�}t j t |�||��}|j t �sztd��t |�tt �d�}t|�\}}t|�\}}t|�\}}t|�\} }| dkr�td��t|�\} }t| �\} } t| �} | j| �\} } t| �t|�\}}t|�||fttfk�r�|j�}|tk�rHtd|��|tk�r^td|��t|d }t||�t|�\}}t|�\}}t|�t|||j�||�}t |j�j|��}nd }t||�t|�\}}t|�\}}||k�r�td ��t|�\}}|| k�rtd ��| j|| |�\}}t|�\}}|tdt|��k�rNtd ��|S)z.Load private key from OpenSSH custom encoding.r)Nr2zNot OpenSSH private key formatrzOnly one key supportedzUnsupported cipher: %rzUnsupported KDF: %r�r<zCorrupt data: broken checksumzCorrupt data: key type mismatchzCorrupt data: invalid padding)r�_check_bytesliker� _check_bytes�_PEM_RC�searchr"r\�end�binascii� a2b_base64rT� startswith� _SK_MAGICr-r@r;r�rfr/�_NONEr^r0r�_BCRYPTr.r7Z decryptor�updaterr�_PADDING)r)r2r5�mZp1Zp2r1�kdfnameZ kdfoptions�nkeysZpubdataZ pub_key_type�kformatrlZedata�blklenr3Zkbufr4�ciphZck1Zck2rhrk�commentrrr�load_ssh_private_key�sl                            r�cCs>|dk rtjd|�|r,t|�tkr,td��t|tj�rFt|j ��}n>t|t j �rXt }n,t|t j�rjt}nt|tj�r|t}ntd��t|�}t�}|r�t}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*|||�||d��t+|d|��}t'|�|||�<|S) z3Serialize private key with OpenSSH custom encoding.Nr2zNPasswords longer than 72 bytes are not supported by OpenSSH private key formatzUnsupported key typer�rr<rr8r&),rr�r-� _MAX_PASSWORDr"rRr ZEllipticCurvePrivateKeyr$r#r Z RSAPrivateKey�_SSH_RSArZ DSAPrivateKey�_SSH_DSAr r�� _SSH_ED25519r�rI�_DEFAULT_CIPHERr0r��_DEFAULT_ROUNDS�os�urandomrWrQrr7r�rtrvrOr�rVr�rTrUr]Z encryptorZ update_intor,)rkr2rhr�Z f_kdfoptionsr1r�r�r4r3r5r�r�Zcheckvalr�Z f_public_keyZ f_secretsZf_mainZslenZmlenr_ZofsZtxtrrr�serialize_ssh_private_keyst                         r�c Cs�t|�}tjd|�tj|�}|s*td��|jd�}}|jd�}d}t|tt� d�krrd}|dtt� �}t |�}yt t j |��}Wn"t t jfk r�td��YnXt|�\}}||kr�td��|r�t|�\} }|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 formatr�FNTzInvalid key format)rrr��_SSH_PUBKEY_RC�matchr"�group� _CERT_SUFFIXr-r�rTr�r�� TypeError�Errorr@rjr>r;r/)r)r5r�rhZ orig_key_typeZkey_bodyZ with_certr�Zinner_key_typeZnoncer#�serialZcctypeZkey_idZ principalsZ valid_afterZ valid_beforeZ crit_options� extensionsZreservedZsig_keyZ signaturerrr�load_ssh_public_keymsH                r�cCs�t|tj�rt|�}n>t|tj�r(t}n,t|tj�r:t }nt|t j �rLt }nt d��t|�}t�}|j|�|j||�tj|j��j�}dj|d|g�S)z&One-line public key format for OpenSSHzUnsupported key typer&� )rRr r�r$r Z RSAPublicKeyr�rZ DSAPublicKeyr�r r�r�r"r�rIrWrtr�Z b2a_base64r^�stripr')r#rhr�rsZpubrrr�serialize_ssh_public_key�s       r��)N)N)N)^Z __future__rrrr�r��re�structrBZ cryptographyrZcryptography.exceptionsrZcryptography.hazmat.backendsrZ)cryptography.hazmat.primitives.asymmetricrr r r Z&cryptography.hazmat.primitives.ciphersr r rZ,cryptography.hazmat.primitives.serializationrrrrZbcryptrrZ_bcrypt_supported� ImportError�base64rr(rr�r�r�Z_ECDSA_NISTP256Z_ECDSA_NISTP384Z_ECDSA_NISTP521r��compiler�r�Z _SK_STARTZ_SK_ENDr�r�r�r�r��DOTALLr�rTrU�ranger�ZAESZCTRZCBCr0r!�Structr9r=r$r,r.r/r7r;r>r@rErH�objectrIrdrwrr�Z SECP256R1Z SECP384R1Z SECP521R1r�r�r�r�r�r�rrrr�s�          0>>=: J O +