Spade
Mini Shell
�
d�_ac@s�dZddlZddlZddlZddlZddlmZddlmZm Z ddl
mZddlm
Z
ddlmZmZddlmZdd lmZdd
lmZmZmZddlmZddlmZddlZddlZddlZdd
l
m!Z"ddl#m$Z$ddl%m&Z&ddl%m'Z'ddl%m(Z(ddl)m*Z*ej+e,�Z-dddd�Z.d�Z/d�Z0d�Z1d�Z2dddd�Z4d�Z5d�Z6d�Z7d
�Z8d!�Z9d"�Z:d#�Z;ej<d$�Z=ej<d%�Z>ej<d&�Z?d'�Z@d(�ZAej<d)�ZBej<d*�ZCd+�ZDd,�ZEd-�ZFd.�ZGejHd/ejI�ZJd0�ZKd1�ZLeMd2�ZNdS(3s�Certbot
client crypto utility functions.
.. todo:: Make the transition to use PSS rather than PKCS1_v1_5 when the
server
is capable of handling the signatures.
i����N(tx509(tInvalidSignaturetUnsupportedAlgorithm(tdefault_backend(tec(tECDSAtEllipticCurvePublicKey(tPKCS1v15(tRSAPublicKey(tEncodingtNoEncryptiont
PrivateFormat(tcrypto(tSSL(tcrypto_util(tIO(terrors(t
interfaces(tutil(tostrsat secp256r1skey-certbot.pemc
Csy%td|d|pdd|�}Wn,tk
rS}tjddt�|�nXtjjtj �}t
j|d|j�t
j
tjj||�dd �\}} |�|j|�Wd
QX|dkr�tjd|| �ntjd
|| �t
j| |�S(siInitializes and saves a privkey.
Inits key and saves it in PEM format on the filesystem.
.. note:: keyname is the attempted filename, it may be different if a
file
already exists at the path.
:param int key_size: key size in bits if key size is rsa.
:param str key_dir: Key save directory.
:param str key_type: Key Type [rsa, ecdsa]
:param str elliptic_curve: Name of the elliptic curve if key type is
ecdsa.
:param str keyname: Filename of key
:returns: Key
:rtype: :class:`certbot.util.Key`
:raises ValueError: If unable to generate the key given key_size.
tbitstelliptic_curveRtkey_typettexc_infoi�i�twbNRs
Generating RSA key (%d bits): %ss"Generating ECDSA key (%d bits):
%s(tmake_keyt
ValueErrortloggerterrortTruetzopet componentt
getUtilityRtIConfigRtmake_or_verify_dirtstrict_permissionstunique_fileRtpathtjointwritetdebugtKey(
tkey_sizetkey_dirRRtkeynametkey_pemterrtconfigtkey_ftkey_path((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyt
init_save_key's
$cCs�tjjtj�}tj|j|d|j�}t j
|d|j�t jt
jj|d�dd�\}}|�|j|�WdQXtjd|�t j||d�S( s2Initialize
a CSR with the given private key.
:param privkey: Key to include in the CSR
:type privkey: :class:`certbot.util.Key`
:param set names: `str` names to include in the CSR
:param str path: Certificate save directory.
:returns: CSR
:rtype: :class:`certbot.util.CSR`
tmust_staplei�scsr-certbot.pemi�RNsCreating CSR:
%stpem(R!R"R#RR$tacme_crypto_utiltmake_csrR7R6RR%R&R'RR(R)R*RR+tCSR(tprivkeytnamesR(R2tcsr_pemtcsr_ftcsr_filename((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyt
init_save_csrTs$cCs[y,tjtj|�}|j|j��SWn(tjk
rVtjddt�t SXdS(s�Validate CSR.
Check if `csr` is a valid CSR for the given domains.
:param str csr: CSR in PEM.
:returns: Validity of CSR.
:rtype: bool
RRN(
Rtload_certificate_requesttFILETYPE_PEMtverifyt
get_pubkeytErrorRR+R
tFalse(tcsrtreq((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyt valid_csrwscCsjtjtj|�}tjtj|�}y|j|�SWn(tjk
retjddt�t SXdS(s�Does private key correspond to the
subject public key in the CSR?
:param str csr: CSR in PEM.
:param str privkey: Private key file contents (PEM)
:returns: Correspondence of private key to CSR subject public key.
:rtype: bool
RRN(
RRARBtload_privatekeyRCRERR+R
RF(RGR;RHtpkey((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pytcsr_matches_pubkey�s
cCs�tj}tj}y|tj|�}WnVtjk
r�y|||�}Wq�tjk
r|tjdj|���q�XnXt|�}tj||�}|t j
d|d|dd�|fS(s/Import a CSR file, which can be either PEM or DER.
:param str csrfile: CSR filename
:param str data: contents of the CSR file
:returns: (`crypto.FILETYPE_PEM`,
util.CSR object representing the CSR,
list of domains requested in the CSR)
:rtype: tuple
sFailed to parse CSR file:
{0}tfiletdatatformR7(RRBRAt
FILETYPE_ASN1RERtformatt"_get_names_from_loaded_cert_or_reqtdump_certificate_requestRR:(tcsrfileRNtPEMtloadRGtdomainstdata_pem((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pytimport_csr_file�s
icCs�|dkrU|dkr3tjdj|���ntj�}|jtj|�n)|dkrfyg|j�}|dkr�tj dt
t|j�d��d t��}ntjd
j|���Wn\t
k
r�tjd
j|���n4tk
r&}tj|tjt|����nX|jdtjdtjd
t��}tjtj|�}ntjdj|���tjtj|�S(sDGenerate
PEM encoded RSA|EC key.
:param int bits: Number of bits if key_type=rsa. At least 1024 for RSA.
:param str ec_curve: The elliptic curve to use.
:returns: new RSA or ECDSA key in PEM form with specified number of
bits
or of type ec_curve when key_type ecdsa is used.
:rtype: str
RisUnsupported RSA key length:
{}tecdsat SECP256R1t SECP384R1t SECP512R1tcurvetbackendsUnsupported
elliptic curve: {}tencodingRQtencryption_algorithms0Invalid key_type
specified: {}. Use
[rsa|ecdsa](R[R\R]N(RRERQRtPKeytgenerate_keytTYPE_RSAtupperRtgenerate_private_keytgetattrtNoneRt TypeErrorRtsixt
raise_fromtstrt
private_bytesR RURtTraditionalOpenSSLR
RJRBtdump_privatekey(RRRtkeytnamet_keytet_key_pem((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyR�s0
% cCs?ytjtj|�j�SWnttjfk
r:tSXdS(s�Is valid RSA private key?
:param str privkey: Private key file contents in PEM
:returns: Validity of private key.
:rtype: bool
N(RRJRBtcheckRiRERF(R;((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyt
valid_privkey�s
cCs+t|�t|�t|j|j�dS(s�For checking that
your certs were not corrupted on disk.
Several things are checked:
1. Signature verification for the cert.
2. That fullchain matches cert and chain when concatenated.
3. Check that the private key matches the certificate.
:param renewable_cert: cert to verify
:type renewable_cert: certbot.interfaces.RenewableCert
:raises errors.Error: If verification fails.
N(tverify_renewable_cert_sigtverify_fullchaintverify_cert_matches_priv_keyt cert_pathR4(trenewable_cert((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pytverify_renewable_cert�s
cCs�y�t|jd��"}tj|j�t��}WdQXt|jd��"}tj|j�t��}WdQX|j�}tj ��!t
||j|j|j
�WdQXWnMtttfk
r�}dj|j|�}tj|�tj|��nXdS(s�Verifies the
signature of a RenewableCert object.
:param renewable_cert: cert to verify
:type renewable_cert: certbot.interfaces.RenewableCert
:raises errors.Error: If signature verification fails.
trbNsbverifying the signature of the certificate located at {0} has
failed. Details: {1}(topent
chain_pathRtload_pem_x509_certificatetreadRRzt
public_keytwarningstcatch_warningstverify_signed_payloadt signaturettbs_certificate_bytestsignature_hash_algorithmtIOErrorRRRQRt exceptionRRE(R{t
chain_filetchaint cert_filetcerttpkRst error_str((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyRws!!
cCs�tj���tjd�t|t�r[|j|t�|�}|j|�|j�nPt|t �r�|j|t
|��}|j|�|j�ntjd��WdQXdS(s�Check the
signature of a payload.
:param RSAPublicKey/EllipticCurvePublicKey public_key: the public_key
to check signature
:param bytes signature: the signature bytes
:param bytes payload: the payload bytes
:param cryptography.hazmat.primitives.hashes.HashAlgorithm
signature_hash_algorithm: algorithm used to hash the payload
:raises InvalidSignature: If signature verification fails.
:raises errors.Error: If public key type is not supported
tignoresUnsupported public key typeN(
R�R�tsimplefiltert
isinstanceRtverifierRtupdateRCRRRRE(R�R�tpayloadR�R�((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyR�
s
cCs�y:tjtj�}|j|�|j|�|j�WnMttjfk
r�}dj|||�}t j
|�tj|��nXdS(s� Verifies that the private key and cert
match.
:param str cert_path: path to a cert in PEM format
:param str key_path: path to a private key file
:raises errors.Error: If they don't match.
s�verifying the certificate located at {0} matches the
private key located at {1} has failed. Details:
{2}N(R
tContextt
SSLv23_METHODtuse_certificate_filetuse_privatekey_filetcheck_privatekeyR�RERQRR�R(RzR4tcontextRsR�((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyRy?s
c Cs
y�t|j��}|j�}WdQXt|j��}|j�}WdQXt|j��}|j�}WdQX|||kr�d}|j|j�}tj|��nWnYt k
r�}dj|�}t
j|�tj|��ntjk
r}|�nXdS(s� Verifies that fullchain is indeed cert
concatenated with chain.
:param renewable_cert: cert to verify
:type renewable_cert: certbot.interfaces.RenewableCert
:raises errors.Error: If cert and chain do not combine to fullchain.
Ns.fullchain does not match cert + chain for {0}!s8reading one of cert,
chain, or fullchain has failed:
{0}(R~RR�Rztfullchain_pathRQtlineagenameRRER�RR�( R{R�R�R�R�tfullchain_filet fullchainR�Rs((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyRxUs"
cCs�g}xZtjtjfD]F}ytj||�|fSWqtjk
r^}|j|�qXqWtjdjdjd�|D�����dS(s:Load
PEM/DER certificate.
:raises errors.Error:
sUnable to load:
{0}t,css|]}t|�VqdS(N(Rl(t.0R((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pys <genexpr>sN( RRBRPtload_certificateREtappendRRQR)(RNtopenssl_errorst file_typeR((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pytpyopenssl_load_certificatepscCsBy|||�SWn*tjk
r=tjddt��nXdS(NRR(RRERRR
(tcert_or_req_strt load_functtyp((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyt_load_cert_or_req�s
cCstjt|||��S(N(R8t_pyopenssl_cert_or_req_sanR�(R�R�R�((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyt_get_sans_from_cert_or_req�s cCst|tj|�S(s�Get
a list of Subject Alternative Names from a certificate.
:param str cert: Certificate (encoded).
:param typ: `crypto.FILETYPE_PEM` or `crypto.FILETYPE_ASN1`
:returns: A list of Subject Alternative Names.
:rtype: list
(R�RR�(R�R�((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pytget_sans_from_cert�s
cCst|||�}t|�S(N(R�RR(tcert_or_reqR�R�tloaded_cert_or_req((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyt_get_names_from_cert_or_req�scCs
tj|�S(N(R8t
_pyopenssl_cert_or_req_all_names(R�((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyRR�scCst|tj|�S(s�Get
a list of domains from a cert, including the CN if it is set.
:param str cert: Certificate (encoded).
:param typ: `crypto.FILETYPE_PEM` or `crypto.FILETYPE_ASN1`
:returns: A list of domain names.
:rtype: list
(R�RR�(RGR�((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pytget_names_from_cert�s
cCstj||�S(s�Dump certificate chain into a bundle.
:param list chain: List of `crypto.X509` (or wrapped in
:class:`josepy.util.ComparableX509`).
(R8tdump_pyopenssl_chain(R�tfiletype((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyR��s cCst|tjj�S(s�When
does the cert at cert_path start being valid?
:param str cert_path: path to a cert in PEM format
:returns: the notBefore value from the cert at cert_path
:rtype: :class:`datetime.datetime`
(t_notAfterBeforeRtX509t
get_notBefore(Rz((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyt notBefore�s cCst|tjj�S(s�When
does the cert at cert_path stop being valid?
:param str cert_path: path to a cert in PEM format
:returns: the notAfter value from the cert at cert_path
:rtype: :class:`datetime.datetime`
(R�RR�tget_notAfter(Rz((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pytnotAfter�s c
Cs�t|d��"}tjtj|j��}WdQX||�}|dd!d|dd!d|dd!d|dd !d
|d d!d
|dg}dj|�}tjr�|jd
�}n|}t j
|�S(sPInternal helper function for finding notbefore/notafter.
:param str cert_path: path to a cert in PEM format
:param function method: one of ``crypto.X509.get_notBefore``
or ``crypto.X509.get_notAfter``
:returns: the notBefore or notAfter value from the cert at cert_path
:rtype: :class:`datetime.datetime`
R}Niit-iitTi
t:iRtascii(R~RR�RBR�R)RjtPY3tdecodet pyrfc3339tparse(RztmethodtfRt timestamptreformatted_timestampttimestamp_bytest
timestamp_str((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyR��s! cCsJtj�}t|d��#}|j|j�jd��WdQX|j�S(sNCompute
a sha256sum of a file.
NB: In given file, platform specific newlines characters will be
converted
into their equivalent unicode counterparts before calculating the hash.
:param str filename: path to the file whose hash will be computed
:returns: sha256 digest of the file in hexadecimal
:rtype: str
trsUTF-8N(thashlibtsha256R~R�R�tencodet hexdigest(tfilenameR�tfile_d((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyt sha256sum�s"s@-----BEGIN
CERTIFICATE-----
?
.+?
?
-----END CERTIFICATE-----
?
cCs�tj|j��}t|�dkr=tjdd��ng|D]0}tjtjtj tj|��j
�^qD}|ddj|d�fS(sSplit fullchain_pem into cert_pem and
chain_pem
:param str fullchain_pem: concatenated cert + chain
:returns: tuple of string cert_pem and chain_pem
:rtype: tuple
:raises errors.Error: If there are less than 2 certificates in the
chain.
is/failed to parse fullchain into cert and chain: s!less than 2
certificates in
chainiRi(tCERT_PEM_REGEXtfindallR�tlenRRERtdump_certificateRBR�R�R)(t
fullchain_pemtcertsR�tcerts_normalized((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pytcert_and_chain_from_fullchains
:cCs=t|d��"}tjtj|j��}WdQX|j�S(s�Retrieve
the serial number of a certificate from certificate path
:param str cert_path: path to a cert in PEM format
:returns: serial number of the certificate
:rtype: int
R}N(R~RR�RBR�tget_serial_number(RzR�R((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pytget_serial_from_cert1s !cCs�xq|D]i}tj|j��}tj|dt��}|jjtjj �}|r|dj
|kr|SqW|r�tjd|�n|dS(s'Chooses the first
certificate chain from fullchains whose topmost
intermediate has an Issuer Common Name matching issuer_cn (in other
words
the first chain which chains to a root whose name matches issuer_cn).
:param fullchains: The list of fullchains in PEM chain format.
:type fullchains: `list` of `str`
:param `str` issuer_cn: The exact Subject Common Name to match against
any
issuer in the certificate chain.
:returns: The best-matching fullchain, PEM-encoded, or the first if
none match.
:rtype: `str`
i����is�Certbot has been configured to prefer certificate
chains with issuer '%s', but no chain from the CA matched this
issuer. Using the default certificate chain
instead.(
R�R�R�RR�Rtissuertget_attributes_for_oidtNameOIDtCOMMON_NAMEtvalueRtinfo(t
fullchainst issuer_cntwarn_on_no_matchR�R�ttop_certt
top_issuer_cn((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pytfind_chain_with_issuer?s
(Ot__doc__R�tloggingR�tretcryptographyRtcryptography.exceptionsRRtcryptography.hazmat.backendsRt)cryptography.hazmat.primitives.asymmetricRt,cryptography.hazmat.primitives.asymmetric.ecRRt1cryptography.hazmat.primitives.asymmetric.paddingRt-cryptography.hazmat.primitives.asymmetric.rsaRt,cryptography.hazmat.primitives.serializationR R
RtOpenSSLRR
R�Rjtzope.componentR!tacmeRR8tacme.magic_typingRtcertbotRRRtcertbot.compatRt getLoggert__name__RR5R@RIRLRYRhRRvR|RwR�RyRxR�RBR�R�R�R�RRR�R�R�R�R�R�tcompiletDOTALLR�R�R�RFR�(((s7/usr/lib/python2.7/site-packages/certbot/crypto_util.pyt<module>sl, # *