a
    còfËÊ  ã                   @  sÊ  U d dl mZ d dlZ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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"m#Z#m$Z$m%Z% zd dl&m'Z( dZ)W n2 e*�y    dZ)d”dddddddœdd„Z(Y n0 dZ+dZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3dZ4dZ5e 6d¡Z7d Z8d!Z9d"Z:d#Z;d$Z<d%Z=d&Z>e 6e9d' e: ej?¡Z@eAeBeCd(d)ƒƒƒZDeG d*d+„ d+ƒƒZEeEejFd,ejGd&d&ddd-�eEejFd,ejHd&d&ddd-�eEejFd,ejId&d.d&dd-�d/œZJd0eKd1< e.e/e0d2œZLd3dd4œd5d6„ZMd7dd8œd9d:„ZNe9d; e:d; fddddd<œd=d>„ZOddd?d@œdAdB„ZPdd?dCœdDdE„ZQddFdddGdHœdIdJ„ZRdKdLdCœdMdN„ZSdKdLdCœdOdP„ZTdKdQdCœdRdS„ZUdKdLdCœdTdU„ZVdddVœdWdX„ZWG dYdZ„ dZƒZXG d[d\„ d\ƒZYG d]d^„ d^ƒZZG d_d`„ d`ƒZ[G dadb„ dbƒZ\dQdcœddde„Z]G dfdg„ dgƒZ^G dhdi„ diƒZ_e,eYƒ e-eZƒ e+e\ƒ e.e[dje `¡ ƒe/e[dke a¡ ƒe0e[dle b¡ ƒe2e^ƒ e3e_ƒ iZcddmœdndo„Zdejeejfejgejhejif Zjd•ddFdpdqdrœdsdt„Zkdqdduddvœdwdx„Zlejeejmejnejoejpf Zqejeejmejnejpf ZrG dydz„ dzejsƒZtG d{d|„ d|ƒZud}d~dœd€d�„Zvd–dd‚dCœdƒd„„Zwdd‚dCœd…d†„ZxdKd‡dˆœd‰dŠ„Zyd—ddpd‹dŒœd�dŽ„Zzd‹dd8œd�d�„Z{ejeejfejgejif Z|d‘Z}G d’d“„ d“ƒZ~dS )˜é    )ÚannotationsN)Úencodebytes)Ú	dataclass)Úutils©ÚUnsupportedAlgorithm)Úhashes)ÚdsaÚecÚed25519ÚpaddingÚrsa)ÚAEADDecryptionContextÚCipherÚ
algorithmsÚmodes)ÚEncodingÚKeySerializationEncryptionÚNoEncryptionÚPrivateFormatÚPublicFormatÚ_KeySerializationEncryption)ÚkdfTFÚbytesÚintÚbool)ÚpasswordÚsaltÚdesired_key_bytesÚroundsÚignore_few_roundsÚreturnc                 C  s   t dƒ‚d S )NzNeed bcrypt moduler   )r   r   r   r   r    © r"   úm/home/httpd/docs/test/DocsMgr/lib/python3.9/site-packages/cryptography/hazmat/primitives/serialization/ssh.pyÚ_bcrypt_kdf1   s    r$   s   ssh-ed25519s   ssh-rsas   ssh-dsss   ecdsa-sha2-nistp256s   ecdsa-sha2-nistp384s   ecdsa-sha2-nistp521s   -cert-v01@openssh.coms   sk-ssh-ed25519@openssh.coms"   sk-ecdsa-sha2-nistp256@openssh.coms   rsa-sha2-256s   rsa-sha2-512s   \A(\S+)[ \t]+(\S+)s   openssh-key-v1 s#   -----BEGIN OPENSSH PRIVATE KEY-----s!   -----END OPENSSH PRIVATE KEY-----s   bcrypts   noneó
   aes256-ctré   s   (.*?)é   é   c                   @  sF   e Zd ZU ded< ded< ded< ded< ded< d	ed
< ded< dS )Ú
_SSHCipherztype[algorithms.AES]Úalgr   Úkey_lenz3type[modes.CTR] | type[modes.CBC] | type[modes.GCM]ÚmodeÚ	block_lenÚiv_lenú
int | NoneÚtag_lenr   Úis_aeadN)Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r"   r"   r"   r#   r)   \   s   
r)   é    )r*   r+   r,   r-   r.   r0   r1   é   )r%   s
   aes256-cbcs   aes256-gcm@openssh.comzdict[bytes, _SSHCipher]Ú_SSH_CIPHERS)Z	secp256r1Z	secp384r1Z	secp521r1z&SSHPrivateKeyTypes | SSHPublicKeyTypes)Úkeyr!   c                 C  s„   t | tjƒrt|  ¡ ƒ}nft | tjƒr0t| ƒ}nPt | tjtjfƒrHt	}n8t | t
jt
jfƒr`t}n t | tjtjfƒrxt}ntdƒ‚|S )NúUnsupported key type)Ú
isinstancer
   ÚEllipticCurvePrivateKeyÚ_ecdsa_key_typeÚ
public_keyÚEllipticCurvePublicKeyr   ÚRSAPrivateKeyÚRSAPublicKeyÚ_SSH_RSAr	   ÚDSAPrivateKeyÚDSAPublicKeyÚ_SSH_DSAr   ÚEd25519PrivateKeyÚEd25519PublicKeyÚ_SSH_ED25519Ú
ValueError)r9   Úkey_typer"   r"   r#   Ú_get_ssh_key_typeŽ   s    
ÿrK   úec.EllipticCurvePublicKey©r>   r!   c                 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: )ÚcurveÚnameÚ_ECDSA_KEY_TYPErI   )r>   rN   r"   r"   r#   r=   ¡   s    

ÿr=   ó   
)ÚdataÚprefixÚsuffixr!   c                 C  s   d  |t| ƒ|g¡S )Nó    )ÚjoinÚ_base64_encode)rR   rS   rT   r"   r"   r#   Ú_ssh_pem_encode«   s    rX   ÚNone)rR   r-   r!   c                 C  s    | rt | ƒ| dkrtdƒ‚dS )zRequire data to be full blocksr   zCorrupt data: missing paddingN)ÚlenrI   )rR   r-   r"   r"   r#   Ú_check_block_size³   s    r[   ©rR   r!   c                 C  s   | rt dƒ‚dS )z!All data should have been parsed.zCorrupt data: unparsed dataN)rI   ©rR   r"   r"   r#   Ú_check_empty¹   s    r^   úbytes | Nonez)Cipher[modes.CBC | modes.CTR | modes.GCM])Ú
ciphernamer   r   r   r!   c                 C  sV   |st dƒ‚t|  }t|||j|j |dƒ}t| |d|j… ¡| ||jd… ¡ƒS )z$Generate key + iv and return cipher.zKey is password-protected.TN)rI   r8   r$   r+   r.   r   r*   r,   )r`   r   r   r   ÚciphÚseedr"   r"   r#   Ú_init_cipher¿   s    ÿþrc   Ú
memoryviewztuple[int, memoryview]c                 C  s6   t | ƒdk rtdƒ‚tj| dd… dd�| dd… fS )ZUint32é   úInvalid dataNÚbig©Ú	byteorder©rZ   rI   r   Ú
from_bytesr]   r"   r"   r#   Ú_get_u32Ó   s    rl   c                 C  s6   t | ƒdk rtdƒ‚tj| dd… dd�| dd… fS )ZUint64é   rf   Nrg   rh   rj   r]   r"   r"   r#   Ú_get_u64Ú   s    rn   ztuple[memoryview, memoryview]c                 C  s8   t | ƒ\}} |t| ƒkr tdƒ‚| d|… | |d… fS )zBytes with u32 length prefixrf   N)rl   rZ   rI   )rR   Únr"   r"   r#   Ú_get_sshstrá   s    rp   c                 C  s4   t | ƒ\}} |r$|d dkr$tdƒ‚t |d¡| fS )zBig integer.r   é   rf   rg   )rp   rI   r   rk   )rR   Úvalr"   r"   r#   Ú
_get_mpinté   s    rs   ©rr   r!   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 allowedrU   rm   )rI   Ú
bit_lengthr   Zint_to_bytes)rr   Únbytesr"   r"   r#   Ú	_to_mpintñ   s    rw   c                   @  s¬   e Zd ZU dZded< d"dddœdd	„Zd
ddœdd„Zdddœdd„Zdddœdd„Zdddœdd„Z	dddœdd„Z
ddœdd„Zd#ddddœdd„Zd
dœd d!„ZdS )$Ú	_FragListz,Build recursive structure without data copy.úlist[bytes]ÚflistNzlist[bytes] | NonerY   )Úinitr!   c                 C  s   g | _ |r| j  |¡ d S ©N)rz   Úextend)Úselfr{   r"   r"   r#   Ú__init__   s    z_FragList.__init__r   rt   c                 C  s   | j  |¡ dS )zAdd plain bytesN)rz   Úappend©r~   rr   r"   r"   r#   Úput_raw  s    z_FragList.put_rawr   c                 C  s   | j  |jddd�¡ dS )zBig-endian uint32re   rg   ©Úlengthri   N©rz   r€   Úto_bytesr�   r"   r"   r#   Úput_u32	  s    z_FragList.put_u32c                 C  s   | j  |jddd�¡ dS )zBig-endian uint64rm   rg   rƒ   Nr…   r�   r"   r"   r#   Úput_u64  s    z_FragList.put_u64zbytes | _FragListc                 C  sL   t |tttfƒr,|  t|ƒ¡ | j |¡ n|  | ¡ ¡ | j 	|j¡ dS )zBytes prefixed with u32 lengthN)
r;   r   rd   Ú	bytearrayr‡   rZ   rz   r€   Úsizer}   r�   r"   r"   r#   Ú
put_sshstr  s
    z_FragList.put_sshstrc                 C  s   |   t|ƒ¡ dS )z*Big-endian bigint prefixed with u32 lengthN)r‹   rw   r�   r"   r"   r#   Ú	put_mpint  s    z_FragList.put_mpint©r!   c                 C  s   t tt| jƒƒS )zCurrent number of bytes)ÚsumÚmaprZ   rz   ©r~   r"   r"   r#   rŠ     s    z_FragList.sizer   rd   )ÚdstbufÚposr!   c                 C  s2   | j D ]&}t|ƒ}|||  }}||||…< q|S )zWrite into bytearray)rz   rZ   )r~   r‘   r’   ÚfragZflenÚstartr"   r"   r#   Úrender"  s
    
z_FragList.renderc                 C  s"   t t|  ¡ ƒƒ}|  |¡ | ¡ S )zReturn as bytes)rd   r‰   rŠ   r•   Útobytes)r~   Úbufr"   r"   r#   r–   *  s    
z_FragList.tobytes)N)r   )r2   r3   r4   Ú__doc__r5   r   r‚   r‡   rˆ   r‹   rŒ   rŠ   r•   r–   r"   r"   r"   r#   rx   û   s   
	rx   c                   @  sd   e Zd ZdZdddœdd„Zdddœdd	„Zdd
dœdd„Zddddœdd„Zddddœdd„ZdS )Ú_SSHFormatRSAzhFormat for RSA keys.

    Public:
        mpint e, n
    Private:
        mpint n, e, d, iqmp, p, q
    rd   z"tuple[tuple[int, int], memoryview]r\   c                 C  s$   t |ƒ\}}t |ƒ\}}||f|fS )zRSA public fields©rs   )r~   rR   Úero   r"   r"   r#   Ú
get_public:  s    z_SSHFormatRSA.get_publicz#tuple[rsa.RSAPublicKey, memoryview]c                 C  s.   |   |¡\\}}}t ||¡}| ¡ }||fS )zMake RSA public key from data.)rœ   r   ÚRSAPublicNumbersr>   )r~   rR   r›   ro   Úpublic_numbersr>   r"   r"   r#   Úload_publicB  s    z_SSHFormatRSA.load_publicz$tuple[rsa.RSAPrivateKey, memoryview]c              	   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)rs   rI   r   Zrsa_crt_dmp1Zrsa_crt_dmq1r�   ZRSAPrivateNumbersÚprivate_key)r~   rR   Ú	pubfieldsro   r›   ÚdÚiqmpÚpÚqZdmp1Zdmq1rž   Úprivate_numbersr    r"   r"   r#   Úload_privateK  s     ÿz_SSHFormatRSA.load_privatezrsa.RSAPublicKeyrx   rY   ©r>   Úf_pubr!   c                 C  s$   |  ¡ }| |j¡ | |j¡ dS )zWrite RSA public keyN)rž   rŒ   r›   ro   )r~   r>   r©   Zpubnr"   r"   r#   Úencode_publica  s    z_SSHFormatRSA.encode_publiczrsa.RSAPrivateKey©r    Úf_privr!   c                 C  sZ   |  ¡ }|j}| |j¡ | |j¡ | |j¡ | |j¡ | |j¡ | |j¡ dS )zWrite RSA private keyN)	r¦   rž   rŒ   ro   r›   r¢   r£   r¤   r¥   )r~   r    r¬   r¦   rž   r"   r"   r#   Úencode_privatei  s    z_SSHFormatRSA.encode_privateN©	r2   r3   r4   r˜   rœ   rŸ   r§   rª   r­   r"   r"   r"   r#   r™   1  s   	r™   c                   @  st   e Zd ZdZdddœdd„Zdddœdd	„Zdd
dœdd„Zddddœdd„Zddddœdd„Zdddœdd„Z	dS )Ú_SSHFormatDSAzhFormat for DSA keys.

    Public:
        mpint p, q, g, y
    Private:
        mpint p, q, g, y, x
    rd   ztuple[tuple, memoryview]r\   c                 C  s@   t |ƒ\}}t |ƒ\}}t |ƒ\}}t |ƒ\}}||||f|fS )zDSA public fieldsrš   )r~   rR   r¤   r¥   ÚgÚyr"   r"   r#   rœ   ‚  s
    z_SSHFormatDSA.get_publicz#tuple[dsa.DSAPublicKey, memoryview]c           	      C  sJ   |   |¡\\}}}}}t |||¡}t ||¡}|  |¡ | ¡ }||fS )zMake DSA public key from data.)rœ   r	   ÚDSAParameterNumbersÚDSAPublicNumbersÚ	_validater>   )	r~   rR   r¤   r¥   r°   r±   Úparameter_numbersrž   r>   r"   r"   r#   rŸ   Š  s    
z_SSHFormatDSA.load_publicz$tuple[dsa.DSAPrivateKey, memoryview]c                 C  sz   |   |¡\\}}}}}t|ƒ\}}||||f|kr:tdƒ‚t |||¡}t ||¡}	|  |	¡ t ||	¡}
|
 ¡ }||fS )zMake DSA private key from data.z Corrupt data: dsa field mismatch)	rœ   rs   rI   r	   r²   r³   r´   ZDSAPrivateNumbersr    )r~   rR   r¡   r¤   r¥   r°   r±   Úxrµ   rž   r¦   r    r"   r"   r#   r§   •  s    
z_SSHFormatDSA.load_privatezdsa.DSAPublicKeyrx   rY   r¨   c                 C  sL   |  ¡ }|j}|  |¡ | |j¡ | |j¡ | |j¡ | |j¡ dS )zWrite DSA public keyN)rž   rµ   r´   rŒ   r¤   r¥   r°   r±   )r~   r>   r©   rž   rµ   r"   r"   r#   rª   ¥  s    
z_SSHFormatDSA.encode_publiczdsa.DSAPrivateKeyr«   c                 C  s$   |   | ¡ |¡ | | ¡ j¡ dS )zWrite DSA private keyN)rª   r>   rŒ   r¦   r¶   )r~   r    r¬   r"   r"   r#   r­   ²  s    z_SSHFormatDSA.encode_privatezdsa.DSAPublicNumbers)rž   r!   c                 C  s    |j }|j ¡ dkrtdƒ‚d S )Ni   z#SSH supports only 1024 bit DSA keys)rµ   r¤   ru   rI   )r~   rž   rµ   r"   r"   r#   r´   ¹  s    z_SSHFormatDSA._validateN)
r2   r3   r4   r˜   rœ   rŸ   r§   rª   r­   r´   r"   r"   r"   r#   r¯   y  s   r¯   c                   @  st   e Zd ZdZdddœdd„Zddd	œd
d„Zddd	œdd„Zddd	œdd„Zddddœdd„Zddddœdd„Z	dS )Ú_SSHFormatECDSAz–Format for ECDSA keys.

    Public:
        str curve
        bytes point
    Private:
        str curve
        bytes point
        mpint secret
    r   úec.EllipticCurve©Ússh_curve_namerN   c                 C  s   || _ || _d S r|   r¹   )r~   rº   rN   r"   r"   r#   r   Ë  s    z_SSHFormatECDSA.__init__rd   z0tuple[tuple[memoryview, memoryview], memoryview]r\   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   re   zNeed uncompressed point)rp   rº   rI   ÚNotImplementedError)r~   rR   rN   Úpointr"   r"   r#   rœ   Ï  s    
z_SSHFormatECDSA.get_publicú,tuple[ec.EllipticCurvePublicKey, memoryview]c                 C  s.   |   |¡\\}}}tj | j| ¡ ¡}||fS ©z Make ECDSA public key from data.)rœ   r
   r?   Zfrom_encoded_pointrN   r–   )r~   rR   Ú_r¼   r>   r"   r"   r#   rŸ   Û  s
    
ÿz_SSHFormatECDSA.load_publicz-tuple[ec.EllipticCurvePrivateKey, memoryview]c                 C  sH   |   |¡\\}}}t|ƒ\}}||f|kr2tdƒ‚t || j¡}||fS )z!Make ECDSA private key from data.z"Corrupt data: ecdsa field mismatch)rœ   rs   rI   r
   Zderive_private_keyrN   )r~   rR   r¡   Z
curve_namer¼   Úsecretr    r"   r"   r#   r§   å  s    z_SSHFormatECDSA.load_privaterL   rx   rY   r¨   c                 C  s*   |  tjtj¡}| | j¡ | |¡ dS )zWrite ECDSA public keyN)Úpublic_bytesr   ZX962r   ZUncompressedPointr‹   rº   )r~   r>   r©   r¼   r"   r"   r#   rª   ñ  s
    ÿz_SSHFormatECDSA.encode_publiczec.EllipticCurvePrivateKeyr«   c                 C  s,   |  ¡ }| ¡ }|  ||¡ | |j¡ dS )zWrite ECDSA private keyN)r>   r¦   rª   rŒ   Zprivate_value)r~   r    r¬   r>   r¦   r"   r"   r#   r­   û  s    z_SSHFormatECDSA.encode_privateN)
r2   r3   r4   r˜   r   rœ   rŸ   r§   rª   r­   r"   r"   r"   r#   r·   ¿  s   

r·   c                   @  sd   e Zd ZdZdddœdd„Zdddœdd	„Zdd
dœdd„Zddddœdd„Zddddœdd„ZdS )Ú_SSHFormatEd25519z~Format for Ed25519 keys.

    Public:
        bytes point
    Private:
        bytes point
        bytes secret_and_point
    rd   z$tuple[tuple[memoryview], memoryview]r\   c                 C  s   t |ƒ\}}|f|fS )zEd25519 public fields)rp   )r~   rR   r¼   r"   r"   r#   rœ     s    z_SSHFormatEd25519.get_publicú+tuple[ed25519.Ed25519PublicKey, memoryview]c                 C  s(   |   |¡\\}}tj | ¡ ¡}||fS ©z"Make Ed25519 public key from data.)rœ   r   rG   Zfrom_public_bytesr–   )r~   rR   r¼   r>   r"   r"   r#   rŸ     s
    ÿz_SSHFormatEd25519.load_publicz,tuple[ed25519.Ed25519PrivateKey, memoryview]c                 C  sb   |   |¡\\}}t|ƒ\}}|dd… }|dd… }||ksF|f|krNtdƒ‚tj |¡}||fS )z#Make Ed25519 private key from data.Nr6   z$Corrupt data: ed25519 field mismatch)rœ   rp   rI   r   rF   Zfrom_private_bytes)r~   rR   r¡   r¼   ZkeypairrÀ   Zpoint2r    r"   r"   r#   r§   !  s    z_SSHFormatEd25519.load_privatezed25519.Ed25519PublicKeyrx   rY   r¨   c                 C  s   |  tjtj¡}| |¡ dS )zWrite Ed25519 public keyN)rÁ   r   ÚRawr   r‹   )r~   r>   r©   Úraw_public_keyr"   r"   r#   rª   /  s    ÿz_SSHFormatEd25519.encode_publiczed25519.Ed25519PrivateKeyr«   c                 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   rx   rª   r‹   )r~   r    r¬   r>   Zraw_private_keyrÆ   Z	f_keypairr"   r"   r#   r­   8  s    ÿÿz _SSHFormatEd25519.encode_privateNr®   r"   r"   r"   r#   rÂ     s   	
	rÂ   r�   c                 C  s2   t | ƒ\}} | ¡  d¡s*td|› d�ƒ‚|| fS )z!
    U2F application strings
    s   ssh:z4U2F application string does not start with b'ssh:' (ú))rp   r–   Ú
startswithrI   )rR   Zapplicationr"   r"   r#   Úload_applicationI  s    ÿÿrÉ   c                   @  s    e Zd ZdZdddœdd„ZdS )Ú_SSHFormatSKEd25519zÏ
    The format of a sk-ssh-ed25519@openssh.com public key is:

        string		"sk-ssh-ed25519@openssh.com"
        string		public key
        string		application (user-specified, but typically "ssh:")
    rd   rÃ   r\   c                 C  s&   t tƒ |¡\}}t|ƒ\}}||fS rÄ   )Ú_lookup_kformatrH   rŸ   rÉ   ©r~   rR   r>   r¿   r"   r"   r#   rŸ   _  s    z_SSHFormatSKEd25519.load_publicN©r2   r3   r4   r˜   rŸ   r"   r"   r"   r#   rÊ   V  s   rÊ   c                   @  s    e Zd ZdZdddœdd„ZdS )Ú_SSHFormatSKECDSAzò
    The format of a sk-ecdsa-sha2-nistp256@openssh.com public key is:

        string		"sk-ecdsa-sha2-nistp256@openssh.com"
        string		curve name
        ec_point	Q
        string		application (user-specified, but typically "ssh:")
    rd   r½   r\   c                 C  s&   t tƒ |¡\}}t|ƒ\}}||fS r¾   )rË   Ú_ECDSA_NISTP256rŸ   rÉ   rÌ   r"   r"   r#   rŸ   r  s    z_SSHFormatSKECDSA.load_publicNrÍ   r"   r"   r"   r#   rÎ   h  s   	rÎ   s   nistp256s   nistp384s   nistp521©rJ   c                 C  s8   t | tƒst| ƒ ¡ } | tv r&t|  S td| ›�ƒ‚dS )z"Return valid format or throw errorzUnsupported key type: N)r;   r   rd   r–   Ú_KEY_FORMATSr   rÐ   r"   r"   r#   rË   ‡  s
    
