M/e `dZddlZddlZddlZddlZddlmZddlmZddlmZddlm Z ddlm Z ddlm Z dd lm Z dd l mZdd lmZdd lmZdd lmZddlmZddlmZddlmZddlmZddlmZddlmZddlm Z ddl!m"Z"ddl!m#Z#ddl!m$Z$ddl%Z%ddl&m'Z'ddl&m(Z(ddl)Z)ddl*m+Z,ddl-m.Z.ddl-m/Z/ddl-m0Z0ddl1m2Z2e rddl3m4Z4dd l5m6Z6dd!l7m8Z8dd"l9m:Z:ejve<Z= dhd#e>d$ee?d%e?d&e?d'e?d(e@d)e0jfd*ZB did+e0jd,e ee?e e?fd-ee?d.e@d(e@d)e0jf d/ZDd0eEd)e@fd1ZFd0eEd+eEd)e@fd2ZGd3e?d4eEd)e e>e0jee?ffd5ZH djd6e>d%e?d&ee?d)eEfd7ZId+e e?eEfd)e@fd8ZJd9e/jd)dfd:ZLd9e/jd)dfd;ZMdee d?d@fdAeEdBeEdCejd)df dDZOdEe?dFe?d)dfdGZPd9e/jd)dfdHZQd4eEd)e e'je>ffdIZSe'jfdJeEdKee>eEge e'je'jffdLe>d)e e'je'jffdMZVe'jfdJeEdKee>eEge e'je'jffdLe>d)ee?fdNZWe'jfdOeEdLe>d)ee?fdPZXdQeEdKee>eEge e'je'jffdLe>d)ee?fdRZYdSe e'je'jfd)ee?fdTZZe'jfdOeEdLe>d)ee?fdUZ[e'jfd0eEdLe>d)ee?fdVZ\e'jfdWe ee'jee%jfdXe>d)eEfdYZ^dEe?d)ejfdZZ_dEe?d)ejfd[Z`dEe?d\ee'jgeeEfd)ejfd]Zad^e?d)e?fd_Zbejd`ejZedae?d)e e?e?ffdbZfdEe?d)e>fdcZg dkddee?dee?dfe@d)e?fdgZhy)lzCertbot 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. N)Callable)List)Optional)Set)Tuple) TYPE_CHECKING)Union)x509)InvalidSignature)UnsupportedAlgorithm)default_backend)hashes)ec) DSAPublicKey)ECDSA)EllipticCurvePublicKey)PKCS1v15) RSAPublicKey)Encoding) NoEncryption) PrivateFormat)crypto)SSL) crypto_util)errors) interfaces)util)os)Ed448PublicKey)Ed25519PublicKey) X448PublicKey)X25519PublicKeykey_sizekey_dirkey_typeelliptic_curvekeynamestrict_permissionsreturncD t||xsd|}d}|rt j|d|t jtjj||d d \} }| 5| j|ddd|d k(rtjd ||ntjd ||t j||S#t$r=}tjddtj dt ||d}~wwxYw#1swYxYw)a$Initializes 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: Optional 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 :param bool strict_permissions: If true and key_dir exists, an exception is raised if the directory doesn't have 0700 permissions or isn't owned by the current user. :returns: Key :rtype: :class:`certbot.util.Key` :raises ValueError: If unable to generate the key given key_size. secp256r1)bitsr&r%Texc_infoz&Encountered error while making key: %sNiiwbrsaz Generating RSA key (%d bits): %sz"Generating ECDSA key (%d bits): %s)make_key ValueErrorloggerdebugerrorstrrmake_or_verify_dir unique_filerpathjoinwriteKey) r#r$r%r&r'r(key_pemerrkey_pathkey_fs 5/usr/lib/python3/dist-packages/certbot/crypto_util.py generate_keyrC8s0.*GKRZ H 0BC** GGLL' *E49x  ! KK  ! u  LL;Xx P LL=x R 88Hg &&%  R$ ' =s3xH  ! !s#C )D D8DDDprivkeynamesr: must_staplectj|j||}d}|rtj|d|tj t jj|ddd\}}|5|j|dddtjd|tj||dS#1swY6xYw) aCInitialize 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: Optional certificate save directory. :param bool must_staple: If true, include the TLS Feature extension "OCSP Must-Staple" :param bool strict_permissions: If true and path exists, an exception is raised if the directory doesn't have 0755 permissions or isn't owned by the current user. :returns: CSR :rtype: :class:`certbot.util.CSR` )rFNizcsr-certbot.pemir0zCreating CSR: %spem) acme_crypto_utilmake_csrrHrr8r9rr:r;r<r4r5CSR)rDrEr:rFr(csr_pem csr_filenamecsr_fs rB generate_csrrOis '' U 5GL  e-?@".. GGLL0 15$@|  ! KK  ! '6 88L'5 11  ! !s 8B??Ccsrc tjtj|}|j|j S#tj $rt jddYywxYw)zValidate CSR. Check if `csr` is a valid CSR for the given domains. :param bytes csr: CSR in PEM. :returns: Validity of CSR. :rtype: bool r-Tr.F)rload_certificate_request FILETYPE_PEMverify get_pubkeyErrorr4r5)rPreqs rB valid_csrrXs^--   &zz#..*++ << R$ 'sAA*A21A2ctjtj|}tjtj|} |j |S#tj $rt jddYywxYw)zDoes private key correspond to the subject public key in the CSR? :param bytes csr: CSR in PEM. :param bytes privkey: Private key file contents (PEM) :returns: Correspondence of private key to CSR subject public key. :rtype: bool r-Tr.F)rrRrSload_privatekeyrTrVr4r5)rPrDrWpkeys rBcsr_matches_pubkeyr\sq  ) )S "C  ! !&"5"5w ?Dzz$ << R$ 's A*BBcsrfiledatactj}tj} |tj|}t|}tj||}|tj||d|fS#tj$rI |||}n;#tj$r%t jdj |wxYwYwxYw)a1Import a CSR file, which can be either PEM or DER. :param str csrfile: CSR filename :param bytes 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 zFailed to parse CSR file: {0}rH)filer^form) rrSrR FILETYPE_ASN1rVrformat"_get_names_from_loaded_cert_or_reqdump_certificate_requestrrK)r]r^PEMloadrPdomainsdata_pems rBimport_csr_filerjs   C  * *DP6''.15G..sC8H gH5A7 JJ <<P PsD/C|| P,,>EEgNO O P Ps)A55C BC8C  CCr,c4|dk(r_|dkr$tjdj|tj}|j tj |n5|dk(r |stjd |j}|dvr]tt|j}|stjd|tj|t}n$tjd j| |jt j"t$j&t) }tj*tj,|}n$tjd j|tj.tj,|S#t$r%tjd j|t$r$}|tjt|d }~wwxYw) aGenerate PEM encoded RSA|EC key. :param int bits: Number of bits if key_type=rsa. At least 2048 for RSA. :param str key_type: The type of key to generate, but be rsa or ecdsa :param str elliptic_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 r1zUnsupported RSA key length: {}ecdsaz3When key_type == ecdsa, elliptic_curve must be set.) SECP256R1 SECP384R1 SECP521R1zInvalid curve type: )curvebackendzUnsupported elliptic curve: {}N)encodingrcencryption_algorithmz0Invalid key_type specified: {}. Use [rsa|ecdsa])rrVrcrPKeyrCTYPE_RSAuppergetattrrgenerate_private_keyr TypeErrorr r7 private_bytesrrfrTraditionalOpenSSLrrZrSdump_privatekey) r,r%r&keynamerq_keye_key_pems rBr2r2s5 $;,,?FFtLM Mkkm $/ W ,,TU U .!'')D>>N$8$8$:; ,,)=n=M'NOO..'+- ll#C#J#J>#Z[[ %%\\ 33!-&  $$V%8%8(CllMTTU]^__  ! !&"5"5s ;; X,,?FF~VW W# .c!f- - .sBF>>5H3HHc tjtj|jS#ttj f$rYywxYw)zIs valid RSA private key? :param privkey: Private key file contents in PEM :returns: Validity of private key. :rtype: bool F)rrZrScheckrzrV)rDs rB valid_privkeyrsG%%   **/%' 2 v|| $s14AArenewable_certcpt|t|t|j|jy)aFor 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)verify_renewable_cert_sigverify_fullchainverify_cert_matches_priv_key cert_pathr@)rs rBverify_renewable_certrs*n-^$ !9!9>;R;RSc t|jd5}tj|j t }dddt|j d5}tj|j t }dddj}jsJt||j|j|jy#1swYxYw#1swY`xYw#tttf$rK}dj|j |}t j#|t%j&|d}~wwxYw)zVerifies 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. rbNzbverifying the signature of the certificate located at {0} has failed. Details: {1})open chain_pathr load_pem_x509_certificatereadr r public_keysignature_hash_algorithmverify_signed_payload signaturetbs_certificate_bytesIOErrorr3r rcr4 exceptionrrV)r chain_filechain cert_filecertpkr error_strs rBrr%s% & .++T 2 Yj22:??3DoFWXE Y .**D 1 WY11)..2BODUVD W    ,,,,b$..$2L2L $ = = ?  Y Y W W Z!1 2&$f^%=%=qA #ll9%% &sHC;-C#C;#-C/AC;#C,(C;/C84C;;EAEErr rr"r!rpayloadrct|tr|j||t|yt|tr|j||t |yt jd)aCheck 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 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 zUnsupported public key type.N) isinstancerrTrrrrrV)rrrrs rBrr=sb*l+ w ,D  J 6 7 w&> ? ll9::rrr@cl tjtj}|j||j ||j y#t tjf$rB}dj|||}tj|tj|d}~wwxYw)z 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. zverifying the certificate located at {0} matches the private key located at {1} has failed. Details: {2}N) rContext SSLv23_METHODuse_certificate_fileuse_privatekey_filecheck_privatekeyrrVrcr4rr)rr@contextrrs rBrrXs &++c//0$$Y/##H-  " SYY &$fY !%  #ll9%% &sAAB31=B..B3c t|j5}|j}dddt|j5}|j}dddt|j5}|j}dddzk7r2d}|j |j }tj|y#1swYxYw#1swY~xYw#1swY\xYw#t$r@}dj |}tj|tj|d}~wtj$r}|d}~wwxYw)z 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. Nz.fullchain does not match cert + chain for {0}!z8reading one of cert, chain, or fullchain has failed: {0}) rrrrfullchain_pathrc lineagenamerrVrr4r) rrrrrfullchain_file fullchainrrs rBrrns( .++ , & OO%E & .** + $y>>#D $ .// 0 .N&++-I . 5LY &HI!(()C)CDI,,y) ) '  & & $ $ . . &NUUVWX #ll9%% <<sjC+CC+CC+3CAC+C C+CC+C($C++ E 4;D//E EE cZg}tjtjfD]} tj|||fcSt jdjdjd|D#tj$r}|j |Yd}~d}~wwxYw)z:Load PEM/DER certificate. :raises errors.Error: NzUnable to load: {0},c32K|]}t|ywN)r7).0r6s rB z-pyopenssl_load_certificate..s=0E =0s) rrSrbload_certificaterVappendrrcr;)r^openssl_errors file_typer6s rBpyopenssl_load_certificatersN))6+?+?@)  )**9d;YF F) ,,,33CHH=0 .=0501 22|| )  ! !% ( ( )sA<<B*B%%B*cert_or_req_str load_functypc |||S#tj$r<}tjddtj dt |d}~wwxYw)Nr-Tr.z6Encountered error while loading certificate or csr: %s)rrVr4r5r6r7)rrrr?s rB_load_cert_or_reqrsOo.. << R$ ' MsSVxX s A7AAcBtjt|||Sr)rI_pyopenssl_cert_or_req_sanr)rrrs rB_get_sans_from_cert_or_reqrs&  6 67HC8) **rrc8t|tj|S)zGet 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 )rrrrrs rBget_sans_from_certrs & f%%s ,,r cert_or_reqc2t|||}t|Sr)rrd)rrrloaded_cert_or_reqs rB_get_names_from_cert_or_reqrs+; 3G -.@ AArrc,tj|Sr)rI _pyopenssl_cert_or_req_all_names)rs rBrdrds  < <=O PPrc8t|tj|S)zGet 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 )rrrrs rBget_names_from_certrs ' f%%s ,,rc8t|tj|S)zGet a list of domains from a CSR, including the CN if it is set. :param str csr: CSR (encoded). :param typ: `crypto.FILETYPE_PEM` or `crypto.FILETYPE_ASN1` :returns: A list of domain names. :rtype: list )rrrR)rPrs rBget_names_from_reqrs 'sF,K,KS QQrrfiletypec.tj||S)zDump certificate chain into a bundle. :param list chain: List of `crypto.X509` (or wrapped in :class:`josepy.util.ComparableX509`). )rIdump_pyopenssl_chain)rrs rBrrs  0 0 AArcJt|tjjS)zWhen 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` )_notAfterBeforerX509 get_notBeforers rB notBeforers 9fkk&?&? @@rcJt|tjjS)zWhen 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` )rrr get_notAfterrs rBnotAfterrs 9fkk&>&> ??rmethodc t|d5}tjtj|j }ddd|}|st j d|ddd|ddd|ddd |dd d |d d d |d dg }d j|}|jd}tj|S#1swY~xYw)aPInternal 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` rNz>Error while invoking timestamp method, None has been returned.r-T : rascii) rrrrSrrrVr;decode pyrfc3339parse)rrfr timestampreformatted_timestamptimestamp_bytes timestamp_strs rBrr s i F!&&v':':AFFHEFt I ll[\\&q^T9Qq>4&q^T9Qr?D&r"-tYrs^Ehh45O#**73M ??= ))FFs 3B==Cfilenamectj}t|d5}|j|j j dddd|j S#1swY|j SxYw)aNCompute 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 rzUTF-8N)hashlibsha256rupdaterencode hexdigest)rrfile_ds rB sha256sumr&sg^^ F h 5 fkkm**7345    5    s /A((Bs@-----BEGIN CERTIFICATE----- ? .+? ? -----END CERTIFICATE----- ? fullchain_pemc tj|j}t|dkrt j d|Dcgc]V}t jt jt jt j|jX}}|ddj|ddfScc}w)aSplit 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. zPfailed to parse fullchain into cert and chain: less than 2 certificates in chainrr-N) CERT_PEM_REGEXfindallrlenrrVrdump_certificaterSrrr;)rcertsrcerts_normalizeds rBcert_and_chain_from_fullchainrAs  " "=#7#7#9 :E 5zA~ll?@ @ RWXIM//0C0C 3 3T:< ?? Xs ACct|d5}tjtj|j }dddj S#1swYxYw)zRetrieve 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 rN)rrrrSrget_serial_number)rrr s rBget_serial_from_certr]sX i F!&&v':':AFFHEF !4 ! ! ##FFs 3AA" fullchains issuer_cnwarn_on_no_matchcj|D]}tj|j}tj|dt }|j jtjj}|s}|dj|k(s|cS|rtjd||dS)a'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` rzCertbot 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.) rrrr rr issuerget_attributes_for_oidNameOID COMMON_NAMEvaluer4warning)rrr rrtop_cert top_issuer_cns rBfind_chain_with_issuerrks&&u||~611%)_=NO >>t||?W?WX ]1-33y@L =>G I a=r)r1r+zkey-certbot.pemT)FT)rlr1N)F)i__doc__datetimerloggingretypingrrrrrrr cryptographyr cryptography.exceptionsr r cryptography.hazmat.backendsr cryptography.hazmat.primitivesr)cryptography.hazmat.primitives.asymmetricr-cryptography.hazmat.primitives.asymmetric.dsar,cryptography.hazmat.primitives.asymmetric.ecrr1cryptography.hazmat.primitives.asymmetric.paddingr-cryptography.hazmat.primitives.asymmetric.rsar,cryptography.hazmat.primitives.serializationrrrjosepyOpenSSLrrracmerrIcertbotrrrcertbot.compatr/cryptography.hazmat.primitives.asymmetric.ed448r1cryptography.hazmat.primitives.asymmetric.ed25519r .cryptography.hazmat.primitives.asymmetric.x448r!0cryptography.hazmat.primitives.asymmetric.x25519r" getLogger__name__r4intr7boolr=rCrKrObytesrXr\rjr2r RenewableCertrr HashAlgorithmrrrrrrSX509ReqrrrrrdrrComparableX509rrrrrcompileDOTALLrrrrrrBr9s   48818F>OFFAEF 0NRLP   8 $ INCT,0.'3.'#.'#.'!$.'=@.'%).'59XX.'dHL2$((25cCH1D+E2XVY]2"2@D2PTPXPX2J5T(EEd(KSKK%TXXtCy8P2QK:05-1-<3-<-<%c]-<6;-<` 5e,   T**B*BTtT$&j.F.F&4&0;eL:LN^,BL,=-O'P;&+;6;;5;4H4H ;NR ;6&C&3&4&,Z%=%=$62U2uV[[#5E/F2("(!4!4u!)3,fkk6>>>Y8Z*Z![9>v{{FNN?Z9[+1*=*=***2C<v{{GM~~HVBW4W+X*%(*CGs)*06/B/B ,U , ,tCy ,BUB+3S%L% HNIWCX5X,YB&)B.2#YBQ5fnnA\;]Q,0IQ 170C0C ,e ,# ,S ,/5.A.A RE R Rd3i R*0)<)< Bd6;;&7f>S>S9T&T U B#& BAF B A A!2!2 A @ @ 1 1 @*s*$fkk]HUO%CD*IQIZIZ*8$II @@sCx@8 $C $C $5:tCyS-1>Ar