Refactor enforced/expected PCRs (#553)

* Merge enforced and expected measurements

* Update measurement generation to new format

* Write expected measurements hex encoded by default

* Allow hex or base64 encoded expected measurements

* Allow hex or base64 encoded clusterID

* Allow security upgrades to warnOnly flag

* Upload signed measurements in JSON format

* Fetch measurements either from JSON or YAML

* Use yaml.v3 instead of yaml.v2

* Error on invalid enforced selection

* Add placeholder measurements to config

* Update e2e test to new measurement format

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
Daniel Weiße 2022-11-24 10:57:58 +01:00 committed by GitHub
parent 8ce954e012
commit f8001efbc0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 1180 additions and 801 deletions

View file

@ -138,10 +138,7 @@ type AWSConfig struct {
IAMProfileWorkerNodes string `yaml:"iamProfileWorkerNodes" validate:"required"`
// description: |
// Expected VM measurements.
Measurements Measurements `yaml:"measurements"`
// description: |
// List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning.
EnforcedMeasurements []uint32 `yaml:"enforcedMeasurements"`
Measurements Measurements `yaml:"measurements" validate:"required,no_placeholders"`
}
// AzureConfig are Azure specific configuration values used by the CLI.
@ -190,10 +187,7 @@ type AzureConfig struct {
EnforceIDKeyDigest *bool `yaml:"enforceIdKeyDigest" validate:"required"`
// description: |
// Expected confidential VM measurements.
Measurements Measurements `yaml:"measurements"`
// description: |
// List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning.
EnforcedMeasurements []uint32 `yaml:"enforcedMeasurements"`
Measurements Measurements `yaml:"measurements" validate:"required,no_placeholders"`
}
// GCPConfig are GCP specific configuration values used by the CLI.
@ -221,10 +215,7 @@ type GCPConfig struct {
DeployCSIDriver *bool `yaml:"deployCSIDriver" validate:"required"`
// description: |
// Expected confidential VM measurements.
Measurements Measurements `yaml:"measurements"`
// description: |
// List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning.
EnforcedMeasurements []uint32 `yaml:"enforcedMeasurements"`
Measurements Measurements `yaml:"measurements" validate:"required,no_placeholders"`
}
// QEMUConfig holds config information for QEMU based Constellation deployments.
@ -255,10 +246,7 @@ type QEMUConfig struct {
Firmware string `yaml:"firmware"`
// description: |
// Measurement used to enable measured boot.
Measurements Measurements `yaml:"measurements"`
// description: |
// List of values that should be enforced to be equal to the ones from the measurement list. Any non-equal values not in this list will only result in a warning.
EnforcedMeasurements []uint32 `yaml:"enforcedMeasurements"`
Measurements Measurements `yaml:"measurements" validate:"required,no_placeholders"`
}
// Default returns a struct with the default config.
@ -276,7 +264,6 @@ func Default() *Config {
IAMProfileControlPlane: "",
IAMProfileWorkerNodes: "",
Measurements: measurements.DefaultsFor(cloudprovider.AWS),
EnforcedMeasurements: []uint32{4, 8, 9, 11, 12, 13, 15},
},
Azure: &AzureConfig{
SubscriptionID: "",
@ -292,7 +279,6 @@ func Default() *Config {
ConfidentialVM: func() *bool { b := true; return &b }(),
SecureBoot: func() *bool { b := false; return &b }(),
Measurements: measurements.DefaultsFor(cloudprovider.Azure),
EnforcedMeasurements: []uint32{4, 8, 9, 11, 12, 13, 15},
},
GCP: &GCPConfig{
Project: "",
@ -303,7 +289,6 @@ func Default() *Config {
StateDiskType: "pd-ssd",
DeployCSIDriver: func() *bool { b := true; return &b }(),
Measurements: measurements.DefaultsFor(cloudprovider.GCP),
EnforcedMeasurements: []uint32{0, 4, 8, 9, 11, 12, 13, 15},
},
QEMU: &QEMUConfig{
ImageFormat: "raw",
@ -314,7 +299,6 @@ func Default() *Config {
LibvirtContainerImage: versions.LibvirtImage,
NVRAM: "production",
Measurements: measurements.DefaultsFor(cloudprovider.QEMU),
EnforcedMeasurements: []uint32{4, 8, 9, 11, 12, 13, 15},
},
},
KubernetesVersion: string(versions.Default),
@ -446,18 +430,18 @@ func (c *Config) EnforcesIDKeyDigest() bool {
return c.Provider.Azure != nil && c.Provider.Azure.EnforceIDKeyDigest != nil && *c.Provider.Azure.EnforceIDKeyDigest
}
// GetEnforcedPCRs returns the list of enforced PCRs for the configured cloud provider.
func (c *Config) GetEnforcedPCRs() []uint32 {
// EnforcedPCRs returns the list of enforced PCRs for the configured cloud provider.
func (c *Config) EnforcedPCRs() []uint32 {
provider := c.GetProvider()
switch provider {
case cloudprovider.AWS:
return c.Provider.AWS.EnforcedMeasurements
return c.Provider.AWS.Measurements.GetEnforced()
case cloudprovider.Azure:
return c.Provider.Azure.EnforcedMeasurements
return c.Provider.Azure.Measurements.GetEnforced()
case cloudprovider.GCP:
return c.Provider.GCP.EnforcedMeasurements
return c.Provider.GCP.Measurements.GetEnforced()
case cloudprovider.QEMU:
return c.Provider.QEMU.EnforcedMeasurements
return c.Provider.QEMU.Measurements.GetEnforced()
default:
return nil
}
@ -499,6 +483,14 @@ func (c *Config) Validate() error {
return err
}
if err := validate.RegisterTranslation("no_placeholders", trans, registerContainsPlaceholderError, translateContainsPlaceholderError); err != nil {
return err
}
if err := validate.RegisterValidation("no_placeholders", validateNoPlaceholder); err != nil {
return err
}
if err := validate.RegisterValidation("safe_image", validateImage); err != nil {
return err
}