Spade
Mini Shell
�
���_c@s�dZddlmZddlmZddlZddlZddlmZddlmZddlm Z ddl
mZdd l
mZdd
l
mZddlmZddlmZddlZddlZdd
lmZddlmZddlmZddlmZddlmZddlmZddlmZy$ddlm
Z e!e j"d�Wne#e$fk
r�dZ
nXej&e'�Z(de)fd��YZ*d�Z+d�Z,d�Z-d�Z.d�Z/dS(s*Tools
for checking certificate
revocation.i����(tdatetime(t timedeltaN(tPIPE(tPopen(tx509(tInvalidSignature(tUnsupportedAlgorithm(tdefault_backend(thashes(t
serialization(tOptional(tTuple(tcrypto_util(terrors(tutil(tgetenv(t
RenewableCert(tocsptsignature_hash_algorithmtRevocationCheckercBs8eZdZed�Zd�Zdd�Zd�ZRS(sEThis
class figures out OCSP checking on this system, and performs
it.cCs�t|_|pt|_|jr�tjd�sKtjd�t|_dSt dddddgdt
dt
d td
tj��}|j�\}}d|kr�d�|_
q�d
�|_
ndS(Ntopenssls-openssl
not installed, can't check
revocationRs-headertvartvaltstdouttstderrtuniversal_newlinestenvs Missing
=cSsd|gS(NsHost=((thost((s0/usr/lib/python2.7/site-packages/certbot/ocsp.pyt<lambda>:scSs
d|gS(NtHost((R((s0/usr/lib/python2.7/site-packages/certbot/ocsp.pyR<s(tFalsetbrokenRtuse_openssl_binaryRt
exe_existstloggertinfotTrueRRtenv_no_snap_for_external_callstcommunicatet host_args(tselftenforce_openssl_binary_usagettest_host_formatt_outterr((s0/usr/lib/python2.7/site-packages/certbot/ocsp.pyt__init__*s
cCs|j|j|j�S(s
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
(tocsp_revoked_by_pathst cert_patht
chain_path(R(tcert((s0/usr/lib/python2.7/site-packages/certbot/ocsp.pytocsp_revoked>si
cCs�|jr
tStjjtj��}tj|�|kr>tSt |�\}}|s^|rbtS|j
r�|j|||||�St||||�S(sEPerforms 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
(
RRtpytztUTCtfromutcRtutcnowRtnotAftert_determine_ocsp_serverR
t_check_ocsp_openssl_bint_check_ocsp_cryptography(R(R/R0ttimeouttnowturlR((s0/usr/lib/python2.7/site-packages/certbot/ocsp.pyR.Ks c
Csjtd�}td�}d}|dk s6|dk rQ|dk rH|n|}n|dkrld|g} n4|jd�r�|td�}nd|d|g} ddd d
|d|d|d
|ddt|�dg|j|�| }
tjd|�tjdj|
��y"t j
|
dtj�\}}Wn%tjk
rYtj
d|�tSXt|||�S(Nt
http_proxyt
HTTP_PROXYs-urlshttp://s-hosts-pathRRs -no_nonces-issuers-certs-CAfiles
-verify_others-trust_others-timeouts-headersQuerying
OCSP for %st tlogs*OCSP check failed for %s (are we offline?)(RtNonet
startswithtlentstrR'R"tdebugtjoinRt
run_scriptR
tSubprocessErrorR#Rt_translate_ocsp_query(
R(R/R0RR=R;tenv_http_proxytenv_HTTP_PROXYt
proxy_hostturl_optstcmdtoutputR,((s0/usr/lib/python2.7/site-packages/certbot/ocsp.pyR9is&
J"(t__name__t
__module__t__doc__RR-R2R.R9(((s0/usr/lib/python2.7/site-packages/certbot/ocsp.pyR's
c Cst|d��"}tj|j�t��}WdQXy`|jjtj�}tjj }g|j
D]}|j|kra|^qa}|djj
}Wn+tj
tfk
r�tjd|�d SX|j�}|jd�djd�}|r�||fStjd||�d
S(s�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)
trbNisCannot extract OCSP URI from %ss://it/s;Cannot process OCSP
host from URL (%s) in certificate at
%s(NN(NN(topenRtload_pem_x509_certificatetreadRt
extensionstget_extension_for_classtAuthorityInformationAccesstAuthorityInformationAccessOIDtOCSPtvaluet
access_methodtaccess_locationtExtensionNotFoundt
IndexErrorR"R#RBtrstript partition( R/tfile_handlerR1t extensiontocsp_oidtdescriptiontdescriptionsR=R((s0/usr/lib/python2.7/site-packages/certbot/ocsp.pyR8�s" !
c
CsUt|d��"}tj|j�t��}WdQXt|d��"}tj|j�t��}WdQXtj�}|j||tj ��}|j
�}|jtj
j�} y,tj|d| didd6d|�}
Wn.tjjk
r
tjd|dt�tSX|
jd kr4tjd
||
j�tStj|
j�}|jtjjkrutjd||j�tSyt||||�Wn�tk
r�}tjt |��n�t!j"k
r�}tjt |��nut#k
r�tjd|�nUt$k
r'}
tjd
|t
|
��n*Xtj%d||j&�|j&tj'j(kStS(NRTtdatatheaderssapplication/ocsp-requestsContent-TypeR;s*OCSP
check failed for %s (are we offline?)texc_infoi�s*OCSP check failed for
%s (HTTP status: %d)s'Invalid OCSP response status for %s: %ss)Invalid
signature on OCSP response for %ss!Invalid OCSP response for %s: %s.s%OCSP
certificate status for %s is:
%s()RVRRWRXRRtOCSPRequestBuildertadd_certificateRtSHA1tbuildtpublic_bytesR tEncodingtDERtrequeststpostt
exceptionstRequestExceptionR"R#R$Rtstatus_codetload_der_ocsp_responsetcontenttresponse_statustOCSPResponseStatust
SUCCESSFULterrort_check_ocsp_responseRRER
tErrorRtAssertionErrorRFtcertificate_statustOCSPCertStatustREVOKED(R/R0R=R;RetissuerR1tbuildertrequesttrequest_binarytresponset
response_ocspteR~((s0/usr/lib/python2.7/site-packages/certbot/ocsp.pyR:�sJ!!
cCs|j|jkr!td��nt|||�t|jt|j��sq|j|jksq|j|jkr�td��ntj �}|j
s�td��n|j
|tdd�kr�td��n|jr|j|tdd�krtd��ndS( s2Verify
that the OCSP is valid for several criteriasMthe certificate in response
does not correspond to the certificate in requests<the issuer does not
correspond to issuer of the certificate.sparam thisUpdate is not
set.tminutesis"param thisUpdate is in the future.s param nextUpdate
is in the past.N(
t
serial_numberR�t_check_ocsp_response_signaturet
isinstancethash_algorithmttypetissuer_key_hashtissuer_name_hashRR6tthis_updateRtnext_update(R�trequest_ocsptissuer_certR/R<((s0/usr/lib/python2.7/site-packages/certbot/ocsp.pyR�s %c
Cs�d�}|j|jks0|j||�krItjd|�|}n'tjd|�g|jD]3}|j|jks�|j||�krc|^qc}|s�td��n|d}|j|jkr�td��ny1|jj t
j�}t
jj
j|jk}Wn t
jtfk
r/t}nX|sEtd��n|j} tj|j�|j|j| �|j} tj|j�|j|j| �dS( sIVerify
an OCSP response signature against certificate issuer or
respondercSstjj|j��jS(N(RtSubjectKeyIdentifiertfrom_public_keyt
public_keytdigest(R1((s0/usr/lib/python2.7/site-packages/certbot/ocsp.pyt _key_hashssGOCSP
response for certificate %s is signed by the certificate's
issuer.sGOCSP response for certificate %s is delegated to an external
responder.s0no matching responder certificate could be foundis?responder
certificate is not signed by the certificate's issuers<responder is
not authorized by issuer to sign OCSP
responsesN(tresponder_nametsubjecttresponder_key_hashR"RFtcertificatesR�R�RYRZRtExtendedKeyUsagetoidtExtendedKeyUsageOIDtOCSP_SIGNINGR^RaRbRRRtverify_signed_payloadR�t signaturettbs_certificate_bytesttbs_response_bytes(
R�R�R/R�tresponder_certR1tresponder_certsRftdelegate_authorizedtchosen_hash((s0/usr/lib/python2.7/site-packages/certbot/ocsp.pyR�s: !
c
sd
}g|D]}dj||�^q
}�fd�|D�\}}}|r_|jd�nd} d|ks�|r}| s�|r�tjd|�tjd �|�tS|r�| r�tS|r�|jd�} | r�tjd
| �ntStjd�|�tSdS(s7Parse openssl's weird output to
work out what it means.tgoodtrevokedtunknowns{0}:
(WARNING.*)?{1}c3s*|]
}tj|�dtj�VqdS(tflagsN(tretsearchtDOTALL(t.0tp(tocsp_output(s0/usr/lib/python2.7/site-packages/certbot/ocsp.pys <genexpr>=sisResponse
verify OKs#Revocation status for %s is unknownsUncertain output:
%s
stderr:
%ssOCSP revocation warning: %ss2Unable to properly parse OCSP output: %s
stderr:%sN(sgoodsrevokedsunknown( tformattgroupRBR"R#RFRR$twarning(
R/R�tocsp_errorststateststpatternsR�R�R�R�((R�s0/usr/lib/python2.7/site-packages/certbot/ocsp.pyRJ8s$%
(0RSRRtloggingR�t
subprocessRRtcryptographyRtcryptography.exceptionsRRtcryptography.hazmat.backendsRtcryptography.hazmat.primitivesRR R3Rttacme.magic_typingR
RtcertbotRR
Rtcertbot.compat.osRtcertbot.interfacesRtcryptography.x509RtgetattrtOCSPResponsetImportErrortAttributeErrorRBt getLoggerRQR"tobjectRR8R:RR�RJ(((s0/usr/lib/python2.7/site-packages/certbot/ocsp.pyt<module>sB
h 2 " 6