-
Notifications
You must be signed in to change notification settings - Fork 251
Bug 2071998: pkg/verify: Expose underlying signature errors #1358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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, ", ")), | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like we are logging the keys too. I am wondering if it is fine from security point of view>
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we're logging the keyring name, which is already public in our GitHub source. The only secret keys here are internal to Red Hat's build-time release signing. By the time we get out to clusters verifying signatures, it's all public names and public keys. |
||
| err: errors.NewAggregate(errs), | ||
| } | ||
| klog.V(4).Info(err.Error()) | ||
| return err | ||
| } | ||
|
|
||
| v.cacheVerification(releaseDigest, signedWith) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/Error()/ErrorStr()/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrapErroris from Go, because I wantedfmt.Sprintf("...%w")'sUnwrapsupport, but without formatting the whole, possibly long aggregate error into the message. We need to useErrorandUnwrapto match theerrorinterface.