From e2789a7f56ea0a3e6d024f45e78f3843f025a026 Mon Sep 17 00:00:00 2001 From: Patrick Zheng Date: Thu, 17 Oct 2024 01:31:10 +0800 Subject: [PATCH] chore: update logs (#469) This PR updates logs. Resolves #430. Also should resolve issue https://github.com/notaryproject/notation/issues/1004. Signed-off-by: Patrick Zheng --- notation.go | 4 ++-- notation_test.go | 52 +++++++++++++++++++++++++++++++------------- verifier/verifier.go | 8 +++++-- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/notation.go b/notation.go index 294664b0..70b50646 100644 --- a/notation.go +++ b/notation.go @@ -357,10 +357,10 @@ func Verify(ctx context.Context, verifier Verifier, repo registry.Repository, ve return ocispec.Descriptor{}, nil, err } if skip { - logger.Infoln("Verification skipped for", verifyOpts.ArtifactReference) + logger.Infoln("Signature verification skipped for", verifyOpts.ArtifactReference) return ocispec.Descriptor{}, []*VerificationOutcome{{VerificationLevel: verificationLevel}}, nil } - logger.Info("Check over. Trust policy is not configured to skip signature verification") + logger.Info("Check over. The signature verification level is not set to 'skip' in the trust policy.") } // get artifact descriptor diff --git a/notation_test.go b/notation_test.go index 64fbe07a..cae65c5f 100644 --- a/notation_test.go +++ b/notation_test.go @@ -225,7 +225,7 @@ func TestSignOptsUnknownMediaType(t *testing.T) { func TestRegistryResolveError(t *testing.T) { repo := mock.NewRepository() policyDocument := dummyPolicyDocument() - verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict} + verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict, false} errorMessage := "network error" expectedErr := ErrorSignatureRetrievalFailed{Msg: errorMessage} @@ -243,7 +243,7 @@ func TestRegistryResolveError(t *testing.T) { func TestVerifyEmptyReference(t *testing.T) { repo := mock.NewRepository() policyDocument := dummyPolicyDocument() - verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict} + verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict, false} errorMessage := "reference is missing digest or tag" expectedErr := ErrorSignatureRetrievalFailed{Msg: errorMessage} @@ -259,7 +259,7 @@ func TestVerifyEmptyReference(t *testing.T) { func TestVerifyTagReferenceFailed(t *testing.T) { repo := mock.NewRepository() policyDocument := dummyPolicyDocument() - verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict} + verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict, false} errorMessage := "invalid reference: invalid repository \"UPPERCASE/test\"" expectedErr := ErrorSignatureRetrievalFailed{Msg: errorMessage} @@ -276,7 +276,7 @@ func TestVerifyDigestNotMatchResolve(t *testing.T) { repo := mock.NewRepository() repo.MissMatchDigest = true policyDocument := dummyPolicyDocument() - verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict} + verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict, false} errorMessage := fmt.Sprintf("user input digest %s does not match the resolved digest %s", mock.SampleDigest, mock.ZeroDigest) expectedErr := ErrorSignatureRetrievalFailed{Msg: errorMessage} @@ -300,7 +300,7 @@ func TestSignDigestNotMatchResolve(t *testing.T) { } errorMessage := fmt.Sprintf("user input digest %s does not match the resolved digest %s", mock.SampleDigest, mock.ZeroDigest) - expectedErr := fmt.Errorf(errorMessage) + expectedErr := errors.New(errorMessage) _, err := Sign(context.Background(), &dummySigner{}, repo, signOpts) if err == nil || err.Error() != errorMessage { @@ -311,7 +311,7 @@ func TestSignDigestNotMatchResolve(t *testing.T) { func TestSkippedSignatureVerification(t *testing.T) { repo := mock.NewRepository() policyDocument := dummyPolicyDocument() - verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelSkip} + verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelSkip, false} opts := VerifyOptions{ArtifactReference: mock.SampleArtifactUri, MaxSignatureAttempts: 50} _, outcomes, err := Verify(context.Background(), &verifier, repo, opts) @@ -324,7 +324,7 @@ func TestSkippedSignatureVerification(t *testing.T) { func TestRegistryNoSignatureManifests(t *testing.T) { repo := mock.NewRepository() policyDocument := dummyPolicyDocument() - verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict} + verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict, false} errorMessage := fmt.Sprintf("no signature is associated with %q, make sure the artifact was signed successfully", mock.SampleArtifactUri) expectedErr := ErrorSignatureRetrievalFailed{Msg: errorMessage} @@ -341,7 +341,7 @@ func TestRegistryNoSignatureManifests(t *testing.T) { func TestRegistryFetchSignatureBlobError(t *testing.T) { repo := mock.NewRepository() policyDocument := dummyPolicyDocument() - verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict} + verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict, false} errorMessage := fmt.Sprintf("unable to retrieve digital signature with digest %q associated with %q from the Repository, error : network error", mock.SampleDigest, mock.SampleArtifactUri) expectedErr := ErrorSignatureRetrievalFailed{Msg: errorMessage} @@ -358,21 +358,35 @@ func TestRegistryFetchSignatureBlobError(t *testing.T) { func TestVerifyValid(t *testing.T) { repo := mock.NewRepository() policyDocument := dummyPolicyDocument() - verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict} + verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict, false} // mock the repository opts := VerifyOptions{ArtifactReference: mock.SampleArtifactUri, MaxSignatureAttempts: 50} _, _, err := Verify(context.Background(), &verifier, repo, opts) if err != nil { - t.Fatalf("SignaureMediaTypeMismatch expected: %v got: %v", nil, err) + t.Fatalf("expected nil error, but got: %v", err) + } +} + +func TestVerifySkip(t *testing.T) { + repo := mock.NewRepository() + policyDocument := dummyPolicyDocument() + verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict, true} + + // mock the repository + opts := VerifyOptions{ArtifactReference: mock.SampleArtifactUri, MaxSignatureAttempts: 50} + _, _, err := Verify(context.Background(), &verifier, repo, opts) + + if err != nil { + t.Fatalf("expected nil error, but got: %v", err) } } func TestMaxSignatureAttemptsMissing(t *testing.T) { repo := mock.NewRepository() policyDocument := dummyPolicyDocument() - verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict} + verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict, false} expectedErr := ErrorSignatureRetrievalFailed{Msg: fmt.Sprintf("verifyOptions.MaxSignatureAttempts expects a positive number, got %d", 0)} // mock the repository @@ -388,7 +402,7 @@ func TestExceededMaxSignatureAttempts(t *testing.T) { repo := mock.NewRepository() repo.ExceededNumOfSignatures = true policyDocument := dummyPolicyDocument() - verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, true, *trustpolicy.LevelStrict} + verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, true, *trustpolicy.LevelStrict, false} expectedErr := ErrorVerificationFailed{Msg: fmt.Sprintf("signature evaluation stopped. The configured limit of %d signatures to verify per artifact exceeded", 1)} @@ -405,7 +419,7 @@ func TestVerifyFailed(t *testing.T) { t.Run("verification error", func(t *testing.T) { policyDocument := dummyPolicyDocument() repo := mock.NewRepository() - verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, true, *trustpolicy.LevelStrict} + verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, true, *trustpolicy.LevelStrict, false} expectedErr := ErrorVerificationFailed{} // mock the repository @@ -432,7 +446,7 @@ func TestVerifyFailed(t *testing.T) { t.Run("repo is nil", func(t *testing.T) { policyDocument := dummyPolicyDocument() - verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict} + verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict, false} expectedErr := errors.New("repo cannot be nil") // mock the repository @@ -494,6 +508,7 @@ type dummyVerifier struct { PluginManager plugin.Manager FailVerify bool VerificationLevel trustpolicy.VerificationLevel + SkipVerification bool } func (v *dummyVerifier) Verify(_ context.Context, _ ocispec.Descriptor, _ []byte, _ VerifierVerifyOptions) (*VerificationOutcome, error) { @@ -507,6 +522,13 @@ func (v *dummyVerifier) Verify(_ context.Context, _ ocispec.Descriptor, _ []byte return outcome, nil } +func (v *dummyVerifier) SkipVerify(_ context.Context, _ VerifierVerifyOptions) (bool, *trustpolicy.VerificationLevel, error) { + if v.SkipVerification { + return true, nil, nil + } + return false, nil, nil +} + var ( reference = "sha256:19dbd2e48e921426ee8ace4dc892edfb2ecdc1d1a72d5416c83670c30acecef0" artifactReference = "local/oci-layout@sha256:19dbd2e48e921426ee8ace4dc892edfb2ecdc1d1a72d5416c83670c30acecef0" @@ -567,7 +589,7 @@ func TestLocalContent(t *testing.T) { MaxSignatureAttempts: math.MaxInt64, } policyDocument := dummyPolicyDocument() - verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict} + verifier := dummyVerifier{&policyDocument, mock.PluginManager{}, false, *trustpolicy.LevelStrict, false} // verify signatures inside the OCI layout folder _, _, err = Verify(context.Background(), &verifier, repo, verifyOpts) if err != nil { diff --git a/verifier/verifier.go b/verifier/verifier.go index b50869ba..69a39484 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -888,7 +888,7 @@ func verifyTimestamp(ctx context.Context, policyName string, trustStores []strin } // Performing timestamp verification - logger.Info("Performing timestamp verification...") + logger.Debug("Performing timestamp verification...") // 1. Timestamp countersignature MUST be present logger.Debug("Checking timestamp countersignature existence...") @@ -937,7 +937,7 @@ func verifyTimestamp(ctx context.Context, policyName string, trustStores []strin if err := nx509.ValidateTimestampingCertChain(tsaCertChain); err != nil { return fmt.Errorf("failed to validate the timestamping certificate chain with error: %w", err) } - logger.Info("TSA identity is: ", tsaCertChain[0].Subject) + logger.Debug("The subject of TSA signing certificate is: ", tsaCertChain[0].Subject) // 4. Check the timestamp against the signing certificate chain logger.Debug("Checking the timestamp against the signing certificate chain...") @@ -949,6 +949,9 @@ func verifyTimestamp(ctx context.Context, policyName string, trustStores []strin if !timestamp.BoundedBefore(cert.NotAfter) { return fmt.Errorf("timestamp can be after certificate %q validity period, it was expired at %q", cert.Subject, cert.NotAfter.Format(time.RFC1123Z)) } + if timeOfVerification.After(cert.NotAfter) { + logger.Debugf("Certificate %q expired at %q, but timestamp is within certificate validity period", cert.Subject, cert.NotAfter.Format(time.RFC1123Z)) + } } // 5. Perform the timestamping certificate chain revocation check @@ -971,5 +974,6 @@ func verifyTimestamp(ctx context.Context, policyName string, trustStores []strin } // success + logger.Debug("Timestamp verification: Success") return nil }