cli: fix incorrect usage of masterSecret salt for clusterID generation (#2169)

* Fix incorrect use of masterSecret salt for clusterID generation

Signed-off-by: Daniel Weiße <dw@edgeless.systems>

---------

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
Co-authored-by: Leonard Cohnen <lc@edgeless.systems>
This commit is contained in:
Daniel Weiße 2023-08-07 15:24:46 +02:00 committed by GitHub
parent bd26e6bae7
commit 8dbe79500f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 166 additions and 114 deletions

View file

@ -198,10 +198,18 @@ func (i *initCmd) initialize(cmd *cobra.Command, newDialer func(validator atls.V
return err
}
i.log.Debugf("Successfully marshaled service account URI")
i.log.Debugf("Generating master secret")
masterSecret, err := i.generateMasterSecret(cmd.OutOrStdout(), flags.workspace)
if err != nil {
return fmt.Errorf("generating master secret: %w", err)
}
i.log.Debugf("Generated measurement salt")
measurementSalt, err := crypto.GenerateRandomBytes(crypto.RNGLengthDefault)
if err != nil {
return fmt.Errorf("generating measurement salt: %w", err)
}
i.log.Debugf("Measurement salt: %x", measurementSalt)
clusterName := clusterid.GetClusterName(conf, idFile)
i.log.Debugf("Setting cluster name to %s", clusterName)
@ -211,6 +219,7 @@ func (i *initCmd) initialize(cmd *cobra.Command, newDialer func(validator atls.V
req := &initproto.InitRequest{
KmsUri: masterSecret.EncodeToURI(),
StorageUri: uri.NoStoreURI,
MeasurementSalt: measurementSalt,
CloudServiceAccountUri: serviceAccURI,
KubernetesVersion: versions.VersionConfigs[k8sVersion].ClusterVersion,
KubernetesComponents: versions.VersionConfigs[k8sVersion].KubernetesComponents.ToInitProto(),
@ -248,7 +257,7 @@ func (i *initCmd) initialize(cmd *cobra.Command, newDialer func(validator atls.V
if err != nil {
return fmt.Errorf("getting Terraform output: %w", err)
}
releases, err := helmLoader.LoadReleases(conf, flags.conformance, flags.helmWaitMode, masterSecret.Key, masterSecret.Salt, serviceAccURI, idFile, output)
releases, err := helmLoader.LoadReleases(conf, flags.conformance, flags.helmWaitMode, masterSecret, measurementSalt, serviceAccURI, idFile, output)
if err != nil {
return fmt.Errorf("loading Helm charts: %w", err)
}

View file

@ -431,6 +431,7 @@ go_library(
"//internal/config",
"//internal/constants",
"//internal/file",
"//internal/kms/uri",
"//internal/retry",
"//internal/semver",
"//internal/versions",
@ -475,6 +476,7 @@ go_test(
"//internal/compatibility",
"//internal/config",
"//internal/file",
"//internal/kms/uri",
"//internal/logger",
"//internal/semver",
"@com_github_pkg_errors//:errors",

View file

@ -25,6 +25,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
"github.com/edgelesssys/constellation/v2/internal/semver"
"github.com/edgelesssys/constellation/v2/internal/versions"
)
@ -106,7 +107,10 @@ func NewLoader(csp cloudprovider.Provider, k8sVersion versions.ValidK8sVersion,
}
// LoadReleases loads the embedded helm charts and returns them as a HelmReleases object.
func (i *ChartLoader) LoadReleases(config *config.Config, conformanceMode bool, helmWaitMode WaitMode, masterSecret, salt []byte, serviceAccURI string, idFile clusterid.File, output terraform.ApplyOutput) (*Releases, error) {
func (i *ChartLoader) LoadReleases(
config *config.Config, conformanceMode bool, helmWaitMode WaitMode, masterSecret uri.MasterSecret,
measurementSalt []byte, serviceAccURI string, idFile clusterid.File, output terraform.ApplyOutput,
) (*Releases, error) {
ciliumRelease, err := i.loadRelease(ciliumInfo, helmWaitMode)
if err != nil {
return nil, fmt.Errorf("loading cilium: %w", err)
@ -129,7 +133,7 @@ func (i *ChartLoader) LoadReleases(config *config.Config, conformanceMode bool,
if err != nil {
return nil, fmt.Errorf("loading constellation-services: %w", err)
}
svcVals, err := extraConstellationServicesValues(config, masterSecret, salt, idFile.UID, serviceAccURI, output)
svcVals, err := extraConstellationServicesValues(config, masterSecret, measurementSalt, idFile.UID, serviceAccURI, output)
if err != nil {
return nil, fmt.Errorf("extending constellation-services values: %w", err)
}

View file

@ -31,6 +31,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/cloud/gcpshared"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
)
func fakeServiceAccURI(provider cloudprovider.Provider) string {
@ -67,7 +68,11 @@ func TestLoadReleases(t *testing.T) {
require := require.New(t)
config := &config.Config{Provider: config.ProviderConfig{GCP: &config.GCPConfig{}}}
chartLoader := ChartLoader{csp: config.GetProvider()}
helmReleases, err := chartLoader.LoadReleases(config, true, WaitModeAtomic, []byte("secret"), []byte("salt"), fakeServiceAccURI(cloudprovider.GCP), clusterid.File{UID: "testuid"}, terraform.ApplyOutput{GCP: &terraform.GCPApplyOutput{}})
helmReleases, err := chartLoader.LoadReleases(
config, true, WaitModeAtomic,
uri.MasterSecret{Key: []byte("secret"), Salt: []byte("salt")}, []byte("salt"),
fakeServiceAccURI(cloudprovider.GCP), clusterid.File{UID: "testuid"}, terraform.ApplyOutput{GCP: &terraform.GCPApplyOutput{}},
)
require.NoError(err)
chart := helmReleases.ConstellationServices.Chart
assert.NotNil(chart.Dependencies())
@ -176,10 +181,16 @@ func TestConstellationServices(t *testing.T) {
require.NoError(err)
values := chartLoader.loadConstellationServicesValues()
serviceAccURI := fakeServiceAccURI(tc.config.GetProvider())
extraVals, err := extraConstellationServicesValues(tc.config, []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), "uid", serviceAccURI, terraform.ApplyOutput{
Azure: &terraform.AzureApplyOutput{},
GCP: &terraform.GCPApplyOutput{},
})
extraVals, err := extraConstellationServicesValues(
tc.config, uri.MasterSecret{
Key: []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
Salt: []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
},
[]byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
"uid", serviceAccURI, terraform.ApplyOutput{
Azure: &terraform.AzureApplyOutput{},
GCP: &terraform.GCPApplyOutput{},
})
require.NoError(err)
values = mergeMaps(values, extraVals)

View file

@ -20,6 +20,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/cloud/openstack"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
)
// TODO(malt3): switch over to DNS name on AWS and Azure
@ -52,7 +53,8 @@ func extraCiliumValues(provider cloudprovider.Provider, conformanceMode bool, ou
// extraConstellationServicesValues extends the given values map by some values depending on user input.
// Values set inside this function are only applied during init, not during upgrade.
func extraConstellationServicesValues(cfg *config.Config, masterSecret, salt []byte, uid, serviceAccURI string, output terraform.ApplyOutput,
func extraConstellationServicesValues(
cfg *config.Config, masterSecret uri.MasterSecret, measurementSalt []byte, uid, serviceAccURI string, output terraform.ApplyOutput,
) (map[string]any, error) {
attestationConfigJSON, err := json.Marshal(cfg.GetAttestationConfig())
if err != nil {
@ -60,7 +62,7 @@ func extraConstellationServicesValues(cfg *config.Config, masterSecret, salt []b
}
extraVals := map[string]any{}
extraVals["join-service"] = map[string]any{
"measurementSalt": base64.StdEncoding.EncodeToString(salt),
"measurementSalt": base64.StdEncoding.EncodeToString(measurementSalt),
"attestationVariant": cfg.GetAttestationConfig().GetVariant().String(),
"attestationConfig": string(attestationConfigJSON),
}
@ -73,8 +75,8 @@ func extraConstellationServicesValues(cfg *config.Config, masterSecret, salt []b
}
extraVals["key-service"] = map[string]any{
"masterSecret": base64.StdEncoding.EncodeToString(masterSecret),
"salt": base64.StdEncoding.EncodeToString(salt),
"masterSecret": base64.StdEncoding.EncodeToString(masterSecret.Key),
"salt": base64.StdEncoding.EncodeToString(masterSecret.Salt),
}
switch cfg.GetProvider() {
case cloudprovider.OpenStack: