diff --git a/policy/policy.go b/policy/policy.go index 81a4f34b..dfac8358 100644 --- a/policy/policy.go +++ b/policy/policy.go @@ -217,30 +217,30 @@ func (p Policy) Verify(ctx context.Context, opts ...VerifyOption) (bool, map[str resultsByStep := make(map[string]StepResult) for depth := 0; depth < vo.searchDepth; depth++ { for stepName, step := range p.Steps { - // Use search to get all the attestations that match the supplied step name and subjects + // initialize the result for this step if it hasn't been already + if _, ok := resultsByStep[stepName]; !ok { + resultsByStep[stepName] = StepResult{Step: stepName} + } + collections, err := vo.verifiedSource.Search(ctx, stepName, vo.subjectDigests, attestationsByStep[stepName]) if err != nil { return false, nil, err } if len(collections) == 0 { - collections = append(collections, source.CollectionVerificationResult{Errors: []error{ErrNoCollections{Step: stepName}}}) + continue } - // Verify the functionaries + // Verify the functionaries and validate attestations collections = step.checkFunctionaries(collections, trustBundles) - stepResult := step.validateAttestations(collections) - // We perform many searches against the same step, so we need to merge the relevant fields - if resultsByStep[stepName].Step == "" { - resultsByStep[stepName] = stepResult - } else { - if result, ok := resultsByStep[stepName]; ok { - result.Passed = append(result.Passed, stepResult.Passed...) - result.Rejected = append(result.Rejected, stepResult.Rejected...) - resultsByStep[stepName] = result - } + // Merge the results + if result, ok := resultsByStep[stepName]; ok { + result.Passed = append(result.Passed, stepResult.Passed...) + result.Rejected = append(result.Rejected, stepResult.Rejected...) + + resultsByStep[stepName] = result } for _, coll := range stepResult.Passed { @@ -303,13 +303,6 @@ func (p Policy) verifyArtifacts(resultsByStep map[string]StepResult) (map[string for _, step := range p.Steps { accepted := false if len(resultsByStep[step.Name].Passed) == 0 { - if result, ok := resultsByStep[step.Name]; ok { - result.Rejected = append(result.Rejected, RejectedCollection{Reason: fmt.Errorf("failed to verify artifacts for step %s: no passed collections present", step.Name)}) - resultsByStep[step.Name] = result - } else { - return nil, fmt.Errorf("failed to find step %s in step results map", step.Name) - } - continue } diff --git a/policy/step.go b/policy/step.go index 5cd5630d..1dae6fd7 100644 --- a/policy/step.go +++ b/policy/step.go @@ -184,7 +184,7 @@ func (s Step) validateAttestations(collectionResults []source.CollectionVerifica if passed { result.Passed = append(result.Passed, collection) } else { - r := strings.Join(reasons, ",\n - ") + r := strings.Join(reasons, "\n - ") reason := fmt.Sprintf("collection validation failed:\n - %s", r) result.Rejected = append(result.Rejected, RejectedCollection{ Collection: collection, diff --git a/source/memory.go b/source/memory.go index 8f7450e7..ee40f43e 100644 --- a/source/memory.go +++ b/source/memory.go @@ -22,6 +22,7 @@ import ( "os" "github.com/in-toto/go-witness/dsse" + "github.com/in-toto/go-witness/log" ) type ErrDuplicateReference string @@ -31,6 +32,7 @@ func (e ErrDuplicateReference) Error() string { } type MemorySource struct { + searched bool envelopesByReference map[string]CollectionEnvelope referencesByCollectionName map[string][]string subjectDigestsByReference map[string]map[string]struct{} @@ -39,6 +41,7 @@ type MemorySource struct { func NewMemorySource() *MemorySource { return &MemorySource{ + searched: false, envelopesByReference: make(map[string]CollectionEnvelope), referencesByCollectionName: make(map[string][]string), subjectDigestsByReference: make(map[string]map[string]struct{}), @@ -104,6 +107,13 @@ func (s *MemorySource) LoadEnvelope(reference string, env dsse.Envelope) error { } func (s *MemorySource) Search(ctx context.Context, collectionName string, subjectDigests, attestations []string) ([]CollectionEnvelope, error) { + if s.searched { + log.Debug("skipping memory source search: already performed") + return []CollectionEnvelope{}, nil + } else { + s.searched = true + } + matches := make([]CollectionEnvelope, 0) for _, potentialMatchReference := range s.referencesByCollectionName[collectionName] { env, ok := s.envelopesByReference[potentialMatchReference] @@ -125,20 +135,6 @@ func (s *MemorySource) Search(ctx context.Context, collectionName string, subjec continue } - // make sure all the expected attestations appear in the collection - attestationsMatched := true - indexAttestations := s.attestationsByReference[potentialMatchReference] - for _, checkAttestation := range attestations { - if _, ok := indexAttestations[checkAttestation]; !ok { - attestationsMatched = false - break - } - } - - if !attestationsMatched { - continue - } - matches = append(matches, env) }