No certificate uri after finalize with dns01

While developing an ACME client (https://github.com/mc3/serverPKI), using the API from automatoes.acme (https://github.com/candango/automatoes), I’m stuck where I receive a response without certificate key after finalizing the order:

def finalize_order(self, order, csr):
    """
    Marks the specified validation as complete.
    :param OrderResult order: authorization to be
    validated
    :return:
    """
    response = self.post(order.contents['finalize'], {
        'csr': export_certificate_for_acme(csr),
    }, kid=self.account.uri)
    if response.status_code == 200:
        return _json(response)
    raise AcmeError(response)

def await_for_order_fulfillment(self, order, timeout=2, iterations=5):
    response = self.post_as_get(order.uri, kid=self.account.uri)
    iteration_count = 0
    while _json(response)['status'] != "valid":
        if iteration_count == iterations:
            break
        time.sleep(timeout)
        response = self.post_as_get(order.uri,
                                    kid=self.account.uri)
        iteration_count += 1

    if _json(response)['status'] in ["valid", "ready"]:
        order.certificate_uri = _json(response)['certificate']

    if response.status_code == 200:
        return _json(response)
    raise AcmeError(response)

Instead, I receive this response:

{
'status': 'ready',
'expires': '2020-08-09T10:39:29Z', 
'identifiers': [
{'type': 'dns', 'value':'test1.lrau.net'},
{'type': 'dns', 'value': 'test2.lrau.net'}], 
'authorizations': [
'https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/12342972',
'https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/12342973'],
'finalize': 'https://acme-staging-v02.api.letsencrypt.org/acme/finalize/12343432/123473776'}

I observed this with cert renewal with additional identifiers and/or different algorithms (mostly now rsa + ec).

If I re-run the programm, I can download the certs w/o problems.

What am I doing wrong?

1 Like

Hi @ajr

if you have that status, the next step is to use the finalize url / upload the CSR. Looks like you do things in the wrong order.

And that

looks wrong. valid != ready, so if the status is valid, it’s not ready. Looks like you check thing too early.

PS: Is time.sleep in seconds or milliseconds? Seconds -> 2 is ok, milliseconds -> 2 is too short.

3 Likes

Hi Juergen,

thanks for your answer.
You are right, that only ‘valid’ brings us to the next state.

This fixed the issue:

@@ -458,6 +458,8 @@ class AcmeV2(Acme):
         response = self.post(order.contents['finalize'], {
             'csr': export_certificate_for_acme(csr),
         }, kid=self.account.uri)
+        if _json(response)['status'] == "valid":
+            order.certificate_uri = _json(response)['certificate']
         if response.status_code == 200:
             return _json(response)
         raise AcmeError(response)
@@ -473,7 +475,7 @@ class AcmeV2(Acme):
                                         kid=self.account.uri)
             iteration_count += 1
 
-        if _json(response)['status'] in ["valid", "ready"]:
+        if _json(response)['status'] == "valid":
             order.certificate_uri = _json(response)['certificate']
 
         if response.status_code == 200:
3 Likes