diff --git a/pkg/verify/verify.go b/pkg/verify/verify.go index a06e4ea83b..a1f8d935a2 100644 --- a/pkg/verify/verify.go +++ b/pkg/verify/verify.go @@ -17,6 +17,7 @@ import ( "time" "golang.org/x/crypto/openpgp" + "k8s.io/apimachinery/pkg/util/errors" "k8s.io/klog/v2" "github.com/openshift/library-go/pkg/verify/store" @@ -43,6 +44,19 @@ type Interface interface { AddStore(additionalStore store.Store) } +type wrapError struct { + msg string + err error +} + +func (e *wrapError) Error() string { + return e.msg +} + +func (e *wrapError) Unwrap() error { + return e.err +} + type rejectVerifier struct{} func (rejectVerifier) Verify(ctx context.Context, releaseDigest string) error { @@ -171,19 +185,23 @@ func (v *releaseVerifier) Verify(ctx context.Context, releaseDigest string) erro } var signedWith [][]byte + var errs []error err := v.store.Signatures(ctx, "", releaseDigest, func(ctx context.Context, signature []byte, errIn error) (done bool, err error) { if errIn != nil { klog.V(4).Infof("error retrieving signature for %s: %v", releaseDigest, errIn) + errs = append(errs, errIn) return false, nil } for k, keyring := range remaining { content, _, err := verifySignatureWithKeyring(bytes.NewReader(signature), keyring) if err != nil { klog.V(4).Infof("keyring %q could not verify signature for %s: %v", k, releaseDigest, err) + errs = append(errs, err) continue } if err := verifyAtomicContainerSignature(content, releaseDigest); err != nil { klog.V(4).Infof("signature for %s is not valid: %v", releaseDigest, err) + errs = append(errs, err) continue } delete(remaining, k) @@ -193,16 +211,21 @@ func (v *releaseVerifier) Verify(ctx context.Context, releaseDigest string) erro }) if err != nil { klog.V(4).Infof("Failed to retrieve signatures for %s (should never happen)", releaseDigest) + errs = append(errs, err) return err } if len(remaining) > 0 { - if klog.V(4).Enabled() { - for k := range remaining { - klog.Infof("Unable to verify %s against keyring %s", releaseDigest, k) - } + remainingKeyRings := make([]string, 0, len(remaining)) + for k := range remaining { + remainingKeyRings = append(remainingKeyRings, k) } - return fmt.Errorf("unable to locate a valid signature for one or more sources") + err := &wrapError{ + msg: fmt.Sprintf("unable to verify %s against keyrings: %s", releaseDigest, strings.Join(remainingKeyRings, ", ")), + err: errors.NewAggregate(errs), + } + klog.V(4).Info(err.Error()) + return err } v.cacheVerification(releaseDigest, signedWith) diff --git a/pkg/verify/verify_test.go b/pkg/verify/verify_test.go index 81b8ef034b..45154baa1d 100644 --- a/pkg/verify/verify_test.go +++ b/pkg/verify/verify_test.go @@ -250,7 +250,7 @@ func Test_ReleaseVerifier_Signatures(t *testing.T) { store: &memory.Store{}, signatureCache: make(map[string][][]byte), } - if err := verifier.Verify(context.Background(), signedDigest); err == nil || err.Error() != "unable to locate a valid signature for one or more sources" { + if err := verifier.Verify(context.Background(), signedDigest); err == nil || err.Error() != fmt.Sprintf("unable to verify %s against keyrings: redhat", signedDigest) { t.Fatal(err) } if sigs := verifier.Signatures(); len(sigs) != 0 {