diff --git a/cmd/cosign/cli/attest/attest.go b/cmd/cosign/cli/attest/attest.go index 6fee22583efc..712d8a352947 100644 --- a/cmd/cosign/cli/attest/attest.go +++ b/cmd/cosign/cli/attest/attest.go @@ -35,7 +35,6 @@ import ( "github.com/sigstore/cosign/pkg/cosign/attestation" cbundle "github.com/sigstore/cosign/pkg/cosign/bundle" cremote "github.com/sigstore/cosign/pkg/cosign/remote" - "github.com/sigstore/cosign/pkg/cosign/tuf" "github.com/sigstore/cosign/pkg/oci/mutate" ociremote "github.com/sigstore/cosign/pkg/oci/remote" "github.com/sigstore/cosign/pkg/oci/static" @@ -160,11 +159,6 @@ func AttestCmd(ctx context.Context, ko sign.KeyOpts, regOpts options.RegistryOpt opts := []static.Option{static.WithLayerMediaType(types.DssePayloadType)} if sv.Cert != nil { opts = append(opts, static.WithCertChain(sv.Cert, sv.Chain)) - timestamp, err := tuf.GetTimestamp(ctx) - if err != nil { - return errors.Wrap(err, "reading tuf timestamp") - } - opts = append(opts, static.WithTimestamp(timestamp)) } // Check whether we should be uploading to the transparency log @@ -176,11 +170,6 @@ func AttestCmd(ctx context.Context, ko sign.KeyOpts, regOpts options.RegistryOpt return err } opts = append(opts, static.WithBundle(bundle)) - timestamp, err := tuf.GetTimestamp(ctx) - if err != nil { - return errors.Wrap(err, "reading tuf timestamp") - } - opts = append(opts, static.WithTimestamp(timestamp)) } sig, err := static.NewAttestation(signedPayload, opts...) diff --git a/cmd/cosign/cli/sign/sign_blob.go b/cmd/cosign/cli/sign/sign_blob.go index 8014c771a51e..e0653067f8e5 100644 --- a/cmd/cosign/cli/sign/sign_blob.go +++ b/cmd/cosign/cli/sign/sign_blob.go @@ -28,7 +28,6 @@ import ( "github.com/pkg/errors" cbundle "github.com/sigstore/cosign/pkg/cosign/bundle" - "github.com/sigstore/cosign/pkg/cosign/tuf" "github.com/sigstore/cosign/cmd/cosign/cli/options" "github.com/sigstore/cosign/cmd/cosign/cli/rekor" @@ -103,11 +102,6 @@ func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOption } fmt.Fprintln(os.Stderr, "tlog entry created with index:", *entry.LogIndex) signedPayload.Bundle = cbundle.EntryToBundle(entry) - ts, err := tuf.GetTimestamp(ctx) - if err != nil { - return nil, err - } - signedPayload.Timestamp = ts } // if bundle is specified, just do that and ignore the rest diff --git a/internal/pkg/cosign/fulcio/signer.go b/internal/pkg/cosign/fulcio/signer.go index 3dbfb3ac8bed..18ba60c08287 100644 --- a/internal/pkg/cosign/fulcio/signer.go +++ b/internal/pkg/cosign/fulcio/signer.go @@ -20,7 +20,6 @@ import ( "io" "github.com/sigstore/cosign/internal/pkg/cosign" - "github.com/sigstore/cosign/pkg/cosign/tuf" "github.com/sigstore/cosign/pkg/oci" "github.com/sigstore/cosign/pkg/oci/mutate" ) @@ -42,13 +41,8 @@ func (fs *signerWrapper) Sign(ctx context.Context, payload io.Reader) (oci.Signa return nil, nil, err } - timestamp, err := tuf.GetTimestamp(ctx) - if err != nil { - return nil, nil, err - } - // TODO(dekkagaijin): move the fulcio SignerVerifier logic here - newSig, err := mutate.Signature(sig, mutate.WithCertChain(fs.cert, fs.chain), mutate.WithTimestamp(timestamp)) + newSig, err := mutate.Signature(sig, mutate.WithCertChain(fs.cert, fs.chain)) if err != nil { return nil, nil, err } diff --git a/internal/pkg/cosign/fulcio/signer_test.go b/internal/pkg/cosign/fulcio/signer_test.go index 53077cd26872..6107238351fd 100644 --- a/internal/pkg/cosign/fulcio/signer_test.go +++ b/internal/pkg/cosign/fulcio/signer_test.go @@ -106,13 +106,6 @@ func TestSigner(t *testing.T) { if chain[0] == nil { t.Fatal("ociSig.Chain()[0] missing certificate, got nil") } - timestamp, err := ociSig.Timestamp() - if err != nil { - t.Fatalf("ociSig.Timestamp() returned error: %v", err) - } - if timestamp == nil { - t.Fatal("ociSig.Timestamp() missing TUF timestamp, got nil") - } // Verify that the wrapped signer was called. verifier, err := signature.LoadVerifier(pub, crypto.SHA256) diff --git a/internal/pkg/cosign/rekor/signer.go b/internal/pkg/cosign/rekor/signer.go index 51b185ef0ed7..9293797df0af 100644 --- a/internal/pkg/cosign/rekor/signer.go +++ b/internal/pkg/cosign/rekor/signer.go @@ -25,7 +25,6 @@ import ( "github.com/sigstore/cosign/internal/pkg/cosign" cosignv1 "github.com/sigstore/cosign/pkg/cosign" cbundle "github.com/sigstore/cosign/pkg/cosign/bundle" - "github.com/sigstore/cosign/pkg/cosign/tuf" "github.com/sigstore/cosign/pkg/oci" "github.com/sigstore/cosign/pkg/oci/mutate" @@ -97,12 +96,7 @@ func (rs *signerWrapper) Sign(ctx context.Context, payload io.Reader) (oci.Signa return nil, nil, err } - timestamp, err := tuf.GetTimestamp(ctx) - if err != nil { - return nil, nil, err - } - - newSig, err := mutate.Signature(sig, mutate.WithBundle(bundle), mutate.WithTimestamp(timestamp)) + newSig, err := mutate.Signature(sig, mutate.WithBundle(bundle)) if err != nil { return nil, nil, err } diff --git a/internal/pkg/cosign/rekor/signer_test.go b/internal/pkg/cosign/rekor/signer_test.go index 89f6e03ed1cf..8c3e58e1db06 100644 --- a/internal/pkg/cosign/rekor/signer_test.go +++ b/internal/pkg/cosign/rekor/signer_test.go @@ -58,15 +58,6 @@ func TestSigner(t *testing.T) { t.Fatalf("Sign() returned error: %v", err) } - // Verify that the OCI signature contains a timestamp. - timestamp, err := ociSig.Timestamp() - if err != nil { - t.Fatalf("ociSig.Timestamp() returned error: %v", err) - } - if timestamp == nil { - t.Fatal("ociSig.Timestamp() missing TUF timestamp, got nil") - } - // Verify that the wrapped signer was called. verifier, err := signature.LoadVerifier(pub, crypto.SHA256) if err != nil { diff --git a/pkg/cosign/fetch.go b/pkg/cosign/fetch.go index 2da17e96a989..04bad1744e50 100644 --- a/pkg/cosign/fetch.go +++ b/pkg/cosign/fetch.go @@ -26,7 +26,6 @@ import ( "github.com/google/go-containerregistry/pkg/name" "github.com/pkg/errors" "github.com/sigstore/cosign/pkg/cosign/bundle" - "github.com/sigstore/cosign/pkg/cosign/tuf" ociremote "github.com/sigstore/cosign/pkg/oci/remote" "knative.dev/pkg/pool" ) @@ -43,7 +42,6 @@ type LocalSignedPayload struct { Base64Signature string `json:"base64Signature"` Cert string `json:"cert,omitempty"` Bundle *bundle.RekorBundle `json:"rekorBundle,omitempty"` - Timestamp *tuf.Timestamp `json:"timestamp,omitempty"` } type Signatures struct { diff --git a/pkg/cosign/tuf/client.go b/pkg/cosign/tuf/client.go index a119748e98be..efbc994447a3 100644 --- a/pkg/cosign/tuf/client.go +++ b/pkg/cosign/tuf/client.go @@ -247,18 +247,6 @@ func (t *TUF) GetTarget(name string) ([]byte, error) { return targetBytes, nil } -func (t *TUF) GetTimestamp() ([]byte, error) { - trustedMeta, err := t.local.GetMeta() - if err != nil { - return nil, errors.Wrap(err, "getting trusted meta") - } - timestamp, ok := trustedMeta["timestamp.json"] - if !ok || len(timestamp) == 0 { - return nil, errors.New("unable to get TUF timestamp") - } - return timestamp, nil -} - func localStore(cacheRoot string) (client.LocalStore, error) { local, err := tuf_leveldbstore.FileLocalStore(cacheRoot) if err != nil { diff --git a/pkg/cosign/tuf/client_test.go b/pkg/cosign/tuf/client_test.go index ec5899f6cd9f..3df12229ca5c 100644 --- a/pkg/cosign/tuf/client_test.go +++ b/pkg/cosign/tuf/client_test.go @@ -220,13 +220,6 @@ func checkTargetsAndMeta(t *testing.T, tuf *TUF) { t.Error("expected error reading target, got nil") } - // Check the TUF timestamp metadata - if ts, err := tuf.GetTimestamp(); err != nil { - t.Error("expected no error reading timestamp, got err") - } else if len(ts) == 0 { - t.Errorf("expected timestamp length of %d, got 0", len(ts)) - } - // Check root status matches status, err := tuf.getRootStatus() if err != nil { diff --git a/pkg/cosign/tuf/timestamp.go b/pkg/cosign/tuf/timestamp.go deleted file mode 100644 index 57c35aaa4b48..000000000000 --- a/pkg/cosign/tuf/timestamp.go +++ /dev/null @@ -1,47 +0,0 @@ -// 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 tuf - -import ( - "context" - "encoding/json" - - "github.com/pkg/errors" - "github.com/theupdateframework/go-tuf/data" -) - -// GetTimestamp fetches the TUF timestamp metadata to be bundled -// with the OCI signature. -func GetTimestamp(ctx context.Context) (*Timestamp, error) { - tuf, err := NewFromEnv(ctx) - if err != nil { - return nil, err - } - defer tuf.Close() - tsBytes, err := tuf.GetTimestamp() - if err != nil { - return nil, err - } - var timestamp Timestamp - if err := json.Unmarshal(tsBytes, ×tamp); err != nil { - return nil, errors.Wrap(err, "unable to unmarshal timestamp") - } - return ×tamp, nil -} - -type Timestamp struct { - Signatures []data.Signature `json:"signatures"` - Signed data.Timestamp `json:"signed"` -} diff --git a/pkg/oci/internal/signature/layer.go b/pkg/oci/internal/signature/layer.go index e84cbd2870d0..e042ce1a7db5 100644 --- a/pkg/oci/internal/signature/layer.go +++ b/pkg/oci/internal/signature/layer.go @@ -25,17 +25,15 @@ import ( v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/pkg/errors" "github.com/sigstore/cosign/pkg/cosign/bundle" - "github.com/sigstore/cosign/pkg/cosign/tuf" "github.com/sigstore/cosign/pkg/oci" "github.com/sigstore/sigstore/pkg/cryptoutils" ) const ( - sigkey = "dev.cosignproject.cosign/signature" - certkey = "dev.sigstore.cosign/certificate" - chainkey = "dev.sigstore.cosign/chain" - BundleKey = "dev.sigstore.cosign/bundle" - TimestampKey = "dev.sigstore.cosign/timestamp" + sigkey = "dev.cosignproject.cosign/signature" + certkey = "dev.sigstore.cosign/certificate" + chainkey = "dev.sigstore.cosign/chain" + BundleKey = "dev.sigstore.cosign/bundle" ) type sigLayer struct { @@ -118,16 +116,3 @@ func (s *sigLayer) Bundle() (*bundle.RekorBundle, error) { } return &b, nil } - -// Timestamp implements oci.Signature -func (s *sigLayer) Timestamp() (*tuf.Timestamp, error) { - timestamp := s.desc.Annotations[TimestampKey] - if timestamp == "" { - return nil, nil - } - var ts tuf.Timestamp - if err := json.Unmarshal([]byte(timestamp), &ts); err != nil { - return nil, errors.Wrap(err, "unmarshaling timestamp") - } - return &ts, nil -} diff --git a/pkg/oci/internal/signature/layer_test.go b/pkg/oci/internal/signature/layer_test.go index 10618dde9c0e..a3ea0d80353d 100644 --- a/pkg/oci/internal/signature/layer_test.go +++ b/pkg/oci/internal/signature/layer_test.go @@ -20,7 +20,6 @@ import ( "encoding/base64" "fmt" "testing" - "time" "github.com/google/go-cmp/cmp" v1 "github.com/google/go-containerregistry/pkg/v1" @@ -28,8 +27,6 @@ import ( "github.com/google/go-containerregistry/pkg/v1/types" "github.com/pkg/errors" "github.com/sigstore/cosign/pkg/cosign/bundle" - "github.com/sigstore/cosign/pkg/cosign/tuf" - "github.com/theupdateframework/go-tuf/data" ) func mustDecode(s string) []byte { @@ -49,22 +46,19 @@ func TestSignature(t *testing.T) { if err != nil { t.Fatalf("Digest() = %v", err) } - ts, _ := time.Parse(time.RFC3339, "2022-01-15T00:39:22Z") tests := []struct { - name string - l *sigLayer - wantPayloadErr error - wantSig string - wantSigErr error - wantCert bool - wantCertErr error - wantChain int - wantChainErr error - wantBundle *bundle.RekorBundle - wantBundleErr error - wantTimestamp *tuf.Timestamp - wantTimestampErr error + name string + l *sigLayer + wantPayloadErr error + wantSig string + wantSigErr error + wantCert bool + wantCertErr error + wantChain int + wantChainErr error + wantBundle *bundle.RekorBundle + wantBundleErr error }{{ name: "just payload and signature", l: &sigLayer{ @@ -84,11 +78,10 @@ func TestSignature(t *testing.T) { desc: v1.Descriptor{ Digest: digest, Annotations: map[string]string{ - sigkey: "blah", - certkey: "", - chainkey: "", - BundleKey: "", - TimestampKey: "", + sigkey: "blah", + certkey: "", + chainkey: "", + BundleKey: "", }, }, }, @@ -116,20 +109,6 @@ func TestSignature(t *testing.T) { }, wantSig: "blah", wantBundleErr: errors.New(`unmarshaling bundle: invalid character '}' looking for beginning of value`), - }, { - name: "min plus bad timestamp", - l: &sigLayer{ - Layer: layer, - desc: v1.Descriptor{ - Digest: digest, - Annotations: map[string]string{ - sigkey: "blah", - TimestampKey: `}`, - }, - }, - }, - wantSig: "blah", - wantTimestampErr: errors.New(`unmarshaling timestamp: invalid character '}' looking for beginning of value`), }, { name: "min plus bad cert", l: &sigLayer{ @@ -182,45 +161,6 @@ func TestSignature(t *testing.T) { LogID: "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d", }, }, - }, { - name: "min plus timestamp", - l: &sigLayer{ - Layer: layer, - desc: v1.Descriptor{ - Digest: digest, - Annotations: map[string]string{ - sigkey: "blah", - TimestampKey: `{"signatures":[{"keyid":"b6710623a30c010738e64c5209d367df1c0a18cf90e6ab5292fb01680f83453d","sig":"3046022100926cd1a5a90539f3efa97390293180132413c7d30d94399c220a8a9aa9907e6e0221009e07b0e207f76dd45caeab87258553ddcf83fc7db6dfbbd4678d18f8c3517023"}],"signed":{"_type":"timestamp","spec_version":"1.0","version":8,"expires":"2022-01-15T00:39:22Z","meta":{"snapshot.json":{"length":1658,"hashes":{"sha256":"95e5b6822e0c3a9924f2f906c0b75e09246ad6d37078806085a273fddd079679","sha512":"4b1df9f2cc2d052bee185554ded7c526e283d4fab8388557a7b684c4ce0efb28c196e33a5140e7de9de99b2f5f37a7b2503617c2ff220168c5b7a79340675acf"},"version":8}}}}`, - }, - }, - }, - wantSig: "blah", - wantTimestamp: &tuf.Timestamp{ - Signatures: []data.Signature{ - { - KeyID: "b6710623a30c010738e64c5209d367df1c0a18cf90e6ab5292fb01680f83453d", - Signature: []byte{48, 70, 2, 33, 0, 146, 108, 209, 165, 169, 5, 57, 243, 239, 169, 115, 144, 41, 49, 128, 19, 36, 19, 199, 211, 13, 148, 57, 156, 34, 10, 138, 154, 169, 144, 126, 110, 2, 33, 0, 158, 7, 176, 226, 7, 247, 109, 212, 92, 174, 171, 135, 37, 133, 83, 221, 207, 131, 252, 125, 182, 223, 187, 212, 103, 141, 24, 248, 195, 81, 112, 35}, - }, - }, - Signed: data.Timestamp{ - Type: "timestamp", - SpecVersion: "1.0", - Version: 8, - Expires: ts, - Meta: map[string]data.TimestampFileMeta{ - "snapshot.json": { - FileMeta: data.FileMeta{ - Length: 1658, - Hashes: map[string]data.HexBytes{ - "sha256": []byte{149, 229, 182, 130, 46, 12, 58, 153, 36, 242, 249, 6, 192, 183, 94, 9, 36, 106, 214, 211, 112, 120, 128, 96, 133, 162, 115, 253, 221, 7, 150, 121}, - "sha512": []byte{75, 29, 249, 242, 204, 45, 5, 43, 238, 24, 85, 84, 222, 215, 197, 38, 226, 131, 212, 250, 184, 56, 133, 87, 167, 182, 132, 196, 206, 14, 251, 40, 193, 150, 227, 58, 81, 64, 231, 222, 157, 233, 155, 47, 95, 55, 167, 178, 80, 54, 23, 194, 255, 34, 1, 104, 197, 183, 167, 147, 64, 103, 90, 207}, - }, - }, - Version: 8, - }, - }, - }, - }, }, { name: "min plus good cert", l: &sigLayer{ @@ -335,15 +275,6 @@ Hr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ== case !cmp.Equal(got, test.wantBundle): t.Errorf("Bundle() %s", cmp.Diff(got, test.wantBundle)) } - - switch got, err := test.l.Timestamp(); { - case (err != nil) != (test.wantTimestampErr != nil): - t.Errorf("Timestamp() = %v, wanted %v", err, test.wantTimestampErr) - case (err != nil) && (test.wantTimestampErr != nil) && err.Error() != test.wantTimestampErr.Error(): - t.Errorf("Timestamp() = %v, wanted %v", err, test.wantTimestampErr) - case !cmp.Equal(got, test.wantTimestamp): - t.Errorf("Timestamp() %s", cmp.Diff(got, test.wantTimestamp)) - } }) } } diff --git a/pkg/oci/mutate/options.go b/pkg/oci/mutate/options.go index 7d55ea942f31..0c19f3da7f57 100644 --- a/pkg/oci/mutate/options.go +++ b/pkg/oci/mutate/options.go @@ -18,7 +18,6 @@ package mutate import ( "github.com/google/go-containerregistry/pkg/v1/types" "github.com/sigstore/cosign/pkg/cosign/bundle" - "github.com/sigstore/cosign/pkg/cosign/tuf" "github.com/sigstore/cosign/pkg/oci" ) @@ -66,7 +65,6 @@ type signatureOpts struct { cert []byte chain []byte mediaType types.MediaType - timestamp *tuf.Timestamp } type SignatureOption func(*signatureOpts) @@ -100,13 +98,6 @@ func WithMediaType(mediaType types.MediaType) SignatureOption { } } -// WithTimestamp specifies the new Timestamp the Signature should have. -func WithTimestamp(timestamp *tuf.Timestamp) SignatureOption { - return func(so *signatureOpts) { - so.timestamp = timestamp - } -} - func makeSignatureOption(opts ...SignatureOption) *signatureOpts { so := &signatureOpts{} for _, opt := range opts { diff --git a/pkg/oci/mutate/signature.go b/pkg/oci/mutate/signature.go index 49ed98b23a08..dd2a7ab68085 100644 --- a/pkg/oci/mutate/signature.go +++ b/pkg/oci/mutate/signature.go @@ -24,7 +24,6 @@ import ( "github.com/google/go-containerregistry/pkg/v1/types" "github.com/pkg/errors" "github.com/sigstore/cosign/pkg/cosign/bundle" - "github.com/sigstore/cosign/pkg/cosign/tuf" "github.com/sigstore/cosign/pkg/oci" "github.com/sigstore/cosign/pkg/oci/static" "github.com/sigstore/sigstore/pkg/cryptoutils" @@ -38,7 +37,6 @@ type sigWrapper struct { cert *x509.Certificate chain []*x509.Certificate mediaType types.MediaType - timestamp *tuf.Timestamp } var _ v1.Layer = (*sigWrapper)(nil) @@ -94,14 +92,6 @@ func (sw *sigWrapper) Bundle() (*bundle.RekorBundle, error) { return sw.wrapped.Bundle() } -// Timestamp implements oci.Signature. -func (sw *sigWrapper) Timestamp() (*tuf.Timestamp, error) { - if sw.timestamp != nil { - return sw.timestamp, nil - } - return sw.wrapped.Timestamp() -} - // MediaType implements v1.Layer func (sw *sigWrapper) MediaType() (types.MediaType, error) { if sw.mediaType != "" { @@ -169,15 +159,6 @@ func Signature(original oci.Signature, opts ...SignatureOption) (oci.Signature, newAnn[static.BundleAnnotationKey] = string(b) } - if so.timestamp != nil { - newSig.timestamp = so.timestamp - t, err := json.Marshal(so.timestamp) - if err != nil { - return nil, err - } - newAnn[static.TimestampAnnotationKey] = string(t) - } - if so.cert != nil { var cert *x509.Certificate var chain []*x509.Certificate diff --git a/pkg/oci/mutate/signature_test.go b/pkg/oci/mutate/signature_test.go index 7f26f82fa6f6..1e17e9bcf0bc 100644 --- a/pkg/oci/mutate/signature_test.go +++ b/pkg/oci/mutate/signature_test.go @@ -22,10 +22,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-containerregistry/pkg/v1/types" "github.com/sigstore/cosign/pkg/cosign/bundle" - "github.com/sigstore/cosign/pkg/cosign/tuf" "github.com/sigstore/cosign/pkg/oci" "github.com/sigstore/cosign/pkg/oci/static" - "github.com/theupdateframework/go-tuf/data" ) var ( @@ -313,40 +311,6 @@ func TestSignatureWithBundle(t *testing.T) { assertSignaturesEqual(t, expectedSig, newSig) } -func TestSignatureWithTimestamp(t *testing.T) { - payload := "this is the TestSignatureWithTimestamp content!" - b64sig := "b64 content2=" - timestamp := &tuf.Timestamp{ - Signatures: []data.Signature{ - { - KeyID: "b6710623a30c010738e64c5209d367df1c0a18cf90e6ab5292fb01680f83453d", - }, - }, - Signed: data.Timestamp{ - Type: "timestamp", - SpecVersion: "1.0", - Version: 8, - Meta: map[string]data.TimestampFileMeta{ - "snapshot.json": { - FileMeta: data.FileMeta{ - Length: 1658, - }, - Version: 8, - }, - }, - }, - } - originalSig := mustCreateSignature(t, []byte(payload), b64sig) - expectedSig := mustCreateSignature(t, []byte(payload), b64sig, static.WithTimestamp(timestamp)) - - newSig, err := Signature(originalSig, WithTimestamp(timestamp)) - if err != nil { - t.Fatalf("Signature(WithTimestamp()) returned error: %v", err) - } - - assertSignaturesEqual(t, expectedSig, newSig) -} - func TestSignatureWithCertChain(t *testing.T) { payload := "this is the TestSignatureWithCertChain content!" b64sig := "b64 content3=" @@ -394,26 +358,6 @@ func TestSignatureWithEverything(t *testing.T) { LogID: "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d", }, } - timestamp := &tuf.Timestamp{ - Signatures: []data.Signature{ - { - KeyID: "b6710623a30c010738e64c5209d367df1c0a18cf90e6ab5292fb01680f83453d", - }, - }, - Signed: data.Timestamp{ - Type: "timestamp", - SpecVersion: "1.0", - Version: 8, - Meta: map[string]data.TimestampFileMeta{ - "snapshot.json": { - FileMeta: data.FileMeta{ - Length: 1658, - }, - Version: 8, - }, - }, - }, - } mediaType := types.MediaType("test/media.type") originalSig := mustCreateSignature(t, []byte(payload), b64sig) @@ -421,14 +365,12 @@ func TestSignatureWithEverything(t *testing.T) { expectedSig := mustCreateSignature(t, []byte(payload), b64sig, static.WithAnnotations(annotations), static.WithBundle(b), - static.WithTimestamp(timestamp), static.WithCertChain(testCertBytes, testChainBytes), static.WithLayerMediaType(mediaType)) newSig, err := Signature(originalSig, WithAnnotations(annotations), WithBundle(b), - WithTimestamp(timestamp), WithCertChain(testCertBytes, testChainBytes), WithMediaType(mediaType)) diff --git a/pkg/oci/signatures.go b/pkg/oci/signatures.go index c791d88ec9fe..e66b7c6c9e1f 100644 --- a/pkg/oci/signatures.go +++ b/pkg/oci/signatures.go @@ -20,7 +20,6 @@ import ( v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/sigstore/cosign/pkg/cosign/bundle" - "github.com/sigstore/cosign/pkg/cosign/tuf" ) // Signatures represents a set of signatures that are associated with a particular @@ -60,9 +59,4 @@ type Signature interface { // Bundle fetches the optional metadata that records the ephemeral // Fulcio key in the transparency log. Bundle() (*bundle.RekorBundle, error) - - // Timestamp fetches the optional TUF timestamp metadata that - // records when the signature was generated. This can be used - // to find the TUF targets used to generate the signature. - Timestamp() (*tuf.Timestamp, error) } diff --git a/pkg/oci/static/options.go b/pkg/oci/static/options.go index 03dc863a114d..e00b6cdb4e5e 100644 --- a/pkg/oci/static/options.go +++ b/pkg/oci/static/options.go @@ -20,7 +20,6 @@ import ( "github.com/google/go-containerregistry/pkg/v1/types" "github.com/sigstore/cosign/pkg/cosign/bundle" - "github.com/sigstore/cosign/pkg/cosign/tuf" ctypes "github.com/sigstore/cosign/pkg/types" ) @@ -34,7 +33,6 @@ type options struct { Cert []byte Chain []byte Annotations map[string]string - Timestamp *tuf.Timestamp } func makeOptions(opts ...Option) (*options, error) { @@ -61,14 +59,6 @@ func makeOptions(opts ...Option) (*options, error) { o.Annotations[BundleAnnotationKey] = string(b) } - if o.Timestamp != nil { - t, err := json.Marshal(o.Timestamp) - if err != nil { - return nil, err - } - o.Annotations[TimestampAnnotationKey] = string(t) - } - return o, nil } @@ -107,10 +97,3 @@ func WithCertChain(cert, chain []byte) Option { o.Chain = chain } } - -// WithTimestamp sets the TUF timestamp to attach to the signature -func WithTimestamp(t *tuf.Timestamp) Option { - return func(o *options) { - o.Timestamp = t - } -} diff --git a/pkg/oci/static/options_test.go b/pkg/oci/static/options_test.go index ca7081067c52..63600c791ab7 100644 --- a/pkg/oci/static/options_test.go +++ b/pkg/oci/static/options_test.go @@ -22,13 +22,11 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-containerregistry/pkg/v1/types" "github.com/sigstore/cosign/pkg/cosign/bundle" - "github.com/sigstore/cosign/pkg/cosign/tuf" ctypes "github.com/sigstore/cosign/pkg/types" ) func TestOptions(t *testing.T) { bundle := &bundle.RekorBundle{} - timestamp := &tuf.Timestamp{} tests := []struct { name string @@ -93,17 +91,6 @@ func TestOptions(t *testing.T) { }, Bundle: bundle, }, - }, { - name: "with timestamp", - opts: []Option{WithTimestamp(timestamp)}, - want: &options{ - LayerMediaType: ctypes.SimpleSigningMediaType, - ConfigMediaType: types.OCIConfigJSON, - Annotations: map[string]string{ - TimestampAnnotationKey: `{"signatures":null,"signed":{"_type":"","spec_version":"","version":0,"expires":"0001-01-01T00:00:00Z","meta":null}}`, - }, - Timestamp: timestamp, - }, }} for _, test := range tests { diff --git a/pkg/oci/static/signature.go b/pkg/oci/static/signature.go index 466f1eba99ae..882ff87e7df5 100644 --- a/pkg/oci/static/signature.go +++ b/pkg/oci/static/signature.go @@ -23,7 +23,6 @@ import ( v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/types" "github.com/sigstore/cosign/pkg/cosign/bundle" - "github.com/sigstore/cosign/pkg/cosign/tuf" "github.com/sigstore/cosign/pkg/oci" "github.com/sigstore/sigstore/pkg/cryptoutils" ) @@ -33,7 +32,6 @@ const ( CertificateAnnotationKey = "dev.sigstore.cosign/certificate" ChainAnnotationKey = "dev.sigstore.cosign/chain" BundleAnnotationKey = "dev.sigstore.cosign/bundle" - TimestampAnnotationKey = "dev.sigstore.cosign/timestamp" ) // NewSignature constructs a new oci.Signature from the provided options. @@ -112,11 +110,6 @@ func (l *staticLayer) Bundle() (*bundle.RekorBundle, error) { return l.opts.Bundle, nil } -// Timestamp implements oci.Signature -func (l *staticLayer) Timestamp() (*tuf.Timestamp, error) { - return l.opts.Timestamp, nil -} - // Digest implements v1.Layer func (l *staticLayer) Digest() (v1.Hash, error) { h, _, err := v1.SHA256(bytes.NewReader(l.b)) diff --git a/pkg/oci/static/signature_test.go b/pkg/oci/static/signature_test.go index affdbf5062ac..1ef5beccb1db 100644 --- a/pkg/oci/static/signature_test.go +++ b/pkg/oci/static/signature_test.go @@ -20,14 +20,11 @@ import ( "io" "strings" "testing" - "time" "github.com/google/go-cmp/cmp" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/types" "github.com/sigstore/cosign/pkg/cosign/bundle" - "github.com/sigstore/cosign/pkg/cosign/tuf" - "github.com/theupdateframework/go-tuf/data" ) func TestNewSignatureBasic(t *testing.T) { @@ -133,14 +130,6 @@ func TestNewSignatureBasic(t *testing.T) { if gotBundle != nil { t.Errorf("Bundle() = %#v, wanted nil", gotBundle) } - - gotTimestamp, err := l.Timestamp() - if err != nil { - t.Fatalf("Timestamp() = %v", err) - } - if gotTimestamp != nil { - t.Errorf("Timestamp() = %#v, wanted nil", gotTimestamp) - } }) t.Run("check annotations", func(t *testing.T) { @@ -179,12 +168,6 @@ func TestNewSignatureBasic(t *testing.T) { t.Errorf("Bundle() = %#v, wanted nil", got) } - if got, err := l.Timestamp(); err != nil { - t.Fatalf("Timestamp() = %v", err) - } else if got != nil { - t.Errorf("Timestamp() = %#v, wanted nil", got) - } - if got, err := l.Cert(); err != nil { t.Fatalf("Cert() = %v", err) } else if got != nil { @@ -301,14 +284,6 @@ func TestNewAttestationBasic(t *testing.T) { if gotBundle != nil { t.Errorf("Bundle() = %#v, wanted nil", gotBundle) } - - gotTimestamp, err := l.Timestamp() - if err != nil { - t.Fatalf("Timestamp() = %v", err) - } - if gotTimestamp != nil { - t.Errorf("Timestamp() = %#v, wanted nil", gotTimestamp) - } }) t.Run("check annotations", func(t *testing.T) { @@ -347,12 +322,6 @@ func TestNewAttestationBasic(t *testing.T) { t.Errorf("Bundle() = %#v, wanted nil", got) } - if got, err := l.Timestamp(); err != nil { - t.Fatalf("Timestamp() = %v", err) - } else if got != nil { - t.Errorf("Timestamp() = %#v, wanted nil", got) - } - if got, err := l.Cert(); err != nil { t.Fatalf("Cert() = %v", err) } else if got != nil { @@ -367,10 +336,9 @@ func TestNewAttestationBasic(t *testing.T) { }) } -func TestNewSignatureCertChainBundleAndTimestamp(t *testing.T) { +func TestNewSignatureCertChainAndBundle(t *testing.T) { payload := "this is the other content!" b64sig := "b64 content=" - ts, _ := time.Parse(time.RFC3339, "2022-01-15T00:39:22Z") // This was extracted from gcr.io/distroless/static:nonroot on 2021/09/16 var ( @@ -416,36 +384,10 @@ Hr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ== LogID: "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d", }, } - timestamp = &tuf.Timestamp{ - Signatures: []data.Signature{ - { - KeyID: "b6710623a30c010738e64c5209d367df1c0a18cf90e6ab5292fb01680f83453d", - Signature: []byte{48, 70, 2, 33, 0, 146, 108, 209, 165, 169, 5, 57, 243, 239, 169, 115, 144, 41, 49, 128, 19, 36, 19, 199, 211, 13, 148, 57, 156, 34, 10, 138, 154, 169, 144, 126, 110, 2, 33, 0, 158, 7, 176, 226, 7, 247, 109, 212, 92, 174, 171, 135, 37, 133, 83, 221, 207, 131, 252, 125, 182, 223, 187, 212, 103, 141, 24, 248, 195, 81, 112, 35}, - }, - }, - Signed: data.Timestamp{ - Type: "timestamp", - SpecVersion: "1.0", - Version: 8, - Expires: ts, - Meta: map[string]data.TimestampFileMeta{ - "snapshot.json": { - FileMeta: data.FileMeta{ - Length: 1658, - Hashes: map[string]data.HexBytes{ - "sha256": []byte{149, 229, 182, 130, 46, 12, 58, 153, 36, 242, 249, 6, 192, 183, 94, 9, 36, 106, 214, 211, 112, 120, 128, 96, 133, 162, 115, 253, 221, 7, 150, 121}, - "sha512": []byte{75, 29, 249, 242, 204, 45, 5, 43, 238, 24, 85, 84, 222, 215, 197, 38, 226, 131, 212, 250, 184, 56, 133, 87, 167, 182, 132, 196, 206, 14, 251, 40, 193, 150, 227, 58, 81, 64, 231, 222, 157, 233, 155, 47, 95, 55, 167, 178, 80, 54, 23, 194, 255, 34, 1, 104, 197, 183, 167, 147, 64, 103, 90, 207}, - }, - }, - Version: 8, - }, - }, - }, - } ) l, err := NewSignature([]byte(payload), b64sig, - WithCertChain(cert, chain), WithBundle(b), WithTimestamp(timestamp)) + WithCertChain(cert, chain), WithBundle(b)) if err != nil { t.Fatalf("NewSignature() = %v", err) } @@ -473,12 +415,6 @@ Hr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ== t.Errorf("Bundle() = %#v, wanted %#v", got, b) } - if got, err := l.Timestamp(); err != nil { - t.Fatalf("Timestamp() = %v", err) - } else if got != timestamp { - t.Errorf("Timestamp() = %#v, wanted %#v", got, timestamp) - } - if got, err := l.Cert(); err != nil { t.Fatalf("Cert() = %v", err) } else if got == nil { @@ -499,8 +435,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"}}`, - TimestampAnnotationKey: `{"signatures":[{"keyid":"b6710623a30c010738e64c5209d367df1c0a18cf90e6ab5292fb01680f83453d","sig":"3046022100926cd1a5a90539f3efa97390293180132413c7d30d94399c220a8a9aa9907e6e0221009e07b0e207f76dd45caeab87258553ddcf83fc7db6dfbbd4678d18f8c3517023"}],"signed":{"_type":"timestamp","spec_version":"1.0","version":8,"expires":"2022-01-15T00:39:22Z","meta":{"snapshot.json":{"length":1658,"hashes":{"sha256":"95e5b6822e0c3a9924f2f906c0b75e09246ad6d37078806085a273fddd079679","sha512":"4b1df9f2cc2d052bee185554ded7c526e283d4fab8388557a7b684c4ce0efb28c196e33a5140e7de9de99b2f5f37a7b2503617c2ff220168c5b7a79340675acf"},"version":8}}}}`, + BundleAnnotationKey: `{"SignedEntryTimestamp":"MEUCIQClUkUqZNf+6dxBc/pxq22JIluTB7Kmip1G0FIF5E0C1wIgLqXm+IM3JYW/P/qjMZSXW+J8bt5EOqNfe3R+0A9ooFE=","Payload":{"body":"REMOVED","integratedTime":1631646761,"logIndex":693591,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}}`, } got, err := l.Annotations() if err != nil { diff --git a/specs/SIGNATURE_SPEC.md b/specs/SIGNATURE_SPEC.md index 9bce4e7ff4bd..df3ede82e3f6 100644 --- a/specs/SIGNATURE_SPEC.md +++ b/specs/SIGNATURE_SPEC.md @@ -125,38 +125,6 @@ Gyp4apdU7AXEwysEQIb034aPrTlpmxh90SnTZFs2DHOvCjCPPAmoWfuQUwPhSPRb For instructions on using the `bundle` for verification, see [USAGE.md](../USAGE.md#verify-a-signature-was-added-to-the-transparency-log). -* `timestamp` string - - This OPTIONAL property contains JSON formatted [TUF timestamp metadata](https://theupdateframework.io/metadata/#timestamp-metadata-timestampjson), which is used to find which versioned TUF target should be used to verify a signature. - Example `timestamp`: - -```json -{ - "signatures": [ - { - "keyid": "b6710623a30c010738e64c5209d367df1c0a18cf90e6ab5292fb01680f83453d", - "sig": "3046022100926cd1a5a90539f3efa97390293180132413c7d30d94399c220a8a9aa9907e6e0221009e07b0e207f76dd45caeab87258553ddcf83fc7db6dfbbd4678d18f8c3517023" - } - ], - "signed": { - "_type": "timestamp", - "expires": "2022-01-15T00:39:22Z", - "meta": { - "snapshot.json": { - "hashes": { - "sha256": "95e5b6822e0c3a9924f2f906c0b75e09246ad6d37078806085a273fddd079679", - "sha512": "4b1df9f2cc2d052bee185554ded7c526e283d4fab8388557a7b684c4ce0efb28c196e33a5140e7de9de99b2f5f37a7b2503617c2ff220168c5b7a79340675acf" - }, - "length": 1658, - "version": 8 - } - }, - "spec_version": "1.0", - "version": 8 - } -} -``` - ## Storage `cosign` image signatures are stored in an OCI registry and are designed to make use of the existing specifications. @@ -272,19 +240,6 @@ Example `chain`: } ``` -##### Timestamp - -The `timestamp` is stored as an `annotation` on the layer, in the same descriptor. -The `annotation` key is `dev.cosignproject.cosign/timestamp`. - -Example `timestamp`: - -```json -"annotations": { - "dev.sigstore.cosign/timestamp": "{\"signatures\": [{\"keyid\": \"b6710623a30c010738e64c5209d367df1c0a18cf90e6ab5292fb01680f83453d\", \"sig\": \"3046022100926cd1a5a90539f3efa97390293180132413c7d30d94399c220a8a9aa9907e6e0221009e07b0e207f76dd45caeab87258553ddcf83fc7db6dfbbd4678d18f8c3517023\"}], \"signed\": {\"_type\": \"timestamp\", \"expires\": \"2022-01-15T00:39:22Z\", \"meta\": {\"snapshot.json\": {\"hashes\": {\"sha256\": \"95e5b6822e0c3a9924f2f906c0b75e09246ad6d37078806085a273fddd079679\", \"sha512\": \"4b1df9f2cc2d052bee185554ded7c526e283d4fab8388557a7b684c4ce0efb28c196e33a5140e7de9de99b2f5f37a7b2503617c2ff220168c5b7a79340675acf\"}, \"length\": 1658, \"version\": 8}}, \"spec_version\": \"1.0\", \"version\": 8}}" -} -``` - ## Payloads Implementations MUST support at least the following payload types: