M/e: dZddlmZddlmZddlZddlZddlZddlmZddlmZddlm Z ddl m Z dd l m Z dd l mZdd lmZdd lmZdd lmZddlmZddlZddlZddlmZddlmZddlmZddlmZddlmZej@e!Z"GddZ#de$de ee$ee$ffdZ%de$de$de$de&de'f dZ(dddd d!e jRde$ddf d"Z*ddd!e jRde$ddfd#Z+de$d$e$d%e$de'fd&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 leZdZdZddeddfdZdedefdZdded ed e defd Z ded ed ed ed e def dZ y)RevocationCheckerzEThis class figures out OCSP checking on this system, and performs it.enforce_openssl_binary_usagereturnNc Jd|_||_|jrtjdstj dd|_yt jgdttddtj}d|jvr d|_ yd |_ yy) NFopensslz-openssl not installed, can't check revocationT)rr-headervarval)stdoutstderruniversal_newlinescheckenvz Missing =cd|zgS)NzHost=hosts ./usr/lib/python3/dist-packages/certbot/ocsp.pyz,RevocationChecker.__init__..0s w~.>c d|gS)NHostr#r$s r&r'z,RevocationChecker.__init__..2s vtnr() brokenuse_openssl_binaryr exe_existsloggerinfo subprocessrunrenv_no_snap_for_external_callsr host_args)selfrtest_host_formats r&__init__zRevocationChecker.__init__!s ">  " "??9- KL"  *~~.Z,0RV+0d6Y6Y6[ ] .555!>!< #r(certcN|j|j|jS)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)r4r7s r& ocsp_revokedzRevocationChecker.ocsp_revoked4s))$..$//JJr(r:r;timeoutc|jrytjtj}t j ||kryt|\}}|r|sy|jr|j|||||St||||S)aEPerforms 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+rnowpytzUTCrnotAfter_determine_ocsp_serverr,_check_ocsp_openssl_bin_check_ocsp_cryptography)r4r:r;r=r?urlr%s r&r9z'RevocationChecker.ocsp_revoked_by_paths@s ;; ll488$    *c 1*95 T3  " "// :tSRYZ Z' :sGLLr(r%rFc:td}td}d}||||n|}|d|g} n%|jdr|tdd}d|d|g} ddd d |d |d |d |ddt|dg|j |z| z} t j d|t j dj|  tj| t j \} } t|| | S#tj$rt jd|YywxYw)N http_proxy HTTP_PROXYz-urlzhttp://z-hostz-pathrrz -no_noncez-issuerz-certz-CAfilez -verify_otherz -trust_otherz-timeoutrzQuerying OCSP for %s )log*OCSP check failed for %s (are we offline?)F)r startswithlenstrr3r.debugjoinr run_scriptrSubprocessErrorr/_translate_ocsp_query) r4r:r;r%rFr=env_http_proxyenv_HTTP_PROXY proxy_hosturl_optscmdoutputerrs r&rDz)RevocationChecker._check_ocsp_openssl_bin]s: - -  %)C+9+E>J  }H$$Y/'I8 Wc:H&* * 3w<!NN4014<<  +Y7 SXXc]# //#6<<@KFC%Y<<%%  KKDi P s9(C..)DD)F) ) __name__ __module__ __qualname____doc__boolr6rr<rOintr9rDr#r(r&rrsO=T=d=& K K4 KMsMMcM[_M:#=#=##=&)#=03#=>A#=FJ#=r(rr:rct|d5}tj|jt }ddd j j tj}tjj}|jDcgc]}|j|k(r|}}|djj}|j#}|j%ddj#d}|r||fStj!d ||y#1swYxYwcc}w#tjtf$rtj!d|YywxYw) zExtract 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) rbNrzCannot extract OCSP URI from %s)NNz:///z;Cannot process OCSP host from URL (%s) in certificate at %s)openrload_pem_x509_certificatereadr extensionsget_extension_for_classAuthorityInformationAccessAuthorityInformationAccessOIDOCSPvalue access_methodaccess_locationExtensionNotFound IndexErrorr.r/rstrip partition) r: file_handlerr7 extensionocsp_oid description descriptionsrFr%s r&rCrCs? i V,--l.?.?.A?CTUV OO;;D<[<[\ 55::7@B &44@$B B1o--33 **,C ==  " ) )# .D Dy KKMsT]^ 'VV B  " "J / 5yAs0-DAD)D$,D)D!$D))/EEr;rFr=c(t|d5}tj|jt }dddt|d5}tj|jt }dddt j }|jtj}|j}|jtjj} tj || ddi|} | j*d k7r"t&j)d || j*yt j,| j.} | j0t j2j4k7r"t&j7d || j0y t9| |||t&j;d || j<| j<t j>j@k(S#1swYxYw#1swYxYw#tj"j$$rt&j)d|dYywxYw#tB$r(} t&j7tE| Yd} ~ yd} ~ wtFjH$r(} t&j7tE| Yd} ~ yd} ~ wtJ$rt&j7d |YytL$r*} t&j7d|tE| Yd} ~ yd} ~ wwxYw)Nrdz Content-Typezapplication/ocsp-request)dataheadersr=rLT)exc_infoFz*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.)'rgrrhrir rOCSPRequestBuilderadd_certificater SHA1build public_bytesr EncodingDERrequestspost exceptionsRequestExceptionr.r/ status_codeload_der_ocsp_responsecontentresponse_statusOCSPResponseStatus SUCCESSFULwarning_check_ocsp_responserPcertificate_statusOCSPCertStatusREVOKEDr rOrErrorr AssertionError)r:r;rFr=rvissuerr7builderrequestrequest_binaryresponse response_ocspeerrors r&rErEs j$ X<// 0A0A0C_EVWX i V,--l.?.?.A?CTUV%%'G%%dFFKKMBGmmoG))-*@*@*D*DEN==>*8:T)U)02 s" @)XMaMab//0@0@AM$$(?(?(J(JJ@ = = ?O]GVYG  < @ @ B//43F3F3N3NNNUXXVV    / / @)VZ [$ s1v  <<s1v  OBIN  S:Is5zRR Ss_-H-H6H+IH H5II LJLJ;;"LL' L  Lrzocsp.OCSPResponse request_ocspzocsp.OCSPRequest issuer_certc||j|jk7r tdt|||t|jt |jr2|j |j k7s|j|jk7r tdtjtjjd}|js td|j|tdzkDr td|jr(|j|tdz kr td yy) z2Verify that the OCSP is valid for several criteriazMthe certificate in response does not correspond to the certificate in requestz >#=+yI }33T,:U:U5V W,, 0L0LL--1N1NN[\\ ,,txx ( ( ( 5C  $ $;<<  31)=#==ABB  ]%>%>yYZG[A[%[?@@&\ r(cBdtjdtfd}|j|jk(s|j ||k(rt jd||}nDt jd||jDcgc]2}|j|jk(s|j ||k(r|4}}|s td|d}|j|jk7r td |jjtj}tjjj |j"v}|s td |j(} | sJt+j,|j/|j0|j2| |j(} | s td t+j,|j/|j0|j4| y cc}w#tj$t&f$rd }YwxYw) zIVerify an OCSP response signature against certificate issuer or responderr7rcptjj|jjS)N)rSubjectKeyIdentifierfrom_public_key public_keydigest)r7s r& _key_hashz1_check_ocsp_response_signature.._key_hashs&((889JKRRRr(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 foundrz?responder certificate is not signed by the certificate's issuerFz>)D/Q SS !ST T )+  K$7$7 7 "@A A (&11II$J_J_`I"&((">">"K"Ky"^ # !_` `*BB ))+*@*@*BND\D\*8*N*NP` b)AA BCC%%n&?&?&A=CZCZ&3&F&FH\^KS$&& 3 ("'  (s7G;7AHHH ocsp_output ocsp_errorscd}|Dcgc]}dj||}}fd|D\}}}|r|jdnd} d|vs|r| s|r.tjd|tj d|y |r| sy |r*|jd} | rtjd | y tj d |y cc}w) z7Parse openssl's weird output to work out what it means.)goodrevokedunknownz{0}: (WARNING.*)?{1}c3jK|]*}tj|tj,yw))flagsN)researchDOTALL).0prs r& z(_translate_ocsp_query..5s%[Qbii;biiHH[s03NzResponse verify OKz#Revocation status for %s is unknownzUncertain output: %s stderr: %sFzOCSP revocation warning: %sTz2Unable to properly parse OCSP output: %s stderr:%s)formatgroupr.r/rPr) r:rrstatesspatternsrrrrs ` r&rTrT0s,FFLM'..y!<MHM[RZ[D'7#djjmGK/Tg' 99E 9; T g --"  KK5w ?L"K 1'NsC)-r`rrloggingrr0rtypingrr cryptographyrcryptography.exceptionsr r cryptography.hazmat.backendsr cryptography.hazmat.primitivesr r cryptography.x509rr@rcertbotrrrcertbot.compat.osrcertbot.interfacesr getLoggerr]r.rrOrCrbrarErrrrTr#r(r&rsF0 48818" $,   8 $b=b=JceHSM8C=4P.Q<...3.QT.Y].b!A(;!AK]!A&*&6&6!ACF!AKO!AH7^2E7^040@0@7^MP7^UY7^tSsQUr(