U
    *}f\                     @   s   d dl mZmZ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mZ d dlmZmZmZ d dlmZ G d	d
 d
eZdZG dd deZG dd deZdS )    )absolute_importdivisionprint_functionN)utils)InvalidSignature)_get_backend)hashespadding)Cipher
algorithmsmodes)HMACc                   @   s   e Zd ZdS )InvalidTokenN)__name__
__module____qualname__ r   r   7/tmp/pip-unpacked-wheel-x36vw73o/cryptography/fernet.pyr      s   r   <   c                   @   sp   e Zd ZdddZedd Zdd Zdd	 Zd
d ZdddZ	dd Z
dd Zedd Zdd Zdd ZdS )FernetNc                 C   sL   t |}t|}t|dkr&td|d d | _|dd  | _|| _d S )N    z4Fernet key must be 32 url-safe base64-encoded bytes.   )r   base64urlsafe_b64decodelen
ValueError_signing_key_encryption_key_backend)selfkeybackendr   r   r   __init__   s    
zFernet.__init__c                 C   s   t tdS )Nr   )r   urlsafe_b64encodeosurandom)clsr   r   r   generate_key,   s    zFernet.generate_keyc                 C   s   |  |tt S Nencrypt_at_timeinttime)r   datar   r   r   encrypt0   s    zFernet.encryptc                 C   s   t d}| |||S )Nr   )r$   r%   _encrypt_from_parts)r   r-   current_timeivr   r   r   r*   3   s    
zFernet.encrypt_at_timec                 C   s   t d| ttjj }|||	  }t
t| jt|| j }|||	  }dtd| | | }t| jt | jd}	|	| |		 }
t||
 S )Nr-      >Qr!   )r   _check_bytesr	   PKCS7r   AES
block_sizepadderupdatefinalizer
   r   r   CBCr   	encryptorstructpackr   r   r   SHA256r   r#   )r   r-   r0   r1   r9   Zpadded_datar=   
ciphertextZbasic_partshhmacr   r   r   r/   7   s    
  
zFernet._encrypt_from_partsc                 C   s&   t |\}}| |||tt S r(   )r   _get_unverified_token_data_decrypt_datar+   r,   )r   tokenttl	timestampr-   r   r   r   decryptJ   s    zFernet.decryptc                 C   s.   |d krt dt|\}}| ||||S )Nz6decrypt_at_time() can only be used with a non-None ttl)r   r   rD   rE   )r   rF   rG   r0   rH   r-   r   r   r   decrypt_at_timeN   s    zFernet.decrypt_at_timec                 C   s   t |\}}| | |S r(   )r   rD   _verify_signature)r   rF   rH   r-   r   r   r   extract_timestampV   s    
zFernet.extract_timestampc              	   C   s   t d|  zt| }W n ttjfk
r8   tY nX |rNt	|ddkrRtzt
d|dd \}W n t
jk
r   tY nX ||fS )NrF   r      r3      	   )r   r5   r   r   	TypeErrorbinasciiErrorr   six
indexbytesr>   unpackerror)rF   r-   rH   r   r   r   rD   \   s    

z!Fernet._get_unverified_token_datac                 C   s\   t | jt | jd}||d d  z||dd   W n tk
rV   tY nX d S )Nr4   )	r   r   r   r@   r   r:   verifyr   r   )r   r-   rB   r   r   r   rK   m   s    zFernet._verify_signaturec                 C   s   |d k	r(|| |k rt |t |k r(t | | |dd }|dd }tt| jt|| j	
 }||}z|| 7 }W n tk
r   t Y nX ttjj }	|	|}
z|
|	 7 }
W n tk
r   t Y nX |
S )NrO      rW   )r   _MAX_CLOCK_SKEWrK   r
   r   r7   r   r   r<   r   	decryptorr:   r;   r   r	   r6   r8   unpadder)r   r-   rH   rG   r0   r1   rA   r[   Zplaintext_paddedr\   Zunpaddedr   r   r   rE   u   s2    

  



zFernet._decrypt_data)N)N)r   r   r   r"   classmethodr'   r.   r*   r/   rI   rJ   rL   staticmethodrD   rK   rE   r   r   r   r   r      s   



r   c                   @   s>   e Zd Zdd Zdd Zdd Zdd Zdd
dZdd Zd	S )MultiFernetc                 C   s   t |}|std|| _d S )Nz1MultiFernet requires at least one Fernet instance)listr   _fernets)r   Zfernetsr   r   r   r"      s    zMultiFernet.__init__c                 C   s   |  |tt S r(   r)   )r   msgr   r   r   r.      s    zMultiFernet.encryptc                 C   s   | j d ||S )Nr   )ra   r*   )r   rb   r0   r   r   r   r*      s    zMultiFernet.encrypt_at_timec              	   C   sl   t |\}}| jD ]4}z|||d d }W  qNW q tk
rF   Y qX qttd}| jd |||S )Nr   r   )r   rD   ra   rE   r   r$   r%   r/   )r   rb   rH   r-   fpr1   r   r   r   rotate   s    


zMultiFernet.rotateNc              	   C   s<   | j D ],}z|||W   S  tk
r0   Y qX qtd S r(   )ra   rI   r   )r   rb   rG   rc   r   r   r   rI      s    
zMultiFernet.decryptc              	   C   s>   | j D ].}z||||W   S  tk
r2   Y qX qtd S r(   )ra   rJ   r   )r   rb   rG   r0   rc   r   r   r   rJ      s    
zMultiFernet.decrypt_at_time)N)	r   r   r   r"   r.   r*   re   rI   rJ   r   r   r   r   r_      s   
r_   )
__future__r   r   r   r   rQ   r$   r>   r,   rS   Zcryptographyr   Zcryptography.exceptionsr   Zcryptography.hazmat.backendsr   Zcryptography.hazmat.primitivesr   r	   Z&cryptography.hazmat.primitives.ciphersr
   r   r   Z#cryptography.hazmat.primitives.hmacr   	Exceptionr   rZ   objectr   r_   r   r   r   r   <module>   s    u