U
    dsE                     @  sb  d Z ddlmZ ddlZddlZddl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 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$ ddl%m&Z' ddl(m)Z* ddl+m,Z- ddl+m.Z/ ddl0m1Z2 ddl0m3Z4 ddl5m6Z7 ddl5m8Z9 ddl5m:Z; ddl5m<Z= ddl5m>Z? ddl5m@ZA ddlBmCZD ddlBmEZF ddlBmGZH ddlBmIZJ ddlKmLZM ddlKmNZO dd lPmQZR dd!lSmTZU dd"lVmWZW erbdd#lXmYZYmZZZm[Z[m\Z\m]Z]m^Z^m_Z_ dd$l`maZa dd%l+mbZb dd&l5mcZcmdZd dd'lemfZfmgZg dd(lBmhZhmiZi dd)ljmkZk dd*llmmZm dd+lnmoZo eeYje]j#eZje\jpe[jqe_j)e^j&f ZresetZuevd,ejwZxd-d.d/d0d1Zyd2d3d4d5d6d7d8Zzd9d:d;d:d<d=d>d?Z{d2d@dAdBdCdDZ|d2d:dEdFdGZ}d3d2dHd.dIdJdKZ~d3d2dLd.dMdNdOZd2dPd<dQdRdSZd2d2dTdUdVdWZd2dPd<dQdXdYZd2d2dZd[d\d]d^d_Zd`d:dadbdcdddeZdS )fz4Support for requesting and verifying OCSP responses.    )annotationsN)datetime)timezone)TYPE_CHECKINGIterableListOptionalTypeUnion)InvalidSignature)default_backend)DSAPublicKey)ECDSA)EllipticCurvePublicKey)PKCS1v15)RSAPublicKey)X448PublicKey)X25519PublicKey)SHA1)Hash)Encoding)PublicFormat)AuthorityInformationAccess)ExtendedKeyUsage)ExtensionNotFound)
TLSFeature)TLSFeatureType)load_pem_x509_certificate)OCSPCertStatus)OCSPRequestBuilder)OCSPResponseStatus)load_der_ocsp_response)AuthorityInformationAccessOID)ExtendedKeyUsageOID)post)RequestException)_csot)dsaeced448ed25519rsax448x25519)	Prehashed)HashAlgorithm)CertificateName)	ExtensionExtensionTypeVar)OCSPRequestOCSPResponse)
Connection)
_OCSPCache)_CallbackDatas9   -----BEGIN CERTIFICATE[^
]+.+?-----END CERTIFICATE[^
]+strzList[Certificate])cafilereturnc              	   C  sN   t | d}| }W 5 Q R X g }t }tt|D ]}|t|| q4|S )z0Parse the tlsCAFile into a list of certificates.rb)openread_default_backend_refindall_CERT_REGEXappend_load_pem_x509_certificate)r:   fdatatrusted_ca_certsbackendZ	cert_data rI   8/tmp/pip-unpacked-wheel-oblwsawz/pymongo/ocsp_support.py_load_trusted_ca_certsh   s    rK   r0   zIterable[Certificate]zOptional[List[Certificate]]zOptional[Certificate])certchainrG   r;   c                 C  sF   | j }|D ]}|j|kr
|  S q
|rB|D ]}|j|kr*|  S q*d S N)issuersubject)rL   rM   rG   Zissuer_name	candidaterI   rI   rJ   _get_issuer_certu   s    



rR   CertificateIssuerPublicKeyTypesbytesz%Union[Prehashed, HashAlgorithm, None]int)key	signature	algorithmrF   r;   c                 C  s   zzt | tr | ||t | nXt | tr:| ||| n>t | trX| ||t| n t | ttfrlW dS | || W n t	k
r   Y dS X dS )N   r   )

isinstance_RSAPublicKeyverify	_PKCS1v15_DSAPublicKey_EllipticCurvePublicKey_ECDSA_X25519PublicKey_X448PublicKey_InvalidSignature)rV   rW   rX   rF   rI   rI   rJ   _verify_signature   s     


 rd   zType[ExtensionTypeVar]z%Optional[Extension[ExtensionTypeVar]])rL   klassr;   c                 C  s*   z| j |W S  tk
