Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract away certificate renewal #155

Open
cowwoc opened this issue Feb 29, 2024 · 9 comments
Open

Abstract away certificate renewal #155

cowwoc opened this issue Feb 29, 2024 · 9 comments

Comments

@cowwoc
Copy link

cowwoc commented Feb 29, 2024

Renewing a certificate is harder than it should be.

If STAR is supported, we are supposed to do one thing.
If RenewalInfo is supported, we are supposed to do a different thing.
Otherwise, we are supposed to do a third thing (come up with our own algorithm to check for certificate expiration on a regular basis).

I suggest adding a class that delegates to one of these scenarios under the hood so end-users don't have to play with it themselves.

@shred
Copy link
Owner

shred commented Mar 1, 2024

Renewing the certificate is basically just:

  1. Check if the certificate is going to expire
  2. Order a new certificate in time

There is nothing more you have to do.

STAR is optional and needs to be supported by the CA. If you don't need short-lived certificates, you can ignore it. If you want to use it, you can skip the order process for renewal and just download the renewed certificate. This difference is rooted in the ACME protocol.

RenewalInfo is optional, needs to be supported by the CA, and only gives suggestions about when it is best to renew your certificate, but otherwise isn't involved in the renewal process.

It seems that you struggle with the low-level nature of the acme4j client. But this is an intentional design decision, so acme4j can used in Spring, JakartaEE, Quarkus, Android, or just in a standalone tool. For a higher-level approach, persistence and asynchronous processes would be needed, which would restrict acme4j to a certain framework.

You are right though that there are two methods Order.getCertificate() and Order.getAutoRenewalCertificate(). This is indeed not necessary, and I will merge it into one method in the coming release.

@shred
Copy link
Owner

shred commented Mar 1, 2024

Ah, wait, I start to understand... Your problem is to find out when to renew a certificate.

How would the result you expect look like?

@cowwoc
Copy link
Author

cowwoc commented Mar 1, 2024

Correct. That was my point.

I was thinking the user would specify what approaches/capabilities to try, and then ask acme4j to check if renewal is necessary. If multiple approaches are equivalent, I would also allow users to specify an order of preference.

The default behavior would have all capabilities enabled for maximum accuracy. Users would disable capabilities to trade accuracy for speed.

@shred
Copy link
Owner

shred commented Mar 1, 2024

Accuracy isn't really a concern here. You should renew the certificate in time (i.e. a few days before expiry) because there could always be network issues, CA issues etc. You wouldn't want to wait to the last minute.

The only information acme4j has for sure is the expiry date of a certificate. It's the individual decision of the user when it's time for renewal before the expiration. If the renewal is too early, the CA might deny it because it had already issued a certificate not too long ago. If the renewal is too late, the certificate could expire before a new one is issued.

Some CAs send RenewalInfo, giving a time window that suggests when it's best to renew the certificate. Other CAs do not send it.

Some CAs support STAR, and also give a time window (or at least a "latest time") when to fetch the renewed certificate. However, this only works if the user has requested a STAR certificate, and if the CA supports it.

So, with all the information acme4j has, it could only give a time window for renewal (if provided by the CA), and the expiry date of the certificate (but then it's too late already).

The unknown factor is your implementation of the renewal process. acme4j does not know about the maximum duration of your renewal process (given you also want to be prepared for unforseen circumstances like network issues), so it cannot really tell you when it's best to do the renewal.

@cowwoc
Copy link
Author

cowwoc commented Mar 1, 2024

Another approach would be for the user to pick a renewal time and then pass it into a method that would clamp it into the range recommended by the CA. If the CA does not provide any recommendations, return the input value.

@shred
Copy link
Owner

shred commented Mar 1, 2024

Sounds reasonable... Let me think about it a little bit.

@cowwoc
Copy link
Author

cowwoc commented Oct 9, 2024

I noticed that in the latest documentation you write:

After your order is finalized, you must use Order.getAutoRenewalCertificate() to retrieve a STAR certificate! Do not use Order.getCertificate() here.

I don't see why users should have to make this decision twice... if a STAR certificate was requested and one is available then why not just have getCertificate() return it? This would simplify the workflow.

@cowwoc
Copy link
Author

cowwoc commented Oct 9, 2024

Similarly, https://shredzone.org/maven/acme4j/usage/renewal.html#fetching-star-certificates-via-get sounds like an implementation detail that should be abstracted away from the user.

@shred
Copy link
Owner

shred commented Oct 9, 2024

if a STAR certificate was requested and one is available then why not just have getCertificate() return it? This would simplify the workflow.

It would make it impossible to access the "classic" certificate if a STAR certificate is available. But you are right, it makes no sense here to make both certificate types available if STAR is enabled. I will change the implementation accordingly.

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

No branches or pull requests

2 participants