mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-25 23:49:37 -05:00
fix: Azure SEV-SNP version always gets overwritten by latest API versions (#1930)
* fix that manual version gets overwritten by latest * put azure in seperate config file * otto feedback
This commit is contained in:
parent
c1f9d86cd3
commit
c5f75513b1
@ -6,6 +6,7 @@ go_library(
|
||||
srcs = [
|
||||
"attestation.go",
|
||||
"attestationversion.go",
|
||||
"azure.go",
|
||||
"config.go",
|
||||
"config_doc.go",
|
||||
# keep
|
||||
|
@ -17,20 +17,20 @@ const placeholderVersionValue = 0
|
||||
// NewLatestPlaceholderVersion returns the latest version with a placeholder version value.
|
||||
func NewLatestPlaceholderVersion() AttestationVersion {
|
||||
return AttestationVersion{
|
||||
Value: placeholderVersionValue,
|
||||
IsLatest: true,
|
||||
Value: placeholderVersionValue,
|
||||
WantLatest: true,
|
||||
}
|
||||
}
|
||||
|
||||
// AttestationVersion is a type that represents a version of a SNP.
|
||||
type AttestationVersion struct {
|
||||
Value uint8
|
||||
IsLatest bool
|
||||
Value uint8
|
||||
WantLatest bool
|
||||
}
|
||||
|
||||
// MarshalYAML implements a custom marshaller to resolve "latest" values.
|
||||
func (v AttestationVersion) MarshalYAML() (any, error) {
|
||||
if v.IsLatest {
|
||||
if v.WantLatest {
|
||||
return "latest", nil
|
||||
}
|
||||
return v.Value, nil
|
||||
@ -48,7 +48,7 @@ func (v *AttestationVersion) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
|
||||
// MarshalJSON implements a custom marshaller to resolve "latest" values.
|
||||
func (v AttestationVersion) MarshalJSON() ([]byte, error) {
|
||||
if v.IsLatest {
|
||||
if v.WantLatest {
|
||||
return json.Marshal("latest")
|
||||
}
|
||||
return json.Marshal(v.Value)
|
||||
@ -67,7 +67,7 @@ func (v *AttestationVersion) parseRawUnmarshal(rawUnmarshal any) error {
|
||||
switch s := rawUnmarshal.(type) {
|
||||
case string:
|
||||
if strings.ToLower(s) == "latest" {
|
||||
v.IsLatest = true
|
||||
v.WantLatest = true
|
||||
v.Value = placeholderVersionValue
|
||||
} else {
|
||||
return fmt.Errorf("invalid version value: %s", s)
|
||||
|
@ -22,16 +22,16 @@ func TestVersionMarshalYAML(t *testing.T) {
|
||||
{
|
||||
name: "isLatest resolves to latest",
|
||||
sut: AttestationVersion{
|
||||
Value: 1,
|
||||
IsLatest: true,
|
||||
Value: 1,
|
||||
WantLatest: true,
|
||||
},
|
||||
want: "latest\n",
|
||||
},
|
||||
{
|
||||
name: "value 5 resolves to 5",
|
||||
sut: AttestationVersion{
|
||||
Value: 5,
|
||||
IsLatest: false,
|
||||
Value: 5,
|
||||
WantLatest: false,
|
||||
},
|
||||
want: "5\n",
|
||||
},
|
||||
|
120
internal/config/azure.go
Normal file
120
internal/config/azure.go
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
|
||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||
)
|
||||
|
||||
// DefaultForAzureSEVSNP returns the default configuration for Azure SEV-SNP attestation.
|
||||
// Version numbers have placeholder values and the latest available values can be fetched using [AzureSEVSNP.FetchAndSetLatestVersionNumbers].
|
||||
func DefaultForAzureSEVSNP() *AzureSEVSNP {
|
||||
return &AzureSEVSNP{
|
||||
Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureSEVSNP{}),
|
||||
BootloaderVersion: NewLatestPlaceholderVersion(),
|
||||
TEEVersion: NewLatestPlaceholderVersion(),
|
||||
SNPVersion: NewLatestPlaceholderVersion(),
|
||||
MicrocodeVersion: NewLatestPlaceholderVersion(),
|
||||
FirmwareSignerConfig: SNPFirmwareSignerConfig{
|
||||
AcceptedKeyDigests: idkeydigest.DefaultList(),
|
||||
EnforcementPolicy: idkeydigest.MAAFallback,
|
||||
},
|
||||
// AMD root key. Received from the AMD Key Distribution System API (KDS).
|
||||
AMDRootKey: mustParsePEM(`-----BEGIN CERTIFICATE-----\nMIIGYzCCBBKgAwIBAgIDAQAAMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC\nBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS\nBgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg\nQ2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp\nY2VzMRIwEAYDVQQDDAlBUkstTWlsYW4wHhcNMjAxMDIyMTcyMzA1WhcNNDUxMDIy\nMTcyMzA1WjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS\nBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j\nZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJQVJLLU1pbGFuMIICIjANBgkqhkiG\n9w0BAQEFAAOCAg8AMIICCgKCAgEA0Ld52RJOdeiJlqK2JdsVmD7FktuotWwX1fNg\nW41XY9Xz1HEhSUmhLz9Cu9DHRlvgJSNxbeYYsnJfvyjx1MfU0V5tkKiU1EesNFta\n1kTA0szNisdYc9isqk7mXT5+KfGRbfc4V/9zRIcE8jlHN61S1ju8X93+6dxDUrG2\nSzxqJ4BhqyYmUDruPXJSX4vUc01P7j98MpqOS95rORdGHeI52Naz5m2B+O+vjsC0\n60d37jY9LFeuOP4Meri8qgfi2S5kKqg/aF6aPtuAZQVR7u3KFYXP59XmJgtcog05\ngmI0T/OitLhuzVvpZcLph0odh/1IPXqx3+MnjD97A7fXpqGd/y8KxX7jksTEzAOg\nbKAeam3lm+3yKIcTYMlsRMXPcjNbIvmsBykD//xSniusuHBkgnlENEWx1UcbQQrs\n+gVDkuVPhsnzIRNgYvM48Y+7LGiJYnrmE8xcrexekBxrva2V9TJQqnN3Q53kt5vi\nQi3+gCfmkwC0F0tirIZbLkXPrPwzZ0M9eNxhIySb2npJfgnqz55I0u33wh4r0ZNQ\neTGfw03MBUtyuzGesGkcw+loqMaq1qR4tjGbPYxCvpCq7+OgpCCoMNit2uLo9M18\nfHz10lOMT8nWAUvRZFzteXCm+7PHdYPlmQwUw3LvenJ/ILXoQPHfbkH0CyPfhl1j\nWhJFZasCAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSFrBrRQ/fI\nrFXUxR1BSKvVeErUUzAPBgNVHRMBAf8EBTADAQH/MDoGA1UdHwQzMDEwL6AtoCuG\nKWh0dHBzOi8va2RzaW50Zi5hbWQuY29tL3ZjZWsvdjEvTWlsYW4vY3JsMEYGCSqG\nSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZI\nAWUDBAICBQCiAwIBMKMDAgEBA4ICAQC6m0kDp6zv4Ojfgy+zleehsx6ol0ocgVel\nETobpx+EuCsqVFRPK1jZ1sp/lyd9+0fQ0r66n7kagRk4Ca39g66WGTJMeJdqYriw\nSTjjDCKVPSesWXYPVAyDhmP5n2v+BYipZWhpvqpaiO+EGK5IBP+578QeW/sSokrK\ndHaLAxG2LhZxj9aF73fqC7OAJZ5aPonw4RE299FVarh1Tx2eT3wSgkDgutCTB1Yq\nzT5DuwvAe+co2CIVIzMDamYuSFjPN0BCgojl7V+bTou7dMsqIu/TW/rPCX9/EUcp\nKGKqPQ3P+N9r1hjEFY1plBg93t53OOo49GNI+V1zvXPLI6xIFVsh+mto2RtgEX/e\npmMKTNN6psW88qg7c1hTWtN6MbRuQ0vm+O+/2tKBF2h8THb94OvvHHoFDpbCELlq\nHnIYhxy0YKXGyaW1NjfULxrrmxVW4wcn5E8GddmvNa6yYm8scJagEi13mhGu4Jqh\n3QU3sf8iUSUr09xQDwHtOQUVIqx4maBZPBtSMf+qUDtjXSSq8lfWcd8bLr9mdsUn\nJZJ0+tuPMKmBnSH860llKk+VpVQsgqbzDIvOLvD6W1Umq25boxCYJ+TuBoa4s+HH\nCViAvgT9kf/rBq1d+ivj6skkHxuzcxbk1xv6ZGxrteJxVH7KlX7YRdZ6eARKwLe4\nAFZEAwoKCQ==\n-----END CERTIFICATE-----\n`),
|
||||
}
|
||||
}
|
||||
|
||||
// GetVariant returns azure-sev-snp as the variant.
|
||||
func (AzureSEVSNP) GetVariant() variant.Variant {
|
||||
return variant.AzureSEVSNP{}
|
||||
}
|
||||
|
||||
// GetMeasurements returns the measurements used for attestation.
|
||||
func (c AzureSEVSNP) GetMeasurements() measurements.M {
|
||||
return c.Measurements
|
||||
}
|
||||
|
||||
// SetMeasurements updates a config's measurements using the given measurements.
|
||||
func (c *AzureSEVSNP) SetMeasurements(m measurements.M) {
|
||||
c.Measurements = m
|
||||
}
|
||||
|
||||
// EqualTo returns true if the config is equal to the given config.
|
||||
func (c AzureSEVSNP) EqualTo(old AttestationCfg) (bool, error) {
|
||||
otherCfg, ok := old.(*AzureSEVSNP)
|
||||
if !ok {
|
||||
return false, fmt.Errorf("cannot compare %T with %T", c, old)
|
||||
}
|
||||
|
||||
firmwareSignerCfgEqual := c.FirmwareSignerConfig.EqualTo(otherCfg.FirmwareSignerConfig)
|
||||
measurementsEqual := c.Measurements.EqualTo(otherCfg.Measurements)
|
||||
bootloaderEqual := c.BootloaderVersion == otherCfg.BootloaderVersion
|
||||
teeEqual := c.TEEVersion == otherCfg.TEEVersion
|
||||
snpEqual := c.SNPVersion == otherCfg.SNPVersion
|
||||
microcodeEqual := c.MicrocodeVersion == otherCfg.MicrocodeVersion
|
||||
rootKeyEqual := bytes.Equal(c.AMDRootKey.Raw, otherCfg.AMDRootKey.Raw)
|
||||
|
||||
return firmwareSignerCfgEqual && measurementsEqual && bootloaderEqual && teeEqual && snpEqual && microcodeEqual && rootKeyEqual, nil
|
||||
}
|
||||
|
||||
// FetchAndSetLatestVersionNumbers fetches the latest version numbers from the configapi and sets them.
|
||||
func (c *AzureSEVSNP) FetchAndSetLatestVersionNumbers(ctx context.Context, fetcher attestationconfigapi.Fetcher, now time.Time) error {
|
||||
versions, err := fetcher.FetchAzureSEVSNPVersionLatest(ctx, now)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// set number and keep isLatest flag
|
||||
c.mergeWithLatestVersion(versions.AzureSEVSNPVersion)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *AzureSEVSNP) mergeWithLatestVersion(latest attestationconfigapi.AzureSEVSNPVersion) {
|
||||
if c.BootloaderVersion.WantLatest {
|
||||
c.BootloaderVersion.Value = latest.Bootloader
|
||||
}
|
||||
if c.TEEVersion.WantLatest {
|
||||
c.TEEVersion.Value = latest.TEE
|
||||
}
|
||||
if c.SNPVersion.WantLatest {
|
||||
c.SNPVersion.Value = latest.SNP
|
||||
}
|
||||
if c.MicrocodeVersion.WantLatest {
|
||||
c.MicrocodeVersion.Value = latest.Microcode
|
||||
}
|
||||
}
|
||||
|
||||
// GetVariant returns azure-trusted-launch as the variant.
|
||||
func (AzureTrustedLaunch) GetVariant() variant.Variant {
|
||||
return variant.AzureTrustedLaunch{}
|
||||
}
|
||||
|
||||
// GetMeasurements returns the measurements used for attestation.
|
||||
func (c AzureTrustedLaunch) GetMeasurements() measurements.M {
|
||||
return c.Measurements
|
||||
}
|
||||
|
||||
// SetMeasurements updates a config's measurements using the given measurements.
|
||||
func (c *AzureTrustedLaunch) SetMeasurements(m measurements.M) {
|
||||
c.Measurements = m
|
||||
}
|
||||
|
||||
// EqualTo returns true if the config is equal to the given config.
|
||||
func (c AzureTrustedLaunch) EqualTo(other AttestationCfg) (bool, error) {
|
||||
otherCfg, ok := other.(*AzureTrustedLaunch)
|
||||
if !ok {
|
||||
return false, fmt.Errorf("cannot compare %T with %T", c, other)
|
||||
}
|
||||
return c.Measurements.EqualTo(otherCfg.Measurements), nil
|
||||
}
|
@ -976,102 +976,9 @@ type AzureSEVSNP struct {
|
||||
AMDRootKey Certificate `json:"amdRootKey" yaml:"amdRootKey"`
|
||||
}
|
||||
|
||||
// DefaultForAzureSEVSNP returns the default configuration for Azure SEV-SNP attestation.
|
||||
// Version numbers have placeholder values and the latest available values can be fetched using [AzureSEVSNP.FetchAndSetLatestVersionNumbers].
|
||||
func DefaultForAzureSEVSNP() *AzureSEVSNP {
|
||||
return &AzureSEVSNP{
|
||||
Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureSEVSNP{}),
|
||||
BootloaderVersion: NewLatestPlaceholderVersion(),
|
||||
TEEVersion: NewLatestPlaceholderVersion(),
|
||||
SNPVersion: NewLatestPlaceholderVersion(),
|
||||
MicrocodeVersion: NewLatestPlaceholderVersion(),
|
||||
FirmwareSignerConfig: SNPFirmwareSignerConfig{
|
||||
AcceptedKeyDigests: idkeydigest.DefaultList(),
|
||||
EnforcementPolicy: idkeydigest.MAAFallback,
|
||||
},
|
||||
// AMD root key. Received from the AMD Key Distribution System API (KDS).
|
||||
AMDRootKey: mustParsePEM(`-----BEGIN CERTIFICATE-----\nMIIGYzCCBBKgAwIBAgIDAQAAMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC\nBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS\nBgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg\nQ2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp\nY2VzMRIwEAYDVQQDDAlBUkstTWlsYW4wHhcNMjAxMDIyMTcyMzA1WhcNNDUxMDIy\nMTcyMzA1WjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS\nBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j\nZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJQVJLLU1pbGFuMIICIjANBgkqhkiG\n9w0BAQEFAAOCAg8AMIICCgKCAgEA0Ld52RJOdeiJlqK2JdsVmD7FktuotWwX1fNg\nW41XY9Xz1HEhSUmhLz9Cu9DHRlvgJSNxbeYYsnJfvyjx1MfU0V5tkKiU1EesNFta\n1kTA0szNisdYc9isqk7mXT5+KfGRbfc4V/9zRIcE8jlHN61S1ju8X93+6dxDUrG2\nSzxqJ4BhqyYmUDruPXJSX4vUc01P7j98MpqOS95rORdGHeI52Naz5m2B+O+vjsC0\n60d37jY9LFeuOP4Meri8qgfi2S5kKqg/aF6aPtuAZQVR7u3KFYXP59XmJgtcog05\ngmI0T/OitLhuzVvpZcLph0odh/1IPXqx3+MnjD97A7fXpqGd/y8KxX7jksTEzAOg\nbKAeam3lm+3yKIcTYMlsRMXPcjNbIvmsBykD//xSniusuHBkgnlENEWx1UcbQQrs\n+gVDkuVPhsnzIRNgYvM48Y+7LGiJYnrmE8xcrexekBxrva2V9TJQqnN3Q53kt5vi\nQi3+gCfmkwC0F0tirIZbLkXPrPwzZ0M9eNxhIySb2npJfgnqz55I0u33wh4r0ZNQ\neTGfw03MBUtyuzGesGkcw+loqMaq1qR4tjGbPYxCvpCq7+OgpCCoMNit2uLo9M18\nfHz10lOMT8nWAUvRZFzteXCm+7PHdYPlmQwUw3LvenJ/ILXoQPHfbkH0CyPfhl1j\nWhJFZasCAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSFrBrRQ/fI\nrFXUxR1BSKvVeErUUzAPBgNVHRMBAf8EBTADAQH/MDoGA1UdHwQzMDEwL6AtoCuG\nKWh0dHBzOi8va2RzaW50Zi5hbWQuY29tL3ZjZWsvdjEvTWlsYW4vY3JsMEYGCSqG\nSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZI\nAWUDBAICBQCiAwIBMKMDAgEBA4ICAQC6m0kDp6zv4Ojfgy+zleehsx6ol0ocgVel\nETobpx+EuCsqVFRPK1jZ1sp/lyd9+0fQ0r66n7kagRk4Ca39g66WGTJMeJdqYriw\nSTjjDCKVPSesWXYPVAyDhmP5n2v+BYipZWhpvqpaiO+EGK5IBP+578QeW/sSokrK\ndHaLAxG2LhZxj9aF73fqC7OAJZ5aPonw4RE299FVarh1Tx2eT3wSgkDgutCTB1Yq\nzT5DuwvAe+co2CIVIzMDamYuSFjPN0BCgojl7V+bTou7dMsqIu/TW/rPCX9/EUcp\nKGKqPQ3P+N9r1hjEFY1plBg93t53OOo49GNI+V1zvXPLI6xIFVsh+mto2RtgEX/e\npmMKTNN6psW88qg7c1hTWtN6MbRuQ0vm+O+/2tKBF2h8THb94OvvHHoFDpbCELlq\nHnIYhxy0YKXGyaW1NjfULxrrmxVW4wcn5E8GddmvNa6yYm8scJagEi13mhGu4Jqh\n3QU3sf8iUSUr09xQDwHtOQUVIqx4maBZPBtSMf+qUDtjXSSq8lfWcd8bLr9mdsUn\nJZJ0+tuPMKmBnSH860llKk+VpVQsgqbzDIvOLvD6W1Umq25boxCYJ+TuBoa4s+HH\nCViAvgT9kf/rBq1d+ivj6skkHxuzcxbk1xv6ZGxrteJxVH7KlX7YRdZ6eARKwLe4\nAFZEAwoKCQ==\n-----END CERTIFICATE-----\n`),
|
||||
}
|
||||
}
|
||||
|
||||
// GetVariant returns azure-sev-snp as the variant.
|
||||
func (AzureSEVSNP) GetVariant() variant.Variant {
|
||||
return variant.AzureSEVSNP{}
|
||||
}
|
||||
|
||||
// GetMeasurements returns the measurements used for attestation.
|
||||
func (c AzureSEVSNP) GetMeasurements() measurements.M {
|
||||
return c.Measurements
|
||||
}
|
||||
|
||||
// SetMeasurements updates a config's measurements using the given measurements.
|
||||
func (c *AzureSEVSNP) SetMeasurements(m measurements.M) {
|
||||
c.Measurements = m
|
||||
}
|
||||
|
||||
// EqualTo returns true if the config is equal to the given config.
|
||||
func (c AzureSEVSNP) EqualTo(old AttestationCfg) (bool, error) {
|
||||
otherCfg, ok := old.(*AzureSEVSNP)
|
||||
if !ok {
|
||||
return false, fmt.Errorf("cannot compare %T with %T", c, old)
|
||||
}
|
||||
|
||||
firmwareSignerCfgEqual := c.FirmwareSignerConfig.EqualTo(otherCfg.FirmwareSignerConfig)
|
||||
measurementsEqual := c.Measurements.EqualTo(otherCfg.Measurements)
|
||||
bootloaderEqual := c.BootloaderVersion == otherCfg.BootloaderVersion
|
||||
teeEqual := c.TEEVersion == otherCfg.TEEVersion
|
||||
snpEqual := c.SNPVersion == otherCfg.SNPVersion
|
||||
microcodeEqual := c.MicrocodeVersion == otherCfg.MicrocodeVersion
|
||||
rootKeyEqual := bytes.Equal(c.AMDRootKey.Raw, otherCfg.AMDRootKey.Raw)
|
||||
|
||||
return firmwareSignerCfgEqual && measurementsEqual && bootloaderEqual && teeEqual && snpEqual && microcodeEqual && rootKeyEqual, nil
|
||||
}
|
||||
|
||||
// FetchAndSetLatestVersionNumbers fetches the latest version numbers from the configapi and sets them.
|
||||
func (c *AzureSEVSNP) FetchAndSetLatestVersionNumbers(ctx context.Context, fetcher attestationconfigapi.Fetcher, now time.Time) error {
|
||||
versions, err := fetcher.FetchAzureSEVSNPVersionLatest(ctx, now)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// set number and keep isLatest flag
|
||||
c.mergeVersionNumbers(versions.AzureSEVSNPVersion)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *AzureSEVSNP) mergeVersionNumbers(versions attestationconfigapi.AzureSEVSNPVersion) {
|
||||
c.BootloaderVersion.Value = versions.Bootloader
|
||||
c.TEEVersion.Value = versions.TEE
|
||||
c.SNPVersion.Value = versions.SNP
|
||||
c.MicrocodeVersion.Value = versions.Microcode
|
||||
}
|
||||
|
||||
// AzureTrustedLaunch is the configuration for Azure Trusted Launch attestation.
|
||||
type AzureTrustedLaunch struct {
|
||||
// description: |
|
||||
// Expected TPM measurements.
|
||||
Measurements measurements.M `json:"measurements" yaml:"measurements" validate:"required,no_placeholders"`
|
||||
}
|
||||
|
||||
// GetVariant returns azure-trusted-launch as the variant.
|
||||
func (AzureTrustedLaunch) GetVariant() variant.Variant {
|
||||
return variant.AzureTrustedLaunch{}
|
||||
}
|
||||
|
||||
// GetMeasurements returns the measurements used for attestation.
|
||||
func (c AzureTrustedLaunch) GetMeasurements() measurements.M {
|
||||
return c.Measurements
|
||||
}
|
||||
|
||||
// SetMeasurements updates a config's measurements using the given measurements.
|
||||
func (c *AzureTrustedLaunch) SetMeasurements(m measurements.M) {
|
||||
c.Measurements = m
|
||||
}
|
||||
|
||||
// EqualTo returns true if the config is equal to the given config.
|
||||
func (c AzureTrustedLaunch) EqualTo(other AttestationCfg) (bool, error) {
|
||||
otherCfg, ok := other.(*AzureTrustedLaunch)
|
||||
if !ok {
|
||||
return false, fmt.Errorf("cannot compare %T with %T", c, other)
|
||||
}
|
||||
return c.Measurements.EqualTo(otherCfg.Measurements), nil
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
"go.uber.org/goleak"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
configapi "github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||
"github.com/edgelesssys/constellation/v2/internal/config/instancetypes"
|
||||
@ -57,16 +57,17 @@ func TestDefaultConfigWritesLatestVersion(t *testing.T) {
|
||||
assert.Equal("latest", mp.getAzureSEVSNPVersion("bootloaderVersion"))
|
||||
}
|
||||
|
||||
func TestReadConfigFile(t *testing.T) {
|
||||
func TestNew(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
config configMap
|
||||
configName string
|
||||
wantResult *Config
|
||||
wantErr bool
|
||||
}{
|
||||
"mix of Latest and uint as version value": {
|
||||
"Azure SEV-SNP: mix of Latest and uint as version value in file correctly sets latest versions values": {
|
||||
config: func() configMap {
|
||||
conf := Default()
|
||||
conf := Default() // default configures latest version
|
||||
modifyConfigForAzureToPassValidate(conf)
|
||||
m := getConfigAsMap(conf, t)
|
||||
m.setAzureSEVSNPVersion("microcodeVersion", "Latest") // check uppercase also works
|
||||
m.setAzureSEVSNPVersion("teeVersion", 2)
|
||||
@ -77,17 +78,68 @@ func TestReadConfigFile(t *testing.T) {
|
||||
configName: constants.ConfigFilename,
|
||||
wantResult: func() *Config {
|
||||
conf := Default()
|
||||
conf.Attestation.AzureSEVSNP.BootloaderVersion = AttestationVersion{
|
||||
Value: 1,
|
||||
IsLatest: false,
|
||||
modifyConfigForAzureToPassValidate(conf)
|
||||
conf.Attestation.AzureSEVSNP.MicrocodeVersion = AttestationVersion{
|
||||
Value: testCfg.Microcode,
|
||||
WantLatest: true,
|
||||
}
|
||||
conf.Attestation.AzureSEVSNP.TEEVersion = AttestationVersion{
|
||||
Value: 2,
|
||||
IsLatest: false,
|
||||
Value: 2,
|
||||
WantLatest: false,
|
||||
}
|
||||
conf.Attestation.AzureSEVSNP.BootloaderVersion = AttestationVersion{
|
||||
Value: 1,
|
||||
WantLatest: false,
|
||||
}
|
||||
conf.Attestation.AzureSEVSNP.SNPVersion = AttestationVersion{
|
||||
Value: testCfg.SNP,
|
||||
WantLatest: true,
|
||||
}
|
||||
return conf
|
||||
}(),
|
||||
},
|
||||
}
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
||||
if tc.config != nil {
|
||||
require.NoError(fileHandler.WriteYAML(tc.configName, tc.config, file.OptNone))
|
||||
}
|
||||
result, err := New(fileHandler, tc.configName, stubAttestationFetcher{}, false)
|
||||
if tc.wantErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
}
|
||||
assert.NoError(err)
|
||||
assert.Equal(tc.wantResult, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func modifyConfigForAzureToPassValidate(c *Config) {
|
||||
c.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||
c.Image = "v" + constants.VersionInfo()
|
||||
c.Provider.Azure.SubscriptionID = "11111111-1111-1111-1111-111111111111"
|
||||
c.Provider.Azure.TenantID = "11111111-1111-1111-1111-111111111111"
|
||||
c.Provider.Azure.Location = "westus"
|
||||
c.Provider.Azure.ResourceGroup = "test"
|
||||
c.Provider.Azure.UserAssignedIdentity = "/subscriptions/11111111-1111-1111-1111-111111111111/resourcegroups/constellation-identity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/constellation-identity"
|
||||
c.Attestation.AzureSEVSNP.Measurements = measurements.M{
|
||||
0: measurements.WithAllBytes(0x00, measurements.Enforce, measurements.PCRMeasurementLength),
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadConfigFile(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
config configMap
|
||||
configName string
|
||||
wantResult *Config
|
||||
wantErr bool
|
||||
wantedErrType error
|
||||
}{
|
||||
"refuse invalid version value": {
|
||||
config: func() configMap {
|
||||
conf := Default()
|
||||
@ -205,16 +257,7 @@ func TestNewWithDefaultOptions(t *testing.T) {
|
||||
confToWrite: func() *Config { // valid config with all, but clientSecretValue
|
||||
c := Default()
|
||||
c.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||
c.Image = "v" + constants.VersionInfo()
|
||||
c.Provider.Azure.SubscriptionID = "f4278079-288c-4766-a98c-ab9d5dba01a5"
|
||||
c.Provider.Azure.TenantID = "d4ff9d63-6d6d-4042-8f6a-21e804add5aa"
|
||||
c.Provider.Azure.Location = "westus"
|
||||
c.Provider.Azure.ResourceGroup = "test"
|
||||
c.Provider.Azure.UserAssignedIdentity = "/subscriptions/8b8bd01f-efd9-4113-9bd1-c82137c32da7/resourcegroups/constellation-identity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/constellation-identity"
|
||||
c.Provider.Azure.AppClientID = "3ea4bdc1-1cc1-4237-ae78-0831eff3491e"
|
||||
c.Attestation.AzureSEVSNP.Measurements = measurements.M{
|
||||
0: measurements.WithAllBytes(0x00, measurements.Enforce, measurements.PCRMeasurementLength),
|
||||
}
|
||||
modifyConfigForAzureToPassValidate(c)
|
||||
return c
|
||||
}(),
|
||||
envToSet: map[string]string{
|
||||
@ -225,18 +268,7 @@ func TestNewWithDefaultOptions(t *testing.T) {
|
||||
"set env overwrites": {
|
||||
confToWrite: func() *Config {
|
||||
c := Default()
|
||||
c.RemoveProviderAndAttestationExcept(cloudprovider.Azure)
|
||||
c.Image = "v" + constants.VersionInfo()
|
||||
c.Provider.Azure.SubscriptionID = "f4278079-288c-4766-a98c-ab9d5dba01a5"
|
||||
c.Provider.Azure.TenantID = "d4ff9d63-6d6d-4042-8f6a-21e804add5aa"
|
||||
c.Provider.Azure.Location = "westus"
|
||||
c.Provider.Azure.ResourceGroup = "test"
|
||||
c.Provider.Azure.ClientSecretValue = "other-value" // < Note secret set in config, as well.
|
||||
c.Provider.Azure.UserAssignedIdentity = "/subscriptions/8b8bd01f-efd9-4113-9bd1-c82137c32da7/resourcegroups/constellation-identity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/constellation-identity"
|
||||
c.Provider.Azure.AppClientID = "3ea4bdc1-1cc1-4237-ae78-0831eff3491e"
|
||||
c.Attestation.AzureSEVSNP.Measurements = measurements.M{
|
||||
0: measurements.WithAllBytes(0x00, measurements.Enforce, measurements.PCRMeasurementLength),
|
||||
}
|
||||
modifyConfigForAzureToPassValidate(c)
|
||||
return c
|
||||
}(),
|
||||
envToSet: map[string]string{
|
||||
@ -895,25 +927,25 @@ func getConfigAsMap(conf *Config, t *testing.T) (res configMap) {
|
||||
|
||||
type stubAttestationFetcher struct{}
|
||||
|
||||
func (f stubAttestationFetcher) FetchAzureSEVSNPVersionList(_ context.Context, _ configapi.AzureSEVSNPVersionList) (configapi.AzureSEVSNPVersionList, error) {
|
||||
return configapi.AzureSEVSNPVersionList(
|
||||
func (f stubAttestationFetcher) FetchAzureSEVSNPVersionList(_ context.Context, _ attestationconfigapi.AzureSEVSNPVersionList) (attestationconfigapi.AzureSEVSNPVersionList, error) {
|
||||
return attestationconfigapi.AzureSEVSNPVersionList(
|
||||
[]string{},
|
||||
), nil
|
||||
}
|
||||
|
||||
func (f stubAttestationFetcher) FetchAzureSEVSNPVersion(_ context.Context, _ configapi.AzureSEVSNPVersionAPI) (configapi.AzureSEVSNPVersionAPI, error) {
|
||||
return configapi.AzureSEVSNPVersionAPI{
|
||||
func (f stubAttestationFetcher) FetchAzureSEVSNPVersion(_ context.Context, _ attestationconfigapi.AzureSEVSNPVersionAPI) (attestationconfigapi.AzureSEVSNPVersionAPI, error) {
|
||||
return attestationconfigapi.AzureSEVSNPVersionAPI{
|
||||
AzureSEVSNPVersion: testCfg,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (f stubAttestationFetcher) FetchAzureSEVSNPVersionLatest(_ context.Context, _ time.Time) (configapi.AzureSEVSNPVersionAPI, error) {
|
||||
return configapi.AzureSEVSNPVersionAPI{
|
||||
func (f stubAttestationFetcher) FetchAzureSEVSNPVersionLatest(_ context.Context, _ time.Time) (attestationconfigapi.AzureSEVSNPVersionAPI, error) {
|
||||
return attestationconfigapi.AzureSEVSNPVersionAPI{
|
||||
AzureSEVSNPVersion: testCfg,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var testCfg = configapi.AzureSEVSNPVersion{
|
||||
var testCfg = attestationconfigapi.AzureSEVSNPVersion{
|
||||
Microcode: 93,
|
||||
TEE: 0,
|
||||
SNP: 6,
|
||||
|
Loading…
Reference in New Issue
Block a user