U
    ccy                     @   s"  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	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 d dlmZmZ d dlmZ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&m'Z'm(Z( ddl)m*Z* ddl+m,Z,m-Z- ddl.m/Z/ ddl0m1Z1 ddl2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8 ddl9m:Z:m;Z;m<Z< ddddddddddddgZ=e>e?Z@e
d e6d!ZAejBejCd"d#d$ZDejCejEejFd%d&dZGe:fejHejBeIeJeeKeKf d'd(dZLejMe#d)d*dZNe6ddddd+fejMe	eA eJeeOe1d,d-dZPe6ddddd+fejMe	eA eJeeOe1d,d.dZQejHee d/d0dZRd?eejM d1d2dZSejHeeJ d/d3dZTejHeeJd4d5dZUejMeeJd6d7dZVeejW ejBeeee eeX f d8d9d:ZYeejW ejBee ejCd;d<dZZdddde*j[dfeeJeej\ej]f ejMeeee1e7d=d>dZ^dS )@    N)datetime)IOIterableListOptionalTupleTypeTypeVarUnion)cmscoretspx509)InvalidSignature)hashes)CertificateValidatorValidationContext)PathBuildingErrorPathValidationError)ACValidationResultasync_validate_ac)
CMSExtractionErrorCMSStructuralErrorMultivaluedAttributeErrorNonexistentAttributeErrorSignedDataCertscheck_ess_certidextract_certificate_infoextract_signer_infofind_unique_cms_attributeget_pyca_cryptography_hash   )misc   )AdESFailureAdESIndeterminate   )errors)KeyUsageConstraints)CAdESSignerAttributeAssertionsCertifiedAttributesClaimedAttributesSignatureStatusStandardCMSSignatureStatusTimestampSignatureStatus)DEFAULT_WEAK_HASH_ALGORITHMSextract_message_digestvalidate_rawvalidate_sig_integrityasync_validate_cms_signaturecollect_timing_infovalidate_tst_signed_dataasync_validate_detached_cmscms_basic_validationcompute_signature_tst_digestextract_tst_dataextract_self_reported_tsextract_certs_for_validationcollect_signer_attr_statusvalidate_algorithm_protection
StatusType)bound)certsigned_attrsc                    sn    fdd}|dt j}|d kr,|dt j}|d kr8d S |d d }t| |sjtjd| jj dtj	d	d S )
Nc              
      sb   zt  | }|| W S  tk
r0   Y d S  tk
r\ } ztd|W 5 d }~X Y nX d S )Nz3Wrong cardinality for signing certificate attribute)r   loaddumpr   r   r'   SignatureValidationError)	attr_nameclsvalueerA    ]/var/www/html/project/venv/lib/python3.8/site-packages/pyhanko/sign/validation/generic_cms.py_grab>   s    
z)_check_signing_certificate.<locals>._grabZsigning_certificate_v2Zsigning_certificatecertsr   zWSigning certificate attribute does not match selected signer's certificate for subject"z".Zades_subindication)
r   ZSigningCertificateV2ZSigningCertificater   r'   rD   subjectZhuman_friendlyr%   NO_SIGNING_CERTIFICATE_FOUND)r@   rA   rL   attrZcertidrJ   rI   rK   _check_signing_certificate:   s    
rR   )attrsclaimed_digest_algorithm_objclaimed_signature_algorithm_objc                 C   s   zt | d}W n2 tk
r&   d}Y n tk
r@   tdY nX |dk	r|d j}||jkrhtd|d j}|dkrtdn||jkrtddS )	a+  
    Internal API to validate the CMS algorithm protection attribute
    defined in :rfc:`6211`, if present.

    :param attrs:
        A CMS attribute list.
    :param claimed_digest_algorithm_obj:
        The claimed (i.e. unprotected) digest algorithm value.
    :param claimed_signature_algorithm_obj:
        The claimed (i.e. unprotected) signature algorithm value.
    :raises errors.CMSStructuralError:
        if multiple CMS protection attributes are present
    :raises errors.CMSAlgorithmProtectionError:
        if a mismatch is detected
    Zcms_algorithm_protectionNz4Multiple CMS algorithm protection attributes presentdigest_algorithmzCDigest algorithm does not match CMS algorithm protection attribute.signature_algorithmz<CMS algorithm protection attribute not valid for signed datazFSignature mechanism does not match CMS algorithm protection attribute.)r   r   r   r   nativer'   CMSAlgorithmProtectionError)rS   rT   rU   Zcms_algid_protectionZauth_digest_algorithmZsigned_sig_algorithmrJ   rJ   rK   r=   a   s8     


)signer_infor@   expected_content_typeactual_digestreturnc              
   C   s  | d }| d }|d j }||kr,t|| d j }| d }	|	tjkrXd}
d}|}n| d  }| }d}zt|||d	 W nh tk
r } ztj	|j
tjd
W 5 d}~X Y n6 tjk
r } ztj	|j
tjd
W 5 d}~X Y nX t|| zt|d}W n* ttfk
r.   tj	dtjd
Y nX |j }||kr\tj	d| d| tjd
t| }
zt|||||||d d}W n tk
r   d}Y nX |
dk	r||
kn|}||fS )a&  
    Validate the integrity of a signature for a particular signerInfo object
    inside a CMS signed data container.

    .. warning::
        This function does not do any trust checks, and is considered
        "dangerous" API because it is easy to misuse.

    :param signer_info:
        A :class:`cms.SignerInfo` object.
    :param cert:
        The signer's certificate.

        .. note::
            This function will not attempt to extract certificates from
            the signed data.
    :param expected_content_type:
        The expected value for the content type attribute (as a Python string,
        see :class:`cms.ContentType`).
    :param actual_digest:
        The actual digest to be matched to the message digest attribute.
    :param weak_hash_algorithms:
        List, tuple or set of weak hashing algorithms.
    :return:
        A tuple of two booleans. The first indicates whether the provided
        digest matches the value in the signed attributes.
        The second indicates whether the signature of the digest is valid.
    rW   rV   	algorithm	signaturerA   NTF)rT   rU   rN   content_typezQContent type not found in signature, or multiple content-type attributes present.zContent type z did not match expected value )	prehashedweak_hash_algorithms)rX   r'   ZWeakHashAlgorithmErrorr   ZVOIDZuntagrC   r=   r   rD   failure_messager$   ZFORMAT_FAILURErY   r%   ZGENERICrR   r   r   r   r0   r1   r   )rZ   r@   r[   r\   rb   rW   Zdigest_algorithm_objmd_algorithmr_   Zsigned_attrs_origZembedded_digestra   signed_datarA   rH   r`   validintactrJ   rJ   rK   r2      s    $



	
 
 
     
)re   r]   c                 C   sV   zt | }|j}W n$ tk
r6   tjdtjdY nX t| }|d }t|| |S )a  
    Extract certificates from a CMS signed data object for validation purposes,
    identifying the signer's certificate in accordance with ETSI EN 319 102-1,
    5.2.3.4.

    :param signed_data:
        The CMS payload.
    :return:
        The extracted certificates.
    z,signer certificate not included in signaturerN   rA   )	r   signer_certr   r'   rD   r%   rP   r   rR   )re   	cert_infor@   rZ   rA   rJ   rJ   rK   r;     s    

F)re   
status_cls
raw_digestvalidation_contextstatus_kwargskey_usage_settingsc              
      s  t | }t| }|j}	|j}
