U
    cZ                  
   @   s  d dl Z d dlmZmZ d dl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 d dl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mZ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)m*Z*m+Z+ d dl,m-Z-m.Z. d dl/m0Z0 d dl1m2Z2m3Z3m4Z4 dZ5ej6ee#dddZ7ej6eee#edddZ8ej6dddZ9eG dd dZ:eej6e
j;f ee-e:e<dd d!Z=e-e)e:eej6 d"d#d$Z>ej6ee<ee< d%d&d'Z?ej6ee#e-ee<e:ee<d(	d)d*Z@e-eee e<d+d,d-ZAee-e:e<d.d/d0ZBeej6e
j;f ee-e)e:eej6 d1d2d3ZCeej6e
j;f ee#e-ee:ee<d4d5d6ZDdCeej6e
j;f e#eee d7d8d9ZEed:d;G d<d= d=ZFed:d;G d>d? d?ZGdDeej6e
j;f e#e0eee eGd@dAdBZHdS )E    N)	dataclassfield)datetime)ListOptionalUnion)cmscrlx509)	CRLReason)PublicKeyInfo)InvalidSignature)ValProcState)	AuthorityAuthorityWithCertTrustAnchor)ValidationContext)OCSPNoMatchesErrorOCSPValidationError OCSPValidationIndeterminateErrorPathValidationErrorPSSParameterMismatchRevokedError)ValidationPath)CertRevTrustPolicyRevocationCheckingPolicyRevocationCheckingRule)CertificateCollectionLayeredCertificateStoreSimpleCertificateStore)OCSPContainerRevinfoUsabilityRating)RevinfoManager)ConsListextract_ac_issuer_dir_namevalidate_sigzXUnable to verify OCSP response since response signing certificate could not be validated)responder_certissueree_pathc                 C   s0   t |tr||j| }ntt|g | d}|S )NZtrust_anchorZintermZleaf)
isinstancer   Ztruncate_to_and_appendcertificater   r   )r&   r'   r(   responder_chain r-   O/tmp/pip-unpacked-wheel-rwcmptg8/pyhanko_certvalidator/revinfo/validate_ocsp.py_delegated_ocsp_response_path6   s    
   r/   r&   r'   validation_contextr(   
proc_statec              
      sn  | | rtd| jj |ddlm} |jddd }| jd k	rt	t
tjtjdd}tt|gd	||j|j|jd
}tt|g | d}	t|j|	|d}
z|||	|
dI d H  W n, tk
r } ztt|W 5 d }~X Y nX t| ||}|| | nht| ||}t|j||d}z||||dI d H  W n. tk
rh } ztt|W 5 d }~X Y nX d S )NzVRecursion detected in OCSP responder authorisation check for responder certificate %s.r   )intl_validate_pathT)Z	never_defz OCSP responder)Zee_certificate_ruleZintermediate_ca_cert_rule)Zrevocation_checking_policyF)Ztrust_rootsZallow_fetchingrevinfo_policymomentZalgorithm_usage_policytime_tolerancer)   )cert_path_stackZee_name_override)pathr2   )Zcheck_path_verif_recursionr   Z
from_statesubjectZhuman_friendlyZpyhanko_certvalidator.validater3   describe_certZocsp_no_check_valuer   r   r   ZNO_CHECKr   r   r5   Zalgorithm_policyr6   r   r   r7   Zconsr   OCSP_PROVENANCE_ERRr/   Zrecord_validation)r&   r'   r1   r(   r2   r3   Zocsp_ee_name_overrider4   ZvcZocsp_trunc_pathZocsp_trunc_proc_stateer,   Zocsp_proc_stater-   r-   r.   #_validate_delegated_ocsp_provenanceE   s    
	  
      
r=   )r&   c                 C   s   | j }|d k	od|jkS )NZocsp_signing)Zextended_key_usage_valuenative)r&   Zextended_key_usager-   r-   r.   _ocsp_allowed   s    r?   c                   @   s,   e Zd ZU eedZeed< dZeed< dS )	_OCSPErrs)default_factoryfailuresr   mismatch_failuresN)	__name__
__module____qualname__r   listrB   __annotations__rC   intr-   r-   r-   r.   r@      s   
r@   )certr'   ocsp_responseerrsreturnc                 C   s   |  }|d kr"| jd7  _dS |d }|d d j}t| tj}|r\t| j|}| j}	n t	| }
t|
|}| d d j}	t|j
|}|d j|k}|d	 j|k}|d j|	k}|s|r|r| jd7  _dS |r|jd
|f dS |r|jd|f dS |r|jd|f dS dS )N   FZcert_idZhash_algorithm	algorithmZac_infoserial_numberZissuer_key_hashZissuer_name_hashz-OCSP response issuer name hash does not matchz6OCSP response certificate serial number does not matchz,OCSP response issuer key hash does not matchT)extract_single_responserC   r>   r*   r
   Certificategetattrr'   rP   r$   
public_keyrB   append)rJ   r'   rK   rL   cert_responseZresponse_cert_idZissuer_hash_algois_pkcZcert_issuer_name_hashZcert_serial_numberZiss_nameZcert_issuer_key_hashZkey_hash_mismatchZname_mismatchZserial_mismatchr-   r-   r.   _match_ocsp_certid   sR    
rX   )rK   
cert_storerL   rM   c                 C   s   |   }|d k	st|d r2tt|d |g}|d }|d jdkr^|d j}||}n ||d j	}|rz|d nd }|s|j
d| f |S )Ncertstbs_response_dataZresponder_idby_keyr   zVUnable to verify OCSP response since response signing certificate could not be located)extract_basic_ocsp_responseAssertionErrorr   r   Z
from_certsnamer>   Zretrieve_by_key_identifierZretrieve_by_namechosenrB   rU   )rK   rY   rL   responsetbs_responseZkey_identifierr&   Zcandidate_responder_certsr-   r-   r.   _identify_responder_cert   s,    	
rc   )r&   r'   rW   rM   c                 C   sR   t |tr>|jj| jkr>|j}t|d }t| d }||kS t| rJ|sNdS dS )z
    This function checks OCSP conditions that don't require path validation
    to pass. If ``None`` is returned, path validation is necessary to proceed.
    Zsignature_valueFN)r*   r   r+   Zissuer_serialbytesr?   )r&   r'   rW   Zissuer_certZ
issuer_sigZresponder_sigr-   r-   r.   _precheck_ocsp_responder_auth  s    re   )	r&   r'   	cert_pathrK   r1   rW   rL   r2   rM   c              
      s   t | ||}|d k	r|}	n^z t| ||||dI d H  d}	W n< tk
rv }
 z|j|
