Mercurial > public > mercurial-scm > hg
comparison mercurial/sslutil.py @ 44875:7c19eb372438
sslutil: remove code checking for presence of ssl.SSLContext
Now that we require the presence of ssl.SSLContext in setup.py, we can remove
this code.
author | Manuel Jacob <me@manueljacob.de> |
---|---|
date | Fri, 29 May 2020 21:18:22 +0200 |
parents | 47b3c8383cc1 |
children | dca2629f6d2e |
comparison
equal
deleted
inserted
replaced
44874:4c53c12b92d5 | 44875:7c19eb372438 |
---|---|
31 | 31 |
32 # Python 2.7.9+ overhauled the built-in SSL/TLS features of Python. It added | 32 # Python 2.7.9+ overhauled the built-in SSL/TLS features of Python. It added |
33 # support for TLS 1.1, TLS 1.2, SNI, system CA stores, etc. These features are | 33 # support for TLS 1.1, TLS 1.2, SNI, system CA stores, etc. These features are |
34 # all exposed via the "ssl" module. | 34 # all exposed via the "ssl" module. |
35 # | 35 # |
36 # Depending on the version of Python being used, SSL/TLS support is either | 36 # We require in setup.py the presence of ssl.SSLContext, which indicates modern |
37 # modern/secure or legacy/insecure. Many operations in this module have | 37 # SSL/TLS support. |
38 # separate code paths depending on support in Python. | |
39 | 38 |
40 configprotocols = { | 39 configprotocols = { |
41 b'tls1.0', | 40 b'tls1.0', |
42 b'tls1.1', | 41 b'tls1.1', |
43 b'tls1.2', | 42 b'tls1.2', |
51 if util.safehasattr(ssl, b'PROTOCOL_TLSv1_1'): | 50 if util.safehasattr(ssl, b'PROTOCOL_TLSv1_1'): |
52 supportedprotocols.add(b'tls1.1') | 51 supportedprotocols.add(b'tls1.1') |
53 if util.safehasattr(ssl, b'PROTOCOL_TLSv1_2'): | 52 if util.safehasattr(ssl, b'PROTOCOL_TLSv1_2'): |
54 supportedprotocols.add(b'tls1.2') | 53 supportedprotocols.add(b'tls1.2') |
55 | 54 |
56 try: | 55 modernssl = True |
57 # ssl.SSLContext was added in 2.7.9 and presence indicates modern | 56 _canloaddefaultcerts = True |
58 # SSL/TLS features are available. | |
59 SSLContext = ssl.SSLContext | |
60 modernssl = True | |
61 _canloaddefaultcerts = True | |
62 except AttributeError: | |
63 modernssl = False | |
64 _canloaddefaultcerts = False | |
65 | |
66 # We implement SSLContext using the interface from the standard library. | |
67 class SSLContext(object): | |
68 def __init__(self, protocol): | |
69 # From the public interface of SSLContext | |
70 self.protocol = protocol | |
71 self.check_hostname = False | |
72 self.options = 0 | |
73 self.verify_mode = ssl.CERT_NONE | |
74 | |
75 # Used by our implementation. | |
76 self._certfile = None | |
77 self._keyfile = None | |
78 self._certpassword = None | |
79 self._cacerts = None | |
80 self._ciphers = None | |
81 | |
82 def load_cert_chain(self, certfile, keyfile=None, password=None): | |
83 self._certfile = certfile | |
84 self._keyfile = keyfile | |
85 self._certpassword = password | |
86 | |
87 def load_default_certs(self, purpose=None): | |
88 pass | |
89 | |
90 def load_verify_locations(self, cafile=None, capath=None, cadata=None): | |
91 if capath: | |
92 raise error.Abort(_(b'capath not supported')) | |
93 if cadata: | |
94 raise error.Abort(_(b'cadata not supported')) | |
95 | |
96 self._cacerts = cafile | |
97 | |
98 def set_ciphers(self, ciphers): | |
99 self._ciphers = ciphers | |
100 | |
101 def wrap_socket(self, socket, server_hostname=None, server_side=False): | |
102 # server_hostname is unique to SSLContext.wrap_socket and is used | |
103 # for SNI in that context. So there's nothing for us to do with it | |
104 # in this legacy code since we don't support SNI. | |
105 | |
106 args = { | |
107 'keyfile': self._keyfile, | |
108 'certfile': self._certfile, | |
109 'server_side': server_side, | |
110 'cert_reqs': self.verify_mode, | |
111 'ssl_version': self.protocol, | |
112 'ca_certs': self._cacerts, | |
113 'ciphers': self._ciphers, | |
114 } | |
115 | |
116 return ssl.wrap_socket(socket, **args) | |
117 | 57 |
118 | 58 |
119 def _hostsettings(ui, hostname): | 59 def _hostsettings(ui, hostname): |
120 """Obtain security settings for a hostname. | 60 """Obtain security settings for a hostname. |
121 | 61 |
412 # have explicit control over CA loading because implicitly loading | 352 # have explicit control over CA loading because implicitly loading |
413 # CAs may undermine the user's intent. For example, a user may define a CA | 353 # CAs may undermine the user's intent. For example, a user may define a CA |
414 # bundle with a specific CA cert removed. If the system/default CA bundle | 354 # bundle with a specific CA cert removed. If the system/default CA bundle |
415 # is loaded and contains that removed CA, you've just undone the user's | 355 # is loaded and contains that removed CA, you've just undone the user's |
416 # choice. | 356 # choice. |
417 sslcontext = SSLContext(settings[b'protocol']) | 357 sslcontext = ssl.SSLContext(settings[b'protocol']) |
418 | 358 |
419 # This is a no-op unless using modern ssl. | 359 # This is a no-op unless using modern ssl. |
420 sslcontext.options |= settings[b'ctxoptions'] | 360 sslcontext.options |= settings[b'ctxoptions'] |
421 | 361 |
422 # This still works on our fake SSLContext. | 362 # This still works on our fake SSLContext. |
640 | 580 |
641 if modernssl: | 581 if modernssl: |
642 # We /could/ use create_default_context() here since it doesn't load | 582 # We /could/ use create_default_context() here since it doesn't load |
643 # CAs when configured for client auth. However, it is hard-coded to | 583 # CAs when configured for client auth. However, it is hard-coded to |
644 # use ssl.PROTOCOL_SSLv23 which may not be appropriate here. | 584 # use ssl.PROTOCOL_SSLv23 which may not be appropriate here. |
645 sslcontext = SSLContext(protocol) | 585 sslcontext = ssl.SSLContext(protocol) |
646 sslcontext.options |= options | 586 sslcontext.options |= options |
647 | 587 |
648 # Improve forward secrecy. | 588 # Improve forward secrecy. |
649 sslcontext.options |= getattr(ssl, 'OP_SINGLE_DH_USE', 0) | 589 sslcontext.options |= getattr(ssl, 'OP_SINGLE_DH_USE', 0) |
650 sslcontext.options |= getattr(ssl, 'OP_SINGLE_ECDH_USE', 0) | 590 sslcontext.options |= getattr(ssl, 'OP_SINGLE_ECDH_USE', 0) |
652 # Use the list of more secure ciphers if found in the ssl module. | 592 # Use the list of more secure ciphers if found in the ssl module. |
653 if util.safehasattr(ssl, b'_RESTRICTED_SERVER_CIPHERS'): | 593 if util.safehasattr(ssl, b'_RESTRICTED_SERVER_CIPHERS'): |
654 sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0) | 594 sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0) |
655 sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS) | 595 sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS) |
656 else: | 596 else: |
657 sslcontext = SSLContext(ssl.PROTOCOL_TLSv1) | 597 sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1) |
658 | 598 |
659 if requireclientcert: | 599 if requireclientcert: |
660 sslcontext.verify_mode = ssl.CERT_REQUIRED | 600 sslcontext.verify_mode = ssl.CERT_REQUIRED |
661 else: | 601 else: |
662 sslcontext.verify_mode = ssl.CERT_NONE | 602 sslcontext.verify_mode = ssl.CERT_NONE |