U
    d,                     @   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   |   }z|t|tr.||j|jt |j nTt|trN||j|j|j n4t|t	rr||j|jt
|j n||j|j W n tk
r   tdY nX d S )Nzfailed to valid ocsp response)
public_key
isinstancer   verify	signatureZtbs_response_bytesr   Zsignature_hash_algorithmr   r
   r	   r   r   )issuer_certocsp_responsepubkey r   ./tmp/pip-unpacked-wheel-f5h5_hbx/redis/ocsp.py_verify_response   s0    


r   Tc                 C   s\  t |}|jt jjkr td|jt jjkr^|jt jj	krft
dt|jdd  dnt
d|jtj kr~t
d|jr|jtj k rt
d|j}|j}|j}| }|d	k	r|| jks||kr| }nv|j}t|| ||}	z|	d
 }
W n tk
r   t
dY nX |
jtj}|d	ks<tjjj|jkrDt
d|
}|rXt || 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 sucessful 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   Zload_der_ocsp_responseZresponse_statusZOCSPResponseStatusUNAUTHORIZEDr   Z
SUCCESSFULZcertificate_statusZOCSPCertStatusZGOODr   strsplitZthis_updatedatetimenowZnext_updateresponder_nameZissuer_key_hashZresponder_key_hashsubjectcertificates_get_certificates
IndexError
extensionsZget_extension_for_classr   ZExtendedKeyUsageoidZExtendedKeyUsageOIDZOCSP_SIGNINGvaluer   )r   
ocsp_bytesvalidater   r%   Zissuer_hashresponder_hashZcert_to_validatecertsZresponder_certsZresponder_certextr   r   r   _check_certificate2   s^    
   
r2   c                    s6   d kr fdd| D }n fdd| D }|S )Nc                    s(   g | ] }t |kr|j jkr|qS r   )_get_pubkey_hashissuerr&   .0c)r   r/   r   r   
<listcomp>o   s    z%_get_certificates.<locals>.<listcomp>c                    s&   g | ]}|j kr|j j kr|qS r   )r&   r4   r5   )r   r%   r   r   r8   u   s   
 r   )r0   r   r%   r/   r'   r   )r   r/   r%   r   r(   m   s    r(   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   ZPKCS1r
   ZX962ZUncompressedPointZSubjectPublicKeyInfor   r   r   default_backendupdatefinalize)Zcertificater   hsha1r   r   r   r3   ~   s    


r3   c                 C   s   |dkrt dd}|   }|  D ] }| }|j|jkr(|} qJq(|dkrZt d|dk	r|t|}||kr|t dt||S )zAn implemention 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   Zget_peer_certificateZto_cryptographyZget_peer_cert_chainr&   r4   r   load_pem_x509_certificater2   )conr-   expectedr   Z	peer_certr7   certer   r   r   ocsp_staple_verifier   s     
rG   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   rB   encoder   r<   )rM   derpemrE   r   r   r   
_bin2ascii   s    
zOCSPVerifier._bin2asciic                 C   s0   | j d}|dkrtd| |}| |S )zThis 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)rI   getpeercertr   rX   _certificate_components)rM   rV   rE   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k
r:   t	dY nX dd |D }z|d j
j}W n tk
rr   d}Y nX dd |D }z|d j
j}W n tk
r   t	dY nX |||fS )zGiven 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   s    g | ]}|j tjjjkr|qS r   )access_methodr   r+   AuthorityInformationAccessOIDZ
CA_ISSUERSr6   ir   r   r   r8      s   z8OCSPVerifier._certificate_components.<locals>.<listcomp>r   Nc                 S   s    g | ]}|j tjjjkr|qS r   )r\   r   r+   r]   ZOCSPr^   r   r   r   r8      s   zno ocsp servers in certificate)r*   Zget_extension_for_oidr   r+   ZExtensionOIDZAUTHORITY_INFORMATION_ACCESSr,   cryptographyZExtensionNotFoundr   Zaccess_locationr)   )rM   rE   ZaiaZissuersr4   Zocspsr   r   r   r   rZ      s*    

z$OCSPVerifier._certificate_componentsc                 C   s6   t j| j| jf| jd}t| t	 }| 
|S )zReturn 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.
        )rQ   )rS   get_server_certificaterJ   rK   rL   r   rB   rU   r   r<   rZ   )rM   rW   rE   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   ZOCSPRequestBuilderZadd_certificater`   r   Z
primitiveshashesSHA256buildbase64	b64encoder:   Zserializationr   r;   r   decode)rM   serverrE   r   Z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sbtdt	||jdS )z5Checks the validitity 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   contentrX   rn   r   netlocr2   )	rM   rj   rE   
issuer_urlrrV   r   Zocsp_urlheaderr   r   r   check_certificate  s    

zOCSPVerifier.check_certificatec                 C   st   z.|   \}}}|dkr td| |||W S  tk
rn   |  \}}}|dkr\td| ||| Y S X dS )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 valididy of OCSP revocation status.
        Nz%no issuers found in certificate chain)r[   r   ry   r   rb   )rM   rE   rv   Zocsp_serverr   r   r   is_valid"  s    	zOCSPVerifier.is_valid)N)__name__
__module____qualname____doc__rR   rX   r[   rZ   rb   rn   ry   rz   r   r   r   r   rH      s   
(
rH   )T)N)(rg   r#   rS   urllib.parser   r   Z%cryptography.hazmat.primitives.hashesr`   rq   r   r   Zcryptography.exceptionsr   Zcryptography.hazmatr   Z-cryptography.hazmat.primitives.asymmetric.dsar   Z,cryptography.hazmat.primitives.asymmetric.ecr	   r
   Z1cryptography.hazmat.primitives.asymmetric.paddingr   Z-cryptography.hazmat.primitives.asymmetric.rsar   r   r   Z,cryptography.hazmat.primitives.serializationr   r   Zcryptography.x509r   Zredis.exceptionsr   r   r   r2   r(   r3   rG   rH   r   r   r   r   <module>   s,   
;
