-
Notifications
You must be signed in to change notification settings - Fork 296
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
Verify bundle signature is valid and is not modified #9209
Verify bundle signature is valid and is not modified #9209
Conversation
e17bb84
to
486d237
Compare
@@ -62,13 +62,4 @@ const ( | |||
|
|||
// KMS key alias | |||
KmsKey = "arn:aws:kms:us-west-2:857151390494:alias/signingEKSABundlesKey" | |||
|
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.
I have moved these constants to eks-anywhere constants package since these are used for both signing and verification purpose and to keep a single source of truth.
486d237
to
4c86845
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #9209 +/- ##
========================================
Coverage 72.37% 72.38%
========================================
Files 585 587 +2
Lines 45710 45836 +126
========================================
+ Hits 33084 33178 +94
- Misses 10888 10910 +22
- Partials 1738 1748 +10 ☔ View full report in Codecov by Sentry. |
4c86845
to
4b17c77
Compare
) | ||
|
||
// ValidateExtendedK8sVersionSupport validates all the validations needed for the support of extended kubernetes support. | ||
func ValidateExtendedK8sVersionSupport(_ context.Context, _ *anywherev1.Cluster, bundle *v1alpha1.Bundles, _ kubernetes.Client) error { |
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.
I am not using context, cluster and client field in this PR but I will need those for further extended support related validations.
4b17c77
to
8506072
Compare
// fields depending on your signing requirements. | ||
Excludes = "LnNwZWMudmVyc2lvbnNCdW5kbGVzW10uYm9vdHN0cmFwCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLmJvdHRsZXJvY2tldEhvc3RDb250YWluZXJzCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLmNlcnRNYW5hZ2VyCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLmNpbGl1bQouc3BlYy52ZXJzaW9uc0J1bmRsZXNbXS5jbG91ZFN0YWNrCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLmNsdXN0ZXJBUEkKLnNwZWMudmVyc2lvbnNCdW5kbGVzW10uY29udHJvbFBsYW5lCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLmRvY2tlcgouc3BlYy52ZXJzaW9uc0J1bmRsZXNbXS5la3NhCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLmV0Y2RhZG1Cb290c3RyYXAKLnNwZWMudmVyc2lvbnNCdW5kbGVzW10uZXRjZGFkbUNvbnRyb2xsZXIKLnNwZWMudmVyc2lvbnNCdW5kbGVzW10uZmx1eAouc3BlYy52ZXJzaW9uc0J1bmRsZXNbXS5oYXByb3h5Ci5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLmtpbmRuZXRkCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLm51dGFuaXgKLnNwZWMudmVyc2lvbnNCdW5kbGVzW10ucGFja2FnZUNvbnRyb2xsZXIKLnNwZWMudmVyc2lvbnNCdW5kbGVzW10uc25vdwouc3BlYy52ZXJzaW9uc0J1bmRsZXNbXS50aW5rZXJiZWxsCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLnVwZ3JhZGVyCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLnZTcGhlcmU=" | ||
// KMSPublicKey to verify bundle signature. | ||
KMSPublicKey = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFZU/Z6VVMU9HioT7rGkPdJg3frC2xyQZhWFIrz5HeZEfeQ2nAdnJMLrs2Qr3V9xVrJrHA54wnIHDoPGbEhojqg==" |
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.
from where did this value come? how is it produced?
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.
This is the public key of the KMS key that we use to sign the bundle.
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.
I know public keys are meant to be public, but should we be putting this out in the open?
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.
We have it in our packages repo too for verifying package bundle signature in the webhook.
pkg/signature/manifest.go
Outdated
|
||
pubparsed, err := x509.ParsePKIXPublicKey(pubdecoded) | ||
if err != nil { | ||
return false, digest, yml, fmt.Errorf("unable parse the public key (not PKIX): %v", err) |
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.
might think about this: %v
-> %w
.
"Wrap an error to expose it to callers. Do not wrap an error when doing so would expose implementation details."
reference: https://go.dev/blog/go1.13-errors#wrapping-errors-with-w
pkg/validations/extendedversion.go
Outdated
if !valid { | ||
return fmt.Errorf("signature on the bundle is invalid, error: %v, digest: %s", err, base64.StdEncoding.EncodeToString(digest[:])) | ||
} | ||
logger.Info("Signature on the bundle is valid.") |
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.
i recommend not logging in a function in a package like this. I recommend letting consumers/callers of the function do the logging. Also, this this looks like a global logger. Where is it even defined?
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.
Agree, I added it as a part of my debugging and forgot to remove. I have removed this log.
8506072
to
b67e52f
Compare
b67e52f
to
83cf0f2
Compare
controllers/cluster_controller.go
Outdated
func validateExtendedK8sVersionSupport(ctx context.Context, client client.Client, cluster *anywherev1.Cluster) error { | ||
bundle, err := c.BundlesForCluster(ctx, clientutil.NewKubeClient(client), cluster) | ||
if err != nil { | ||
return fmt.Errorf("failed to get bundle for cluster: %w", err) |
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.
We generally want to avoid saying error or failed again right?
return fmt.Errorf("failed to get bundle for cluster: %w", err) | |
return fmt.Errorf("getting bundle for cluster: %w", err) |
// Excludes is a base64-encoded, newline-delimited list of JSON/YAML paths to remove | ||
// from the Bundles manifest prior to computing the digest. You can add or remove | ||
// fields depending on your signing requirements. | ||
Excludes = "LnNwZWMudmVyc2lvbnNCdW5kbGVzW10uYm9vdHN0cmFwCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLmJvdHRsZXJvY2tldEhvc3RDb250YWluZXJzCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLmNlcnRNYW5hZ2VyCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLmNpbGl1bQouc3BlYy52ZXJzaW9uc0J1bmRsZXNbXS5jbG91ZFN0YWNrCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLmNsdXN0ZXJBUEkKLnNwZWMudmVyc2lvbnNCdW5kbGVzW10uY29udHJvbFBsYW5lCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLmRvY2tlcgouc3BlYy52ZXJzaW9uc0J1bmRsZXNbXS5la3NhCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLmV0Y2RhZG1Cb290c3RyYXAKLnNwZWMudmVyc2lvbnNCdW5kbGVzW10uZXRjZGFkbUNvbnRyb2xsZXIKLnNwZWMudmVyc2lvbnNCdW5kbGVzW10uZmx1eAouc3BlYy52ZXJzaW9uc0J1bmRsZXNbXS5oYXByb3h5Ci5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLmtpbmRuZXRkCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLm51dGFuaXgKLnNwZWMudmVyc2lvbnNCdW5kbGVzW10ucGFja2FnZUNvbnRyb2xsZXIKLnNwZWMudmVyc2lvbnNCdW5kbGVzW10uc25vdwouc3BlYy52ZXJzaW9uc0J1bmRsZXNbXS50aW5rZXJiZWxsCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLnVwZ3JhZGVyCi5zcGVjLnZlcnNpb25zQnVuZGxlc1tdLnZTcGhlcmU=" |
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.
How did we determine what to remove here?
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.
We are only concerned with the tampering of the above fields for extended support. In the future, if we need to include more fields in the bundle signature for particular usecase, it can be easily added by removing it from the Excludes annotation here.
pkg/signature/manifest.go
Outdated
|
||
pubdecoded, err := base64.StdEncoding.DecodeString(pubKey) | ||
if err != nil { | ||
return false, fmt.Errorf("unable to decode the public key (not base 64): %w", err) |
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.
Yea these should be phrased as such right?
return false, fmt.Errorf("unable to decode the public key (not base 64): %w", err) | |
return false, fmt.Errorf("decoding the public key as string: %w", err) |
// Marshal Bundles object to YAML | ||
yamlBytes, err := yaml.Marshal(bundle) | ||
if err != nil { | ||
return zero, nil, fmt.Errorf("marshalling bundle to YAML: %w", err) |
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.
Yea this is a right error message
@@ -389,6 +389,10 @@ func (r *ClusterReconciler) preClusterProviderReconcile(ctx context.Context, log | |||
return controller.Result{}, err | |||
} | |||
|
|||
if err := validateExtendedK8sVersionSupport(ctx, r.client, cluster); err != nil { |
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.
Are we planning to update the cluster status in any way, or this will just be reflected as an error in the controller logs?
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.
I have updated the status fields with error.
83cf0f2
to
97804a2
Compare
97804a2
to
7cdc7cb
Compare
/test eks-anywhere-release-tooling-test-presubmit |
fb5465a
to
da9a9dd
Compare
pkg/api/v1alpha1/cluster_types.go
Outdated
BundleNotFoundReason FailureReasonType = "BundleNotFoundForCluster" | ||
|
||
// K8sVersionNotSupportedReason reports that validation for supporting extended kubernetes version failed. | ||
K8sVersionNotSupportedReason FailureReasonType = "ExtendedKubernetesVersionNotSupported" |
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.
K8sVersionNotSupportedReason FailureReasonType = "ExtendedKubernetesVersionNotSupported" | |
ExtendedK8sVersionSupportNotSupportedReason FailureReasonType = "ExtendedKubernetesVersionSupportNotSupported" |
pkg/signature/manifets_test.go
Outdated
@@ -0,0 +1,338 @@ | |||
package signature |
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.
Can you rename this file to fix spelling?
/lgtm |
da9a9dd
to
fe12c2c
Compare
[APPROVALNOTIFIER] This PR is APPROVED Approval requirements bypassed by manually added approval. This pull-request has been approved by: The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Issue #, if available:
#6793
Description of changes:
Validate the EKS-A bundle has not been modified by verifying the signature in the bundle annotation. We sign the bundle by adding signature annotation on the bundle field. To verify the bundle, we have used ecdsa.VerifyASN1 method to support air gapped environment scenario. The validation is only added for controller for now.
Testing (if applicable):
Documentation added/planned (if applicable):
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.