Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: updated verifier constructor #508

Merged
merged 3 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion example_verifyBlob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
44 changes: 30 additions & 14 deletions verifier/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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,
Expand All @@ -122,18 +137,16 @@ 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
if trustStore == nil {
return nil, errors.New("trustStore cannot be nil")
}
Expand All @@ -154,7 +167,7 @@ func NewVerifierWithOptions(ociTrustPolicy *trustpolicy.OCIDocument, blobTrustPo
ociTrustPolicyDoc: ociTrustPolicy,
blobTrustPolicyDoc: blobTrustPolicy,
trustStore: trustStore,
pluginManager: pluginManager,
pluginManager: verifierOptions.PluginManager,
}

if err := v.setRevocation(verifierOptions); err != nil {
Expand All @@ -177,7 +190,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
Expand Down
110 changes: 85 additions & 25 deletions verifier/verifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ import (
"context"
"crypto/x509"
"crypto/x509/pkix"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"net/http"
"os"
"path/filepath"
"reflect"
"strconv"
Expand Down Expand Up @@ -728,9 +730,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)
}
Expand All @@ -750,18 +756,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)
}
Expand All @@ -770,19 +786,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)
}
Expand All @@ -803,22 +811,68 @@ 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.")
}
}

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",
Expand All @@ -831,7 +885,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)
}
Expand Down Expand Up @@ -877,7 +934,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)
}
Expand Down
Loading