rË   z
typing.AnyÚSSHPrivateKeyTypes)rR   r   Úbackendr!   c                 C  sî  t  d| ¡ |dur t  d|¡ t | ¡}|s6tdƒ‚| d¡}| d¡}t 	t
| ƒ||… ¡} |  t¡srtdƒ‚t
| ƒttƒd… } t| ƒ\}} t| ƒ\}} t| ƒ\}} t| ƒ\}	} |	dkrÆtdƒ‚t| ƒ\}
} t|
ƒ\}}
t|ƒ}| |
¡\}}
t|
ƒ ||fttfk�r&| ¡ }|tv�r.td|›�ƒ‚|tk�rFtd|›�ƒ‚t| j}t| j}t| ƒ\}} t| j�r’t| ƒ}t|ƒ|k�rštd	ƒ‚nt| ƒ t||ƒ t|ƒ\}}t|ƒ\}}t|ƒ t||| ¡ |ƒ}| ¡ }t
| |¡ƒ}t| j�rt |t!ƒ�sJ ‚t| "|¡ƒ nt| #¡ ƒ n"t| ƒ\}} t| ƒ d
}t||ƒ t|ƒ\}}t|ƒ\}}||k�rrtdƒ‚t|ƒ\}}||k�r�tdƒ‚| $||¡\}}t|ƒ\}}|t%dt|ƒ… k�rÊtdƒ‚t |t&j'ƒ�rêt(j)dt j*dd� |S )z.Load private key from OpenSSH custom encoding.rR   Nr   zNot OpenSSH private key formatr'   zOnly one key supportedzUnsupported cipher: zUnsupported KDF: z+Corrupt data: invalid tag length for cipherrm   zCorrupt data: broken checksumzCorrupt data: key type mismatchzCorrupt data: invalid paddingúDSSH DSA keys are deprecated and will be removed in a future release.é   ©Ú
stacklevel)+r   Ú_check_byteslikeÚ_check_bytesÚ_PEM_RCÚsearchrI   r”   ÚendÚbinasciiÚ
a2b_base64rd   rÈ   Ú	_SK_MAGICrZ   rp   rl   rË   rœ   r^   Ú_NONEr–   r8   r   Ú_BCRYPTr-   r0   r1   r   r[   rc   Z	decryptorÚupdater;   r   Zfinalize_with_tagÚfinalizer§   Ú_PADDINGr	   rC   ÚwarningsÚwarnÚDeprecatedIn40)rR   r   rÓ   ÚmÚp1Úp2r`   ÚkdfnameZ
kdfoptionsÚnkeysZpubdataZpub_key_typeÚkformatr¡   Zciphername_bytesÚblklenr0   ZedataÚtagr   Zkbufr   ra   ÚdecZck1Zck2rJ   r    r¿   r"   r"   r#   Úload_ssh_private_key˜  s�    




ÿ







ürñ   r   )r    r   Úencryption_algorithmr!   c                 C  sæ  t  d|¡ t| tjƒr*tjdt jdd� t| ƒ}t	|ƒ}t
ƒ }|r¢t}t| j}t}t}	t|tƒrt|jdurt|j}	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|… ƒS )
z3Serialize private key with OpenSSH custom encoding.r   úISSH DSA key support is deprecated and will be removed in a future releasere   rÖ   Nr&   rm   r'   rU   )%r   rÙ   r;   r	   rC   rå   ræ   rç   rK   rË   rx   Ú_DEFAULT_CIPHERr8   r-   rá   Ú_DEFAULT_ROUNDSr   Z_kdf_roundsÚosÚurandomr‹   r‡   rc   rà   rª   r>   r­   r‚   rä   rŠ   rß   rd   r‰   r•   Z	encryptorZupdate_intorX   )r    r   rò   rJ   rí   Zf_kdfoptionsr`   rî   rë   r   r   ra   rì   ZcheckvalÚcommentZf_public_keyZ	f_secretsZf_mainÚslenÚmlenr—   Zofsr"   r"   r#   Ú_serialize_ssh_private_key   sl    ü
ÿþ















 rû   c                   @  s   e Zd ZdZdZdS )ÚSSHCertificateTyper'   rÕ   N)r2   r3   r4   ÚUSERZHOSTr"   r"   r"   r#   rü   [  s   rü   c                   @  s  e Zd Zddddddddddddddddddœdd	„Zedd
œdd„ƒZdd
œdd„Zedd
œdd„ƒZedd
œdd„ƒZedd
œdd„ƒZ	edd
œdd„ƒZ
edd
œdd„ƒZedd
œdd„ƒZedd
œdd„ƒZedd
œdd „ƒZdd
œd!d"„Zdd
œd#d$„Zd%d
œd&d'„Zd(S ))ÚSSHCertificaterd   ÚSSHPublicKeyTypesr   ry   údict[bytes, bytes]r   )Ú_nonceÚ_public_keyÚ_serialÚ_cctypeÚ_key_idÚ_valid_principalsÚ_valid_afterÚ_valid_beforeÚ_critical_optionsÚ_extensionsÚ	_sig_typeÚ_sig_keyÚ_inner_sig_typeÚ
_signatureÚ_tbs_cert_bodyÚ_cert_key_typeÚ
_cert_bodyc                 C  sŽ   || _ || _|| _zt|ƒ| _W n ty:   tdƒ‚Y n0 || _|| _|| _|| _	|	| _
|
| _|| _|| _|| _|| _|| _|| _|| _d S )NzInvalid certificate type)r  r  r  rü   Ú_typerI   r  r  r  r  r	  r
  r  r  r  r  r  r  r  )r~   r  r  r  r  r  r  r  r  r	  r
  r  r  r  r  r  r  r  r"   r"   r#   r   a  s(    zSSHCertificate.__init__r�   c                 C  s
   t | jƒS r|   )r   r  r�   r"   r"   r#   ÚnonceŠ  s    zSSHCertificate.nonceÚSSHCertPublicKeyTypesc                 C  s   t  t| j¡S r|   )ÚtypingÚcastr  r  r�   r"   r"   r#   r>   Ž  s    zSSHCertificate.public_keyc                 C  s   | j S r|   )r  r�   r"   r"   r#   Úserial“  s    zSSHCertificate.serialrü   c                 C  s   | j S r|   )r  r�   r"   r"   r#   Útype—  s    zSSHCertificate.typec                 C  s
   t | jƒS r|   )r   r  r�   r"   r"   r#   Úkey_id›  s    zSSHCertificate.key_idc                 C  s   | j S r|   )r  r�   r"   r"   r#   Úvalid_principalsŸ  s    zSSHCertificate.valid_principalsc                 C  s   | j S r|   )r  r�   r"   r"   r#   Úvalid_before£  s    zSSHCertificate.valid_beforec                 C  s   | j S r|   )r  r�   r"   r"   r#   Úvalid_after§  s    zSSHCertificate.valid_afterc                 C  s   | j S r|   )r	  r�   r"   r"   r#   Úcritical_options«  s    zSSHCertificate.critical_optionsc                 C  s   | j S r|   )r
  r�   r"   r"   r#   Ú
