Skip to content
This repository has been archived by the owner on May 3, 2022. It is now read-only.

Commit

Permalink
fix: clean up 'duffle key list' output (#313)
Browse files Browse the repository at this point in the history
This provides a more consistent interface for 'duffle key list'.
  • Loading branch information
technosophos authored Oct 31, 2018
1 parent 5c0b369 commit 423b119
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 14 deletions.
53 changes: 39 additions & 14 deletions cmd/duffle/key_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,64 @@ import (

"github.com/deis/duffle/pkg/duffle/home"
"github.com/deis/duffle/pkg/signature"
"github.com/gosuri/uitable"

"github.com/spf13/cobra"
)

const keyListDesc = `List key IDs for either the public or private keychain.
const keyListDesc = `List key IDs for both public (verify-only) and private (sign and verify) keys.
By default, this lists all of the IDs in the public keychain (the ones you
use to verify bundles). Use '--private' to see the secret keys that you can
use to sign or attest bundles.
By default, this lists both signing and verifying keys. All signing keys can be used
to verify. But a verify-only key can not be used to sign.
Use the '--signing' flag to list just the signing keys, and the '--verify-only' flag to
list just the public keys, which can only be used for verifying.
Because a key can exist in both the public and the secret keyring, it is possible for a
key to show up as a signing key with '--signing', and a verifying key with '--verify-only'.
This simply means that the key has been added to both keyrings.
`

func newKeyListCmd(w io.Writer) *cobra.Command {
var private bool
var (
privateOnly bool
publicOnly bool
)
cmd := &cobra.Command{
Use: "list",
Short: "list key IDs",
Long: keyListDesc,
RunE: func(cmd *cobra.Command, args []string) error {
h := home.Home(homePath())
ring := h.PublicKeyRing()
if private {
ring = h.SecretKeyRing()
// Order is important, since duplicate keys are skipped, and a key
// can appear in both keyrings.
rings := []string{h.SecretKeyRing(), h.PublicKeyRing()}
if privateOnly {
rings = []string{h.SecretKeyRing()}
}
if publicOnly {
rings = []string{h.PublicKeyRing()}
}
return listKeys(cmd.OutOrStdout(), ring)
return listKeys(cmd.OutOrStdout(), rings...)
},
}
cmd.Flags().BoolVarP(&private, "secret", "s", false, "show private keys instead of public keys")
cmd.Flags().BoolVarP(&privateOnly, "signing", "s", false, "show private (sign-or-verify) keys")
cmd.Flags().BoolVarP(&publicOnly, "verify-only", "p", false, "show public (verify-only) keys")

return cmd
}

func listKeys(out io.Writer, ring string) error {
kr, err := signature.LoadKeyRing(ring)
func listKeys(out io.Writer, rings ...string) error {
kr, err := signature.LoadKeyRings(rings...)
if err != nil {
return err
}

table := uitable.New()
table.MaxColWidth = 80
table.Wrap = true

table.AddRow("NAME", "TYPE", "FINGERPRINT")
for _, k := range kr.Keys() {
var name, fingerprint string
id, err := k.UserID()
Expand All @@ -52,8 +73,12 @@ func listKeys(out io.Writer, ring string) error {
name = id.String()
}
fingerprint = k.Fingerprint()
fmt.Printf("%s\t%q\n", name, fingerprint)
typ := "verify-only"
if k.CanSign() {
typ = "signing"
}
table.AddRow(name, typ, fingerprint)
}

fmt.Fprintln(out, table)
return nil
}
6 changes: 6 additions & 0 deletions pkg/signature/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ func (k *Key) Fingerprint() string {
return buf.String()
}

// CanSign indicates that a key is able to be used as a signer.
func (k *Key) CanSign() bool {
_, err := k.findPrivateKey()
return err == nil
}

// bestPrivateKey will find a private key and decrypt it if necessary.
//
// If a specific key is pinned on selectedPrivateKey, that key will be used.
Expand Down

0 comments on commit 423b119

Please sign in to comment.