From 0b28c0f52c40cdac5e3a15151ca360d965929086 Mon Sep 17 00:00:00 2001 From: Tom Meadows Date: Wed, 17 Jan 2024 19:12:57 +0000 Subject: [PATCH] Adding support for using timestamp authority and CA certificates for verifying policy (#124) * fixing a couple of things * renamed fields and added intermediates for verify --------- Signed-off-by: chaosinthecrd --- dsse/dsse.go | 4 ++-- dsse/dsse_test.go | 2 +- dsse/verify.go | 8 +++++++- verify.go | 25 ++++++++++++++++++++----- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/dsse/dsse.go b/dsse/dsse.go index 34d4796f..65a16926 100644 --- a/dsse/dsse.go +++ b/dsse/dsse.go @@ -32,11 +32,11 @@ func (e ErrNoMatchingSigs) Error() string { type ErrThresholdNotMet struct { Theshold int - Acutal int + Actual int } func (e ErrThresholdNotMet) Error() string { - return fmt.Sprintf("envelope did not meet verifier threshold. expected %v valid verifiers but got %v", e.Theshold, e.Acutal) + return fmt.Sprintf("envelope did not meet verifier threshold. expected %v valid verifiers but got %v", e.Theshold, e.Actual) } type ErrInvalidThreshold int diff --git a/dsse/dsse_test.go b/dsse/dsse_test.go index 7a63e251..a23b01f2 100644 --- a/dsse/dsse_test.go +++ b/dsse/dsse_test.go @@ -217,7 +217,7 @@ func TestThreshold(t *testing.T) { assert.ElementsMatch(t, approvedVerifiers, expectedVerifiers) approvedVerifiers, err = env.Verify(VerifyWithVerifiers(verifiers...), VerifyWithThreshold(10)) - require.ErrorIs(t, err, ErrThresholdNotMet{Acutal: 5, Theshold: 10}) + require.ErrorIs(t, err, ErrThresholdNotMet{Actual: 5, Theshold: 10}) assert.ElementsMatch(t, approvedVerifiers, expectedVerifiers) _, err = env.Verify(VerifyWithVerifiers(verifiers...), VerifyWithThreshold(-10)) diff --git a/dsse/verify.go b/dsse/verify.go index b74c24ed..328a23fd 100644 --- a/dsse/verify.go +++ b/dsse/verify.go @@ -22,6 +22,7 @@ import ( "time" "github.com/in-toto/go-witness/cryptoutil" + "github.com/in-toto/go-witness/log" ) type TimestampVerifier interface { @@ -115,6 +116,8 @@ func (e Envelope) Verify(opts ...VerificationOption) ([]PassedVerifier, error) { if verifier, err := verifyX509Time(cert, sigIntermediates, options.roots, pae, sig.Signature, time.Now()); err == nil { matchingSigFound = true passedVerifiers = append(passedVerifiers, PassedVerifier{Verifier: verifier}) + } else { + log.Debugf("failed to verify with timestamp verifier: %w", err) } } else { var passedVerifier cryptoutil.Verifier @@ -130,7 +133,10 @@ func (e Envelope) Verify(opts ...VerificationOption) ([]PassedVerifier, error) { if verifier, err := verifyX509Time(cert, sigIntermediates, options.roots, pae, sig.Signature, timestamp); err == nil { passedVerifier = verifier passedTimestampVerifiers = append(passedTimestampVerifiers, timestampVerifier) + } else { + log.Debugf("failed to verify with timestamp verifier: %w", err) } + } } @@ -159,7 +165,7 @@ func (e Envelope) Verify(opts ...VerificationOption) ([]PassedVerifier, error) { } if len(passedVerifiers) < options.threshold { - return passedVerifiers, ErrThresholdNotMet{Theshold: options.threshold, Acutal: len(passedVerifiers)} + return passedVerifiers, ErrThresholdNotMet{Theshold: options.threshold, Actual: len(passedVerifiers)} } return passedVerifiers, nil diff --git a/verify.go b/verify.go index bb20df6b..68cd5c76 100644 --- a/verify.go +++ b/verify.go @@ -40,10 +40,13 @@ func VerifySignature(r io.Reader, verifiers ...cryptoutil.Verifier) (dsse.Envelo } type verifyOptions struct { - policyEnvelope dsse.Envelope - policyVerifiers []cryptoutil.Verifier - collectionSource source.Sourcer - subjectDigests []string + policyTimestampAuthorities []dsse.TimestampVerifier + policyCARoots []*x509.Certificate + policyCAIntermediates []*x509.Certificate + policyEnvelope dsse.Envelope + policyVerifiers []cryptoutil.Verifier + collectionSource source.Sourcer + subjectDigests []string } type VerifyOption func(*verifyOptions) @@ -64,6 +67,18 @@ func VerifyWithCollectionSource(source source.Sourcer) VerifyOption { } } +func VerifyWithPolicyTimestampAuthorities(authorities []dsse.TimestampVerifier) VerifyOption { + return func(vo *verifyOptions) { + vo.policyTimestampAuthorities = authorities + } +} + +func VerifyWithPolicyCARoots(roots []*x509.Certificate) VerifyOption { + return func(vo *verifyOptions) { + vo.policyCARoots = roots + } +} + // Verify verifies a set of attestations against a provided policy. The set of attestations that satisfy the policy will be returned // if verifiation is successful. func Verify(ctx context.Context, policyEnvelope dsse.Envelope, policyVerifiers []cryptoutil.Verifier, opts ...VerifyOption) (map[string][]source.VerifiedCollection, error) { @@ -76,7 +91,7 @@ func Verify(ctx context.Context, policyEnvelope dsse.Envelope, policyVerifiers [ opt(&vo) } - if _, err := vo.policyEnvelope.Verify(dsse.VerifyWithVerifiers(vo.policyVerifiers...)); err != nil { + 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) }