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..6c89d22b974 100644 --- a/pkg/signature/keys.go +++ b/pkg/signature/keys.go @@ -43,9 +43,19 @@ func LoadPublicKey(ctx context.Context, keyRef string) (verifier signature.Verif // verifier using the provided hash algorithm func VerifierForKeyRef(ctx context.Context, keyRef string, hashAlgorithm crypto.Hash) (verifier signature.Verifier, err error) { // The key could be plaintext, in a file, at a URL, or in KMS. - if kmsKey, err := kms.Get(ctx, keyRef, hashAlgorithm); err == nil { + var perr *kms.ProviderNotFoundError + kmsKey, err := kms.Get(ctx, keyRef, hashAlgorithm) + switch { + case err == nil: // KMS specified return kmsKey, nil + case errors.As(err, &perr): + // We can ignore ProviderNotFoundError; that just means the keyRef + // didn't match any of the KMS schemes. + default: + // 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..fc1ed81f18f 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,28 @@ 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") + }) + var uerr *blob.UnrecognizedSchemeError + + ctx := context.Background() + _, err := PublicKeyFromKeyRef(ctx, "errorkms://bad") + if err == nil { + t.Fatalf("PublicKeyFromKeyRef didn't return any error") + } else if errors.As(err, &uerr) { + 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 !errors.As(err, &uerr) { + t.Fatalf("PublicKeyFromKeyRef didn't return UnrecognizedSchemeError: %v", err) + } +} + func pass(s string) cosign.PassFunc { return func(_ bool) ([]byte, error) { return []byte(s), nil