d}|dk	r.|j}|dkr:t}|d }|d j}|d d j}| d }|d j}|dkrt|d }t|}t	
|}|| | }zt||	|||d\}}W n4 tk
r } ztd	|j |W 5 d}~X Y nX || M }||M }d }}|rxz*t|	|
|d
}|j||dI dH \}}W n8 tk
rv } ztjd|d tj}W 5 d}~X Y nX |pi }|j|||	||||d |S )z
    Perform basic validation of CMS and PKCS#7 signatures in isolation
    (i.e. integrity and trust checks).

    Internal API.
    NrW   r^   rV   encap_content_infor`   content)r[   r\   rb   zCMS structural error: )Zintermediate_certsrl   )rn   z&Processing error in validation process)exc_info)rg   rf   Zsigning_certrd   Zpkcs7_signature_mechanismZtrust_problem_indicZvalidation_path)r   r;   rh   other_certsweak_hash_algosr/   rX   bytesr    r   Hashupdatefinalizer2   r   r'   rD   rc   r   Zvalidate_cert_usage
ValueErrorloggererrorr%   Z!CERTIFICATE_CHAIN_GENERAL_FAILURE)re   rj   rk   rl   rm   rn   encap_data_invalidrZ   ri   r@   rr   rs   rW   Z	mechanismrd   ecir[   rawZmd_specmdrg   rf   rH   Zades_statuspath	validatorrJ   rJ   rK   r7   4  s~    



   
  
    c                    s$   t | ||||||I dH }|f |S )a  
    Validate a CMS signature (i.e. a ``SignedData`` object).

    :param signed_data:
        The :class:`.asn1crypto.cms.SignedData` object to validate.
    :param status_cls:
        Status class to use for the validation result.
    :param raw_digest:
        Raw digest, computed from context.
    :param validation_context:
        Validation context to validate the signer's certificate.
    :param status_kwargs:
        Other keyword arguments to pass to the ``status_class`` when reporting
        validation results.
    :param key_usage_settings:
        A :class:`.KeyUsageConstraints` object specifying which key usages
        must or must not be present in the signer's certificate.
    :param encap_data_invalid:
        If ``True``, the encapsulated data inside the CMS is invalid,
        but the remaining validation logic still has to be run (e.g. a
        timestamp token, which requires validation of the embedded message
        imprint).

        This option is considered internal API, the semantics of which may
        change without notice in the future.
    :return:
        A :class:`.SignatureStatus` object (or an instance of a proper subclass)
    N)r7   )re   rj   rk   rl   rm   rn   r{   rJ   rJ   rK   r3     s    $     
)rZ   r]   c              	   C   s8   z| d }t |d}|jW S  ttfk
r2   Y nX dS )a  
    Extract self-reported timestamp (from the ``signingTime`` attribute)

    Internal API.

    :param signer_info:
        A ``SignerInfo`` value.
    :return:
        The value of the ``signingTime`` attribute as a ``datetime``, or
        ``None``.
    rA   Zsigning_timeN)r   rX   r   r   )rZ   sastrJ   rJ   rK   r:     s    
)r]   c              	   C   sV   z8|r| d }t |d}n| d }t |d}|d }|W S  ttfk
rP   Y nX dS )a  
    Extract signed data associated with a timestamp token.

    Internal API.

    :param signer_info:
        A ``SignerInfo`` value.
    :param signed:
        If ``True``, look for a content timestamp (among the signed
        attributes), else look for a signature timestamp (among the unsigned
        attributes).
    :return:
        The ``SignedData`` value found, or ``None``.
    rA   Zcontent_time_stampZunsigned_attrsZsignature_time_stamp_tokenrp   N)r   r   r   )rZ   signedr   ZtstZuatst_signed_datarJ   rJ   rK   r9     s    
c                 C   sf   t | }|dkrdS |d }|d jd }|d d j}| d j}t|}t|}|| | S )a.  
    Compute the digest of the signature according to the message imprint
    algorithm information in a signature timestamp token.

    Internal API.

    :param signer_info:
        A ``SignerInfo`` value.
    :return:
        The computed digest, or ``None`` if there is no signature timestamp.
    Nro   rp   message_imprintZhash_algorithmr^   r_   )r9   parsedrX   r    r   ru   rv   rw   )rZ   Ztst_datar|   miZtst_md_algorithmZsignature_bytesZtst_md_specr~   rJ   rJ   rK   r8     s    


)rZ   ts_validation_contextrk   c                    s   i }t | }|dk	r||d< t| dd}|dk	rXt||t| I dH }tf |}||d< t| dd}|dk	rt|||dI dH }	tf |	}
|
|d< |S )	a  
    Collect and validate timing information in a ``SignerInfo`` value.
    This includes the ``signingTime`` attribute, content timestamp information
    and signature timestamp information.

    :param signer_info:
        A ``SignerInfo`` value.
    :param ts_validation_context:
        The timestamp validation context to validate against.
    :param raw_digest:
        The raw external message digest bytes (only relevant for the
        validation of the content timestamp token, if there is one)
    Nsigner_reported_dtF)r   Ztimestamp_validityT)expected_tst_imprintZcontent_timestamp_validity)r:   r9   r5   r8   r.   )rZ   r   rk   rm   r   r   Ztst_validity_kwargsZtst_validityZcontent_tst_signed_dataZcontent_tst_validity_kwargsZcontent_tst_validityrJ   rJ   rK   r4     s2     

 )r   rl   r   c                    s   d}| d d }t |tjr"|j}t |tjs8td|d d j}||krtt	
d|  d|  d	 d
}nd}|d j}t| t|d|i|dI dH S )a  
    Validate the ``SignedData`` of a time stamp token.

    :param tst_signed_data:
        The ``SignedData`` value to validate; must encapsulate a ``TSTInfo``
        value.
    :param validation_context:
        The validation context to validate against.
    :param expected_tst_imprint:
        The expected message imprint value that should be contained in
        the encapsulated ``TSTInfo``.
    :return:
        Keyword arguments for a :class:`.TimeStampSignatureStatus`.
    Nro   rp   z'SignedData does not encapsulate TSTInfor   Zhashed_messagezTimestamp token imprint is z, but expected .TFZgen_time	timestamp)rj   rl   rm   r{   )
isinstancer   ZParsableOctetStringr   r   ZTSTInfor'   rD   rX   ry   warninghexr7   r.   )r   rl   r   Ztst_infoZtst_info_bytesZtst_imprintr{   r   rJ   rJ   rK   r5   -  s.    
 )acsrh   rl   r]   c                    sz    fdd| D }g }g }t |D ]J}z||I d H  W q& ttfk
rn } z|| W 5 d }~X Y q&X q&||fS )Nc                    s   g | ]}t | d qS ))Zholder_cert)r   ).0acrh   rl   rJ   rK   
<listcomp>a  s   z+process_certified_attrs.<locals>.<listcomp>)asyncioas_completedappendr   r   )r   rh   rl   jobsresultsr'   ZjobrH   rJ   r   rK   process_certified_attrs\  s    r   sd_attr_certificatesrh   rl   sd_signed_attrsc              
      s  zt |d}W nH tk
r&   d }Y n2 tk
rV } ztt||W 5 d }~X Y nX i }d }d }|d k	rF|d }	tt|	t	j
s|	nd}
|d }d}t|t	j
sdd |D }t|t|k}|d k	rt|||}|I d H \}}|d k	rt|}nd }|pt|d t	j
 }|d k	r2|r2td	 t|
|||d
|d< |d k	rt| ||I d H \}}|rv|| |r|| t||d< ||d< |S )NZsigner_attributes_v2Zclaimed_attributesrJ   Zcertified_attributes_v2Fc                 S   s   g | ]}|j d kr|jqS )Z	attr_cert)nameZchosen)r   rQ   rJ   rJ   rK   r     s   
z.collect_signer_attr_status.<locals>.<listcomp>Zsigned_assertionszCAdES signer attributes with externally certified assertions for which no validation method is available. This may affect signature semantics in unexpected ways.)Zclaimed_attrsZcertified_attrsac_validation_errsZunknown_attrs_presentZcades_signer_attrsZac_attrsr   )r   r   r   r'   rD   strr+   from_iterabler   r   ZVoidlenr   r*   Zfrom_resultsry   r   r)   extend)r   rh   rl   r   Zsigner_attrsrH   resultZcades_ac_resultsZcades_ac_errorsZclaimed_asn1ZclaimedZcertified_asn1Zunknown_cert_attrsZ	cades_acsZval_jobZ	certifiedZunknown_attrsZ
ac_resultsZ	ac_errorsrJ   rJ   rK   r<   o  st    "
   

  

)
input_datare   signer_validation_contextr   ac_validation_contextrn   r]   c                    s  |dkr|}t |}|d d j}	tt|	}
t| trF|
|  n@t| tj	tj
frl|
t| d  nt|}tj|| |
|d |
 }t|||dI dH }t|t||||dI dH }t|}|dk	r|j|j |t|j|j||d d	I dH  tf |S )
a  
    .. versionadded: 0.9.0

    .. versionchanged: 0.11.0
        Added ``ac_validation_context`` param.

    Validate a detached CMS signature.

    :param input_data:
        The input data to sign. This can be either a :class:`bytes` object,
        a file-like object or a :class:`cms.ContentInfo` /
        :class:`cms.EncapsulatedContentInfo` object.

        If a CMS content info object is passed in, the `content` field
        will be extracted.
    :param signed_data:
        The :class:`cms.SignedData` object containing the signature to verify.
    :param signer_validation_context:
        Validation context to use to verify the signer certificate's trust.
    :param ts_validation_context:
        Validation context to use to verify the TSA certificate's trust, if
        a timestamp token is present.
        By default, the same validation context as that of the signer is used.
    :param ac_validation_context:
        Validation context to use to validate attribute certificates.
        If not supplied, no AC validation will be performed.

        .. note::
            :rfc:`5755` requires attribute authority trust roots to be specified
            explicitly; hence why there's no default.
    :param key_usage_settings:
        Key usage parameters for the signer.
    :param chunk_size:
        Chunk size to use when consuming input data.
    :param max_read:
        Maximal number of bytes to read from the input stream.
    :return:
        A description of the signature's status.
    NrV   r^   rp   )max_read)r   rk   )rj   rk   rl   rm   rn   rA   r   )r   rX   r   ru   r    r   rt   rv   r   ContentInfoEncapsulatedContentInfo	bytearrayr"   Zchunked_digestrw   r4   r7   r-   r   Zcertificate_registryZregister_multiplerr   r<   Zattribute_certsrh   )r   re   r   r   r   rn   
chunk_sizer   rZ   rV   hZtemp_bufZdigest_bytesrm   ri   rJ   rJ   rK   r6     sN    2
  
)F)_r   loggingr   typingr   r   r   r   r   r   r	   r
   Z
asn1cryptor   r   r   r   Zcryptography.exceptionsr   Zcryptography.hazmat.primitivesr   Zpyhanko_certvalidatorr   r   Zpyhanko_certvalidator.errorsr   r   Zpyhanko_certvalidator.validater   r   Zpyhanko.sign.generalr   r   r   r   r   r   r   r   r   r    Z	pdf_utilsr"   Zades.reportr$   r%    r'   settingsr(   statusr)   r*   r+   r,   r-   r.   utilsr/   r0   r1   __all__	getLogger__name__ry   r>   ZCertificateZCMSAttributesrR   ZDigestAlgorithmZSignedDigestAlgorithmr=   Z
SignerInfor   rt   boolr2   Z
SignedDatar;   dictr7   r3   r:   r9   r8   r4   r5   ZAttributeCertificateV2	Exceptionr   r<   ZDEFAULT_CHUNK_SIZEr   r   r6   rJ   rJ   rJ   rK   <module>   s   (0       	
(9
  R+00a 