From a513b57e5e3667365f77b040e070cbec05212174 Mon Sep 17 00:00:00 2001 From: osirisinferi Date: Wed, 9 Mar 2022 00:00:12 +0100 Subject: Must staple: check for OCSP support (#9226) * Must staple: check for OCSP support * Expand error message * s/Must Staple/Must-Staple * Broaden the term webserver * Improve error message --- certbot/CHANGELOG.md | 4 ++++ certbot/certbot/_internal/main.py | 14 ++++++++++++++ certbot/certbot/configuration.py | 2 +- certbot/certbot/crypto_util.py | 2 +- certbot/tests/main_test.py | 9 +++++++++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index 29ccd5913..76164e6a1 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -13,6 +13,10 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). * Dropped 32 bit support for the Windows beta installer * Windows beta installer is now distributed as "certbot-beta-installer-win_amd64.exe". Users of the Windows beta should uninstall the old version before running this. +* Added a check whether OCSP stapling is supported by the installer when requesting a + certificate with the `run` subcommand in combination with the `--must-staple` option. + If the installer does not support OCSP and the `--must-staple` option is used, Certbot + will raise an error and quit. ### Fixed diff --git a/certbot/certbot/_internal/main.py b/certbot/certbot/_internal/main.py index 9d63be23a..18d819a5c 100644 --- a/certbot/certbot/_internal/main.py +++ b/certbot/certbot/_internal/main.py @@ -1394,6 +1394,20 @@ def run(config: configuration.NamespaceConfig, except errors.PluginSelectionError as e: return str(e) + if config.must_staple and installer and "staple-ocsp" not in installer.supported_enhancements(): + raise errors.NotSupportedError( + "Must-Staple extension requested, but OCSP stapling is not supported by the selected " + f"installer ({config.installer})\n\n" + "You can either:\n" + " * remove the --must-staple option from the command line and obtain a certificate " + "without the Must-Staple extension, or;\n" + " * use the `certonly` subcommand and manually install the certificate into the " + "intended service (e.g. webserver). You must also then manually enable OCSP stapling, " + "as it is required for certificates with the Must-Staple extension to " + "function properly.\n" + " * choose a different installer plugin (such as --nginx or --apache), if possible." + ) + # Preflight check for enhancement support by the selected installer if not enhancements.are_supported(config, installer): raise errors.NotSupportedError("One ore more of the requested enhancements " diff --git a/certbot/certbot/configuration.py b/certbot/certbot/configuration.py index 1a72cbce7..ebeb8e98c 100644 --- a/certbot/certbot/configuration.py +++ b/certbot/certbot/configuration.py @@ -120,7 +120,7 @@ class NamespaceConfig: @property def must_staple(self) -> bool: - """Adds the OCSP Must Staple extension to the certificate. + """Adds the OCSP Must-Staple extension to the certificate. Autoconfigures OCSP Stapling for supported setups (Apache version >= 2.3.3 ). diff --git a/certbot/certbot/crypto_util.py b/certbot/certbot/crypto_util.py index ef86c5e46..f45bf3505 100644 --- a/certbot/certbot/crypto_util.py +++ b/certbot/certbot/crypto_util.py @@ -143,7 +143,7 @@ def generate_csr(privkey: util.Key, names: Union[List[str], Set[str]], path: str :type privkey: :class:`certbot.util.Key` :param set names: `str` names to include in the CSR :param str path: Certificate save directory. - :param bool must_staple: If true, include the TLS Feature extension "OCSP Must Staple" + :param bool must_staple: If true, include the TLS Feature extension "OCSP Must-Staple" :param bool strict_permissions: If true and path exists, an exception is raised if the directory doesn't have 0755 permissions or isn't owned by the current user. diff --git a/certbot/tests/main_test.py b/certbot/tests/main_test.py index d75b6ad58..c29f4d758 100644 --- a/certbot/tests/main_test.py +++ b/certbot/tests/main_test.py @@ -197,6 +197,15 @@ class RunTest(test_util.ConfigTestCase): # The final success message shouldn't be shown self.mock_success_installation.assert_not_called() + @mock.patch('certbot._internal.main.plug_sel.choose_configurator_plugins') + def test_run_must_staple_not_supported(self, mock_choose): + mock_choose.return_value = (null.Installer(self.config, "null"), None) + plugins = disco.PluginsRegistry.find_all() + self.config.must_staple = True + self.assertRaises(errors.NotSupportedError, + main.run, + self.config, plugins) + class CertonlyTest(unittest.TestCase): """Tests for certbot._internal.main.certonly.""" -- cgit v1.2.3