3
ãde6½  ã               @   sÞ  U 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mZmZmZmZ d dlm
Z d dlmZmZmZ d dlmZmZmZmZmZm Z  yd d	l!m"Z# d
Z$W n4 e%k
�r   dZ$dqe&e&e'e'e(e&dœdd„Z#Y nX dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0dZ1ej2dƒZ3dZ4dZ5dZ6dZ7dZ8dZ9dZ:ej2e5d  e6 ej;ƒZ<e=e>e?d!drƒƒƒZ@ejAd"ejBdfejAd"ejCdfd#œZDejEe&ejFejGejA e'ejHejGejB ejGejC f e'f f De,e-e.d$œZIejHds e&d'œd(d)„ZJejKe&d*œd+d,„ZLe5d- e6d- fe&e&e&e&d.œd/d0„ZMe&e'dd1œd2d3„ZNe&dd4œd5d6„ZOe&ejPe& e&e'eejHejCejBf  d7œd8d9„ZQe=ejFe'e=f d4œd:d;„ZRe=ejFe'e=f d4œd<d=„ZSe=ejFe=e=f d4œd>d?„ZTe=ejFe'e=f d4œd@dA„ZUe'e&dBœdCdD„ZVG dEdF„ dFƒZWG dGdH„ dHƒZXG dIdJ„ dJƒZYG dKdL„ dLƒZZG dMdN„ dNƒZ[e*eXƒ e+eYƒ e)e[ƒ e,eZdOej\ƒ ƒe-eZdPej]ƒ ƒe.eZdQej^ƒ ƒiZ_e&dRœdSdT„Z`ejHejaejbejcejdf Zedte&ejPe& ejfeedUœdVdW„Zgeee&ee&dXœdYdZ„ZhejHejKejiejjejkf ZlejHejKejiejkf ZmG d[d\„ d\ejnƒZoG d]d^„ d^ƒZpejqejrd_œd`da„Zsdue&ejHepelf d4œdbdc„Zte&ejHepelf d4œddde„Zue=ejEe&e&f dfœdgdh„Zvdve&ejfeldiœdjdk„Zwele&d*œdldm„ZxejHejaejbejdf ZydnZzG dodp„ dpƒZ{dS )wé    N)Úencodebytes)Úutils)ÚUnsupportedAlgorithm)Úhashes)ÚdsaÚecÚed25519ÚpaddingÚrsa)ÚCipherÚ
algorithmsÚmodes)ÚEncodingÚKeySerializationEncryptionÚNoEncryptionÚPrivateFormatÚPublicFormatÚ_KeySerializationEncryption)ÚkdfTF)ÚpasswordÚsaltÚdesired_key_bytesÚroundsÚignore_few_roundsÚreturnc             C   s   t dƒ‚d S )NzNeed bcrypt module)r   )r   r   r   r   r   © r   úg/var/www/agendate/envp3/lib/python3.6/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   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   nones
   aes256-ctré   s   (.*?)é   é    )s
   aes256-ctrs
   aes256-cbc)Z	secp256r1Z	secp384r1Z	secp521r1ÚSSHPrivateKeyTypesÚSSHPublicKeyTypes)Úkeyr   c             C   s„   t | tjƒrt| jƒ ƒ}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 )NzUnsupported key type)Ú
isinstancer   ÚEllipticCurvePrivateKeyÚ_ecdsa_key_typeÚ
public_keyÚEllipticCurvePublicKeyr
   ÚRSAPrivateKeyÚRSAPublicKeyÚ_SSH_RSAr   ÚDSAPrivateKeyÚDSAPublicKeyÚ_SSH_DSAr   ÚEd25519PrivateKeyÚEd25519PublicKeyÚ_SSH_ED25519Ú
ValueError)r#   Úkey_typer   r   r   Ú_get_ssh_key_typef   s    
r4   )r'   r   c             C   s*   | j }|jtk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_TYPEr2   )r'   r5   r   r   r   r&   {   s
    
r&   ó   
)ÚdataÚprefixÚsuffixr   c             C   s   dj |t| ƒ|gƒS )Nó    )ÚjoinÚ_base64_encode)r9   r:   r;   r   r   r   Ú_ssh_pem_encode…   s    r?   )r9   Ú	block_lenr   c             C   s"   |  st | ƒ| dkrtdƒ‚dS )zRequire data to be full blocksr   zCorrupt data: missing paddingN)Úlenr2   )r9   r@   r   r   r   Ú_check_block_size�   s    rB   )r9   r   c             C   s   | rt dƒ‚dS )z!All data should have been parsed.zCorrupt data: unparsed dataN)r2   )r9   r   r   r   Ú_check_empty“   s    rC   )Ú
ciphernamer   r   r   r   c       	      C   sR   |st dƒ‚t|  \}}}}t|||| |dƒ}t||d|… ƒ|||d… ƒƒS )z$Generate key + iv and return cipher.zKey is password-protected.TN)r2   Ú_SSH_CIPHERSr   r   )	rD   r   r   r   ÚalgoZkey_lenÚmodeZiv_lenÚseedr   r   r   Ú_init_cipher™   s
    rI   c             C   s6   t | ƒdk rtdƒ‚tj| dd… dd�| dd… fS )ZUint32é   zInvalid dataNÚbig)Ú	byteorder)rA   r2   ÚintÚ
