From e4cef426fc4e249e0ac61cbe89e43d15280ae70b Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 22 Jan 2025 11:28:16 +0800 Subject: [PATCH 1/3] updated verifier Signed-off-by: Patrick Zheng --- example_verifyBlob_test.go | 4 ++- verifier/verifier.go | 43 ++++++++++++++++-------- verifier/verifier_test.go | 68 ++++++++++++++++++++++++-------------- 3 files changed, 76 insertions(+), 39 deletions(-) diff --git a/example_verifyBlob_test.go b/example_verifyBlob_test.go index 4d5952d8..d283340f 100644 --- a/example_verifyBlob_test.go +++ b/example_verifyBlob_test.go @@ -61,7 +61,9 @@ func Example_verifyBlob() { } // exampleVerifier implements [notation.Verify] and [notation.VerifyBlob]. - exampleVerifier, err := verifier.NewVerifier(nil, &exampleBlobPolicyDocument, truststore.NewX509TrustStore(dir.ConfigFS()), nil) + exampleVerifier, err := verifier.NewVerifierWithOptions(truststore.NewX509TrustStore(dir.ConfigFS()), verifier.VerifierOptions{ + BlobTrustPolicy: &exampleBlobPolicyDocument, + }) if err != nil { panic(err) // Handle error } diff --git a/verifier/verifier.go b/verifier/verifier.go index b7aa49d1..6fedcb31 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -88,6 +88,15 @@ type VerifierOptions struct { // RevocationTimestampingValidator is used for verifying revocation of // timestamping certificate chain with context. RevocationTimestampingValidator revocation.Validator + + // OCITrustpolicy is the trust policy document for OCI artifacts. + OCITrustPolicy *trustpolicy.OCIDocument + + // BlobTrustPolicy is the trust policy document for Blob artifacts. + BlobTrustPolicy *trustpolicy.BlobDocument + + // PluginManager manages plugins installed on the system. + PluginManager plugin.Manager } // NewOCIVerifierFromConfig returns an OCI verifier based on local file system @@ -100,7 +109,10 @@ func NewOCIVerifierFromConfig() (*verifier, error) { // load trust store x509TrustStore := truststore.NewX509TrustStore(dir.ConfigFS()) - return NewVerifier(policyDocument, nil, x509TrustStore, plugin.NewCLIManager(dir.PluginFS())) + return NewVerifierWithOptions(x509TrustStore, VerifierOptions{ + OCITrustPolicy: policyDocument, + PluginManager: plugin.NewCLIManager(dir.PluginFS()), + }) } // NewBlobVerifierFromConfig returns a Blob verifier based on local file system @@ -113,7 +125,10 @@ func NewBlobVerifierFromConfig() (*verifier, error) { // load trust store x509TrustStore := truststore.NewX509TrustStore(dir.ConfigFS()) - return NewVerifier(nil, policyDocument, x509TrustStore, plugin.NewCLIManager(dir.PluginFS())) + return NewVerifierWithOptions(x509TrustStore, VerifierOptions{ + BlobTrustPolicy: policyDocument, + PluginManager: plugin.NewCLIManager(dir.PluginFS()), + }) } // NewWithOptions creates a new verifier given ociTrustPolicy, trustStore, @@ -122,18 +137,17 @@ func NewBlobVerifierFromConfig() (*verifier, error) { // Deprecated: NewWithOptions function exists for historical compatibility and // should not be used. To create verifier, use [NewVerifierWithOptions] function. func NewWithOptions(ociTrustPolicy *trustpolicy.OCIDocument, trustStore truststore.X509TrustStore, pluginManager plugin.Manager, opts VerifierOptions) (notation.Verifier, error) { - return NewVerifierWithOptions(ociTrustPolicy, nil, trustStore, pluginManager, opts) -} - -// NewVerifier creates a new verifier given ociTrustPolicy, trustStore and -// pluginManager -func NewVerifier(ociTrustPolicy *trustpolicy.OCIDocument, blobTrustPolicy *trustpolicy.BlobDocument, trustStore truststore.X509TrustStore, pluginManager plugin.Manager) (*verifier, error) { - return NewVerifierWithOptions(ociTrustPolicy, blobTrustPolicy, trustStore, pluginManager, VerifierOptions{}) + opts.OCITrustPolicy = ociTrustPolicy + opts.PluginManager = pluginManager + return NewVerifierWithOptions(trustStore, opts) } -// NewVerifierWithOptions creates a new verifier given ociTrustPolicy, -// blobTrustPolicy, trustStore, pluginManager, and verifierOptions -func NewVerifierWithOptions(ociTrustPolicy *trustpolicy.OCIDocument, blobTrustPolicy *trustpolicy.BlobDocument, trustStore truststore.X509TrustStore, pluginManager plugin.Manager, verifierOptions VerifierOptions) (*verifier, error) { +// NewVerifierWithOptions creates a new verifier given trustStore and +// verifierOptions. +func NewVerifierWithOptions(trustStore truststore.X509TrustStore, verifierOptions VerifierOptions) (*verifier, error) { + ociTrustPolicy := verifierOptions.OCITrustPolicy + blobTrustPolicy := verifierOptions.BlobTrustPolicy + pluginManager := verifierOptions.PluginManager if trustStore == nil { return nil, errors.New("trustStore cannot be nil") } @@ -177,7 +191,10 @@ func NewFromConfig() (notation.Verifier, error) { // Deprecated: New function exists for historical compatibility and // should not be used. To create verifier, use [NewVerifier] function. func New(ociTrustPolicy *trustpolicy.OCIDocument, trustStore truststore.X509TrustStore, pluginManager plugin.Manager) (notation.Verifier, error) { - return NewVerifier(ociTrustPolicy, nil, trustStore, pluginManager) + return NewVerifierWithOptions(trustStore, VerifierOptions{ + OCITrustPolicy: ociTrustPolicy, + PluginManager: pluginManager, + }) } // setRevocation sets revocation validators of v diff --git a/verifier/verifier_test.go b/verifier/verifier_test.go index faac221b..a1ee9732 100644 --- a/verifier/verifier_test.go +++ b/verifier/verifier_test.go @@ -728,9 +728,13 @@ func TestNewVerifierWithOptions(t *testing.T) { if err != nil { t.Fatalf("unexpected error while creating revocation object: %v", err) } - opts := VerifierOptions{RevocationClient: r} - v, err := NewVerifierWithOptions(&ociPolicy, &blobPolicy, store, pm, opts) + v, err := NewVerifierWithOptions(store, VerifierOptions{ + RevocationClient: r, + OCITrustPolicy: &ociPolicy, + BlobTrustPolicy: &blobPolicy, + PluginManager: pm, + }) if err != nil { t.Fatalf("expected NewVerifierWithOptions constructor to succeed, but got %v", err) } @@ -750,18 +754,28 @@ func TestNewVerifierWithOptions(t *testing.T) { t.Fatal("expected nil revocationCodeSigningValidator") } - _, err = NewVerifierWithOptions(nil, &blobPolicy, store, pm, opts) + _, err = NewVerifierWithOptions(store, VerifierOptions{ + RevocationClient: r, + BlobTrustPolicy: &blobPolicy, + PluginManager: pm, + }) if err != nil { t.Fatalf("expected NewVerifierWithOptions constructor to succeed, but got %v", err) } - _, err = NewVerifierWithOptions(&ociPolicy, nil, store, pm, opts) + _, err = NewVerifierWithOptions(store, VerifierOptions{ + RevocationClient: r, + OCITrustPolicy: &ociPolicy, + PluginManager: pm, + }) if err != nil { t.Fatalf("expected NewVerifierWithOptions constructor to succeed, but got %v", err) } - opts.RevocationClient = nil - _, err = NewVerifierWithOptions(&ociPolicy, nil, store, pm, opts) + _, err = NewVerifierWithOptions(store, VerifierOptions{ + OCITrustPolicy: &ociPolicy, + PluginManager: pm, + }) if err != nil { t.Fatalf("expected NewVerifierWithOptions constructor to succeed, but got %v", err) } @@ -770,19 +784,11 @@ func TestNewVerifierWithOptions(t *testing.T) { if err != nil { t.Fatal(err) } - opts = VerifierOptions{ + v, err = NewVerifierWithOptions(store, VerifierOptions{ RevocationCodeSigningValidator: csValidator, - } - v, err = NewVerifierWithOptions(&ociPolicy, nil, store, pm, opts) - if err != nil { - t.Fatalf("expected NewVerifierWithOptions constructor to succeed, but got %v", err) - } - if v.revocationCodeSigningValidator == nil { - t.Fatal("expected v.revocationCodeSigningValidator to be non-nil") - } - - opts = VerifierOptions{} - v, err = NewVerifierWithOptions(&ociPolicy, nil, store, pm, opts) + OCITrustPolicy: &ociPolicy, + PluginManager: pm, + }) if err != nil { t.Fatalf("expected NewVerifierWithOptions constructor to succeed, but got %v", err) } @@ -803,17 +809,23 @@ func TestNewVerifierWithOptionsError(t *testing.T) { if err != nil { t.Fatalf("unexpected error while creating revocation timestamp object: %v", err) } - opts := VerifierOptions{ + + _, err = NewVerifierWithOptions(store, VerifierOptions{ RevocationClient: r, RevocationTimestampingValidator: rt, - } - - _, err = NewVerifierWithOptions(nil, nil, store, pm, opts) + PluginManager: pm, + }) if err == nil || err.Error() != "ociTrustPolicy and blobTrustPolicy both cannot be nil" { t.Errorf("expected err but not found.") } - _, err = NewVerifierWithOptions(&ociPolicy, &blobPolicy, nil, pm, opts) + _, err = NewVerifierWithOptions(nil, VerifierOptions{ + RevocationClient: r, + RevocationTimestampingValidator: rt, + OCITrustPolicy: &ociPolicy, + BlobTrustPolicy: &blobPolicy, + PluginManager: pm, + }) if err == nil || err.Error() != "trustStore cannot be nil" { t.Errorf("expected err but not found.") } @@ -831,7 +843,10 @@ func TestVerifyBlob(t *testing.T) { }, }, } - v, err := NewVerifier(nil, policy, &testTrustStore{}, pm) + v, err := NewVerifierWithOptions(&testTrustStore{}, VerifierOptions{ + BlobTrustPolicy: policy, + PluginManager: pm, + }) if err != nil { t.Fatalf("unexpected error while creating verifier: %v", err) } @@ -877,7 +892,10 @@ func TestVerifyBlob_Error(t *testing.T) { }, }, } - v, err := NewVerifier(nil, policy, &testTrustStore{}, pm) + v, err := NewVerifierWithOptions(&testTrustStore{}, VerifierOptions{ + BlobTrustPolicy: policy, + PluginManager: pm, + }) if err != nil { t.Fatalf("unexpected error while creating verifier: %v", err) } From 839f2e567da7719a378d034f0aec822d77d6d2a8 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 22 Jan 2025 13:20:16 +0800 Subject: [PATCH 2/3] add tests Signed-off-by: Patrick Zheng --- verifier/verifier_test.go | 42 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/verifier/verifier_test.go b/verifier/verifier_test.go index a1ee9732..f4748635 100644 --- a/verifier/verifier_test.go +++ b/verifier/verifier_test.go @@ -17,10 +17,12 @@ import ( "context" "crypto/x509" "crypto/x509/pkix" + "encoding/json" "encoding/pem" "errors" "fmt" "net/http" + "os" "path/filepath" "reflect" "strconv" @@ -831,6 +833,46 @@ func TestNewVerifierWithOptionsError(t *testing.T) { } } +func TestNewOCIVerifierFromConfig(t *testing.T) { + defer func(oldUserConfigDir string) { + dir.UserConfigDir = oldUserConfigDir + }(dir.UserConfigDir) + + tempRoot := t.TempDir() + dir.UserConfigDir = tempRoot + path := filepath.Join(tempRoot, "trustpolicy.oci.json") + policyJson, _ := json.Marshal(dummyOCIPolicyDocument()) + if err := os.WriteFile(path, policyJson, 0600); err != nil { + t.Fatalf("TestLoadOCIDocument write policy file failed. Error: %v", err) + } + t.Cleanup(func() { os.RemoveAll(tempRoot) }) + + _, err := NewOCIVerifierFromConfig() + if err != nil { + t.Fatalf("expected NewOCIVerifierFromConfig constructor to succeed, but got %v", err) + } +} + +func TestNewBlobVerifierFromConfig(t *testing.T) { + defer func(oldUserConfigDir string) { + dir.UserConfigDir = oldUserConfigDir + }(dir.UserConfigDir) + + tempRoot := t.TempDir() + dir.UserConfigDir = tempRoot + path := filepath.Join(tempRoot, "trustpolicy.blob.json") + policyJson, _ := json.Marshal(dummyBlobPolicyDocument()) + if err := os.WriteFile(path, policyJson, 0600); err != nil { + t.Fatalf("TestLoadBlobDocument write policy file failed. Error: %v", err) + } + t.Cleanup(func() { os.RemoveAll(tempRoot) }) + + _, err := NewBlobVerifierFromConfig() + if err != nil { + t.Fatalf("expected NewBlobVerifierFromConfig constructor to succeed, but got %v", err) + } +} + func TestVerifyBlob(t *testing.T) { policy := &trustpolicy.BlobDocument{ Version: "1.0", From c4dc115ce7f2f532f96d73a3bbfd69c201383e87 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Wed, 22 Jan 2025 14:14:51 +0800 Subject: [PATCH 3/3] update Signed-off-by: Patrick Zheng --- verifier/verifier.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/verifier/verifier.go b/verifier/verifier.go index 6fedcb31..e9395683 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -147,7 +147,6 @@ func NewWithOptions(ociTrustPolicy *trustpolicy.OCIDocument, trustStore truststo func NewVerifierWithOptions(trustStore truststore.X509TrustStore, verifierOptions VerifierOptions) (*verifier, error) { ociTrustPolicy := verifierOptions.OCITrustPolicy blobTrustPolicy := verifierOptions.BlobTrustPolicy - pluginManager := verifierOptions.PluginManager if trustStore == nil { return nil, errors.New("trustStore cannot be nil") } @@ -168,7 +167,7 @@ func NewVerifierWithOptions(trustStore truststore.X509TrustStore, verifierOption ociTrustPolicyDoc: ociTrustPolicy, blobTrustPolicyDoc: blobTrustPolicy, trustStore: trustStore, - pluginManager: pluginManager, + pluginManager: verifierOptions.PluginManager, } if err := v.setRevocation(verifierOptions); err != nil {