Remove tls-sni challenge in standalone plugin
diff --git a/certbot/plugins/standalone.py b/certbot/plugins/standalone.py
index 16f872a3f43..207eff0b6ca 100644
--- a/certbot/plugins/standalone.py
+++ b/certbot/plugins/standalone.py
@@ -6,7 +6,7 @@
 # https://github.com/python/typeshed/blob/master/stdlib/2and3/socket.pyi
 from socket import errno as socket_errors  # type: ignore
 
-import OpenSSL
+import OpenSSL  # pylint: disable=unused-import
 import six
 import zope.interface
 
@@ -55,25 +55,21 @@ def run(self, port, challenge_type, listenaddr=""):
 
         :param int port: Port to run the server on.
         :param challenge_type: Subclass of `acme.challenges.Challenge`,
-            either `acme.challenge.HTTP01` or `acme.challenges.TLSSNI01`.
+            currently only `acme.challenge.HTTP01`.
         :param str listenaddr: (optional) The address to listen on. Defaults to all addrs.
 
         :returns: DualNetworkedServers instance.
         :rtype: ACMEServerMixin
 
         """
-        assert challenge_type in (challenges.TLSSNI01, challenges.HTTP01)
+        assert challenge_type == challenges.HTTP01
         if port in self._instances:
             return self._instances[port]
 
         address = (listenaddr, port)
         try:
-            if challenge_type is challenges.TLSSNI01:
-                servers = acme_standalone.TLSSNI01DualNetworkedServers(
-                    address, self.certs)  # type: acme_standalone.BaseDualNetworkedServers
-            else:  # challenges.HTTP01
-                servers = acme_standalone.HTTP01DualNetworkedServers(
-                    address, self.http_01_resources)
+            servers = acme_standalone.HTTP01DualNetworkedServers(
+                address, self.http_01_resources)
         except socket.error as error:
             raise errors.StandaloneBindError(error, port)
 
@@ -96,8 +92,6 @@ def stop(self, port):
         for sockname in instance.getsocknames():
             logger.debug("Stopping server at %s:%d...",
                          *sockname[:2])
-        # Not calling server_close causes problems when renewing multiple
-        # certs with `certbot renew` using TLSSNI01 and PyOpenSSL 0.13
         instance.shutdown_and_server_close()
         del self._instances[port]
 
@@ -114,7 +108,7 @@ def running(self):
         return self._instances.copy()
 
 
-SUPPORTED_CHALLENGES = [challenges.HTTP01, challenges.TLSSNI01] \
+SUPPORTED_CHALLENGES = [challenges.HTTP01] \
 # type: List[Type[challenges.KeyAuthorizationChallenge]]
 
 
@@ -132,8 +126,6 @@ def __call__(self, parser, namespace, values, option_string=None):
     def _convert_and_validate(self, data):
         """Validate the value of supported challenges provided by the user.
 
-        References to "dvsni" are automatically converted to "tls-sni-01".
-
         :param str data: comma delimited list of challenge types
 
         :returns: validated and converted list of challenge types
@@ -141,15 +133,6 @@ def _convert_and_validate(self, data):
 
         """
         challs = data.split(",")
-
-        # tls-sni-01 was dvsni during private beta
-        if "dvsni" in challs:
-            logger.info(
-                "Updating legacy standalone_supported_challenges value")
-            challs = [challenges.TLSSNI01.typ if chall == "dvsni" else chall
-                      for chall in challs]
-            data = ",".join(challs)
-
         unrecognized = [name for name in challs
                         if name not in challenges.Challenge.TYPES]
 
@@ -177,7 +160,7 @@ class Authenticator(common.Plugin):
     """Standalone Authenticator.
 
     This authenticator creates its own ephemeral TCP listener on the
