o
    >e                     @   sz  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	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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!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-m.Z. d dl/m0Z0m1Z1 d dl2m3Z3m4Z4 d dl5m6Z6m7Z7 d dl8m9Z9 d dl:m;Z; d dl<m=Z= ddl>m?Z?m@Z@ ddlAmBZBmCZCmDZDmEZE ddlFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZP ddlQmRZRmSZS ddlTmUZUmVZV eWeXZYeddG dd dZZG dd deJe j[Z\G d d! d!e\eUZ]G d"d# d#e\eVZ^	 e?_d$Z`	 e?_d%Za	 	 dmd&d'Zbdmd(d)Zc	 ejdG d*d+ d+ejeZf	dnd,egd-ehfd.d/Zid0ed1ejjd2egfd3d4Zkd0ed1ejjd2egfd5d6Zld1ejjd7ejd8egfd9d:Zmd0ed;ee!jneef fd<d=Zod0ed1ejpd2egfd>d?Zqd1ejpd@ed7ejdAegd8egf
dBdCZrd2egdDejsdEeZfdFdGZt	dndHeejs d,egd-ehdEeZd;ejuf
dIdJZvG dKdL dLewZxG dMdN dNZyG dOdP dPejzZ{G dQdR dRejzZ|e}dSZ~dTe!jndUejdVeeg d;e9fdWdXZG dYdZ dZeyeRZeRe d[ejd\eyd;eeg fd]d^Zd_ejud\eyd;eeeg eeh f fd`daZdbe?jfdcddZdedf Zdgdh Zdidj ZeNjG dkdl dleNZdS )o    N)	dataclass)sha1sha256)DictListOptionalSetTupleUnion)algoscmscorex509)RSAESOAEPParams)KeyEncryptionAlgorithmKeyEncryptionAlgorithmId)PrivateKeyInfoPublicKeyAlgorithmPublicKeyInfo)hasheskeywrapserialization)ECDHEllipticCurvePrivateKeyEllipticCurvePublicKey)generate_private_key)MGF1OAEPAsymmetricPaddingPKCS1v15)RSAPrivateKeyRSAPublicKey)X448PrivateKeyX448PublicKey)X25519PrivateKeyX25519PublicKey)KeyDerivationFunction)X963KDF)pkcs12   )genericmisc   )aes_cbc_decryptaes_cbc_encrypt	as_signedrc4_encrypt)
	ALL_PERMS
AuthResult
AuthStatusCryptFilterCryptFilterBuilderCryptFilterConfigurationIdentityCryptFilterSecurityHandlerSecurityHandlerVersionbuild_crypt_filter)SerialisableCredentialSerialisedCredential)AESCryptFilterMixinRC4CryptFilterMixinT)frozenc                   @   s(   e Zd ZU dZeed< 	 dZeed< dS )RecipientEncryptionPolicyFignore_key_usageprefer_oaepN)__name__
__module____qualname__rA   bool__annotations__rB    rH   rH   _/var/www/html/humari/django-venv/lib/python3.10/site-packages/pyhanko/pdf_utils/crypt/pubkey.pyr@   B   s
   
 r@   c                       s   e Zd ZU dZdZed ed< dddd fdd	
Zed
e	fddZ
 fddZefdeej defddZd
efddZd
efddZ fddZ  ZS )PubKeyCryptFiltera  
    Crypt filter for use with public key security handler.
    These are a little more independent than their counterparts for
    the standard security handlers, since different crypt filters
    can cater to different sets of recipients.

    :param recipients:
        List of CMS objects encoding recipient information for this crypt
        filters.
    :param acts_as_default:
        Indicates whether this filter is intended to be used in
        ``/StrF`` or ``/StmF``.
    :param encrypt_metadata:
        Whether this crypt filter should encrypt document-level metadata.

        .. warning::
            See :class:`.SecurityHandler` for some background on the
            way pyHanko interprets this value.
    NPubKeySecurityHandler_handlerFT)
recipientsacts_as_defaultencrypt_metadatac                   s:   || _ || _|| _d| _d  | _| _t jdi | d S )NFrH   )rM   rN   rO   _pubkey_auth_failed_shared_key_recp_key_seedsuper__init__)selfrM   rN   rO   kwargs	__class__rH   rI   rT   i   s   zPubKeyCryptFilter.__init__returnc                 C      | j S N)rP   rU   rH   rH   rI   _auth_failedx      zPubKeyCryptFilter._auth_failedc                    s*   t |tstt | d  | _| _d S r[   )
isinstancerK   	TypeErrorrS   _set_security_handlerrQ   rR   )rU   handlerrW   rH   rI   ra   |   s   
z'PubKeyCryptFilter._set_security_handlercertspolicyc                 C   sz   | j s| jrtd| jdu rtd| _g | _| jdus#| jdu r(tdt|| jt	||| j d}| j
| dS )ay  
        Add recipients to this crypt filter.
        This always adds one full CMS object to the Recipients array

        :param certs:
            A list of recipient certificates.
        :param policy:
            Encryption policy choices for the chosen set of recipients.
        :param perms:
            The permission bits to assign to the listed recipients.
        zCA non-default crypt filter cannot have multiple sets of recipients.N   zYAdding recipients after deriving the shared key or before authenticating is not possible.)rd   include_permissions)rN   rM   r+   PdfErrorsecretstoken_bytesrR   rQ   construct_recipient_cmsr/   append)rU   rc   rd   permsnew_cmsrH   rH   rI   add_recipients   s&   
z PubKeyCryptFilter.add_recipientsc                 C   sB   | j D ]}t||\}}|dur|| _ttj|  S qttjS )a  
        Authenticate to this crypt filter in particular.
        If used in ``/StmF`` or ``/StrF``, you don't need to worry about
        calling this method directly.

        :param credential:
            The :class:`.EnvelopeKeyDecrypter` to authenticate with.
        :return:
            An :class:`AuthResult` object indicating the level of access
            obtained.
        N)rM   read_seed_from_recipient_cmsrR   r2   r3   USERFAILED)rU   
credentialrecpseedrl   rH   rH   rI   authenticate   s   

zPubKeyCryptFilter.authenticatec                 C   s   | j d usJ | jd u rtd| j jtjkrt }nt }|	| j | j
D ]	}|	|  q(| js=| jr=|	d | d | j S )Nz&No seed available; authenticate first.s   )rL   rR   r+   rg   versionr9   AES256r   r   updaterM   dumprO   rN   digestkeylen)rU   mdrs   rH   rH   rI   derive_shared_encryption_key   s   



z.PubKeyCryptFilter.derive_shared_encryption_keyc                    sd   t   }t| jd |d< tdd | jD }| jr"||d< n|d |d< t| j	|d< |S )N   /Lengthc                 s       | ]
}t | V  qd S r[   r*   ByteStringObjectry   .0rs   rH   rH   rI   	<genexpr>   s    
z2PubKeyCryptFilter.as_pdf_object.<locals>.<genexpr>/Recipientsr   /EncryptMetadata)
rS   as_pdf_objectr*   NumberObjectr{   ArrayObjectrM   rN   BooleanObjectrO   )rU   resultrM   rW   rH   rI   r      s   


zPubKeyCryptFilter.as_pdf_object)rC   rD   rE   __doc__rL   r   rG   rT   propertyrF   r]   ra   r1   r   r   Certificater@   rn   r2   ru   bytesr}   r   __classcell__rH   rH   rW   rI   rJ   R   s&   
 

+rJ   c                   @      e Zd ZdZdS )PubKeyAESCryptFilterz<
    AES crypt filter for public key security handlers.
    NrC   rD   rE   r   rH   rH   rH   rI   r          r   c                   @   r   )PubKeyRC4CryptFilterz<
    RC4 crypt filter for public key security handlers.
    Nr   rH   rH   rH   rI   r      r   r   z/DefaultCryptFilterz/DefEmbeddedFilec                 C      t tt| d||dittdS NT)r{   rN   rM   rO   )default_stream_filterdefault_string_filter)r6   DEFAULT_CRYPT_FILTERr   r{   rM   rO   rH   rH   rI   _pubkey_rc4_config     r   c                 C   r   r   )r6   r   r   r   rH   rH   rI   _pubkey_aes_config  r   r   c                   @   s.   e Zd ZdZedZedZedZdS )PubKeyAdbeSubFilterz{
    Enum describing the different subfilters that can be used for public key
    encryption in the PDF specification.
    z/adbe.pkcs7.s3z/adbe.pkcs7.s4z/adbe.pkcs7.s5N)	rC   rD   rE   r   r*   
NameObjectS3S4S5rH   rH   rH   rI   r   )  s
    

r   rt   rl   c                 C   s*   t | dksJ | |rtd| S d S )Nre   <i    )lenstructpack)rt   rl   rf   rH   rH   rI   construct_envelope_content5  s   r   pub_key_inforidenvelope_keyc                 C   sR   t  }tdtdi}t|  }t|tsJ |j	||d}t
|||dS )N	algorithmrsaes_pkcs1v15paddingr   algoencrypted_data)r   r   r   r   r   load_der_public_keyry   r_   r!   encrypt_format_ktri)r   r   r   r   r   pub_keyr   rH   rH   rI   _rsaes_pkcs1v15_recipient<  s   r   c                 C   s   ddl m} ddlm} || }||}ttdtd|idd|iddd}tt	||d d	}t
|  }	t|	tsBJ |	j||d
}
t|||
dS )Nr   get_pyca_cryptography_hash)select_suitable_signing_md
rsaes_oaepr   mgf1r   
parameters)hash_algorithmmask_gen_algorithmmgfr   labelr   r   )pyhanko.sign.generalr   pyhanko.sign.signers.pdf_cmsr   r   r   r   r   r   r   r   r   ry   r_   r!   r   r   )r   r   r   r   r   digest_function_namedigest_specr   r   r   r   rH   rH   rI   _rsaes_oaep_recipientM  s(   r   r   r   c              
   C   s   t dt d| ||diS )Nktrir   )rv   r   key_encryption_algorithmencrypted_key)r   RecipientInfoKeyTransRecipientInfor   rH   rH   rI   r   n  s   r   rY   c                 C   s~   | j }|dkr| jd }n	|dkrd}nd}|dkr%t tdtdfS |dkr4t td	td
fS t tdtdfS )Necr)   x25519      aes128_wrapz1.3.132.1.11.1   aes192_wrapz1.3.132.1.11.2aes256_wrapz1.3.132.1.11.3)r   bit_sizer   SHA256r   SHA384SHA512)r   	algo_nameapprox_sec_levelrH   rH   rI   _choose_ecdh_settings  s(   r   c                 C   s   t | \}}}td|i}t|  }t|tr&t|j}|	t
 |}	n t|tr5t }|	|}	nt|trDt }|	|}	ntt| tjjtjj}
td}t|||d}||	}tj||d}t||
t ||d||dS )Nr      
kdf_digestkey_wrap_algouser_keying_material)wrapping_keykey_to_wrapr   r   originator_keyr   ukmr   )!r   r   r   r   ry   r_   r   generate_ec_private_keycurveexchanger   r%   r$   generater#   r"   NotImplementedErrorr   load
public_keypublic_bytesEncodingDERPublicFormatSubjectPublicKeyInforh   ri   _kdf_for_exchangederiver   aes_key_wrap_format_karir   )r   r   r   r   key_wrap_algo_idkey_exch_algo_idr   r   r   
ecdh_valueoriginator_key_infor   kdfkekr   rH   rH   rI   _ecdh_recipient  sT   






r   r   r   c                 C   s8   t jdt dt jd|d||t | |dgddS )Nkari   r   )namevalue)r   r   )rv   
originatorr   r   recipient_encrypted_keys)r   r   KeyAgreeRecipientInfoOriginatorIdentifierOrKeyRecipientEncryptedKeyr   rH   rH   rI   r     s    r   certrd   c           
      C   s   |j }|d }|d j}t| dksJ |js.|j}|d u s#d|jvr.td|jj dt	
|j|jd}|dkrRt	d|i}|jrLt||| S t||| S |d	v rct	d|i}	t||	| S td
| d)Nr       key_enciphermentzCertificate for subject z8 does not have the 'key_encipherment' key usage bit set.)issuerserial_numberrsaissuer_and_serial_number)r   r   x448zCannot encrypt for key type '')r   nativer   rA   key_usage_valuer+   PdfWriteErrorsubjecthuman_friendlyr   IssuerAndSerialNumberr  r  RecipientIdentifierrB   r   r   KeyAgreementRecipientIdentifierr   r   )
r   r	  rd   r   pubkey_algo_infoalgorithm_name	key_usageiss_serial_ridr   ka_ridrH   rH   rI   _recipient_info  s8   

r  certificatesc                    s   t |||d}td t |d d\}} fdd| D }ttd|d}	tt	d|	|d	}
t
d
||
d}tt	d|dS )N)rf   r
  )ivc                    s   g | ]	}t  |d qS ))rd   )r  )r   r	  r   rd   rH   rI   
<listcomp>C  s    z+construct_recipient_cms.<locals>.<listcomp>
aes256_cbcr   data)content_typecontent_encryption_algorithmencrypted_contentr   )rv   recipient_infosencrypted_content_infoenveloped_data)r&  content)r   rh   ri   r.   r   EncryptionAlgorithmr   EncryptionAlgorithmIdEncryptedContentInfoContentTypeEnvelopedDataContentInfo)r   rt   rl   rd   rf   envelope_contentr!  encrypted_envelope_content	rec_infosr   r*  r+  rH   r"  rI   rj   "  s@   


	rj   c                   @   s   e Zd ZdS )InappropriateCredentialErrorN)rC   rD   rE   rH   rH   rH   rI   r6  i  s    r6  c                
   @   s^   e Zd ZdZedejfddZdede	j
defddZdede	j
d	e	jd
edef
ddZdS )EnvelopeKeyDecrypterz
    General credential class for use with public key security handlers.

    This allows the key decryption process to happen offline, e.g. on a smart
    card.
    rY   c                 C      t )zI
        :return:
            Return the recipient's certificate
        r   r\   rH   rH   rI   r	  v  s   zEnvelopeKeyDecrypter.certr   algo_paramsc                 C   r8  )a  
        Invoke the actual key decryption algorithm.
        Used with key transport.

        :param encrypted_key:
            Payload to decrypt.
        :param algo_params:
            Specification of the encryption algorithm as a CMS object.
        :raises InappropriateCredentialError:
            if the credential cannot be used for key transport.
        :return:
            The decrypted payload.
        r9  )rU   r   r:  rH   rH   rI   decrypt~  s   zEnvelopeKeyDecrypter.decryptoriginator_identifierr   c                 C   r8  )a"  
        Decrypt an envelope key using a key derived from a key exchange.

        :param encrypted_key:
            Payload to decrypt.
        :param algo_params:
            Specification of the encryption algorithm as a CMS object.
        :param originator_identifier:
            Information about the originator necessary to complete the key
            exchange.
        :param user_keying_material:
            The user keying material that will be used in the key derivation.
        :return:
            The decrypted payload.
        r9  )rU   r   r:  r<  r   rH   rH   rI   decrypt_with_exchange  s   z*EnvelopeKeyDecrypter.decrypt_with_exchangeN)rC   rD   rE   r   r   r   r   r	  r   r   r   r;  r  r=  rH   rH   rH   rI   r7  n  s,    
r7  c                   @   s   e Zd ZdefdejfgZdS )_PrivKeyAndCertkeyr	  N)rC   rD   rE   r   r   r   _fieldsrH   rH   rH   rI   r>    s    r>  c                   @   s4   e Zd ZdefdejdddfdejddifgZd	S )
ECCCMSSharedInfokey_infoentityUInfor   T)explicitoptionalsuppPubInforD  r)   N)rC   rD   rE   r   r   OctetStringr@  rH   rH   rH   rI   rA    s    rA  zaes(\d+)_wrap(_pad)?r   r   r   c              
   C   s^   |d j }t|}|st| dt|d}t| |d t||t	d|d
 dS )Nr   * is not a supported key wrapping algorithmr,   r~   z>I)rB  rC  rF  )r   length
sharedinfo)r  AES_WRAP_PATTERN	fullmatchr   intgroupr'   rA  r   r   ry   )r   r   r   r   
wrap_matchkek_bit_lenrH   rH   rI   r     s$   


r   c                
   @   s   e Zd ZdZedZedefddZ	de
fddZede
fd	d
ZdejdefddZedejfddZedddZedddZde
dejde
fddZde
dejdejdee
 de
f
ddZdS )SimpleEnvelopeKeyDecrypterz
    Implementation of :class:`.EnvelopeKeyDecrypter` where the private key
    is an RSA or ECC key residing in memory.

    :param cert:
        The recipient's certificate.
    :param private_key:
        The recipient's private key.
    z1\.3\.132\.1\.11\.(\d+)rY   c                 C   s   dS )Nraw_privkeyrH   clsrH   rH   rI   get_name  s   z#SimpleEnvelopeKeyDecrypter.get_namec                 C   s   | j | jd}t| S )N)r?  r	  )private_keyr	  r>  ry   )rU   valuesrH   rH   rI   
_ser_value  s   z%SimpleEnvelopeKeyDecrypter._ser_valuer%  c              
   C   sP   zt |}|d }|d }W n ty! } ztd|d }~ww t||dS )Nr?  r	  z-Failed to decode serialised pubkey credentialr	  rV  )r>  r   
ValueErrorr+   PdfReadErrorrQ  )rT  r%  decodedr?  r	  erH   rH   rI   _deser_value  s   
z'SimpleEnvelopeKeyDecrypter._deser_valuer	  rV  c                 C   s   || _ || _d S r[   )rV  _cert)rU   r	  rV  rH   rH   rI   rT     s   
z#SimpleEnvelopeKeyDecrypter.__init__c                 C   rZ   r[   )r_  r\   rH   rH   rI   r	    r^   zSimpleEnvelopeKeyDecrypter.certNc              
   C   sx   ddl m} z|| |d}ddl m} ||}W n tttfy5 } ztjd|d W Y d}~dS d}~ww t||dS )	a  
        Load a key decrypter using key material from files on disk.

        :param key_file:
            File containing the recipient's private key.
        :param cert_file:
            File containing the recipient's certificate.
        :param key_passphrase:
            Passphrase for the key file, if applicable.
        :return:
            An instance of :class:`.SimpleEnvelopeKeyDecrypter`.
        r  )load_private_key_from_pemder)
passphrase)load_cert_from_pemderz%Could not load cryptographic materialexc_infoNrY  )	keysr`  rb  IOErrorrZ  r`   loggererrorrQ  )key_file	cert_filekey_passphraser`  rV  rb  r	  r]  rH   rH   rI   r     s   zSimpleEnvelopeKeyDecrypter.loadc              
   C   s   z4t |d}| }W d   n1 sw   Y  t||\}}}ddlm}m}	 ||}|	|}W n! ttt	fyU }
 zt
jd| d|
d W Y d}
~
dS d}
~
ww t||dS )	aZ  
        Load a key decrypter using key material from a PKCS#12 file on disk.

        :param pfx_file:
            Path to the PKCS#12 file containing the key material.
        :param passphrase:
            Passphrase for the private key, if applicable.
        :return:
            An instance of :class:`.SimpleEnvelopeKeyDecrypter`.
        rbNr  ))_translate_pyca_cryptography_cert_to_asn1(_translate_pyca_cryptography_key_to_asn1zCould not open PKCS#12 file .rc  rY  )openreadr(   load_key_and_certificatesre  rm  rn  rf  rZ  r`   rg  rh  rQ  )rT  pfx_filera  f	pfx_bytesrV  r	  other_certsrm  rn  r]  rH   rH   rI   load_pkcs12  s    

z&SimpleEnvelopeKeyDecrypter.load_pkcs12r   r:  c           
      C   s   |d j }|dkrt }nD|dkrIddlm} |d }|d }|d j }|dkr0td	| d
tt||d d j d||d d j dd}ntd| dtj| j	
 dd}	t|	tsdtd|	j||dS )a  
        Decrypt the payload using RSA with PKCS#1 v1.5 padding or OAEP.
        Other schemes are not (currently) supported by this implementation.

        :param encrypted_key:
            Payload to decrypt.
        :param algo_params:
            Specification of the encryption algorithm as a CMS object.
            Must use ``rsaes_pkcs1v15`` or ``rsaes_oaep``.
        :return:
            The decrypted payload.
        r   r   r   r   r   r   r   r   z#Only MGF1 is implemented, but got 'r  )r   r   Nr   zSOnly 'rsaes_pkcs1v15' and 'rsaes_oaep' are supported for envelope decryption, not 'z'.passwordz5The loaded key does not seem to be an RSA private keyr   )r  r   r   r   r   r   r   r   load_der_private_keyrV  ry   r_   r    r6  r;  )
rU   r   r:  r   r   r   oaep_paramsr   mgf_namepriv_keyrH   rH   rI   r;  <  sH   




z"SimpleEnvelopeKeyDecrypter.decryptr<  r   c                 C   s  |d }| j |j}d}|r%t t t t d|	dd}|s+t
dtj|d  }|d j}	t|	sFt
|	 d|	drNtjntj}
t|||d	}|jd
krat
d|j }t| }tj| j dd}d}t|trt|tr|j j|j jkrt!||j"t# |d}n,t|t$rt|t%st!||"|}nt|t&rt|t'st!||"|}nt(d|)|}|
||dS )am  
        Decrypt the payload using a key agreed via ephemeral-static
        standard (non-cofactor) ECDH with X9.63 key derivation.
        Other schemes aer not supported at this time.


        :param encrypted_key:
            Payload to decrypt.
        :param algo_params:
            Specification of the encryption algorithm as a CMS object.
        :param originator_identifier:
            The originator info, which must be an EC key.
        :param user_keying_material:
            The user keying material that will be used in the key derivation.
        :return:
            The decrypted payload.
        r   N)0123r,   zGOnly dhSinglePass-stdDH algorithms from SEC 1 / RFC 5753 are supported.r   rH  _padr   r   z Only originator_key is supportedrx  zCOriginator's public key is not compatible with selected private key)peer_public_keyz4The loaded key does not seem to be an EC private key)r   wrapped_key)*dhsinglepass_stddh_arc_patternrL  dottedr   SHA224r   r   r   getrN  r   r   r   r   ry   r  rK  endswithr   aes_key_unwrap_with_paddingaes_key_unwrapr   r  chosenuntagr   r   rz  rV  r_   r   r   r   rZ  r   r   r$   r%   r"   r#   r6  r   )rU   r   r:  r<  r   oidmatchr   r   r   
unwrap_keyr   originator_pub_key_infooriginator_pub_keyr}  mismatch_msgr   derived_kekrH   rH   rI   r=  r  s   










z0SimpleEnvelopeKeyDecrypter.decrypt_with_exchanger[   )rC   rD   rE   r   recompiler  classmethodstrrU  r   rX  r^  r   r   r   rT   r   r	  staticmethodr   rw  r   r   r;  r  r   r=  rH   rH   rH   rI   rQ    sB    

 
6rQ  ed	decrypterc           
      C   s  | d D ]}|j dkra|j}|d j}t|tjstd|d }|d j}|jj|kr`|jj	|kr`z|
|d j|d W   S  tyN } z|d }~w ty_ } ztd	|d }~ww q|j d
kr|j}|d D ]^}	|	d j}t|tjs~td|d }|d j}|jj|kr|jj	|krz|j|	d j|d |d |d jdW     S  ty } z|d }~w ty } ztd	|d }~ww qmqtdd S )Nr)  r   r   z;Recipient identifier must be of type IssuerAndSerialNumber.r  r  r   r   zFailed to decrypt envelope keyr   r  r  r   )r<  r   zLRecipientInfo must be of type KeyTransRecipientInfo or KeyAgreeRecipientInfo)r  r  r_   r   r  r   r  r	  r  r  r;  r6  	Exceptionr+   r[  r=  )
r  r  rec_infor   issuer_and_serialr  serialr]  r   recipient_enc_keyrH   rH   rI   read_envelope_key  s   