from_bytes)r9   r   r   r   Ú_get_u32¨   s    rO   c             C   s6   t | ƒdk rtdƒ‚tj| dd… dd�| dd… fS )ZUint64é   zInvalid dataNrK   )rL   )rA   r2   rM   rN   )r9   r   r   r   Ú_get_u64¯   s    rQ   c             C   s8   t | ƒ\}} |t| ƒkr tdƒ‚| d|… | |d… fS )zBytes with u32 length prefixzInvalid dataN)rO   rA   r2   )r9   Únr   r   r   Ú_get_sshstr¶   s    rS   c             C   s4   t | ƒ\}} |r$|d dkr$tdƒ‚tj|dƒ| fS )zBig integer.r   é   zInvalid datarK   )rS   r2   rM   rN   )r9   Úvalr   r   r   Ú
_get_mpint¾   s    rV   )rU   r   c             C   s4   | dk rt dƒ‚| sdS | jƒ d d }tj| |ƒS )z!Storage format for signed bigint.r   znegative mpint not allowedr<   rP   )r2   Ú
bit_lengthr   Zint_to_bytes)rU   Únbytesr   r   r   Ú	_to_mpintÆ   s    rY   c               @   sÄ   e Zd ZU dZeje dejej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jed f ddœdd„Zeddœdd„Zedœdd„Zdeeedœdd„Zedœdd„ZdS )Ú	_FragListz,Build recursive structure without data copy.N)Úinitr   c             C   s   g | _ |r| j j|ƒ d S )N)ÚflistÚextend)Úselfr[   r   r   r   Ú__init__Õ   s    z_FragList.__init__)rU   r   c             C   s   | j j|ƒ dS )zAdd plain bytesN)r\   Úappend)r^   rU   r   r   r   Úput_rawÜ   s    z_FragList.put_rawc             C   s   | j j|jddd�ƒ dS )zBig-endian uint32rJ   rK   )ÚlengthrL   N)r\   r`   Úto_bytes)r^   rU   r   r   r   Úput_u32à   s    z_FragList.put_u32c             C   s   | j j|jddd�ƒ dS )zBig-endian uint64rP   rK   )rb   rL   N)r\   r`   rc   )r^   rU   r   r   r   Úput_u64ä   s    z_FragList.put_u64c             C   sL   t |tttfƒr,| jt|ƒƒ | jj|ƒ n| j|jƒ ƒ | jj	|jƒ dS )zBytes prefixed with u32 lengthN)
r$   ÚbytesÚ
memoryviewÚ	bytearrayrd   rA   r\   r`   Úsizer]   )r^   rU   r   r   r   Ú
put_sshstrè   s
    z_FragList.put_sshstrc             C   s   | j t|ƒƒ dS )z*Big-endian bigint prefixed with u32 lengthN)rj   rY   )r^   rU   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ÚmaprA   r\   )r^   r   r   r   ri   õ   s    z_FragList.sizer   )ÚdstbufÚposr   c             C   s6   x0| j D ]&}t|ƒ}|||  }}||||…< qW |S )zWrite into bytearray)r\   rA   )r^   rn   ro   ÚfragZflenÚstartr   r   r   Úrenderù   s
    z_FragList.renderc             C   s"   t t| jƒ ƒƒ}| j|ƒ |jƒ S )zReturn as bytes)rg   rh   ri   rr   Útobytes)r^   Úbufr   r   r   rs     s    
z_FragList.tobytes)N)r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚtypingÚListrf   r\   ÚOptionalr_   ra   rM   rd   re   ÚUnionrj   rk   ri   rg   rr   rs   r   r   r   r   rZ   Ð   s   

	rZ   c               @   s~   e Zd ZdZedœdd„Zeejej	ef dœdd„Z
eejejef dœdd	„Zej	ed
dœdd„Zejed
dœdd„Zd
S )Ú_SSHFormatRSAzhFormat for RSA keys.

    Public:
        mpint e, n
    Private:
        mpint n, e, d, iqmp, p, q
    )r9   c             C   s$   t |ƒ\}}t |ƒ\}}||f|fS )zRSA public fields)rV   )r^   r9   ÚerR   r   r   r   Ú
get_public  s    z_SSHFormatRSA.get_public)r9   r   c             C   s.   | j |ƒ\\}}}tj||ƒ}|jƒ }||fS )zMake RSA public key from data.)r   r
   ÚRSAPublicNumbersr'   )r^   r9   r~   rR   Ú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j||ƒ}	tj||ƒ}
tj||ƒ}tj||||	|
||ƒ}|jƒ }||fS )zMake RSA private key from data.z Corrupt data: rsa field mismatch)rV   r2   r
   Zrsa_crt_dmp1Zrsa_crt_dmq1r€   ZRSAPrivateNumbersÚprivate_key)r^   r9   Ú	pubfieldsrR   r~   ÚdÚiqmpÚpÚqZdmp1Zdmq1r�   Úprivate_numbersrƒ   r   r   r   Úload_private   s    z_SSHFormatRSA.load_privateN)r'   Úf_pubr   c             C   s$   |j ƒ }|j|jƒ |j|jƒ dS )zWrite RSA public keyN)r�   rk   r~   rR   )r^   r'   r‹   Zpubnr   r   r   Úencode_public6  s    z_SSHFormatRSA.encode_public)rƒ   Úf_privr   c             C   sZ   |j ƒ }|j}|j|jƒ |j|jƒ |j|jƒ |j|jƒ |j|jƒ |j|jƒ dS )zWrite RSA private keyN)	r‰   r�   rk   rR   r~   r…   r†   r‡   rˆ   )r^   rƒ   r�   r‰   r�   r   r   r   Úencode_private>  s    z_SSHFormatRSA.encode_private)ru   rv   rw   rx   rg   r   ry   ÚTupler
   r*   r‚   r)   rŠ   rZ   rŒ   rŽ   r   r   r   r   r}     s   r}   c               @   sž   e Zd ZdZeejejef dœdd„Zeejej	ef dœdd„Z
eejejef dœdd„Zej	ed	d
œdd„Zejed	dœdd„Zejd	dœdd„Zd	S )Ú_SSHFormatDSAzhFormat for DSA keys.

    Public:
        mpint p, q, g, y
    Private:
        mpint p, q, g, y, x
    )r9   r   c             C   s@   t |ƒ\}}t |ƒ\}}t |ƒ\}}t |ƒ\}}||||f|fS )zDSA public fields)rV   )r^   r9   r‡   rˆ   ÚgÚyr   r   r   r   W  s
    z_SSHFormatDSA.get_publicc       	      C   sJ   | j |ƒ\\}}}}}tj|||ƒ}tj||ƒ}| j|ƒ |jƒ }||fS )zMake DSA public key from data.)r   r   ÚDSAParameterNumbersÚDSAPublicNumbersÚ	_validater'   )	r^   r9   r‡   rˆ   r‘   r’   Úparameter_numbersr�   r'   r   r   r   r‚   a  s    
z_SSHFormatDSA.load_publicc             C   sz   | j |ƒ\\}}}}}t|ƒ\}}||||f|kr:tdƒ‚tj|||ƒ}tj||ƒ}	| j|	ƒ tj||	ƒ}
|
jƒ }||fS )zMake DSA private key from data.z Corrupt data: dsa field mismatch)	r   rV   r2   r   r“   r”   r•   ZDSAPrivateNumbersrƒ   )r^   r9   r„   r‡   rˆ   r‘   r’   Úxr–   r�   r‰   rƒ   r   r   r   rŠ   l  s    
z_SSHFormatDSA.load_privateN)r'   r‹   r   c             C   sL   |j ƒ }|j}| j|ƒ |j|jƒ |j|jƒ |j|jƒ |j|jƒ dS )zWrite DSA public keyN)r�   r–   r•   rk   r‡   rˆ   r‘   r’   )r^   r'   r‹   r�   r–   r   r   r   rŒ   |  s    
z_SSHFormatDSA.encode_public)rƒ   r�   r   c             C   s$   | j |jƒ |ƒ |j|jƒ jƒ dS )zWrite DSA private keyN)rŒ   r'   rk   r‰   r—   )r^   rƒ   r�   r   r   r   rŽ   ‰  s    z_SSHFormatDSA.encode_private)r�   r   c             C   s    |j }|jjƒ dkrtdƒ‚d S )Ni   z#SSH supports only 1024 bit DSA keys)r–   r‡   rW   r2   )r^   r�   r–   r   r   r   r•   �  s    z_SSHFormatDSA._validate)ru   rv   rw   rx   rg   ry   r�   r   r   r-   r‚   r,   rŠ   rZ   rŒ   rŽ   r”   r•   r   r   r   r   r�   N  s   	
r�   c               @   sž   e Zd ZdZeejdœdd„Zee	j
e	j
ef dœdd„Zee	j
ejef dœdd	„Zee	j
ejef dœd
d„Zejeddœdd„Zejeddœdd„ZdS )Ú_SSHFormatECDSAz–Format for ECDSA keys.

    Public:
        str curve
        bytes point
    Private:
        str curve
        bytes point
        mpint secret
    )Ússh_curve_namer5   c             C   s   || _ || _d S )N)r™   r5   )r^   r™   r5   r   r   r   r_   ¢  s    z_SSHFormatECDSA.__init__)r9   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   rJ   zNeed uncompressed point)rS   r™   r2   ÚNotImplementedError)r^   r9   r5   Úpointr   r   r   r   ¦  s    
z_SSHFormatECDSA.get_publicc             C   s.   | j |ƒ\\}}}tjj| j|jƒ ƒ}||fS )z Make ECDSA public key from data.)r   r   r(   Zfrom_encoded_pointr5   rs   )r^   r9   Ú
curve_namer›   r'   r   r   r   r‚   ²  s    z_SSHFormatECDSA.load_publicc             C   sH   | j |ƒ\\}}}t|ƒ\}}||f|kr2tdƒ‚tj|| jƒ}||fS )z!Make ECDSA private key from data.z"Corrupt data: ecdsa field mismatch)r   rV   r2   r   Zderive_private_keyr5   )r^   r9   r„   rœ   r›   Úsecretrƒ   r   r   r   rŠ   ¼  s    z_SSHFormatECDSA.load_privateN)r'   r‹   r   c             C   s*   |j tjtjƒ}|j| jƒ |j|ƒ dS )zWrite ECDSA public keyN)Úpublic_bytesr   ZX962r   ZUncompressedPointrj   r™   )r^   r'   r‹   r›   r   r   r   rŒ   È  s    z_SSHFormatECDSA.encode_public)rƒ   r�   r   c             C   s,   |j ƒ }|jƒ }| j||ƒ |j|jƒ dS )zWrite ECDSA private keyN)r'   r‰   rŒ   rk   Zprivate_value)r^   rƒ   r�   r'   r‰   r   r   r   rŽ   Ò  s    z_SSHFormatECDSA.encode_private)ru   rv   rw   rx   rf   r   ÚEllipticCurver_   rg   ry   r�   r   r(   r‚   r%   rŠ   rZ   rŒ   rŽ   r   r   r   r   r˜   –  s   
		r˜   c               @   sŒ   e Zd ZdZeejejef dœdd„Zeejej	ef dœdd„Z
eejejef dœdd„Zej	ed	d
œdd„Zejed	dœdd„Zd	S )Ú_SSHFormatEd25519z~Format for Ed25519 keys.

    Public:
        bytes point
    Private:
        bytes point
        bytes secret_and_point
    )r9   r   c             C   s   t |ƒ\}}|f|fS )zEd25519 public fields)rS   )r^   r9   r›   r   r   r   r   ç  s    z_SSHFormatEd25519.get_publicc             C   s(   | j |ƒ\\}}tjj|jƒ ƒ}||fS )z"Make Ed25519 public key from data.)r   r   r0   Zfrom_public_bytesrs   )r^   r9   r›   r'   r   r   r   r‚   î  s    
z_SSHFormatEd25519.load_publicc             C   sb   | j |ƒ\\}}t|ƒ\}}|dd… }|dd… }||ksF|f|krNtdƒ‚tjj|ƒ}||fS )z#Make Ed25519 private key from data.Nr    z$Corrupt data: ed25519 field mismatch)r   rS   r2   r   r/   Zfrom_private_bytes)r^   r9   r„   r›   Zkeypairr�   Zpoint2rƒ   r   r   r   rŠ   ø  s    z_SSHFormatEd25519.load_privateN)r'   r‹   r   c             C   s   |j tjtjƒ}|j|ƒ dS )zWrite Ed25519 public keyN)rž   r   ÚRawr   rj   )r^   r'   r‹   Úraw_public_keyr   r   r   rŒ     s    z_SSHFormatEd25519.encode_public)rƒ   r�   r   c             C   sR   |j ƒ }|jtjtjtƒ ƒ}|jtjtjƒ}t||gƒ}| j	||ƒ |j
|ƒ dS )zWrite Ed25519 private keyN)r'   Zprivate_bytesr   r¡   r   r   rž   r   rZ   rŒ   rj   )r^   rƒ   r�   r'   Zraw_private_keyr¢   Z	f_keypairr   r   r   rŽ     s    z _SSHFormatEd25519.encode_private)ru   rv   rw   rx   rg   ry   r�   r   r   r0   r‚   r/   rŠ   rZ   rŒ   rŽ   r   r   r   r   r    Ý  s   	r    s   nistp256s   nistp384s   nistp521)r3   c             C   s8   t | tƒst| ƒjƒ } | tkr&t|  S td| ›�ƒ‚dS )z"Return valid format or throw errorzUnsupported key type: N)r$   rf   rg   rs   Ú_KEY_FORMATSr   )r3   r   r   r   Ú_lookup_kformat*  s
    
r¤   )r9   r   Úbackendr   c             C   sj  t jd| ƒ |dk	r t jd|ƒ tj| ƒ}|s6tdƒ‚|jdƒ}|jdƒ}tj	t
| ƒ||… ƒ} | jtƒsrtdƒ‚t
| ƒttƒd… } t| ƒ\}} t| ƒ\}} t| ƒ\}} t| ƒ\}	} |	dkrÆtdƒ‚t| ƒ\}
} t|
ƒ\}}
t|ƒ}|j|
ƒ\}}
t|
ƒ t| ƒ\}} t| ƒ ||fttfk�r¶|jƒ }|tk�rBtd|›�ƒ‚|tk�rZtd|›�ƒ‚t| d	 }t||ƒ t|ƒ\}}t|ƒ\}}t|ƒ t|||jƒ |ƒ}t
|jƒ j|ƒƒ}nd
}t||ƒ t|ƒ\}}t|ƒ\}}||k�rîtdƒ‚t|ƒ\}}||k�rtdƒ‚|j||ƒ\}}t|ƒ\}}|tdt|ƒ… k�rFtdƒ‚t|tj ƒ�rft!j"dt j#dd� |S )z.Load private key from OpenSSH custom encoding.r9   Nr   zNot OpenSSH private key formatr   zOnly one key supportedzUnsupported cipher: zUnsupported KDF: é   rP   zCorrupt data: broken checksumzCorrupt data: key type mismatchzCorrupt data: invalid paddingzDSSH DSA keys are deprecated and will be removed in a future release.é   )Ú
stacklevel)$r   Ú_check_byteslikeÚ_check_bytesÚ_PEM_RCÚsearchr2   rq   ÚendÚbinasciiÚ
a2b_base64rg   Ú
startswithÚ	_SK_MAGICrA   rS   rO   r¤   r   rC   Ú_NONErs   rE   r   Ú_BCRYPTrB   rI   Z	decryptorÚupdaterŠ   Ú_PADDINGr$   r   r,   ÚwarningsÚwarnÚDeprecatedIn40)r9   r   r¥   ÚmÚp1Úp2rD   ÚkdfnameZ
kdfoptionsÚnkeysZpubdataZpub_key_typeÚkformatr„   ZedataZciphername_bytesÚblklenr   Zkbufr   ÚciphZck1Zck2r3   rƒ   Úcommentr   r   r   Úload_ssh_private_key;  st    









rÂ   )rƒ   r   Úencryption_algorithmr   c             C   sè  t jd|ƒ t| tjƒr*tjdt jdd� t| ƒ}t	|ƒ}t
ƒ }|r¤t}t| d }t}t}	t|tƒrv|jdk	rv|j}	tjdƒ}
|j|
ƒ |j|	ƒ t|||
|	ƒ}nt }}d}d}d	}tjdƒ}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 |ƒ || }|dk	�rØ|j!ƒ j"|||… ||d… ƒ t#|d|… ƒS )z3Serialize private key with OpenSSH custom encoding.r   zISSH DSA key support is deprecated and will be removed in a future releaserJ   )r¨   r¦   Nr   rP   r   r<   )$r   rª   r$   r   r,   r¶   r·   r¸   r4   r¤   rZ   Ú_DEFAULT_CIPHERrE   r³   Ú_DEFAULT_ROUNDSr   Z_kdf_roundsÚosÚurandomrj   rd   rI   r²   rŒ   r'   rŽ   ra   rµ   ri   r±   rg   rh   rr   Z	encryptorZupdate_intor?   )rƒ   r   rÃ   r3   r¾   Zf_kdfoptionsrD   r¿   r¼   r   r   rÀ   r½   ZcheckvalrÁ   Zf_public_keyZ	f_secretsZf_mainÚslenÚmlenrt   Zofsr   r   r   Ú_serialize_ssh_private_key�  sf    

















 rÊ   c               @   s   e Zd ZdZdZdS )ÚSSHCertificateTyper   r§   N)ru   rv   rw   ÚUSERZHOSTr   r   r   r   rË   ë  s   rË   c               @   sH  e Zd Zeeeeeeje eeej	eef ej	eef eeeeeeedœdd„Z
eedœdd„ƒZedœdd„Zeedœd	d
„ƒZeedœdd„ƒZeedœdd„ƒZeeje dœdd„ƒZeedœdd„ƒZeedœdd„ƒZeej	eef dœdd„ƒZeej	eef dœdd„ƒZedœdd„Zedœdd„Zddœdd„ZdS ) ÚSSHCertificate)Ú_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�   || _ || _|| _yt|ƒ| _W n tk
r<   tdƒ‚Y nX || _|| _|| _|| _	|	| _
|
| _|| _|| _|| _|| _|| _|| _|| _d S )NzInvalid certificate type)rÎ   rÏ   rÐ   rË   Ú_typer2   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_   ñ  s(    zSSHCertificate.__init__)r   c             C   s
   t | jƒS )N)rf   rÎ   )r^   r   r   r   Únonce  s    zSSHCertificate.noncec             C   s   t jt| jƒS )N)ry   ÚcastÚSSHCertPublicKeyTypesrÏ   )r^   r   r   r   r'     s    zSSHCertificate.public_keyc             C   s   | j S )N)rÐ   )r^   r   r   r   Úserial#  s    zSSHCertificate.serialc             C   s   | j S )N)rß   )r^   r   r   r   Útype'  s    zSSHCertificate.typec             C   s
   t | jƒS )N)rf   rÒ   )r^   r   r   r   Úkey_id+  s    zSSHCertificate.key_idc             C   s   | j S )N)rÓ   )r^   r   r   r   Úvalid_principals/  s    zSSHCertificate.valid_principalsc             C   s   | j S )N)rÕ   )r^   r   r   r   Úvalid_before3  s    zSSHCertificate.valid_beforec             C   s   | j S )N)rÔ   )r^   r   r   r   Úvalid_after7  s    zSSHCertificate.valid_afterc             C   s   | j S )N)rÖ   )r^   r   r   r   Úcritical_options;  s    zSSHCertificate.critical_optionsc             C   s   | j S )N)r×   )r^   r   r   r   Ú
extensions?  s    zSSHCertificate.extensionsc             C   s&   t | jƒ}|j| jƒ\}}t|ƒ |S )N)r¤   rØ   r‚   rÙ   rC   )r^   Z	sigformatÚsignature_keyZsigkey_restr   r   r   rë   C  s    
zSSHCertificate.signature_keyc             C   s"   t | jƒd tjt | jƒdd� S )Nó    F)Únewline)rf   rÝ   r®   Ú
b2a_base64rÞ   )r^   r   r   r   rž   I  s    zSSHCertificate.public_bytesNc             C   s   | j ƒ }t|tjƒr.|jt| jƒt| jƒƒ nÎt|tj	ƒrŽt
| jƒ\}}t
|ƒ\}}t|ƒ tj||ƒ}t|jƒ}|j|t| jƒtj|ƒƒ nnt|tjƒsžt‚| jtkr²tjƒ }n*| jtkrÆtjƒ }n| jtksÔt‚tjƒ }|jt| jƒt| jƒtjƒ |ƒ d S )N)rë   r$   r   r0   Úverifyrf   rÛ   rÜ   r   r(   rV   rC   Ú
asym_utilsZencode_dss_signatureÚ_get_ec_hash_algr5   ÚECDSAr
   r*   ÚAssertionErrorrÚ   r+   r   ÚSHA1Ú_SSH_RSA_SHA256ÚSHA256Ú_SSH_RSA_SHA512ÚSHA512r	   ÚPKCS1v15)r^   rë   Úrr9   ÚsZcomputed_sigÚhash_algr   r   r   Úverify_cert_signatureP  s0    




z$SSHCertificate.verify_cert_signature)ru   rv   rw   rg   r"   rM   ry   rz   rf   ÚDictr_   Úpropertyrà   râ   r'   rã   rË   rä   rå   ræ   rç   rè   ré   rê   rë   rž   rý   r   r   r   r   rÍ   ð  sN   rÍ   )r5   r   c             C   sD   t | tjƒrtjƒ S t | tjƒr(tjƒ S t | tjƒs8t‚tj	ƒ S d S )N)
r$   r   Ú	SECP256R1r   rö   Ú	SECP384R1ÚSHA384Ú	SECP521R1ró   rø   )r5   r   r   r   rñ   q  s    rñ   c       "      C   sˆ  t jd| ƒ tj| ƒ}|s"tdƒ‚|jdƒ }}|jdƒ}d}|jtƒr^d}|d ttƒ … }|t	krt| rtt
dƒ‚t|ƒ}yttj|ƒƒ}W n" ttjfk
r°   tdƒ‚Y nX |rº|}	t|ƒ\}
}|
|krÖtd	ƒ‚|ræt|ƒ\}}|j|ƒ\}}|�rxt|ƒ\}}t|ƒ\}}t|ƒ\}}t|ƒ\}}g }x&|�rTt|ƒ\}}|jt|ƒƒ �q0W t|ƒ\}}t|ƒ\}}t|ƒ\}}t|ƒ}t|ƒ\}}t|ƒ}t|ƒ\}}t|ƒ\}}t|ƒ\}}|t	k�rÔ| �rÔt
d
ƒ‚|	d t|ƒ … }t|ƒ\}}t|ƒ t|ƒ\}} |tk�r |tttgk�s4|tk�r<||k�r<tdƒ‚t| ƒ\}!} t| ƒ t||||||||||||||!|||	ƒS t|ƒ |S d S )Nr9   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Úmatchr2   ÚgroupÚendswithÚ_CERT_SUFFIXrA   r.   r   r¤   rg   r®   r¯   Ú	TypeErrorÚErrorrS   r‚   rQ   rO   r`   rf   Ú_parse_exts_optsrC   r+   rõ   r÷   rÍ   )"r9   Ú_legacy_dsa_allowedr¹   r3   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ê   Ú_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œ    



