Patchwork [03,of,15] sslutil: remove code checking for presence of ssl.SSLContext

login
register
mail settings
Submitter Manuel Jacob
Date May 30, 2020, 5:52 a.m.
Message ID <4b0fc7112e0c75ae290e.1590817935@tmp>
Download mbox | patch
Permalink /patch/46398/
State New
Headers show

Comments

Manuel Jacob - May 30, 2020, 5:52 a.m.
# HG changeset patch
# User Manuel Jacob <me@manueljacob.de>
# Date 1590779902 -7200
#      Fri May 29 21:18:22 2020 +0200
# Node ID 4b0fc7112e0c75ae290e9204bd9efdca841244df
# Parent  c8a697e466dec7726cf0e5d30dafcc37f13196f0
# EXP-Topic require_modern_ssl
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.

Patch

diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py
--- a/mercurial/sslutil.py
+++ b/mercurial/sslutil.py
@@ -33,9 +33,8 @@  from .utils import (
 # support for TLS 1.1, TLS 1.2, SNI, system CA stores, etc. These features are
 # all exposed via the "ssl" module.
 #
-# Depending on the version of Python being used, SSL/TLS support is either
-# modern/secure or legacy/insecure. Many operations in this module have
-# separate code paths depending on support in Python.
+# We require in setup.py the presence of ssl.SSLContext, which indicates modern
+# SSL/TLS support.
 
 configprotocols = {
     b'tls1.0',
@@ -53,67 +52,8 @@  if util.safehasattr(ssl, b'PROTOCOL_TLSv
 if util.safehasattr(ssl, b'PROTOCOL_TLSv1_2'):
     supportedprotocols.add(b'tls1.2')
 
-try:
-    # ssl.SSLContext was added in 2.7.9 and presence indicates modern
-    # SSL/TLS features are available.
-    SSLContext = ssl.SSLContext
-    modernssl = True
-    _canloaddefaultcerts = True
-except AttributeError:
-    modernssl = False
-    _canloaddefaultcerts = False
-
-    # We implement SSLContext using the interface from the standard library.
-    class SSLContext(object):
-        def __init__(self, protocol):
-            # From the public interface of SSLContext
-            self.protocol = protocol
-            self.check_hostname = False
-            self.options = 0
-            self.verify_mode = ssl.CERT_NONE
-
-            # Used by our implementation.
-            self._certfile = None
-            self._keyfile = None
-            self._certpassword = None
-            self._cacerts = None
-            self._ciphers = None
-
-        def load_cert_chain(self, certfile, keyfile=None, password=None):
-            self._certfile = certfile
-            self._keyfile = keyfile
-            self._certpassword = password
-
-        def load_default_certs(self, purpose=None):
-            pass
-
-        def load_verify_locations(self, cafile=None, capath=None, cadata=None):
-            if capath:
-                raise error.Abort(_(b'capath not supported'))
-            if cadata:
-                raise error.Abort(_(b'cadata not supported'))
-
-            self._cacerts = cafile
-
-        def set_ciphers(self, ciphers):
-            self._ciphers = ciphers
-
-        def wrap_socket(self, socket, server_hostname=None, server_side=False):
-            # server_hostname is unique to SSLContext.wrap_socket and is used
-            # for SNI in that context. So there's nothing for us to do with it
-            # in this legacy code since we don't support SNI.
-
-            args = {
-                'keyfile': self._keyfile,
-                'certfile': self._certfile,
-                'server_side': server_side,
-                'cert_reqs': self.verify_mode,
-                'ssl_version': self.protocol,
-                'ca_certs': self._cacerts,
-                'ciphers': self._ciphers,
-            }
-
-            return ssl.wrap_socket(socket, **args)
+modernssl = True
+_canloaddefaultcerts = True
 
 
 def _hostsettings(ui, hostname):
@@ -414,7 +354,7 @@  def wrapsocket(sock, keyfile, certfile, 
     # bundle with a specific CA cert removed. If the system/default CA bundle
     # is loaded and contains that removed CA, you've just undone the user's
     # choice.
-    sslcontext = SSLContext(settings[b'protocol'])
+    sslcontext = ssl.SSLContext(settings[b'protocol'])
 
     # This is a no-op unless using modern ssl.
     sslcontext.options |= settings[b'ctxoptions']
@@ -642,7 +582,7 @@  def wrapserversocket(
         # We /could/ use create_default_context() here since it doesn't load
         # CAs when configured for client auth. However, it is hard-coded to
         # use ssl.PROTOCOL_SSLv23 which may not be appropriate here.
-        sslcontext = SSLContext(protocol)
+        sslcontext = ssl.SSLContext(protocol)
         sslcontext.options |= options
 
         # Improve forward secrecy.
@@ -654,7 +594,7 @@  def wrapserversocket(
             sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0)
             sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS)
     else:
-        sslcontext = SSLContext(ssl.PROTOCOL_TLSv1)
+        sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 
     if requireclientcert:
         sslcontext.verify_mode = ssl.CERT_REQUIRED