Skip to content

Commit

Permalink
This commit addresses the issue of artifacts which have (tektoncd#676)
Browse files Browse the repository at this point in the history
sha1 digest not being added into materials.

Before this fix checkDigest would only check if the digest was
sha256 and would reject other digests.
This commit fixes checkDigest to ensue that it accepts all
valid digests of type sha256, sha512, sha384 and sha1.

Signed-off-by: jagathprakash <[email protected]>

Signed-off-by: jagathprakash <[email protected]>
  • Loading branch information
jagathprakash committed Jan 24, 2023
1 parent e075201 commit 9273c34
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 15 deletions.
9 changes: 4 additions & 5 deletions cmd/controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ limitations under the License.
package main

import (
"flag"

"github.com/tektoncd/chains/pkg/reconciler/pipelinerun"
"github.com/tektoncd/chains/pkg/reconciler/taskrun"
"knative.dev/pkg/injection"
Expand All @@ -35,11 +33,12 @@ import (
_ "github.com/sigstore/sigstore/pkg/signature/kms/hashivault"
)

var namespace = flag.String("namespace", "", "Namespace to restrict informer to. Optional, defaults to all namespaces.")
// var namespace = flag.String("namespace", "", "Namespace to restrict informer to. Optional, defaults to all namespaces.")
var namespace = ""

func main() {
flag.Parse()
ctx := injection.WithNamespaceScope(signals.NewContext(), *namespace)
// flag.Parse()
ctx := injection.WithNamespaceScope(signals.NewContext(), namespace)

sharedmain.MainWithContext(ctx, "watcher", taskrun.NewController, pipelinerun.NewController)
}
34 changes: 28 additions & 6 deletions pkg/artifacts/signable.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ package artifacts

import (
_ "crypto/sha256" // Recommended by go-digest.
_ "crypto/sha512" // Recommended by go-digest.
"fmt"
"regexp"
"strings"

"github.com/google/go-containerregistry/pkg/name"
Expand All @@ -33,6 +35,10 @@ const (
ArtifactsOutputsResultName = "ARTIFACT_OUTPUTS"
)

var (
Sha1Regexp *regexp.Regexp = regexp.MustCompile(`^[a-f0-9]{40}$`)
)

type Signable interface {
ExtractObjects(obj objects.TektonObject) []interface{}
StorageBackend(cfg config.Config) sets.String
Expand Down Expand Up @@ -339,6 +345,7 @@ func ExtractStructuredTargetFromResults(obj objects.TektonObject, categoryMarker
logger.Debugf("ExtractStructuredTargetFromResults: %v", err)
}
if valid {
logger.Debugf("Extracted Structured data from Result %s, %s", res.Value.ObjectVal["uri"], res.Value.ObjectVal["digest"])
objs = append(objs, &StructuredSignable{URI: res.Value.ObjectVal["uri"], Digest: res.Value.ObjectVal["digest"]})
}
}
Expand Down Expand Up @@ -366,13 +373,28 @@ func isStructuredResult(res objects.Result, categoryMarker string) (bool, error)
}

func checkDigest(dig string) error {
prefix := digest.Canonical.String() + ":"
if !strings.HasPrefix(dig, prefix) {
return fmt.Errorf("unsupported digest algorithm: %s", dig)
parts := strings.Split(dig, ":")
if len(parts) != 2 {
return fmt.Errorf("digest string %s, not in the format of <algorithm>:<digest>", dig)
}
hex := strings.TrimPrefix(dig, prefix)
if err := digest.Canonical.Validate(hex); err != nil {
return err
algo_string := strings.ToLower(strings.TrimSpace(parts[0]))
algo := digest.Algorithm(algo_string)
hex := strings.TrimSpace(parts[1])

switch {
case algo.Available():
if err := algo.Validate(hex); err != nil {
return err
}
case algo_string == "sha1":
// Version 1.0.0, which is the released version, of go_digest does not support SHA1,
// hence this has to be handled differently.
if !Sha1Regexp.MatchString(hex) {
return fmt.Errorf("sha1 digest %s does not match regexp %s", dig, Sha1Regexp.String())
}
default:
return fmt.Errorf("unsupported digest algorithm: %s", dig)

}
return nil
}
Expand Down
59 changes: 55 additions & 4 deletions pkg/artifacts/signable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,16 @@ import (
)

const (
digest1 = "sha256:05f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b5"
digest2 = "sha256:05f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b6"
digest3 = "sha256:05f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b7"
digest4 = "sha256:05f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b8"
digest1 = "sha256:05f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b5"
digest2 = "sha256:05f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b6"
digest3 = "sha256:05f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b7"
digest4 = "sha256:05f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b8"
digest_sha384 = "sha384:05f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b893c56eeba9ec70f74c9bfd297d951664"
digest_sha512 = "sha512:05f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b805f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b8"
digest_sha1 = "sha1:93c56eeba9ec70f74c9bfd297d9516642d366cb5"
digest_incorrect_sha1 = "sha1:93c56eeba9ec70f74c9bfd297d9516642d366c5"
digest_incorrect_sha512 = "sha512:05f95b26ed1066b7183c1e2da98610e91372fa9f510046d4ce5812addad86b805f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b8"
digest_incorrect_sha384 = "sha384:0595b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b893c56eeba9ec70f74c9bfd297d951664"
)

var ignore = []cmp.Option{cmpopts.IgnoreUnexported(name.Registry{}, name.Repository{}, name.Digest{})}
Expand Down Expand Up @@ -412,6 +418,48 @@ func TestExtractStructuredTargetFromResults(t *testing.T) {
"digest": digest3,
}),
},
{
Name: "img2_input_sha1" + "_" + ArtifactsInputsResultName,
Value: *v1beta1.NewObject(map[string]string{
"uri": "gcr.io/foo/bar",
"digest": digest_sha1,
}),
},
{
Name: "img2_input_incorrect_sha1" + "_" + ArtifactsInputsResultName,
Value: *v1beta1.NewObject(map[string]string{
"uri": "gcr.io/foo/bar",
"digest": digest_incorrect_sha1,
}),
},
{
Name: "img3_input_sha384" + "_" + ArtifactsInputsResultName,
Value: *v1beta1.NewObject(map[string]string{
"uri": "gcr.io/foo/bar",
"digest": digest_sha384,
}),
},
{
Name: "img3_input_incorrect_sha384" + "_" + ArtifactsInputsResultName,
Value: *v1beta1.NewObject(map[string]string{
"uri": "gcr.io/foo/bar",
"digest": digest_incorrect_sha384,
}),
},
{
Name: "img4_input_sha512" + "_" + ArtifactsInputsResultName,
Value: *v1beta1.NewObject(map[string]string{
"uri": "gcr.io/foo/bar",
"digest": digest_sha512,
}),
},
{
Name: "img4_input_incorrect_sha512" + "_" + ArtifactsInputsResultName,
Value: *v1beta1.NewObject(map[string]string{
"uri": "gcr.io/foo/bar",
"digest": digest_incorrect_sha512,
}),
},
{
Name: "img2_input_no_digest" + "_" + ArtifactsInputsResultName,
Value: *v1beta1.NewObject(map[string]string{
Expand All @@ -426,6 +474,9 @@ func TestExtractStructuredTargetFromResults(t *testing.T) {

wantInputs := []*StructuredSignable{
{URI: "gcr.io/foo/bar", Digest: digest3},
{URI: "gcr.io/foo/bar", Digest: digest_sha1},
{URI: "gcr.io/foo/bar", Digest: digest_sha384},
{URI: "gcr.io/foo/bar", Digest: digest_sha512},
}
gotInputs := ExtractStructuredTargetFromResults(objects.NewTaskRunObject(tr), ArtifactsInputsResultName, logtesting.TestLogger(t))
if diff := cmp.Diff(gotInputs, wantInputs, cmpopts.SortSlices(func(x, y *StructuredSignable) bool { return x.Digest < y.Digest })); diff != "" {
Expand Down

0 comments on commit 9273c34

Please sign in to comment.