Ë
    M/ÅeÌ:  ã            
       óê  — d Z ddlmZ ddlmZ ddlZddlZddl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Zddl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  ej@                  e!«      Z" G d„ d«      Z#de$de	ee$   ee$   f   fd„Z%de$de$de$de&de'f
d„Z(dddd d!ejR                  de$ddf
d"„Z*ddd!ejR                  de$ddfd#„Z+de$d$e$d%e$de'fd&„Z,y)'z*Tools for checking certificate revocation.é    )Údatetime)Ú	timedeltaN)ÚPIPE)ÚOptional)ÚTuple)Úx509)ÚInvalidSignature)ÚUnsupportedAlgorithm)Údefault_backend)Úhashes)Úserialization)Úocsp)Úcrypto_util)Úerrors)Úutil)Úgetenv)ÚRenewableCertc                   ól   — e Zd ZdZddeddfd„Zdedefd„Zdded	ed
e	defd„Z
ded	ededed
e	defd„Zy)ÚRevocationCheckerzEThis class figures out OCSP checking on this system, and performs it.Úenforce_openssl_binary_usageÚreturnNc           	      óJ  — d| _         || _        | j                  r‰t        j                  d«      st        j                  d«       d| _         y t        j                  g d¢t        t        ddt        j                  «       ¬«      }d|j                  v r	d„ | _        y d	„ | _        y y )
NFÚopensslz-openssl not installed, can't check revocationT)r   r   ú-headerÚvarÚval)ÚstdoutÚstderrÚuniversal_newlinesÚcheckÚenvz	Missing =c                 ó   — d| z   gS )NzHost=© ©Úhosts    ú./usr/lib/python3/dist-packages/certbot/ocsp.pyú<lambda>z,RevocationChecker.__init__.<locals>.<lambda>0   s   € ¨w¸©~Ð.>€ ó    c                 ó
   — d| gS )NÚHostr#   r$   s    r&   r'   z,RevocationChecker.__init__.<locals>.<lambda>2   s
   € ¨v°t¨n€ r(   )ÚbrokenÚuse_openssl_binaryr   Ú
exe_existsÚloggerÚinfoÚ
subprocessÚrunr   Úenv_no_snap_for_external_callsr   Ú	host_args)Úselfr   Útest_host_formats      r&   Ú__init__zRevocationChecker.__init__!   sŒ   € ØˆŒØ">ˆÔà×"Ò"Ü—?‘? 9Ô-Ü—‘ÐKÔLØ"�”Øô  *Ÿ~™~Ò.ZÜ,0¼ÐRVØ+0´d×6YÑ6YÓ6[ô ]Ðð Ð.×5Ñ5Ñ5Ù!>�•á!<�•ð #r(   Úcertc                 óN   — | j                  |j                  |j                  «      S )a   Get revoked status for a particular cert version.

        .. todo:: Make this a non-blocking call

        :param `.interfaces.RenewableCert` cert: Certificate object
        :returns: True if revoked; False if valid or the check failed or cert is expired.
        :rtype: bool

        )Úocsp_revoked_by_pathsÚ	cert_pathÚ
chain_path)r4   r7   s     r&   Úocsp_revokedzRevocationChecker.ocsp_revoked4   s   € ð ×)Ñ)¨$¯.©.¸$¿/¹/ÓJÐJr(   r:   r;   Útimeoutc                 ó  — | j                   ryt        j                  t        j                  «      }t        j                  |«      |k  ryt        |«      \  }}|r|sy| j                  r| j                  |||||«      S t        ||||«      S )aE  Performs the OCSP revocation check

        :param str cert_path: Certificate filepath
        :param str chain_path: Certificate chain
        :param int timeout: Timeout (in seconds) for the OCSP query

        :returns: True if revoked; False if valid or the check failed or cert is expired.
        :rtype: bool

        F)r+   r   ÚnowÚpytzÚUTCr   ÚnotAfterÚ_determine_ocsp_serverr,   Ú_check_ocsp_openssl_binÚ_check_ocsp_cryptography)r4   r:   r;   r=   r?   Úurlr%   s          r&   r9   z'RevocationChecker.ocsp_revoked_by_paths@   s‚   € ð �;Š;Øô
 �l‰lœ4Ÿ8™8Ó$ˆÜ×Ñ 	Ó*¨cÒ1Øä*¨9Ó5‰	ˆˆTÙ™3Øà×"Ò"Ø×/Ñ/°	¸:ÀtÈSÐRYÓZÐZÜ'¨	°:¸sÀGÓLÐLr(   r%   rF   c                 ó:  — t        d«      }t        d«      }d }|€|�|�|n|}|€d|g}	n%|j                  d«      r|t        d«      d  }d|d|g}	ddd	d
|d|d|d|ddt        |«      dg| j	                  |«      z   |	z   }
t
        j                  d|«       t
        j                  dj                  |
«      «       	 t        j                  |
t
        j                  ¬«      \  }}t        |||«      S # t        j                  $ r t
        j                  d|«       Y yw xY w)NÚ
http_proxyÚ
HTTP_PROXYz-urlzhttp://z-hostz-pathr   r   z	-no_noncez-issuerz-certz-CAfilez-verify_otherz-trust_otherz-timeoutr   zQuerying OCSP for %sú )Úlogú*OCSP check failed for %s (are we offline?)F)r   Ú
startswithÚlenÚstrr3   r.   ÚdebugÚjoinr   Ú
run_scriptr   ÚSubprocessErrorr/   Ú_translate_ocsp_query)r4   r:   r;   r%   rF   r=   Úenv_http_proxyÚenv_HTTP_PROXYÚ
proxy_hostÚurl_optsÚcmdÚoutputÚerrs                r&   rD   z)RevocationChecker._check_ocsp_openssl_bin]   s:  € ô   Ó-ˆÜ Ó-ˆØˆ
ØÐ%¨Ð)CØ+9Ð+E™È>ˆJØÐØ �}‰Hà×$Ñ$ YÔ/Ø'¬¨I«¨Ð8�
Ø ¨W°cÐ:ˆHà˜&ØØ˜*Ø˜	Ø˜*Ø 
ØØœ3˜w›<Øðð !ŸN™N¨4Ó0ñ1ð 4<ñ<ˆô 	�‰Ð+¨YÔ7Ü�‰�S—X‘X˜c“]Ô#ð	ÜŸ/™/¨#´6·<±<Ô@‰KˆF�Cô % Y°¸Ó<Ð<øô ×%Ñ%ò 	Ü�K‰KÐDÀiÔPÙð	ús   Â9(C. Ã.)DÄD)F)é
   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úboolr6   r   r<   rO   Úintr9   rD   r#   r(   r&   r   r      sˆ   „ ÙOñ=°Tð =Àdó =ð&
K ð 
K°4ó 
KñM¨sð MÀð MÈcð MÐ[_ó Mð:#=°ð #=À#ð #=Ø&)ð#=Ø03ð#=Ø>Að#=ØFJô#=r(   r   r:   r   c                 ó¼  — t        | d«      5 }t        j                  |j                  «       t	        «       «      }ddd«       	 j
                  j                  t        j                  «      }t        j                  j                  }|j                  D �cg c]  }|j                  |k(  r|‘Œ }}|d   j                  j                  }|j#                  «       }|j%                  d«      d   j#                  d«      }|r||fS t        j!                  d	|| «       y# 1 sw Y   ŒßxY wc c}w # t        j                  t        f$ r t        j!                  d| «       Y yw xY w)
zÎExtract the OCSP server host from a certificate.

    :param str cert_path: Path to the cert we're checking OCSP for
    :rtype tuple:
    :returns: (OCSP server URL or None, OCSP server host or None)

    ÚrbNr   zCannot extract OCSP URI from %s)NNz://é   ú/z;Cannot process OCSP host from URL (%s) in certificate at %s)Úopenr   Úload_pem_x509_certificateÚreadr   Ú
