a }|gD @sdZddlZddlZddlZddlZddlZddlZddlZddlZddlm Z ddlm Z ddlm Z ddlm Z ddlm Z ddlmZdd lmZdd lmZdd lmZdd lmZdd lmZmZddlmZmZmZmZmZddlZddlm Z ddlm!Z!ddl"m#Z#e$e%Z&e!j'Z(Gdddej)Z*GdddZ+GdddZ,dde(ddfe-e-e.e.e.ee/e.fe ee-e j0dddZ1d3e-e eee/e e/fe2e e eej3ej4fe-dd d!Z5ej6ej7e e/d"d#d$Z8ee j0e j9fe e/d%d&d'Z:ee j0e j9fe e/d(d)d*Z;d4e je*j?fee ej@e e j0fee*e.fe-d0d1d2ZAdS)5zCrypto utilities.N)Any)Callable)List)Mapping)Optional)Sequence)Set)Tuple)Union)x509)hashes serialization)dsarsaeced25519ed448)crypto)SSL)errorsc@s,eZdZdZejZejZe j dddZ dS)FormatzFile format to be used when parsing or serializing X.509 structures. Backwards compatible with the `FILETYPE_ASN1` and `FILETYPE_PEM` constants from pyOpenSSL. returncCs|tjkrtjjStjjSdS)zJConverts the Format to the corresponding cryptography `Encoding`. N)rDERr EncodingPEM)selfr4/usr/lib/python3.9/site-packages/acme/crypto_util.pyto_cryptography_encoding2s zFormat.to_cryptography_encodingN) __name__ __module__ __qualname____doc__rZ FILETYPE_ASN1rZ FILETYPE_PEMrr rrrrrrr)src@sPeZdZeeeejejffdddZ e j e eejejfdddZ dS)_DefaultCertSelectioncertscCs ||_dSNr%)rr&rrr__init__<sz_DefaultCertSelection.__init__ connectionrcCs|}|r|j|dSdSr')get_servernamer&get)rr*Z server_namerrr__call__?sz_DefaultCertSelection.__call__N)r r!r"rbytesr rPKeyX509r(r Connectionrr-rrrrr$;s"r$c @seZdZdZdeddfejeeee e j e j ffe eeejeegefeeejgee e j e j ffddddZeedddZejdd d d ZGd d d Ze eefdddZdS) SSLSocketaSSL wrapper for sockets. :ivar socket sock: Original wrapped socket. :ivar dict certs: Mapping from domain names (`bytes`) to `OpenSSL.crypto.X509`. :ivar method: See `OpenSSL.SSL.Context` for allowed values. :ivar alpn_selection: Hook to select negotiated ALPN protocol for connection. :ivar cert_selection: Hook to select certificate for connection. If given, `certs` parameter would be ignored, and therefore must be empty. N)sockr&methodalpn_selectioncert_selectionrcCsT||_||_||_|s"|s"td|r2|r2td|durJt|rD|ni}||_dS)Nz*Neither cert_selection or certs specified.z(Both cert_selection and certs specified.)r3r5r4 ValueErrorr$r6)rr3r&r4r5r6rrrr(SszSSLSocket.__init__namercCs t|j|Sr')getattrr3rr9rrr __getattr__fszSSLSocket.__getattr__r)cCs||}|dur&td|dS|\}}t|j}|tj|tj | || ||j dur|| |j ||dS)aSNI certificate callback. This method will set a new OpenSSL context object for this connection when an incoming connection provides an SNI name (in order to serve the appropriate certificate, if any). :param connection: The TLS connection object on which the SNI extension was received. :type connection: :class:`OpenSSL.Connection` Nz=Certificate selection for server name %s failed, dropping SSL)r6loggerdebugr+rContextr4 set_options OP_NO_SSLv2 OP_NO_SSLv3Zuse_privatekeyZuse_certificater5set_alpn_select_callbackZ set_context)rr*ZpairkeycertZ new_contextrrr_pick_certificate_cbis        zSSLSocket._pick_certificate_cbc@sBeZdZdZejddddZeedddZ ee d d d Z dS) zSSLSocket.FakeConnectionzFake OpenSSL.SSL.Connection.Nr)cCs ||_dSr')_wrapped)rr*rrrr(sz!SSLSocket.FakeConnection.__init__r8cCs t|j|Sr')r:rGr;rrrr<sz$SSLSocket.FakeConnection.__getattr__) unused_argsrc Gs@z |jWStjy:}zt|WYd}~n d}~00dSr')rGshutdownrErrorOSError)rrHerrorrrrrIs z!SSLSocket.FakeConnection.shutdown) r r!r"r#rr1r(strrr<boolrIrrrrFakeConnectionsrOrc Cs|j\}}zt|j}|tj|tj||j |j durV| |j | t ||}|td|z |Wn.tjy}zt|WYd}~n d}~00||fWS|Yn0dS)NzPerforming handshake with %s)r3acceptrr?r4r@rArBZset_tlsext_servername_callbackrFr5rCrOr1Zset_accept_stater=r> do_handshakerJrKclose)rr3addrcontextZssl_sockrLrrrrPs&         zSSLSocket.accept)r r!r"r#_DEFAULT_SSL_METHODsocketrrr.r rr/r0intrrr1rr(rMrr<rFrOrPrrrrr2Fs(   r2ii,)r)r9hostporttimeoutr4source_addressalpn_protocolsrc CsFt|}||d|i}zJtd||t|rDd|d|dnd||f} tj| fi|} Wn.t y} zt | WYd} ~ n d} ~ 00t | } t|| } | | ||dur| |z| | Wn2tj y} zt | WYd} ~ n d} ~ 00Wdn1s00Y| }|S)a Probe SNI server for SSL certificate. :param bytes name: Byte string to send as the server name in the client hello message. :param bytes host: Host to connect to. :param int port: Port to connect to. :param int timeout: Timeout in seconds. :param method: See `OpenSSL.SSL.Context` for allowed values. :param tuple source_address: Enables multi-path probing (selection of source interface). See `socket.creation_connection` for more info. Available only in Python 2.7+. :param alpn_protocols: Protocols to request using ALPN. :type alpn_protocols: `Sequence` of `bytes` :raises acme.errors.Error: In case of any problems. :returns: SSL certificate presented by the server. :rtype: OpenSSL.crypto.X509 r\z!Attempting to connect to %s:%d%s.z from {0}:{1}rrXN)rr?Z set_timeoutr=r>anyformatrVZcreate_connectionrKrrJ contextlibclosingr1Zset_connect_stateZset_tlsext_host_nameZset_alpn_protosrQrIZget_peer_certificate)r9rYrZr[r4r\r]rTZ socket_kwargsZ socket_tupler3rLZclientZ client_sslrErrr probe_snis<        @rcF)private_key_pemdomains must_stapleipaddrsrcCstj|dd}t|tjtjtjt j t j fs>t dt||durJg}|durVg}t|t|dkrrt dttgjtdd|Ddd|Dd d }|r|jttjjgd d }||t}|tjjS) aGenerate a CSR containing domains or IPs as subjectAltNames. Parameters are ordered this way for backwards compatibility when called using positional arguments. :param buffer private_key_pem: Private key, in PEM PKCS#8 format. :param list domains: List of DNS names to include in subjectAltNames of CSR. :param bool must_staple: Whether to include the TLS Feature extension (aka OCSP Must Staple: https://tools.ietf.org/html/rfc7633). :param list ipaddrs: List of IPaddress(type ipaddress.IPv4Address or ipaddress.IPv6Address) names to include in subbjectAltNames of CSR. :returns: buffer PEM-encoded Certificate Signing Request. N)passwordzInvalid private key type: rzAAt least one of domains or ipaddrs parameter need to be not emptycSsg|]}t|qSr)r DNSName.0drrr $zmake_csr..cSsg|]}t|qSr)r Z IPAddress)rkirrrrm%rnF)critical)r Zload_pem_private_key isinstancerZ DSAPrivateKeyrZ RSAPrivateKeyrZEllipticCurvePrivateKeyrZEd25519PrivateKeyrZEd448PrivateKeyr7typelenr Z CertificateSigningRequestBuilderZ subject_nameName add_extensionSubjectAlternativeNameZ TLSFeatureZTLSFeatureTypeZstatus_requestsignr ZSHA256 public_bytesrr)rdrerfrgZ private_keyZbuilderZcsrrrrmake_csrsJ    ry)subjectextsrcsxdd|tjjDz|tj}Wntjy@g}Yn0|jtj }sX|Sdgfdd|DSdS)aGets all DNS SAN names as well as the first Common Name from subject. :param subject: Name of the x509 object, which may include Common Name :type subject: `cryptography.x509.Name` :param exts: Extensions of the x509 object, which may include SANs :type exts: `cryptography.x509.Extensions` :returns: List of DNS Subject Alternative Names and first Common Name :rtype: `list` of `str` cSsg|]}tt|jqSr)typingcastrMvalue)rkcrrrrmEsz9get_names_from_subject_and_extensions..rcsg|]}|dkr|qS)rrrjZcnsrrrmUrnN) Zget_attributes_for_oidr ZNameOIDZ COMMON_NAMEget_extension_for_classrvExtensionNotFoundr~get_values_for_typeri)rzr{san_extZ dns_namesrrr%get_names_from_subject_and_extensions6s  r)loaded_cert_or_reqrcCs|}t|j|jSr')to_cryptographyrrz extensions)r cert_or_reqrrr _pyopenssl_cert_or_req_all_namesXsr)rrcCsB|j}z|tj}Wntjy2gYS0|jtjS)ayGet Subject Alternative Names from certificate or CSR using pyOpenSSL. .. note:: Although this is `acme` internal API, it is used by `letsencrypt`. :param cert_or_req: Certificate or CSR. :type cert_or_req: `OpenSSL.crypto.X509` or `OpenSSL.crypto.X509Req`. :returns: A list of Subject Alternative Names that is DNS. :rtype: `list` of `str` ) rrrr rvrr~rri)rr{rrrr_pyopenssl_cert_or_req_san`s  r: T)rDre not_beforevalidity force_sanripsrc CsNt}|tttdd|d|dur:g}|durFg}|durRg}| t dddt |dkr|d| _ || g}|D]} | d| q|D]} | d | jqd |d } |st |d kst |dkr| tj d d| d||||dur$dn|||||||d|S)atGenerate new self-signed certificate. :type domains: `list` of `str` :param OpenSSL.crypto.PKey key: :param bool force_san: :param extensions: List of additional extensions to include in the cert. :type extensions: `list` of `OpenSSL.crypto.X509Extension` :type ips: `list` of (`ipaddress.IPv4Address` or `ipaddress.IPv6Address`) If more than one domain is provided, all of the domains are put into ``subjectAltName`` X.509 extension and first domain is set as the subject CN. If only one domain is provided no ``subjectAltName`` extension is used, unless `force_san` is ``True``. NsbasicConstraintsTsCA:TRUE, pathlen:0rzDNS:zIP:z, asciir^ssubjectAltNameF)rpr~Zsha256)rr0Zset_serial_numberrWbinasciiZhexlifyosurandomZ set_versionappend X509ExtensionrsZ get_subjectZCNZ set_issuerexplodedjoinencodeZadd_extensionsZgmtime_adj_notBeforeZgmtime_adj_notAfterZ set_pubkeyrw) rDrerrrrrrEZsanlistaddressipZ san_stringrrr gen_ss_certvsF      r)chainfiletypercs@tttjtjftdfdd dfdd|DS)zDump certificate chain into a bundle. :param list chain: List of `OpenSSL.crypto.X509` (or wrapped in :class:`josepy.util.ComparableX509`). :returns: certificate chain bundle :rtype: bytes )rErcs<t|tjr*t|jtjr$td|j}| S)NzUnexpected CSR provided.) rqjoseComparableX509wrappedrX509ReqrrJrrxr)rE)rrr _dump_certs   z(dump_pyopenssl_chain.._dump_certrnc3s|]}|VqdSr'r)rkrE)rrr rnz'dump_pyopenssl_chain..)rr rrrr0r.r)rrr)rrrdump_pyopenssl_chains r)NFN)NNrTNN)Br#rraenum ipaddressZloggingrrVr|rrrrrrrr r Z cryptographyr Zcryptography.hazmat.primitivesr r Z)cryptography.hazmat.primitives.asymmetricrrrrrZjosepyrZOpenSSLrrZacmerZ getLoggerr r=Z SSLv23_METHODrUIntEnumrr$r2r.rWrMr0rcrN IPv4Address IPv6AddressryrtZ Extensionsrrrrr/rrrrrrrrrs               t   ; D "    C