sigstore / cosign

Code signing and transparency for containers and binaries
Apache License 2.0
4.49k stars 547 forks source link

verify-blob can't verify DSSE blobs with COSIGN_EXPERIMENTAL #2138

Open wlynch opened 2 years ago

wlynch commented 2 years ago

Description

@eddiezane and I stumbled on this today - verify-blob has logic for handling DSSE messages

https://github.com/sigstore/cosign/blob/128f8fbd5f1bed0f7f1069d01c7e33cd52f6c381/cmd/cosign/cli/verify/verify_blob.go#L234-L237

but when this is combined with COSIGN_EXPERIMENTAL, it fails:

$ cat test.json.sig 
{"payloadType":"application/vnd.in-toto+json","payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInByZWRpY2F0ZVR5cGUiOiIiLCJzdWJqZWN0IjpbeyJuYW1lIjoiIiwiZGlnZXN0Ijp7InNoYTI1NiI6IjVmMzY0OTgwZjc0NDAwZjg3NzNmODJjZjU4ZWM3ODQ0YTExZDI3Y2YifX1dLCJwcmVkaWNhdGUiOnsibmFtZSI6InVuaXQtdGVzdC0xIiwic3RhdHVzIjoic3VjY2VzcyJ9fQ==","signatures":[{"keyid":"","sig":"MEUCIEha6COOH9fAeqZE36P2nlpmT5dmN/DQdi6ffhdEI5s1AiEAlVTKIYxPAQLxbTUBjOIdFJLzkLf9wgSGH2VuTdx4k9U="}]}

$ COSIGN_EXPERIMENTAL=1 cosign verify-blob --signature test.json.sig test.json.sig --cert=<(rekor-cli get --log-index 3121421 --format json | jq -r .Body.IntotoObj.publicKey | base64 -d)
Error: verifying blob [test.json.sig]: searching log query: [POST /api/v1/log/entries/retrieve][400] searchLogQueryBadRequest  &{Code:400 Message:verifying signature: failed to verify signature: %!w(<nil>)}
main.go:62: error during command execution: verifying blob [test.json.sig]: searching log query: [POST /api/v1/log/entries/retrieve][400] searchLogQueryBadRequest  &{Code:400 Message:verifying signature: failed to verify signature: %!w(<nil>)}

$ cosign verify-blob --signature test.json.sig test.json.sig --cert=<(rekor-cli get --log-index 3121421 --format json | jq -r .Body.IntotoObj.publicKey | base64 -d)
Verified OK

We think the root cause is verify-blob is expecting a blob + signature (because by default it's not expecting raw bytes, not a DSSE envelope), so when it tries to look up the rekor entry it fails because the check to whether to lookup by HashedRekord or Intoto depends on whether a signature is present (it assumes a signature for DSSE is not needed because it's in the message itself):

https://github.com/sigstore/cosign/blob/128f8fbd5f1bed0f7f1069d01c7e33cd52f6c381/pkg/cosign/tlog.go#L289-L303

however, verify-blob requires --signature, which means you can't query by intoto:

$ cosign verify-blob test.json.sig --cert=<(rekor-cli get --log-index 3121421 --format json | jq -r .Body.IntotoObj.publicKey | base64 -d) 
Error: verifying blob [test.json.sig]: missing flag '--signature'
main.go:62: error during command execution: verifying blob [test.json.sig]: missing flag '--signature'

We can't use verify-attestation, since that is assuming there's an OCI image (I'm just trying to verify a raw DSSE envelope signed by via keyless signing).

One thing that was a bit surprising was that verify-blob had any kind of special casing for DSSE at all. Maybe it would be worth breaking this up into a separate verify-dsse subcommand, or let verify-attestation act on direct messages instead of requiring OCI?

Version

128f8fbd5f1bed0f7f1069d01c7e33cd52f6c381

haydentherapper commented 2 years ago

cc @asraa

asraa commented 2 years ago

I think this will be addressed in verify-blob-attestation, given that there's an attest-blob separate command. @priyawadhwa