From af8c2b8afc0086a305bffb4786edc33c651db241 Mon Sep 17 00:00:00 2001 From: Hector Fernandez Date: Tue, 8 Nov 2022 11:16:10 +0100 Subject: [PATCH 1/2] add sigstore bundle type Signed-off-by: Hector Fernandez --- pkg/cosign/bundle/bundle.go | 86 +++++++++++++++++++++++++++++++++++++ pkg/cosign/bundle/rekor.go | 24 +---------- 2 files changed, 87 insertions(+), 23 deletions(-) create mode 100644 pkg/cosign/bundle/bundle.go diff --git a/pkg/cosign/bundle/bundle.go b/pkg/cosign/bundle/bundle.go new file mode 100644 index 00000000000..dcf25851826 --- /dev/null +++ b/pkg/cosign/bundle/bundle.go @@ -0,0 +1,86 @@ +// Copyright 2022 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bundle + +import ( + "github.com/sigstore/rekor/pkg/generated/models" +) + +type Bundle struct { + VerificationData + VerificationMaterial +} + +// VerificationData contains extra data that can be used to verify things +// such as transparency logs and timestamped verifications. +type VerificationData struct { + // RekorPayload holds metadata about recording a Signature's ephemeral key to + // a Rekor transparency log. + // Use Payload instead of TransparencyLogEntry to keep backwards compatibility. + Payload RekorPayload + + // TimestampVerificationData holds metadata about a timestamped verification. + TimestampVerificationData +} + +// VerificationMaterial captures details on the materials used to verify +// signatures or any additional timestamped verifications. +type VerificationMaterial struct { + // A chain of X.509 certificates. + CertBytes []byte + + // PublicKeyIdentifier optional unauthenticated hint on which key to use. + PublicKeyIdentifier string +} + +// TimestampVerificationData contains various timestamped data following RFC3161. +type TimestampVerificationData struct { + // SignedEntryTimestamp holds metadata about a timestamped counter signature over the artifacts signature. + SignedEntryTimestamp []byte + + // EntryTimestampAuthority contains the recorded entry from timestamp authority server. + EntryTimestampAuthority []byte +} + +func EntryToBundle(tLogEntry *models.LogEntryAnon, signedEntryTimestamp, entryTimestampAuthority, certBytes []byte, pubKeyID string) *Bundle { + b := &Bundle{} + // If none of the verification data is configured then return nil + if (tLogEntry == nil || tLogEntry.Verification == nil) && len(entryTimestampAuthority) == 0 { + return nil + } + // Add Transparency log entry and a signed timestamp value + if tLogEntry != nil && tLogEntry.Verification != nil { + b.Payload = RekorPayload{ + Body: tLogEntry.Body, + IntegratedTime: *tLogEntry.IntegratedTime, + LogIndex: *tLogEntry.LogIndex, + LogID: *tLogEntry.LogID, + } + b.SignedEntryTimestamp = tLogEntry.Verification.SignedEntryTimestamp + + if len(signedEntryTimestamp) > 0 { + b.SignedEntryTimestamp = signedEntryTimestamp + } + } + // Set the EntryTimestampAuthority from the timestamp authority server + if len(entryTimestampAuthority) > 0 { + b.EntryTimestampAuthority = entryTimestampAuthority + } + if len(certBytes) > 0 || pubKeyID != "" { + b.CertBytes = certBytes + b.PublicKeyIdentifier = pubKeyID + } + return b +} diff --git a/pkg/cosign/bundle/rekor.go b/pkg/cosign/bundle/rekor.go index 497aa7a464a..5c869902a47 100644 --- a/pkg/cosign/bundle/rekor.go +++ b/pkg/cosign/bundle/rekor.go @@ -14,33 +14,11 @@ package bundle -import "github.com/sigstore/rekor/pkg/generated/models" - -// RekorBundle holds metadata about recording a Signature's ephemeral key to +// RekorPayload holds metadata about recording a Signature's ephemeral key to // a Rekor transparency log. -type RekorBundle struct { - SignedEntryTimestamp []byte - Payload RekorPayload -} - type RekorPayload struct { Body interface{} `json:"body"` IntegratedTime int64 `json:"integratedTime"` LogIndex int64 `json:"logIndex"` LogID string `json:"logID"` } - -func EntryToBundle(entry *models.LogEntryAnon) *RekorBundle { - if entry.Verification == nil { - return nil - } - return &RekorBundle{ - SignedEntryTimestamp: entry.Verification.SignedEntryTimestamp, - Payload: RekorPayload{ - Body: entry.Body, - IntegratedTime: *entry.IntegratedTime, - LogIndex: *entry.LogIndex, - LogID: *entry.LogID, - }, - } -} From 19038741cc1437531b65503da5947c5421f2aee1 Mon Sep 17 00:00:00 2001 From: Hector Fernandez Date: Tue, 8 Nov 2022 11:16:45 +0100 Subject: [PATCH 2/2] adapt code and tests to use new Bundle fields Signed-off-by: Hector Fernandez --- cmd/cosign/cli/attest/attest.go | 4 +-- cmd/cosign/cli/sign/sign_blob.go | 2 +- cmd/cosign/cli/verify/verify_blob.go | 8 ++--- cmd/cosign/cli/verify/verify_blob_test.go | 38 ++++++++++++++--------- internal/pkg/cosign/rekor/signer.go | 4 +-- pkg/cosign/fetch.go | 8 ++--- pkg/cosign/verify_test.go | 12 ++++--- pkg/oci/internal/signature/layer.go | 4 +-- pkg/oci/internal/signature/layer_test.go | 20 +++++++----- pkg/oci/mutate/options.go | 4 +-- pkg/oci/mutate/signature.go | 4 +-- pkg/oci/mutate/signature_test.go | 37 +++++++++++++--------- pkg/oci/signature/layer.go | 4 +-- pkg/oci/signature/layer_test.go | 20 +++++++----- pkg/oci/signatures.go | 2 +- pkg/oci/static/options.go | 4 +-- pkg/oci/static/options_test.go | 4 +-- pkg/oci/static/signature.go | 2 +- pkg/oci/static/signature_test.go | 20 +++++++----- pkg/policy/attestation_test.go | 2 +- 20 files changed, 118 insertions(+), 85 deletions(-) diff --git a/cmd/cosign/cli/attest/attest.go b/cmd/cosign/cli/attest/attest.go index 5a6b969ca1a..dc69a69c390 100644 --- a/cmd/cosign/cli/attest/attest.go +++ b/cmd/cosign/cli/attest/attest.go @@ -47,7 +47,7 @@ import ( type tlogUploadFn func(*client.Rekor, []byte) (*models.LogEntryAnon, error) -func uploadToTlog(ctx context.Context, sv *sign.SignerVerifier, rekorURL string, upload tlogUploadFn) (*cbundle.RekorBundle, error) { +func uploadToTlog(ctx context.Context, sv *sign.SignerVerifier, rekorURL string, upload tlogUploadFn) (*cbundle.Bundle, error) { rekorBytes, err := sv.Bytes(ctx) if err != nil { return nil, err @@ -62,7 +62,7 @@ func uploadToTlog(ctx context.Context, sv *sign.SignerVerifier, rekorURL string, return nil, err } fmt.Fprintln(os.Stderr, "tlog entry created with index:", *entry.LogIndex) - return cbundle.EntryToBundle(entry), nil + return cbundle.EntryToBundle(entry, []byte{}, []byte{}, []byte{}, ""), nil } // nolint diff --git a/cmd/cosign/cli/sign/sign_blob.go b/cmd/cosign/cli/sign/sign_blob.go index 446959af3d2..0d2f5a94bca 100644 --- a/cmd/cosign/cli/sign/sign_blob.go +++ b/cmd/cosign/cli/sign/sign_blob.go @@ -79,7 +79,7 @@ func SignBlobCmd(ro *options.RootOptions, ko options.KeyOpts, regOpts options.Re return nil, err } fmt.Fprintln(os.Stderr, "tlog entry created with index:", *entry.LogIndex) - signedPayload.Bundle = cbundle.EntryToBundle(entry) + signedPayload.Bundle = cbundle.EntryToBundle(entry, []byte{}, []byte{}, []byte{}, "") } // if bundle is specified, just do that and ignore the rest diff --git a/cmd/cosign/cli/verify/verify_blob.go b/cmd/cosign/cli/verify/verify_blob.go index d94e9dbaf4f..6edf8e0e12e 100644 --- a/cmd/cosign/cli/verify/verify_blob.go +++ b/cmd/cosign/cli/verify/verify_blob.go @@ -87,7 +87,7 @@ type VerifyBlobCmd struct { // nolint func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error { var cert *x509.Certificate - var bundle *bundle.RekorBundle + var bundle *bundle.Bundle if !options.OneOf(c.KeyRef, c.Sk, c.CertRef) && !options.EnableExperimental() && c.BundlePath == "" { return &options.PubKeyParseError{} @@ -312,7 +312,7 @@ We recommend requesting the certificate/signature from the original signer of th // clean up the args into CheckOpts or use KeyOpts here to resolve different KeyOpts. func verifyBlob(ctx context.Context, co *cosign.CheckOpts, blobBytes []byte, sig string, cert *x509.Certificate, - bundle *bundle.RekorBundle, e *models.LogEntryAnon) error { + bundle *bundle.Bundle, e *models.LogEntryAnon) error { if cert != nil { // This would have already be done in the main entrypoint, but do this for robustness. var err error @@ -504,7 +504,7 @@ func payloadBytes(blobRef string) ([]byte, error) { return blobBytes, nil } -func verifyRekorBundle(ctx context.Context, bundle *bundle.RekorBundle, +func verifyRekorBundle(ctx context.Context, bundle *bundle.Bundle, blobBytes []byte, sig string, pubKeyBytes []byte) (*bundle.RekorPayload, error) { if err := verifyBundleMatchesData(ctx, bundle, blobBytes, pubKeyBytes, []byte(sig)); err != nil { return nil, err @@ -530,7 +530,7 @@ func verifyRekorBundle(ctx context.Context, bundle *bundle.RekorBundle, return &bundle.Payload, nil } -func verifyBundleMatchesData(ctx context.Context, bundle *bundle.RekorBundle, blobBytes, certBytes, sigBytes []byte) error { +func verifyBundleMatchesData(ctx context.Context, bundle *bundle.Bundle, blobBytes, certBytes, sigBytes []byte) error { eimpl, kind, apiVersion, err := unmarshalEntryImpl(bundle.Payload.Body.(string)) if err != nil { return err diff --git a/cmd/cosign/cli/verify/verify_blob_test.go b/cmd/cosign/cli/verify/verify_blob_test.go index b577441fd30..ed73ccbcfab 100644 --- a/cmd/cosign/cli/verify/verify_blob_test.go +++ b/cmd/cosign/cli/verify/verify_blob_test.go @@ -552,7 +552,7 @@ func TestVerifyBlob(t *testing.T) { co.RekorClient = &mClient } - var bundle *bundle.RekorBundle + var bundle *bundle.Bundle b, err := cosign.FetchLocalSignedPayloadFromPath(tt.bundlePath) if err == nil && b.Bundle != nil { bundle = b.Bundle @@ -650,14 +650,18 @@ func makeLocalBundle(t *testing.T, rekorSigner signature.ECDSASignerVerifier, b := cosign.LocalSignedPayload{ Base64Signature: base64.StdEncoding.EncodeToString(sig), Cert: string(svBytes), - Bundle: &bundle.RekorBundle{ - Payload: bundle.RekorPayload{ - Body: e.Body, - IntegratedTime: *e.IntegratedTime, - LogIndex: *e.LogIndex, - LogID: *e.LogID, + Bundle: &bundle.Bundle{ + VerificationData: bundle.VerificationData{ + Payload: bundle.RekorPayload{ + Body: e.Body, + IntegratedTime: *e.IntegratedTime, + LogIndex: *e.LogIndex, + LogID: *e.LogID, + }, + TimestampVerificationData: bundle.TimestampVerificationData{ + SignedEntryTimestamp: e.Verification.SignedEntryTimestamp, + }, }, - SignedEntryTimestamp: e.Verification.SignedEntryTimestamp, }, } @@ -1263,13 +1267,17 @@ func createBundle(_ *testing.T, sig []byte, certPem []byte, logID string, integr b := &cosign.LocalSignedPayload{ Base64Signature: base64.StdEncoding.EncodeToString(sig), Cert: string(certPem), - Bundle: &bundle.RekorBundle{ - SignedEntryTimestamp: []byte{}, - Payload: bundle.RekorPayload{ - LogID: logID, - IntegratedTime: integratedTime, - LogIndex: 1, - Body: rekorEntry, + Bundle: &bundle.Bundle{ + VerificationData: bundle.VerificationData{ + TimestampVerificationData: bundle.TimestampVerificationData{ + SignedEntryTimestamp: []byte{}, + }, + Payload: bundle.RekorPayload{ + LogID: logID, + IntegratedTime: integratedTime, + LogIndex: 1, + Body: rekorEntry, + }, }, }, } diff --git a/internal/pkg/cosign/rekor/signer.go b/internal/pkg/cosign/rekor/signer.go index 9293797df0a..625d3a90da3 100644 --- a/internal/pkg/cosign/rekor/signer.go +++ b/internal/pkg/cosign/rekor/signer.go @@ -35,13 +35,13 @@ import ( type tlogUploadFn func(*client.Rekor, []byte) (*models.LogEntryAnon, error) -func uploadToTlog(rekorBytes []byte, rClient *client.Rekor, upload tlogUploadFn) (*cbundle.RekorBundle, error) { +func uploadToTlog(rekorBytes []byte, rClient *client.Rekor, upload tlogUploadFn) (*cbundle.Bundle, error) { entry, err := upload(rClient, rekorBytes) if err != nil { return nil, err } fmt.Fprintln(os.Stderr, "tlog entry created with index:", *entry.LogIndex) - return cbundle.EntryToBundle(entry), nil + return cbundle.EntryToBundle(entry, []byte{}, []byte{}, []byte{}, ""), nil } // signerWrapper calls a wrapped, inner signer then uploads either the Cert or Pub(licKey) of the results to Rekor, then adds the resulting `Bundle` diff --git a/pkg/cosign/fetch.go b/pkg/cosign/fetch.go index 1fc761157ea..bc1d0459dc4 100644 --- a/pkg/cosign/fetch.go +++ b/pkg/cosign/fetch.go @@ -34,13 +34,13 @@ type SignedPayload struct { Payload []byte Cert *x509.Certificate Chain []*x509.Certificate - Bundle *bundle.RekorBundle + Bundle *bundle.Bundle } type LocalSignedPayload struct { - Base64Signature string `json:"base64Signature"` - Cert string `json:"cert,omitempty"` - Bundle *bundle.RekorBundle `json:"rekorBundle,omitempty"` + Base64Signature string `json:"base64Signature"` + Cert string `json:"cert,omitempty"` + Bundle *bundle.Bundle `json:"rekorBundle,omitempty"` } type Signatures struct { diff --git a/pkg/cosign/verify_test.go b/pkg/cosign/verify_test.go index a83cbca3d7c..01fd35d31fe 100644 --- a/pkg/cosign/verify_test.go +++ b/pkg/cosign/verify_test.go @@ -199,7 +199,7 @@ func signEntry(ctx context.Context, t *testing.T, signer signature.Signer, entry return signature } -func CreateTestBundle(ctx context.Context, t *testing.T, rekor signature.Signer, leaf []byte) *bundle.RekorBundle { +func CreateTestBundle(ctx context.Context, t *testing.T, rekor signature.Signer, leaf []byte) *bundle.Bundle { // generate log ID according to rekor public key pk, _ := rekor.PublicKey(nil) keyID, _ := getLogID(pk) @@ -211,9 +211,13 @@ func CreateTestBundle(ctx context.Context, t *testing.T, rekor signature.Signer, } // Sign with root. signature := signEntry(ctx, t, rekor, pyld) - b := &bundle.RekorBundle{ - SignedEntryTimestamp: strfmt.Base64(signature), - Payload: pyld, + b := &bundle.Bundle{ + VerificationData: bundle.VerificationData{ + Payload: pyld, + TimestampVerificationData: bundle.TimestampVerificationData{ + SignedEntryTimestamp: strfmt.Base64(signature), + }, + }, } return b } diff --git a/pkg/oci/internal/signature/layer.go b/pkg/oci/internal/signature/layer.go index 3a815d3c64f..735dddab37b 100644 --- a/pkg/oci/internal/signature/layer.go +++ b/pkg/oci/internal/signature/layer.go @@ -104,12 +104,12 @@ func (s *sigLayer) Chain() ([]*x509.Certificate, error) { } // Bundle implements oci.Signature -func (s *sigLayer) Bundle() (*bundle.RekorBundle, error) { +func (s *sigLayer) Bundle() (*bundle.Bundle, error) { val := s.desc.Annotations[BundleKey] if val == "" { return nil, nil } - var b bundle.RekorBundle + var b bundle.Bundle if err := json.Unmarshal([]byte(val), &b); err != nil { return nil, fmt.Errorf("unmarshaling bundle: %w", err) } diff --git a/pkg/oci/internal/signature/layer_test.go b/pkg/oci/internal/signature/layer_test.go index 929dd975601..8a326d431a4 100644 --- a/pkg/oci/internal/signature/layer_test.go +++ b/pkg/oci/internal/signature/layer_test.go @@ -57,7 +57,7 @@ func TestSignature(t *testing.T) { wantCertErr error wantChain int wantChainErr error - wantBundle *bundle.RekorBundle + wantBundle *bundle.Bundle wantBundleErr error }{{ name: "just payload and signature", @@ -152,13 +152,17 @@ func TestSignature(t *testing.T) { }, }, wantSig: "blah", - wantBundle: &bundle.RekorBundle{ - SignedEntryTimestamp: mustDecode("MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="), - Payload: bundle.RekorPayload{ - Body: "REMOVED", - IntegratedTime: 1631646761, - LogIndex: 693591, - LogID: "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d", + wantBundle: &bundle.Bundle{ + VerificationData: bundle.VerificationData{ + Payload: bundle.RekorPayload{ + Body: "REMOVED", + IntegratedTime: 1631646761, + LogIndex: 693591, + LogID: "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d", + }, + TimestampVerificationData: bundle.TimestampVerificationData{ + SignedEntryTimestamp: mustDecode("MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="), + }, }, }, }, { diff --git a/pkg/oci/mutate/options.go b/pkg/oci/mutate/options.go index 0c19f3da7f5..82371d1af2c 100644 --- a/pkg/oci/mutate/options.go +++ b/pkg/oci/mutate/options.go @@ -61,7 +61,7 @@ func WithReplaceOp(ro ReplaceOp) SignOption { type signatureOpts struct { annotations map[string]string - bundle *bundle.RekorBundle + bundle *bundle.Bundle cert []byte chain []byte mediaType types.MediaType @@ -77,7 +77,7 @@ func WithAnnotations(annotations map[string]string) SignatureOption { } // WithBundle specifies the new Bundle the Signature should have. -func WithBundle(b *bundle.RekorBundle) SignatureOption { +func WithBundle(b *bundle.Bundle) SignatureOption { return func(so *signatureOpts) { so.bundle = b } diff --git a/pkg/oci/mutate/signature.go b/pkg/oci/mutate/signature.go index ed07f4540ff..9abbca5b775 100644 --- a/pkg/oci/mutate/signature.go +++ b/pkg/oci/mutate/signature.go @@ -33,7 +33,7 @@ type sigWrapper struct { wrapped oci.Signature annotations map[string]string - bundle *bundle.RekorBundle + bundle *bundle.Bundle cert *x509.Certificate chain []*x509.Certificate mediaType types.MediaType @@ -85,7 +85,7 @@ func (sw *sigWrapper) Chain() ([]*x509.Certificate, error) { } // Bundle implements oci.Signature. -func (sw *sigWrapper) Bundle() (*bundle.RekorBundle, error) { +func (sw *sigWrapper) Bundle() (*bundle.Bundle, error) { if sw.bundle != nil { return sw.bundle, nil } diff --git a/pkg/oci/mutate/signature_test.go b/pkg/oci/mutate/signature_test.go index 1e17e9bcf0b..680e69fdfac 100644 --- a/pkg/oci/mutate/signature_test.go +++ b/pkg/oci/mutate/signature_test.go @@ -291,13 +291,17 @@ func TestSignatureWithAnnotations(t *testing.T) { func TestSignatureWithBundle(t *testing.T) { payload := "this is the TestSignatureWithBundle content!" b64sig := "b64 content2=" - b := &bundle.RekorBundle{ - SignedEntryTimestamp: mustBase64Decode(t, "MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="), - Payload: bundle.RekorPayload{ - Body: "REMOVED", - IntegratedTime: 1631646761, - LogIndex: 693591, - LogID: "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d", + b := &bundle.Bundle{ + VerificationData: bundle.VerificationData{ + TimestampVerificationData: bundle.TimestampVerificationData{ + SignedEntryTimestamp: mustBase64Decode(t, "MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="), + }, + Payload: bundle.RekorPayload{ + Body: "REMOVED", + IntegratedTime: 1631646761, + LogIndex: 693591, + LogID: "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d", + }, }, } originalSig := mustCreateSignature(t, []byte(payload), b64sig) @@ -349,15 +353,20 @@ func TestSignatureWithEverything(t *testing.T) { "foo": "bar", "test": "yes", } - b := &bundle.RekorBundle{ - SignedEntryTimestamp: mustBase64Decode(t, "MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="), - Payload: bundle.RekorPayload{ - Body: "REMOVED", - IntegratedTime: 1631646761, - LogIndex: 693591, - LogID: "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d", + b := &bundle.Bundle{ + VerificationData: bundle.VerificationData{ + TimestampVerificationData: bundle.TimestampVerificationData{ + SignedEntryTimestamp: mustBase64Decode(t, "MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="), + }, + Payload: bundle.RekorPayload{ + Body: "REMOVED", + IntegratedTime: 1631646761, + LogIndex: 693591, + LogID: "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d", + }, }, } + mediaType := types.MediaType("test/media.type") originalSig := mustCreateSignature(t, []byte(payload), b64sig) diff --git a/pkg/oci/signature/layer.go b/pkg/oci/signature/layer.go index 3a815d3c64f..735dddab37b 100644 --- a/pkg/oci/signature/layer.go +++ b/pkg/oci/signature/layer.go @@ -104,12 +104,12 @@ func (s *sigLayer) Chain() ([]*x509.Certificate, error) { } // Bundle implements oci.Signature -func (s *sigLayer) Bundle() (*bundle.RekorBundle, error) { +func (s *sigLayer) Bundle() (*bundle.Bundle, error) { val := s.desc.Annotations[BundleKey] if val == "" { return nil, nil } - var b bundle.RekorBundle + var b bundle.Bundle if err := json.Unmarshal([]byte(val), &b); err != nil { return nil, fmt.Errorf("unmarshaling bundle: %w", err) } diff --git a/pkg/oci/signature/layer_test.go b/pkg/oci/signature/layer_test.go index 929dd975601..a6e48a08a08 100644 --- a/pkg/oci/signature/layer_test.go +++ b/pkg/oci/signature/layer_test.go @@ -57,7 +57,7 @@ func TestSignature(t *testing.T) { wantCertErr error wantChain int wantChainErr error - wantBundle *bundle.RekorBundle + wantBundle *bundle.Bundle wantBundleErr error }{{ name: "just payload and signature", @@ -152,13 +152,17 @@ func TestSignature(t *testing.T) { }, }, wantSig: "blah", - wantBundle: &bundle.RekorBundle{ - SignedEntryTimestamp: mustDecode("MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="), - Payload: bundle.RekorPayload{ - Body: "REMOVED", - IntegratedTime: 1631646761, - LogIndex: 693591, - LogID: "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d", + wantBundle: &bundle.Bundle{ + VerificationData: bundle.VerificationData{ + TimestampVerificationData: bundle.TimestampVerificationData{ + SignedEntryTimestamp: mustDecode("MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="), + }, + Payload: bundle.RekorPayload{ + Body: "REMOVED", + IntegratedTime: 1631646761, + LogIndex: 693591, + LogID: "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d", + }, }, }, }, { diff --git a/pkg/oci/signatures.go b/pkg/oci/signatures.go index e66b7c6c9e1..31160480c40 100644 --- a/pkg/oci/signatures.go +++ b/pkg/oci/signatures.go @@ -58,5 +58,5 @@ type Signature interface { // Bundle fetches the optional metadata that records the ephemeral // Fulcio key in the transparency log. - Bundle() (*bundle.RekorBundle, error) + Bundle() (*bundle.Bundle, error) } diff --git a/pkg/oci/static/options.go b/pkg/oci/static/options.go index e00b6cdb4e5..ce98eb3d562 100644 --- a/pkg/oci/static/options.go +++ b/pkg/oci/static/options.go @@ -29,7 +29,7 @@ type Option func(*options) type options struct { LayerMediaType types.MediaType ConfigMediaType types.MediaType - Bundle *bundle.RekorBundle + Bundle *bundle.Bundle Cert []byte Chain []byte Annotations map[string]string @@ -84,7 +84,7 @@ func WithAnnotations(ann map[string]string) Option { } // WithBundle sets the bundle to attach to the signature -func WithBundle(b *bundle.RekorBundle) Option { +func WithBundle(b *bundle.Bundle) Option { return func(o *options) { o.Bundle = b } diff --git a/pkg/oci/static/options_test.go b/pkg/oci/static/options_test.go index 63600c791ab..6a2e93d224e 100644 --- a/pkg/oci/static/options_test.go +++ b/pkg/oci/static/options_test.go @@ -26,7 +26,7 @@ import ( ) func TestOptions(t *testing.T) { - bundle := &bundle.RekorBundle{} + bundle := &bundle.Bundle{} tests := []struct { name string @@ -87,7 +87,7 @@ func TestOptions(t *testing.T) { LayerMediaType: ctypes.SimpleSigningMediaType, ConfigMediaType: types.OCIConfigJSON, Annotations: map[string]string{ - BundleAnnotationKey: "{\"SignedEntryTimestamp\":null,\"Payload\":{\"body\":null,\"integratedTime\":0,\"logIndex\":0,\"logID\":\"\"}}", + BundleAnnotationKey: "{\"Payload\":{\"body\":null,\"integratedTime\":0,\"logIndex\":0,\"logID\":\"\"},\"SignedEntryTimestamp\":null,\"EntryTimestampAuthority\":null,\"CertBytes\":null,\"PublicKeyIdentifier\":\"\"}", }, Bundle: bundle, }, diff --git a/pkg/oci/static/signature.go b/pkg/oci/static/signature.go index 1766102c8f1..6081fc80ce6 100644 --- a/pkg/oci/static/signature.go +++ b/pkg/oci/static/signature.go @@ -158,7 +158,7 @@ func (l *staticLayer) Chain() ([]*x509.Certificate, error) { } // Bundle implements oci.Signature -func (l *staticLayer) Bundle() (*bundle.RekorBundle, error) { +func (l *staticLayer) Bundle() (*bundle.Bundle, error) { return l.opts.Bundle, nil } diff --git a/pkg/oci/static/signature_test.go b/pkg/oci/static/signature_test.go index 1ef5beccb1d..96f5a403cd2 100644 --- a/pkg/oci/static/signature_test.go +++ b/pkg/oci/static/signature_test.go @@ -375,13 +375,17 @@ Ve/83WrFomwmNf056y1X48F9c4m3a3ozXAIxAKjRay5/aj/jsKKGIkmQatjI8uup Hr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ== -----END CERTIFICATE----- `) - b = &bundle.RekorBundle{ - SignedEntryTimestamp: mustDecode("MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="), - Payload: bundle.RekorPayload{ - Body: "REMOVED", - IntegratedTime: 1631646761, - LogIndex: 693591, - LogID: "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d", + b = &bundle.Bundle{ + VerificationData: bundle.VerificationData{ + TimestampVerificationData: bundle.TimestampVerificationData{ + SignedEntryTimestamp: mustDecode("MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE="), + }, + Payload: bundle.RekorPayload{ + Body: "REMOVED", + IntegratedTime: 1631646761, + LogIndex: 693591, + LogID: "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d", + }, }, } ) @@ -435,7 +439,7 @@ Hr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ== ChainAnnotationKey: string(chain), // This was extracted from gcr.io/distroless/static:nonroot on 2021/09/16. // The Body has been removed for brevity - BundleAnnotationKey: `{"SignedEntryTimestamp":"MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE=","Payload":{"body":"REMOVED","integratedTime":1631646761,"logIndex":693591,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}}`, + BundleAnnotationKey: `{"Payload":{"body":"REMOVED","integratedTime":1631646761,"logIndex":693591,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"},"SignedEntryTimestamp":"MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE=","EntryTimestampAuthority":null,"CertBytes":null,"PublicKeyIdentifier":""}`, } got, err := l.Annotations() if err != nil { diff --git a/pkg/policy/attestation_test.go b/pkg/policy/attestation_test.go index bd2139c4a42..cf848ffc93a 100644 --- a/pkg/policy/attestation_test.go +++ b/pkg/policy/attestation_test.go @@ -52,7 +52,7 @@ func (fa *failingAttestation) Cert() (*x509.Certificate, error) { func (fa *failingAttestation) Chain() ([]*x509.Certificate, error) { return nil, fmt.Errorf("unimplemented") } -func (fa *failingAttestation) Bundle() (*bundle.RekorBundle, error) { +func (fa *failingAttestation) Bundle() (*bundle.Bundle, error) { return nil, fmt.Errorf("unimplemented") } func (fa *failingAttestation) Digest() (v1.Hash, error) {