U
    g,                     @   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	signaturetbs_response_bytesr   signature_hash_algorithmr   r
   r	   r   r   )issuer_certocsp_responsepubkey r   ./tmp/pip-unpacked-wheel-f3sx1i9r/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 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_statusZOCSPResponseStatusUNAUTHORIZEDr   Z
SUCCESSFULcertificate_statusZOCSPCertStatusZ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   r,   Zissuer_hashresponder_hashZcert_to_validatecertsZresponder_certsZresponder_certextr   r   r   _check_certificate1   s^    
   
r?   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>n   s    z%_get_certificates.<locals>.<listcomp>c                    s&   g | ]}|j kr|j j kr|qS r   )r/   rA   rB   )r   r,   r   r   rE   t   s   
 r   )r=   r   r,   r<   r0   r   )r   r<   r,   r   r1   l   s    r1   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   r@   }   s    


r@   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 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_chainr/   rA   r   load_pem_x509_certificater?   )conr:   expectedr   Z	peer_certrD   certer   r   r   ocsp_staple_verifier   s     
r\   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   rW   encoder   rM   )rb   derpemrZ   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)r^   getpeercertr   rm   _certificate_components)rb   rk   rZ   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   r6   AuthorityInformationAccessOID
CA_ISSUERSrC   ir   r   r   rE      s   z8OCSPVerifier._certificate_components.<locals>.<listcomp>r   Nc                 S   s    g | ]}|j tjjjkr|qS r   )rq   r   r6   rr   OCSPrt   r   r   r   rE      s   zno ocsp servers in certificate)r3   get_extension_for_oidr   r6   ExtensionOIDAUTHORITY_INFORMATION_ACCESSr9   cryptographyExtensionNotFoundr   access_locationr2   )rb   rZ   ZaiaZissuersrA   Zocspsr   r   r   r   ro      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.
        )rf   )rh   get_server_certificater_   r`   ra   r   rW   rj   r   rM   ro   )rb   rl   rZ   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_certificaterz   r   
primitiveshashesSHA256buildbase64	b64encoderG   serializationr   rH   r   decode)rb   serverrZ   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 )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   contentrm   r   r   netlocr?   )	rb   r   rZ   
issuer_urlrrk   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 validity of OCSP revocation status.
        Nz%no issuers found in certificate chain)rp   r   r   r   r~   )rb   rZ   r   Zocsp_serverr   r   r   is_valid!  s    	zOCSPVerifier.is_valid)N)__name__
__module____qualname____doc__rg   rm   rp   ro   r~   r   r   r   r   r   r   r   r]      s   
(
r]   )T)N)(r   r)   rh   urllib.parser   r   %cryptography.hazmat.primitives.hashesrz   r   r   r   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   ,cryptography.hazmat.primitives.serializationr   r   cryptography.x509r   Zredis.exceptionsr   r   r   r?   r1   r@   r\   r]   r   r   r   r   <module>   s,   
;
