-
Notifications
You must be signed in to change notification settings - Fork 547
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
Add bundle create helper command #3901
Conversation
Signed-off-by: Zach Steindler <[email protected]>
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3901 +/- ##
==========================================
- Coverage 40.10% 36.26% -3.84%
==========================================
Files 155 209 +54
Lines 10044 13335 +3291
==========================================
+ Hits 4028 4836 +808
- Misses 5530 7874 +2344
- Partials 486 625 +139 ☔ View full report in Codecov by Sentry. |
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 had trouble getting this to work with a regular legacy bundle generated from sign-blob
:
$ go run cmd/cosign/main.go sign-blob /tmp/blob -y --bundle /tmp/test.old.bundle
Using payload from: /tmp/blob
Generating ephemeral keys...
Retrieving signed certificate...
[snipped]
Wrote bundle to file /tmp/test.old.bundle
MEUCIQD7GLMc2j2zn5SlejBDtvHIjZXzQB0sTe+bDHzFfMAJ1gIgEWMeFd/rjfwXb5jlimZY1kcQB/ulwP0ZNeuUye9AcS8=
$ go run cmd/cosign/main.go bundle create --bundle /tmp/test.old.bundle --out /tmp/test.converted.bundle --artifact /tmp/blob
Error: searching log query: [POST /api/v1/log/entries/retrieve][400] searchLogQueryBadRequest &{Code:400 Message:validation failure list:
validation failure list:
proposedContent.proposedContent.verifiers in body is required}
main.go:74: error during command execution: searching log query: [POST /api/v1/log/entries/retrieve][400] searchLogQueryBadRequest &{Code:400 Message:validation failure list:
validation failure list:
proposedContent.proposedContent.verifiers in body is required}
exit status 1
Signed-off-by: Zach Steindler <[email protected]>
Nice catch! I did some refactoring around a nil envelope pointer vs an empty envelope and missed a check. |
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package bundle |
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'm not sure where go tests should go that load data from "resources" and run tests against them. But I think we should have tests that use known signature data (including ones with certs) and generates a bundle? vs generating the data here?
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 an interesting idea!
Most of the existing cosign tests generate the material they work with on the fly. Some advantages of generating the material is you don't need to include known data, and you're testing with a variety of inputs. Of course, a disadvantage is that you could have a test that intermittently fails!
I think this could be something cosign considers more broadly, but might not make sense to address in this specific pull request.
payload = buf.Bytes() | ||
} | ||
|
||
tlogEntries, err := cosign.FindTlogEntry(ctx, rekorClient, sigB64, payload, pem) |
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.
Something seems to be wrong with how the signature is being encoded when I try to use the detached signature generated by cosign:
$ go run cmd/cosign/main.go sign-blob /tmp/blob -y --output-signature /tmp/blob.sig --key cosign.key
Using payload from: /tmp/blob
[snipped]
tlog entry created with index: 144824671
Wrote signature to file /tmp/blob.sig
$ go run cmd/cosign/main.go bundle create --signature /tmp/blob.sig --out /tmp/test.converted.bundle --artifact /tmp/blob --key cosign.pub
Error: searching log query: [POST /api/v1/log/entries/retrieve][400] searchLogQueryBadRequest &{Code:400 Message:verifying signature: invalid signature when validating IEEE_P1363 encoded signature}
main.go:74: error during command execution: searching log query: [POST /api/v1/log/entries/retrieve][400] searchLogQueryBadRequest &{Code:400 Message:verifying signature: invalid signature when validating IEEE_P1363 encoded signature}
exit status 1
$ go run cmd/cosign/main.go sign-blob /tmp/blob -y --output-signature /tmp/blob.sig --key cosign.key --b64
Using payload from: /tmp/blob
[snipped]
tlog entry created with index: 144825079
Wrote signature to file /tmp/blob.sig
$ go run cmd/cosign/main.go bundle create --signature /tmp/blob.sig --out /tmp/test.converted.bundle --artifact /tmp/blob --key cosign.pub
Error: searching log query: [POST /api/v1/log/entries/retrieve][400] searchLogQueryBadRequest &{Code:400 Message:verifying signature: invalid signature when validating IEEE_P1363 encoded signature}
main.go:74: error during command execution: searching log query: [POST /api/v1/log/entries/retrieve][400] searchLogQueryBadRequest &{Code:400 Message:verifying signature: invalid signature when validating IEEE_P1363 encoded signature}
exit status 1
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.
If you want to confirm what's been uploaded against what's being constructed, the --bundle
can contain the canonicalized entry -
cosign/pkg/cosign/bundle/rekor.go
Line 29 in 9b17791
Body interface{} `json:"body"` |
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.
Oops! Yes, this is another bug in handling detached signatures, which should now be fixed.
IgnoreTlog: true, | ||
Out: outPath, | ||
SignaturePath: sigPath, | ||
} |
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.
Could more cases be tested here? For example, for converting an old-style bundle, or for when there's a fulcio identity certificate instead of a key?
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 seems fair; I have added another test that does both the old style bundle and when a Fulcio identity certificate is used.
payload = buf.Bytes() | ||
} | ||
|
||
tlogEntries, err := cosign.FindTlogEntry(ctx, rekorClient, sigB64, payload, pem) |
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.
If you want to confirm what's been uploaded against what's being constructed, the --bundle
can contain the canonicalized entry -
cosign/pkg/cosign/bundle/rekor.go
Line 29 in 9b17791
Body interface{} `json:"body"` |
if len(tlogEntries) == 0 { | ||
return nil, fmt.Errorf("unable to find tlog entry") | ||
} | ||
// Attempt to verify with the earliest integrated entry |
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.
Since FindTlogEntry
is searching based on entry hash, you should only match one entry, so you could add that as a check.
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 was copying
Lines 446 to 469 in 9b17791
tlogEntries, err := FindTlogEntry(ctx, client, b64sig, payload, pem) | |
if err != nil { | |
return nil, err | |
} | |
if len(tlogEntries) == 0 { | |
return nil, fmt.Errorf("no valid tlog entries found with proposed entry") | |
} | |
// Always return the earliest integrated entry. That | |
// always suffices for verification of signature time. | |
var earliestLogEntry models.LogEntryAnon | |
var earliestLogEntryTime *time.Time | |
entryVerificationErrs := make([]string, 0) | |
for _, e := range tlogEntries { | |
entry := e | |
if err := VerifyTLogEntryOffline(ctx, &entry, rekorPubKeys); err != nil { | |
entryVerificationErrs = append(entryVerificationErrs, err.Error()) | |
continue | |
} | |
entryTime := time.Unix(*entry.IntegratedTime, 0) | |
if earliestLogEntryTime == nil || entryTime.Before(*earliestLogEntryTime) { | |
earliestLogEntryTime = &entryTime | |
earliestLogEntry = entry | |
} | |
} |
Also add test for Fulcio certificate and old bundle format Signed-off-by: Zach Steindler <[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.
Looks great! I'll leave it open til EoD Monday in case there are any other comments.
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
Summary
Working towards #3139, #3794
There are several
cosign
commands that now support the new protobuf bundle format. Users may have signed material in other formats, and this pull request adds acosign bundle create...
helper to assemble that material into a new protobuf bundle for use with the work in #3139.You can test this with something like:
Release Note
cosign bundle create
command to assist users in assembling signed content into the new protobuf bundle format to use in cosign verification commandsDocumentation
sigstore/docs#327