o
    bW                     @   sT  d dl Z d dlZd dlZd dl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 d dlmZ d dlmZmZmZmZ d dlmZmZmZ d d	lmZmZmZmZ z
d d
lmZ  dZ!W n e"y|   dZ!	d]de#de#de$de$de%de#fddZ Y nw dZ&dZ'dZ(dZ)dZ*dZ+dZ,e-dZ.dZ/dZ0dZ1d Z2d!Z3d"Z4d#Z5d$Z6e-e0d% e1 ej7Z8e9e:e;d&d'Z<ej=d(ej>d#fej=d(ej?d#fd)Z@e)e*e+d*ZAeBd+ZCeBd,ZDd-d. ZEe0d/ e1d/ fd0d1ZFd2d3 ZGd4d5 ZHd6d7 ZId8d9 ZJd:d; ZKd<d= ZLd>d? ZMd@dA ZNG dBdC dCeOZPG dDdE dEeOZQG dFdG dGeOZRG dHdI dIeOZSG dJdK dKeOZTe'eQ e(eR e&eT e)eSdLeU e*eSdMeV e+eSdNeW iZXdOdP ZYejZej[ej\ej]ej^f Z_	d^dQe#dej`e# dRej`e de_fdSdTZa	d^dUe_dej`e# de#fdVdWZbejZejcejdejeejff Zg	d^dQe#dRej`e degfdXdYZhdZegde#fd[d\ZidS )_    N)encodebytes)utilsUnsupportedAlgorithm)_get_backend)Backend)dsaeced25519rsa)Cipher
algorithmsmodes)EncodingNoEncryptionPrivateFormatPublicFormat)kdfTFpasswordsaltdesired_key_bytesroundsignore_few_roundsreturnc                 C   s   t d)NzNeed bcrypt moduler   )r   r   r   r   r    r   o/var/www/secure340b-portal/env/lib/python3.10/site-packages/cryptography/hazmat/primitives/serialization/ssh.py_bcrypt_kdf!   s   r   s   ssh-ed25519s   ssh-rsas   ssh-dsss   ecdsa-sha2-nistp256s   ecdsa-sha2-nistp384s   ecdsa-sha2-nistp521s   -cert-v01@openssh.coms   \A(\S+)[ \t]+(\S+)s   openssh-key-v1 s#   -----BEGIN OPENSSH PRIVATE KEY-----s!   -----END OPENSSH PRIVATE KEY-----s   bcrypts   none
   aes256-ctr   H   s   (.*?)          )r   s
   aes256-cbc)Z	secp256r1Z	secp384r1Z	secp521r1s   >Is   >Qc                 C   s(   | j }|jtvrtd|j t|j S )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_keyr#   r   r   r   _ecdsa_key_typeT   s   

r(      
c                 C   s   d |t| |gS )N    )join_base64_encode)dataprefixsuffixr   r   r   _ssh_pem_encode^   s   r0   c                 C   s    | r
t | | dkrtddS )zRequire data to be full blocksr   zCorrupt data: missing paddingN)lenr&   )r-   Z	block_lenr   r   r   _check_block_sizeb   s   r2   c                 C   s   | rt ddS )z!All data should have been parsed.zCorrupt data: unparsed dataN)r&   r-   r   r   r   _check_emptyh   s   r4   c           
      C   sT   |st dt|  \}}}}t|||| |d}	t||	d| ||	|d |S )z$Generate key + iv and return cipher.zKey is password-protected.TN)r&   _SSH_CIPHERSr   r   )

ciphernamer   r   r   backendalgoZkey_lenmodeZiv_lenseedr   r   r   _init_ciphern   s
   $r;   c                 C   6   t | dk r
tdt| dd d | dd fS )ZUint32   Invalid dataNr   )r1   r&   _U32unpackr3   r   r   r   _get_u32x      "rA   c                 C   r<   )ZUint64   r>   Nr   )r1   r&   _U64r@   r3   r   r   r   _get_u64   rB   rE   c                 C   s8   t | \}} |t| krtd| d| | |d fS )zBytes with u32 length prefixr>   N)rA   r1   r&   )r-   nr   r   r   _get_sshstr   s   rG   c                 C   s4   t | \}} |r|d dkrtdt|d| fS )zBig integer.r      r>   big)rG   r&   int
from_bytes)r-   valr   r   r   
_get_mpint   s   rM   c                 C   s4   | dk rt d| sdS |  d d }t| |S )z!Storage format for signed bigint.r   znegative mpint not allowedr*   rC   )r&   
bit_lengthr   Zint_to_bytes)rL   nbytesr   r   r   	_to_mpint   s   rP   c                   @   sT   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dddZ
dd ZdS )	_FragListz,Build recursive structure without data copy.Nc                 C   s   g | _ |r| j | d S d S N)flistextend)selfinitr   r   r   __init__   s   z_FragList.__init__c                 C   s   | j | dS )zAdd plain bytesN)rS   appendrU   rL   r   r   r   put_raw      z_FragList.put_rawc                 C   s   | j t| dS )zBig-endian uint32N)rS   rX   r?   packrY   r   r   r   put_u32   s   z_FragList.put_u32c                 C   sN   t |tttfr| t| | j| dS | |  | j	|j dS )zBytes prefixed with u32 lengthN)

isinstancebytes
memoryview	bytearrayr]   r1   rS   rX   sizerT   rY   r   r   r   
put_sshstr   s
   z_FragList.put_sshstrc                 C   s   |  t| dS )z*Big-endian bigint prefixed with u32 lengthN)rc   rP   rY   r   r   r   	put_mpint   s   z_FragList.put_mpintc                 C   s   t tt| jS )zCurrent number of bytes)summapr1   rS   )rU   r   r   r   rb      r[   z_FragList.sizer   c                 C   s2   | j D ]}t|}||| }}||||< q|S )zWrite into bytearray)rS   r1   )rU   ZdstbufposfragZflenstartr   r   r   render   s
   
z_FragList.renderc                 C   s"   t t|  }| | | S )zReturn as bytes)r`   ra   rb   rj   tobytes)rU   bufr   r   r   rk      s   
z_FragList.tobytesrR   )r   )__name__
__module____qualname____doc__rW   rZ   r]   rc   rd   rb   rj   rk   r   r   r   r   rQ      s    
	
rQ   c                   @   8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )_SSHFormatRSAzhFormat for RSA keys.

    Public:
        mpint e, n
    Private:
        mpint n, e, d, iqmp, p, q
    c                 C   s$   t |\}}t |\}}||f|fS )zRSA public fieldsrM   )rU   r-   erF   r   r   r   
get_public   s   z_SSHFormatRSA.get_publicc                 C   s0   |  |\\}}}t||}||}||fS )zMake RSA public key from data.)ru   r   RSAPublicNumbersr'   )rU   key_typer-   r7   rt   rF   public_numbersr'   r   r   r   load_public   s   
z_SSHFormatRSA.load_publicc              	   C   s   t |\}}t |\}}t |\}}t |\}}t |\}}t |\}	}||f|kr.tdt||}
t||	}t||}t||	||
|||}||}||fS )zMake RSA private key from data.z Corrupt data: rsa field mismatch)rM   r&   r   Zrsa_crt_dmp1Zrsa_crt_dmq1rv   ZRSAPrivateNumbersprivate_key)rU   r-   	pubfieldsr7   rF   rt   diqmppqZdmp1Zdmq1rx   private_numbersrz   r   r   r   load_private   s    
z_SSHFormatRSA.load_privatec                 C   s$   |  }||j ||j dS )zWrite RSA public keyN)rx   rd   rt   rF   )rU   r'   f_pubZpubnr   r   r   encode_public   s   z_SSHFormatRSA.encode_publicc                 C   sZ   |  }|j}||j ||j ||j ||j ||j ||j dS )zWrite RSA private keyN)	r   rx   rd   rF   rt   r|   r}   r~   r   )rU   rz   f_privr   rx   r   r   r   encode_private   s   z_SSHFormatRSA.encode_privateN	rm   rn   ro   rp   ru   ry   r   r   r   r   r   r   r   rr      s    rr   c                   @   @   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )_SSHFormatDSAzhFormat for DSA keys.

    Public:
        mpint p, q, g, y
    Private:
        mpint p, q, g, y, x
    c                 C   s@   t |\}}t |\}}t |\}}t |\}}||||f|fS )zDSA public fieldsrs   )rU   r-   r~   r   gyr   r   r   ru     s
   z_SSHFormatDSA.get_publicc                 C   sL   |  |\\}}}}}t|||}t||}	| |	 |	|}
|
|fS )zMake DSA public key from data.)ru   r   DSAParameterNumbersDSAPublicNumbers	_validater'   )rU   rw   r-   r7   r~   r   r   r   parameter_numbersrx   r'   r   r   r   ry     s   

z_SSHFormatDSA.load_publicc                 C   s|   |  |\\}}}}}t|\}}||||f|krtdt|||}	t||	}
| |
 t||
}||}||fS )zMake DSA private key from data.z Corrupt data: dsa field mismatch)	ru   rM   r&   r   r   r   r   ZDSAPrivateNumbersrz   )rU   r-   r{   r7   r~   r   r   r   xr   rx   r   rz   r   r   r   r   (  s   

z_SSHFormatDSA.load_privatec                 C   sL   |  }|j}| | ||j ||j ||j ||j dS )zWrite DSA public keyN)rx   r   r   rd   r~   r   r   r   )rU   r'   r   rx   r   r   r   r   r   6  s   
z_SSHFormatDSA.encode_publicc                 C   s$   |  | | || j dS )zWrite DSA private keyN)r   r'   rd   r   r   )rU   rz   r   r   r   r   r   A  s   z_SSHFormatDSA.encode_privatec                 C   s    |j }|j dkrtdd S )Ni   z#SSH supports only 1024 bit DSA keys)r   r~   rN   r&   )rU   rx   r   r   r   r   r   F  s   z_SSHFormatDSA._validateN)
rm   rn   ro   rp   ru   ry   r   r   r   r   r   r   r   r   r     s    	r   c                   @   r   )_SSHFormatECDSAzFormat for ECDSA keys.

    Public:
        str curve
        bytes point
    Private:
        str curve
        bytes point
        mpint secret
    c                 C   s   || _ || _d S rR   )ssh_curve_namer#   )rU   r   r#   r   r   r   rW   X  s   
z_SSHFormatECDSA.__init__c                 C   sJ   t |\}}t |\}}|| jkrtd|d dkrtd||f|fS )zECDSA public fieldszCurve name mismatchr   r=   zNeed uncompressed point)rG   r   r&   NotImplementedError)rU   r-   r#   pointr   r   r   ru   \  s   
z_SSHFormatECDSA.get_publicc                 C   s.   |  |\\}}}tj| j| }||fS )z Make ECDSA public key from data.)ru   r	   EllipticCurvePublicKeyZfrom_encoded_pointr#   rk   )rU   rw   r-   r7   
curve_namer   r'   r   r   r   ry   f  s
   
z_SSHFormatECDSA.load_publicc                 C   sJ   |  |\\}}}t|\}}||f|krtdt|| j|}||fS )z!Make ECDSA private key from data.z"Corrupt data: ecdsa field mismatch)ru   rM   r&   r	   Zderive_private_keyr#   )rU   r-   r{   r7   r   r   secretrz   r   r   r   r   n  s   z_SSHFormatECDSA.load_privatec                 C   s*   | tjtj}|| j || dS )zWrite ECDSA public keyN)public_bytesr   ZX962r   ZUncompressedPointrc   r   )rU   r'   r   r   r   r   r   r   x  s
   z_SSHFormatECDSA.encode_publicc                 C   s,   |  }| }| || ||j dS )zWrite ECDSA private keyN)r'   r   r   rd   Zprivate_value)rU   rz   r   r'   r   r   r   r   r     s   z_SSHFormatECDSA.encode_privateN)
