U
    c(                     @   s  d Z ddlZddlZddl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 ddlmZ ddlmZ d	d
ddddddddddgZeeZeddddgZedddgZedddgZeddgZeee eeddd	Z eeddd Z!eej"e	j#f eej$d!d"d#Z%ej"eeed$d%d
Z&eej'ed&d'dZ(d(d Z)d)d* Z*d+d Z+d,d- Z,d.d Z-eej"e	j#f d/d0dZ.d1d Z/dS )2zd
Internal backend-agnostic utilities to help process fetched certificates, CRLs
and OCSP responses.
    N)OptionalUnion)algoscmscoreocsppemx509   )errors)	Authority)get_ac_extension_valueunpack_cert_contentformat_ocsp_requestprocess_ocsp_response_dataqueue_fetch_taskcrl_job_results_as_completedocsp_job_get_earliestcomplete_certificate_fetch_jobsgather_aia_issuer_urls$ACCEPTABLE_STRICT_CERT_CONTENT_TYPESACCEPTABLE_CERT_PEM_ALIASESACCEPTABLE_PKCS7_DER_ALIASESACCEPTABLE_CERT_DER_ALIASESzapplication/pkix-certzapplication/pkcs7-mimezapplication/x-x509-ca-certz application/x-pkcs7-certificateszapplication/x-pem-filez
text/plainzapplication/octet-stream)response_datacontent_typeurl
permit_pemc                 c   s   |d ks|t krDt| sD|d kr4td| d tj| V  n|tkr^t	| |E d H  np|r|t
krt| rtj| ddD ]2\}}}|dkrt	||E d H  qtj|V  qntd| d| dd S )	Nz)Response to certificate fetch request to zb did not include a content type, assuming response body is a single DER-encoded X.509 certificate.T)multipleZPKCS7z-Expected PEM data when extracting certs from z payload. Source URL: .)r   r   detectloggerwarningr	   Certificateloadr   _unpack_der_pkcs7r   Zunarmor
ValueError)r   r   r   r   	type_name_data r*   O/tmp/pip-unpacked-wheel-rwcmptg8/pyhanko_certvalidator/fetchers/common_utils.pyr   D   s,    

)
pkcs7_data	pkcs7_urlc                 c   sp   t j| }|d j}|dkr4td| d| d|d }t|d t jrl|d D ]}|jdkrT|jV  qTd S )	Nr   signed_dataziExpected CMS SignedData when extracting certs from application/pkcs7-mime payload, but content type was 'z'. Source URL: r   contentZcertificatesZcertificate)	r   ZContentInfor$   nativer&   
isinstanceZCertificateSetnameZchosen)r,   r-   Zcontent_infoZcms_ctr.   Zcert_choicer*   r*   r+   r%   g   s    

r%   )cert	authorityreturnc                C   sX   t | tjr| j}n| d d j}t|j|}tt	
d|i|t|j||d}|S )NZac_infoserial_number	algorithm)Zhash_algorithmZissuer_name_hashZissuer_key_hashr6   )r1   r	   r#   r6   r0   getattrr2   r   CertIdr   ZDigestAlgorithmZ
public_key)r3   r4   certid_hash_algor6   Ziss_name_hashcert_idr*   r*   r+   
get_certidw   s    

r<   )r3   r4   r:   request_noncesc             	   C   sr   t | ||d}td|i}tdt|gi}|rdtddtt	dd}t
|g|d< td	|iS )
N)r:   Zreq_certZrequest_listnonceF   )Zextn_idcriticalZ
extn_valueZrequest_extensionstbs_request)r<   r   RequestZ
TBSRequestZRequestsZTBSRequestExtensionr   ZOctetStringosurandomZTBSRequestExtensionsOCSPRequest)r3   r4   r:   r=   r;   requestrA   Znonce_extensionr*   r*   r+   r      s,      
)r   ocsp_requestocsp_urlc                C   s   zt j| }W n tk
r.   tdY nX |d j}|dkrTtd||f |j}|r~|j}|r~|j|jkr~td|S )Nz)Failed to parse response from OCSP serverZresponse_statusZ
successfulz5OCSP server at %s returned an error. Status was '%s'.zQUnable to verify OCSP response since the request and response nonces do not match)	r   ZOCSPResponser$   r&   r   OCSPFetchErrorr0   ZOCSPValidationErrorZnonce_value)r   rG   rH   Zocsp_responsestatusZrequest_nonceZresponse_noncer*   r*   r+   r      s&    
c                    sX  z(| | }t dt| d t|W S  tk
r<   Y nX zP|| }t dt| d | I d H  t dt| d t| | W S  tk
rR   t dt| d t  ||< }z| I d H }W nB tk
r } z"t d	t| d
|  |}W 5 d }~X Y nX || |< t d	t| d ||= |	  t| Y S X d S )NzResult for fetch job with tag z was available in cache.zWaiting for fetch job with tag z to return...z,Received completion signal for job with tag r   z Starting new fetch job with tag z...zNew fetch job with tag z threw an exception: z
 returned.)
r!   debugrepr_return_or_raiseKeyErrorwaitasyncioEvent	Exceptionset)resultsZrunning_jobstagZ	async_funresultZ
wait_eventer*   r*   r+   r      s>    
c                 C   s   t | tr| | S N)r1   rR   )rV   r*   r*   r+   rM      s    
rM   c                 C  sn   d }d}t t| D ]B}z|I d H }|V  W q tjk
rV } z|}W 5 d }~X Y qX q|d k	rj|sj|d S )NF)rP   as_completedlistr   ZCRLFetchError)jobslast_eZat_least_one_successZcrl_jobZfetched_crlrW   r*   r*   r+   r     s    

c                    s<   t j|  }|  z|I d H  W n t jk
r6   Y nX d S rX   )rP   ZgathercancelZCancelledError)Zpending_taskspendingr*   r*   r+   
cancel_all  s    
r_   c                    s   dd | D }d  }}|r~t j|t jdI d H \}}|D ]B}z|I d H }W  qW q8 tjk
rx } z|}W 5 d }~X Y q8X q8q|d k	rt|I d H  |S |ptdd S )Nc                 S   s   g | ]}t |qS r*   )rP   Zcreate_task).0coror*   r*   r+   
<listcomp>  s     z)ocsp_job_get_earliest.<locals>.<listcomp>)Zreturn_whenzNo OCSP results)rP   rO   ZFIRST_COMPLETEDr   rI   r_   )r[   queueZ	ocsp_respr\   doneZocsp_jobrW   r*   r*   r+   r     s"     

)r3   c                 c   sp   t | tjr| j}n
t| d}|d kr*d S |D ]<}|d jdkr.|d }|jdkrTq.|j}|dr.|V  q.d S )NZauthority_information_accessZaccess_methodZ
ca_issuersZaccess_locationZuniform_resource_identifierhttp)r1   r	   r#   Z"authority_information_access_valuer   r0   r2   
startswith)r3   Z	aia_valueentrylocationr   r*   r*   r+   r   /  s    


c                 C  sr   t | D ]b}z|I d H }W n> tjk
rZ } ztd| d W Y q
W 5 d }~X Y nX |D ]
}|V  q`q
d S )Nz8Error during certificate fetch job, skipping... (Error: ))rP   rY   r   ZCertificateFetchErrorr!   r"   )Z
fetch_jobsZ	fetch_jobZcerts_fetchedrW   r3   r*   r*   r+   r   B  s    
)0__doc__rP   loggingrC   typingr   r   Z
asn1cryptor   r   r   r   r   r	    r   r4   r   utilr   __all__	getLogger__name__r!   	frozensetr   r   r   r   bytesstrboolr   r%   r#   ZAttributeCertificateV2r9   r<   r   rE   r   r   rM   r   r_   r   r   r   r*   r*   r*   r+   <module>   s    
			#$  ,	