o
    vhZ                  	   @   s2  d dl Z d dlZd dlmZ d dlmZmZmZmZm	Z	m
Z
 d dlmZmZmZ d dlmZ d dlmZmZmZ d dlmZ d dlmZmZ d	d
lmZmZmZmZmZmZm Z m!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-m.Z. ddlm/Z/ ddl0m1Z1 ddl2m3Z3 ddl4m5Z5 g dZ6e-e/de/ddddde.j7dZ8e9g dZ:	 G dd  d eZ;G d!d" d"Z<d#e5d$e=d%ee= fd&d'Z>d(d) Z?d*d+ Z@d,ejAd-ejBfd.d/ZCd-e	ejBe=f fd0d1ZDe:e<fd2e1d3eeE d4e
e< fd5d6ZFG d7d8 d8e#ZGd9ddejHfd:e3d;eEfd<d=ZIdS )>    N)compare_digest)AnyDict	FrozenSetOptionalTupleType)algoscmscore)VOID)hasheshmackeywrap)hkdf)genericmisc   )CMSStructuralErrorMultivaluedAttributeErrorNonexistentAttributeErrorValueErrorWithMessagebyte_range_digestfind_unique_cms_attributeget_pyca_cryptography_hashsimple_cms_attribute)PdfByteRangeDigestPreparedByteRangeDigest)CMSAlgorithmProtectionErrorDisallowedAlgorithmError)validate_algorithm_protection)extract_contents   )DeveloperExtensionDevExtensionMultivalued)pdf_name)PdfFileReader)BasePdfFileWriter   )PdfMacIntegrityInfo)PdfMacTokenHandlervalidate_pdf_macadd_standalone_macISO32004ALLOWED_MD_ALGSz/ISO_z/2.0i}  z:2024z'https://www.iso.org/standard/45877.htmlF)prefix_namebase_versionextension_levelextension_revisionurlcompare_by_levelmultivalued)sha256sha3_256sha384sha3_384sha512sha3_512shake256c                   @   s   e Zd ZdS )PdfMacValidationErrorN)__name__
__module____qualname__ rA   rA   \/var/www/html/hyperkenya/venv/lib/python3.10/site-packages/pyhanko/pdf_utils/crypt/pdfmac.pyr=   J   s    r=   c                   @   s  e Zd ZdZeddiZdd Zede	de	de
fd	d
Zeefde	de	dejdee
 fddZdedefddZede	de	de	fddZde	dejfddZdedee	ejf fddZde	dee	 dee	e	f fddZdejd e	d!ejd"e	dejf
d#d$Zd%e	d&e	de	fd'd(Zd)d*de	dee	 dedejfd+d,Zd-ejde	fd.d/Z d0ejd1e!j"fd2d3Z#dejfd4d5Z$dejde%fd6d7Z&dejde	dee	 fd8d9Z'd:S );r*   a:  
    Internal utility class to create and validate PDF MAC tokens.

    .. warning::
        This is a class to simplify local overrides for creating test documents
        with various defects.

        Instances of this class should never be created or manipulated directly
        during regular operation.
    	algorithmr6   c                C   s   || _ || _d S Nmac_kekmd_algorithm)selfrF   rG   rA   rA   rB   __init__\   s   