rm   rn   ro   rp   rW   ru   ry   r   r   r   r   r   r   r   r   L  s    

r   c                   @   rq   )_SSHFormatEd25519z~Format for Ed25519 keys.

    Public:
        bytes point
    Private:
        bytes point
        bytes secret_and_point
    c                 C   s   t |\}}|f|fS )zEd25519 public fields)rG   )rU   r-   r   r   r   r   ru     s   
z_SSHFormatEd25519.get_publicc                 C   s(   |  |\\}}tj| }||fS )z"Make Ed25519 public key from data.)ru   r
   Ed25519PublicKeyZfrom_public_bytesrk   )rU   rw   r-   r7   r   r'   r   r   r   ry     s
   z_SSHFormatEd25519.load_publicc           	      C   sb   |  |\\}}t|\}}|dd }|dd }||ks#|f|kr'tdtj|}||fS )z#Make Ed25519 private key from data.Nr"   z$Corrupt data: ed25519 field mismatch)ru   rG   r&   r
   Ed25519PrivateKeyZfrom_private_bytes)	rU   r-   r{   r7   r   Zkeypairr   Zpoint2rz   r   r   r   r     s   z_SSHFormatEd25519.load_privatec                 C   s   | tjtj}|| dS )zWrite Ed25519 public keyN)r   r   Rawr   rc   )rU   r'   r   raw_public_keyr   r   r   r     s   z_SSHFormatEd25519.encode_publicc                 C   sR   |  }|tjtjt }|tjtj}t||g}| 	|| |
| dS )zWrite Ed25519 private keyN)r'   Zprivate_bytesr   r   r   r   r   r   rQ   r   rc   )rU   rz   r   r'   Zraw_private_keyr   Z	f_keypairr   r   r   r     s   z _SSHFormatEd25519.encode_privateNr   r   r   r   r   r     s    	r   s   nistp256s   nistp384s   nistp521c                 C   s2   t | tst|  } | tv rt|  S td|  )z"Return valid format or throw errorzUnsupported key type: %r)r^   r_   r`   rk   _KEY_FORMATSr   )rw   r   r   r   _lookup_kformat  s
   
r   r-   r7   c                 C   sJ  t d|  t|}|durt d| t| }|std|d}|d}t	
t| || } | ts=tdt| ttd } t| \}} t| \}} t| \}} t| \}	} |	dkrgtdt| \}
} t|
\}}
t|}||
\}}
t|
 t| \}} t|  ||fttfkr| }|tvrtd| |tkrtd| t| d	 }t|| t|\}}t|\}}t| t||| ||}t| |}nd
}t|| t|\}}t|\}}||krtdt|\}}||krtd||||\}}t|\}}|tdt| kr#td|S )z.Load private key from OpenSSH custom encoding.r-   Nr   zNot OpenSSH private key formatr    zOnly one key supportedzUnsupported cipher: %rzUnsupported KDF: %r   rC   zCorrupt data: broken checksumzCorrupt data: key type mismatchzCorrupt data: invalid padding)r   _check_bytesliker   _check_bytes_PEM_RCsearchr&   ri   endbinascii
a2b_base64r`   
startswith	_SK_MAGICr1   rG   rA   r   ru   r4   _NONErk   r5   r   _BCRYPTr2   r;   Z	decryptorupdater   _PADDING)r-   r   r7   mp1p2r6   kdfnameZ
kdfoptionsnkeysZpubdataZpub_key_typekformatr{   Zedatablklenr   Zkbufr   ciphZck1Zck2rw   rz   commentr   r   r   load_ssh_private_key  sn   






r   rz   c                 C   s>  |dur
t d| |rt|tkrtdt| tjr#t| 	 }nt| t
jr,t}nt| tjr5t}nt| tjr>t}ntdt|}t }|rst}t| d }t}t}td}	||	 || td}
t|||	||
}nt }}d}d}d}td	}d
}t }|| | | 	 | t||g}|| |!| | || |"t#d||$ |    t }|"t% || || || || || || |$ }|$ }t&t'|| }|(| || }|dur|) *||| ||d  t+|d| }t'||||< |S )z3Serialize private key with OpenSSH custom encoding.Nr   zNPasswords longer than 72 bytes are not supported by OpenSSH private key formatUnsupported key typer   r   rC   r    r=   r*   ),r   r   r1   _MAX_PASSWORDr&   r^   r	   EllipticCurvePrivateKeyr(   r'   r   RSAPrivateKey_SSH_RSAr   DSAPrivateKey_SSH_DSAr
   r   _SSH_ED25519r   rQ   _DEFAULT_CIPHERr5   r   _DEFAULT_ROUNDSosurandomrc   r]   r   r;   r   r   r   rZ   r   rb   r   r`   ra   rj   Z	encryptorZupdate_intor0   )rz   r   rw   r   Zf_kdfoptionsr6   r   r   r   r   r7   r   r   Zcheckvalr   Zf_public_keyZ	f_secretsZf_mainslenmlenrl   Zofstxtr   r   r   serialize_ssh_private_key+  sv   















 r   c              	   C   s|  t |}td|  t| }|std|d }}|d}d}t|tt d kr9d}|dtt  }t	|}z	t
