Skip to content
Open
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
2 changes: 1 addition & 1 deletion cmd/notation/blob/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ func prepareBlobSigningOpts(ctx context.Context, opts *blobSignOpts) (notation.S
if err != nil {
return notation.SignBlobOptions{}, err
}
tsaRevocationValidator, err := clirev.NewRevocationValidator(ctx, purpose.Timestamping)
tsaRevocationValidator, err := clirev.NewRevocationValidator(ctx, purpose.Timestamping, clirev.DefaultOCSPTimeout)
if err != nil {
return notation.SignBlobOptions{}, fmt.Errorf("failed to create timestamping revocation validator: %w", err)
}
Expand Down
6 changes: 5 additions & 1 deletion cmd/notation/blob/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ import (
"os"
"path/filepath"
"strings"
"time"

"github.com/notaryproject/notation-go"
"github.com/notaryproject/notation/v2/cmd/notation/internal/display"
"github.com/notaryproject/notation/v2/cmd/notation/internal/display/output"
"github.com/notaryproject/notation/v2/cmd/notation/internal/flag"
"github.com/notaryproject/notation/v2/cmd/notation/internal/verify"
"github.com/notaryproject/notation/v2/internal/envelope"
clirev "github.com/notaryproject/notation/v2/internal/revocation"
"github.com/spf13/cobra"
)

Expand All @@ -38,6 +40,7 @@ type blobVerifyOpts struct {
userMetadata []string
policyStatementName string
blobMediaType string
ocspTimeout time.Duration
}

func verifyCommand(opts *blobVerifyOpts) *cobra.Command {
Expand Down Expand Up @@ -90,6 +93,7 @@ Example - Verify the signature on a blob artifact using a policy statement name:
command.Flags().StringArrayVar(&opts.pluginConfig, "plugin-config", nil, "{key}={value} pairs that are passed as it is to a plugin, if the verification is associated with a verification plugin, refer plugin documentation to set appropriate values")
command.Flags().StringVar(&opts.blobMediaType, "media-type", "", "media type of the blob to verify")
command.Flags().StringVar(&opts.policyStatementName, "policy-name", "", "policy name to verify against. If not provided, the global policy is used if exists")
command.Flags().DurationVar(&opts.ocspTimeout, "ocsp-timeout", clirev.DefaultOCSPTimeout, "timeout for OCSP requests during certificate revocation checking")
flag.SetPflagUserMetadata(command.Flags(), &opts.userMetadata, flag.PflagUserMetadataVerifyUsage)
command.MarkFlagRequired("signature")
return command
Expand All @@ -111,7 +115,7 @@ func runVerify(command *cobra.Command, cmdOpts *blobVerifyOpts) error {
if err != nil {
return err
}
blobVerifier, err := verify.GetBlobVerifier(ctx)
blobVerifier, err := verify.GetBlobVerifier(ctx, cmdOpts.ocspTimeout)
if err != nil {
return err
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/notation/blob/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package blob
import (
"reflect"
"testing"

clirev "github.com/notaryproject/notation/v2/internal/revocation"
)

func TestVerifyCommand_BasicArgs(t *testing.T) {
Expand All @@ -24,6 +26,7 @@ func TestVerifyCommand_BasicArgs(t *testing.T) {
expected := &blobVerifyOpts{
blobPath: "blob_path",
signaturePath: "sig_path",
ocspTimeout: clirev.DefaultOCSPTimeout,
}
if err := command.ParseFlags([]string{
expected.blobPath,
Expand All @@ -45,6 +48,7 @@ func TestVerifyCommand_MoreArgs(t *testing.T) {
blobPath: "blob_path",
signaturePath: "sig_path",
pluginConfig: []string{"key1=val1", "key2=val2"},
ocspTimeout: clirev.DefaultOCSPTimeout,
}
if err := command.ParseFlags([]string{
expected.blobPath,
Expand Down
15 changes: 8 additions & 7 deletions cmd/notation/internal/verify/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"errors"
"fmt"
"io/fs"
"time"

"github.com/notaryproject/notation-core-go/revocation/purpose"
"github.com/notaryproject/notation-go"
Expand All @@ -38,8 +39,8 @@ type Verifier interface {
}

// GetVerifier creates a Verifier.
func GetVerifier(ctx context.Context) (Verifier, error) {
verifierOptions, err := newVerifierOptions(ctx)
func GetVerifier(ctx context.Context, ocspTimeout time.Duration) (Verifier, error) {
verifierOptions, err := newVerifierOptions(ctx, ocspTimeout)
if err != nil {
return nil, err
}
Expand All @@ -55,8 +56,8 @@ func GetVerifier(ctx context.Context) (Verifier, error) {
}

// GetBlobVerifier creates a BlobVerifier.
func GetBlobVerifier(ctx context.Context) (Verifier, error) {
verifierOptions, err := newVerifierOptions(ctx)
func GetBlobVerifier(ctx context.Context, ocspTimeout time.Duration) (Verifier, error) {
verifierOptions, err := newVerifierOptions(ctx, ocspTimeout)
if err != nil {
return nil, err
}
Expand All @@ -72,12 +73,12 @@ func GetBlobVerifier(ctx context.Context) (Verifier, error) {
}

// newVerifierOptions creates a verifier.VerifierOptions.
func newVerifierOptions(ctx context.Context) (verifier.VerifierOptions, error) {
revocationCodeSigningValidator, err := clirev.NewRevocationValidator(ctx, purpose.CodeSigning)
func newVerifierOptions(ctx context.Context, ocspTimeout time.Duration) (verifier.VerifierOptions, error) {
revocationCodeSigningValidator, err := clirev.NewRevocationValidator(ctx, purpose.CodeSigning, ocspTimeout)
if err != nil {
return verifier.VerifierOptions{}, err
}
revocationTimestampingValidator, err := clirev.NewRevocationValidator(ctx, purpose.Timestamping)
revocationTimestampingValidator, err := clirev.NewRevocationValidator(ctx, purpose.Timestamping, ocspTimeout)
if err != nil {
return verifier.VerifierOptions{}, err
}
Expand Down
13 changes: 7 additions & 6 deletions cmd/notation/internal/verify/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/notaryproject/notation-go"
"github.com/notaryproject/notation-go/dir"
"github.com/notaryproject/notation-go/verifier/trustpolicy"
clirev "github.com/notaryproject/notation/v2/internal/revocation"
)

func TestGetVerifier(t *testing.T) {
Expand All @@ -41,7 +42,7 @@ func TestGetVerifier(t *testing.T) {
}
t.Cleanup(func() { os.RemoveAll(tempRoot) })

_, err := GetVerifier(context.Background())
_, err := GetVerifier(context.Background(), clirev.DefaultOCSPTimeout)
if err != nil {
t.Fatal(err)
}
Expand All @@ -50,7 +51,7 @@ func TestGetVerifier(t *testing.T) {
t.Run("non-existing oci trust policy", func(t *testing.T) {
dir.UserConfigDir = "/"
expectedErrMsg := "trust policy is not present. To create a trust policy, see: https://notaryproject.dev/docs/quickstart/#create-a-trust-policy"
_, err := GetVerifier(context.Background())
_, err := GetVerifier(context.Background(), clirev.DefaultOCSPTimeout)
if err == nil || err.Error() != expectedErrMsg {
t.Fatalf("expected %s, but got %s", expectedErrMsg, err)
}
Expand All @@ -67,7 +68,7 @@ func TestGetVerifier(t *testing.T) {
t.Cleanup(func() { os.RemoveAll(tempRoot) })

expectedErrMsg := "oci trust policy document has empty version, version must be specified"
_, err := GetVerifier(context.Background())
_, err := GetVerifier(context.Background(), clirev.DefaultOCSPTimeout)
if err == nil || err.Error() != expectedErrMsg {
t.Fatalf("expected %s, but got %s", expectedErrMsg, err)
}
Expand All @@ -90,7 +91,7 @@ func TestGetBlobVerifier(t *testing.T) {
}
t.Cleanup(func() { os.RemoveAll(tempRoot) })

_, err := GetBlobVerifier(context.Background())
_, err := GetBlobVerifier(context.Background(), clirev.DefaultOCSPTimeout)
if err != nil {
t.Fatal(err)
}
Expand All @@ -99,7 +100,7 @@ func TestGetBlobVerifier(t *testing.T) {
t.Run("non-existing blob trust policy", func(t *testing.T) {
dir.UserConfigDir = "/"
expectedErrMsg := "trust policy is not present. To create a trust policy, see: https://notaryproject.dev/docs/quickstart/#create-a-trust-policy"
_, err := GetBlobVerifier(context.Background())
_, err := GetBlobVerifier(context.Background(), clirev.DefaultOCSPTimeout)
if err == nil || err.Error() != expectedErrMsg {
t.Fatalf("expected %s, but got %s", expectedErrMsg, err)
}
Expand All @@ -116,7 +117,7 @@ func TestGetBlobVerifier(t *testing.T) {
t.Cleanup(func() { os.RemoveAll(tempRoot) })

expectedErrMsg := "blob trust policy document has empty version, version must be specified"
_, err := GetBlobVerifier(context.Background())
_, err := GetBlobVerifier(context.Background(), clirev.DefaultOCSPTimeout)
if err == nil || err.Error() != expectedErrMsg {
t.Fatalf("expected %s, but got %s", expectedErrMsg, err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/notation/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func prepareSigningOpts(ctx context.Context, opts *signOpts) (notation.SignOptio
if err != nil {
return notation.SignOptions{}, err
}
tsaRevocationValidator, err := clirev.NewRevocationValidator(ctx, purpose.Timestamping)
tsaRevocationValidator, err := clirev.NewRevocationValidator(ctx, purpose.Timestamping, clirev.DefaultOCSPTimeout)
if err != nil {
return notation.SignOptions{}, fmt.Errorf("failed to create timestamping revocation validator: %w", err)
}
Expand Down
6 changes: 5 additions & 1 deletion cmd/notation/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ package main
import (
"errors"
"fmt"
"time"

"github.com/notaryproject/notation-go"
"github.com/notaryproject/notation/v2/cmd/notation/internal/display"
"github.com/notaryproject/notation/v2/cmd/notation/internal/display/output"
"github.com/notaryproject/notation/v2/cmd/notation/internal/experimental"
"github.com/notaryproject/notation/v2/cmd/notation/internal/flag"
"github.com/notaryproject/notation/v2/cmd/notation/internal/verify"
clirev "github.com/notaryproject/notation/v2/internal/revocation"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/cobra"
)
Expand All @@ -38,6 +40,7 @@ type verifyOpts struct {
trustPolicyScope string
inputType inputType
maxSignatureAttempts int
ocspTimeout time.Duration
}

func verifyCommand(opts *verifyOpts) *cobra.Command {
Expand Down Expand Up @@ -93,6 +96,7 @@ Example - [Experimental] Verify a signature on an OCI artifact identified by a t
command.Flags().StringArrayVar(&opts.pluginConfig, "plugin-config", nil, "{key}={value} pairs that are passed as it is to a plugin, if the verification is associated with a verification plugin, refer plugin documentation to set appropriate values")
flag.SetPflagUserMetadata(command.Flags(), &opts.userMetadata, flag.PflagUserMetadataVerifyUsage)
command.Flags().IntVar(&opts.maxSignatureAttempts, "max-signatures", 100, "maximum number of signatures to evaluate or examine")
command.Flags().DurationVar(&opts.ocspTimeout, "ocsp-timeout", clirev.DefaultOCSPTimeout, "timeout for OCSP requests during certificate revocation checking")
command.Flags().BoolVar(&opts.ociLayout, "oci-layout", false, "[Experimental] verify the artifact stored as OCI image layout")
command.Flags().StringVar(&opts.trustPolicyScope, "scope", "", "[Experimental] set trust policy scope for artifact verification, required and can only be used when flag \"--oci-layout\" is set")
command.MarkFlagsRequiredTogether("oci-layout", "scope")
Expand All @@ -106,7 +110,7 @@ func runVerify(command *cobra.Command, opts *verifyOpts) error {

// initialize
displayHandler := display.NewVerifyHandler(opts.printer)
sigVerifier, err := verify.GetVerifier(ctx)
sigVerifier, err := verify.GetVerifier(ctx, opts.ocspTimeout)
if err != nil {
return err
}
Expand Down
3 changes: 3 additions & 0 deletions cmd/notation/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"testing"

"github.com/notaryproject/notation/v2/cmd/notation/internal/flag"
clirev "github.com/notaryproject/notation/v2/internal/revocation"
)

func TestVerifyCommand_BasicArgs(t *testing.T) {
Expand All @@ -31,6 +32,7 @@ func TestVerifyCommand_BasicArgs(t *testing.T) {
},
pluginConfig: []string{"key1=val1"},
maxSignatureAttempts: 100,
ocspTimeout: clirev.DefaultOCSPTimeout,
}
if err := command.ParseFlags([]string{
expected.reference,
Expand All @@ -57,6 +59,7 @@ func TestVerifyCommand_MoreArgs(t *testing.T) {
},
pluginConfig: []string{"key1=val1", "key2=val2"},
maxSignatureAttempts: 100,
ocspTimeout: clirev.DefaultOCSPTimeout,
}
if err := command.ParseFlags([]string{
expected.reference,
Expand Down
10 changes: 7 additions & 3 deletions internal/revocation/revocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@ import (
clicrl "github.com/notaryproject/notation/v2/internal/revocation/crl"
)

// DefaultOCSPTimeout is the default timeout for OCSP requests issued during
// certificate revocation checking.
const DefaultOCSPTimeout = 2 * time.Second

// NewRevocationValidator returns a revocation.Validator given the certificate
// purpose
func NewRevocationValidator(ctx context.Context, purpose purpose.Purpose) (revocation.Validator, error) {
// purpose and the timeout for OCSP requests.
func NewRevocationValidator(ctx context.Context, purpose purpose.Purpose, ocspTimeout time.Duration) (revocation.Validator, error) {
// err is always nil
crlFetcher, _ := corecrl.NewHTTPFetcher(httputil.NewClient(ctx, &http.Client{Timeout: 5 * time.Second}))
crlFetcher.DiscardCacheError = true // discard crl cache error
Expand All @@ -47,7 +51,7 @@ func NewRevocationValidator(ctx context.Context, purpose purpose.Purpose) (revoc
}
}
return revocation.NewWithOptions(revocation.Options{
OCSPHTTPClient: httputil.NewClient(ctx, &http.Client{Timeout: 2 * time.Second}),
OCSPHTTPClient: httputil.NewClient(ctx, &http.Client{Timeout: ocspTimeout}),
CRLFetcher: crlFetcher,
CertChainPurpose: purpose,
})
Expand Down
4 changes: 2 additions & 2 deletions internal/revocation/revocation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestNewRevocationValidator(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("skipping test on Windows")
}
if _, err := NewRevocationValidator(context.Background(), purpose.Timestamping); err != nil {
if _, err := NewRevocationValidator(context.Background(), purpose.Timestamping, DefaultOCSPTimeout); err != nil {
t.Fatal(err)
}
})
Expand All @@ -56,7 +56,7 @@ func TestNewRevocationValidator(t *testing.T) {
t.Fatalf("failed to change permission: %v", err)
}
}()
if _, err := NewRevocationValidator(context.Background(), purpose.Timestamping); err != nil {
if _, err := NewRevocationValidator(context.Background(), purpose.Timestamping, DefaultOCSPTimeout); err != nil {
t.Fatal(err)
}
})
Expand Down
1 change: 1 addition & 0 deletions specs/cmd/blob.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ Flags:
-d, --debug debug mode
-h, --help help for verify
--media-type string media type of the blob to verify
--ocsp-timeout duration timeout for OCSP requests during certificate revocation checking (default 2s)
--plugin-config stringArray {key}={value} pairs that are passed as it is to a plugin, if the verification is associated with a verification plugin, refer plugin documentation to set appropriate values
--policy-name string policy name to verify against. If not provided, the global policy is used if exists
-s --signature string filepath of the signature to be verified
Expand Down
1 change: 1 addition & 0 deletions specs/cmd/verify.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Flags:
--insecure-registry use HTTP protocol while connecting to registries. Should be used only for testing
--max-signatures int maximum number of signatures to evaluate or examine (default 100)
--oci-layout [Experimental] verify the artifact stored as OCI image layout
--ocsp-timeout duration timeout for OCSP requests during certificate revocation checking (default 2s)
-p, --password string password for registry operations (default to $NOTATION_PASSWORD if not specified)
--plugin-config stringArray {key}={value} pairs that are passed as it is to a plugin, if the verification is associated with a verification plugin, refer plugin documentation to set appropriate values
--scope string [Experimental] set trust policy scope for artifact verification, required and can only be used when flag "--oci-layout" is set
Expand Down