o
    Š¨Êh»,  ã                   @   s  d dl Z d dlZd dlZd dlmZmZ d dlZd dlZd dlm	Z	m
Z
 d dlmZ d dlmZ d dlmZ d dl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 d dlm Z m!Z! dd„ Z"ddd„Z#dd„ Z$dd„ Z%ddd„Z&G dd„ dƒZ'dS )é    N)ÚurljoinÚurlparse)ÚhazmatÚx509)ÚInvalidSignature)Úbackends)ÚDSAPublicKey)ÚECDSAÚEllipticCurvePublicKey)ÚPKCS1v15)ÚRSAPublicKey)ÚSHA1ÚHash)ÚEncodingÚPublicFormat)Úocsp)ÚAuthorizationErrorÚConnectionErrorc                 C   sª   |   ¡ }zEt|tƒr| |j|jtƒ |j¡ W d S t|tƒr+| |j|j|j¡ W d S t|t	ƒr?| |j|jt
|jƒ¡ W d S | |j|j¡ W d S  tyT   tdƒ‚w )Nzfailed to valid ocsp response)Ú
public_keyÚ
isinstancer   ÚverifyÚ	signatureÚtbs_response_bytesr   Úsignature_hash_algorithmr   r
   r	   r   r   )Úissuer_certÚocsp_responseÚpubkey© r   ú</var/www/html/env/lib/python3.10/site-packages/redis/ocsp.pyÚ_verify_response   s2   

ü

ý

ýÿr   Tc                 C   sN  t  |¡}|jt jjkrtdƒ‚|jt jjkr/|jt jj	kr.t
dt|jƒ d¡d › d�ƒ‚nt
dƒ‚|jtj ¡ kr?t
dƒ‚|jrN|jtj ¡ k rNt
dƒ‚|j}|j}|j}| }|d	urb|| jksf||kri| }n5|j}t|| ||ƒ}	z|	d
 }
W n ty„   t
dƒ‚w |
j tj¡}|d	u s˜tjjj|jvrœt
dƒ‚|
}|r¥t ||ƒ dS )z=A wrapper the return the validity of a known ocsp certificatez4you are not authorized to view this ocsp certificatezReceived an Ú.é   z ocsp certificate statusz@failed to retrieve a successful response from the ocsp responderz)ocsp certificate was issued in the futurez1ocsp certificate has invalid update - in the pastNr   z'no certificates found for the responderz'delegate not autorized for ocsp signingT)!r   Úload_der_ocsp_responseÚresponse_statusÚOCSPResponseStatusÚUNAUTHORIZEDr   Ú
SUCCESSFULÚcertificate_statusÚOCSPCertStatusÚGOODr   ÚstrÚsplitÚthis_updateÚdatetimeÚnowÚnext_updateÚresponder_nameÚissuer_key_hashÚresponder_key_hashÚsubjectÚcertificatesÚ_get_certificatesÚ
IndexErrorÚ
extensionsÚget_extension_for_classr   ÚExtendedKeyUsageÚoidÚExtendedKeyUsageOIDÚOCSP_SIGNINGÚvaluer   )r   Ú
ocsp_bytesÚvalidater   r0   Úissuer_hashÚresponder_hashÚcert_to_validateÚcertsÚresponder_certsÚresponder_certÚextr   r   r   Ú_check_certificate1   sT   
ÿÿÿÿ
ÿÿ
rG   c                    s8   ˆd u r‡ ‡fdd„| D ƒ}|S ‡ ‡fdd„| D ƒ}|S )Nc                    s(   g | ]}t |ƒˆkr|jˆ jkr|‘qS r   )Ú_get_pubkey_hashÚissuerr3   ©Ú.0Úc)r   rA   r   r   Ú
<listcomp>n   s
    þz%_get_certificates.<locals>.<listcomp>c                    s&   g | ]}|j ˆkr|jˆ j kr|‘qS r   )r3   rI   rJ   )r   r0   r   r   rM   t   s
    þr   )rC   r   r0   rA   r4   r   )r   rA   r0   r   r5   l   s   þúþr5   c                 C   st   |   ¡ }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)Úbackend)r   r   r   Úpublic_bytesr   ÚDERr   ÚPKCS1r
   ÚX962ÚUncompressedPointÚSubjectPublicKeyInfor   r   r   Údefault_backendÚupdateÚfinalize)Úcertificater   ÚhÚsha1r   r   r   rH   }   s   


rH   c                 C   s†   |dv rt dƒ‚d}|  ¡  ¡ }|  ¡ D ]}| ¡ }|j|jkr$|} nq|du r-t dƒ‚|dur>t |¡}||kr>t dƒ‚t||ƒS )zÌAn implementation of a function for set_ocsp_client_callback in PyOpenSSL.

    This function validates that the provide ocsp_bytes response is valid,
    and matches the expected, stapled responses.
    )ó    Nzno ocsp response presentNz2no matching issuer cert found in certificate chainz/received and expected certificates do not match)	r   Úget_peer_certificateÚto_cryptographyÚget_peer_cert_chainr3   rI   r   Úload_pem_x509_certificaterG   )Úconr>   Úexpectedr   Ú	peer_certrL   ÚcertÚer   r   r   Úocsp_staple_verifier�   s"   þ

re   c                   @   sR   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ ZdS )ÚOCSPVerifiera  A class to verify ssl sockets for RFC6960/RFC6961. This can be used
    when using direct validation of OCSP responses and certificate revocations.

    @see https://datatracker.ietf.org/doc/html/rfc6960
    @see https://datatracker.ietf.org/doc/html/rfc6961
    Nc                 C   s   || _ || _|| _|| _d S ©N)ÚSOCKÚHOSTÚPORTÚCA_CERTS)ÚselfÚsockÚhostÚportÚca_certsr   r   r   Ú__init__±   s   
zOCSPVerifier.__init__c                 C   s"   t  |¡}t | ¡ t ¡ ¡}|S )z?Convert SSL certificates in a binary (DER) format to ASCII PEM.)ÚsslÚDER_cert_to_PEM_certr   r_   Úencoder   rU   )rl   ÚderÚpemrc   r   r   r   Ú
_bin2ascii·   s   
zOCSPVerifier._bin2asciic                 C   s0   | j  d¡}|du rtdƒ‚|  |¡}|  |¡S )z“This function returns the certificate, primary issuer, and primary ocsp
        server in the chain for a socket already wrapped with ssl.
        TFz!no certificate found for ssl peer)rh   Úgetpeercertr   rw   Ú_certificate_components)rl   ru   rc   r   r   r   Úcomponents_from_socket¾   s
   

z#OCSPVerifier.components_from_socketc                 C   s¬   z|j  tjjj¡j}W n tjj jy   t	dƒ‚w dd„ |D ƒ}z|d j
j}W n ty5   d}Y nw dd„ |D ƒ}z|d j
j}W n tyP   t	dƒ‚w |||fS )zÌGiven an SSL certificate, retract the useful components for
        validating the certificate status with an OCSP server.

        Args:
            cert ([bytes]): A PEM encoded ssl certificate
        z-No AIA information present in ssl certificatec                 S   ó    g | ]}|j tjjjkr|‘qS r   )Úaccess_methodr   r:   ÚAuthorityInformationAccessOIDÚ
CA_ISSUERS©rK   Úir   r   r   rM   Ú   ó
    þz8OCSPVerifier._certificate_components.<locals>.<listcomp>r   Nc                 S   r{   r   )r|   r   r:   r}   ÚOCSPr   r   r   r   rM   å   r�   zno ocsp servers in certificate)r7   Úget_extension_for_oidr   r:   ÚExtensionOIDÚAUTHORITY_INFORMATION_ACCESSr=   ÚcryptographyÚExtensionNotFoundr   Úaccess_locationr6   )rl   rc   ÚaiaÚissuersrI   Úocspsr   r   r   r   ry   Ê   s4   ÿþÿþÿþÿ
z$OCSPVerifier._certificate_componentsc                 C   s6   t j| j| jf| jd�}t | ¡ t 	¡ ¡}|  
|¡S )zÎReturn the certificate, primary issuer, and primary ocsp server
        from the host defined by the socket. This is useful in cases where
        different certificates are occasionally presented.
        )rp   )rr   Úget_server_certificateri   rj   rk   r   r_   rt   r   rU   ry   )rl   rv   rc   r   r   r   Ú!components_from_direct_connectionò   s   
z.OCSPVerifier.components_from_direct_connectionc                 C   sT   t  ¡ }| ||tjjj ¡ ¡}| ¡ }t	 
| tjjjj¡¡}t|| d¡ƒ}|S )z#Return the complete url to the ocspÚascii)r   ÚOCSPRequestBuilderÚadd_certificater†   r   Ú
primitivesÚhashesÚSHA256ÚbuildÚbase64Ú	b64encoderO   Úserializationr   rP   r   Údecode)rl   Úserverrc   r   ÚorbÚrequestÚpathÚurlr   r   r   Úbuild_certificate_urlü   s   ÿÿz"OCSPVerifier.build_certificate_urlc           	      C   sp   t  |¡}|jstdƒ‚|j}|  |¡}|  |||¡}t|ƒjddœ}t j||d�}|js1tdƒ‚t	||jdƒS )z3Checks the validity of an ocsp server for an issuerz"failed to fetch issuer certificatezapplication/ocsp-request)ÚHostzContent-Type)Úheadersz failed to fetch ocsp certificateT)
ÚrequestsÚgetÚokr   Úcontentrw   rž   r   ÚnetlocrG   )	rl   r™   rc   Ú
issuer_urlÚrru   r   Úocsp_urlÚheaderr   r   r   Úcheck_certificate  s   

þzOCSPVerifier.check_certificatec                 C   sn   z|   ¡ \}}}|du rtdƒ‚|  |||¡W S  ty6   |  ¡ \}}}|du r-tdƒ‚|  |||¡ Y S w )aD  Returns the validity of the certificate wrapping our socket.
        This first retrieves for validate the certificate, issuer_url,
        and ocsp_server for certificate validate. Then retrieves the
        issuer certificate from the issuer_url, and finally checks
        the validity of OCSP revocation status.
        Nz%no issuers found in certificate chain)rz   r   rª   r   r�   )rl   rc   r¦   Úocsp_serverr   r   r   Úis_valid!  s   	üzOCSPVerifier.is_validrg   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__rq   rw   rz   ry   r�   rž   rª   r¬   r   r   r   r   rf   ©   s    
(
rf   )Trg   )(r•   r-   rr   Úurllib.parser   r   Ú%cryptography.hazmat.primitives.hashesr†   r¡   r   r   Úcryptography.exceptionsr   Úcryptography.hazmatr   Ú-cryptography.hazmat.primitives.asymmetric.dsar   Ú,cryptography.hazmat.primitives.asymmetric.ecr	   r
   Ú1cryptography.hazmat.primitives.asymmetric.paddingr   Ú-cryptography.hazmat.primitives.asymmetric.rsar   r   r   Ú,cryptography.hazmat.primitives.serializationr   r   Úcryptography.x509r   Úredis.exceptionsr   r   r   rG   r5   rH   re   rf   r   r   r   r   Ú<module>   s.    
;