-    necessary port in order to respond to incoming tls-sni-01 and http-01
+    necessary port in order to respond to incoming http-01
     challenges from the certificate authority. Therefore, it does not
     rely on any existing server program.
     """
@@ -187,10 +170,6 @@ class Authenticator(common.Plugin):
     def __init__(self, *args, **kwargs):
         super(Authenticator, self).__init__(*args, **kwargs)
 
-        # one self-signed key for all tls-sni-01 certificates
-        self.key = OpenSSL.crypto.PKey()
-        self.key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
-
         self.served = collections.defaultdict(set)  # type: ServedType
 
         # Stuff below is shared across threads (i.e. servers read
@@ -219,9 +198,8 @@ def supported_challenges(self):
     def more_info(self):  # pylint: disable=missing-docstring
         return("This authenticator creates its own ephemeral TCP listener "
                "on the necessary port in order to respond to incoming "
-               "tls-sni-01 and http-01 challenges from the certificate "
-               "authority. Therefore, it does not rely on any existing "
-               "server program.")
+               "http-01 challenges from the certificate authority. Therefore, "
+               "it does not rely on any existing server program.")
 
     def prepare(self):  # pylint: disable=missing-docstring
         pass
@@ -241,10 +219,7 @@ def _try_perform_single(self, achall):
                 _handle_perform_error(error)
 
     def _perform_single(self, achall):
-        if isinstance(achall.chall, challenges.HTTP01):
-            servers, response = self._perform_http_01(achall)
-        else:  # tls-sni-01
-            servers, response = self._perform_tls_sni_01(achall)
+        servers, response = self._perform_http_01(achall)
         self.served[servers].add(achall)
         return response
 
@@ -258,14 +233,6 @@ def _perform_http_01(self, achall):
         self.http_01_resources.add(resource)
         return servers, response
 
-    def _perform_tls_sni_01(self, achall):
-        port = self.config.tls_sni_01_port
-        addr = self.config.tls_sni_01_address
-        servers = self.servers.run(port, challenges.TLSSNI01, listenaddr=addr)
-        response, (cert, _) = achall.response_and_validation(cert_key=self.key)
-        self.certs[response.z_domain] = (self.key, cert)
-        return servers, response
-
     def cleanup(self, achalls):  # pylint: disable=missing-docstring
         # reduce self.served and close servers if no challenges are served
         for unused_servers, server_achalls in self.served.items():
diff --git a/certbot/plugins/standalone_test.py b/certbot/plugins/standalone_test.py
index 9b741fc6fac..db4dbeb3bb9 100644
--- a/certbot/plugins/standalone_test.py
+++ b/certbot/plugins/standalone_test.py
@@ -44,9 +44,6 @@ def _test_run_stop(self, challenge_type):
         self.mgr.stop(port=port)
         self.assertEqual(self.mgr.running(), {})
 
-    def test_run_stop_tls_sni_01(self):
-        self._test_run_stop(challenges.TLSSNI01)
-
     def test_run_stop_http_01(self):
         self._test_run_stop(challenges.HTTP01)
 
@@ -98,10 +95,7 @@ def setUp(self):
         self.parser.add_argument(self.flag, action=SupportedChallengesAction)
 
     def test_correct(self):
-        self.assertEqual("tls-sni-01", self._call("tls-sni-01"))
         self.assertEqual("http-01", self._call("http-01"))
-        self.assertEqual("tls-sni-01,http-01", self._call("tls-sni-01,http-01"))
-        self.assertEqual("http-01,tls-sni-01", self._call("http-01,tls-sni-01"))
 
     def test_unrecognized(self):
         assert "foo" not in challenges.Challenge.TYPES
@@ -110,11 +104,6 @@ def test_unrecognized(self):
     def test_not_subset(self):
         self.assertRaises(SystemExit, self._call, "dns")
 
-    def test_dvsni(self):
-        self.assertEqual("tls-sni-01", self._call("dvsni"))
-        self.assertEqual("http-01,tls-sni-01", self._call("http-01,dvsni"))
-        self.assertEqual("tls-sni-01,http-01", self._call("dvsni,http-01"))
-
 
 def get_open_port():
     """Gets an open port number from the OS."""
@@ -132,31 +121,31 @@ def setUp(self):
         from certbot.plugins.standalone import Authenticator
 
         self.config = mock.MagicMock(
-            tls_sni_01_port=get_open_port(), http01_port=get_open_port(),
-            standalone_supported_challenges="tls-sni-01,http-01")
+            http01_port=get_open_port(),
+            standalone_supported_challenges="http-01")
         self.auth = Authenticator(self.config, name="standalone")
         self.auth.servers = mock.MagicMock()
 
     def test_supported_challenges(self):
         self.assertEqual(self.auth.supported_challenges,
-                         [challenges.TLSSNI01, challenges.HTTP01])
+                         [challenges.HTTP01])
 
     def test_supported_challenges_configured(self):
-        self.config.standalone_supported_challenges = "tls-sni-01"
+        self.config.standalone_supported_challenges = "http-01"
         self.assertEqual(self.auth.supported_challenges,
-                         [challenges.TLSSNI01])
+                         [challenges.HTTP01])
 
     def test_more_info(self):
         self.assertTrue(isinstance(self.auth.more_info(), six.string_types))
 
     def test_get_chall_pref(self):
         self.assertEqual(self.auth.get_chall_pref(domain=None),
-                         [challenges.TLSSNI01, challenges.HTTP01])
+                         [challenges.HTTP01])
 
     def test_get_chall_pref_configured(self):
-        self.config.standalone_supported_challenges = "tls-sni-01"
+        self.config.standalone_supported_challenges = "http-01"
         self.assertEqual(self.auth.get_chall_pref(domain=None),
-                         [challenges.TLSSNI01])
+                         [challenges.HTTP01])
 
     def test_perform(self):
         achalls = self._get_achalls()
@@ -212,10 +201,8 @@ def _get_achalls(cls):
         key = jose.JWK.load(test_util.load_vector('rsa512_key.pem'))
         http_01 = achallenges.KeyAuthorizationAnnotatedChallenge(
             challb=acme_util.HTTP01_P, domain=domain, account_key=key)
-        tls_sni_01 = achallenges.KeyAuthorizationAnnotatedChallenge(
-            challb=acme_util.TLSSNI01_P, domain=domain, account_key=key)
 
-        return [http_01, tls_sni_01]
+        return [http_01]
 
     def test_cleanup(self):
         self.auth.servers.running.return_value = {
@@ -243,5 +230,6 @@ def test_cleanup(self):
             "server1": set(), "server2": set([])})
         self.auth.servers.stop.assert_called_with(2)
 
+
 if __name__ == "__main__":
     unittest.main()  # pragma: no cover

This PR is a part of the tls-sni-01 removal plan described in #6849.

It removes the capability to make tls-sni-01 challenges in the standalone plugin.