1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
U
Z±dŽ­ã@sÆddlZddlZddlmZddlZddlm    Z    m
Z
ddl m Z ddl mZddlmZmZdZd    d
„ZGd d „d eƒZGd d„dƒZeddddgƒZGdd„de    edZGdd„de
eedZdS)éN)ÚEnumé)ÚStreamÚListener)Úaclose_forcefully)Ú_sync)ÚConflictDetectorÚFinali@cCs t|tjƒpt|dƒod|jkS)NÚstrerrorZUNEXPECTED_EOF_WHILE_READING)Ú
isinstanceÚ _stdlib_sslÚ SSLEOFErrorÚhasattrr
)Úexc©rú@d:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\trio/_ssl.pyÚ_is_eofÁs ÿrc@seZdZdZdS)ÚNeedHandshakeErrorz§Some :class:`SSLStream` methods can't return any meaningful data until
    after the handshake. If you call them before the handshake, they raise
    this error.
 
    N)Ú__name__Ú
__module__Ú __qualname__Ú__doc__rrrrrËsrc@s(eZdZdd„Zdd„Zedd„ƒZdS)Ú_OncecGs ||_||_d|_t ¡|_dS©NF)Ú_afnÚ_argsÚstartedrÚEventÚ_done)ÚselfZafnÚargsrrrÚ__init__Ôsz_Once.__init__cÃsP|js*d|_|j|jŽIdH|j ¡n"|s<|j ¡r<dS|j ¡IdHdS)NT)rrrrÚsetÚis_setÚwait)rÚ
checkpointrrrÚensureÚs z _Once.ensurecCs
|j ¡S©N)rr#©rrrrÚdoneäsz
_Once.doneN)rrrr!r&Úpropertyr)rrrrrÓs
rÚ_StateÚOKÚBROKENÚCLOSEDcsÎeZdZdZddddœdd„Zddd    d
d d d dddddddhZd d d ddddddh    Zdd„Z‡fdd„Z‡fdd„Z    dd„Z
dddœdd„Z d d!„Z d"d#„Z d.d$d%„Zd&d'„Zd(d)„Zd*d+„Zd,d-„Z‡ZS)/Ú    SSLStreamaEncrypted communication using SSL/TLS.
 
    :class:`SSLStream` wraps an arbitrary :class:`~trio.abc.Stream`, and
    allows you to perform encrypted communication over it using the usual
    :class:`~trio.abc.Stream` interface. You pass regular data to
    :meth:`send_all`, then it encrypts it and sends the encrypted data on the
    underlying :class:`~trio.abc.Stream`; :meth:`receive_some` takes encrypted
    data out of the underlying :class:`~trio.abc.Stream` and decrypts it
    before returning it.
 
    You should read the standard library's :mod:`ssl` documentation carefully
    before attempting to use this class, and probably other general
    documentation on SSL/TLS as well. SSL/TLS is subtle and quick to
    anger. Really. I'm not kidding.
 
    Args:
      transport_stream (~trio.abc.Stream): The stream used to transport
          encrypted data. Required.
 
      ssl_context (~ssl.SSLContext): The :class:`~ssl.SSLContext` used for
          this connection. Required. Usually created by calling
          :func:`ssl.create_default_context`.
 
      server_hostname (str or None): The name of the server being connected
          to. Used for `SNI
          <https://en.wikipedia.org/wiki/Server_Name_Indication>`__ and for
          validating the server's certificate (if hostname checking is
          enabled). This is effectively mandatory for clients, and actually
          mandatory if ``ssl_context.check_hostname`` is ``True``.
 
      server_side (bool): Whether this stream is acting as a client or
          server. Defaults to False, i.e. client mode.
 
      https_compatible (bool): There are two versions of SSL/TLS commonly
          encountered in the wild: the standard version, and the version used
          for HTTPS (HTTP-over-SSL/TLS).
 
          Standard-compliant SSL/TLS implementations always send a
          cryptographically signed ``close_notify`` message before closing the
          connection. This is important because if the underlying transport
          were simply closed, then there wouldn't be any way for the other
          side to know whether the connection was intentionally closed by the
          peer that they negotiated a cryptographic connection to, or by some
          `man-in-the-middle
          <https://en.wikipedia.org/wiki/Man-in-the-middle_attack>`__ attacker
          who can't manipulate the cryptographic stream, but can manipulate
          the transport layer (a so-called "truncation attack").
 
          However, this part of the standard is widely ignored by real-world
          HTTPS implementations, which means that if you want to interoperate
          with them, then you NEED to ignore it too.
 
          Fortunately this isn't as bad as it sounds, because the HTTP
          protocol already includes its own equivalent of ``close_notify``, so
          doing this again at the SSL/TLS level is redundant. But not all
          protocols do! Therefore, by default Trio implements the safer
          standard-compliant version (``https_compatible=False``). But if
          you're speaking HTTPS or some other protocol where
          ``close_notify``\s are commonly skipped, then you should set
          ``https_compatible=True``; with this setting, Trio will neither
          expect nor send ``close_notify`` messages.
 
          If you have code that was written to use :class:`ssl.SSLSocket` and
          now you're porting it to Trio, then it may be useful to know that a
          difference between :class:`SSLStream` and :class:`ssl.SSLSocket` is
          that :class:`~ssl.SSLSocket` implements the
          ``https_compatible=True`` behavior by default.
 
    Attributes:
      transport_stream (trio.abc.Stream): The underlying transport stream
          that was passed to ``__init__``. An example of when this would be
          useful is if you're using :class:`SSLStream` over a
          :class:`~trio.SocketStream` and want to call the
          :class:`~trio.SocketStream`'s :meth:`~trio.SocketStream.setsockopt`
          method.
 
    Internally, this class is implemented using an instance of
    :class:`ssl.SSLObject`, and all of :class:`~ssl.SSLObject`'s methods and
    attributes are re-exported as methods and attributes on this class.
    However, there is one difference: :class:`~ssl.SSLObject` has several
    methods that return information about the encrypted connection, like
    :meth:`~ssl.SSLSocket.cipher` or
    :meth:`~ssl.SSLSocket.selected_alpn_protocol`. If you call them before the
    handshake, when they can't possibly return useful data, then
    :class:`ssl.SSLObject` returns None, but :class:`trio.SSLStream`
    raises :exc:`NeedHandshakeError`.
 
    This also means that if you register a SNI callback using
    `~ssl.SSLContext.sni_callback`, then the first argument your callback
    receives will be a :class:`ssl.SSLObject`.
 
    NF)Úserver_hostnameÚ server_sideÚhttps_compatiblecCsŠ||_tj|_||_t ¡|_d|_t ¡|_    |j
|j    |j||d|_ t |j ƒ|_t ¡|_d|_t ¡|_tdƒ|_tdƒ|_t|_dS)N)r1r0rz8another task is currently sending data on this SSLStreamz:another task is currently receiving data on this SSLStream)Útransport_streamr+r,Ú_stateÚ_https_compatibler Ú    MemoryBIOÚ    _outgoingÚ_delayed_outgoingÚ    _incomingÚwrap_bioÚ _ssl_objectrÚ _do_handshakeÚ
_handshookrZStrictFIFOLockÚ_inner_send_lockÚ_inner_recv_countÚLockÚ_inner_recv_lockrÚ_outer_send_conflict_detectorÚ_outer_recv_conflict_detectorÚSTARTING_RECEIVE_SIZEÚ_estimated_receive_size)rr3Ú ssl_contextr0r1r2rrrr!Ls.    
 
ü 
 
ÿÿzSSLStream.__init__Úcontextr1r0ÚsessionÚsession_reusedÚ getpeercertÚselected_npn_protocolÚcipherÚshared_ciphersÚ compressionÚpendingÚget_channel_bindingÚselected_alpn_protocolÚversioncCsB||jkr6||jkr*|jjs*td |¡ƒ‚t|j|ƒSt|ƒ‚dS)Nz'call do_handshake() before calling {!r})    Ú
_forwardedÚ_after_handshaker=r)rÚformatÚgetattrr;ÚAttributeError)rÚnamerrrÚ __getattr__’s
ÿ zSSLStream.__getattr__cs,||jkrt|j||ƒntƒ ||¡dSr')rSÚsetattrr;ÚsuperÚ __setattr__)rrXÚvalue©Ú    __class__rrr\s
zSSLStream.__setattr__cstƒ ¡t|jƒSr')r[Ú__dir__ÚlistrSr(r^rrr`£szSSLStream.__dir__cCsD|jtjkrdS|jtjkr$tj‚n|jtjkr8tj‚nds@t‚dSr)    r4r+r,r-ÚtrioÚBrokenResourceErrorr.ZClosedResourceErrorÚAssertionErrorr(rrrÚ _check_status¦s   zSSLStream._check_status)Úignore_want_readÚ is_handshakec
Çsðtj ¡IdHd}d}|sÖd}d}z ||Ž}WnRtjk
rLd}Yn>tjtjfk
r„}    ztj|_    tj
|    ‚W5d}    ~    XYnXd}|r–d}d}|j   ¡}
|rÖ|sÖ|j jrÖ|j  ¡dkrÖ|jdksÌt‚|
|_d}
|
rL|j4IdHšTd}z2|jdk    r|j|
}
d|_|j |
¡IdHWntj|_    ‚YnXW5QIdHRXq|r|j} |j4IdHšdd}| |jkrÄ|j ¡IdH} | s˜|j ¡nt|jt| ƒƒ|_|j | ¡|jd7_W5QIdHRXq|sìtj ¡IdH|S)NFTzTLSv1.3ór)rbÚlowlevelZcheckpoint_if_cancelledr ÚSSLWantReadErrorÚSSLErrorÚCertificateErrorr+r-r4rcr7Úreadr;r1rRr8rdr>r3Úsend_allr?rAÚ receive_somer9Ú    write_eofÚmaxrEÚlenÚwriteZcancel_shielded_checkpoint) rÚfnrfrgr ÚyieldedÚfinishedZ    want_readÚretrZto_sendZ
recv_countÚdatarrrÚ_retry´sr 
ÿþý ü; 
   ÿ  zSSLStream._retrycÃs8z|j|jjddIdHWntj|_‚YnXdS)NT)rg)ryr;Ú do_handshaker+r-r4r(rrrr<`s
zSSLStream._do_handshakecÃs | ¡|jjddIdHdS)u‡Ensure that the initial handshake has completed.
 
        The SSL protocol requires an initial handshake to exchange
        certificates, select cryptographic keys, and so forth, before any
        actual data can be sent or received. You don't have to call this
        method; if you don't, then :class:`SSLStream` will automatically
        perform the handshake as needed, the first time you try to send or
        receive data. But if you want to trigger it manually â€“ for example,
        because you want to look at the peer's certificate before you start
        talking to them â€“ then you can call this method.
 
        If the initial handshake is already in progress in another task, this
        waits for it to complete and then returns.
 
        If the initial handshake has already completed, this returns
        immediately without doing anything (except executing a checkpoint).
 
        .. warning:: If this method is cancelled, then it may leave the
           :class:`SSLStream` in an unusable state. If this happens then any
           future attempt to use the object will raise
           :exc:`trio.BrokenResourceError`.
 
        T©r%N)rer=r&r(rrrrzgszSSLStream.do_handshakec Ãs\|jJ| ¡z|jjddIdHWnhtjk
r’}zH|jr€t|jt    j
ƒs\t |jƒr€tj   ¡IdHWY¢W5QR£dS‚W5d}~XYnX|dkr®t|j|jjƒ}nt |¡}|dkrÈtdƒ‚z$| |jj|¡IdHWW5QR£Stjk
rL}z>|jr:t |jƒr:tj   ¡IdHWY¢W5QR£dS‚W5d}~XYnXW5QRXdS)aãRead some data from the underlying transport, decrypt it, and
        return it.
 
        See :meth:`trio.abc.ReceiveStream.receive_some` for details.
 
        .. warning:: If this method is cancelled while the initial handshake
           or a renegotiation are in progress, then it may leave the
           :class:`SSLStream` in an unusable state. If this happens then any
           future attempt to use the object will raise
           :exc:`trio.BrokenResourceError`.
 
        Fr{Nrhrzmax_bytes must be >= 1)rCrer=r&rbrcr5r Ú    __cause__r ÚSSLSyscallErrorrrir%rqrEr9rOÚ    _operatorÚindexÚ
ValueErrorryr;rm)rZ    max_bytesrrrrroŠs2
 ÿþ
$zSSLStream.receive_somec    Ãsj|jZ| ¡|jjddIdH|sFtj ¡IdHW5QR£dS| |jj    |¡IdHW5QRXdS)azEncrypt some data and then send it on the underlying transport.
 
        See :meth:`trio.abc.SendStream.send_all` for details.
 
        .. warning:: If this method is cancelled, then it may leave the
           :class:`SSLStream` in an unusable state. If this happens then any
           attempt to use the object will raise
           :exc:`trio.BrokenResourceError`.
 
        Fr{N)
rBrer=r&rbrir%ryr;rs)rrxrrrrn¿s zSSLStream.send_allc ÃsŽ|j~|jl| ¡|jjddIdH| |jj¡IdH|j}d|_t    j
|_ ||j   ¡fW5QR£W5QR£SQRXW5QRXdS)aðCleanly close down the SSL/TLS encryption layer, allowing the
        underlying stream to be used for unencrypted communication.
 
        You almost certainly don't need this.
 
        Returns:
          A pair ``(transport_stream, trailing_bytes)``, where
          ``transport_stream`` is the underlying transport stream, and
          ``trailing_bytes`` is a byte string. Since :class:`SSLStream`
          doesn't necessarily know where the end of the encrypted data will
          be, it can happen that it accidentally reads too much from the
          underlying stream. ``trailing_bytes`` contains this extra data; you
          should process it as if it was returned from a call to
          ``transport_stream.receive_some(...)``.
 
        Fr{N)rCrBrer=r&ryr;Úunwrapr3r+r.r4r9rm©rr3rrrrÔszSSLStream.unwrapc    Ãsä|jtjkr tj ¡IdHdS|jtjks2|jrNtj|_|j     ¡IdHdSz†zR|j
j ddIdHz|j |j jddIdHWntjtjfk
ržYnXWnt|jƒIdH‚YnX|j     ¡IdHW5tj|_XdS)aÃGracefully shut down this connection, and close the underlying
        transport.
 
        If ``https_compatible`` is False (the default), then this attempts to
        first send a ``close_notify`` and then close the underlying stream by
        calling its :meth:`~trio.abc.AsyncResource.aclose` method.
 
        If ``https_compatible`` is set to True, then this simply closes the
        underlying stream and marks this stream as closed.
 
        NFr{T)rf)r4r+r.rbrir%r-r5r3Úacloser=r&ryr;rrcZBusyResourceErrorrr(rrrrƒîs$ 0
zSSLStream.aclosec ÃsN|j>| ¡|j4IdHš|j ¡IdHW5QIdHRXW5QRXdS)z>See :meth:`trio.abc.SendStream.wait_send_all_might_not_block`.N)rBrer>r3Úwait_send_all_might_not_blockr(rrrr„Esz'SSLStream.wait_send_all_might_not_block)N)rrrrr!rSrTrYr\r`reryr<rzrornrrƒr„Ú __classcell__rrr^rr/ìsVdù *ò÷   -#
5Wr/)Ú    metaclassc@s.eZdZdZddœdd„Zdd„Zdd    „Zd
S) Ú SSLListenera»A :class:`~trio.abc.Listener` for SSL/TLS-encrypted servers.
 
    :class:`SSLListener` wraps around another Listener, and converts
    all incoming connections to encrypted connections by wrapping them
    in a :class:`SSLStream`.
 
    Args:
      transport_listener (~trio.abc.Listener): The listener whose incoming
          connections will be wrapped in :class:`SSLStream`.
 
      ssl_context (~ssl.SSLContext): The :class:`~ssl.SSLContext` that will be
          used for incoming connections.
 
      https_compatible (bool): Passed on to :class:`SSLStream`.
 
    Attributes:
      transport_listener (trio.abc.Listener): The underlying listener that was
          passed to ``__init__``.
 
    F)r2cCs||_||_||_dSr')Útransport_listenerÚ _ssl_contextr5)rrˆrFr2rrrr!„szSSLListener.__init__cÃs$|j ¡IdH}t||jd|jdS)z…Accept the next connection and wrap it in an :class:`SSLStream`.
 
        See :meth:`trio.abc.Listener.accept` for details.
 
        NT)r1r2)rˆÚacceptr/r‰r5r‚rrrrŠsüzSSLListener.acceptcÃs|j ¡IdHdS)zClose the transport listener.N)rˆrƒr(rrrrƒszSSLListener.acloseN)rrrrr!rŠrƒrrrrr‡ns
û r‡)Úoperatorr~Ússlr ÚenumrÚ_EnumrbÚabcrrZ_highlevel_genericrÚrZ_utilrr    rDrÚ    Exceptionrrr+r/r‡rrrrÚ<module>˜s&