zPdfMacTokenHandler.__init__file_encryption_keykdf_saltrG   c                 C   s   |  ||}| ||dS )NrE   )_derive_mac_kek)clsrJ   rK   rG   rF   rA   rA   rB   from_key_mat`   s   zPdfMacTokenHandler.from_key_mat	auth_dataallowed_mdsc           	      C   s\   |d }|d j }|dkrtd|d }|d j }||vr&t|tjdd| j|||dS )	Nmac_algorithmrC   r6   z:Only HMAC-SHA256 is currently supported for PDF MAC tokensdigest_algorithmT)oid_type	permanent)rJ   rK   rG   )nativeNotImplementedErrorr   r	   DigestAlgorithmIdrN   )	rM   rJ   rK   rO   rP   mac_algo_objmac_algodigest_algo_objmd_algorA   rA   rB   for_validationg   s&   	

z!PdfMacTokenHandler.for_validationinclude_signature_digestreturnc                 C   s8   t t| j }| j||r|nd dd}t| S )NT)document_digestsignature_digestdry_run)r   Hashr   rG   finalizebuild_pdfmac_tokenlendump)rH   r]   
dummy_hashdummy_tokenrA   rA   rB   determine_token_size   s   
z'PdfMacTokenHandler.determine_token_sizec                 C   s    t jt d|dd}||S )N    s   PDFMAC)rC   lengthsaltinfo)r   HKDFr   SHA256derive)rM   rJ   rK   kdfrA   rA   rB   rL      s   
z"PdfMacTokenHandler._derive_mac_kekmessage_digestc                 C   s@   t | jt d| jid}t tddtd|td|gS )NrC   )rQ   rR   content_typepdf_mac_integrity_inforr   cms_algorithm_protection)r
   CMSAlgorithmProtectionmac_algo_identDigestAlgorithmrG   CMSAttributesr   )rH   rr   algo_protectionrA   rA   rB   _format_auth_attrs   s   z%PdfMacTokenHandler._format_auth_attrsra   c              	   C   sb   |rt d}ntd}tj| j|d}td|t	ddit
ddid}|td|ifS )	Nrj   )wrapping_keykey_to_wrapr   rC   pdf_mac_wrap_kdfaes256_wrap)versionencrypted_keykey_derivation_algorithmkey_encryption_algorithmpwri)bytessecretstoken_bytesr   aes_key_wraprF   r
   PasswordRecipientInfor	   KdfAlgorithmKeyEncryptionAlgorithmRecipientInfo)rH   ra   mac_keyr   r   rA   rA   rB   _get_mac_keying_info   s&   

z'PdfMacTokenHandler._get_mac_keying_infor_   r`   c           	      C   s^   d|i}|d ur||d< d|d< t |}| }t| j}t|}|| | }||fS )Ndata_digestr`   r   r   )r)   rf   r   rG   r   rb   updaterc   )	rH   r_   r`   message_kwargsmessagemessage_bytesmd_specmd_funrr   rA   rA   rB   _format_message   s   


z"PdfMacTokenHandler._format_messagerecipient_infor   
auth_attrsmacc                 C   sD   t d|gt ddit d| jit dt|d||dS )Nr   rC   r6   rt   rs   content)r   recipient_infosrQ   rR   encap_content_infor   r   )r
   AuthenticatedDataHmacAlgorithmrx   rG   EncapsulatedContentInfor   ParsableOctetString)rH   r   r   r   r   rA   rA   rB   _format_auth_data   s    z$PdfMacTokenHandler._format_auth_datar   data_to_macc                 C   s$   t j|t d}|| | S )N)keyrC   )r   HMACr   ro   r   rc   )rH   r   r   hmac_funrA   rA   rB   compute_mac   s   
zPdfMacTokenHandler.compute_macFra   c                C   sb   | j |d\}}| ||\}}| |}| j||  d}	| j||||	d}
td|
dS )Nr   )r   r   )r   r   r   r   authenticated_datar   )	r   r   r{   r   untagrf   r   r
   ContentInfo)rH   r_   r`   ra   r   rir   rr   r   r   authed_datarA   rA   rB   rd     s"   
z%PdfMacTokenHandler.build_pdfmac_token
recp_infosc                 C   s   d }z|\}|j }W n	 ty   Y nw t|tjstd|d }|tu s-|d jdkr1td|d d }|jdkrEtd|j	d	|d
 j}zt
j| j|d}W |S  t
jya   tdw )NzWPDF MAC requires exactly one recipientInfo, which must be of PasswordRecipientInfo typer   rC   r~   z_PDF MAC tokens must have their key derivation algorithm explicitly identified as pdfMacWrapKdf.r   r   zPPDF MAC only supports unpadded 256-bit AES key wrapping for key encryption; not .r   )r|   wrapped_keyzFailed to unwrap MAC key)chosen
ValueError
isinstancer
   r   r=   r   rU   rV   dottedr   aes_key_unwraprF   InvalidUnwrap)rH   r   r   recprq   kea_objr   r   rA   rA   rB   _retrieve_mac_key  s@   


z$PdfMacTokenHandler._retrieve_mac_keyattrsencap_contentc              	   C   sh   t | j}t|}|t| | }zt|d}|j|kr$t	dW d S  t
tfy3   t	dw )Nrr   zMValue of messageDigest attribute does not match hash of encapsulated content.zcMessage digest not found in authenticated attributes, or multiple messageDigest attributes present.)r   rG   r   rb   r   r   rc   r   rU   r=   r   r   )rH   r   r   r   mdrr   claimed_message_digestrA   rA   rB   _validate_message_digestD  s$   


z+PdfMacTokenHandler._validate_message_digestc              
   C   st   |d }t | zt|d |d |d d W n ty* } ztd|j |d }~ww |d d }| j||d d S )	Nr   rR   rQ   )claimed_signature_algorithm_objclaimed_digest_algorithm_objclaimed_mac_algorithm_objz%CMS alg protection validation error: r   r   )r   )_validate_content_type_attrr    r   r=   failure_messager   )rH   rO   r   eint_info_objrA   rA   rB   _validate_auth_attrsZ  s&   
z'PdfMacTokenHandler._validate_auth_attrsc           	   
   C   s   |d }|t urtd|d }|d }| |}| j||  d}t||d js0tdz| | W n t	yK } ztd|j
 |d }~ww |d	 d
 j}|dkr[td|d	 d jS )Nunauth_attrsz5PDF MAC tokens cannot have unauthenticated attributesr   r   )r   r   zPDF MAC token has invalid MACzCMS structural error: r   rs   rt   z_The content type of the encapsulated content in a PDF MAC token must be id-pdfMacIntegrityInfo.r   )r   r=   r   r   r   rf   r   rU   r   r   r   parsed)	rH   rO   r   r   r   r   computed_macr   eci_ctrA   rA   rB   #_validate_and_extract_encap_contentq  s:   
z6PdfMacTokenHandler._validate_and_extract_encap_contentc                C   s   |  |}t||| d S rD   )r    _validate_pdf_mac_integrity_info)rH   rO   r_   r`   r   rA   rA   rB   validate_pdfmac_token_cms  s   
z,PdfMacTokenHandler.validate_pdfmac_token_cmsN)(r>   r?   r@   __doc__r
   r   rw   rI   classmethodr   strrN   r.   r   r   r\   boolintri   rL   ry   r{   r   r   r   r   r   r   r   r   rd   RecipientInfosr   r   r   r   r   r)   r   r   rA   rA   rA   rB   r*   N   s     





&

(r*   int_infor_   r`   c                 C   sh   | d j }||krtd| d }|d u r|turtdd S |j }|d u r*td||kr2tdd S )Nr   z;Document digest does not match value in PdfMacIntegrityInfor`   z;PdfMacIntegrityInfo contains an unexpected signature digestz6Could not find signature digest in PdfMacIntegrityInfoz<Signature digest does not match value in PdfMacIntegrityInfo)rU   r=   r   )r   r_   r`   claimed_data_digestsig_digest_objclaimed_signature_digestrA   rA   rB   r     s,   
r   c              	   C   sF   zt | d}|jdkrtd|jW d S  ttfy"   tdw )Nrs   rt   zRThe content type attribute of a PDF MAC token must be id-pdfMacIntegrityInfo, not z`Content type not found in authenticated attributes, or multiple content-type attributes present.)r   rU   r=   r   r   r   )r   rs   rA   rA   rB   r     s   

r   c           	      C   s   z|  d}W n ty   d }Y nw t|tjstdt|dkrC|\}}}}d| d }|dkrC|| |krC||| | krCd S td)N
/ByteRangez(No sensible /ByteRange found in AuthCode   r"   r   z;PDF MAC token must have /ByteRange covering the entire file)raw_getKeyErrorr   r   ArrayObjectr=   re   )	pdf_dictfile_lenpayload_len
byte_rangeo1l1o2l2value_lit_lenrA   rA   rB   _validate_byte_range  s"   r   ac_dictr^   c              	   C   sz   z|  dj}W n ttfy   tdw tj|}t|}t|	 }||kr5td| d| dt
| || |S )N/MACz'Failed to retrieve standalone MAC valuez<Standalone MACs must not have trailing CMS data: payload is z bytes long, but token is z bytes.)r   original_bytesr   AttributeErrorr=   r
   r   loadre   rf   r   )r   r   	mac_bytesmac_cir   	token_lenrA   rA   rB   _extract_standalone_mac  s$   r   c              
   C   s   zt | }W n tttjfy   tdw tj|}t	|}t
| || d }|d jdkrA|d }t	|d dkrA|d d }|d u rItdz	t|d	 d
}W n ttfy_   tdw ||d jfS )Nz%Failed to retrieve signature contentsrs   signed_datar   signer_infosr(   r   zQSignature dictionary must contain a SignedData message with exactly 1 signerInfo.unsigned_attrspdf_mac_dataz;Signature must have exactly 1 pdfMacData unsigned attribute	signature)r!   r   r   r   PdfReadErrorr=   r
   r   r   re   r   rU   r   r   r   )sig_dictr   	sig_bytessig_cir   signer_infosdr   rA   rA   rB   _extract_mac_in_sig  s6   r   readerrP   handler_clsc              
   C   s$  z| j d}W n ty   d }Y nw t|tjrtdt|tjs(tdd}d}z|d}t|tjrE|dkr?d}n|dkrEd}W n	 tyO   Y nw | j	
d	tj}|rft||}|d
 }	d }
n>|rz|d}W n tjy{   td ty   tdw | }t|tjstdt||\}}
|d
 }	ntd|d jdkrtd| j}|d usJ |d }|d d j }t| j	|	|d\}}|
d urtt|}||
 | }nd }z| }W n tjy } ztd|d }~ww |j| |||dj |||d d S )N	/AuthCodez&AuthCode dictionary cannot be indirectz$Failed to locate AuthCode dictionaryF/MACLocation/StandaloneTz/AttachedToSigr   r   z
/SigObjRefz7Value of /SigObjRef entry must be an indirect referencez"/AttachedToSig requires /SigObjRefz)/SigObjRef does not point to a dictionaryz Failed to locate MAC in documentrs   r   z0MAC tokens must be of CMS type AuthenticatedDatar   rR   rC   )r   rG   zError retrieving salt)rJ   rK   rO   rP   )rO   r_   r`   )!trailer_viewr   r   r   r   IndirectObjectr=   DictionaryObject
NameObjectstreamseekosSEEK_ENDr   get_value_as_referenceIndirectObjectExpected
get_objectr   rU   security_handlerlowerr   r   rb   r   r   rc   get_kdf_saltr   r   r\   get_file_encryption_keyr   )r   rP   r   r   is_standaloneis_in_signaturemac_locationr   r   r   signature_valuesig_refr   shrO   rG   _r_   sig_mdr`   rl   r   rA   rA   rB   r+   &  s   







r+   c                       s   e Zd Z fddZ  ZS )StandalonePdfMacc                   s$   t  jtd|d td| d< d S )Nr   )data_keybytes_reservedr   r   )superrI   r%   )rH   r  	__class__rA   rB   rI     s   zStandalonePdfMac.__init__)r>   r?   r@   rI   __classcell__rA   rA   r  rB   r  ~  s    r  r6   wrG   c                 C   s   | j |d}|jdd}td| d}| td| |j| |j|||d}t|\}	}
|j|	j	d d}|	j
|
|d	 t||
S )
N)rG   F)r]   r"   )r  r   )rG   in_place
chunk_sizeoutput)r_   r`   )cms_data)_init_mac_handlerri   r  set_custom_trailer_entryr%   fillrG   nextrd   r_   fill_with_cmsr   finalise_output)r  rG   r   r"  r!  handlertok_sizemac_dict
cms_writerprepared_br_digest
res_outputpdfmac_tokenrA   rA   rB   r,     s(   
r,   )Jr  r   r   r   typingr   r   r   r   r   r   
asn1cryptor	   r
   r   asn1crypto.corer   cryptography.hazmat.primitivesr   r   "cryptography.hazmat.primitives.kdfr   pyhanko.pdf_utilsr   r   sign.generalr   r   r   r   r   r   r   r   sign.signers.pdf_byteranger   r   sign.validation.errorsr   r   sign.validation.generic_cmsr    sign.validation.pdf_embeddedr!   
extensionsr#   r$   r%   r   r&   writerr'   _iso32004_asn1r)   __all__ALWAYSr-   	frozensetr.   r=   r*   r   r   r   r   r  r   r   r   r   r+   r  DEFAULT_CHUNK_SIZEr,   rA   rA   rA   rB   <module>   s     (
	  [

$
X
