Free ACME CA feature comparison

I feel like this is a case of what can be done and not necessarily what should be done.

To me, effectively deprecating the entire subject component of a leaf certificate is... lazy. We would never do this for intermediate or root certificates (where the subject isn't an fqdn at all, but a made up name).

3 Likes

Never say never.
Oh no!

3 Likes

How would one identify a root/intermediate certificate without its subject? Might as well just throw the certificate away and use only the public key with a sticky note.

:grin:

2 Likes

I like sticky notes; They hold passwords really well and securely!

3 Likes

For those who are interested:

In the latter, 2 links from jsha:

RFC 2818 from May 2000 deprecates Common Name: RFC 2818 - HTTP Over TLS

Also BRs 1.6.6 section 7.1.4.2.2: Subject Distinguished Name Fields: https://cabforum.org/wp-content/uploads/CA-Browser-Forum-BR-1.6.6.pdf

From the Baseline Requirements regarding Common Name:

Required/Optional: Deprecated (Discouraged, but not prohibited)

TLDR; discussing the merits of this decision is pointless and off-topic. The field was officially deprecated from Certificates via both the CA/B Forum and RFC and could be prohibited at any point in the future. The relevant RFCs and current Baseline Requirements state the field is currently optional; with current ACME servers and CAs split in their decision to support it. As a client author, I have n hours per week allocated to handling SSL Certificate concerns. That limited time is better spent ensuring the client is functional and implements the spec correctly, than criticizing upstream decisions or advocating for change.

4 Likes

Can you imagine a driver's license consisting of nothing but aliases? :laughing:

That'd be funny as hell.

2 Likes

Yep. Glad you gathered the relevant pieces. Thanks for that. It's very useful for citation later. I often tell people the CN has been deprecated for basically the whole life of the modern internet (to which I usually get blank stares). I agree fully that at day's end, we as developers need to get things to work. Sometimes we can forget the users' expectations/beliefs/understandings in the process though. I find remembering to be one of the most challenging (and occasionally rewarding) aspects of writing auditable code.

2 Likes

May as well post an update: ~8 days later, the challenge is still processing. The maximum backoff seems to be 24 hours. The acme-challenge file is being accessed once per day at the same time.

4 Likes

Fascinating. Do you know when the authz expires? I'd be curious if it just keeps trying daily until that happens.

1 Like

I have experienced similar weird ZeroSSL retrying behaviour (ACME):

When I issued my first certificate with ZeroSSL via ACME in November 2020, I forgot to add a proper CAA record for Sectigo. This caused issuance to fail initially, with some weird error (something like "issuance failed", no specific error indicating CAA problem).

After going through potential issues, realizing CAA was missing, I corrected the CAA record and created a new order and successfully retrieved a new certificate.

3(!) days later, my automatic CT monitor notified me that (unexpectedly) a new certificate was issued for my domain - by ZeroSSL. Investigation revealed that this looked like the order I created 3 days earlier, retroactively fulfilled now, as the CAA now allowed it - even though the ACME server already reported failure and I abandoned the order. The timestamp ("NotBefore") on the certificate was three days after I originally created the order/DNS validation was performed. (ZeroSSL always sets NotBefore to midnight, so it was initially difficult for me to draw a conclusion between order and cert, given that I already had destroyed the keys and had to inspect backups).

I found that very weird, given that I a) already had made a new order and b) thought the original order had failed ("invalid"), but I might have misread that - apparently it does always retry. Anyway, It felt strange and so I went ahead and revoked the unexpected issuance, just to be sure.

6 Likes

It's curious.

On one hand, the recorded authz expiry is precisely 30 days. On the other, my program's authz (finally) went invalid after ~28.42 days, right after the final polling attempt. No problem/error recorded on the authz.

3 Likes

I suppose that sort of makes sense. It gives up immediately after it knows it won't have time to make another attempt prior to the expiration? The lack of error on the authz is weird though.

2 Likes

I noticed while LE don't care about http-01 challenge reply's content type, buypass.com will reject at least application/octet-stream as if server replied with 503

4 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.

BuyPass may have changed since your initial eval.

Seeing this for BuyPass with DNS challenge (did not try with HTTP Challenge)

... normal setup ...

Post Challenge URL. Reply reports error (fairly I guess as DNS intentionally wrong)
The status=processing and its error object has status=403 and 1 subprob

Poll Authz and see status=pending
The Authz challenges detail for dns-01 shows status=processing and two subprobs

About 30 seconds after this initial error the DNS problem was manually corrected
(Credible timeline. I was using Route53 which shows 'InSync' status in its console and API)

Continue polling Authz every 1 min. Continues to show status=pending
The Authz challenges detail is unchanged: dns-01 still status=processing and two subprobs

