Skip to content
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

fix: adds envelope hash to in-toto entries in tlog entry creation #2118

Merged
merged 16 commits into from Aug 14, 2022
Merged

fix: adds envelope hash to in-toto entries in tlog entry creation #2118

merged 16 commits into from Aug 14, 2022

Conversation

nkreiger
Copy link
Contributor

@nkreiger nkreiger commented Aug 2, 2022

Signed-off-by: Noah Kreiger noahkreiger@gmail.com

Summary

By not using the types.NewProposedEntry the in-toto rekor function was not assiging the hash key, which caused a downstream error when querying by the hash to find the log entry after it was added, making it appear as if it did not get added.

This fix will add the envelope hash to in-toto entries during tlog entry creation that will allow the entries to be queried by the hash downstream.

Release Note

  • Bugfix adds envelope hash to in-toto entries in tlog entry creation

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>
Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>
returnVal := models.Intoto{
APIVersion: swag.String(e.APIVersion()),
Spec: e.IntotoObj,
e, err := types.NewProposedEntry(context.Background(), "intoto", "0.0.1", types.ArtifactProperties{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn’t you use the context from the input argument as it ? It sounds like a better option to me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I don’t feel hardcoding the intoto version as text is an improvement. Perhaps that is something to get from the api type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hectorj2f correct sorry I addressed the comments by isolating it to the specific intoto function, and allowing it to propagate the default version...maybe we want to keep it a specific version though to reduce the risk of dependency changes?

@codecov-commenter
Copy link

codecov-commenter commented Aug 2, 2022

Codecov Report

Merging #2118 (a1b8b7b) into main (e4a1dff) will increase coverage by 0.03%.
The diff coverage is 0.00%.

@@            Coverage Diff             @@
##             main    #2118      +/-   ##
==========================================
+ Coverage   26.23%   26.26%   +0.03%     
==========================================
  Files         130      130              
  Lines        7617     7610       -7     
==========================================
+ Hits         1998     1999       +1     
+ Misses       5362     5355       -7     
+ Partials      257      256       -1     
Impacted Files Coverage Δ
pkg/cosign/tlog.go 31.22% <0.00%> (+1.15%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@asraa
Copy link
Contributor

asraa commented Aug 2, 2022

By not using the types.NewProposedEntry the in-toto rekor function was not assiging the hash key, which caused a downstream error when querying by the hash to find the log entry

What do you mean by hash key? I'm curious if you have a reproducer or diff on the change. Before and after your change I ran

COSIGN_EXPERIMENTAL=1 ./cosign attest --predicate pred.json --type slsaprovenance gcr.io/asra-ali/busybox/demo

and I was able to search both by payload hash. The entry contents themselves populate the same fields. (including content.hash.value and payloadHash.value)

If you meant hash key as in the merkle leaf hash then both have entry hashes that you can get log entry by UUID with.

@nkreiger
Copy link
Contributor Author

nkreiger commented Aug 2, 2022

By not using the types.NewProposedEntry the in-toto rekor function was not assiging the hash key, which caused a downstream error when querying by the hash to find the log entry

What do you mean by hash key? I'm curious if you have a reproducer or diff on the change. Before and after your change I ran

COSIGN_EXPERIMENTAL=1 ./cosign attest --predicate pred.json --type slsaprovenance gcr.io/asra-ali/busybox/demo

and I was able to search both by payload hash. The entry contents themselves populate the same fields. (including content.hash.value and payloadHash.value)

If you meant hash key as in the merkle leaf hash then both have entry hashes that you can get log entry by UUID with.

Hi @asraa...this is how I re-create the issue with the current cosign binary

COSIGN_EXPERIMENTAL=1 cosign attest --predicate test.json --type custom $someimage:0.0.1

...log entry created with index:...(mine was 3089316)

GET https://rekor.sigstore.dev/api/v1/log/entries?logIndex=3089316

which returns your log, then I base64 decode the "body", which gives you the hash, and payloadHash

in this case:

"content": {
            "hash": {
                "algorithm": "sha256",
                "value": "5fcf6b25abdc0a0becf5855d43361c4fad5f10290cdea213359526228bf540e8"
            },
            "payloadHash": {
                "algorithm": "sha256",
                "value": "9791b5658e1e832c889cf6518f600283365f819295916b27d0c2da0830cc975c"
            }
        },

then I attempt to retrieve the entry by the hash

curl --location --request POST 'https://rekor.sigstore.dev/api/v1/index/retrieve' \
--header 'Content-Type: application/json' \
--data-raw '{
    "hash": "sha256:5fcf6b25abdc0a0becf5855d43361c4fad5f10290cdea213359526228bf540e8"
}'

which returns []

with my changes that fix that bug, you will get an array of UUID back running this same flow

@nkreiger
Copy link
Contributor Author

nkreiger commented Aug 2, 2022

actually on further review @asraa you are right, you can use the payloadHash, with my changes it would let you search by the Hash or the PayloadHash, I was doing something hacky and was on a different version of rekor (cosign is on 0.4 I was on 0.10), so it looked like a bug to me from my local machine...if that is not desired behavior I can close this PR

also these changes would only work on upgrading to the latest rekor, which I am not sure if you want to do right now, lmk

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>
Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>
@asraa
Copy link
Contributor

asraa commented Aug 2, 2022

with my changes it would let you search by the Hash or the PayloadHash, I was doing something hacky and was on a different version of rekor (cosign is on 0.4 I was on 0.10), so it looked like a bug to me from my local machine...if that is not desired behavior I can close this PR

I believe that there was an old bug that prevented old versions of Rekor from searching by content: sigstore/rekor#870 or sigstore/rekor#876

So I think it was just Rekor versions that "fixes" the bug.

That being said, you could consider this PR unifying the entry types and upload using types.NewProposedEntry, but I originally thought we avoided that to avoid too many deps. I don't have a preference, just wanted to jump in to fix the PR description in case anyone searches a similar issue!

@nkreiger
Copy link
Contributor Author

nkreiger commented Aug 2, 2022

@asraa thanks for posting that! That issue shows why that the changes I'm making still only allow you to search by the payloadHash on rekor 0.4, but allow you to search on either in 0.10

however, I still believe this is a bug on the cosign side (I tested the current cosign implementation against the latest rekor to confirm) due to this:

current implementation creates the intoto model, without the hash

https://github.com/sigstore/cosign/blob/main/pkg/cosign/tlog.go#L202

my proposed fix:

https://github.com/sigstore/rekor/blob/main/pkg/types/intoto/v0.0.1/entry.go#L293,L301

as you can see it is assigning the hash here, which allows you to query by it downstream

@asraa
Copy link
Contributor

asraa commented Aug 2, 2022

however, I still believe this is a bug on the cosign side (I tested the current cosign implementation against the latest rekor to confirm) due to this:

Thanks Noah! This is great. Definitely +1 to add the hash in this PR. Clarify the PR description to something like "Add envelope hash to in-toto entries in tlog entry creation"?

@nkreiger
Copy link
Contributor Author

nkreiger commented Aug 2, 2022

however, I still believe this is a bug on the cosign side (I tested the current cosign implementation against the latest rekor to confirm) due to this:

Thanks Noah! This is great. Definitely +1 to add the hash in this PR. Clarify the PR description to something like "Add envelope hash to in-toto entries in tlog entry creation"?

sure, updated

@nkreiger nkreiger changed the title fix: rekor in-toto issue with tlog creation fix: adds envelope hash to in-toto entries in tlog entry creation Aug 2, 2022
@dlorenc
Copy link
Member

dlorenc commented Aug 2, 2022

Not sure why tests aren't running here, but it looks like you need to rebase now.

pkg/cosign/tlog.go Outdated Show resolved Hide resolved
pkg/cosign/tlog.go Outdated Show resolved Hide resolved
Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>
Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>
@nkreiger
Copy link
Contributor Author

nkreiger commented Aug 2, 2022

Not sure why tests aren't running here, but it looks like you need to rebase now.

@dlorenc sorry this is my first PR for a project this big, can you elaborate on what I need to do to run the tests?

Copy link
Contributor

@asraa asraa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sg! intoto entry change lgtm

@dlorenc
Copy link
Member

dlorenc commented Aug 3, 2022

Not sure why tests aren't running here, but it looks like you need to rebase now.

@dlorenc sorry this is my first PR for a project this big, can you elaborate on what I need to do to run the tests?

I don't think it's your fault - GitHub isn't running them for some reason. Can you rebase and force push? It might re-trigger them.

@bobcallaway
Copy link
Member

I'm not sure we need to change anything in cosign, as the hash is computed and added server-side before making the entry into the log: https://github.com/sigstore/rekor/blob/102dc64d4f217013dfcf789837c3581d3f03b3d7/pkg/types/intoto/v0.0.1/entry.go#L202

Are you really seeing client behavior differences between omitting it and specifying it?

@nkreiger
Copy link
Contributor Author

nkreiger commented Aug 3, 2022

I'm not sure we need to change anything in cosign, as the hash is computed and added server-side before making the entry into the log: https://github.com/sigstore/rekor/blob/102dc64d4f217013dfcf789837c3581d3f03b3d7/pkg/types/intoto/v0.0.1/entry.go#L202

Are you really seeing client behavior differences between omitting it and specifying it?

@bobcallaway yes, it does add the hash on the server side, I am not seeing that the hash doesn't exist...only that the current implementation of cosign does not add the hash before sending to the server, and it makes it so you can not query on it downstream:

#2118 (comment)

see this example earlier in the PR

the only difference as far as I could tell was cosign doesn't use the types.NewProposedEntry for intoto, which adds the hash, and doing that fixes downstream query issue (if you are on latest rekor)

do you think its an issue on the rekor server side? I don't have the bandwidth to look into that today, but I can investigate if you think that is necessary

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>
@asraa
Copy link
Contributor

asraa commented Aug 3, 2022

Are you really seeing client behavior differences between omitting it and specifying it?

I believe it is happening. IndexKeys happens BEFORE canonicalization. sigstore/rekor#854

I guess the clarification here is that this prevented searching by envelope hash:

you can use the payloadHash, with my changes it would let you search by the Hash or the PayloadHash,

@bobcallaway
Copy link
Member

Are you really seeing client behavior differences between omitting it and specifying it?

I believe it is happening. IndexKeys happens BEFORE canonicalization. sigstore/rekor#854

So I don't think the order of the calls matters (in the insertion flow, canonicalization happens before IndexKeys() is called); but I do see the issue that is being reported here. The V001Entry.IntotoObj isn't ever updated to include the computed hash, but is included in the byte array that gets inserted into the log.

IMO this should be fixed in rekor, not in cosign.

I guess the clarification here is that this prevented searching by envelope hash:

you can use the payloadHash, with my changes it would let you search by the Hash or the PayloadHash,

@nkreiger
Copy link
Contributor Author

nkreiger commented Aug 3, 2022

IMO this should be fixed in rekor, not in cosign.

agreed, however, I think there is still value in the PR which "unifies the entry types and upload using types.NewProposedEntry" to quote @asraa because it translates to use the

https://github.com/sigstore/rekor/blob/main/pkg/types/intoto/v0.0.1/entry.go#L264 CreateFromArtifactProperties and on the rekor-server side on upload of an entry of intoto type it is using Canocalize, Unmarshal, validate ... all off the same intoto entry struct, so I don't see the dependency issue that was the original concern?

lmk if you want me to close the PR though and open an issue on the rekor side

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>
Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>
@nkreiger
Copy link
Contributor Author

thoughts? @bobcallaway

lmk if I should close the PR and move the issue, so I can stop bothering y'all :)

Comment on lines 82 to 90
e, err := types.NewProposedEntry(ctx, intoto.KIND, intoto_v001.APIVERSION, types.ArtifactProperties{
ArtifactBytes: signature,
PublicKeyBytes: pubKey,
})
if err != nil {
return nil, err
}

return e, err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
e, err := types.NewProposedEntry(ctx, intoto.KIND, intoto_v001.APIVERSION, types.ArtifactProperties{
ArtifactBytes: signature,
PublicKeyBytes: pubKey,
})
if err != nil {
return nil, err
}
return e, err
return types.NewProposedEntry(ctx, intoto.KIND, intoto_v001.APIVERSION, types.ArtifactProperties{
ArtifactBytes: signature,
PublicKeyBytes: pubKey,
})

Copy link
Member

@bobcallaway bobcallaway left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one nit but otherwise LGTM

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>
Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>
@nkreiger
Copy link
Contributor Author

one nit but otherwise LGTM

@bobcallaway good catch, resolved, all commits signed off, lmk if there is anything else I need to do!

@dlorenc
Copy link
Member

dlorenc commented Aug 13, 2022

Should be good now, thanks for your patience!

@dlorenc
Copy link
Member

dlorenc commented Aug 13, 2022

Oh whoops, it looks like you might have to drop the go.mod changes, now we're getting a build failure due to downgrading rekor.

@nkreiger
Copy link
Contributor Author

nkreiger commented Aug 13, 2022

@dlorenc you're right, looks like it is in the release-utils pkg bumpt to 0.7.3 that came with the rekor bump

#2102 (there is a PR open actually to bump that pkg), maybe I could wait for that to go through? or should I revert the go.mod changes?

regardless, I added the replace command in the go.mod which fixed all the tests without having to rollback the rekor version, is that fine?

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>
@dlorenc
Copy link
Member

dlorenc commented Aug 14, 2022

No idea what's wrong with that one, I'll poke dependabot and see if that helps. If that doesn't get fixed by tomorrow or so we can merge this and fix after. Thanks!

@dlorenc
Copy link
Member

dlorenc commented Aug 14, 2022

OK, #2102 is in, can you drop the replace and rebase?

@nkreiger
Copy link
Contributor Author

@dlorenc dropped

@dlorenc
Copy link
Member

dlorenc commented Aug 14, 2022

Awesome, let's get this in!

@dlorenc
Copy link
Member

dlorenc commented Aug 14, 2022

Thank you so much for the patience here!

@dlorenc dlorenc merged commit 734869c into sigstore:main Aug 14, 2022
@github-actions github-actions bot added this to the v1.11.0 milestone Aug 14, 2022
cldmnky pushed a commit to cldmnky/cosign that referenced this pull request Aug 21, 2022
…gstore#2118)

* bufix resoled

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>

* clean up unused

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>

* needs to be upgraded

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>

* rm test file

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>

* clean up for comments

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>

* accidentally added test

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>

* force rebase

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>

* fix linting issue

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>

* deleted image

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>

* restore gif

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>

* see if this fixes the build issue

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>

* merge in main branch with release utils changes

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>

Signed-off-by: Noah Kreiger <noahkreiger@gmail.com>
@lcarva
Copy link
Contributor

lcarva commented Aug 23, 2022

FYI, I'm seeing issues with verify-attestation starting with this change: #2197

@csullivanupgrade
Copy link

govulncheck is reporting a type mismatch when using sigstore/rekor types.NewProposedEntry:

govulncheck: Packages contain errors:
/Users/csullivan/go/pkg/mod/github.com/sigstore/cosign@v1.11.1/pkg/cosign/tlog.go:89:19: cannot use pubKey (variable of type []byte) as [][]byte value in struct literal

@csullivanupgrade
Copy link

It looks like this was just recently changed on Rekor side:
sigstore/rekor#973

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants