Skip to content

Implement ARI support when checking certificate renewal#959

Open
BtbN wants to merge 2 commits into
dehydrated-io:masterfrom
BtbN:ari
Open

Implement ARI support when checking certificate renewal#959
BtbN wants to merge 2 commits into
dehydrated-io:masterfrom
BtbN:ari

Conversation

@BtbN

@BtbN BtbN commented Feb 11, 2025

Copy link
Copy Markdown
Contributor

This implements ACME ARI according to https://letsencrypt.org/2024/04/25/guide-to-integrating-ari-into-existing-acme-clients/

Since we can't trigger a run at some point in the future, this is implemented according to the alternative approach.
It assumes the script is run once per day, so if the randomized renewal time is within the next 24h, a renewal will be triggered.

I did not test this on OSX/non-coreutils systems, so I do not know if the date-magic for it works. But I also didn't find any good portable way to deal with those rfc3339 dates.

Comment thread dehydrated
Comment on lines +1841 to +1842
serial="$("${OPENSSL}" x509 -in "${cert}" -noout -serial | cut -d= -f2)"
encserial="$("${OPENSSL}" asn1parse -genstr "INT:0x${serial}" -noout -out - | tail -c +3 | urlbase64)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reaseon for the roundtrip through asn1parse?

AIUI,

encserial="$("${OPENSSL}" x509 -in "${cert}" -noout -serial | cut -d= -f2 | hex2bin | urlbase64)"

does the same thing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's implemented in line with https://letsencrypt.org/2024/04/25/guide-to-integrating-ari-into-existing-acme-clients/
Which does the same round-trip, just in go-code.
It reads to me like it's done to "ensure the serial is a positive integer". Why it does that, I'm not sure myself.
If for example the serial starts with 0x87... like in that example, piping it through asn1 like that would result in a leading zero-byte being added, which LE apparently expects:

$ openssl asn1parse -genstr "INT:0x87123456789A" -noout -out - | tail -c +3 | hexdump -v -e '/1 "%02x"'; echo
0087123456789a

Now if the ID does not start with a 1 bit, the extra 00 is not added:

$ openssl asn1parse -genstr "INT:0x57123456789A" -noout -out - | tail -c +3 | hexdump -v -e '/1 "%02x"'; echo
57123456789a

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, I remember reading about the positive integer stuff. Makes sense.

@lukas2511 lukas2511 added this to the v0.7.2 milestone Apr 15, 2025
@a-tze

a-tze commented Jan 26, 2026

Copy link
Copy Markdown

Since 0.7.2 was released without this feature, is there any new target milestone for this feature?

@a-tze

a-tze commented Jul 21, 2026

Copy link
Copy Markdown

FWIW: because of current events, I use 7f4ef7f in production and it works like a charm.

@a-tze

a-tze commented Jul 24, 2026

Copy link
Copy Markdown

Ok, Murphy is at work: one issue has shown up: OpenSSL 1.1.0 on older Debians outputs the AKI with a prefix of "keyid:" in front of the hex string.

I put something like " sed '/s/keyid://' " into the extraction command and that fixed it. There is probably a more elegant solution.

I did not research, if the output changed with OpenSSL 3.x or with any other specific version, or if it might even be distribution-dependent.

@BtbN
BtbN force-pushed the ari branch 2 times, most recently from df37f2e to 6bae321 Compare July 24, 2026 12:57
As per RFC9773, clients SHOULD include this field in newOrder
requests if there is a clear predecessor certificate.
@BtbN

BtbN commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Should be fixed now, and parsing should also be a bit more robust in general for lack of grep.

I also was made aware that the RFC calls for the client sending the certificate identifier along whenever renewal info is present, to indicate to the server which certificate is being replaced.
This was pretty simple to implement, since it's already calculated, and just needs to be passed through a few function calls to be included in the order payload.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants