U
    gäVcK  ã                   @   s¤   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mZ d dl	m
Z
mZ d dlmZ d dlmZ d dlmZ d dlmZmZ d dlT G d	d
„ d
ejjƒZdS )é    N)ÚAESÚ
PKCS1_OAEP)ÚSHA256ÚSHA1)ÚRSA)Úget_random_bytes)Ú
PKCS1_v1_5)ÚpadÚunpad)Ú*c                   @   s„   e Zd ZdZdZedd„ ƒZedd„ ƒZdd„ Zd	d
„ Z	dd„ Z
dd„ Zedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZdd„ ZdS )ÚCmfAuthé    é
   c                 C   s   t  | j d¡d ¡S )Nú$éÿÿÿÿ©Úbase64Ú	b64decodeÚ	pass_hashÚsplit©Úself© r   ú*./contrib/auth/modules/auth/models/auth.pyÚkey   s    zCmfAuth.keyc                 C   s   t  | j d¡d ¡S )Nr   éþÿÿÿr   r   r   r   r   Úsalt   s    zCmfAuth.saltc                 C   s2   t  | j¡}|ttt ¡ ƒƒ7 }|| j ¡ 7 }|S ©N)ÚsecretsÚ	token_hexÚtoken_lengthÚstrÚintÚtimer   Úhex)r   Úserver_challenger   r   r   Úgen_server_challenge   s    zCmfAuth.gen_server_challengec                 C   sÒ   d| j d  }}|||… }||d  }}|||… }|t|ƒ }}t |||… ¡}t d| ¡ |d¡}	t | j ¡}
t	t
t ¡ ƒƒ}||
 | | }ttjƒ}t |	tj|¡}| t| ¡ tjƒ¡}||  ¡ S )Nr   é   r   Zsha256i † )r    ÚlenÚbytesÚfromhexÚhashlibZpbkdf2_hmacÚencoder   r   r!   r"   r#   r   r   Ú
block_sizeÚnewÚMODE_CBCZencryptr	   r$   )r   ÚloginZpasswordr%   ÚstartÚendÚserver_randomÚserver_timestampZserver_saltZtest_keyÚclient_randomZsecretÚivÚcipherZencrypted_secretr   r   r   Útest_gen_server_challenge_resp$   s&       ÿ
z&CmfAuth.test_gen_server_challenge_respc                 C   sh   dddœ}| j ttt ¡ d ƒƒ| jdœ}t t |¡ 	¡ ¡ 
¡ }t t |¡ 	¡ ¡ 
¡ }|› d|› S )NZRS256ZJWT)ZalgÚtypi / )r0   ÚexpÚscopeÚ.)r0   r!   r"   r#   Úgroupsr   Ú	b64encodeÚjsonÚdumpsr,   Údecode)r   ÚheaderÚpayloadr   r   r   Ú
create_jwt@   s    
ýzCmfAuth.create_jwtc                 C   sT   |   ¡ }t tj¡}t ¡ }| | ¡ ¡ | |¡}t	 
|¡ ¡ }|› d|› }|S )Nr<   )rD   r   r.   ÚAPPZrsa_private_keyr   Úupdater,   Úsignr   r>   rA   )r   ÚjwtZsignerÚdigestrG   Úresr   r   r   Úrsa_sign_pack_jwtK   s    
zCmfAuth.rsa_sign_pack_jwtc                 C   s˜   |   d¡\}}}t ¡ }|› d|› }| | ¡ ¡ t |¡}t tj	¡}| 
||¡}|s^d S t |¡ ¡ }t |¡ ¡ }t |¡}t |¡}||dœS )Nr<   )rB   rC   )r   r   r.   rF   r,   r   r   r   rE   Zrsa_public_keyZverifyrA   r?   Úloads)ÚrjwtrB   rC   Z	signaturerI   rH   ZverifierZverifiedr   r   r   Úrsa_verify_unpack_jwtV   s    


zCmfAuth.rsa_verify_unpack_jwtc              	   C   sÖ   t dƒ |st dƒ d S |  |¡}|s2t dƒ d S d}zt|d  dd¡ƒ}W n ttfk
rf   Y nX tj ¡  ¡ }||krŠt dƒ d S | ƒ }|d d |_	|d d |_
|d d	 |_t d
|j	› d|j› ƒ |S )Nzfrom_jwt: startzfrom_jwt: warn not jwtz2from_jwt: warn not cls.rsa_verify_unpack_jwt(rjwt)r   rC   r:   z)from_jwt: reset auth, cause token expiredr0   r;   zfrom_jwt: jwt is ok, z, )ÚprintrN   r"   ÚgetÚ	TypeErrorÚ
ValueErrorÚdatetimeÚnowZ	timestampr0   Úemailr=   )ÚclsrM   rH   r:   rT   Úobjr   r   r   Úfrom_jwtl   s.    
zCmfAuth.from_jwtc                 C   s  | j |d}|sd S t |¡}dtj }}|||… }|t|ƒ }}|||… }t |jtj|¡}| 	|¡}	t
|	tjƒ}
|
 ¡ }d|jd  }}|||… }|||jd   }}|||… }|||j  }}|||… }|t|ƒ }}|||… }t ¡ t|ƒ dkrd S |S )N)r0   r   r'   i€Q )rP   r)   r*   r   r-   r(   r.   r   r/   Zdecryptr
   rA   r    Ú	ts_lengthr#   r"   )rV   r0   Zchallenge_resprW   r1   r2   r6   Zencrypted_messager7   Zres0Zres1Zres2r3   r5   r4   r   r   r   Úget_by_challenge_resp‹   s.    

zCmfAuth.get_by_challenge_respc                 C   s"   | ƒ }||_ ||_| ||¡ |S r   )r0   rU   Úset_pass_hash)rV   r0   Úhashr   rW   r   r   r   Únew_from_login_hash_salt°   s
    z CmfAuth.new_from_login_hash_saltc                 C   sF   t  |¡}t  |¡}t |¡ ¡ }t |¡ ¡ }d|› d|› | _d S )Nzpbkdf2_sha256$100000$r   )r)   r*   r   r>   rA   r   )r   r\   r   Z
hash_bytesZ
salt_bytesZhash_b64Zsalt_b64r   r   r   r[   »   s    

ýzCmfAuth.set_pass_hashN)Ú__name__Ú
__module__Ú__qualname__r    rY   Úpropertyr   r   r&   r8   rD   rK   ÚstaticmethodrN   ÚclassmethodrX   rZ   r]   r[   r   r   r   r   r      s&   




$

r   )r   r+   r?   rS   r   r#   ZCrypto.Cipherr   r   ZCrypto.Hashr   r   ZCrypto.PublicKeyr   ZCrypto.Randomr   ZCrypto.Signaturer   ZCrypto.Util.Paddingr	   r
   Zcmf.includeZcmfZmodelsZCmfModelr   r   r   r   r   Ú<module>   s   