UNTIL about 11-12 minutes after start
At this time the Authz status=valid as is the challenge status
The challenge detail still shows an 'error' object but now just 1 subprob (weird)

The order finalize and cert requests completed normally

Note polling of the Authz was the only request after posting the original challenge URL.

Summary: It looks like BuyPass will retry the dns-01 challenge in 'processing' state without explicit request from the client. My guess is they retry 10 minutes after their second try shown in the subprobs for initial Authz poll. I did not test durations beyond this.

This seems fine from an RFC point of view. It would have been nice for them to provide the retry-after header to indicate when a poll should be retried. Or, even some docs about this. Would have saved me some time :slight_smile:

2 Likes

It's plausible BuyPass always worked this way and I just didn't wait long enough to notice in my original testing. I agree though that explicit documentation from BuyPass would make things a whole lot easier to test and verify.

3 Likes

On Friday I had some HTTP-01 issues with BuyPass due to a staging server misconfiguration. I was able to successfully validate the challenge with a manual trigger; it did not trigger an error in the response.

I am adjusting my code today and hope to have some more clarity about how DNS-01 and HTTP-01 operate with that CA.

My current plan is to timeout polling at 45s; then record a timeout along with the number of subproblems. That should generate a dataset that shows if subproblems grow on failed triggers, and if they grow between invocations.

3 Likes

Not directly related, but every time I renew my Let's Encrypt certs, I also renew some test certs with Buypass and ZeroSSL (best way to make sure the Ansible ACME client still works with them :wink: ). The most recent time was yesterday.

Almost every time I see some 502 and 504 errors with Buypass and/or ZeroSSL (yesterday with both of them), and some retries are needed because of that. With Let's Encrypt errors during renewals are usually my own fault (like screwing up some configuration :wink: ).

I guess the summary is that retrying on 502/504 errors is a good idea :wink:

(BTW, does anyone know whether Buypass and ZeroSSL have a status page, similar to Let's Encrypt Status)

2 Likes

I just did some testing against BuyPass staging - until I was ratelimited

I can confirm the following behavior:

  • triggering a challenge will cause their server to immediately retry
  • the standard authz payload is:
    • challenges
    • identifier
    • status
    • wildcard
  • under challenges, the standard payload is:
    • status
    • token
    • type
    • url
  • if an auth is attempted, the challenge receives an additional key
    • validated - timestamp of attempt
  • if the auth fails, the challenge receives an additional key
    • error
  • The error key /might/ have a "subproblems" key (I have not encountered it missing, yet)
  • On every failed attempt, the validated timestamp is updated, and a subproblem is added.

It would have been nice if they put a timestamp in each subproblem.

I should probably store these errors better, but for now I am just storing the MY timestamp, their validation attempt timestamp, and the number of subproblems. (I log the errors, but am storing the data into the database, cross referenced to the order/challenge/auth for quick retrieval and analysis)

Example payload is below.

{'challenges': [{'error': {'detail': 'Errors during validation',
                           'status': 403,
                           'subproblems': [{'detail': 'The server could not '
                                                      'connect to validation '
                                                      'target',
                                            'status': 400,
                                            'title': 'Bad Request',
                                            'type': 'urn:ietf:params:acme:error:connection'},
                                           {'detail': 'The server could not '
                                                      'connect to validation '
                                                      'target',
                                            'status': 400,
                                            'title': 'Bad Request',
                                            'type': 'urn:ietf:params:acme:error:connection'},
                                           {'detail': 'The server could not '
                                                      'connect to validation '
                                                      'target',
                                            'status': 400,
                                            'title': 'Bad Request',
                                            'type': 'urn:ietf:params:acme:error:connection'},
                                           {'detail': 'The server could not '
                                                      'connect to validation '
                                                      'target',
                                            'status': 400,
                                            'title': 'Bad Request',
                                            'type': 'urn:ietf:params:acme:error:connection'}],
                           'title': 'Forbidden',
                           'type': 'urn:ietf:params:acme:error:compound'},
                 'status': 'processing',
                 'token': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
                 'type': 'http-01',
                 'url': 'https://api.test4.buypass.no/acme/authz/XXXXXXXXXXXXXXXXXXXX/1',
                 'validated': '2025-04-07T19:59:59Z'},
                {'status': 'pending',
                 'token': 'YYYYYYYYYYYYY',
                 'type': 'dns-01',
                 'url': 'https://api.test4.buypass.no/acme/authz/XXXXXXXXXXXXXXXXXXXX/2'}],
 'identifier': {'type': 'dns', 'value': 'dev.aptise.com'},
 'status': 'pending',
 'wildcard': False}

crossreferencing BuyPass Staging - Failed Challenge stays "Processing"

2 Likes