-
Notifications
You must be signed in to change notification settings - Fork 31
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
Use default Verifier for the public key contained in a certificate (closes #74) #424
base: main
Are you sure you want to change the base?
Conversation
4371c3e
to
f87ab73
Compare
9497e29
to
b404df7
Compare
Thanks @ret2libc, could you run |
b404df7
to
c67a77c
Compare
@kommendorkapten fixed! |
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!
@kommendorkapten can you approve the the workflows? |
Can you also update the title to refer to the issue: #74 (I believe that's the correct one). |
The conformance test is failing, and the version was updated in |
Signed-off-by: Riccardo Schirone <[email protected]>
1794621
to
82a67fb
Compare
I think it was already updated, but I re-did anyway and it's still failing :( What's weird is that this change shouldn't really affect most common scenarios as nothing changes for ecdsa-p256. Moreover, I tested sigstore-conformance locally and I don't see any error here. |
I think I understand now. All errors are in |
Hm, I ran this (before the rebase)
And that commit was before the merge in main, but anyway. It's still failing :( The test is successful for me locally too, but there are some extra work that has to be done locally to run the tests that fails (verify cpython) that requires a clone of https://github.com/woodruffw/cpython-release-tracker IIRC. I can spend some time after lunch to see if I can get conformance test running properly locally. You can some references here https://github.com/sigstore/sigstore-conformance/blob/main/action.yml#L37 |
Yes indeed! I just found out about it and I was able to reproduce locally. There are some non-p256 keys there :) Thanks |
The problem now is that this is essentially a breaking change: by using a given hash for a given key type (instead of using sha256 everywhere), we cannot verify anymore blobs signed by older cosign with a key like ecdsa-384. ECDSA-P384 now expects a SHA384, but until now we just used SHA256. Thus the errors. AFAIS there are a bunch of tests in sigstore-conformance that uses ECDSA-P384 (no other non-standard keys). This was discussed previously and I was under the impression we were fine with the breakage. It would require re-signing all blobs with the new cosign (sigstore/cosign#4050). Just to re-iterate, the options are:
|
Thanks for the summary @ret2libc My vote would be to fix conformance test so that P-384 uses SHA-384 to avoid confusion, and look at P-384/SHA-256 as a legacy construct. If needed, we could bump the conformance version to indicate that his is a potentially breaking change, to let other clients update in their pace. |
Apparently the assumption that ECDSA-384 was not too much used might be wrong. Parts of the conformance tests use python executables and sigstore bundles (e.g. https://www.python.org/ftp/python/3.10.1/) and those .sigstore files have a ECDSA-P384 public key inside, but they use SHA256. Not supporting ECDSA-P384 + SHA256 means people won't be able to verify those python binaries anymore or they need to be re-generated (I'm still not sure how those are generated). This affects all python releases after ~3.10. For reference: |
@ret2libc thanks for digging into this. Can we go with the previous proposal to support p384/521 paired with sha256 as a deprecated key type? If we can support this on the verification path, but use the correct pairing on the sign path, this won’t be breaking. The tricky part is how to do verification - we can try multiple key types, albeit that’s a bit sketchy. The bundle can contain a key hint, could we also add which algorithm is used? Then we can update all cpython bundles. Worst case, we can just support this old mapping and deprecate it with major releases across all clients later on. |
Another thought - maybe we can treat keys vs certs differently. I doubt there are many self provided keys that also requested certificates. |
That seems reasonable I think. However, as we are standardizing on a set of supported algorithms in the bundle spec, can we at least make sure that this fallback scheme is only valid for bundles up v5? That would make me feel a bit better. |
Same 🙂 -- I suppose that would prevent infallible automatic upgrades of older bundles to newer versions, but IMO that's not a huge issue. |
This should be doable.
I'll investigate what's needed for that! |
LGTM to all of the above. Can we review if there's any service changes we need to make or revert with this? I just checked Rekor, and it looks like since we aren't loading in any default hashes, we'll continue to use sha256, so clients can continue to upload key-signed artifacts to Rekor. (I was thinking about this in the context of the Cosign change - currently you can upload an artifact to Rekor whose digest is sha512, but I think the artifact must be signed using sha256) |
Signed-off-by: Riccardo Schirone <[email protected]>
Signed-off-by: Riccardo Schirone <[email protected]>
9c851da
Signed-off-by: Riccardo Schirone <[email protected]>
Signed-off-by: Riccardo Schirone <[email protected]>
Signed-off-by: Riccardo Schirone <[email protected]>
Signed-off-by: Riccardo Schirone <[email protected]>
Ok this seems to work. I've implemented fallbacks for P384/P521, but right now it's always enabled. If we want to do this compatibility check only for some artifacts, we need a way to propogate the bundle version somehow (not sure there is one already). Moreover, shall we update the client spec to mention the fallback mechanisms? |
Signed-off-by: Riccardo Schirone <[email protected]>
Signed-off-by: Riccardo Schirone <[email protected]>
Signed-off-by: Riccardo Schirone <[email protected]>
In order to enable/disable the fallback logic based on the bundle version, I had to expose a |
Signed-off-by: Riccardo Schirone <[email protected]>
Signed-off-by: Riccardo Schirone <[email protected]>
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.
Overall this LGTM but I'd want another maintainer to chime in as well
// | ||
// Pass `WithED25519ph()` to select Ed25519ph by default, when ED25519 | ||
// key is found, because for hashedrekord entries this is the only option. | ||
defaultOpts := []signature.LoadOption{options.WithED25519ph()} |
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 would mean this fallback verifier is only valid for hashedrekord and not DSSE, yes? We should document if so
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.
to be honest there's no runtime check or anything in place to enforce that this is done only for hashedrekord. It will just use pre-hashed every time there is a ed25519 key no matter what. Shall we restrict the behaviour to just hashedrekord?
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.
Can we pass the type in and set whether it’s the PH variant or not based on the type? There could also be DSSE bundles with the older mapping that we should support.
Signed-off-by: Riccardo Schirone <[email protected]>
Signed-off-by: Riccardo Schirone <[email protected]>
Signed-off-by: Riccardo Schirone <[email protected]>
case "v0.3": | ||
fallthrough | ||
case "0.3": | ||
enableCompat = true |
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.
For the future, this should be exposed as a policy option I think. But that's for the future when we have v0.4
bundles 🙂
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.
I initially exposed it as an option, but then every sigstore-go user (well, maybe there's only cosign, I'm not sure) would have to implement the bundle version check+policy enable/disable by themselves. In this way, instead, v0.4 bundles will never use the fallback logic, while v0.3 will. This is required if clients still want to verify older signatures, I think.
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.
That's fair. And to prevent downgrade attacks, the Bundle.MinVersion
check can be exposed as a verification option WithMinBundleVersion
to safeguard that no older bundles can be verified if a user want to ensure only non deprecated algorithms are used.
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.
Nice job, thank you!
return nil, fmt.Errorf("failed to fetch entity version: %w", err) | ||
} | ||
|
||
var enableCompat bool |
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.
TIL that Go booleans default to false
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.
Looks great! Just one thought on supporting dsse
@@ -9,7 +9,7 @@ replace github.com/sigstore/sigstore-go => ../../ | |||
require ( | |||
github.com/google/go-containerregistry v0.20.3 | |||
github.com/sigstore/protobuf-specs v0.4.1 | |||
github.com/sigstore/sigstore v1.9.1 | |||
github.com/sigstore/sigstore v1.9.2-0.20250408060058-404e5b5549bc |
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.
// | ||
// Pass `WithED25519ph()` to select Ed25519ph by default, when ED25519 | ||
// key is found, because for hashedrekord entries this is the only option. | ||
defaultOpts := []signature.LoadOption{options.WithED25519ph()} |
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.
Can we pass the type in and set whether it’s the PH variant or not based on the type? There could also be DSSE bundles with the older mapping that we should support.
Summary
Closes #74
Release Note
Documentation