diff --git a/cmd/cosign/cli/attest/attest_blob.go b/cmd/cosign/cli/attest/attest_blob.go index 8bd71686015..50795215e66 100644 --- a/cmd/cosign/cli/attest/attest_blob.go +++ b/cmd/cosign/cli/attest/attest_blob.go @@ -165,21 +165,7 @@ func (c *AttestBlobCommand) Exec(ctx context.Context, artifactPath string) error var rekorEntry *models.LogEntryAnon if c.TSAServerURL != "" { - // sig is the entire JSON DSSE Envelope; we just want the signature for TSA - var envelope dsse.Envelope - err = json.Unmarshal(sig, &envelope) - if err != nil { - return err - } - if len(envelope.Signatures) == 0 { - return fmt.Errorf("envelope has no signatures") - } - envelopeSigBytes, err := base64.StdEncoding.DecodeString(envelope.Signatures[0].Sig) - if err != nil { - return err - } - - timestampBytes, err = tsa.GetTimestampedSignature(envelopeSigBytes, client.NewTSAClient(c.TSAServerURL)) + timestampBytes, err = tsa.GetTimestampedSignature(sig, client.NewTSAClient(c.TSAServerURL)) if err != nil { return err } diff --git a/cmd/cosign/cli/verify/verify_bundle_test.go b/cmd/cosign/cli/verify/verify_bundle_test.go new file mode 100644 index 00000000000..04dfc82334b --- /dev/null +++ b/cmd/cosign/cli/verify/verify_bundle_test.go @@ -0,0 +1,91 @@ +// +// Copyright 2024 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 verify + +import ( + "context" + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/sha256" + "crypto/x509" + "encoding/pem" + "os" + "path/filepath" + "testing" + + "github.com/sigstore/cosign/v2/pkg/signature" +) + +func TestVerifyBundleWithKey(t *testing.T) { + // First assemble bundle + ctx := context.Background() + artifact := "hello world" + digest := sha256.Sum256([]byte(artifact)) + + privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + checkErr(t, err) + sigBytes, err := privateKey.Sign(rand.Reader, digest[:], crypto.SHA256) + checkErr(t, err) + + td := t.TempDir() + artifactPath := filepath.Join(td, "artifact") + err = os.WriteFile(artifactPath, []byte(artifact), 0600) + checkErr(t, err) + + pubKeyBytes, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey) + checkErr(t, err) + pemBlock := &pem.Block{ + Type: "PUBLIC KEY", + Bytes: pubKeyBytes, + } + verifier, err := signature.LoadPublicKeyRaw( + pem.EncodeToMemory(pemBlock), crypto.SHA256, + ) + checkErr(t, err) + + bundle, err := assembleNewBundle(ctx, sigBytes, nil, nil, artifactPath, nil, + true, verifier, nil, nil, + ) + checkErr(t, err) + + if bundle == nil { + t.Fatal("invalid bundle") + } + + // The verify assembled bundle + trustedRootPath := filepath.Join(td, "trusted_root.json") + err = os.WriteFile(trustedRootPath, []byte(`{"mediaType":"application/vnd.dev.sigstore.trustedroot+json;version=0.1"}`), 0600) + checkErr(t, err) + + publicKeyPath := filepath.Join(td, "key.pub") + err = os.WriteFile(publicKeyPath, pem.EncodeToMemory(pemBlock), 0600) + checkErr(t, err) + + result, err := verifyNewBundle(ctx, bundle, trustedRootPath, publicKeyPath, "", "", "", "", "", "", "", "", "", "", artifactPath, false, true, false, true) + checkErr(t, err) + + if result == nil { + t.Fatal("invalid verification result") + } +} + +func checkErr(t *testing.T, err error) { + if err != nil { + t.Fatal(err) + } +}