extensionsÚget_extension_for_classÚAuthorityInformationAccessÚAuthorityInformationAccessOIDÚOCSPÚvalueÚaccess_methodÚaccess_locationÚExtensionNotFoundÚ
IndexErrorr.   r/   ÚrstripÚ	partition)	r:   Úfile_handlerr7   Ú	extensionÚocsp_oidÚdescriptionÚdescriptionsrF   r%   s	            r&   rC   rC   ƒ   s?  € ô 
ˆi˜Ó	ð V ,Ü×-Ñ-¨l×.?Ñ.?Ó.AÄ?ÓCTÓUˆ÷Vð	Ø—O‘O×;Ñ;¼D×<[Ñ<[Ó\ˆ	Ü×5Ñ5×:Ñ:ˆØ7@·±ö B¨Ø&×4Ñ4¸Ò@ò $ð Bˆð Bð ˜1‰o×-Ñ-×3Ñ3ˆð
 �*‰*‹,€CØ�=‰=˜Ó Ñ"×)Ñ)¨#Ó.€DáØ�DˆyÐÜ
‡K�KÐMÈsÐT]Ô^Ø÷'Vð Vüò
Bøô ×"Ñ"¤JÐ/ò Ü�‰Ð5°yÔAÙðús0   �-DÁAD) ÂD$Â,D) ÄD!Ä$D) Ä)/EÅEr;   rF   r=   c                 ó(  — t        |d«      5 }t        j                  |j                  «       t	        «       «      }d d d «       t        | d«      5 }t        j                  |j                  «       t	        «       «      }d d d «       t        j                  «       }|j                  t        j                  «       «      }|j                  «       }|j                  t        j                  j                  «      }		 t        j                   ||	ddi|¬«      }
|
j*                  d	k7  r"t&        j)                  d
| |
j*                  «       yt        j,                  |
j.                  «      }|j0                  t
        j2                  j4                  k7  r"t&        j7                  d| |j0                  «       y	 t9        |||| «       t&        j;                  d| |j<                  «       |j<                  t
        j>                  j@                  k(  S # 1 sw Y   �ŒÉxY w# 1 sw Y   �Œ•xY w# t        j"                  j$                  $ r t&        j)                  d| d¬«       Y yw xY w# tB        $ r(}t&        j7                  tE        |«      «       Y d }~yd }~wtF        jH                  $ r(}t&        j7                  tE        |«      «       Y d }~yd }~wtJ        $ r t&        j7                  d| «       Y ytL        $ r*}t&        j7                  d| tE        |«      «       Y d }~yd }~ww xY w)Nrd   zContent-Typezapplication/ocsp-request)ÚdataÚheadersr=   rL   T)Úexc_infoFéÈ   z*OCSP check failed for %s (HTTP status: %d)z'Invalid OCSP response status for %s: %sz%OCSP certificate status for %s is: %sz)Invalid signature on OCSP response for %sz!Invalid OCSP response for %s: %s.)'rg   r   rh   ri   r   r   ÚOCSPRequestBuilderÚadd_certificater   ÚSHA1ÚbuildÚpublic_bytesr   ÚEncodingÚDERÚrequestsÚpostÚ
exceptionsÚRequestExceptionr.   r/   Ústatus_codeÚload_der_ocsp_responseÚcontentÚresponse_statusÚOCSPResponseStatusÚ
SUCCESSFULÚwarningÚ_check_ocsp_responserP   Úcertificate_statusÚOCSPCertStatusÚREVOKEDr
   rO   r   ÚErrorr	   ÚAssertionError)r:   r;   rF   r=   rv   Úissuerr7   ÚbuilderÚrequestÚrequest_binaryÚresponseÚresponse_ocspÚeÚerrors                 r&   rE   rE   ¡   sŽ  € ä	ˆj˜$Ó	ð X <Ü×/Ñ/°×0AÑ0AÓ0CÄ_ÓEVÓWˆ÷Xä	ˆi˜Ó	ð V ,Ü×-Ñ-¨l×.?Ñ.?Ó.AÄ?ÓCTÓUˆ÷Vä×%Ñ%Ó'€GØ×%Ñ% d¨F´F·K±K³MÓB€GØ�m‰m‹o€GØ×)Ñ)¬-×*@Ñ*@×*DÑ*DÓE€NðÜ—=‘= ¨>Ø*8Ð:TÐ)UØ)0ô2ˆð ×Ñ˜sÒ"Ü�‰Ð@À)ÈX×MaÑMaÔbØä×/Ñ/°×0@Ñ0@ÓA€Mð ×$Ñ$¬×(?Ñ(?×(JÑ(JÒJÜ�‰Ð@Ø × =Ñ =ô	?àðOÜ˜]¨G°V¸YÔGô 	�‰Ð<Ø × @Ñ @ô	Bà×/Ñ/´4×3FÑ3F×3NÑ3NÑNÐN÷UXñ Xú÷Vñ Vûô ×Ñ×/Ñ/ò Ü�‰Ð@À)ÐVZˆÔ[Ùðûô$  ò Ü�‰”s˜1“v×Ðð ûô �<‰<ò Ü�‰”s˜1“v×Ðð ûô ò OÜ�‰ÐBÀIÕNð ô ò SÜ�‰Ð:¸IÄsÈ5Ãz×RÐRð ûðSús_   �-HÁ-HÃ6H Æ+I ÈHÈHÈ5IÉIÉ	LÉJÊLÊJ;Ê;"LËLË' LÌLr�   zocsp.OCSPResponseÚrequest_ocspzocsp.OCSPRequestÚissuer_certc                 ó|  — | j                   |j                   k7  rt        d«      ‚t        | ||«       t        | j                  t        |j                  «      «      r2| j                  |j                  k7  s| j                  |j                  k7  rt        d«      ‚t        j                  t        j                  «      j                  d¬«      }| j                  st        d«      ‚| j                  |t        d¬«      z   kD  rt        d«      ‚| j                  r(| j                  |t        d¬«      z
  k  rt        d	«      ‚yy)
z2Verify that the OCSP is valid for several criteriazMthe certificate in response does not correspond to the certificate in requestz<the issuer does not correspond to issuer of the certificate.N)Útzinfozparam thisUpdate is not set.é   )Úminutesz"param thisUpdate is in the future.z param nextUpdate is in the past.)Úserial_numberr—   Ú_check_ocsp_response_signatureÚ
isinstanceÚhash_algorithmÚtypeÚissuer_key_hashÚissuer_name_hashr   r?   r@   rA   ÚreplaceÚthis_updater   Únext_update)r�   r    r¡   r:   r?   s        r&   r’   r’   Ò   s  € ð ×"Ñ" l×&@Ñ&@Ò@Üð =ó >ð 	>ô # =°+¸yÔIô �}×3Ñ3´T¸,×:UÑ:UÓ5VÔWØ×,Ñ,°×0LÑ0LÒLØ×-Ñ-°×1NÑ1NÒNÜÐ[Ó\Ð\ô �,‰,”t—x‘xÓ
 ×
(Ñ
(°Ð
(Ó
5€CØ×$Ò$ÜÐ;Ó<Ð<Ø× Ñ  3¬¸1Ô)=Ñ#=Ò=ÜÐAÓBÐBØ× Ò  ]×%>Ñ%>ÀÄyÐYZÔG[ÑA[Ò%[ÜÐ?Ó@Ð@ð &\Ð r(   c                 óB  — dt         j                  dt        fd„}| j                  |j                  k(  s| j
                   ||«      k(  rt        j                  d|«       |}�nDt        j                  d|«       | j                  D �cg c]2  }| j                  |j                  k(  s| j
                   ||«      k(  r|‘Œ4 }}|st        d«      ‚|d   }|j                  |j                  k7  rt        d«      ‚	 |j                  j                  t         j                  «      }t         j                  j                  j                   |j"                  v }|st        d
