def test_perform(self, mock_restart, mock_dvsni_perform): # Only tests functionality specific to configurator.perform # Note: As more challenges are offered this will have to be expanded auth_key = le_util.Key(self.rsa256_file, self.rsa256_pem) achall1 = achallenges.DVSNI(challb=messages.ChallengeBody( chall=challenges.DVSNI(r="foo", nonce="bar"), uri="https://ca.org/chall0_uri", status=messages.Status("pending"), ), domain="localhost", key=auth_key) achall2 = achallenges.DVSNI(challb=messages.ChallengeBody( chall=challenges.DVSNI(r="abc", nonce="def"), uri="https://ca.org/chall1_uri", status=messages.Status("pending"), ), domain="example.com", key=auth_key) dvsni_ret_val = [ challenges.DVSNIResponse(s="irrelevant"), challenges.DVSNIResponse(s="arbitrary"), ] mock_dvsni_perform.return_value = dvsni_ret_val responses = self.config.perform([achall1, achall2]) self.assertEqual(mock_dvsni_perform.call_count, 1) self.assertEqual(responses, dvsni_ret_val) self.assertEqual(mock_restart.call_count, 1)
def test_perform(self, mock_restart, mock_dvsni_perform): # Only tests functionality specific to configurator.perform # Note: As more challenges are offered this will have to be expanded auth_key = le_util.Key(self.rsa256_file, self.rsa256_pem) achall1 = achallenges.DVSNI( challb=acme_util.chall_to_challb( challenges.DVSNI( r="jIq_Xy1mXGN37tb4L6Xj_es58fW571ZNyXekdZzhh7Q", nonce="37bc5eb75d3e00a19b4f6355845e5a18"), "pending"), domain="encryption-example.demo", key=auth_key) achall2 = achallenges.DVSNI( challb=acme_util.chall_to_challb( challenges.DVSNI( r="uqnaPzxtrndteOqtrXb0Asl5gOJfWAnnx6QJyvcmlDU", nonce="59ed014cac95f77057b1d7a1b2c596ba"), "pending"), domain="letsencrypt.demo", key=auth_key) dvsni_ret_val = [ challenges.DVSNIResponse(s="randomS1"), challenges.DVSNIResponse(s="randomS2"), ] mock_dvsni_perform.return_value = dvsni_ret_val responses = self.config.perform([achall1, achall2]) self.assertEqual(mock_dvsni_perform.call_count, 1) self.assertEqual(responses, dvsni_ret_val) self.assertEqual(mock_restart.call_count, 1)
def _from_config_fp(cls, config, config_fp): try: acc_config = configobj.ConfigObj(infile=config_fp, file_error=True, create_empty=False) except IOError: raise errors.LetsEncryptClientError( "Account for %s does not exist" % os.path.basename(config_fp)) if os.path.basename(config_fp) != "default": email = os.path.basename(config_fp) else: email = None phone = acc_config["phone"] if acc_config["phone"] != "None" else None with open(acc_config["key"]) as key_file: key = le_util.Key(acc_config["key"], key_file.read()) if "RegistrationResource" in acc_config: acc_config_rr = acc_config["RegistrationResource"] regr = messages2.RegistrationResource( uri=acc_config_rr["uri"], new_authzr_uri=acc_config_rr["new_authzr_uri"], terms_of_service=acc_config_rr["terms_of_service"], body=messages2.Registration.from_json(acc_config_rr["body"])) else: regr = None return cls(config, key, email, phone, regr)
def setUp(self): from letsencrypt.account import Account logging.disable(logging.CRITICAL) self.accounts_dir = tempfile.mkdtemp("accounts") self.account_keys_dir = os.path.join(self.accounts_dir, "keys") os.makedirs(self.account_keys_dir, 0o700) self.config = mock.MagicMock( spec=configuration.NamespaceConfig, accounts_dir=self.accounts_dir, account_keys_dir=self.account_keys_dir, rsa_key_size=2048, server="letsencrypt-demo.org") key_file = pkg_resources.resource_filename( "acme.jose", os.path.join("testdata", "rsa512_key.pem")) key_pem = pkg_resources.resource_string( "acme.jose", os.path.join("testdata", "rsa512_key.pem")) self.key = le_util.Key(key_file, key_pem) self.email = "*****@*****.**" self.regr = messages2.RegistrationResource( uri="uri", new_authzr_uri="new_authzr_uri", terms_of_service="terms_of_service", body=messages2.Registration( recovery_token="recovery_token", agreement="agreement") ) self.test_account = Account( self.config, self.key, self.email, None, self.regr)
def init_save_key(key_size, key_dir, keyname="key-letsencrypt.pem"): """Initializes and saves a privkey. Inits key and saves it in PEM format on the filesystem. .. note:: keyname is the attempted filename, it may be different if a file already exists at the path. :param int key_size: RSA key size in bits :param str key_dir: Key save directory. :param str keyname: Filename of key :returns: Key :rtype: :class:`letsencrypt.le_util.Key` :raises ValueError: If unable to generate the key given key_size. """ try: key_pem = make_key(key_size) except ValueError as err: logger.exception(err) raise err # Save file le_util.make_or_verify_dir(key_dir, 0o700, os.geteuid()) key_f, key_path = le_util.unique_file(os.path.join(key_dir, keyname), 0o600) key_f.write(key_pem) key_f.close() logger.info("Generating key (%d bits): %s", key_size, key_path) return le_util.Key(key_path, key_pem)
class DvsniTest(unittest.TestCase): """Tests for letsencrypt.plugins.common.DvsniTest.""" rsa256_file = pkg_resources.resource_filename( "acme.jose", "testdata/rsa256_key.pem") rsa256_pem = pkg_resources.resource_string( "acme.jose", "testdata/rsa256_key.pem") auth_key = le_util.Key(rsa256_file, rsa256_pem) achalls = [ achallenges.DVSNI( challb=acme_util.chall_to_challb( challenges.DVSNI( r="\x8c\x8a\xbf_-f\\cw\xee\xd6\xf8/\xa5\xe3\xfd\xeb9" "\xf1\xf5\xb9\xefVM\xc9w\xa4u\x9c\xe1\x87\xb4", nonce="7\xbc^\xb7]>\x00\xa1\x9bOcU\x84^Z\x18", ), "pending"), domain="encryption-example.demo", key=auth_key), achallenges.DVSNI( challb=acme_util.chall_to_challb( challenges.DVSNI( r="\xba\xa9\xda?<m\xaewmx\xea\xad\xadv\xf4\x02\xc9y\x80" "\xe2_X\t\xe7\xc7\xa4\t\xca\xf7&\x945", nonce="Y\xed\x01L\xac\x95\xf7pW\xb1\xd7\xa1\xb2\xc5" "\x96\xba", ), "pending"), domain="letsencrypt.demo", key=auth_key), ] def setUp(self): from letsencrypt.plugins.common import Dvsni self.sni = Dvsni(configurator=mock.MagicMock()) def test_setup_challenge_cert(self): # This is a helper function that can be used for handling # open context managers more elegantly. It avoids dealing with # __enter__ and __exit__ calls. # http://www.voidspace.org.uk/python/mock/helpers.html#mock.mock_open m_open = mock.mock_open() response = challenges.DVSNIResponse(s="randomS1") achall = mock.MagicMock(nonce=self.achalls[0].nonce, nonce_domain=self.achalls[0].nonce_domain) achall.gen_cert_and_response.return_value = ("pem", response) with mock.patch("letsencrypt.plugins.common.open", m_open, create=True): # pylint: disable=protected-access self.assertEqual(response, self.sni._setup_challenge_cert( achall, "randomS1")) self.assertTrue(m_open.called) self.assertEqual( m_open.call_args[0], (self.sni.get_cert_file(achall), "w")) self.assertEqual(m_open().write.call_args[0][0], "pem")
def setUp(self): from letsencrypt.revoker import Revoker super(RevokerTest, self).setUp() with open(self.key_path) as key_file: self.key = le_util.Key(self.key_path, key_file.read()) self._store_certs() self.revoker = Revoker(installer=mock.MagicMock(), config=self.mock_config)
def setUp(self): self.chall = acme_util.chall_to_challb( challenges.DVSNI(r="r_value", nonce="12345ABCDE"), "pending") self.response = challenges.DVSNIResponse() key = le_util.Key( "path", pkg_resources.resource_string( "acme.jose", os.path.join("testdata", "rsa512_key.pem"))) from letsencrypt.achallenges import DVSNI self.achall = DVSNI(challb=self.chall, domain="example.com", key=key)
def test_revoke_by_wrong_key(self, mock_display, mock_acme): mock_display().confirm_revocation.return_value = True key_path = test_util.vector_path("rsa256_key.pem") wrong_key = le_util.Key(key_path, open(key_path).read()) self.revoker.revoke_from_key(wrong_key) # Nothing was removed self.assertEqual(len(self._get_rows()), 2) # No revocation went through self.assertEqual(mock_acme.call_count, 0)
def test_revoke_by_wrong_key(self, mock_display, mock_net): mock_display().confirm_revocation.return_value = True key_path = pkg_resources.resource_filename( "acme.jose", os.path.join("testdata", "rsa256_key.pem")) wrong_key = le_util.Key(key_path, open(key_path).read()) self.revoker.revoke_from_key(wrong_key) # Nothing was removed self.assertEqual(len(self._get_rows()), 2) # No revocation went through self.assertEqual(mock_net.call_count, 0)
def setUp(self): from letsencrypt.auth_handler import AuthHandler self.mock_auth = mock.MagicMock(name="ApacheConfigurator") self.mock_auth.get_chall_pref.return_value = [challenges.TLSSNI01] self.mock_auth.perform.side_effect = gen_auth_resp self.mock_account = mock.Mock(key=le_util.Key("file_path", "PEM")) self.mock_net = mock.MagicMock(spec=acme_client.Client) self.handler = AuthHandler( self.mock_auth, self.mock_net, self.mock_account) logging.disable(logging.CRITICAL)
def setUp(self): zope.component.provideUtility(display_util.FileDisplay(sys.stdout)) self.accounts_dir = tempfile.mkdtemp("accounts") self.account_keys_dir = os.path.join(self.accounts_dir, "keys") os.makedirs(self.account_keys_dir, 0o700) self.config = mock.MagicMock(accounts_dir=self.accounts_dir, account_keys_dir=self.account_keys_dir, server="letsencrypt-demo.org") self.key = le_util.Key("keypath", "pem") self.acc1 = account.Account(self.config, self.key, "*****@*****.**") self.acc2 = account.Account(self.config, self.key, "*****@*****.**", "phone") self.acc1.save() self.acc2.save()
def setUp(self): from letsencrypt.auth_handler import AuthHandler self.mock_dv_auth = mock.MagicMock(name="ApacheConfigurator") self.mock_cont_auth = mock.MagicMock(name="ContinuityAuthenticator") self.mock_dv_auth.get_chall_pref.return_value = [challenges.DVSNI] self.mock_cont_auth.get_chall_pref.return_value = [ challenges.RecoveryToken] self.mock_cont_auth.perform.side_effect = gen_auth_resp self.mock_dv_auth.perform.side_effect = gen_auth_resp self.mock_account = mock.Mock(key=le_util.Key("file_path", "PEM")) self.mock_net = mock.MagicMock(spec=network2.Network) self.handler = AuthHandler( self.mock_dv_auth, self.mock_cont_auth, self.mock_net, self.mock_account) logging.disable(logging.CRITICAL)
def revoke(default_installer, config, plugins, no_confirm, cert, authkey): """Revoke certificates. :param config: Configuration. :type config: :class:`letsencrypt.interfaces.IConfig` """ installer = display_ops.pick_installer( config, default_installer, plugins, question="Which installer " "should be used for certificate revocation?") revoc = revoker.Revoker(installer, config, no_confirm) # Cert is most selective, so it is chosen first. if cert is not None: revoc.revoke_from_cert(cert[0]) elif authkey is not None: revoc.revoke_from_key(le_util.Key(authkey[0], authkey[1])) else: revoc.revoke_from_menu()
def setUp(self): super(DvsniPerformTest, self).setUp() with mock.patch("letsencrypt_apache.configurator." "mod_loaded") as mock_load: mock_load.return_value = True config = util.get_apache_configurator( self.config_path, self.config_dir, self.work_dir, self.ssl_options) from letsencrypt_apache import dvsni self.sni = dvsni.ApacheDvsni(config) rsa256_file = pkg_resources.resource_filename( "acme.jose", "testdata/rsa256_key.pem") rsa256_pem = pkg_resources.resource_string( "acme.jose", "testdata/rsa256_key.pem") auth_key = le_util.Key(rsa256_file, rsa256_pem) self.achalls = [ achallenges.DVSNI( challb=acme_util.chall_to_challb( challenges.DVSNI( r="\x8c\x8a\xbf_-f\\cw\xee\xd6\xf8/\xa5\xe3\xfd\xeb9" "\xf1\xf5\xb9\xefVM\xc9w\xa4u\x9c\xe1\x87\xb4", nonce="7\xbc^\xb7]>\x00\xa1\x9bOcU\x84^Z\x18", ), "pending"), domain="encryption-example.demo", key=auth_key), achallenges.DVSNI( challb=acme_util.chall_to_challb( challenges.DVSNI( r="\xba\xa9\xda?<m\xaewmx\xea\xad\xadv\xf4\x02\xc9y\x80" "\xe2_X\t\xe7\xc7\xa4\t\xca\xf7&\x945", nonce="Y\xed\x01L\xac\x95\xf7pW\xb1\xd7\xa1\xb2\xc5" "\x96\xba", ), "pending"), domain="letsencrypt.demo", key=auth_key), ]
def setUp(self): super(DvsniPerformTest, self).setUp() config = util.get_nginx_configurator(self.config_path, self.config_dir, self.work_dir, self.ssl_options) rsa256_file = pkg_resources.resource_filename( "acme.jose", "testdata/rsa256_key.pem") rsa256_pem = pkg_resources.resource_string("acme.jose", "testdata/rsa256_key.pem") auth_key = le_util.Key(rsa256_file, rsa256_pem) from letsencrypt_nginx import dvsni self.sni = dvsni.NginxDvsni(config) self.achalls = [ achallenges.DVSNI(challb=acme_util.chall_to_challb( challenges.DVSNI(r="foo", nonce="bar"), "pending"), domain="www.example.com", key=auth_key), achallenges.DVSNI(challb=acme_util.chall_to_challb( challenges.DVSNI( r="\xba\xa9\xda?<m\xaewmx\xea\xad\xadv\xf4\x02\xc9y\x80" "\xe2_X\t\xe7\xc7\xa4\t\xca\xf7&\x945", nonce="Y\xed\x01L\xac\x95\xf7pW\xb1\xd7" "\xa1\xb2\xc5\x96\xba"), "pending"), domain="blah", key=auth_key), achallenges.DVSNI(challb=acme_util.chall_to_challb( challenges.DVSNI( r="\x8c\x8a\xbf_-f\\cw\xee\xd6\xf8/\xa5\xe3\xfd\xeb9" "\xf1\xf5\xb9\xefVM\xc9w\xa4u\x9c\xe1\x87\xb4", nonce="7\xbc^\xb7]>\x00\xa1\x9bOcU\x84^Z\x18"), "pending"), domain="www.example.org", key=auth_key) ]
def test_determine_account(self, mock_op, mock_prompt): """Test determine account""" from letsencrypt import client key = le_util.Key(tempfile.mkstemp()[1], "pem") test_acc = account.Account(self.config, key, "*****@*****.**") mock_op.return_value = test_acc # Test 0 mock_prompt.return_value = None self.assertTrue(client.determine_account(self.config) is None) # Test 1 test_acc.save() acc = client.determine_account(self.config) self.assertEqual(acc.email, test_acc.email) # Test multiple self.assertFalse(mock_op.called) acc2 = account.Account(self.config, key) acc2.save() chosen_acc = client.determine_account(self.config) self.assertTrue(mock_op.called) self.assertTrue(chosen_acc.email, test_acc.email)
import socket import unittest import mock import OpenSSL.crypto import OpenSSL.SSL from acme import challenges from letsencrypt import achallenges from letsencrypt import le_util from letsencrypt.tests import acme_util KEY = le_util.Key("foo", pkg_resources.resource_string( "acme.jose", os.path.join("testdata", "rsa512_key.pem"))) PRIVATE_KEY = OpenSSL.crypto.load_privatekey( OpenSSL.crypto.FILETYPE_PEM, KEY.pem) CONFIG = mock.Mock(dvsni_port=5001) # Classes based on to allow interrupting infinite loop under test # after one iteration, based on. # http://igorsobreira.com/2013/03/17/testing-infinite-loops.html class _SocketAcceptOnlyNTimes(object): # pylint: disable=too-few-public-methods """ Callable that will raise `CallableExhausted` exception after `limit` calls, modified to also return a tuple simulating the return values of a socket.accept()