Skip to content

Commit

Permalink
Refactor signing options a bit between blob/image. (#455)
Browse files Browse the repository at this point in the history
Signed-off-by: Dan Lorenc <dlorenc@google.com>
  • Loading branch information
dlorenc authored Jul 19, 2021
1 parent 2af7bd0 commit 9c0eb2e
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 66 deletions.
46 changes: 18 additions & 28 deletions cmd/cosign/cli/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,15 @@ EXAMPLES
return flag.ErrHelp
}

so := SignOpts{
KeyRef: *key,
Annotations: annotations.annotations,
Pf: GetPass,
Sk: *sk,
Slot: *slot,
IDToken: *idToken,
ko := KeyOpts{
KeyRef: *key,
PassFunc: GetPass,
Sk: *sk,
Slot: *slot,
IDToken: *idToken,
}
for _, img := range args {
if err := SignCmd(ctx, so, img, *cert, *upload, *payloadPath, *force, *recursive); err != nil {
if err := SignCmd(ctx, ko, annotations.annotations, img, *cert, *upload, *payloadPath, *force, *recursive); err != nil {
return errors.Wrapf(err, "signing %s", img)
}
}
Expand All @@ -149,15 +148,6 @@ EXAMPLES
}
}

type SignOpts struct {
Annotations map[string]interface{}
KeyRef string
Sk bool
Slot string
Pf cosign.PassFunc
IDToken string
}

func getTransitiveImages(rootIndex *remote.Descriptor, repo name.Repository, opts ...remote.Option) ([]name.Digest, error) {
var imgs []name.Digest

Expand Down Expand Up @@ -193,16 +183,16 @@ func getTransitiveImages(rootIndex *remote.Descriptor, repo name.Repository, opt
return imgs, nil
}

func SignCmd(ctx context.Context, so SignOpts,
func SignCmd(ctx context.Context, ko KeyOpts, annotations map[string]interface{},
imageRef string, certPath string, upload bool, payloadPath string, force bool, recursive bool) error {

// A key file or token is required unless we're in experimental mode!
if EnableExperimental() {
if nOf(so.KeyRef, so.Sk) > 1 {
if nOf(ko.KeyRef, ko.Sk) > 1 {
return &KeyParseError{}
}
} else {
if !oneOf(so.KeyRef, so.Sk) {
if !oneOf(ko.KeyRef, ko.Sk) {
return &KeyParseError{}
}
}
Expand Down Expand Up @@ -238,8 +228,8 @@ func SignCmd(ctx context.Context, so SignOpts,
var dupeDetector signature.Verifier
var cert, chain string
switch {
case so.Sk:
sk, err := pivkey.GetKeyWithSlot(so.Slot)
case ko.Sk:
sk, err := pivkey.GetKeyWithSlot(ko.Slot)
defer sk.Close()
if err != nil {
return err
Expand All @@ -262,8 +252,8 @@ func SignCmd(ctx context.Context, so SignOpts,
}
cert = string(cosign.CertToPem(certFromPIV))

case so.KeyRef != "":
k, err := signerVerifierFromKeyRef(ctx, so.KeyRef, so.Pf)
case ko.KeyRef != "":
k, err := signerVerifierFromKeyRef(ctx, ko.KeyRef, ko.PassFunc)
if err != nil {
return errors.Wrap(err, "reading key")
}
Expand Down Expand Up @@ -310,7 +300,7 @@ func SignCmd(ctx context.Context, so SignOpts,

default: // Keyless!
fmt.Fprintln(os.Stderr, "Generating ephemeral keys...")
k, err := fulcio.NewSigner(ctx, so.IDToken)
k, err := fulcio.NewSigner(ctx, ko.IDToken)
if err != nil {
return errors.Wrap(err, "getting key from Fulcio")
}
Expand Down Expand Up @@ -366,7 +356,7 @@ func SignCmd(ctx context.Context, so SignOpts,
if len(payload) == 0 {
payload, err = (&sigPayload.Cosign{
Image: img,
Annotations: so.Annotations,
Annotations: annotations,
}).MarshalJSON()
if err != nil {
return errors.Wrap(err, "payload")
Expand Down Expand Up @@ -416,7 +406,7 @@ func SignCmd(ctx context.Context, so SignOpts,
fmt.Println("tlog entry created with index: ", *entry.LogIndex)

uo.Bundle = bundle(entry)
uo.AdditionalAnnotations = annotations(entry)
uo.AdditionalAnnotations = parseAnnotations(entry)
}

fmt.Fprintln(os.Stderr, "Pushing signature to:", sigRef.String())
Expand All @@ -443,7 +433,7 @@ func bundle(entry *models.LogEntryAnon) *cremote.Bundle {
}
}

func annotations(entry *models.LogEntryAnon) map[string]string {
func parseAnnotations(entry *models.LogEntryAnon) map[string]string {
annts := map[string]string{}
if bund := bundle(entry); bund != nil {
contents, _ := json.Marshal(bund)
Expand Down
24 changes: 14 additions & 10 deletions cmd/cosign/cli/sign_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,14 @@ EXAMPLES
return flag.ErrHelp
}
ko := KeyOpts{
KeyRef: *key,
Sk: *sk,
Slot: *slot,
KeyRef: *key,
Sk: *sk,
Slot: *slot,
PassFunc: GetPass,
IDToken: *idToken,
}
for _, blob := range args {
if _, err := SignBlobCmd(ctx, ko, blob, *b64, GetPass, *idToken, *output); err != nil {
if _, err := SignBlobCmd(ctx, ko, blob, *b64, *output); err != nil {
return errors.Wrapf(err, "signing %s", blob)
}
}
Expand All @@ -99,12 +101,14 @@ EXAMPLES
}

type KeyOpts struct {
Sk bool
Slot string
KeyRef string
Sk bool
Slot string
KeyRef string
IDToken string
PassFunc cosign.PassFunc
}

func SignBlobCmd(ctx context.Context, ko KeyOpts, payloadPath string, b64 bool, pf cosign.PassFunc, idToken, output string) ([]byte, error) {
func SignBlobCmd(ctx context.Context, ko KeyOpts, payloadPath string, b64 bool, output string) ([]byte, error) {
var payload []byte
var err error
if payloadPath == "-" {
Expand All @@ -121,7 +125,7 @@ func SignBlobCmd(ctx context.Context, ko KeyOpts, payloadPath string, b64 bool,
var signer signature.Signer
switch {
case ko.KeyRef != "":
k, err := signerFromKeyRef(ctx, ko.KeyRef, pf)
k, err := signerFromKeyRef(ctx, ko.KeyRef, ko.PassFunc)
if err != nil {
return nil, errors.Wrap(err, "loading key")
}
Expand All @@ -140,7 +144,7 @@ func SignBlobCmd(ctx context.Context, ko KeyOpts, payloadPath string, b64 bool,
default:
// Keyless!
fmt.Fprintln(os.Stderr, "Generating ephemeral keys...")
k, err := fulcio.NewSigner(ctx, idToken)
k, err := fulcio.NewSigner(ctx, ko.IDToken)
if err != nil {
return nil, errors.Wrap(err, "getting key from Fulcio")
}
Expand Down
10 changes: 5 additions & 5 deletions cmd/cosign/cli/sign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ import (
func TestSignCmdLocalKeyAndSk(t *testing.T) {
ctx := context.Background()

for _, so := range []SignOpts{
for _, ko := range []KeyOpts{
// local and sk keys
{
KeyRef: "testLocalPath",
Pf: GetPass,
Sk: true,
KeyRef: "testLocalPath",
PassFunc: GetPass,
Sk: true,
},
} {
err := SignCmd(ctx, so, "", "", false, "", false, false)
err := SignCmd(ctx, ko, nil, "", "", false, "", false, false)
if (errors.Is(err, &KeyParseError{}) == false) {
t.Fatal("expected KeyParseError")
}
Expand Down
50 changes: 27 additions & 23 deletions test/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ func TestSignVerify(t *testing.T) {
mustErr(download.SignatureCmd(ctx, imgName), t)

// Now sign the image
so := cli.SignOpts{KeyRef: privKeyPath, Pf: passFunc}
must(cli.SignCmd(ctx, so, imgName, "", true, "", false, false), t)
ko := cli.KeyOpts{KeyRef: privKeyPath, PassFunc: passFunc}
must(cli.SignCmd(ctx, ko, nil, imgName, "", true, "", false, false), t)

// Now verify and download should work!
must(verify(pubKeyPath, imgName, true, nil), t)
Expand All @@ -99,8 +99,8 @@ func TestSignVerify(t *testing.T) {
mustErr(verify(pubKeyPath, imgName, true, map[string]interface{}{"foo": "bar"}), t)

// Sign the image with an annotation
so.Annotations = map[string]interface{}{"foo": "bar"}
must(cli.SignCmd(ctx, so, imgName, "", true, "", false, false), t)
annotations := map[string]interface{}{"foo": "bar"}
must(cli.SignCmd(ctx, ko, annotations, imgName, "", true, "", false, false), t)

// It should match this time.
must(verify(pubKeyPath, imgName, true, map[string]interface{}{"foo": "bar"}), t)
Expand All @@ -123,8 +123,8 @@ func TestSignVerifyClean(t *testing.T) {
ctx := context.Background()

// Now sign the image
so := cli.SignOpts{KeyRef: privKeyPath, Pf: passFunc}
must(cli.SignCmd(ctx, so, imgName, "", true, "", false, false), t)
ko := cli.KeyOpts{KeyRef: privKeyPath, PassFunc: passFunc}
must(cli.SignCmd(ctx, ko, nil, imgName, "", true, "", false, false), t)

// Now verify and download should work!
must(verify(pubKeyPath, imgName, true, nil), t)
Expand Down Expand Up @@ -156,13 +156,13 @@ func TestBundle(t *testing.T) {

ctx := context.Background()

so := cli.SignOpts{
KeyRef: privKeyPath,
Pf: passFunc,
ko := cli.KeyOpts{
KeyRef: privKeyPath,
PassFunc: passFunc,
}

// Sign the image
must(cli.SignCmd(ctx, so, imgName, "", true, "", false, false), t)
must(cli.SignCmd(ctx, ko, nil, imgName, "", true, "", false, false), t)
// Make sure verify works
must(verify(pubKeyPath, imgName, true, nil), t)

Expand Down Expand Up @@ -190,15 +190,15 @@ func TestDuplicateSign(t *testing.T) {
mustErr(download.SignatureCmd(ctx, imgName), t)

// Now sign the image
so := cli.SignOpts{KeyRef: privKeyPath, Pf: passFunc}
must(cli.SignCmd(ctx, so, imgName, "", true, "", false, false), t)
ko := cli.KeyOpts{KeyRef: privKeyPath, PassFunc: passFunc}
must(cli.SignCmd(ctx, ko, nil, imgName, "", true, "", false, false), t)

// Now verify and download should work!
must(verify(pubKeyPath, imgName, true, nil), t)
must(download.SignatureCmd(ctx, imgName), t)

// Signing again should work just fine...
must(cli.SignCmd(ctx, so, imgName, "", true, "", false, false), t)
must(cli.SignCmd(ctx, ko, nil, imgName, "", true, "", false, false), t)
// but a duplicate signature should not be a uploaded
sigRepo, err := cli.TargetRepositoryForImage(ref)
if err != nil {
Expand Down Expand Up @@ -291,15 +291,15 @@ func TestMultipleSignatures(t *testing.T) {
mustErr(verify(pub2, imgName, true, nil), t)

// Now sign the image with one key
so := cli.SignOpts{KeyRef: priv1, Pf: passFunc}
must(cli.SignCmd(ctx, so, imgName, "", true, "", false, false), t)
ko := cli.KeyOpts{KeyRef: priv1, PassFunc: passFunc}
must(cli.SignCmd(ctx, ko, nil, imgName, "", true, "", false, false), t)
// Now verify should work with that one, but not the other
must(verify(pub1, imgName, true, nil), t)
mustErr(verify(pub2, imgName, true, nil), t)

// Now sign with the other key too
so.KeyRef = priv2
must(cli.SignCmd(ctx, so, imgName, "", true, "", false, false), t)
ko.KeyRef = priv2
must(cli.SignCmd(ctx, ko, nil, imgName, "", true, "", false, false), t)

// Now verify should work with both
must(verify(pub1, imgName, true, nil), t)
Expand Down Expand Up @@ -337,7 +337,11 @@ func TestSignBlob(t *testing.T) {
mustErr(cli.VerifyBlobCmd(ctx, ko2, "", "badsig", blob), t)

// Now sign the blob with one key
sig, err := cli.SignBlobCmd(ctx, cli.KeyOpts{KeyRef: privKeyPath1}, bp, true, passFunc, "", "")
ko := cli.KeyOpts{
KeyRef: privKeyPath1,
PassFunc: passFunc,
}
sig, err := cli.SignBlobCmd(ctx, ko, bp, true, "")
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -595,11 +599,11 @@ func TestTlog(t *testing.T) {
mustErr(verify(pubKeyPath, imgName, true, nil), t)

// Now sign the image without the tlog
so := cli.SignOpts{
KeyRef: privKeyPath,
Pf: passFunc,
ko := cli.KeyOpts{
KeyRef: privKeyPath,
PassFunc: passFunc,
}
must(cli.SignCmd(ctx, so, imgName, "", true, "", false, false), t)
must(cli.SignCmd(ctx, ko, nil, imgName, "", true, "", false, false), t)

// Now verify should work!
must(verify(pubKeyPath, imgName, true, nil), t)
Expand All @@ -611,7 +615,7 @@ func TestTlog(t *testing.T) {
mustErr(verify(pubKeyPath, imgName, true, nil), t)

// Sign again with the tlog env var on
must(cli.SignCmd(ctx, so, imgName, "", true, "", false, false), t)
must(cli.SignCmd(ctx, ko, nil, imgName, "", true, "", false, false), t)
// And now verify works!
must(verify(pubKeyPath, imgName, true, nil), t)
}
Expand Down

0 comments on commit 9c0eb2e

Please sign in to comment.