From 9a394435da8f16e0ae0e5bb8ba341fcb7b340740 Mon Sep 17 00:00:00 2001 From: Zachary Newman Date: Fri, 2 Sep 2022 20:51:19 -0400 Subject: [PATCH] Clarify error when KMS provider fails to load Before: $ KEY_REF=gcpkms://projects/test/locations/global/keyRings/test/cryptoKeys/mykey/cryptoKeyVersions/1 $ cosign verify-blob --key $KEY_REF --signature /dev/null /dev/null Error: verifying blob [/dev/null]: loading public key: loading URL: unrecognized scheme: gcpkms:// main.go:62: error during command execution: verifying blob [/dev/null]: loading public key: loading URL: unrecognized scheme: gcpkms:// After: $ KEY_REF=gcpkms://projects/test/locations/global/keyRings/test/cryptoKeys/mykey/cryptoKeyVersions/1 $ cosign verify-blob --key $KEY_REF --signature /dev/null /dev/null Error: verifying blob [/dev/null]: loading public key: new gcp kms client: google: could not find default credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information. main.go:62: error during command execution: verifying blob [/dev/null]: loading public key: new gcp kms client: google: could not find default credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information. Addresses #2094; I'm not sure if this fixes it, but it'll give us more information. Signed-off-by: Zachary Newman --- pkg/blob/load.go | 10 +++++++++- pkg/signature/keys.go | 5 +++++ pkg/signature/keys_test.go | 26 ++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/pkg/blob/load.go b/pkg/blob/load.go index c92d49c4ca3..26db1367848 100644 --- a/pkg/blob/load.go +++ b/pkg/blob/load.go @@ -23,6 +23,14 @@ import ( "strings" ) +type UnrecognizedSchemeError struct { + Scheme string +} + +func (e *UnrecognizedSchemeError) Error() string { + return fmt.Sprintf("loading URL: unrecognized scheme: %s", e.Scheme) +} + func LoadFileOrURL(fileRef string) ([]byte, error) { var raw []byte var err error @@ -51,7 +59,7 @@ func LoadFileOrURL(fileRef string) ([]byte, error) { } raw = []byte(value) default: - return nil, fmt.Errorf("loading URL: unrecognized scheme: %s", scheme) + return nil, &UnrecognizedSchemeError{Scheme: scheme} } } else { raw, err = os.ReadFile(filepath.Clean(fileRef)) diff --git a/pkg/signature/keys.go b/pkg/signature/keys.go index 21f22ce5ef8..982619705dd 100644 --- a/pkg/signature/keys.go +++ b/pkg/signature/keys.go @@ -46,6 +46,11 @@ func VerifierForKeyRef(ctx context.Context, keyRef string, hashAlgorithm crypto. if kmsKey, err := kms.Get(ctx, keyRef, hashAlgorithm); err == nil { // KMS specified return kmsKey, nil + } else if _, ok := err.(*kms.ProviderNotFoundError); !ok { + // We can ignore ProviderNotFoundError; that just means the keyRef + // didn't match any of the KMS schemes. But other errors indicate + // something more insidious; pass those through. + return nil, err } raw, err := blob.LoadFileOrURL(keyRef) diff --git a/pkg/signature/keys_test.go b/pkg/signature/keys_test.go index ef5600d104d..2446d8fd20b 100644 --- a/pkg/signature/keys_test.go +++ b/pkg/signature/keys_test.go @@ -16,10 +16,15 @@ package signature import ( "context" + "crypto" + "errors" "os" "testing" + "github.com/sigstore/cosign/pkg/blob" "github.com/sigstore/cosign/pkg/cosign" + sigsignature "github.com/sigstore/sigstore/pkg/signature" + "github.com/sigstore/sigstore/pkg/signature/kms" ) func generateKeyFile(t *testing.T, tmpDir string, pf cosign.PassFunc) (privFile, pubFile string) { @@ -134,6 +139,27 @@ func TestSignerVerifierFromEnvVar(t *testing.T) { } } +func TestVerifierForKeyRefError(t *testing.T) { + kms.AddProvider("errorkms://", func(ctx context.Context, _ string, hf crypto.Hash, _ ...sigsignature.RPCOption) (kms.SignerVerifier, error) { + return nil, errors.New("bad") + }) + + ctx := context.Background() + _, err := PublicKeyFromKeyRef(ctx, "errorkms://bad") + if err == nil { + t.Fatalf("PublicKeyFromKeyRef didn't return any error") + } else if _, ok := err.(*blob.UnrecognizedSchemeError); ok { + t.Fatalf("PublicKeyFromKeyRef returned UnrecognizedSchemeError: %v", err) + } + + _, err = PublicKeyFromKeyRef(ctx, "badscheme://bad") + if err == nil { + t.Fatalf("PublicKeyFromKeyRef didn't return any error") + } else if _, ok := err.(*blob.UnrecognizedSchemeError); !ok { + t.Fatalf("PublicKeyFromKeyRef didn't return UnrecognizedSchemeError: %v", err) + } +} + func pass(s string) cosign.PassFunc { return func(_ bool) ([]byte, error) { return []byte(s), nil