comparison mercurial/sslutil.py @ 44960:53b3baaadb64

sslutil: propagate return value ssl.PROTOCOL_SSLv23 from protocolsettings() Also, protocolsettings() was renamed to commonssloptions() to reflect that only the options are returned.
author Manuel Jacob <me@manueljacob.de>
date Mon, 01 Jun 2020 14:34:22 +0200
parents 38e3df9ff1e7
children 24d440e2fdbb
comparison
equal deleted inserted replaced
44959:38e3df9ff1e7 44960:53b3baaadb64
224 assert s[b'verifymode'] is not None 224 assert s[b'verifymode'] is not None
225 225
226 return s 226 return s
227 227
228 228
229 def protocolsettings(minimumprotocol): 229 def commonssloptions(minimumprotocol):
230 """Resolve the protocol for a config value. 230 """Return SSLContext options common to servers and clients.
231
232 Returns a tuple of (protocol, options) which are values used by SSLContext.
233 """ 231 """
234 if minimumprotocol not in configprotocols: 232 if minimumprotocol not in configprotocols:
235 raise ValueError(b'protocol value not supported: %s' % minimumprotocol) 233 raise ValueError(b'protocol value not supported: %s' % minimumprotocol)
236
237 # Despite its name, PROTOCOL_SSLv23 selects the highest protocol
238 # that both ends support, including TLS protocols.
239 #
240 # The PROTOCOL_TLSv* constants select a specific TLS version
241 # only (as opposed to multiple versions). So the method for
242 # supporting multiple TLS versions is to use PROTOCOL_SSLv23 and
243 # disable protocols via SSLContext.options and OP_NO_* constants.
244 234
245 # SSLv2 and SSLv3 are broken. We ban them outright. 235 # SSLv2 and SSLv3 are broken. We ban them outright.
246 options = ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 236 options = ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3
247 237
248 if minimumprotocol == b'tls1.0': 238 if minimumprotocol == b'tls1.0':
257 247
258 # Prevent CRIME. 248 # Prevent CRIME.
259 # There is no guarantee this attribute is defined on the module. 249 # There is no guarantee this attribute is defined on the module.
260 options |= getattr(ssl, 'OP_NO_COMPRESSION', 0) 250 options |= getattr(ssl, 'OP_NO_COMPRESSION', 0)
261 251
262 return ssl.PROTOCOL_SSLv23, options 252 return options
263 253
264 254
265 def wrapsocket(sock, keyfile, certfile, ui, serverhostname=None): 255 def wrapsocket(sock, keyfile, certfile, ui, serverhostname=None):
266 """Add SSL/TLS to a socket. 256 """Add SSL/TLS to a socket.
267 257
312 # have explicit control over CA loading because implicitly loading 302 # have explicit control over CA loading because implicitly loading
313 # CAs may undermine the user's intent. For example, a user may define a CA 303 # CAs may undermine the user's intent. For example, a user may define a CA
314 # bundle with a specific CA cert removed. If the system/default CA bundle 304 # bundle with a specific CA cert removed. If the system/default CA bundle
315 # is loaded and contains that removed CA, you've just undone the user's 305 # is loaded and contains that removed CA, you've just undone the user's
316 # choice. 306 # choice.
317 protocol, options = protocolsettings(settings[b'minimumprotocol']) 307 #
318 sslcontext = ssl.SSLContext(protocol) 308 # Despite its name, PROTOCOL_SSLv23 selects the highest protocol that both
319 sslcontext.options |= options 309 # ends support, including TLS protocols. commonssloptions() restricts the
310 # set of allowed protocols.
311 sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
312 sslcontext.options |= commonssloptions(settings[b'minimumprotocol'])
320 sslcontext.verify_mode = settings[b'verifymode'] 313 sslcontext.verify_mode = settings[b'verifymode']
321 314
322 if settings[b'ciphers']: 315 if settings[b'ciphers']:
323 try: 316 try:
324 sslcontext.set_ciphers(pycompat.sysstr(settings[b'ciphers'])) 317 sslcontext.set_ciphers(pycompat.sysstr(settings[b'ciphers']))
510 if f and not os.path.exists(f): 503 if f and not os.path.exists(f):
511 raise error.Abort( 504 raise error.Abort(
512 _(b'referenced certificate file (%s) does not exist') % f 505 _(b'referenced certificate file (%s) does not exist') % f
513 ) 506 )
514 507
515 protocol, options = protocolsettings(b'tls1.0') 508 # Despite its name, PROTOCOL_SSLv23 selects the highest protocol that both
509 # ends support, including TLS protocols. commonssloptions() restricts the
510 # set of allowed protocols.
511 protocol = ssl.PROTOCOL_SSLv23
512 options = commonssloptions(b'tls1.0')
516 513
517 # This config option is intended for use in tests only. It is a giant 514 # This config option is intended for use in tests only. It is a giant
518 # footgun to kill security. Don't define it. 515 # footgun to kill security. Don't define it.
519 exactprotocol = ui.config(b'devel', b'serverexactprotocol') 516 exactprotocol = ui.config(b'devel', b'serverexactprotocol')
520 if exactprotocol == b'tls1.0': 517 if exactprotocol == b'tls1.0':