t|} W n ttjfyT   tdw t| \}} ||krctd|rkt| \}	} ||| |\}
} |rt| \}} t| \}} t| \}} t| \}} t| \}} t| \}} t| \}} t| \}} t| \}} t| \}} t| \}} t|  |
S )	z-Load public key from OpenSSH one-line format.r-   zInvalid line formatr       FNTzInvalid key format)r   r   r   _SSH_PUBKEY_RCmatchr&   group_CERT_SUFFIXr1   r   r`   r   r   	TypeErrorErrorrG   ry   rE   rA   r4   )r-   r7   r   rw   Zorig_key_typeZkey_bodyZ	with_certr   Zinner_key_typenoncer'   serialZcctypeZkey_idZ
principalsZvalid_afterZvalid_beforeZcrit_options
extensionsreservedZsig_key	signaturer   r   r   load_ssh_public_key  sJ   

r   r'   c                 C   s   t | tjrt| }nt | tjrt}nt | tjrt	}nt | t
jr&t}ntdt|}t }|| || | t|  }d|d|gS )z&One-line public key format for OpenSSHr   r*       )r^   r	   r   r(   r   RSAPublicKeyr   r   DSAPublicKeyr   r
   r   r   r&   r   rQ   rc   r   r   
b2a_base64rk   stripr+   )r'   rw   r   r   Zpubr   r   r   serialize_ssh_public_key  s   

r   )FrR   )jr   r   restructtypingbase64r   r,   Zcryptographyr   Zcryptography.exceptionsr   Zcryptography.hazmat.backendsr   Z'cryptography.hazmat.backends.interfacesr   Z)cryptography.hazmat.primitives.asymmetricr   r	   r
   r   Z&cryptography.hazmat.primitives.ciphersr   r   r   Z,cryptography.hazmat.primitives.serializationr   r   r   r   Zbcryptr   r   Z_bcrypt_supportedImportErrorr_   rJ   boolr   r   r   Z_ECDSA_NISTP256Z_ECDSA_NISTP384Z_ECDSA_NISTP521r   compiler   r   Z	_SK_STARTZ_SK_ENDr   r   r   r   r   DOTALLr   r`   ra   ranger   ZAESZCTRZCBCr5   r%   Structr?   rD   r(   r0   r2   r4   r;   rA   rE   rG   rM   rP   objectrQ   rr   r   r   r   Z	SECP256R1Z	SECP384R1Z	SECP521R1r   r   Unionr   r   r   r   Z_SSH_PRIVATE_KEY_TYPESOptionalr   r   r   r   r   r   Z_SSH_PUBLIC_KEY_TYPESr   r   r   r   r   r   <module>   s   





0>>=:
	
P
U	
-