major structure of finalize_order shim refactor

This commit is contained in:
Erica Portnoy 2018-02-20 18:51:55 -08:00
parent 1f7b35e320
commit 0a67e1a4e8
3 changed files with 55 additions and 50 deletions

View file

@ -723,10 +723,48 @@ class BackwardsCompatibleClientV2(object):
authorizations = []
for domain in dnsNames:
authorizations.append(self.client.request_domain_challenges(domain))
return messages.OrderResource(authorizations=authorizations)
return messages.OrderResource(authorizations=authorizations, csr_pem=csr_pem)
else:
return self.client.new_order(csr_pem)
def finalize_order(self, orderr, deadline):
"""Finalize an order and obtain a certificate.
:param messages.OrderResource orderr: order to finalize
:param datetime.datetime deadline: when to stop polling and timeout
:returns: finalized order
:rtype: messages.OrderResource
"""
if self.acme_version == 1:
csr_pem = orderr.csr_pem
certr = self.client.request_issuance(
jose.ComparableX509(
OpenSSL.crypto.load_certificate_request(OpenSSL.crypto.FILETYPE_PEM, csr_pem)),
orderr.authorizations)
chain = None
while datetime.datetime.now() < deadline:
try:
chain = self.client.fetch_chain(certr)
break
except acme_errors.Error:
time.sleep(1)
if chain is None:
raise errors.Error(
'Failed to fetch chain. You should not deploy the generated '
'certificate, please rerun the command for a new one.')
cert = OpenSSL.crypto.dump_certificate(
OpenSSL.crypto.FILETYPE_PEM, certr.body.wrapped)
chain = crypto_util.dump_pyopenssl_chain(chain)
return orderr.update(fullchain_pem=(cert + chain))
else:
return self.client.finalize_order(orderr, deadline)
def _acme_version_from_directory(self, directory):
if hasattr(directory, 'newNonce'):
return 2

View file

@ -243,8 +243,7 @@ class Client(object):
than `authkey`.
:param acme.messages.OrderResource orderr: contains authzrs
:returns: `.CertificateResource` and certificate chain (as
returned by `.fetch_chain`).
:returns: certificate and chain as PEM strings
:rtype: tuple
"""
@ -264,32 +263,9 @@ class Client(object):
orderr = orderr.update(authorizations=authzr)
authzr = orderr.authorizations
certr = self.acme.request_issuance(
jose.ComparableX509(
OpenSSL.crypto.load_certificate_request(OpenSSL.crypto.FILETYPE_PEM, csr.data)),
authzr)
notify = zope.component.getUtility(interfaces.IDisplay).notification
retries = 0
chain = None
while retries <= 1:
if retries:
notify('Failed to fetch chain, please check your network '
'and continue', pause=True)
try:
chain = self.acme.fetch_chain(certr)
break
except acme_errors.Error:
logger.debug('Failed to fetch chain', exc_info=True)
retries += 1
if chain is None:
raise acme_errors.Error(
'Failed to fetch chain. You should not deploy the generated '
'certificate, please rerun the command for a new one.')
return certr, chain
deadline = datetime.datetime.now() + datetime.timedelta(seconds=90)
orderr = self.acme.finalize_order(orderr, deadline)
return crypto_util.cert_and_chain_from_fullchain(orderr.fullchain_pem)
def obtain_certificate(self, domains):
"""Obtains a certificate from the ACME server.
@ -370,14 +346,12 @@ class Client(object):
key.pem, crypto_util.dump_pyopenssl_chain(chain),
self.config)
def save_certificate(self, certr, chain_cert,
def save_certificate(self, cert_pem, chain_pem,
cert_path, chain_path, fullchain_path):
"""Saves the certificate received from the ACME server.
:param certr: ACME "certificate" resource.
:type certr: :class:`acme.messages.Certificate`
:param list chain_cert:
:param str cert_pem:
:param str chain_pem:
:param str cert_path: Candidate path to a certificate.
:param str chain_path: Candidate path to a certificate chain.
:param str fullchain_path: Candidate path to a full cert chain.
@ -394,8 +368,6 @@ class Client(object):
os.path.dirname(path), 0o755, os.geteuid(),
self.config.strict_permissions)
cert_pem = OpenSSL.crypto.dump_certificate(
OpenSSL.crypto.FILETYPE_PEM, certr.body.wrapped)
cert_file, abs_cert_path = _open_pem_file('cert_path', cert_path)
@ -406,20 +378,15 @@ class Client(object):
logger.info("Server issued certificate; certificate written to %s",
abs_cert_path)
if not chain_cert:
return abs_cert_path, None, None
else:
chain_pem = crypto_util.dump_pyopenssl_chain(chain_cert)
chain_file, abs_chain_path =\
_open_pem_file('chain_path', chain_path)
fullchain_file, abs_fullchain_path =\
_open_pem_file('fullchain_path', fullchain_path)
chain_file, abs_chain_path =\
_open_pem_file('chain_path', chain_path)
fullchain_file, abs_fullchain_path =\
_open_pem_file('fullchain_path', fullchain_path)
_save_chain(chain_pem, chain_file)
_save_chain(cert_pem + chain_pem, fullchain_file)
_save_chain(chain_pem, chain_file)
_save_chain(cert_pem + chain_pem, fullchain_file)
return abs_cert_path, abs_chain_path, abs_fullchain_path
return abs_cert_path, abs_chain_path, abs_fullchain_path
def deploy_certificate(self, domains, privkey_path,
cert_path, chain_path, fullchain_path):

View file

@ -1064,13 +1064,13 @@ def _csr_get_and_save_cert(config, le_client):
"""
csr, _ = config.actual_csr
certr, chain = le_client.obtain_certificate_from_csr(csr)
cert, chain = le_client.obtain_certificate_from_csr(csr)
if config.dry_run:
logger.debug(
"Dry run: skipping saving certificate to %s", config.cert_path)
return None, None
cert_path, _, fullchain_path = le_client.save_certificate(
certr, chain, config.cert_path, config.chain_path, config.fullchain_path)
cert, chain, config.cert_path, config.chain_path, config.fullchain_path)
return cert_path, fullchain_path
def renew_cert(config, plugins, lineage):