r  c             C   s   t | ƒS )N)r  )r9   r   r   r   Úload_ssh_public_identityÚ  s    r  )Ú	exts_optsr   c             C   sn   i }d }x`| rht | ƒ\}} t|ƒ}||kr2tdƒ‚|d k	rJ||k rJtdƒ‚t | ƒ\}} t|ƒ||< |}q
W |S )NzDuplicate namezFields not lexically sorted)rS   rf   r2   )r  ÚresultÚ	last_namer6   ZbnameÚvaluer   r   r   r  à  s    r  )r9   r¥   r   c             C   sF   t | dd�}t|tƒr |jƒ }n|}t|tjƒrBtjdtj	dd� |S )NT)r  zDSSH DSA keys are deprecated and will be removed in a future release.r§   )r¨   )
r  r$   rÍ   r'   r   r-   r¶   r·   r   r¸   )r9   r¥   Zcert_or_keyr'   r   r   r   Úload_ssh_public_keyð  s    

r  c             C   sl   t | tjƒrtjdtjdd� t| ƒ}t|ƒ}t	ƒ }|j
|ƒ |j| |ƒ tj|jƒ ƒjƒ }dj|d|gƒS )z&One-line public key format for OpenSSHzISSH DSA key support is deprecated and will be removed in a future releaserJ   )r¨   r<   rì   )r$   r   r-   r¶   r·   r   r¸   r4   r¤   rZ   rj   rŒ   r®   rî   rs   Ústripr=   )r'   r3   r¾   r‹   Zpubr   r   r   Úserialize_ssh_public_key  s    
r  é   c               @   sR  e Zd Zddddg dddg g f
eje eje eje eje ej	e e
eje eje ej	ejeef  ej	ejeef  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j	e d dœdd„Zdd„ Zejeef d dœdd„Zejeef d dœdd„Zeed dœdd„Zeed dœd d!„Zeed"œd#d$„ZdS )%ÚSSHCertificateBuilderNF)
rÏ   rÐ   rß   rÒ   rÓ   Ú_valid_for_all_principalsrÕ   rÔ   rÖ   r×   c             C   s@   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	d S )N)
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_   %  s    zSSHCertificateBuilder.__init__)r'   r   c             C   s^   t |tjtjtjfƒstdƒ‚| jd k	r0t	dƒ‚t
|| j| j| j| j| j| j| j| j| jd�
S )NzUnsupported key typezpublic_key already set)
rÏ   rÐ   rß   rÒ   rÓ   r  rÕ   rÔ   rÖ   r×   )r$   r   r(   r
   r*   r   r0   r	  rÏ   r2   r  rÐ   rß   rÒ   rÓ   r  rÕ   rÔ   rÖ   r×   )r^   r'   r   r   r   r'   =  s&    

z SSHCertificateBuilder.public_key)rã   r   c             C   sr   t |tƒstdƒ‚d|  ko$dk n  s2tdƒ‚| jd k	rDtdƒ‚t| j|| j| j| j	| j
| j| j| j| jd�
S )	Nzserial must be an integerr   r§   é@   z"serial must be between 0 and 2**64zserial already set)
rÏ   rÐ   rß   rÒ   rÓ   r  rÕ   rÔ   rÖ   r×   l            )r$   rM   r	  r2   rÐ   r  rÏ   rß   rÒ   rÓ   r  rÕ   rÔ   rÖ   r×   )r^   rã   r   r   r   rã   Y  s"    

zSSHCertificateBuilder.serial)rä   r   c             C   sR   t |tƒstdƒ‚| jd k	r$tdƒ‚t| j| j|| j| j	| j
| j| j| j| jd�
S )Nz"type must be an SSHCertificateTypeztype already set)
rÏ   rÐ   rß   rÒ   rÓ   r  rÕ   rÔ   rÖ   r×   )r$   rË   r	  rß   r2   r  rÏ   rÐ   rÒ   rÓ   r  rÕ   rÔ   rÖ   r×   )r^   rä   r   r   r   rä   n  s    

zSSHCertificateBuilder.type)rå   r   c             C   sR   t |tƒstdƒ‚| jd k	r$tdƒ‚t| j| j| j|| j	| j
| j| j| j| jd�
S )Nzkey_id must be byteszkey_id already set)
rÏ   rÐ   rß   rÒ   rÓ   r  rÕ   rÔ   rÖ   r×   )r$   rf   r	  rÒ   r2   r  rÏ   rÐ   rß   rÓ   r  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 ƒƒ s(| r0tdƒ‚| jr>tdƒ‚t|ƒtkrRt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 )N)r$   rf   )Ú.0r—   r   r   r   ú	<genexpr>�  s    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_principals)
rÏ   rÐ   rß   rÒ   rÓ   r  rÕ   rÔ   rÖ   r×   )r  r2   Úallr	  rÓ   rA   Ú_SSHKEY_CERT_MAX_PRINCIPALSr  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 setT)
rÏ   rÐ   rß   rÒ   rÓ   r  rÕ   rÔ   rÖ   r×   )rÓ   r2   r  r  rÏ   rÐ   rß   rÒ   rÕ   rÔ   rÖ   r×   )r^   r   r   r   Úvalid_for_all_principals¸  s     z.SSHCertificateBuilder.valid_for_all_principals)rç   r   c             C   sv   t |ttfƒstdƒ‚t|ƒ}|dk s.|dkr6tdƒ‚| jd k	rHtdƒ‚t| j| j| j	| j
| j| j|| j| j| jd�
S )	Nz$valid_before must be an int or floatr   r§   r  zvalid_before must [0, 2**64)zvalid_before already set)
rÏ   rÐ   rß   rÒ   rÓ   r  rÕ   rÔ   rÖ   r×   l            )r$   rM   Úfloatr	  r2   rÕ   r  rÏ   rÐ   rß   rÒ   rÓ   r  rÔ   rÖ   r×   )r^   rç   r   r   r   rç   Î  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 k	rHtdƒ‚t| j| j| j	| j
| j| j| j|| j| jd�
S )	Nz#valid_after must be an int or floatr   r§   r  zvalid_after must [0, 2**64)zvalid_after already set)
rÏ   rÐ   rß   rÒ   rÓ   r  rÕ   rÔ   rÖ   r×   l            )r$   rM   r#  r	  r2   rÔ   r  rÏ   rÐ   rß   rÒ   rÓ   r  rÕ   rÖ   r×   )r^   rè   r   r   r   rè   æ  s$    
z!SSHCertificateBuilder.valid_after)r6   r  r   c             C   sv   t |tƒ st |tƒ r tdƒ‚|dd„ | jD ƒkr<tdƒ‚t| j| j| j| j	| j
| j| j| j| j||fg | jd�
S )Nzname and value must be bytesc             S   s   g | ]\}}|‘qS r   r   )r  r6   r  r   r   r   ú
<listcomp>  s    z=SSHCertificateBuilder.add_critical_option.<locals>.<listcomp>zDuplicate critical option name)
rÏ   rÐ   rß   rÒ   rÓ   r  rÕ   rÔ   rÖ   r×   )r$   rf   r	  rÖ   r2   r  rÏ   rÐ   rß   rÒ   rÓ   r  rÕ   rÔ   r×   )r^   r6   r  r   r   r   Úadd_critical_optionþ  s    z)SSHCertificateBuilder.add_critical_optionc             C   sv   t |tƒ st |tƒ r tdƒ‚|dd„ | jD ƒkr<tdƒ‚t| j| j| j| j	| j
| j| j| j| j| j||fg d�
S )Nzname and value must be bytesc             S   s   g | ]\}}|‘qS r   r   )r  r6   r  r   r   r   r$    s    z7SSHCertificateBuilder.add_extension.<locals>.<listcomp>zDuplicate extension name)
rÏ   rÐ   rß   rÒ   rÓ   r  rÕ   rÔ   rÖ   r×   )r$   rf   r	  r×   r2   r  rÏ   rÐ   rß   rÒ   rÓ   r  rÕ   rÔ   rÖ   )r^   r6   r  r   r   r   Úadd_extension  s    z#SSHCertificateBuilder.add_extension)rƒ   r   c             C   s¤  t |tjtjtjfƒstdƒ‚| jd kr0t	dƒ‚| j
d kr>dn| j
}| jd krVt	dƒ‚| jd krddn| j}| j r‚| j r‚t	dƒ‚| jd kr”t	dƒ‚| jd kr¦t	dƒ‚| j| jkrºt	d	ƒ‚| jjd
d„ d� | jjdd„ d� t| jƒ}|t }tjdƒ}t|ƒ}tƒ }|j|ƒ |j|ƒ |j| j|ƒ |j|ƒ |j| jjƒ |j|ƒ tƒ }	x| jD ]}
|	j|
ƒ �qZW |j|	jƒ ƒ |j| jƒ |j| jƒ tƒ }x(| jD ]\}}|j|ƒ |j|ƒ �q¢W |j|jƒ ƒ tƒ }x(| jD ]\}}|j|ƒ |j|ƒ �qàW |j|jƒ ƒ |jdƒ t|ƒ}t|ƒ}tƒ }|j|ƒ |j|j ƒ |ƒ |j|jƒ ƒ t |tjƒ�rž|j!|jƒ ƒ}tƒ }|j|ƒ |j|ƒ |j|jƒ ƒ nØt |tjƒ�r"t"|j#ƒ}|j!|jƒ tj$|ƒƒ}t%j&|ƒ\}}tƒ }|j|ƒ tƒ }|j'|ƒ |j'|ƒ |j|jƒ ƒ |j|jƒ ƒ nTt |tjƒ�s4t(‚tƒ }|jt)ƒ |j!|jƒ t*j+ƒ t,j-ƒ ƒ}|j|ƒ |j|jƒ ƒ t.j/|jƒ ƒj0ƒ }t1j2t3t4dj5|d|gƒƒƒS )NzUnsupported private key typezpublic_key must be setr   ztype must be setr<   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>U  s    z,SSHCertificateBuilder.sign.<locals>.<lambda>)r#   c             S   s   | d S )Nr   r   )r—   r   r   r   r'  V  s    r    rì   )6r$   r   r%   r
   r)   r   r/   r	  rÏ   r2   rÐ   rß   rÒ   rÓ   r  rÕ   rÔ   rÖ   Úsortr×   r4   r  rÆ   rÇ   r¤   rZ   rj   rŒ   re   rd   r  rs   r'   Úsignrñ   r5   rò   rð   Zdecode_dss_signaturerk   ró   r÷   r	   rù   r   rø   r®   rî   r  ry   rá   rÍ   r  r=   )r^   rƒ   rã   rå   r3   Zcert_prefixrà   r¾   ÚfZfprincipalsr‡   Zfcritr6   r  ZfextZca_typeZcaformatZcafr  Zfsigrü   rú   rû   ZfsigblobZ	cert_datar   r   r   r)  *  sª    






















zSSHCertificateBuilder.sign)ru   rv   rw   ry   r{   râ   rM   rË   rf   rz   Úboolr�   r_   r'   rã   rä   rå   ræ   r"  r|   r#  rç   rè   r%  r&  ÚSSHCertPrivateKeyTypesrÍ   r)  r   r   r   r   r  $  s6   n"r  )Fé   )r!   r"   )N)F)N)|r®   ÚenumrÆ   Úrery   r¶   Úbase64r   r>   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   Z,cryptography.hazmat.primitives.serializationr   r   r   r   r   r   Zbcryptr   r   Z_bcrypt_supportedÚImportErrorrf   rM   r+  r1   r+   r.   Z_ECDSA_NISTP256Z_ECDSA_NISTP384Z_ECDSA_NISTP521r  rõ   r÷   Úcompiler  r±   Z	_SK_STARTZ_SK_ENDr³   r²   rÄ   rÅ   ÚDOTALLr«   rg   rh   Úrangerµ   ZAESZCTRZCBCrE   rþ   r�   ÚTyper|   r7   r4   r(   r&   r?   rB   rC   r{   rI   rO   rQ   rS   rV   rY   rZ   r}   r�   r˜   r    r   r  r  r£   r¤   r%   r)   r,   r/   r!   ÚAnyrÂ   rÊ   r*   r-   r0   r"   râ   ÚEnumrË   rÍ   rŸ   ZHashAlgorithmrñ   r  r  r  r  r  r,  r!  r  r   r   r   r   Ú<module>   sâ     	
R 

8FHGD	
RI

 ]
