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

update: updated CLI outputs of sign/verification #450

Merged
merged 46 commits into from
Dec 5, 2022
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
b910a8a
updated dependency
Two-Hearts Oct 12, 2022
28b0438
resolved conflicts
Two-Hearts Oct 12, 2022
4f4e2a4
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 12, 2022
eea8003
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 13, 2022
216cea2
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 17, 2022
1267c02
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 18, 2022
1c3dfbb
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 18, 2022
98e5946
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 18, 2022
55563d3
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 19, 2022
c68d602
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 19, 2022
d165a7b
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 20, 2022
7166877
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 25, 2022
94f174d
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 28, 2022
e1d8437
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 29, 2022
a873c67
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 31, 2022
cd877de
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 31, 2022
53b847d
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 31, 2022
1e29bb4
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 31, 2022
5121684
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 31, 2022
679e01d
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 31, 2022
394b59a
Merge branch 'notaryproject:main' into main
Two-Hearts Oct 31, 2022
c6e8dd1
Merge branch 'notaryproject:main' into main
Two-Hearts Nov 7, 2022
b54b712
Merge branch 'notaryproject:main' into main
Two-Hearts Nov 12, 2022
60e9fdf
updated CLI outputs for sign/verification with tag reference
Two-Hearts Nov 22, 2022
99d98de
update
Two-Hearts Nov 22, 2022
32ff7b0
Merge branch 'notaryproject:main' into tag_to_digest
Two-Hearts Nov 28, 2022
2125072
resolved conflicts
Two-Hearts Nov 30, 2022
9b8bf6c
update based on spec
Two-Hearts Nov 30, 2022
e2f3d97
update
Two-Hearts Nov 30, 2022
92a6b0d
update
Two-Hearts Dec 1, 2022
7c71f4f
update
Two-Hearts Dec 1, 2022
fbdfe52
update
Two-Hearts Dec 1, 2022
d4a00ef
updated output for verify
Two-Hearts Dec 2, 2022
04a877f
resolved conflicts
Two-Hearts Dec 2, 2022
7f87d1a
resolved conflicts
Two-Hearts Dec 2, 2022
8ec720a
update
Two-Hearts Dec 2, 2022
92b82c3
update
Two-Hearts Dec 2, 2022
58e79a8
Merge branch 'notaryproject:main' into tag_to_digest
Two-Hearts Dec 2, 2022
c74fdc8
added back tag to digest warnings print out
Two-Hearts Dec 2, 2022
0a4a379
update
Two-Hearts Dec 2, 2022
89d544c
updated per code review
Two-Hearts Dec 3, 2022
77a9187
return err if reference is missing digest or tag
Two-Hearts Dec 5, 2022
17c2751
updated per code review
Two-Hearts Dec 5, 2022
a2b9467
updated per code review
Two-Hearts Dec 5, 2022
c28e2ab
updated dependencies
Two-Hearts Dec 5, 2022
e21c8ee
update
Two-Hearts Dec 5, 2022
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
8 changes: 4 additions & 4 deletions cmd/notation/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"errors"
"fmt"

notationRegistry "github.com/notaryproject/notation-go/registry"
notationregistry "github.com/notaryproject/notation-go/registry"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -50,7 +50,7 @@ func runList(command *cobra.Command, opts *listOpts) error {
}

// core process
manifestDesc, err := getManifestDescriptorFromReference(command.Context(), &opts.SecureFlagOpts, reference)
manifestDesc, _, err := getManifestDescriptorFromReference(command.Context(), &opts.SecureFlagOpts, reference)
if err != nil {
return err
}
Expand All @@ -61,7 +61,7 @@ func runList(command *cobra.Command, opts *listOpts) error {

// printSignatureManifestDigests returns the signature manifest digests of
// the subject manifest.
func printSignatureManifestDigests(ctx context.Context, manifestDigest digest.Digest, sigRepo notationRegistry.Repository, reference string) error {
func printSignatureManifestDigests(ctx context.Context, manifestDigest digest.Digest, sigRepo notationregistry.Repository, reference string) error {
// prepare title
ref, err := registry.ParseReference(reference)
if err != nil {
Expand All @@ -72,7 +72,7 @@ func printSignatureManifestDigests(ctx context.Context, manifestDigest digest.Di
printTitle := func() {
if !titlePrinted {
fmt.Println(ref)
fmt.Printf("└── %s\n", notationRegistry.ArtifactTypeNotation)
fmt.Printf("└── %s\n", notationregistry.ArtifactTypeNotation)
titlePrinted = true
}
}
Expand Down
20 changes: 14 additions & 6 deletions cmd/notation/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,30 @@ import (
"oras.land/oras-go/v2/registry"
)

func getManifestDescriptorFromContext(ctx context.Context, opts *SecureFlagOpts, ref string) (ocispec.Descriptor, error) {
func getManifestDescriptorFromContext(ctx context.Context, opts *SecureFlagOpts, ref string) (ocispec.Descriptor, registry.Reference, error) {
if ref == "" {
return ocispec.Descriptor{}, errors.New("missing reference")
return ocispec.Descriptor{}, registry.Reference{}, errors.New("missing reference")
}

return getManifestDescriptorFromReference(ctx, opts, ref)
}

func getManifestDescriptorFromReference(ctx context.Context, opts *SecureFlagOpts, reference string) (ocispec.Descriptor, error) {
func getManifestDescriptorFromReference(ctx context.Context, opts *SecureFlagOpts, reference string) (ocispec.Descriptor, registry.Reference, error) {
patrickzheng200 marked this conversation as resolved.
Show resolved Hide resolved
ref, err := registry.ParseReference(reference)
if err != nil {
return ocispec.Descriptor{}, err
return ocispec.Descriptor{}, registry.Reference{}, err
}
if ref.Reference == "" {
return ocispec.Descriptor{}, registry.Reference{}, errors.New("reference is missing digest or tag")
}
repo, err := getRepositoryClient(opts, ref)
if err != nil {
return ocispec.Descriptor{}, err
return ocispec.Descriptor{}, registry.Reference{}, err
}

manifestDesc, err := repo.Resolve(ctx, ref.Reference)
if err != nil {
return ocispec.Descriptor{}, registry.Reference{}, err
}
return repo.Resolve(ctx, ref.ReferenceOrDefault())
return manifestDesc, ref, err
patrickzheng200 marked this conversation as resolved.
Show resolved Hide resolved
}
29 changes: 19 additions & 10 deletions cmd/notation/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"github.com/notaryproject/notation-go"
"github.com/notaryproject/notation/internal/cmd"
"github.com/notaryproject/notation/internal/envelope"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/cobra"
"oras.land/oras-go/v2/registry"
)

type signOpts struct {
Expand Down Expand Up @@ -74,7 +74,7 @@ func runSign(command *cobra.Command, cmdOpts *signOpts) error {
}

// core process
desc, opts, err := prepareSigningContent(command.Context(), cmdOpts)
opts, ref, err := prepareSigningContent(command.Context(), cmdOpts)
if err != nil {
return err
}
Expand All @@ -88,30 +88,39 @@ func runSign(command *cobra.Command, cmdOpts *signOpts) error {
}

// write out
fmt.Println(desc.Digest)
fmt.Println("Successfully signed", ref)

patrickzheng200 marked this conversation as resolved.
Show resolved Hide resolved
return nil
}

func prepareSigningContent(ctx context.Context, opts *signOpts) (ocispec.Descriptor, notation.SignOptions, error) {
manifestDesc, err := getManifestDescriptorFromContext(ctx, &opts.SecureFlagOpts, opts.reference)
func prepareSigningContent(ctx context.Context, opts *signOpts) (notation.SignOptions, registry.Reference, error) {
manifestDesc, ref, err := getManifestDescriptorFromContext(ctx, &opts.SecureFlagOpts, opts.reference)
if err != nil {
return ocispec.Descriptor{}, notation.SignOptions{}, err
return notation.SignOptions{}, registry.Reference{}, err
}
mediaType, err := envelope.GetEnvelopeMediaType(opts.SignerFlagOpts.SignatureFormat)
if err != nil {
return ocispec.Descriptor{}, notation.SignOptions{}, err
return notation.SignOptions{}, registry.Reference{}, err
}
pluginConfig, err := cmd.ParseFlagPluginConfig(opts.pluginConfig)
if err != nil {
return ocispec.Descriptor{}, notation.SignOptions{}, err
return notation.SignOptions{}, registry.Reference{}, err
}
if ref.ValidateReferenceAsDigest() != nil {
patrickzheng200 marked this conversation as resolved.
Show resolved Hide resolved
// reference is not a digest reference
fmt.Printf("Warning: Always sign the artifact using digest(`@sha256:...`) rather than a tag(`:%s`) because tags are mutable and a tag reference can point to a different artifact than the one signed.\n", ref.Reference)
fmt.Printf("Resolved artifact tag `%s` to digest `%s` before signing.\n", ref.Reference, manifestDesc.Digest.String())

// resolve tag to digest reference
ref.Reference = manifestDesc.Digest.String()
patrickzheng200 marked this conversation as resolved.
Show resolved Hide resolved
}

signOpts := notation.SignOptions{
ArtifactReference: opts.reference,
ArtifactReference: ref.String(),
SignatureMediaType: mediaType,
ExpiryDuration: opts.expiry,
PluginConfig: pluginConfig,
}

return manifestDesc, signOpts, nil
return signOpts, ref, nil
}
53 changes: 30 additions & 23 deletions cmd/notation/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ package main

import (
"errors"
"fmt"
"math"
"os"
"strings"

"github.com/notaryproject/notation-go"
notationregistry "github.com/notaryproject/notation-go/registry"
"github.com/notaryproject/notation-go/verifier"
"github.com/notaryproject/notation/internal/cmd"
"github.com/notaryproject/notation/internal/ioutil"

"github.com/spf13/cobra"
"oras.land/oras-go/v2/registry"
Expand Down Expand Up @@ -57,13 +55,13 @@ Example - Verify a signature on an OCI artifact identified by a tag (Notation w
}

func runVerify(command *cobra.Command, opts *verifyOpts) error {
// resolve the given reference and set the digest.
// resolve the given reference and set the digest
ref, err := resolveReference(command, opts)
if err != nil {
return err
}

// initialize verifier.
// initialize verifier
verifier, err := verifier.NewFromConfig()
if err != nil {
return err
Expand All @@ -76,7 +74,7 @@ func runVerify(command *cobra.Command, opts *verifyOpts) error {
}
repo := notationregistry.NewRepository(&remoteRepo)

// set up verification plugin config.
// set up verification plugin config
configs, err := cmd.ParseFlagPluginConfig(opts.pluginConfig)
if err != nil {
return err
Expand All @@ -90,11 +88,27 @@ func runVerify(command *cobra.Command, opts *verifyOpts) error {
MaxSignatureAttempts: math.MaxInt64,
}

// core verify process.
// core verify process
_, outcomes, err := notation.Verify(command.Context(), verifier, repo, verifyOpts)

// write out.
return ioutil.PrintVerificationResults(os.Stdout, outcomes, err, ref.Reference)
// write out
// on failure
if err != nil || len(outcomes) == 0 {
return fmt.Errorf("signature verification failed for all the signatures associated with %s", ref.String())
}

// on success
outcome := outcomes[0]
// print out warning for any failed result with logged verification action
for _, result := range outcome.VerificationResults {
if result.Error != nil {
// at this point, the verification action has to be logged and
// it's failed
fmt.Printf("Warning: %v was set to \"logged\" and failed with error: %v\n", result.Type, result.Error)
}
}
fmt.Println("Successfully verified signature for", ref.String())
return nil
}

func resolveReference(command *cobra.Command, opts *verifyOpts) (registry.Reference, error) {
Expand All @@ -103,26 +117,19 @@ func resolveReference(command *cobra.Command, opts *verifyOpts) (registry.Refere
return registry.Reference{}, err
}

if isDigestReference(opts.reference) {
// reference is a digest reference
if ref.ValidateReferenceAsDigest() == nil {
patrickzheng200 marked this conversation as resolved.
Show resolved Hide resolved
return ref, nil
}

// Resolve tag reference to digest reference.
manifestDesc, err := getManifestDescriptorFromReference(command.Context(), &opts.SecureFlagOpts, opts.reference)
// resolve tag to digest reference
manifestDesc, ref, err := getManifestDescriptorFromReference(command.Context(), &opts.SecureFlagOpts, opts.reference)
patrickzheng200 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return registry.Reference{}, err
}

fmt.Printf("Resolved artifact tag `%s` to digest `%s` before verification.\n", ref.Reference, manifestDesc.Digest.String())
fmt.Println("Warning: The resolved digest may not point to the same signed artifact, since tags are mutable.")
ref.Reference = manifestDesc.Digest.String()
return ref, nil
}

func isDigestReference(reference string) bool {
parts := strings.SplitN(reference, "/", 2)
if len(parts) == 1 {
return false
}

index := strings.Index(parts[1], "@")
return index != -1
return ref, nil
}
15 changes: 0 additions & 15 deletions internal/ioutil/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"io"
"text/tabwriter"

"github.com/notaryproject/notation-go"
"github.com/notaryproject/notation-go/config"
)

Expand Down Expand Up @@ -33,17 +32,3 @@ func PrintKeyMap(w io.Writer, target string, v []config.KeySuite) error {
}
return tw.Flush()
}

func PrintVerificationResults(w io.Writer, v []*notation.VerificationOutcome, resultErr error, digest string) error {
tw := newTabWriter(w)

if resultErr == nil {
fmt.Fprintf(tw, "Successfully verified for %s\n", digest)
// TODO[https://github.com/notaryproject/notation/issues/304]: print out failed validations as warnings.
return nil
}
fmt.Printf("Signature verification failed for all the signatures associated with digest: %s\n", digest)
tw.Flush()

return resultErr
}