Skip to content

Commit

Permalink
adding logic so policy signature can be checked against constraints
Browse files Browse the repository at this point in the history
Signed-off-by: chaosinthecrd <[email protected]>
  • Loading branch information
ChaosInTheCRD committed Jan 29, 2024
1 parent 027b47d commit e405a20
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 28 deletions.
30 changes: 4 additions & 26 deletions policy/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,35 +236,13 @@ func (step Step) checkFunctionaries(verifiedStatements []source.VerifiedCollecti
}

for _, verifier := range verifiedStatement.Verifiers {
verifierID, err := verifier.KeyID()
if err != nil {
log.Debugf("(policy) skipping verifier: could not get key id: %w", err)
continue
}

for _, functionary := range step.Functionaries {
if functionary.PublicKeyID != "" && functionary.PublicKeyID == verifierID {
collections = append(collections, verifiedStatement)
break
}

x509Verifier, ok := verifier.(*cryptoutil.X509Verifier)
if !ok {
log.Debugf("(policy) skipping verifier: verifier with ID %v is not a public key verifier or a x509 verifier", verifierID)
continue
}

if len(functionary.CertConstraint.Roots) == 0 {
log.Debugf("(policy) skipping verifier: verifier with ID %v is an x509 verifier, but step %v does not have any truested roots", verifierID, step)
continue
}

if err := functionary.CertConstraint.Check(x509Verifier, trustBundles); err != nil {
log.Debugf("(policy) skipping verifier: verifier with ID %v doesn't meet certificate constraint: %w", verifierID, err)
if err := functionary.Validate(verifier, trustBundles); err != nil {
log.Debugf("(policy) skipping verifier: %w", err)
continue
} else {
collections = append(collections, verifiedStatement)
}

collections = append(collections, verifiedStatement)
}
}
}
Expand Down
27 changes: 27 additions & 0 deletions policy/step.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"strings"

"github.com/in-toto/go-witness/attestation"
"github.com/in-toto/go-witness/cryptoutil"
"github.com/in-toto/go-witness/source"
)

Expand Down Expand Up @@ -80,6 +81,32 @@ type RejectedCollection struct {
Reason error
}

func (f Functionary) Validate(verifier cryptoutil.Verifier, trustBundles map[string]TrustBundle) error {
verifierID, err := verifier.KeyID()
if err != nil {
return fmt.Errorf("could not get key id: %w", err)
}

if f.PublicKeyID != "" && f.PublicKeyID == verifierID {
return nil
}

x509Verifier, ok := verifier.(*cryptoutil.X509Verifier)
if !ok {
return fmt.Errorf("verifier with ID %v is not a public key verifier or a x509 verifier", verifierID)
}

if len(f.CertConstraint.Roots) == 0 {
return fmt.Errorf("verifier with ID %v is an x509 verifier, but no trusted roots provided in functionary", verifierID)
}

if err := f.CertConstraint.Check(x509Verifier, trustBundles); err != nil {
return fmt.Errorf("verifier with ID %v doesn't meet certificate constraint: %w", verifierID, err)
}

return nil
}

// validateAttestations will test each collection against to ensure the expected attestations
// appear in the collection as well as that any rego policies pass for the step.
func (s Step) validateAttestations(verifiedCollections []source.VerifiedCollection) StepResult {
Expand Down
59 changes: 57 additions & 2 deletions verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ package witness
import (
"context"
"crypto/x509"
"encoding/base64"
"encoding/json"
"fmt"
"io"

"github.com/in-toto/go-witness/cryptoutil"
"github.com/in-toto/go-witness/dsse"
"github.com/in-toto/go-witness/log"
"github.com/in-toto/go-witness/policy"
"github.com/in-toto/go-witness/source"
"github.com/in-toto/go-witness/timestamp"
Expand Down Expand Up @@ -97,10 +99,12 @@ func Verify(ctx context.Context, policyEnvelope dsse.Envelope, policyVerifiers [
opt(&vo)
}

if _, err := vo.policyEnvelope.Verify(dsse.VerifyWithVerifiers(vo.policyVerifiers...), dsse.VerifyWithTimestampVerifiers(vo.policyTimestampAuthorities...), dsse.VerifyWithRoots(vo.policyCARoots...), dsse.VerifyWithIntermediates(vo.policyCAIntermediates...)); err != nil {
return nil, fmt.Errorf("could not verify policy: %w", err)
if err := verifyPolicySignature(ctx, vo); err != nil {
return nil, fmt.Errorf("failed to verify policy signature: %w", err)
}

log.Info("Policy signature verification passed")

pol := policy.Policy{}
if err := json.Unmarshal(vo.policyEnvelope.Payload, &pol); err != nil {
return nil, fmt.Errorf("failed to unmarshal policy from envelope: %w", err)
Expand Down Expand Up @@ -154,3 +158,54 @@ func Verify(ctx context.Context, policyEnvelope dsse.Envelope, policyVerifiers [

return accepted, nil
}

func verifyPolicySignature(ctx context.Context, vo verifyOptions) error {
passedPolicyVerifiers, err := vo.policyEnvelope.Verify(dsse.VerifyWithVerifiers(vo.policyVerifiers...), dsse.VerifyWithTimestampVerifiers(vo.policyTimestampAuthorities...), dsse.VerifyWithRoots(vo.policyCARoots...), dsse.VerifyWithIntermediates(vo.policyCAIntermediates...))
if err != nil {
return fmt.Errorf("could not verify policy: %w", err)
}

var passed bool
for _, verifier := range passedPolicyVerifiers {
kid, err := verifier.Verifier.KeyID()
if err != nil {
return fmt.Errorf("could not get verifier key id: %w", err)
}
v, ok := verifier.Verifier.(*cryptoutil.X509Verifier)
if !ok {
log.Debug("Policy Verifier %s is not an X509Verifier, continuing...", kid)
}

rootIDs := make([]string, 0)
trustBundle := make(map[string]policy.TrustBundle)
for _, root := range vo.policyCARoots {
id := base64.StdEncoding.EncodeToString(root.Raw)
rootIDs = append(rootIDs, id)
trustBundle[id] = policy.TrustBundle{
Root: root,
}
}

f := policy.Functionary{
Type: "root",
CertConstraint: policy.CertConstraint{
Roots: rootIDs,
CommonName: "*",
},
}

err = f.Validate(v, trustBundle)
if err != nil {
log.Debugf("Policy Verifier %s failed failed to match supplied constraints: %w, continuing...", err, kid)

Check failure on line 199 in verify.go

View workflow job for this annotation

GitHub Actions / sast / witness

github.com/in-toto/go-witness/log.Debugf format %w has arg kid of wrong type string

Check failure on line 199 in verify.go

View workflow job for this annotation

GitHub Actions / unit-test / witness

github.com/in-toto/go-witness/log.Debugf format %w has arg kid of wrong type string
continue
}

passed = true
}

if !passed {
return fmt.Errorf("no policy verifiers passed verification")
} else {
return nil
}
}

0 comments on commit e405a20

Please sign in to comment.