o
    RDi                     @  s   d dl m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	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 dd	lmZmZmZmZ dd
lmZ ddlmZ eejj d Z e
rfddl!m"Z" ee#Z$dddZ%G dd dZ&dS )    )annotationsN)	getLogger)IOTYPE_CHECKING)default_backend)Cipher
algorithmsmodes   )PKCS5_OFFSET	PKCS5_PADPKCS5_UNPAD)UTF8EncryptionMetadataMaterialDescriptorkilobyte)owner_rw_opener)random_string   )SnowflakeFileEncryptionMaterialmatdescr   returnstrc                 C  s(   t tj| jt | jt | jdddS )z.Convert Material Descriptor to Unicode String.)queryIdsmkIdkeySize),:)
separators)r   jsondumpsquery_idsmk_idkey_size)r    r$   \/var/www/Datamplify/venv/lib/python3.10/site-packages/snowflake/connector/encryption_util.pymatdesc_to_unicode   s   r&   c                   @  sx   e Zd Zed"ddZede fd#ddZede dfd$ddZede fd%ddZede ddfd&d d!Z	dS )'SnowflakeEncryptionUtilbyte_lengthintr   bytesc                 C  s
   t | S )N)osurandom)r(   r$   r$   r%   get_secure_random*   s   
z)SnowflakeEncryptionUtil.get_secure_random@   encryption_materialr   src	IO[bytes]out
chunk_sizer   c                 C  s^  t t}t| j}t|}|d| tt	}t|}t
 }	tt|t||	d}
|
 }d}	 ||}t|dkrAnt|t	 dkrPt|t	}d}||| q5|sj||t	tt	t  ||  tt|t |	d}
|
 }|t|t	|  }t| j| j|d d}tt|dt|dt |d	}|S )
a  Reads content from src and write the encrypted content into out.

        This function is sensitive to current position of src and out.
        It does not seek to position 0 in neither stream objects before or after the encryption.

        Args:
            encryption_material: The encryption material for file.
            src: The input stream.
            out: The output stream.
            chunk_size: The size of read chunks (Default value = block_size * 4 * 1024

        Returns:
            The encryption metadata.
        zkey_size = %sbackendFTr   r   )r"   r!   r#   zutf-8)keyivr   )!r   __name__base64standard_b64decodequery_stage_master_keylendebugr'   r-   
block_sizer   r   r   AESr	   CBC	encryptorreadr   writeupdatechrencoder   finalizeECBr   r"   r!   r   	b64encodedecoder&   )r/   r0   r2   r3   loggerdecoded_keyr#   iv_datafile_keyr5   cipherrA   paddedchunkenc_kekmat_descmetadatar$   r$   r%   encrypt_stream.   sN   



z&SnowflakeEncryptionUtil.encrypt_streamNin_filenamer   tmp_dir
str | Nonetuple[EncryptionMetadata, str]c           
   	   C  s   t t}tjd|tj|d d\}}|d||| t|d3}t	|d}t
| |||}	W d   n1 s;w   Y  W d   |	|fS W d   |	|fS 1 sWw   Y  |	|fS )a  Encrypts a file in a temporary directory.

        Args:
            encryption_material: The encryption material for file.
            in_filename: The input file's name.
            chunk_size: The size of read chunks (Default value = block_size * 4 * 1024).
            tmp_dir: Temporary directory to use, optional (Default value = None).

        Returns:
            The encryption metadata and the encrypted file's location.
        F#)textdirprefixz0unencrypted file: %s, temp file: %s, tmp_dir: %srbwbN)r   r8   tempfilemkstempr+   pathbasenamer=   openfdopenr'   rU   )
r/   rV   r3   rW   rK   temp_output_fdtemp_output_fileinfileoutfilerT   r$   r$   r%   encrypt_fileq   s.   


z$SnowflakeEncryptionUtil.encrypt_filerT   Nonec                 C  s  | j }| j}t|j}t|}t|}	t }
tt|t	
 |
d}| }t|||  }tt|t	|	|
d}| }d}||}t|dkrm|dur[|| ||}|}||}t|dksR|durt|}||d|   ||  dS )z7To read from `src` stream then decrypt to `out` stream.r4   Nr   )r6   r7   r9   r:   r;   r   r   r   r?   r	   rH   	decryptorr   rD   rG   r@   rB   r<   rC   r   )rT   r/   r0   r2   r3   
key_base64	iv_base64rL   	key_bytesiv_bytesr5   rO   rl   rN   last_decrypted_chunkrQ   doffsetr$   r$   r%   decrypt_stream   s4   






z&SnowflakeEncryptionUtil.decrypt_streamFunsafe_file_writeboolc           
   	   C  s   t j| dt  }|rt j||}td|| |r dnt}t|d1}t|d|d}	t	
| |||	| W d   n1 sCw   Y  W d   |S W d   |S 1 s[w   Y  |S )a  Decrypts a file and stores the output in the temporary directory.

        Args:
            metadata: The file's metadata input.
            encryption_material: The file's encryption material.
            in_filename: The name of the input file.
            chunk_size: The size of read chunks (Default value = block_size * 4 * 1024).
            tmp_dir: Temporary directory to use, optional (Default value = None).

        Returns:
            The decrypted file's location.
        rZ   z encrypted file: %s, tmp file: %sNr^   r_   )opener)r+   rb   rc   r   joinrK   r=   r   rd   r'   rt   )
rT   r/   rV   r3   rW   ru   rg   file_openerrh   ri   r$   r$   r%   decrypt_file   s$   


z$SnowflakeEncryptionUtil.decrypt_file)r(   r)   r   r*   )
r/   r   r0   r1   r2   r1   r3   r)   r   r   )
r/   r   rV   r   r3   r)   rW   rX   r   rY   )rT   r   r/   r   r0   r1   r2   r1   r3   r)   r   rk   )rT   r   r/   r   rV   r   r3   r)   rW   rX   ru   rv   r   r   )
r8   
__module____qualname__staticmethodr-   r   rU   rj   rt   rz   r$   r$   r$   r%   r'   )   s$    B"&r'   )r   r   r   r   )'
__future__r   r9   r   r+   r`   loggingr   typingr   r   cryptography.hazmat.backendsr   &cryptography.hazmat.primitives.ciphersr   r   r	   compatr   r   r   	constantsr   r   r   r   	file_utilr   	util_textr   r)   r?   r>   storage_clientr   r8   rK   r&   r'   r$   r$   r$   r%   <module>   s&   
