U
    g"                     @   s   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Z	dd Z
eeef ed	d
dZdd Zdd Zdd ZedddZdeeeedddZdS )    N)md5)Union)generic)rc4_encrypts    (N^NuAd NV.. h>/dSizc           
      C   s   | t  dd } t| }|| td| }|| || |dkr\|s\|d | }|dkrtdD ]}	t|d|  }qt|d| S )z{
    Implementation of algorithm 3.2 of the PDF standard security handler,
    section 3.5.2 of the PDF 1.6 reference.
    N    z<I   s      2   )_encryption_paddingr   updatestructpackZ	as_uint32digestrange)
passwordrevkeylenowner_entryp_entry	id1_entryencrypt_metadatammd5_hashi r   C/tmp/pip-unpacked-wheel-owvgwkas/pyhanko/pdf_utils/crypt/_legacy.pyderive_legacy_file_key   s    



r   )r   returnc                 C   s,   t | trt| d d S | d d S d S )Nr   )
isinstancestrr   Zencode_pdfdocencoding)r   r   r   r   legacy_normalise_pw@   s    
r    c                    sb   t | ||}|t dd }t||}|dkr^tddD ]$ t fdd|D }t||}q8|S )z{
    Implementation of algorithm 3.3 of the PDF standard security handler,
    section 3.5.2 of the PDF 1.6 reference.
    Nr   r         c                 3   s   | ]}| A V  qd S Nr   .0br   r   r   	<genexpr>]   s     z)compute_o_value_legacy.<locals>.<genexpr>)compute_o_value_legacy_prepr
   r   r   bytes)Z	owner_pwdZuser_pwdr   r   keyvalnew_keyr   r'   r   compute_o_value_legacyG   s    
r.   c                 C   sR   | t  dd } t| }| }|dkrBtdD ]}t| }q0|d| }|S )z$
    Steps 1-4 of algorithm 3.3
    Nr   r   r	   )r
   r   r   r   )r   r   r   r   r   r   r+   r   r   r   r)   d   s    r)   c              	   C   s(   t | dd|||dd}t|t}||fS ){
    Implementation of algorithm 3.4 of the PDF standard security handler,
    section 3.5.2 of the PDF 1.6 reference.
          Tr   )r   r   r
   )r   r   r   r   r+   ur   r   r   compute_u_value_r2~   s          
r4   r2   c              	      s~   t | ||||||d}t }|t || | }	t||	}
tddD ]$ t fdd|D }t||
}
qL|
d |fS )r/   r2   r!   r"   c                 3   s   | ]}| A V  qd S r#   r   r$   r'   r   r   r(      s     z&compute_u_value_r34.<locals>.<genexpr>s                   )r   r   r   r
   r   r   r   r*   )r   r   r   r   r   r   r   r+   r   r   r,   r-   r   r'   r   compute_u_value_r34   s$    


r5   F)
shared_keyidnum
generationr   c                 C   s~   t d|dd }t d|dd }| | | }t|t| d ksLt|rX|d7 }t| }|dtdt| d  S )a  
    Function that does the key derivation for PDF's legacy security handlers.

    :param shared_key:
        Global file encryption key.
    :param idnum:
        ID of the object being written.
    :param generation:
        Generation number of the object being written.
    :param use_aes:
        Boolean indicating whether the security handler uses RC4 or AES(-128).
    :return:
    z<iNr   r0   r1   s   sAlT   )r   r   lenAssertionErrorr   r   min)r6   r7   r8   Zuse_aesZpack1Zpack2r+   r   r   r   r   legacy_derive_object_key   s    r=   )F)r   hashlibr   typingr   Zpyhanko.pdf_utilsr   Zpyhanko.pdf_utils.crypt._utilr   r
   r   r   r*   r    r.   r)   r4   boolr5   intr=   r   r   r   r   <module>   s(   19   