Hello community, here is the log from the commit of package python-certbot for openSUSE:Factory checked in at 2020-06-11 15:15:30 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-certbot (Old) and /work/SRC/openSUSE:Factory/.python-certbot.new.3606 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-certbot" Thu Jun 11 15:15:30 2020 rev:27 rq:813507 version:1.5.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-certbot/python-certbot.changes 2020-05-14 23:26:40.705227658 +0200 +++ /work/SRC/openSUSE:Factory/.python-certbot.new.3606/python-certbot.changes 2020-06-11 15:15:31.734966994 +0200 @@ -1,0 +2,8 @@ +Thu Jun 11 12:10:12 UTC 2020 - Marketa Calabkova <[email protected]> + +- Update to version 1.5.0 + * Require explicit confirmation of snap plugin permissions before connecting. + * Add support for OCSP responses which use a public key hash ResponderID, + fixing interoperability with Sectigo CAs. + +------------------------------------------------------------------- Old: ---- certbot-1.4.0.tar.gz New: ---- certbot-1.5.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-certbot.spec ++++++ --- /var/tmp/diff_new_pack.VTEcGq/_old 2020-06-11 15:15:32.294968564 +0200 +++ /var/tmp/diff_new_pack.VTEcGq/_new 2020-06-11 15:15:32.298968575 +0200 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %bcond_without python2 Name: python-certbot -Version: 1.4.0 +Version: 1.5.0 Release: 0 Summary: ACME client License: Apache-2.0 ++++++ certbot-1.4.0.tar.gz -> certbot-1.5.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.4.0/CHANGELOG.md new/certbot-1.5.0/CHANGELOG.md --- old/certbot-1.4.0/CHANGELOG.md 2020-05-05 21:37:33.000000000 +0200 +++ new/certbot-1.5.0/CHANGELOG.md 2020-06-02 19:12:32.000000000 +0200 @@ -2,6 +2,24 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). +## 1.5.0 - 2020-06-02 + +### Added + +* Require explicit confirmation of snap plugin permissions before connecting. + +### Changed + +* Improved error message in apache installer when mod_ssl is not available. + +### Fixed + +* Add support for OCSP responses which use a public key hash ResponderID, fixing + interoperability with Sectigo CAs. +* Fix TLS-ALPN test that fails when run with newer versions of OpenSSL. + +More details about these changes can be found on our GitHub repo. + ## 1.4.0 - 2020-05-05 ### Added @@ -24,6 +42,7 @@ * Stop asking interactively if the user would like to add a redirect. * `mock` dependency is now conditional on Python 2 in all of our packages. * Deprecate certbot-auto on Gentoo, macOS, and FreeBSD. +* Allow existing but empty archive and live dir to be used when creating new lineage. ### Fixed diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.4.0/PKG-INFO new/certbot-1.5.0/PKG-INFO --- old/certbot-1.4.0/PKG-INFO 2020-05-05 21:37:35.039927000 +0200 +++ new/certbot-1.5.0/PKG-INFO 2020-06-02 19:12:36.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: certbot -Version: 1.4.0 +Version: 1.5.0 Summary: ACME client Home-page: https://github.com/letsencrypt/letsencrypt Author: Certbot Project @@ -79,16 +79,12 @@ ACME working area in github: https://github.com/ietf-wg-acme/acme - |build-status| |container| + |build-status| .. |build-status| image:: https://travis-ci.com/certbot/certbot.svg?branch=master :target: https://travis-ci.com/certbot/certbot :alt: Travis CI status - .. |container| image:: https://quay.io/repository/letsencrypt/letsencrypt/status - :target: https://quay.io/repository/letsencrypt/letsencrypt - :alt: Docker Repository on Quay.io - .. Do not modify this comment unless you know what you're doing. tag:links-end System Requirements diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.4.0/README.rst new/certbot-1.5.0/README.rst --- old/certbot-1.4.0/README.rst 2020-05-05 21:37:33.000000000 +0200 +++ new/certbot-1.5.0/README.rst 2020-06-02 19:12:32.000000000 +0200 @@ -71,16 +71,12 @@ ACME working area in github: https://github.com/ietf-wg-acme/acme -|build-status| |container| +|build-status| .. |build-status| image:: https://travis-ci.com/certbot/certbot.svg?branch=master :target: https://travis-ci.com/certbot/certbot :alt: Travis CI status -.. |container| image:: https://quay.io/repository/letsencrypt/letsencrypt/status - :target: https://quay.io/repository/letsencrypt/letsencrypt - :alt: Docker Repository on Quay.io - .. Do not modify this comment unless you know what you're doing. tag:links-end System Requirements diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.4.0/certbot/__init__.py new/certbot-1.5.0/certbot/__init__.py --- old/certbot-1.4.0/certbot/__init__.py 2020-05-05 21:37:34.000000000 +0200 +++ new/certbot-1.5.0/certbot/__init__.py 2020-06-02 19:12:35.000000000 +0200 @@ -1,4 +1,4 @@ """Certbot client.""" # version number like 1.2.3a0, must have at least 2 parts, like 1.2 -__version__ = '1.4.0' +__version__ = '1.5.0' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.4.0/certbot/_internal/log.py new/certbot-1.5.0/certbot/_internal/log.py --- old/certbot-1.4.0/certbot/_internal/log.py 2020-05-05 21:37:33.000000000 +0200 +++ new/certbot-1.5.0/certbot/_internal/log.py 2020-06-02 19:12:32.000000000 +0200 @@ -322,15 +322,23 @@ logger.error('Exiting abnormally:', exc_info=exc_info) else: logger.debug('Exiting abnormally:', exc_info=exc_info) + # Use logger to print the error message to take advantage of + # our logger printing warnings and errors in red text. if issubclass(exc_type, errors.Error): - sys.exit(exc_value) + logger.error(str(exc_value)) + sys.exit(1) logger.error('An unexpected error occurred:') if messages.is_acme_error(exc_value): # Remove the ACME error prefix from the exception _, _, exc_str = str(exc_value).partition(':: ') logger.error(exc_str) else: - traceback.print_exception(exc_type, exc_value, None) + output = traceback.format_exception_only(exc_type, exc_value) + # format_exception_only returns a list of strings each + # terminated by a newline. We combine them into one string + # and remove the final newline before passing it to + # logger.error. + logger.error(''.join(output).rstrip()) exit_with_log_path(log_path) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.4.0/certbot/_internal/storage.py new/certbot-1.5.0/certbot/_internal/storage.py --- old/certbot-1.4.0/certbot/_internal/storage.py 2020-05-05 21:37:33.000000000 +0200 +++ new/certbot-1.5.0/certbot/_internal/storage.py 2020-06-02 19:12:32.000000000 +0200 @@ -1007,18 +1007,18 @@ lineagename = lineagename_for_filename(config_filename) archive = full_archive_path(None, cli_config, lineagename) live_dir = _full_live_path(cli_config, lineagename) - if os.path.exists(archive): + if os.path.exists(archive) and (not os.path.isdir(archive) or os.listdir(archive)): config_file.close() raise errors.CertStorageError( "archive directory exists for " + lineagename) - if os.path.exists(live_dir): + if os.path.exists(live_dir) and (not os.path.isdir(live_dir) or os.listdir(live_dir)): config_file.close() raise errors.CertStorageError( "live directory exists for " + lineagename) - filesystem.mkdir(archive) - filesystem.mkdir(live_dir) - logger.debug("Archive directory %s and live " - "directory %s created.", archive, live_dir) + for i in (archive, live_dir): + if not os.path.exists(i): + filesystem.makedirs(i) + logger.debug("Creating directory %s.", i) # Put the data into the appropriate files on disk target = {kind: os.path.join(live_dir, kind + ".pem") for kind in ALL_FOUR} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.4.0/certbot/compat/filesystem.py new/certbot-1.5.0/certbot/compat/filesystem.py --- old/certbot-1.4.0/certbot/compat/filesystem.py 2020-05-05 21:37:33.000000000 +0200 +++ new/certbot-1.5.0/certbot/compat/filesystem.py 2020-06-02 19:12:32.000000000 +0200 @@ -78,6 +78,35 @@ chmod(dst, mode) +# Quite similar to copy_ownership_and_apply_mode, but this time the DACL is copied from +# the source file on Windows. The DACL stays consistent with the dynamic rights of the +# equivalent POSIX mode, because ownership and mode are copied altogether on the destination +# file, so no recomputing of the DACL against the new owner is needed, as it would be +# for a copy_ownership alone method. +def copy_ownership_and_mode(src, dst, copy_user=True, copy_group=True): + # type: (str, str, bool, bool) -> None + """ + Copy ownership (user and optionally group on Linux) and mode/DACL + from the source to the destination. + :param str src: Path of the source file + :param str dst: Path of the destination file + :param bool copy_user: Copy user if `True` + :param bool copy_group: Copy group if `True` on Linux (has no effect on Windows) + """ + if POSIX_MODE: + # On Linux, we just delegate to chown and chmod. + stats = os.stat(src) + user_id = stats.st_uid if copy_user else -1 + group_id = stats.st_gid if copy_group else -1 + os.chown(dst, user_id, group_id) + chmod(dst, stats.st_mode) + else: + if copy_user: + # There is no group handling in Windows + _copy_win_ownership(src, dst) + _copy_win_mode(src, dst) + + def check_mode(file_path, mode): # type: (str, int) -> bool """ @@ -208,8 +237,19 @@ will be applied if ``None`` """ if POSIX_MODE: - return os.makedirs(file_path, mode) + # Since Python 3.7, os.makedirs does not set the given mode to the intermediate directories + # that could be created in the process. To keep things safe and consistent on all + # Python versions, we set the umask accordingly to have all directories (intermediate and + # leaf) created with the given mode. + current_umask = os.umask(0) + try: + os.umask(current_umask | 0o777 ^ mode) + return os.makedirs(file_path, mode) + finally: + os.umask(current_umask) + # TODO: Windows does not support umask. A specific PR (#7967) is handling this, and will need + # to add appropriate umask call for the Windows part of the logic below. orig_mkdir_fn = os.mkdir try: # As we know that os.mkdir is called internally by os.makedirs, we will swap the function in @@ -515,6 +555,9 @@ def _copy_win_ownership(src, dst): + # Resolve symbolic links + src = realpath(src) + security_src = win32security.GetFileSecurity(src, win32security.OWNER_SECURITY_INFORMATION) user_src = security_src.GetSecurityDescriptorOwner() @@ -526,6 +569,19 @@ win32security.SetFileSecurity(dst, win32security.OWNER_SECURITY_INFORMATION, security_dst) +def _copy_win_mode(src, dst): + # Resolve symbolic links + src = realpath(src) + + # Copy the DACL from src to dst. + security_src = win32security.GetFileSecurity(src, win32security.DACL_SECURITY_INFORMATION) + dacl = security_src.GetSecurityDescriptorDacl() + + security_dst = win32security.GetFileSecurity(dst, win32security.DACL_SECURITY_INFORMATION) + security_dst.SetSecurityDescriptorDacl(1, dacl, 0) + win32security.SetFileSecurity(dst, win32security.DACL_SECURITY_INFORMATION, security_dst) + + def _generate_windows_flags(rights_desc): # Some notes about how each POSIX right is interpreted. # diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.4.0/certbot/ocsp.py new/certbot-1.5.0/certbot/ocsp.py --- old/certbot-1.4.0/certbot/ocsp.py 2020-05-05 21:37:33.000000000 +0200 +++ new/certbot-1.5.0/certbot/ocsp.py 2020-06-02 19:12:32.000000000 +0200 @@ -256,7 +256,11 @@ def _check_ocsp_response_signature(response_ocsp, issuer_cert, cert_path): """Verify an OCSP response signature against certificate issuer or responder""" - if response_ocsp.responder_name == issuer_cert.subject: + def _key_hash(cert): + return x509.SubjectKeyIdentifier.from_public_key(cert.public_key()).digest + + if response_ocsp.responder_name == issuer_cert.subject or \ + response_ocsp.responder_key_hash == _key_hash(issuer_cert): # Case where the OCSP responder is also the certificate issuer logger.debug('OCSP response for certificate %s is signed by the certificate\'s issuer.', cert_path) @@ -267,7 +271,8 @@ cert_path) responder_certs = [cert for cert in response_ocsp.certificates - if cert.subject == response_ocsp.responder_name] + if response_ocsp.responder_name == cert.subject or \ + response_ocsp.responder_key_hash == _key_hash(cert)] if not responder_certs: raise AssertionError('no matching responder certificate could be found') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.4.0/certbot.egg-info/PKG-INFO new/certbot-1.5.0/certbot.egg-info/PKG-INFO --- old/certbot-1.4.0/certbot.egg-info/PKG-INFO 2020-05-05 21:37:34.000000000 +0200 +++ new/certbot-1.5.0/certbot.egg-info/PKG-INFO 2020-06-02 19:12:36.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: certbot -Version: 1.4.0 +Version: 1.5.0 Summary: ACME client Home-page: https://github.com/letsencrypt/letsencrypt Author: Certbot Project @@ -79,16 +79,12 @@ ACME working area in github: https://github.com/ietf-wg-acme/acme - |build-status| |container| + |build-status| .. |build-status| image:: https://travis-ci.com/certbot/certbot.svg?branch=master :target: https://travis-ci.com/certbot/certbot :alt: Travis CI status - .. |container| image:: https://quay.io/repository/letsencrypt/letsencrypt/status - :target: https://quay.io/repository/letsencrypt/letsencrypt - :alt: Docker Repository on Quay.io - .. Do not modify this comment unless you know what you're doing. tag:links-end System Requirements diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.4.0/docs/cli-help.txt new/certbot-1.5.0/docs/cli-help.txt --- old/certbot-1.4.0/docs/cli-help.txt 2020-05-05 21:37:33.000000000 +0200 +++ new/certbot-1.5.0/docs/cli-help.txt 2020-06-02 19:12:32.000000000 +0200 @@ -113,7 +113,7 @@ case, and to know when to deprecate support for past Python versions and flags. If you wish to hide this information from the Let's Encrypt server, set this to - "". (default: CertbotACMEClient/1.3.0 (certbot(-auto); + "". (default: CertbotACMEClient/1.4.0 (certbot(-auto); OS_NAME OS_VERSION) Authenticator/XXX Installer/YYY (SUBCOMMAND; flags: FLAGS) Py/major.minor.patchlevel). The flags encoded in the user agent are: --duplicate, @@ -188,10 +188,12 @@ supported setups (Apache version >= 2.3.3 ). (default: False) --redirect Automatically redirect all HTTP traffic to HTTPS for - the newly authenticated vhost. (default: Ask) + the newly authenticated vhost. (default: redirect + enabled for install and run, disabled for enhance) --no-redirect Do not automatically redirect all HTTP traffic to HTTPS for the newly authenticated vhost. (default: - Ask) + redirect enabled for install and run, disabled for + enhance) --hsts Add the Strict-Transport-Security header to every HTTP response. Forcing browser to always use SSL for the domain. Defends against SSL Stripping. (default: None) @@ -213,8 +215,8 @@ --test-cert, --staging Use the staging server to obtain or revoke test - (invalid) certificates; equivalent to --server https - ://acme-staging-v02.api.letsencrypt.org/directory + (invalid) certificates; equivalent to --server + https://acme-staging-v02.api.letsencrypt.org/directory (default: False) --debug Show tracebacks in case of errors, and allow certbot- auto execution on experimental platforms (default: @@ -319,8 +321,8 @@ of renewed certificate domains (for example, "example.com www.example.com" (default: None) --disable-hook-validation - Ordinarily the commands specified for --pre-hook - /--post-hook/--deploy-hook will be checked for + Ordinarily the commands specified for --pre- + hook/--post-hook/--deploy-hook will be checked for validity, to see if the programs being run are in the $PATH, so that mistakes can be caught early, even when the hooks aren't being run just yet. The validation is @@ -669,7 +671,11 @@ requested when performing an HTTP-01 challenge. An additional cleanup script can also be provided and can use the additional variable $CERTBOT_AUTH_OUTPUT which contains the stdout output from the auth - script. + script.For both authenticator and cleanup script, on HTTP-01 and DNS-01 + challenges,$CERTBOT_REMAINING_CHALLENGES will be equal to the number of + challenges that remain after the current one, and $CERTBOT_ALL_DOMAINS + contains a comma-separated list of all domains that are challenged for the + current certificate. --manual-auth-hook MANUAL_AUTH_HOOK Path or command to execute for the authentication diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.4.0/tests/compat/filesystem_test.py new/certbot-1.5.0/tests/compat/filesystem_test.py --- old/certbot-1.4.0/tests/compat/filesystem_test.py 2020-05-05 21:37:33.000000000 +0200 +++ new/certbot-1.5.0/tests/compat/filesystem_test.py 2020-06-02 19:12:32.000000000 +0200 @@ -1,6 +1,7 @@ """Tests for certbot.compat.filesystem""" import contextlib import errno +import stat import unittest try: @@ -280,14 +281,34 @@ self.assertEqual(original_mkdir, std_os.mkdir) -class OwnershipTest(test_util.TempDirTestCase): - """Tests about copy_ownership_and_apply_mode and has_same_ownership""" +# TODO: This test can be used both by Linux and Windows once on #7967 [email protected](POSIX_MODE, reason='Needs umask to succeed, and Windows does not have it') +class LinuxMkdirTests(test_util.TempDirTestCase): + """Unit tests for Linux mkdir + makedirs functions in filesystem module""" + def test_makedirs_correct_permissions(self): + path = os.path.join(self.tempdir, 'dir') + subpath = os.path.join(path, 'subpath') + + previous_umask = os.umask(0o022) + + try: + filesystem.makedirs(subpath, 0o700) + + import os as std_os # pylint: disable=os-module-forbidden + assert stat.S_IMODE(std_os.stat(path).st_mode) == 0o700 + assert stat.S_IMODE(std_os.stat(subpath).st_mode) == 0o700 + finally: + os.umask(previous_umask) + + +class CopyOwnershipAndModeTest(test_util.TempDirTestCase): + """Tests about copy_ownership_and_apply_mode, copy_ownership_and_mode and has_same_ownership""" def setUp(self): - super(OwnershipTest, self).setUp() + super(CopyOwnershipAndModeTest, self).setUp() self.probe_path = _create_probe(self.tempdir) @unittest.skipIf(POSIX_MODE, reason='Test specific to Windows security') - def test_copy_ownership_windows(self): + def test_copy_ownership_and_apply_mode_windows(self): system = win32security.ConvertStringSidToSid(SYSTEM_SID) security = win32security.SECURITY_ATTRIBUTES().SECURITY_DESCRIPTOR security.SetSecurityDescriptorOwner(system, False) @@ -313,7 +334,7 @@ if dacl.GetAce(index)[2] == everybody]) @unittest.skipUnless(POSIX_MODE, reason='Test specific to Linux security') - def test_copy_ownership_linux(self): + def test_copy_ownership_and_apply_mode_linux(self): with mock.patch('os.chown') as mock_chown: with mock.patch('os.chmod') as mock_chmod: with mock.patch('os.stat') as mock_stat: @@ -334,6 +355,24 @@ self.assertTrue(filesystem.has_same_ownership(path1, path2)) + @unittest.skipIf(POSIX_MODE, reason='Test specific to Windows security') + def test_copy_ownership_and_mode_windows(self): + src = self.probe_path + dst = _create_probe(self.tempdir, name='dst') + + filesystem.chmod(src, 0o700) + self.assertTrue(filesystem.check_mode(src, 0o700)) + self.assertTrue(filesystem.check_mode(dst, 0o744)) + + # Checking an actual change of owner is tricky during a unit test, since we do not know + # if any user exists beside the current one. So we mock _copy_win_ownership. It's behavior + # have been checked theoretically with test_copy_ownership_and_apply_mode_windows. + with mock.patch('certbot.compat.filesystem._copy_win_ownership') as mock_copy_owner: + filesystem.copy_ownership_and_mode(src, dst) + + mock_copy_owner.assert_called_once_with(src, dst) + self.assertTrue(filesystem.check_mode(dst, 0o700)) + class CheckPermissionsTest(test_util.TempDirTestCase): """Tests relative to functions that check modes.""" @@ -537,9 +576,9 @@ target, win32security.OWNER_SECURITY_INFORMATION, security_owner) -def _create_probe(tempdir): +def _create_probe(tempdir, name='probe'): filesystem.chmod(tempdir, 0o744) - probe_path = os.path.join(tempdir, 'probe') + probe_path = os.path.join(tempdir, name) util.safe_open(probe_path, 'w', chmod=0o744).close() return probe_path diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.4.0/tests/ocsp_test.py new/certbot-1.5.0/tests/ocsp_test.py --- old/certbot-1.4.0/tests/ocsp_test.py 2020-05-05 21:37:33.000000000 +0200 +++ new/certbot-1.5.0/tests/ocsp_test.py 2020-06-02 19:12:32.000000000 +0200 @@ -182,13 +182,23 @@ with _ocsp_mock(ocsp_lib.OCSPCertStatus.REVOKED, ocsp_lib.OCSPResponseStatus.SUCCESSFUL) as mocks: + # OCSP response with ResponseID as Name mocks['mock_response'].return_value.responder_name = issuer.subject + mocks['mock_response'].return_value.responder_key_hash = None self.checker.ocsp_revoked(self.cert_obj) + # OCSP response with ResponseID as KeyHash + key_hash = x509.SubjectKeyIdentifier.from_public_key(issuer.public_key()).digest + mocks['mock_response'].return_value.responder_name = None + mocks['mock_response'].return_value.responder_key_hash = key_hash + self.checker.ocsp_revoked(self.cert_obj) + # Here responder and issuer are the same. So only the signature of the OCSP # response is checked (using the issuer/responder public key). - self.assertEqual(mocks['mock_check'].call_count, 1) - self.assertEqual(mocks['mock_check'].call_args[0][0].public_numbers(), - issuer.public_key().public_numbers()) + self.assertEqual(mocks['mock_check'].call_count, 2) + self.assertEqual(mocks['mock_check'].call_args_list[0][0][0].public_numbers(), + issuer.public_key().public_numbers()) + self.assertEqual(mocks['mock_check'].call_args_list[1][0][0].public_numbers(), + issuer.public_key().public_numbers()) def test_responder_is_authorized_delegate(self): issuer = x509.load_pem_x509_certificate( @@ -198,15 +208,28 @@ with _ocsp_mock(ocsp_lib.OCSPCertStatus.REVOKED, ocsp_lib.OCSPResponseStatus.SUCCESSFUL) as mocks: + # OCSP response with ResponseID as Name + mocks['mock_response'].return_value.responder_name = responder.subject + mocks['mock_response'].return_value.responder_key_hash = None self.checker.ocsp_revoked(self.cert_obj) + # OCSP response with ResponseID as KeyHash + key_hash = x509.SubjectKeyIdentifier.from_public_key(responder.public_key()).digest + mocks['mock_response'].return_value.responder_name = None + mocks['mock_response'].return_value.responder_key_hash = key_hash + self.checker.ocsp_revoked(self.cert_obj) + # Here responder and issuer are not the same. Two signatures will be checked then, # first to verify the responder cert (using the issuer public key), second to # to verify the OCSP response itself (using the responder public key). - self.assertEqual(mocks['mock_check'].call_count, 2) + self.assertEqual(mocks['mock_check'].call_count, 4) self.assertEqual(mocks['mock_check'].call_args_list[0][0][0].public_numbers(), issuer.public_key().public_numbers()) self.assertEqual(mocks['mock_check'].call_args_list[1][0][0].public_numbers(), responder.public_key().public_numbers()) + self.assertEqual(mocks['mock_check'].call_args_list[2][0][0].public_numbers(), + issuer.public_key().public_numbers()) + self.assertEqual(mocks['mock_check'].call_args_list[3][0][0].public_numbers(), + responder.public_key().public_numbers()) def test_revoke_resiliency(self): # Server return an invalid HTTP response diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.4.0/tests/storage_test.py new/certbot-1.5.0/tests/storage_test.py --- old/certbot-1.4.0/tests/storage_test.py 2020-05-05 21:37:33.000000000 +0200 +++ new/certbot-1.5.0/tests/storage_test.py 2020-06-02 19:12:32.000000000 +0200 @@ -610,17 +610,25 @@ self.config.renewal_configs_dir, "the-lineage.com-0001.conf"))) self.assertTrue(os.path.exists(os.path.join( self.config.live_dir, "the-lineage.com-0001", "README"))) + # Allow write to existing but empty dir + filesystem.mkdir(os.path.join(self.config.default_archive_dir, "the-lineage.com-0002")) + result = storage.RenewableCert.new_lineage( + "the-lineage.com", b"cert3", b"privkey3", b"chain3", self.config) + self.assertTrue(os.path.exists(os.path.join( + self.config.live_dir, "the-lineage.com-0002", "README"))) + self.assertTrue(filesystem.check_mode(result.key_path, 0o600)) # Now trigger the detection of already existing files - filesystem.mkdir(os.path.join( - self.config.live_dir, "the-lineage.com-0002")) + shutil.copytree(os.path.join(self.config.live_dir, "the-lineage.com"), + os.path.join(self.config.live_dir, "the-lineage.com-0003")) self.assertRaises(errors.CertStorageError, storage.RenewableCert.new_lineage, "the-lineage.com", - b"cert3", b"privkey3", b"chain3", self.config) - filesystem.mkdir(os.path.join(self.config.default_archive_dir, "other-example.com")) + b"cert4", b"privkey4", b"chain4", self.config) + shutil.copytree(os.path.join(self.config.live_dir, "the-lineage.com"), + os.path.join(self.config.live_dir, "other-example.com")) self.assertRaises(errors.CertStorageError, storage.RenewableCert.new_lineage, - "other-example.com", b"cert4", - b"privkey4", b"chain4", self.config) + "other-example.com", b"cert5", + b"privkey5", b"chain5", self.config) # Make sure it can accept renewal parameters result = storage.RenewableCert.new_lineage( "the-lineage.com", b"cert2", b"privkey2", b"chain2", self.config)
