diff --git a/letsencrypt/acme/messages2.py b/letsencrypt/acme/messages2.py index 93f77a3e9..a2829ff57 100644 --- a/letsencrypt/acme/messages2.py +++ b/letsencrypt/acme/messages2.py @@ -46,6 +46,11 @@ class Error(jose.JSONObjectWithFields, Exception): """Hardcoded error description based on its type.""" return self.ERROR_TYPE_DESCRIPTIONS[self.typ] + def __str__(self): + if self.typ is not None: + return ' :: '.join([self.typ, self.description, self.detail]) + else: + return str(self.detail) class _Constant(jose.JSONDeSerializable): """ACME constant.""" diff --git a/letsencrypt/acme/messages2_test.py b/letsencrypt/acme/messages2_test.py index d45aa7f9e..9e8ef33c8 100644 --- a/letsencrypt/acme/messages2_test.py +++ b/letsencrypt/acme/messages2_test.py @@ -50,6 +50,12 @@ class ErrorTest(unittest.TestCase): from letsencrypt.acme.messages2 import Error hash(Error.from_json(self.error.to_json())) + def test_str(self): + self.assertEqual( + 'malformed :: The request message was malformed :: foo', + str(self.error)) + self.assertEqual('foo', str(self.error.update(typ=None))) + class ConstantTest(unittest.TestCase): """Tests for letsencrypt.acme.messages2._Constant.""" @@ -163,6 +169,9 @@ class ChallengeBodyTest(unittest.TestCase): from letsencrypt.acme.messages2 import ChallengeBody hash(ChallengeBody.from_json(self.jobj_from)) + def test_proxy(self): + self.assertEqual('foo', self.challb.token) + class AuthorizationTest(unittest.TestCase): """Tests for letsencrypt.acme.messages2.Authorization.""" diff --git a/letsencrypt/client/cli.py b/letsencrypt/client/cli.py index f874f4d7d..762e9a850 100644 --- a/letsencrypt/client/cli.py +++ b/letsencrypt/client/cli.py @@ -98,8 +98,8 @@ def run(args, config, plugins): return "Configurator could not be determined" acme, doms = _common_run(args, config, acc, authenticator, installer) - cert_path, chain_path = acme.obtain_certificate(doms) - acme.deploy_certificate(doms, acc.key, cert_path, chain_path) + cert_key, cert_path, chain_path = acme.obtain_certificate(doms) + acme.deploy_certificate(doms, cert_key, cert_path, chain_path) acme.enhance_config(doms, args.redirect) diff --git a/letsencrypt/client/client.py b/letsencrypt/client/client.py index 12a652a7f..6622ea8de 100644 --- a/letsencrypt/client/client.py +++ b/letsencrypt/client/client.py @@ -98,9 +98,7 @@ class Client(object): :meth:`.register` must be called before :meth:`.obtain_certificate` - .. todo:: This function currently uses the account key for the cert. - This should be changed to an independent key once renewal is sorted - out. + .. todo:: This function does not currently handle csr correctly... :param set domains: domains to get a certificate @@ -108,8 +106,8 @@ class Client(object): this CSR can be different than self.authkey :type csr: :class:`CSR` - :returns: cert_path, chain_path (paths to respective files) - :rtype: `tuple` of `str` + :returns: cert_key, cert_path, chain_path + :rtype: `tuple` of (:class:`letsencrypt.client.le_util.Key`, str, str) """ if self.auth_handler is None: @@ -125,9 +123,10 @@ class Client(object): authzr = self.auth_handler.get_authorizations(domains) # Create CSR from names - if csr is None: - csr = crypto_util.init_save_csr( - self.account.key, domains, self.config.cert_dir) + cert_key = crypto_util.init_save_key( + self.config.rsa_key_size, self.config.key_dir) + csr = crypto_util.init_save_csr( + cert_key, domains, self.config.cert_dir) # Retrieve certificate certr = self.network.request_issuance( @@ -142,7 +141,7 @@ class Client(object): revoker.Revoker.store_cert_key( cert_path, self.account.key.file, self.config) - return cert_path, chain_path + return cert_key, cert_path, chain_path def save_certificate(self, certr, cert_path, chain_path): # pylint: disable=no-self-use