-
-
Notifications
You must be signed in to change notification settings - Fork 614
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
Upgrade from go/go-jose.v2 to go-jose/go-jose.v3 #6581
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.
LGTM!
Why do we need this?
I'd also add to this section something along the lines of "the square/go-jose repository is being deprecated and replaced by go-jose/go-jose", to explain why we're making this change as opposed to just why we need this dependency at all.
I noticed a comment that seems like it was left over from an ACMEv1 divergence.
Ooh, we should just delete that doc entirely! ACMEv1 is dead, long live ACME, etc etc. Wanna file a PR for that?
Boulder core/objects.go already handles a fix for stripping padding off base64 strings that go-jose/go-jose/v3 implemented.
Interesting! Two small notes here:
- It's just interesting to see how these accomplish the same goal but using opposite tools: the go-jose version strips trailing
=
and then uses base64.RawURLEncoding, while the Boulder version adds the right number of=
and then uses base64.URLEncoding. Frankly the go-jose version is "more correct" because clients are supposed to be stripping those padding characters themselves, so I'm changing the Boulder version here. - These actually serve slightly different purposes: the go-jose code is stripping padding from base64-encoded fields that are relevant to the JWS (e.g. the signature field) while the Boulder code is only doing so for base64-encoded fields that are relevant to ACME, like CSRs. So we can't just use one to replace the other.
There were a lot of lint failures that gofmt fixed for me and our test suite ended up passing successfully.
All of these lint failures were just import ordering failures: the import statements within each block of imports must be sorted alphabetically, so switching from "square" to "go-jose" caused the entry to move upward in the list.
We shut down the ACMEv1 API in summer of 2021 and no longer have use for this text. Requested by @aarongable over at #6581
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.
Thanks for making the upgrade! There were two issues I spotted in the diff that I'd like to follow up with upstream about before we merge this. I'll file issues upstream about them.
@@ -524,18 +526,18 @@ func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Heade | |||
} | |||
} | |||
|
|||
if plaintext == nil || err != nil { | |||
if plaintext == nil { |
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.
Note for other reviewers: this was part of a lint cleanup in 7d3b437c, presumably because the err
being checked here isn't the err
from the loop above (which is scoped to just the loop); it's an err that was declared and checked far above here. The cleanup is correct.
return -1, Header{}, nil, ErrCryptoFailure | ||
} | ||
|
||
// The "zip" header parameter may only be present in the protected header. | ||
if comp := obj.protected.getCompression(); comp != "" { | ||
plaintext, err = decompress(comp, plaintext) | ||
plaintext, _ = decompress(comp, plaintext) |
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.
This was also part of the lint cleanup in go-jose/go-jose@7d3b437c. I'm not sure it's correct! It seems like the fix should have been to check the error, not ignore it.
// base64URLDecode is implemented as defined in https://www.rfc-editor.org/rfc/rfc7515.html#appendix-C | ||
func base64URLDecode(value string) ([]byte, error) { | ||
value = strings.TrimRight(value, "=") | ||
return base64.RawURLEncoding.DecodeString(value) | ||
} |
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.
This was added in go-jose/go-jose@d7b900b. I'm not sure it's correct. The linked commit cites an appendix of RFC 7515 with an example implementation, but I don't think that implementation is normative.
https://www.rfc-editor.org/rfc/rfc7515.html#section-2 has the normative definition of base64url, which does not treat the padding as optional but says "Base64 encoding using the URL- and filename-safe character set defined in Section 5 of RFC 4648 [RFC4648], with all trailing '=' characters omitted"
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.
Agreed that treating the padding characters as optional is not correct -- if you're using base64url, they are not supposed to be there at all. But as the commit message says, they've seen it in the wild, and so have we -- we allow folks to send us CSRs with padding even though the ACME spec says they're not supposed to. So I'm not totally surprised they're being liberal in what they accept here.
The go-jose/go-jose now has a v2.6.0 tag which matches the v2.6.0 tag we currently reference in the square/go-jose repo: https://github.com/go-jose/go-jose/releases/tag/v2.6.0 |
We'll use this PR to track switching from |
This removes quite a bit of dependent code (295 kB on macOS). It also adds a new github.com/go-jose/go-jose.v2 , but we'll get rid of that again after letsencrypt/boulder#6581 lands. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
Since #6598 got merged, can this move forward? |
Yep, it can. It just hasn't been as high a priority as migrating away from the deprecated repository was. |
This removes quite a bit of dependent code (295 kB on macOS). It also adds a new github.com/go-jose/go-jose.v2 , but we'll get rid of that again after letsencrypt/boulder#6581 lands. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
Why do we need this?
The
square/go-jose
repository has been deprecated and replaced bygo-jose/go-jose
. Additionally, work onsquare/go-jose v2
has stopped. Further work will be done ongo-jose/go-jose v3
.According to the ACME RFC, Boulder uses JSON Web Signature (JWS) RFC 7515 for request URL integrity, request authentication, and replay protection via nonces.
What functionality actually changed in this upgrade?
Great question, here's the release notes. https://github.com/go-jose/go-jose/releases/tag/v3.0.0
I noticed a comment that seems like it was left over from an ACMEv1 divergence. This divergence is not listed for ACMEv2.
boulder/web/context.go
Lines 142 to 145 in b21f9b7
Boulder core/objects.go already handles a fix for stripping padding off base64 strings that go-jose/go-jose/v3 implemented.
ACME RFC 8555 section 6.2 states that the JWS payload must not be detached, but go-jose/go-jose/v3 now supports that for JWKs which is cool I guess.
We're not using the
jose-util
tools as far as I can tell.None of the other commits in go-jose/go-jose/v3 appear to be relevant to boulder.
Here's the crux of the upgrade.
There were a lot of lint failures that gofmt fixed for me and our test suite ended up passing successfully.
I noticed that vendored dependencies don't download the
${module}_test.go
files, so to test the new go-jose version perCONTRIBUTING.md
I ran:Fixes #6573