r$   Y d S X d S rN   )
extensionsZget_extension_for_class_ExtensionNotFound)rL   re   rI   rI   rJ   _get_extension   s    rh   )rL   r;   c                 C  sr   |   }t|tr$|tjtj}n,t|tr@|tj	tj
}n|tjtj}tt t d}|| | S )N)rH   )
public_keyrZ   r[   public_bytes	_EncodingDER_PublicFormatZPKCS1r_   ZX962ZUncompressedPointZSubjectPublicKeyInfo_Hash_SHA1r?   updatefinalize)rL   ri   ZpbytesdigestrI   rI   rJ   _public_key_hash   s    


rs   zOptional[bytes])certificatesrO   responder_key_hashr;   c                   s    fdd| D S )Nc                   s(   g | ] }t |kr|j jkr|qS rI   )rs   rO   rP   .0rL   rO   ru   rI   rJ   
<listcomp>   s    z*_get_certs_by_key_hash.<locals>.<listcomp>rI   )rt   rO   ru   rI   rx   rJ   _get_certs_by_key_hash   s    rz   zOptional[Name])rt   rO   responder_namer;   c                   s    fdd| D S )Nc                   s&   g | ]}|j kr|j j kr|qS rI   )rP   rO   rv   rO   r{   rI   rJ   ry      s   
 z&_get_certs_by_name.<locals>.<listcomp>rI   )rt   rO   r{   rI   r|   rJ   _get_certs_by_name   s    r}   r5   )rO   responser;   c           
      C  s  |j }|j}|j}|d k	r$|| jks,||kr<td | }ntd |j}|j d k	rnt|| |}td nt|| |}td |std dS |d }t	|t
}|rtj|jkrtd dS t|  |j|j|jstd dS t| |j|j|j}	|	std	 |	S )
NzResponder is issuerzResponder is a delegatezUsing responder namezUsing key hashz%No matching or valid responder certs.r   z(Delegate not authorized for OCSP signingz&Delegate signature verification failedz&Response signature verification failed)r{   ru   Zissuer_key_hashrP   _LOGGERdebugrt   r}   rz   rh   _ExtendedKeyUsage_ExtendedKeyUsageOIDZOCSP_SIGNINGvaluerd   ri   rW   Zsignature_hash_algorithmZtbs_certificate_bytesZtbs_response_bytes)
rO   r~   nameZ	rkey_hashZ	ikey_hashZresponder_certcertsZresponder_certsextretrI   rI   rJ   _verify_response_signature   sL    








r   r4   )rL   rO   r;   c                 C  s   t  }|| |t }| S rN   )_OCSPRequestBuilderZadd_certificatero   build)rL   rO   ZbuilderrI   rI   rJ   _build_ocsp_request  s    r   c                 C  sl   t d t| |}|sdS tjtjdjd d}|j|krJt d dS |j	rh|j	|k rht d dS dS )NzVerifying responser   )tz)tzinfozthisUpdate is in the futureznextUpdate is in the pastrY   )
r   r   r   	_datetimenowr   utcreplaceZthis_updateZnext_update)rO   r~   resr   rI   rI   rJ   _verify_response  s    




r   zUnion[str, bytes]r7   zOptional[OCSPResponse])rL   rO   uriocsp_response_cacher;   c           	      C  s0  t | |}z|| }td W n tk
r*   ttdd}z t||t	j
ddi|d}W n6 tk
r } ztd| W Y Y d S d }~X Y nX |jdkrtd	|j Y d S t|j}td
|j |jtjkrY d S |j|jkrtd Y d S t||sY d S td |||< Y nX |S )NzUsing cached OCSP response.   gMbP?zContent-Typezapplication/ocsp-request)rF   headerstimeoutzHTTP request failed: %s   zHTTP request returned %dOCSP response status: %rz-Response serial number does not match requestzCaching OCSP response.)r   r   r   KeyErrormaxr&   Zclamp_remaining_postrj   rk   rl   _RequestExceptionstatus_code_load_der_ocsp_responsecontentresponse_status_OCSPResponseStatus
SUCCESSFULZserial_numberr   )	rL   rO   r   r   Zocsp_requestZocsp_responser   r~   excrI   rI   rJ   _get_ocsp_response"  s>    






r   r6   zOptional[_CallbackData]bool)conn
ocsp_bytes	user_datar;   c                 C  sj  |st |  }|dkr&td dS | }t| drF|  }d}n|  }|j}|sftd dS dd |D }t	|||}d}	t
|t}
|
dk	r|
jD ] }|tjkrtd d	}	 qq|j}|d
krtd |	rtd dS |jstd d	S t
|t}|dkr td d	S dd |jD }|sDtd d	S |dkr\td dS td |D ]d}td| t||||}|dkrqjtd|j |jtjkr d	S |jtjkrj dS qjtd d	S td |dkr td dS t|}td|j |jtjkr(dS t||s8dS ||t||< td|j |jtjkrfdS d	S )zCCallback for use with OpenSSL.SSL.Context.set_ocsp_client_callback.NzNo peer cert?Fget_verified_chainzNo peer cert chain?c                 S  s   g | ]}|  qS rI   )to_cryptography)rw   ZcerrI   rI   rJ   ry   b  s     z"_ocsp_callback.<locals>.<listcomp>z!Peer presented a must-staple certT    z$Peer did not staple an OCSP responsez5Must-staple cert with no stapled response, hard fail.z.OCSP endpoint checking is disabled, soft fail.z*No authority access information, soft failc                 S  s    g | ]}|j tjkr|jjqS rI   )Zaccess_method_AuthorityInformationAccessOIDZOCSPZaccess_locationr   )rw   descrI   rI   rJ   ry     s   zNo OCSP URI, soft failzNo issuer cert?zRequesting OCSP dataz	Trying %szOCSP cert status: %rz)No definitive OCSP cert status, soft failzPeer stapled an OCSP responser   )AssertionErrorZget_peer_certificater   r   r   hasattrr   Zget_peer_cert_chainrG   rR   rh   _TLSFeaturer   _TLSFeatureTypeZstatus_requestr   Zcheck_ocsp_endpoint_AuthorityInformationAccessr   Zcertificate_status_OCSPCertStatusZGOODZREVOKEDr   r   r   r   r   r   )r   r   r   ZpycertrL   ZpychainrG   rM   rO   Zmust_stapleZext_tlsZfeaturer   Zext_aiaurisr   r~   rI   rI   rJ   _ocsp_callbackO  s    























r   )__doc__
__future__r   loggingZ_loggingrer@   r   r   r   typingr   r   r   r   r	   r
   Zcryptography.exceptionsr   rc   Zcryptography.hazmat.backendsr   r?   Z-cryptography.hazmat.primitives.asymmetric.dsar   r^   Z,cryptography.hazmat.primitives.asymmetric.ecr   r`   r   r_   Z1cryptography.hazmat.primitives.asymmetric.paddingr   r]   Z-cryptography.hazmat.primitives.asymmetric.rsar   r[   Z.cryptography.hazmat.primitives.asymmetric.x448r   rb   Z0cryptography.hazmat.primitives.asymmetric.x25519r   ra   Z%cryptography.hazmat.primitives.hashesr   ro   r   rn   Z,cryptography.hazmat.primitives.serializationr   rk   r   rm   Zcryptography.x509r   r   r   r   r   rg   r   r   r   r   r   rD   Zcryptography.x509.ocspr   r   r   r   r    r   r!   r   Zcryptography.x509.oidr"   r   r#   r   requestsr$   r   Zrequests.exceptionsr%   r   Zpymongor&   Z)cryptography.hazmat.primitives.asymmetricr'   r(   r)   r*   r+   r,   r-   Z/cryptography.hazmat.primitives.asymmetric.utilsr.   r/   r0   r1   Zcryptography.x509.extensionsr2   r3   r4   r5   ZOpenSSL.SSLr6   Zpymongo.ocsp_cacher7   Zpymongo.pyopenssl_contextr8   ZEd25519PublicKeyZEd448PublicKeyrS   	getLogger__name__r   compileDOTALLrB   rK   rR   rd   rh   rs   rz   r}   r   r   r   r   r   rI   rI   rI   rJ   <module>   s    $	
 	

6-