«      ‚|j(                  }	|	sJ ‚t+        j,                  |j/                  «       |j0                  |j2                  |	«       | j(                  }
|
st        d«      ‚t+        j,                  |j/                  «       | j0                  | j4                  |
«       yc c}w # t         j$                  t&        f$ r d	}Y ŒÍw xY w)zIVerify an OCSP response signature against certificate issuer or responderr7   r   c                 óp   — t         j                  j                  | j                  «       «      j                  S )N)r   ÚSubjectKeyIdentifierÚfrom_public_keyÚ
public_keyÚdigest)r7   s    r&   Ú	_key_hashz1_check_ocsp_response_signature.<locals>._key_hashù   s&   € Ü×(Ñ(×8Ñ8¸¿¹Ó9JÓK×RÑRÐRr(   zGOCSP response for certificate %s is signed by the certificate's issuer.zGOCSP response for certificate %s is delegated to an external responder.z0no matching responder certificate could be foundr   z?responder certificate is not signed by the certificate's issuerFz<responder is not authorized by issuer to sign OCSP responsesz#no signature hash algorithm definedN)r   ÚCertificateÚbytesÚresponder_nameÚsubjectÚresponder_key_hashr.   rP   Úcertificatesr—   r˜   rj   rk   ÚExtendedKeyUsageÚoidÚExtendedKeyUsageOIDÚOCSP_SIGNINGro   rr   rs   Úsignature_hash_algorithmr   Úverify_signed_payloadr´   Ú	signatureÚtbs_certificate_bytesÚtbs_response_bytes)r�   r¡   r:   r¶   Úresponder_certr7   Úresponder_certsrw   Údelegate_authorizedÚchosen_cert_hashÚchosen_response_hashs              r&   r§   r§   ö   s  € ðSœ×(Ñ(ð S¬Uó Sð 	×$Ñ$¨×(;Ñ(;Ò;Ø×/Ñ/±9¸[Ó3IÒIä�‰Ð_Øô	 à$Šô 	�‰Ð^Øô	 ð -:×,FÑ,Fö S DØ+×:Ñ:¸d¿l¹lÒJØ+×>Ñ>Á)ÈDÃ/ÒQò  ð Sˆð Sñ Ü Ð!SÓTÐTð
 )¨Ñ+ˆà× Ñ  K×$7Ñ$7Ò7Ü ð "@ó Að Að	(Ø&×1Ñ1×IÑIÌ$×J_ÑJ_Ó`ˆIÜ"&§(¡(×">Ñ">×"KÑ"KÈyÏÉÐ"^Ðñ #Ü Ð!_Ó`Ð`ð *×BÑBÐÙÐÐô 	×)Ñ)¨+×*@Ñ*@Ó*BÀN×D\ÑD\Ø*8×*NÑ*NÐP`ô	bð )×AÑAÐñ  ÜÐBÓCÐCÜ×%Ñ% n×&?Ñ&?Ó&AÀ=×CZÑCZØ&3×&FÑ&FÐH\õ^ùòKSøô$ ×&Ñ&¬
Ð3ò 	(Ø"'Òð	(ús   Â7G;Ã7AH  È HÈHÚocsp_outputÚocsp_errorsc                 óš  ‡— d}|D �cg c]  }dj                  | |«      ‘Œ }}ˆfd„|D «       \  }}}|r|j                  d«      nd}	d|vs|r|	s|r.t        j                  d| «       t        j	                  d‰|«       y	|r|	sy	|r*|j                  d«      }	|	rt        j                  d
|	«       yt        j                  d‰|«       y	c c}w )z7Parse openssl's weird output to work out what it means.)ÚgoodÚrevokedÚunknownz{0}: (WARNING.*)?{1}c              3   ój   •K  — | ]*  }t        j                  |‰t         j                  ¬ «      –— Œ, y­w))ÚflagsN)ÚreÚsearchÚDOTALL)Ú.0ÚprË   s     €r&   ú	<genexpr>z(_translate_ocsp_query.<locals>.<genexpr>5  s%   øè ø€ Ò[ÈQœbŸi™i¨¨;¼b¿i¹i×HÐHÑ[ùs   ƒ03é   NzResponse verify OKz#Revocation status for %s is unknownzUncertain output:
%s
stderr:
%sFzOCSP revocation warning: %sTz2Unable to properly parse OCSP output: %s
stderr:%s)ÚformatÚgroupr.   r/   rP   r‘   )
r:   rË   rÌ   ÚstatesÚsÚpatternsrÎ   rÏ   rÐ   r‘   s
    `        r&   rT   rT   0  sÊ   ø€ ð ,€FØFLÖMÀÐ'×.Ñ.¨y¸!Õ<ÐM€HÐMÛ[ÐRZÔ[Ñ€Dˆ'�7á#ˆd�j‰j˜Œm¨€Gà KÑ/±T¹gÉ'Ü�‰Ð9¸9ÔEÜ�‰Ð9¸;ÈÔTØÙ	‘gØÙ	Ø—-‘- Ó"ˆÙÜ�K‰KÐ5°wÔ?Øä�‰ÐLØ" Kô	1àùò' Ns   ˆC)-r`   r   r   ÚloggingrÓ   r0   r   Útypingr   r   Úcryptographyr   Úcryptography.exceptionsr	   r
   Úcryptography.hazmat.backendsr   Úcryptography.hazmat.primitivesr   r   Úcryptography.x509r   r@   r‡   Úcertbotr   r   r   Úcertbot.compat.osr   Úcertbot.interfacesr   Ú	getLoggerr]   r.   r   rO   rC   rb   ra   rE   r·   r’   r§   rT   r#   r(   r&   ú<module>rê      sF  ðÙ 0Ý Ý Û Û 	Û Ý Ý Ý å Ý 4Ý 8Ý 8Ý 1Ý 8Ý "Û Û å Ý Ý Ý $Ý ,à	ˆ×	Ñ	˜8Ó	$€÷b=ñ b=ðJ cð ¨e°H¸S±MÀ8ÈCÁ=Ð4PÑ.Qó ð<.¨ð .¸ð .À3ð .ÐQTð .ÐY]ó .ðb!AÐ(;ð !AÐK]ð !AØ&*×&6Ñ&6ð!AØCFð!AØKOó!AðH7^Ð2Eð 7^Ø04×0@Ñ0@ð7^ØMPð7^ØUYó7^ðt Sð °sð Èð ÐQUô r(   