U
    Nf*                     @   s  d Z ddlZddlZddl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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dgZeddddgZed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,e	d)Z-e	d*Z.ee-e
e.e/f f ee-ej0f e-eg ee. f e
e.e/f d+d,dZ1d-d. Z2d/d Z3d0d1 Z4d2d Z5e
ej&ej'f d3d4dZ6d5d Z7dS )6zd
Internal backend-agnostic utilities to help process fetched certificates, CRLs
and OCSP responses.
    N)	AwaitableCallableDictOptionalTypeVar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-streamzbinary/octet-stream)response_datacontent_typeurl
permit_pemc           	      c   s   t | }|d ks|tkrz|sz|d kr8td| d ttj| }|dkrbt	| |E d H  q|dkrt
j| V  n|tkr|st	| |E d H  nb|r|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 zi did not include a content type, verifying it's sequence length to check if it is a certificate or pkcs7.r      T)multipleZPKCS7zFailed to extract certs from z payload. Source URL: .)r   detectr   loggerwarninglenr
   Sequenceload_unpack_der_pkcs7r   Certificater   Zunarmor
ValueError)	r   r   r    r!   Zis_pemZder_sequence_length	type_name_data r1   O/tmp/pip-unpacked-wheel-p64bl1fm/pyhanko_certvalidator/fetchers/common_utils.pyr   G   s4    

)
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)r3   r4   Zcontent_infoZcms_ctr5   Zcert_choicer1   r1   r2   r+   n   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_hashr=   )r8   r   r,   r=   r7   getattrr9   r   CertIdr   ZDigestAlgorithmZ
public_key)r:   r;   certid_hash_algor=   Ziss_name_hashcert_idr1   r1   r2   
get_certid~   s    

rC   )r:   r;   rA   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)rA   Zreq_certZrequest_listnonceF   )Zextn_idcriticalZ
extn_valueZrequest_extensionstbs_request)rC   r   RequestZ
TBSRequestZRequestsZTBSRequestExtensionr
   ZOctetStringosurandomZTBSRequestExtensionsOCSPRequest)r:   r;   rA   rD   rB   requestrH   Znonce_extensionr1   r1   r2   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   OCSPFetchErrorr7   ZOCSPValidationErrorZnonce_value)r   rN   rO   Zocsp_responsestatusZrequest_nonceZresponse_noncer1   r1   r2   r      s&    
TR)resultsrunning_jobstag	async_funr<   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)rT   rU   rV   rW   resultZ
wait_eventer1   r1   r2   r      s>    
c                 C   s   t | tr| | S N)r8   r_   )ra   r1   r1   r2   rZ     s    
rZ   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)r]   as_completedlistr   ZCRLFetchError)jobslast_eZat_least_one_successZcrl_jobZfetched_crlrb   r1   r1   r2   r     s    

c                    s<   t j|  }|  z|I d H  W n t jk
r6   Y nX d S rc   )r]   ZgathercancelZCancelledError)Zpending_taskspendingr1   r1   r2   
cancel_all!  s    
rj   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 r1   )r]   Zcreate_task).0coror1   r1   r2   
<listcomp>+  s     z)ocsp_job_get_earliest.<locals>.<listcomp>)Zreturn_whenzNo OCSP results)r]   r\   ZFIRST_COMPLETEDr   rP   rj   )rf   queueZ	ocsp_resprg   doneZocsp_jobrb   r1   r1   r2   r   *  s"     

)r:   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)r8   r   r,   Z"authority_information_access_valuer   r7   r9   
startswith)r:   Z	aia_valueentrylocationr    r1   r1   r2   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: ))r]   rd   r   ZCertificateFetchErrorr&   r'   )Z
fetch_jobsZ	fetch_jobZcerts_fetchedrb   r:   r1   r1   r2   r   Q  s    
)8__doc__r]   loggingrJ   typingr   r   r   r   r   r   Z
asn1cryptor   r	   r
   r   r   r    r   r;   r   utilr   __all__	getLogger__name__r&   	frozensetr   r   r   r   bytesstrboolr   r+   r,   ZAttributeCertificateV2r@   rC   r   rL   r   rR   rS   r_   r^   r   rZ   r   rj   r   r   r   r1   r1   r1   r2   <module>   s     
		

'$  
1	