Skip to content

Commit

Permalink
refactor: updated verifier constructor (#508)
Browse files Browse the repository at this point in the history
Signed-off-by: Patrick Zheng <patrickzheng@microsoft.com>
  • Loading branch information
Two-Hearts authored Jan 22, 2025
1 parent 96b7133 commit 6eb53a5
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 40 deletions.
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

0 comments on commit 6eb53a5

Please sign in to comment.