U
    c#                     @   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rX|sX|d | }|dkrtdD ]}	t|d|  }qp|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    <i   s      2   )_encryption_paddingr   updatestructpackdigestrange)
passwordrevkeylenowner_entryp_entry	id1_entryencrypt_metadatammd5_hashi r   C/tmp/pip-unpacked-wheel-0kb_yl26/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_legacyF   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*   c   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     
r5   r3   c              	      s~   t | ||||||d}t }|t || | }	t||	}
tddD ]$ t fdd|D }t||
}
qL|
d |fS )r0   r3   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    	 


r6   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:
    r   Nr	   r1   r2   s   sAlT   )r   r   lenAssertionErrorr   r   min)r7   r8   r9   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*   r5   boolr6   intr>   r   r   r   r   <module>   s"   0+ 