extensions¯  s    zSSHCertificate.extensionsc                 C  s&   t | jƒ}| | j¡\}}t|ƒ |S r|   )rË   r  rŸ   r  r^   )r~   Z	sigformatÚsignature_keyZsigkey_restr"   r"   r#   r  ³  s    
zSSHCertificate.signature_keyc                 C  s"   t | jƒd tjt | jƒdd� S )Nó    F)Únewline)r   r  rÝ   Ú
b2a_base64r  r�   r"   r"   r#   rÁ   ¹  s    ÿþÿzSSHCertificate.public_bytesrY   c                 C  s   |   ¡ }t|tjƒr.| t| jƒt| jƒ¡ nÎt|tj	ƒrŽt
| jƒ\}}t
|ƒ\}}t|ƒ t ||¡}t|jƒ}| |t| jƒt |¡¡ nnt|tjƒsžJ ‚| jtkr²t ¡ }n*| jtkrÆt ¡ }n| jtksÔJ ‚t ¡ }| t| jƒt| jƒt ¡ |¡ d S r|   )r  r;   r   rG   Úverifyr   r  r  r
   r?   rs   r^   Ú
asym_utilsZencode_dss_signatureÚ_get_ec_hash_algrN   ÚECDSAr   rA   r  rB   r   ÚSHA1Ú_SSH_RSA_SHA256ÚSHA256Ú_SSH_RSA_SHA512ÚSHA512r   ÚPKCS1v15)r~   r  ÚrrR   ÚsZcomputed_sigÚhash_algr"   r"   r#   Úverify_cert_signatureÀ  s6    ÿ
ÿ



üz$SSHCertificate.verify_cert_signatureN)r2   r3   r4   r   Úpropertyr  r>   r  r  r  r  r  r  r  r  r  rÁ   r0  r"   r"   r"   r#   rþ   `  s.   .)rþ   r¸   zhashes.HashAlgorithm)rN   r!   c                 C  sD   t | tjƒrt ¡ S t | tjƒr(t ¡ S t | tjƒs8J ‚t ¡ S d S r|   )	r;   r
   Ú	SECP256R1r   r)  Ú	SECP384R1ÚSHA384Ú	SECP521R1r+  )rN   r"   r"   r#   r%  á  s    r%  z"SSHCertificate | SSHPublicKeyTypesc           "      C  s~  t  d| ¡ t | ¡}|s"tdƒ‚| d¡ }}| d¡}d}| t¡r^d}|d ttƒ … }|t	krr|srt
dƒ‚t|ƒ}ztt |¡ƒ}W n  ttjfy¬   tdƒ‚Y n0 |r¶|}	t|ƒ\}
}|
|krÒtd	ƒ‚|rât|ƒ\}}| |¡\}}|�rnt|ƒ\}}t|ƒ\}}t|ƒ\}}t|ƒ\}}g }|�rNt|ƒ\}}| t|ƒ¡ �q*t|ƒ\}}t|ƒ\}}t|ƒ\}}t|ƒ}t|ƒ\}}t|ƒ}t|ƒ\}}t|ƒ\}}t|ƒ\}}|t	k�rÊ|�sÊt
d
ƒ‚|	d t|ƒ … }t|ƒ\}}t|ƒ t|ƒ\}} |tk�r|tttfv�s*|tk�r2||k�r2tdƒ‚t| ƒ\}!} t| ƒ t||||||||||||||!|||	ƒS t|ƒ |S d S )NrR   zInvalid line formatr'   rÕ   FTz-DSA keys aren't supported in SSH certificateszInvalid formatzInvalid key formatz3DSA signatures aren't supported in SSH certificatesz!Signature key type does not match)r   rØ   Ú_SSH_PUBKEY_RCÚmatchrI   ÚgroupÚendswithÚ_CERT_SUFFIXrZ   rE   r   rË   rd   rÝ   rÞ   Ú	TypeErrorÚErrorrp   rŸ   rn   rl   r€   r   Ú_parse_exts_optsr^   rB   r(  r*  rþ   )"rR   Ú_legacy_dsa_allowedrè   rJ   Zorig_key_typeZkey_bodyZ	with_certrí   ÚrestZ	cert_bodyZinner_key_typer  r>   r  Zcctyper  Z
principalsr  Z	principalr  r  Zcrit_optionsr  Úextsr  r¿   Zsig_key_rawZsig_typeZsig_keyZtbs_cert_bodyZsignature_rawZinner_sig_typeZsig_restÚ	signaturer"   r"   r#   Ú_load_ssh_public_identityë  s®    


ÿÿÿÿþüüïrB  c                 C  s   t | ƒS r|   )rB  r]   r"   r"   r#   Úload_ssh_public_identityJ  s    rC  r   )Ú	exts_optsr!   c                 C  s–   i }d }| r’t | ƒ\}} t|ƒ}||v r0tdƒ‚|d urH||k rHtdƒ‚t | ƒ\}} t|ƒdkr€t |ƒ\}}t|ƒdkr€tdƒ‚t|ƒ||< |}q|S )NzDuplicate namezFields not lexically sortedr   z!Unexpected extra data after value)rp   r   rI   rZ   )rD  ÚresultÚ	last_namerO   ZbnameÚvalueÚextrar"   r"   r#   r=  P  s"    r=  rÿ   )rR   rÓ   r!   c                 C  sF   t | dd�}t|tƒr | ¡ }n|}t|tjƒrBtjdtj	dd� |S )NT)r>  rÔ   rÕ   rÖ   )
rB  r;   rþ   r>   r	   rD   rå   ræ   r   rç   )rR   rÓ   Zcert_or_keyr>   r"   r"   r#   Úload_ssh_public_keyd  s    

ürI  c                 C  sl   t | tjƒrtjdtjdd� t| ƒ}t|ƒ}t	ƒ }| 
|¡ | | |¡ t | ¡ ¡ ¡ }d |d|g¡S )z&One-line public key format for OpenSSHró   re   rÖ   rU   r   )r;   r	   rD   rå   ræ   r   rç   rK   rË   rx   r‹   rª   rÝ   r"  r–   ÚstriprV   )r>   rJ   rí   r©   Zpubr"   r"   r#   Úserialize_ssh_public_keyx  s    ü
rK  é   c                   @  sî   e Zd Zddddg dddg g f
ddddddddd	d	d
œ
dd„Zdd dœdd„Zdd dœdd„Zdd dœdd„Zdd dœdd„Zdd dœdd„Zd d!„ Z	d"d d#œd$d%„Z
d"d d&œd'd(„Zddd d)œd*d+„Zddd d)œd,d-„Zd.d/d0œd1d2„ZdS )3ÚSSHCertificateBuilderNFzSSHCertPublicKeyTypes | Noner/   zSSHCertificateType | Noner_   ry   r   zlist[tuple[bytes, bytes]]©
r  r  r  r  r  Ú_valid_for_all_principalsr  r  r	  r
  c                 C  s@   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	d S r|   rN  )r~   r  r  r  r  r  rO  r  r  r	  r
  r"   r"   r#   r   ™  s    zSSHCertificateBuilder.__init__r  rM   c                 C  s^   t |tjtjtjfƒstdƒ‚| jd ur0t	dƒ‚t
|| j| j| j| j| j| j| j| j| jd�
S )Nr:   zpublic_key already setrN  )r;   r
   r?   r   rA   r   rG   r;  r  rI   rM  r  r  r  r  rO  r  r  r	  r
  )r~   r>   r"   r"   r#   r>   ±  s,    ýþ
öz SSHCertificateBuilder.public_keyr   )r  r!   c                 C  sp   t |tƒstdƒ‚d|  kr&dk s0n tdƒ‚| jd urBtdƒ‚t| j|| j| j| j	| j
| j| j| j| jd�
S )Nzserial must be an integerr   ì            z"serial must be between 0 and 2**64zserial already setrN  )r;   r   r;  rI   r  rM  r  r  r  r  rO  r  r  r	  r
  )r~   r  r"   r"   r#   r  Í  s$    

özSSHCertificateBuilder.serialrü   )r  r!   c                 C  sR   t |tƒstdƒ‚| jd ur$tdƒ‚t| j| j|| j| j	| j
| j| j| j| jd�
S )Nz"type must be an SSHCertificateTypeztype already setrN  )r;   rü   r;  r  rI   rM  r  r  r  r  rO  r  r  r	  r
  )r~   r  r"   r"   r#   r  â  s     

özSSHCertificateBuilder.typer   )r  r!   c                 C  sR   t |tƒstdƒ‚| jd ur$tdƒ‚t| j| j| j|| j	| j
| j| j| j| jd�
S )Nzkey_id must be byteszkey_id already setrN  )r;   r   r;  r  rI   rM  r  r  r  r  rO  r  r  r	  r
  )r~   r  r"   r"   r#   r  õ  s     

özSSHCertificateBuilder.key_id)r  r!   c                 C  s|   | j rtdƒ‚tdd„ |D ƒƒr$|s,tdƒ‚| jr:tdƒ‚t|ƒtkrNtdƒ‚t| j| j	| j
| j|| j | j| j| j| jd�
S )NzDPrincipals can't be set because the cert is valid for all principalsc                 s  s   | ]}t |tƒV  qd S r|   )r;   r   )Ú.0r¶   r"   r"   r#   Ú	<genexpr>  rU   z9SSHCertificateBuilder.valid_principals.<locals>.<genexpr>z5principals must be a list of bytes and can't be emptyzvalid_principals already setz:Reached or exceeded the maximum number of valid_principalsrN  )rO  rI   Úallr;  r  rZ   Ú_SSHKEY_CERT_MAX_PRINCIPALSrM  r  r  r  r  r  r  r	  r
  )r~   r  r"   r"   r#   r    s:    ÿÿþÿÿöz&SSHCertificateBuilder.valid_principalsc                 C  sJ   | j rtdƒ‚| jrtdƒ‚t| j| j| j| j| j d| j| j	| j
| jd�
S )Nz@valid_principals already set, can't set valid_for_all_principalsz$valid_for_all_principals already setTrN  )r  rI   rO  rM  r  r  r  r  r  r  r	  r
  r�   r"   r"   r#   Úvalid_for_all_principals,  s$    ÿöz.SSHCertificateBuilder.valid_for_all_principalszint | float)r  r!   c                 C  sv   t |ttfƒstdƒ‚t|ƒ}|dk s.|dkr6tdƒ‚| jd urHtdƒ‚t| j| j| j	| j
| j| j|| j| j| jd�
S )Nz$valid_before must be an int or floatr   rP  zvalid_before must [0, 2**64)zvalid_before already setrN  )r;   r   Úfloatr;  rI   r  rM  r  r  r  r  r  rO  r  r	  r
  )r~   r  r"   r"   r#   r  B  s&    
öz"SSHCertificateBuilder.valid_before)r  r!   c                 C  sv   t |ttfƒstdƒ‚t|ƒ}|dk s.|dkr6tdƒ‚| jd urHtdƒ‚t| j| j| j	| j
| j| j| j|| j| jd�
S )Nz#valid_after must be an int or floatr   rP  zvalid_after must [0, 2**64)zvalid_after already setrN  )r;   r   rV  r;  rI   r  rM  r  r  r  r  r  rO  r  r	  r
  )r~   r  r"   r"   r#   r  X  s&    