jd |f d}	W 5 d }
~
X Y nX |	s|jd|f |	S )Nr0   Tr   FzWUnable to verify OCSP response since response was signed by an unauthorized certificate)re   r=   r   rB   rU   args)r&   r'   rf   rK   r1   rW   rL   r2   Zsimple_checkZauth_okr<   r-   r-   r.   _check_ocsp_authorisation7  s,    rh   )rK   r2   control_timerM   c                 C   s   |   }|d krdS |d j}|dkr*dS |dkr|d j}|d }|jd krXtd}|d j}|d ksr||krtj||d	|d
dS )NFZcert_statusZgoodTZrevokedZrevocation_reasonunspecifiedZrevocation_timezOCSP response)reasonrevocation_dtZrevinfo_typer2   )rQ   r_   r`   r>   r	   r   r   format)rK   r2   ri   rV   statusZrevocation_infork   rl   r-   r-   r.   _check_ocsp_status_  s(    




ro   )responder_keyrK   rL   rM   c                 C   s   |  }|d krdS |d j}|d j}|d }z,t|d j| | |||d d d W dS  tk
r   |jd|f Y n$ t	k
r   |jd	|f Y nX dS )
NFZsignature_algorithmr[   	signature
parameters)rq   Zsigned_dataZpublic_key_infoZsig_algo	hash_algorr   Tz\The signature parameters on the OCSP response do not match the constraints on the public keyz(Unable to verify OCSP response signature)
r]   signature_algors   r%   r>   dumpr   rB   rU   r   )rp   rK   rL   ra   rt   rs   rb   r-   r-   r.   _verify_ocsp_signature~  s6    



rv   )rJ   r'   rK   rY   rL   rM   c                 C   sJ   t | |||d}|sd S t|||d}|s.d S t|j||d}|sFd S |S )N)r'   rK   rL   )rY   rL   )rp   rK   rL   )rX   rc   rv   rT   )rJ   r'   rK   rY   rL   matchedr&   Zsignature_okr-   r-   r.   _assess_ocsp_relevance  s.         rx   )rJ   r'   r8   rK   r1   rL   r2   rM   c              
      s   t | |||j|d}|d kr dS |j|j|jd}|j}	|	tjkrz|	tjkrRd}
n|	tj	krbd}
nd}
|j
|
|f dS t|||||t| tj||dI d H }|sdS |j}|jr|jnd }t|||S )NrJ   r'   rK   rY   rL   F)policytiming_paramsz"OCSP response is not recent enoughzOCSP response is too recentz0OCSP response freshness could not be established)r'   rf   rK   r1   rW   rL   r2   )rx   certificate_registryZ	usable_atr4   r{   ratingr!   OKZSTALEZTOO_NEWrB   rU   rh   r*   r
   rR   Zpoint_in_time_validationZvalidation_timero   )rJ   r'   r8   rK   r1   rL   r2   r&   Zfreshness_resultr}   msgZ
authorisedZtimingri   r-   r-   r.   _handle_single_ocsp_resp  sL    





r   )rJ   r8   r1   r2   c                    s  |pt t|d}| }z|| }W n" tk
rL   td| Y nX t }|j	| |I dH }|D ]v}z,t
| ||||||dI dH }	|	rW  dS W ql tk
r }
 z&d}tj||
d |j||f W 5 d}
~
X Y qlX ql|jt|krtd| dtd	| d
|jdS )aa  
    Verifies an OCSP response, checking to make sure the certificate has not
    been revoked. Fulfills the requirements of
    https://tools.ietf.org/html/rfc6960#section-3.2.

    :param cert:
        An asn1cyrpto.x509.Certificate object or
        an asn1crypto.cms.AttributeCertificateV2 object to verify the OCSP
        response for

    :param path:
        A pyhanko_certvalidator.path.ValidationPath object of the cert's
        validation path, or in the case of an AC, the AA's validation path.

    :param validation_context:
        A pyhanko_certvalidator.context.ValidationContext object to use for
        caching validation information

    :param proc_state:
        Internal state for error reporting and policy application decisions.

    :raises:
        pyhanko_certvalidator.errors.OCSPNoMatchesError - when none of the OCSP responses match the certificate
        pyhanko_certvalidator.errors.OCSPValidationIndeterminateError - when the OCSP response could not be verified
        pyhanko_certvalidator.errors.RevokedError - when the OCSP response indicates the certificate has been revoked
    r7   z6Could not determine issuer certificate for %s in path.N)rJ   r'   r8   rK   r1   rL   r2   8Generic processing error while validating OCSP response.exc_infoz"No OCSP responses were issued for .zUnable to determine if z@ is revoked due to insufficient information from OCSP responses.)r   r#   singr:   find_issuing_authorityLookupErrorr   r@   revinfo_managerasync_retrieve_ocspsr   
ValueErrorloggingdebugrB   rU   rC   lenr   )rJ   r8   r1   r2   Zcert_descriptionZcert_issuerrL   ocsp_responsesrK   Z	ocsp_goodr<   r   r-   r-   r.   verify_ocsp_response  sP    !
 	$

r   T)frozenc                   @   s   e Zd ZU eed< eed< dS )OCSPResponseOfInterestrK   	prov_pathN)rD   rE   rF   r    rH   r   r-   r-   r-   r.   r   M  s   
r   c                   @   s*   e Zd ZU dZee ed< ee ed< dS )OCSPCollectionResultzd
    The result of an OCSP collection operation for AdES point-in-time
    validation purposes.
    	responsesfailure_msgsN)rD   rE   rF   __doc__r   r   rH   strr-   r-   r-   r.   r   S  s   
r   )rJ   r8   r   ri   r2   rM   c                    sJ  |pt t|d}z|| }W n( tk
rJ   td|  dY nX g }|| |I dH }|j}t	 }	|D ]}
|
j
}|
j}|dksr||ksr|| |krqrzHt| ||
|j|	d}|dkrW qrt|||d}t|
|d}|| W qr tk
r. } z&d}tj||d	 |	j||
f W 5 d}~X Y qrX qrt|d
d |	jD dS )a5  
    Collect potentially relevant OCSP responses with the associated validation
    paths. Will not perform actual path validation.

    :param cert:
        The certificate under scrutiny.
    :param path:
        The path currently being evaluated.
    :param revinfo_manager:
        The revocation info manager.
    :param control_time:
        The control time before which the validation info should have been
        issued.
    :param proc_state:
        The state of any prior validation process.
    :return:
        A :class:`.OCSPCollectionResult`.
    r   z+Could not determine issuer certificate for z	 in path.Nry   )r(   )rK   r   r   r   c                 S   s   g | ]}|d  qS )r   r-   ).0fr-   r-   r.   
<listcomp>  s     z9collect_relevant_responses_with_paths.<locals>.<listcomp>)r   r   )r   r#   r   r   r   r   r:   r   poe_managerr@   Zissuance_dateZocsp_response_datarx   r|   r/   r   rU   r   r   r   rB   r   )rJ   r8   r   ri   r2   Zcert_issuer_authZrelevantr   r   rL   Zocsp_response_contZissuedZocsp_resp_datar&   resultr<   r   r-   r-   r.   %collect_relevant_responses_with_pathse  sh    
 

   $r   )N)N)Ir   Zdataclassesr   r   r   typingr   r   r   Z
asn1cryptor   r	   r
   Zasn1crypto.crlr   Zasn1crypto.keysr   Zcryptography.exceptionsr   Zpyhanko_certvalidator._stater   Zpyhanko_certvalidator.authorityr   r   r   Zpyhanko_certvalidator.contextr   Zpyhanko_certvalidator.errorsr   r   r   r   r   r   Zpyhanko_certvalidator.pathr   Z!pyhanko_certvalidator.policy_declr   r   r   Zpyhanko_certvalidator.registryr   r   r   Z&pyhanko_certvalidator.revinfo.archivalr    r!   Z%pyhanko_certvalidator.revinfo.managerr"   Zpyhanko_certvalidator.utilr#   r$   r%   r;   rR   r/   r=   r?   r@   ZAttributeCertificateV2boolrX   rc   re   rh   ro   rv   rx   r   r   r   r   r   r-   r-   r-   r.   <module>   s      YA(  %)   (< R 