r  recipient_cmsc              	   C   s^  | d j }|dkrtd| | d }|d }t||}|d u r#dS |d }|d j }z|j}W n ttfyA   |d	 j }Y nw d
ti}	zddlm	}
 |	
|
j|
j|
jd W n tyk   |dv ritdY nw ||	v r~|	| }|j}||||}n|dkrt||}n	td| d|d d }d }t|dkrtd|dd  d }||fS )Nr&  r+  z7Recipient CMS content type must be enveloped data, not r,  r*  )NNr'  r(  r   aesr   )	symmetric)des	tripledesrc2z0DES, 3DES and RC2 require oscrypto to be presentrc4zCipher z is not allowed in PDF 2.0.re      r   )r  r+   r[  r  encryption_cipherrZ  KeyErrorr-   oscryptor  rx   des_cbc_pkcs5_decrypttripledes_cbc_pkcs5_decryptrc2_cbc_pkcs5_decryptImportErrorr   encryption_ivr0   r   r   unpack)r  r  r&  r  r*  r   r   r4  cipher_namewith_ivr  decryption_funr!  r,  rt   rl   rH   rH   rI   ro   "  sn   



ro   cfdictc                 C   s\   z| d }W n t y   tdw t|tjr|f}dd |D }| dd}||dS )Nr   z.PubKey CF dictionary must have /Recipients keyc                 S      g | ]	}t j|jqS rH   r   r2  r   original_bytesr   xrH   rH   rI   r#  u  s    z0_read_generic_pubkey_cf_info.<locals>.<listcomp>r   TrM   rO   )r  r+   r[  r_   r*   r   r  )r  rM   recipient_objsrO   rH   rH   rI   _read_generic_pubkey_cf_infol  s   
r  c                 C   s(   |  dd}td|d |dt| S )Nr   (   r~   r{   rN   rH   )r  r   r  )r  rN   keylen_bitsrH   rH   rI   _build_legacy_pubkey_cf|  s   r  c                 C      t dd|dt| S )Nr   r  rH   r   r  r  rN   rH   rH   rI   _build_aes128_pubkey_cf     r  c                 C   r  )Nr
  r  rH   r  r  rH   rH   rI   _build_aes256_pubkey_cf  r  r  c                
       s  e Zd ZU dZedeedeedeeddd iZ	e
