Are notBefore and notAfter on order objects immutable?

Now that I have an excuse to implement notBefore/notAfter support in my client thanks to pki.goog supporting them in their ACME implementation, I find myself wondering whether I should attempt to support a use-case where the user may want to change the values after the order is requested but before it is finalized.

While Google's implementation allows you to send a POST against the order object with new values, it doesn't appear to actually change anything and you just get back the original order details as if you had sent an empty POST-as-GET payload.

But from an RFC 8555 perspective, could an ACME Server decide to allow it? After skimming the spec a few times, I can't find any verbiage that would explicitly disallow it. But it does call out the identifiers array as immutable once set...which is the only other client supplied property on an order.

Obviously in practice, it doesn't really matter until an ACME Server actually supports the concept. But I'm just curious if anyone has a different interpretation of the spec.

4 Likes

Does RFC8555 define what POST'ing a JSON body to a resource does, in generic terms?

From what I can see, it explicitly describes a finite set of operations which happen to use the POST verb: updating an account, responding to a challenge, deactivating an authorization, etc.

By asking this question, are you extrapolating something like "you may POST to a resource to update its fields"?

As the spec is written, I don't think that clients should expect to be able to do this, nor should servers be expected to support it.

2 Likes

I'd be curious to hear how you are intending to support notBefore/notAfter in Posh-ACME, though. With these fields being absolute dates rather than a duration, being set at newOrder time, it all seems like a bit of a UX problem to me, Either you ask users to set an absolute expiry date or you ask them to provide a duration, from which they will lose some number of seconds, due to order processing time.

2 Likes

Interesting, I just set it in the CSR, which worked fine. I didn't attempt to set it any other way.

1 Like

For fields that are user-supplied and not explicitly called out as immutable once set, yeah. In the abstract, it seems no different to the way you can POST to an account resource to update the contact property. Though clearly, the usefulness of such a capability for notBefore/notAfter is going to be marginal at best.

At the moment, I'm definitely leaning towards having users specify a lifetime value (in days) rather than absolute dates. That value then gets converted to the appropriate timestamps right as the order request is submitted.

I was working on how to deal with the equivalent of Set-PAOrder -LifetimeDays 30 for an order that is still pending which made me post this question. For an order that's already complete, I'll just update the lifetime value on the local order object so that subsequent renewals will use the new value. But I also wanted to see if changing the values on the pending order was possible.

But yeah, I don't think anyone is going to care about losing a few seconds of validity under normal circumstances. It was more the edge case where the order is created and then left for a few days before being finalized and wondering if I could effectively "refresh" the dates. Or the edge case where you want to change the lifetime from say 90 days to 30 days without having to abandon the pending/ready order and create a new one.

3 Likes

Are you saying this works with pki.goog without needing to specify it in the original order request payload? If so, that's fascinating and makes me wonder what happens if you specify it in both places and the values are different.

Side note, I also find it mildly annoying that Boulder throws an error if you specify notBefore/notAfter in the order request rather than just ignoring them. Had to include a bunch of warnings in the help for the lifetime parameter that your CA may not support this feature.

4 Likes

Actually no, I'm talking rubbish - my mind completely invented that and we do set it in the order.

2 Likes

For me, the difference is that this is covered by "7.3.2. Account Update".

There's nothing specified for POST'ing to an order resource, other than POST-as-GET.

I hope not :laughing:. Just more oddball values showing up here I guess.

2 Likes

I don't know as I've ever heard anyone complain that Let's Encrypt's certificates are actually 90-days-minus-1-hour long. :slight_smile:

3 Likes

Which is partly why I always thought 91 days would be more logical.
Renewing when 30 days left means there are 5 uncovered days each year.
(90-30)*6=360 [short 5 days a year]
(91-30)*6=366 [even leap years are covered]

3 Likes

@rmhrisk, could we get your opinions about this, since your server implementation is the only one currently known to be affected by this question?

2 Likes

Yeah, but that only matters to humans. Machines (and automated ACME clients) should not care.

4 Likes

Based on my experience, this seems to be one of the "vague" specification elements that is left to interpretation. That is, at least, the general excuse I've gotten from the RFC authors and LetsEncrypt staff in the past for elements like this.

My question for LetsEncrypt/ISRG would be more along the lines of "is there any interest in ever allowing it?" If so, supporting it in Pebble (but not boulder) at this point would be in line with Pebble's design goals.

The WEIRD thing to me about ACME v2 is that a CSR is only generated during order finalization - IIRC, under ACME v1, the CSR was generated first and the domains, dates, etc were all pulled from a properly conforming CSR. Under ACME V2, an order starts with a listing of domains to prove validation for (and yes, the account identifiers for those who like to be pedantic). Because of this timeline and differences, IMHO, the notBefore/notAfter fields never seemed appropriate on the Acme v2 Order Object to begin with.

Rephrasing this in more lay speak, the ACME V2 flow has been "What domains do you want to prove control over? Great! Thanks for validating! Please provide a CSR for these domains to mature into a Certificate." Having the server initially assign the notBefore/notAfter is just weird in this flow, unless it's being done so as a min/max the client could refine to be shorter. I see it as useful for instructing poorly written clients on what dates to submit, and guarding them from requesting dates that are not highly usable, but IMHO it seems more appropriate to handle at CSR time.

3 Likes

True...
But machines (still) report to humans! - LOL

4 Likes

Sorry for the delayed response.

My personal take on this topic is that setting the value after the initial order does not seem terribly useful and since the behavior is not strictly specified in this case treating the updates to these values similar to "authorizations" and "identifiers" seems like the conservative implementation decision.

The elements of the "authorizations" and "identifiers" arrays are
immutable once set. The server MUST NOT change the contents of
either array after they are created. If a client observes a change
in the contents of either array, then it SHOULD consider the order
invalid.

If for no other reason than it is always easier to loosen a restriction than to take something away later.

I also agree with:

That being said it does seem like there is an opportunity to clarify the RFC intent with an errata or to batch an update to this in a future revision of the RFC to make implementors lives easier.

2 Likes

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