öz!SSHCertificateBuilder.valid_after)rO   rG  r!   c                 C  st   t |tƒrt |tƒstdƒ‚|dd„ | jD ƒv r8tdƒ‚t| j| j| j| j	| j
| j| j| jg | j¢||f‘| jd�
S )Núname and value must be bytesc                 S  s   g | ]\}}|‘qS r"   r"   ©rQ  rO   r¿   r"   r"   r#   Ú
<listcomp>t  rU   z=SSHCertificateBuilder.add_critical_option.<locals>.<listcomp>zDuplicate critical option namerN  )r;   r   r;  r	  rI   rM  r  r  r  r  r  rO  r  r  r
  ©r~   rO   rG  r"   r"   r#   Úadd_critical_optionn  s     öz)SSHCertificateBuilder.add_critical_optionc                 C  st   t |tƒrt |tƒstdƒ‚|dd„ | jD ƒv r8tdƒ‚t| j| j| j| j	| j
| j| j| j| jg | j¢||f‘d�
S )NrW  c                 S  s   g | ]\}}|‘qS r"   r"   rX  r"   r"   r#   rY  Š  rU   z7SSHCertificateBuilder.add_extension.<locals>.<listcomp>zDuplicate extension namerN  )r;   r   r;  r
  rI   rM  r  r  r  r  r  rO  r  r  r	  rZ  r"   r"   r#   Úadd_extension„  s     öz#SSHCertificateBuilder.add_extensionÚSSHCertPrivateKeyTypesrþ   )r    r!   c              	   C  sð  t |tjtjtjfƒstdƒ‚| jd u r0t	dƒ‚| j
d u r>dn| j
}| jd u rVt	dƒ‚| jd u rddn| j}| js~| js~t	dƒ‚| jd u r�t	dƒ‚| jd u r¢t	dƒ‚| j| jkr¶t	d	ƒ‚| jjd
d„ d� | jjdd„ d� t| jƒ}|t }t d¡}t|ƒ}tƒ }| |¡ | |¡ | | j|¡ | |¡ | | jj¡ | |¡ tƒ }	| jD ]}
|	 |
¡ �qT| |	 ¡ ¡ | | j¡ | | j¡ tƒ }| jD ]L\}}| |¡ t |ƒdk�rØtƒ }| |¡ | | ¡ ¡ n
| |¡ �q˜| | ¡ ¡ tƒ }| jD ]L\}}| |¡ t |ƒdk�r@tƒ }| |¡ | | ¡ ¡ n
| |¡ �q | | ¡ ¡ | d¡ t|ƒ}t|ƒ}tƒ }| |¡ | | !¡ |¡ | | ¡ ¡ t |tjƒ�rê| "| ¡ ¡}tƒ }| |¡ | |¡ | | ¡ ¡ nØt |tjƒ�rnt#|j$ƒ}| "| ¡ t %|¡¡}t& '|¡\}}tƒ }| |¡ tƒ }| (|¡ | (|¡ | | ¡ ¡ | | ¡ ¡ nTt |tjƒ�s€J ‚tƒ }| t)¡ | "| ¡ t* +¡ t, -¡ ¡}| |¡ | | ¡ ¡ t. /| ¡ ¡ 0¡ }t1 2t3t4d 5|d|g¡ƒ¡S )NzUnsupported private key typezpublic_key must be setr   ztype must be setrU   zAvalid_principals must be set if valid_for_all_principals is Falsezvalid_before must be setzvalid_after must be setz-valid_after must be earlier than valid_beforec                 S  s   | d S ©Nr   r"   ©r¶   r"   r"   r#   Ú<lambda>Å  rU   z,SSHCertificateBuilder.sign.<locals>.<lambda>)r9   c                 S  s   | d S r^  r"   r_  r"   r"   r#   r`  Æ  rU   r6   r   )6r;   r
   r<   r   r@   r   rF   r;  r  rI   r  r  r  r  rO  r  r  r	  Úsortr
  rK   r:  rö   r÷   rË   rx   r‹   rª   rˆ   r‡   rG  r–   rZ   r>   Úsignr%  rN   r&  r$  Zdecode_dss_signaturerŒ   r*  r   r,  r   r+  rÝ   r"  rJ  r  r  rþ   rC  rV   )r~   r    r  r  rJ   Zcert_prefixr  rí   ÚfZfprincipalsr¤   ZfcritrO   rG  ZfoptvalZfextZfextvalZca_typeZcaformatZcafrA  Zfsigr/  r-  r.  ZfsigblobZ	cert_datar"   r"   r#   rb  š  sÄ    ýþ

ÿ





















ÿ
þzSSHCertificateBuilder.sign)r2   r3   r4   r   r>   r  r  r  r  rU  r  r  r[  r\  rb  r"   r"   r"   r#   rM  ˜  s,   õ"$rM  )F)N)F)N)Ú
__future__r   rÝ   Úenumrö   Úrer  rå   Úbase64r   rW   Údataclassesr   Zcryptographyr   Zcryptography.exceptionsr   Zcryptography.hazmat.primitivesr   Z)cryptography.hazmat.primitives.asymmetricr	   r
   r   r   r   r$  Z&cryptography.hazmat.primitives.ciphersr   r   r   r   Z,cryptography.hazmat.primitives.serializationr   r   r   r   r   r   Zbcryptr   r$   Z_bcrypt_supportedÚImportErrorrH   rB   rE   rÏ   Z_ECDSA_NISTP384Z_ECDSA_NISTP521r:  Z_SK_SSH_ED25519Z_SK_SSH_ECDSA_NISTP256r(  r*  Úcompiler6  rß   Z	_SK_STARTZ_SK_ENDrá   rà   rô   rõ   ÚDOTALLrÚ   rd   r‰   Úrangerä   r)   ZAESZCTRZCBCZGCMr8   r5   rP   rK   r=   rX   r[   r^   rc   rl   rn   rp   rs   rw   rx   r™   r¯   r·   rÂ   rÉ   rÊ   rÎ   r2  r3  r5  rÑ   rË   ÚUnionr<   r@   rC   rF   rÒ   rñ   rû   r?   rA   rD   rG   rÿ   r  ÚEnumrü   rþ   r%  rB  rC  r=  rI  rK  r]  rT  rM  r"   r"   r"   r#   Ú<module>   s,   	 û 

ù	ù	ùí ýý
6HFGCø	ýÿ ýhMýÿþÿ  þ_ ÿþÿ	