diff --git a/pkg/verify/signature.go b/pkg/verify/signature.go index c7056c4..26db76a 100644 --- a/pkg/verify/signature.go +++ b/pkg/verify/signature.go @@ -24,6 +24,7 @@ import ( "hash" "io" + in_toto "github.com/in-toto/attestation/go/v1" "github.com/secure-systems-lab/go-securesystemslib/dsse" "github.com/sigstore/sigstore-go/pkg/root" "github.com/sigstore/sigstore/pkg/signature" @@ -142,6 +143,11 @@ func verifyEnvelopeWithArtifact(verifier signature.Verifier, envelope EnvelopeCo if err != nil { return fmt.Errorf("could not verify artifact: unable to extract statement from envelope: %w", err) } + err = limitSubjects(statement) + if err != nil { + return err + } + var artifactDigestAlgorithm string var artifactDigest []byte @@ -182,17 +188,8 @@ func verifyEnvelopeWithArtifact(verifier signature.Verifier, envelope EnvelopeCo } artifactDigest = hasher.Sum(nil) - // limit the number of subjects to prevent DoS - if len(statement.Subject) > maxAllowedSubjects { - return fmt.Errorf("too many subjects: %d > %d", len(statement.Subject), maxAllowedSubjects) - } - // Look for artifact digest in statement for _, subject := range statement.Subject { - // limit the number of digests to prevent DoS - if len(subject.Digest) > maxAllowedSubjectDigests { - return fmt.Errorf("too many digests: %d > %d", len(subject.Digest), maxAllowedSubjectDigests) - } for alg, digest := range subject.Digest { hexdigest, err := hex.DecodeString(digest) if err != nil { @@ -215,17 +212,12 @@ func verifyEnvelopeWithArtifactDigest(verifier signature.Verifier, envelope Enve if err != nil { return fmt.Errorf("could not verify artifact: unable to extract statement from envelope: %w", err) } - - // limit the number of subjects to prevent DoS - if len(statement.Subject) > maxAllowedSubjects { - return fmt.Errorf("too many subjects: %d > %d", len(statement.Subject), maxAllowedSubjects) + err = limitSubjects(statement) + if err != nil { + return err } for _, subject := range statement.Subject { - // limit the number of digests to prevent DoS - if len(subject.Digest) > maxAllowedSubjectDigests { - return fmt.Errorf("too many digests: %d > %d", len(subject.Digest), maxAllowedSubjectDigests) - } for alg, digest := range subject.Digest { if alg == artifactDigestAlgorithm { hexdigest, err := hex.DecodeString(digest) @@ -265,3 +257,17 @@ func verifyMessageSignatureWithArtifactDigest(verifier signature.Verifier, msg M return nil } + +// limitSubjects limits the number of subjects and digests in a statement to prevent DoS. +func limitSubjects(statement *in_toto.Statement) error { + if len(statement.Subject) > maxAllowedSubjects { + return fmt.Errorf("too many subjects: %d > %d", len(statement.Subject), maxAllowedSubjects) + } + for _, subject := range statement.Subject { + // limit the number of digests too + if len(subject.Digest) > maxAllowedSubjectDigests { + return fmt.Errorf("too many digests: %d > %d", len(subject.Digest), maxAllowedSubjectDigests) + } + } + return nil +}