ejef ed< ed	ejd
d
ed
e fdeej dededd fddZ	
			
d3dededed dee f fddZedefddZedee fddZedejde de!fdd Z"ed!ejded f fd"d#Z#ed!ejfd$d%Z$ed!ejfd&d'Z%ed!ejfd(d)Z&d*d+ Z'ee fdeej defd,d-Z(	d4d.e)e*e+f de,fd/d0Z-de.fd1d2Z/  Z0S )5rK   z
    Security handler for public key encryption in PDF.

    As with the standard security handler, you essentially shouldn't ever
    have to instantiate these yourself (see :meth:`build_from_certs`).
    z/V2z/AESV2z/AESV3z	/Identityc                 C   s   t  S r[   )r7   )___rH   rH   rI   <lambda>  s    zPubKeySecurityHandler.<lambda>_known_crypt_filtersr   Trc   rl   rd   rY   c	                 K   sp   |rt jnt j}
d}|tjkr |rtd|dd}nt|d|d}| ||
|f||dd|	}|j|||d |S )a  
        Create a new public key security handler.

        This method takes many parameters, but only ``certs`` is mandatory.
        The default behaviour is to create a public key encryption handler
        where the underlying symmetric encryption is provided by AES-256.
        Any remaining keyword arguments will be passed to the constructor.

        :param certs:
            The recipients' certificates.
        :param keylen_bytes:
            The key length (in bytes). This is only relevant for legacy
            security handlers.
        :param version:
            The security handler version to use.
        :param use_aes:
            Use AES-128 instead of RC4 (only meaningful if the ``version``
            parameter is :attr:`~.SecurityHandlerVersion.RC4_OR_AES128`).
        :param use_crypt_filters:
            Whether to use crypt filters. This is mandatory for security
            handlers of version :attr:`~.SecurityHandlerVersion.RC4_OR_AES128`
            or higher.
        :param perms:
            Permission flags (as a 4-byte signed integer).
        :param encrypt_metadata:
            Whether to encrypt document metadata.

            .. warning::
                See :class:`.SecurityHandler` for some background on the
                way pyHanko interprets this value.
        :param policy:
            Encryption policy choices for the chosen set of recipients.
        :return:
            An instance of :class:`.PubKeySecurityHandler`.
        Nr   )rO   rM   r  )rO   crypt_filter_configr  rl   rd   )r   r   r   r9   RC4_OR_AES128r   r   rn   )rT  rc   keylen_bytesrv   use_aesuse_crypt_filtersrl   rO   rd   rV   	subfiltercfcshrH   rH   rI   build_from_certs  s8   2
	z&PubKeySecurityHandler.build_from_certsNrv   pubkey_handler_subfilterr  r6   r  c                    s   |t jkr|tjkrtd|d u r?|t jkr td||d}n|t jkr-t|||d}n|t j	kr:t
d||d}ntdt j|||||d || _|| _d | _d S )NzESubfilter /adbe.pkcs7.s5 is required for security handlers beyond V4.   )r{   rO   rM   r
  z1Failed to impute a reasonable crypt filter config)rO   compat_entries)r9   r  r   r   r+   rg   RC4_40r   RC4_LONGER_KEYSrw   r   rS   rT   r  rO   rQ   )rU   rv   r  legacy_keylenrO   r  r  r  rW   rH   rI   rT     sJ   





zPubKeySecurityHandler.__init__c                 C   s
   t dS )Nz/Adobe.PubSec)r*   r   rS  rH   rH   rI   rU  /  s   
zPubKeySecurityHandler.get_namec                 C   s   dd t D S )Nc                 S   s   h | ]}|j qS rH   )r  r  rH   rH   rI   	<setcomp>5  s    zCPubKeySecurityHandler.support_generic_subfilters.<locals>.<setcomp>)r   rS  rH   rH   rI   support_generic_subfilters3  s   z0PubKeySecurityHandler.support_generic_subfiltersr  rN   c                 C   s$   t | j||}|d u rtd|S )NzJAn absent CFM or CFM of /None doesn't make sense in a PubSec CF dictionary)r:   r  r+   r[  )rT  r  rN   cfrH   rH   rI   read_cf_dictionary7  s   z(PubKeySecurityHandler.read_cf_dictionaryencrypt_dictc                    sR   t  |}| |}|d ur|tjkrtd|d u r'|tjkr'td|S )Nz=Crypt filters require /adbe.pkcs7.s5 as the declared handler.z./adbe.pkcs7.s5 handler requires crypt filters.)rS   process_crypt_filters_determine_subfilterr   r   r+   r[  )rT  r  r  r  rW   rH   rI   r  E  s   
z+PubKeySecurityHandler.process_crypt_filtersc                 C   sZ   | dd}|d dkrtd|d }t|ddd }|jd	td
d}t|||dS )Nr   r   r~   r   z"Key length must be a multiple of 8r   c                 S   s   dd | D S )Nc                 S   r  rH   r  r  rH   rH   rI   r#  a  s    zSPubKeySecurityHandler.gather_pub_key_metadata.<locals>.<lambda>.<locals>.<listcomp>rH   )lstrH   rH   rI   r  a  s    z?PubKeySecurityHandler.gather_pub_key_metadata.<locals>.<lambda>r   Tdefault)r  r  rO   )r  r+   rg   get_and_applyrF   dict)rT  r  r  r{   rM   rO   rH   rH   rI   gather_pub_key_metadataW  s"   
z-PubKeySecurityHandler.gather_pub_key_metadatac                 C   sL   zt j|dtd|v rtjdW S tjdW S  ty%   t d|d  w )N
/SubFilterz/CFr  z8Invalid /SubFilter in public key encryption dictionary: )r+   r  r   r   r   rZ  r[  )rT  r  rH   rH   rI   r  o  s"   
z*PubKeySecurityHandler._determine_subfilterc                 C   s6   t |d }td|| || |d| |S )N/V)rv   r  r  rH   )r9   from_numberrK   r  r  r  )rT  r  vrH   rH   rI   instantiate_from_pdf_object  s   z1PubKeySecurityHandler.instantiate_from_pdf_objectc                 C   s   t  }t |  |d< | jj|d< | j |d< | js#| jt	j
kr-t | jd |d< | jt	j
kr;t | j|d< | jtjkrK|| j  |S |  }t|tsVtt dd |jD |d	< |S )
Nz/Filterr  r  r~   r   r   c                 s   r   r[   r   r   rH   rH   rI   r     s
    
z6PubKeySecurityHandler.as_pdf_object.<locals>.<genexpr>r   )r*   DictionaryObjectr   rU  r  r  rv   r   _compat_entriesr9   r  r   r{   r   rO   r   r   rx   r  get_stream_filterr_   rJ   r`   r   rM   )rU   r   
default_cfrH   rH   rI   r     s,   


z#PubKeySecurityHandler.as_pdf_objectc                 C   s0   | j  D ]}t|tsq|j|||d qd S )Nr  )r  standard_filtersr_   rJ   rn   )rU   rc   rl   rd   r  rH   rH   rI   rn     s
   

z$PubKeySecurityHandler.add_recipientsrr   c                 C   s   t |trt|}t |tstdt| d|}n|}d}| j	 D ]!}t |t
s.q&||}|jtjkr=|  S |jdurG||jM }q&t |trP|| _ttjt|S )a  
        Authenticate a user to this security handler.

        :param credential:
            The credential to use (an instance of :class:`.EnvelopeKeyDecrypter`
            in this case).
        :param id1:
            First part of the document ID.
            Public key encryption handlers ignore this key.
        :return:
            An :class:`AuthResult` object indicating the level of access
            obtained.
        zRPubkey authentication credential must be an instance of EnvelopeKeyDecrypter, not ro  l    N)r_   r<   r;   deserialiser7  r+   r[  typer  r  rJ   ru   statusr3   rq   permission_flags_credentialr2   rp   r/   )rU   rr   id1deser_credentialactual_credentialrl   r  r   rH   rH   rI   ru     s.   







z"PubKeySecurityHandler.authenticatec                 C   s   | j  jS r[   )r  get_for_stream
shared_keyr\   rH   rH   rI   get_file_encryption_key  s   z-PubKeySecurityHandler.get_file_encryption_key)TNNTr[   )1rC   rD   rE   r   r*   r   r  r  r  r  r   r5   rG   r  r9   rw   r1   r@   r   r   r   rM  r  r   r   listrT   r  rU  r   r  r  rF   r4   r  r  r  r  r  r   rn   r
   r7  r<   r2   ru   r   r  r   rH   rH   rW   rI   rK     s   
 


	T:


0rK   )NT)T)abcenumloggingr  rh   r   dataclassesr   hashlibr   r   typingr   r   r   r   r	   r
   
asn1cryptor   r   r   r   asn1crypto.algosr   asn1crypto.cmsr   r   asn1crypto.keysr   r   r   cryptography.hazmat.primitivesr   r   r   ,cryptography.hazmat.primitives.asymmetric.ecr   r   r   r   r   1cryptography.hazmat.primitives.asymmetric.paddingr   r   r   r   -cryptography.hazmat.primitives.asymmetric.rsar    r!   .cryptography.hazmat.primitives.asymmetric.x448r"   r#   0cryptography.hazmat.primitives.asymmetric.x25519r$   r%   "cryptography.hazmat.primitives.kdfr&   *cryptography.hazmat.primitives.kdf.x963kdfr'   ,cryptography.hazmat.primitives.serializationr(    r*   r+   _utilr-   r.   r/   r0   apir1   r2   r3   r4   r5   r6   r7   r8   r9   r:   cred_serr;   r<   filter_mixinsr=   r>   	getLoggerrC   rg  r@   ABCrJ   r   r   r   r   DEF_EMBEDDED_FILEr   r   uniqueEnumr   r   rM  r   r  r   r   r   HashAlgorithmr   r  r   r   r   r  r2  rj   r`   r6  r7  Sequencer>  rA  r  rK  r   rQ  registerr1  r  ro   r  r  r  r  r  rK   rH   rH   rH   rI   <module>   s6    0
 






!


!
:

0
G;

  
	
B
J	