29
29
TLSVersion ,
30
30
platformTrust ,
31
31
)
32
+ from twisted .protocols .tls import TLSMemoryBIOProtocol
32
33
from twisted .python .failure import Failure
33
34
from twisted .web .iweb import IPolicyForHTTPS
34
35
36
+ from synapse .config .homeserver import HomeServerConfig
37
+
35
38
logger = logging .getLogger (__name__ )
36
39
37
40
@@ -51,7 +54,7 @@ class ServerContextFactory(ContextFactory):
51
54
per https://github.com/matrix-org/synapse/issues/1691
52
55
"""
53
56
54
- def __init__ (self , config ):
57
+ def __init__ (self , config : HomeServerConfig ):
55
58
# TODO: once pyOpenSSL exposes TLS_METHOD and SSL_CTX_set_min_proto_version,
56
59
# switch to those (see https://github.com/pyca/cryptography/issues/5379).
57
60
#
@@ -64,7 +67,7 @@ def __init__(self, config):
64
67
self .configure_context (self ._context , config )
65
68
66
69
@staticmethod
67
- def configure_context (context , config ) :
70
+ def configure_context (context : SSL . Context , config : HomeServerConfig ) -> None :
68
71
try :
69
72
_ecCurve = crypto .get_elliptic_curve (_defaultCurveName )
70
73
context .set_tmp_ecdh (_ecCurve )
@@ -75,14 +78,15 @@ def configure_context(context, config):
75
78
SSL .OP_NO_SSLv2 | SSL .OP_NO_SSLv3 | SSL .OP_NO_TLSv1 | SSL .OP_NO_TLSv1_1
76
79
)
77
80
context .use_certificate_chain_file (config .tls .tls_certificate_file )
81
+ assert config .tls .tls_private_key is not None
78
82
context .use_privatekey (config .tls .tls_private_key )
79
83
80
84
# https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
81
85
context .set_cipher_list (
82
- "ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES256:ECDH+AES128:!aNULL:!SHA1:!AESCCM"
86
+ b "ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES256:ECDH+AES128:!aNULL:!SHA1:!AESCCM"
83
87
)
84
88
85
- def getContext (self ):
89
+ def getContext (self ) -> SSL . Context :
86
90
return self ._context
87
91
88
92
@@ -98,7 +102,7 @@ class FederationPolicyForHTTPS:
98
102
constructs an SSLClientConnectionCreator factory accordingly.
99
103
"""
100
104
101
- def __init__ (self , config ):
105
+ def __init__ (self , config : HomeServerConfig ):
102
106
self ._config = config
103
107
104
108
# Check if we're using a custom list of a CA certificates
@@ -131,7 +135,7 @@ def __init__(self, config):
131
135
self ._config .tls .federation_certificate_verification_whitelist
132
136
)
133
137
134
- def get_options (self , host : bytes ):
138
+ def get_options (self , host : bytes ) -> IOpenSSLClientConnectionCreator :
135
139
# IPolicyForHTTPS.get_options takes bytes, but we want to compare
136
140
# against the str whitelist. The hostnames in the whitelist are already
137
141
# IDNA-encoded like the hosts will be here.
@@ -153,7 +157,9 @@ def get_options(self, host: bytes):
153
157
154
158
return SSLClientConnectionCreator (host , ssl_context , should_verify )
155
159
156
- def creatorForNetloc (self , hostname , port ):
160
+ def creatorForNetloc (
161
+ self , hostname : bytes , port : int
162
+ ) -> IOpenSSLClientConnectionCreator :
157
163
"""Implements the IPolicyForHTTPS interface so that this can be passed
158
164
directly to agents.
159
165
"""
@@ -169,16 +175,18 @@ class RegularPolicyForHTTPS:
169
175
trust root.
170
176
"""
171
177
172
- def __init__ (self ):
178
+ def __init__ (self ) -> None :
173
179
trust_root = platformTrust ()
174
180
self ._ssl_context = CertificateOptions (trustRoot = trust_root ).getContext ()
175
181
self ._ssl_context .set_info_callback (_context_info_cb )
176
182
177
- def creatorForNetloc (self , hostname , port ):
183
+ def creatorForNetloc (
184
+ self , hostname : bytes , port : int
185
+ ) -> IOpenSSLClientConnectionCreator :
178
186
return SSLClientConnectionCreator (hostname , self ._ssl_context , True )
179
187
180
188
181
- def _context_info_cb (ssl_connection , where , ret ) :
189
+ def _context_info_cb (ssl_connection : SSL . Connection , where : int , ret : int ) -> None :
182
190
"""The 'information callback' for our openssl context objects.
183
191
184
192
Note: Once this is set as the info callback on a Context object, the Context should
@@ -204,11 +212,13 @@ class SSLClientConnectionCreator:
204
212
Replaces twisted.internet.ssl.ClientTLSOptions
205
213
"""
206
214
207
- def __init__ (self , hostname : bytes , ctx , verify_certs : bool ):
215
+ def __init__ (self , hostname : bytes , ctx : SSL . Context , verify_certs : bool ):
208
216
self ._ctx = ctx
209
217
self ._verifier = ConnectionVerifier (hostname , verify_certs )
210
218
211
- def clientConnectionForTLS (self , tls_protocol ):
219
+ def clientConnectionForTLS (
220
+ self , tls_protocol : TLSMemoryBIOProtocol
221
+ ) -> SSL .Connection :
212
222
context = self ._ctx
213
223
connection = SSL .Connection (context , None )
214
224
@@ -219,7 +229,7 @@ def clientConnectionForTLS(self, tls_protocol):
219
229
# ... and we also gut-wrench a '_synapse_tls_verifier' attribute into the
220
230
# tls_protocol so that the SSL context's info callback has something to
221
231
# call to do the cert verification.
222
- tls_protocol ._synapse_tls_verifier = self ._verifier
232
+ tls_protocol ._synapse_tls_verifier = self ._verifier # type: ignore[attr-defined]
223
233
return connection
224
234
225
235
@@ -244,7 +254,9 @@ def __init__(self, hostname: bytes, verify_certs: bool):
244
254
self ._hostnameBytes = hostname
245
255
self ._hostnameASCII = self ._hostnameBytes .decode ("ascii" )
246
256
247
- def verify_context_info_cb (self , ssl_connection , where ):
257
+ def verify_context_info_cb (
258
+ self , ssl_connection : SSL .Connection , where : int
259
+ ) -> None :
248
260
if where & SSL .SSL_CB_HANDSHAKE_START and not self ._is_ip_address :
249
261
ssl_connection .set_tlsext_host_name (self ._hostnameBytes )
250
262
0 commit comments