-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Remove keyAuthorization field from the challenge response JWS token #6758
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this change also affect ACMEv1?
There are other ACME CAs out there using Certbot and I worry that this change might break things for them. Is there a way we can only make this change for ACMEv2? I'm happy to brainstorm with you on how to do this if you'd like.
I choose this implementation because it has a very low impact on API, while making in sync the However, if you have concerns on the retro-compatibility (but think on it twice in term of the impact on a deprecated protocol vs security related improvement), I have another proposition with API low impact. It is to do like POST-as-GET, with dynamic fallback to older formats of the spec. From the lowest level of POST implementation in
For other bodies, normal process. And in any circumstances, do not log the Formely, the spec says to send an empty If it becomes a problem on Boulder V2, we could pass to a three steps try, instead of two (empty, |
However again on the security related issue, this process exposes Certbot to leak the So considering that:
I will still strongly militate for a clean removal without fallback. |
There's no spec for "ACME v1", just a reference implementation (Boulder). I'm not sure when in the history of Boulder we removed processing a Personally I think anyone that implemented an "ACME v1" server made a poor choice and there are two solutions available to them that wouldn't be a burden on Certbot: they could implement a protocol with a specification (ACMEv2), or they could invest the engineering effort required to track and adopt Boulder's changes as they happen. Server operators that do neither of these things are guaranteed to have endless compatibility problems and I would hate to see the client ecosystem encourage more "ACME v1" development by working too hard to remain compatible. |
@adferrand, you wrote a lot about your concerns about leaking the key authorization. What is the attack here? Rather than falling back, I think my personally preferred behavior is to change Certbot's behavior based on the ACME version as suggested by jsha at #6755 (comment). I'd argue that "ACME v1" (however you want to define it) requires the @cpu,
Right, but as you know, there has been a lot of client software implemented against this reference implementation. The other ACME CAs listed at https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment#CAs_&_PKIs_that_offer_ACME_certificates whose directory endpoint I've been able to query implement "ACME v1".
If that's the case, simply suddenly changing the behavior is honestly tempting to me, however, this does not seem to be documented at https://github.com/letsencrypt/boulder/blob/master/docs/acme-divergences.md so I wouldn't expect CAs other than boulder who implemented "ACME v1" to know this.
I agree this would be great but I don't think this happening.
I think this is likely particularly painful for Certbot. For better or worse, many CAs recommend people use Certbot as well. I've heard stories about ACME servers being implemented with the goal being that "it works with Certbot". With that said, I personally think we're making progress here. We've been talking about deprecating and then removing our support for "ACME v1" to strongly discourage CAs from continuing to rely on this dated "spec". |
@bmw I wrote about security, because it seems to be an initial concern to remove it server side, but I may be wrong. Maybe @jsha or @cpu could confirm or not that it is the case. For the other proposition I made, I prefer it over to decide depending on the acme version, because Boulder seems to support it with acme v1, so we will end up to remove this deprecated key most of the time, for any acme version used. |
On my previous post, for the concerns, I was thinking of this: letsencrypt/boulder#3526, that prevents to display the |
I haven't followed this whole thread, but it sounds like you're asking: Is the keyAuthorization a confidential value? If so, no it's not. The removal in letsencrypt/boulder#3526 was just to get closer to matching the spec, not to avoid writing anything to logs. |
OK, then the fallback is reasonable, and not insecure. I will do that. Are we agree on my approach, to rely on the Once it becomes a RFC, we should remove the fallback. |
I don't think these other CAs implement ACME. They implement something unspecified.
This isn't a specification and shouldn't be used by other CAs in place of one - it isn't intended for server developers. Arguably it isn't a divergence because we won't error if you do POST the keyAuthorization, its just ignored. What I'm trying to say is that if another CA implemented "ACME v1" then the way they are supposed to know about these changes is to closely follow Boulder/Certbot development. That's the trade-off of choosing ACME v1.
Right, and this is a chance to indicate that's not a strategy the team supports. It's your call if you do want to send a message that this is an acceptable way to implement ACME but I'm trying to convince you that it's a bad idea for the long term health of the ecosystem. One of the major goals of ACME is to promote a vendor neutral protocol that would let users switch server providers and clients without risking compatibility. Ossifying on what Certbot supported at a specific point in time for an unspecified protocol is the opposite of this.
I'm a big +1 for this because again, there is no spec! There's not even a single draft # that can be pointed to that approximates ACMEv1. It's a reference implementation spanning multiple drafts as a product of the co-evolution that occurred. It sounds like I'm in the minority here so I won't keep beating on this dead horse. If you want to maintain the |
@bmw you have heard of other ACME CA servers to develop by following the Certbot implementation. @cpu you are talking about not giving a bad signal to developer about maintaining deprecated and unspecified features, and also state that implementing ACME "v1" is in fact following Boulder/Certbot development. As it is not a security update, there is no urge to process immediately. But it is clearly an occasion to be proactive and engage a migration path to incite other ACME CA server maintainers to clean their implementation. Instead of waiting official RFC for ACME, or support forever |
I'm happy to respond to some/all of what you wrote or answer any questions if you'd like to talk about this more @cpu. I largely agree with you with my main hesitation here being suddenly making these changes without sufficient notice. @adferrand, your approach sounds good to me. |
@bmw If everyone is on board with @adferrand's plan I don't think we need to talk more. It sounds like a deprecation notice and delaying the removal a release or two would address your hesitation about a sudden change/sufficient notice and also result in it being removed in the near future so I'm 👍 |
bee659f
to
9dcba7e
Compare
@bmw I implemented the new behavior with fallback. Changelog is also updated. |
Co-Authored-By: adferrand <adferrand@users.noreply.github.com>
# Conflicts: # CHANGELOG.md
Co-Authored-By: adferrand <adferrand@users.noreply.github.com>
…lace. Make a soon to be removed method private.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
…ertbot#6758) Fixes certbot#6755. POSTing the `keyAuthorization` in a JWS token when answering an ACME challenge, has been deprecated for some time now. Indeed, this is superfluous as the request is already authentified by the JWS signature. Boulder still accepts to see this field in the JWS token, and ignore it. Pebble in non strict mode also. But Pebble in strict mode refuses the request, to prepare complete removal of this field in ACME v2. Certbot still sends the `keyAuthorization` field. This PR removes it, and makes Certbot compliant with current ACME v2 protocol, and so Pebble in strict mode. See also [letsencrypt/pebble#192](letsencrypt/pebble#192) for implementation details server side. * New implementation, with a fallback. * Add deprecation on changelog * Update acme/acme/client.py Co-Authored-By: adferrand <adferrand@users.noreply.github.com> * Fix an instance parameter * Update changelog, extend coverage * Update comment * Add unit tests on keyAuthorization dump * Update acme/acme/client.py Co-Authored-By: adferrand <adferrand@users.noreply.github.com> * Restrict the magic of setting a variable in immutable object in one place. Make a soon to be removed method private. # Conflicts: # CHANGELOG.md
Fixes #6755.
POSTing the
keyAuthorization
in a JWS token when answering an ACME challenge, has been deprecated for some time now. Indeed, this is superfluous as the request is already authentified by the JWS signature.Boulder still accepts to see this field in the JWS token, and ignore it. Pebble in non strict mode also. But Pebble in strict mode refuses the request, to prepare complete removal of this field in ACME v2.
Certbot still sends the
keyAuthorization
field. This PR removes it, and makes Certbot compliant with current ACME v2 protocol, and so Pebble in strict mode.The implementation chosen here is done to reduce at most the surface of the API change, to mitigate risk of breakage in third-party applications that rely on
acme
. Indeed, the objects themselves see their API untouched: only the JSON serialization, done to build the JWS token, filter out thekeyAuthorization
field.See also letsencrypt/pebble#192 for implementation details server side.