comparison mercurial/sslutil.py @ 44937:035199ba04ee

sslutil: eliminate `modernssl` by constant-folding code using it
author Manuel Jacob <me@manueljacob.de>
date Fri, 29 May 2020 21:30:04 +0200
parents dca2629f6d2e
children 7dd63a8cb1ee
comparison
equal deleted inserted replaced
44936:86a7b7abf28e 44937:035199ba04ee
50 if util.safehasattr(ssl, b'PROTOCOL_TLSv1_1'): 50 if util.safehasattr(ssl, b'PROTOCOL_TLSv1_1'):
51 supportedprotocols.add(b'tls1.1') 51 supportedprotocols.add(b'tls1.1')
52 if util.safehasattr(ssl, b'PROTOCOL_TLSv1_2'): 52 if util.safehasattr(ssl, b'PROTOCOL_TLSv1_2'):
53 supportedprotocols.add(b'tls1.2') 53 supportedprotocols.add(b'tls1.2')
54 54
55 modernssl = True
56 _canloaddefaultcerts = True 55 _canloaddefaultcerts = True
57 56
58 57
59 def _hostsettings(ui, hostname): 58 def _hostsettings(ui, hostname):
60 """Obtain security settings for a hostname. 59 """Obtain security settings for a hostname.
397 sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname) 396 sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname)
398 except ssl.SSLError as e: 397 except ssl.SSLError as e:
399 # If we're doing certificate verification and no CA certs are loaded, 398 # If we're doing certificate verification and no CA certs are loaded,
400 # that is almost certainly the reason why verification failed. Provide 399 # that is almost certainly the reason why verification failed. Provide
401 # a hint to the user. 400 # a hint to the user.
402 # Only modern ssl module exposes SSLContext.get_ca_certs() so we can
403 # only show this warning if modern ssl is available.
404 # The exception handler is here to handle bugs around cert attributes: 401 # The exception handler is here to handle bugs around cert attributes:
405 # https://bugs.python.org/issue20916#msg213479. (See issues5313.) 402 # https://bugs.python.org/issue20916#msg213479. (See issues5313.)
406 # When the main 20916 bug occurs, 'sslcontext.get_ca_certs()' is a 403 # When the main 20916 bug occurs, 'sslcontext.get_ca_certs()' is a
407 # non-empty list, but the following conditional is otherwise True. 404 # non-empty list, but the following conditional is otherwise True.
408 try: 405 try:
409 if ( 406 if (
410 caloaded 407 caloaded
411 and settings[b'verifymode'] == ssl.CERT_REQUIRED 408 and settings[b'verifymode'] == ssl.CERT_REQUIRED
412 and modernssl
413 and not sslcontext.get_ca_certs() 409 and not sslcontext.get_ca_certs()
414 ): 410 ):
415 ui.warn( 411 ui.warn(
416 _( 412 _(
417 b'(an attempt was made to load CA certificates but ' 413 b'(an attempt was made to load CA certificates but '
567 elif exactprotocol: 563 elif exactprotocol:
568 raise error.Abort( 564 raise error.Abort(
569 _(b'invalid value for serverexactprotocol: %s') % exactprotocol 565 _(b'invalid value for serverexactprotocol: %s') % exactprotocol
570 ) 566 )
571 567
572 if modernssl: 568 # We /could/ use create_default_context() here since it doesn't load
573 # We /could/ use create_default_context() here since it doesn't load 569 # CAs when configured for client auth. However, it is hard-coded to
574 # CAs when configured for client auth. However, it is hard-coded to 570 # use ssl.PROTOCOL_SSLv23 which may not be appropriate here.
575 # use ssl.PROTOCOL_SSLv23 which may not be appropriate here. 571 sslcontext = ssl.SSLContext(protocol)
576 sslcontext = ssl.SSLContext(protocol) 572 sslcontext.options |= options
577 sslcontext.options |= options 573
578 574 # Improve forward secrecy.
579 # Improve forward secrecy. 575 sslcontext.options |= getattr(ssl, 'OP_SINGLE_DH_USE', 0)
580 sslcontext.options |= getattr(ssl, 'OP_SINGLE_DH_USE', 0) 576 sslcontext.options |= getattr(ssl, 'OP_SINGLE_ECDH_USE', 0)
581 sslcontext.options |= getattr(ssl, 'OP_SINGLE_ECDH_USE', 0) 577
582 578 # Use the list of more secure ciphers if found in the ssl module.
583 # Use the list of more secure ciphers if found in the ssl module. 579 if util.safehasattr(ssl, b'_RESTRICTED_SERVER_CIPHERS'):
584 if util.safehasattr(ssl, b'_RESTRICTED_SERVER_CIPHERS'): 580 sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0)
585 sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0) 581 sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS)
586 sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS)
587 else:
588 sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
589 582
590 if requireclientcert: 583 if requireclientcert:
591 sslcontext.verify_mode = ssl.CERT_REQUIRED 584 sslcontext.verify_mode = ssl.CERT_REQUIRED
592 else: 585 else:
593 sslcontext.verify_mode = ssl.CERT_NONE 586 sslcontext.verify_mode = ssl.CERT_NONE