3 5lc^A @s\dZddlZddlZddlZddlZddlZddlZddlZddlm Z ddlm Z ddlm Z ddlm Z ddlm Z ddlmZdd lmZdd lmZddlZdd lmZdd lmZdd lmZejeZejZGdddZGdddZdded0dfeee e e ee!e fe e e!ej"dddZ#d1ee eee!e e!fe$e e eej%ej&fedddZ'eej"ej(fe e!dddZ)eej"ej(fe e!dd d!Z*eej"ej(fe e!dd"d#Z+eej"ej(fe e!dd$d%Z,d5ej-e e e!e e e e$e e ej.e e eej%ej&fej"d*d+d,Z/ej0fe ej"e ed-d.d/Z1dS)6zCrypto utilities.N)Any)Callable)List)Mapping)Optional)Set)Tuple)Union)crypto)SSL)errorsc@sPeZdZeeeejejffdddZ e j e eejejfdddZ dS)_DefaultCertSelection)certscCs ||_dS)N)r)selfrr!/usr/lib/python3.6/crypto_util.py__init__%sz_DefaultCertSelection.__init__) connectionreturncCs|j}|jj|dS)N)get_servernamerget)rrZ server_namerrr__call__(sz_DefaultCertSelection.__call__N)__name__ __module__ __qualname__rbytesrr PKeyX509rr Connectionrrrrrrr $s"r c @seZdZdZdeddfejeeee e j e j ffe eeejeegefeeejge 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)sockrmethodalpn_selectioncert_selectionrcCs\||_||_||_| r&| r&td|r6|r6td|}|dkrRt|rL|ni}||_dS)Nz*Neither cert_selection or certs specified.z(Both cert_selection and certs specified.)r r"r! ValueErrorr r#)rr rr!r"r#Zactual_cert_selectionrrrr:s zSSLSocket.__init__)namercCs t|j|S)N)getattrr )rr%rrr __getattr__PszSSLSocket.__getattr__)rrcCs|j|}|dkr&tjd|jdS|\}}tj|j}|jtj|jtj |j ||j ||j dk r||j |j |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)r#loggerdebugrr Contextr! set_options OP_NO_SSLv2 OP_NO_SSLv3Zuse_privatekeyZuse_certificater"set_alpn_select_callbackZ set_context)rrZpairkeycertZ new_contextrrr_pick_certificate_cbSs         zSSLSocket._pick_certificate_cbc@sBeZdZdZejddddZeedddZ ee d d d Z dS) zSSLSocket.FakeConnectionzFake OpenSSL.SSL.Connection.N)rrcCs ||_dS)N)_wrapped)rrrrrrssz!SSLSocket.FakeConnection.__init__)r%rcCs t|j|S)N)r&r2)rr%rrrr'vsz$SSLSocket.FakeConnection.__getattr__) unused_argsrcGs |jjS)N)r2shutdown)rr3rrrr4ysz!SSLSocket.FakeConnection.shutdown) rrr__doc__r rrstrrr'boolr4rrrrFakeConnectionnsr8)rcCs|jj\}}tj|j}|jtj|jtj|j|j |j dk rT|j |j |j tj ||}|jtjd|y |jWn.tjk r}ztj|WYdd}~XnX||fS)NzPerforming handshake with %s)r acceptr r*r!r+r,r-Zset_tlsext_servername_callbackr1r"r.r8rZset_accept_stater(r) do_handshakeErrorsocketerror)rr ZaddrcontextZssl_sockr=rrrr9}s        zSSLSocket.accept)rrrr5_DEFAULT_SSL_METHODr<rrrrr rrintrr rrrr6rr'r1r8r9rrrrr-s Zrii,)r%hostporttimeoutr!source_addressalpn_protocolsrc%Cs&tj|}|j|d|i}yFtjd||t|rDdj|d|dnd||f} tj| f|} Wn.tj k r} zt j | WYdd} ~ XnXt j | |} tj|| } | j| j||dk r| j|y| j| jWn0tj k r} zt j | WYdd} ~ XnXWdQRX| jS)aProbe 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: `list` of `str` :raises acme.errors.Error: In case of any problems. :returns: SSL certificate presented by the server. :rtype: OpenSSL.crypto.X509 rEz!Attempting to connect to %s:%d%s.z from {0}:{1}rrAN)r r*Z set_timeoutr(r)anyformatr<Zcreate_connectionr=r r; contextlibclosingrZset_connect_stateZset_tlsext_host_nameZset_alpn_protosr:r4Zget_peer_certificate)r%rBrCrDr!rErFr>Z socket_kwargsZ socket_tupler r=ZclientZ client_sslrrr probe_snis.  "     &rLF)private_key_pemdomains must_stapleipaddrsrc Cstjtj|}tj}g}|dkr&g}|dkr2g}t|t|dkrNtdx|D]}|jd|qTWx|D]}|jd|jqpWdj|j d} tj dd | d g} |r| jtj d d d d |j | |j ||j d|j|d tjtj|S)aGenerate a CSR containing domains or IPs as subjectAltNames. :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. params ordered this way for backward competablity when called by positional argument. :returns: buffer PEM-encoded Certificate Signing Request. NrzAAt least one of domains or ipaddrs parameter need to be not emptyzDNS:zIP:z, asciissubjectAltNameF)criticalvalues1.3.6.1.5.5.7.1.24sDER:30:03:02:01:05sha256)r Zload_privatekey FILETYPE_PEMX509Reqlenr$appendexplodedjoinencode X509Extensionadd_extensions set_pubkey set_versionsigndump_certificate_request) rMrNrOrPZ private_keyZcsrsanlistaddressips san_string extensionsrrrmake_csrs<         rg)loaded_cert_or_reqrcs6|jjt|}dkr|Sgfdd|DS)Ncsg|]}|kr|qSrr).0d) common_namerr sz4_pyopenssl_cert_or_req_all_names..) get_subjectCN_pyopenssl_cert_or_req_san)rhZsansr)rkr _pyopenssl_cert_or_req_all_namess  rp) cert_or_reqrcs(ddt|}fdd|DS)aGet Subject Alternative Names from certificate or CSR using pyOpenSSL. .. todo:: Implement directly in 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 `unicode` :ZDNScs$g|]}|jr|jdqS)rG) startswithsplit)ripart)part_separatorprefixrrrl$sz._pyopenssl_cert_or_req_san..)_pyopenssl_extract_san_list_raw)rq sans_partsr)rvrwrro s  rocs&d}d|t|}fdd|DS)aiGet Subject Alternative Names IPs from certificate or CSR using pyOpenSSL. :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 are IP Addresses. :rtype: `list` of `unicode`. note that this returns as string, not IPaddress object rrz IP Addresscs&g|]}|jr|tdqS)N)rsrW)riru)rwrrrl9sz1_pyopenssl_cert_or_req_san_ip..)rx)rqrvryr)rwr_pyopenssl_cert_or_req_san_ip(s rzcCsft|tjr"tjtj|jd}ntjtj|jd}tjd|}d}|dkrRgn|j dj |}|S)aGet raw SAN string from cert or csr, parse it as UTF-8 and return. :param cert_or_req: Certificate or CSR. :type cert_or_req: `OpenSSL.crypto.X509` or `OpenSSL.crypto.X509Req`. :returns: raw san strings, parsed byte as utf-8 :rtype: `list` of `unicode` zutf-8z5X509v3 Subject Alternative Name:(?: critical)?\s*(.*)z, NrG) isinstancer rdump_certificateZ FILETYPE_TEXTdecoderaresearchgrouprt)rqtextZraw_sanZparts_separatorryrrrrx<s  rx<T)r/rN not_beforevalidity force_sanrfrdrc CsVtj}|jttjtjdd|jd|dkr:g}|dkrFg}|dkrRg}|j tj dddt |dkr|d|j _ |j|j g}x|D]} |j d| qWx|D]} |j d | jqWd j|jd } |st |d kst |dkr|j tj d d| d|j||j|dkr,dn||j||j||j|d|S)axGenerate new self-signed certificate. :type domains: `list` of `unicode` :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, rQrGssubjectAltNameF)rRrSrT)r rZset_serial_numberr@binasciiZhexlifyosurandomr_rXr\rWrmrnZ set_issuerrYrZr[r]Zgmtime_adj_notBeforeZgmtime_adj_notAfterr^r`) r/rNrrrrfrdr0rbrcZiprerrr gen_ss_cert[s@          r)chainfiletypercs8ttjtjftdfdd djfdd|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 )r0rcst|tjr|j}tj|S)N)r{joseComparableX509wrappedr r|)r0)rrr _dump_certs z(dump_pyopenssl_chain.._dump_certc3s|]}|VqdS)Nr)rir0)rrr sz'dump_pyopenssl_chain..)r rrr rrrZ)rrr)rrrdump_pyopenssl_chains r)rAr)NFNi`': )NNrTNN)2r5rrJZ ipaddressZloggingrr~r<Ztypingrrrrrrrr ZjosepyrZOpenSSLr r Zacmer Z getLoggerrr(Z SSLv23_METHODr?r rrr@r6rrLr7Z IPv4AddressZ IPv6AddressrgrVrprorzrxrr\rrUrrrrrsT             h2523   <=