attestation: add awsSEVSNP as new variant (#1900)

* variant: move into internal/attestation
* attesation: move aws attesation into subfolder nitrotpm
* config: add aws-sev-snp variant
* cli: add tf option to enable AWS SNP

For now the implementations in aws/nitrotpm and aws/snp
are identical. They both contain the aws/nitrotpm impl.
A separate commit will add the actual attestation logic.
This commit is contained in:
Otto Bittner 2023-06-09 15:41:02 +02:00 committed by GitHub
parent 947d0cb20a
commit 8f21972aec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
110 changed files with 993 additions and 215 deletions

View File

@ -107,8 +107,8 @@ runs:
constellation-conf.yaml
yq eval -i \
"(.provider | select(. | has(\"aws\")).aws.region) = \"eu-central-1\" |
(.provider | select(. | has(\"aws\")).aws.zone) = \"eu-central-1c\" |
"(.provider | select(. | has(\"aws\")).aws.region) = \"eu-west-1\" |
(.provider | select(. | has(\"aws\")).aws.zone) = \"eu-west-1c\" |
(.provider | select(. | has(\"aws\")).aws.iamProfileControlPlane) = \"e2e_test_control_plane_instance_profile\" |
(.provider | select(. | has(\"aws\")).aws.iamProfileWorkerNodes) = \"e2e_test_worker_node_instance_profile\"" \
constellation-conf.yaml
@ -143,6 +143,10 @@ runs:
"(.attestation | select(. | has(\"awsNitroTPM\")).awsNitroTPM.measurements) = {15:{\"expected\":\"0000000000000000000000000000000000000000000000000000000000000000\",\"warnOnly\":false}}" \
constellation-conf.yaml
yq eval -i \
"(.attestation | select(. | has(\"awsSEVSNP\")).awsSEVSNP.measurements) = {15:{\"expected\":\"0000000000000000000000000000000000000000000000000000000000000000\",\"warnOnly\":false}}" \
constellation-conf.yaml
yq eval -i \
"(.attestation | select(. | has(\"azureSEVSNP\")).azureSEVSNP.measurements) = {15:{\"expected\":\"0000000000000000000000000000000000000000000000000000000000000000\",\"warnOnly\":false}}" \
constellation-conf.yaml

View File

@ -203,7 +203,7 @@ runs:
with:
cloudProvider: ${{ inputs.cloudProvider }}
namePrefix: ${{ steps.create-prefix.outputs.prefix }}
awsZone: eu-central-1c
awsZone: eu-west-1c
azureRegion: northeurope
gcpProjectID: ${{ inputs.gcpProject }}
gcpZone: europe-west3-b

View File

@ -26,6 +26,7 @@ go_library(
"//internal/attestation/initialize",
"//internal/attestation/simulator",
"//internal/attestation/tdx",
"//internal/attestation/variant",
"//internal/attestation/vtpm",
"//internal/cloud/aws",
"//internal/cloud/azure",
@ -40,7 +41,6 @@ go_library(
"//internal/kubernetes/kubectl",
"//internal/logger",
"//internal/role",
"//internal/variant",
"//internal/versions/components",
"@com_github_spf13_afero//:afero",
"@io_k8s_kubernetes//cmd/kubeadm/app/apis/kubeadm/v1beta3",

View File

@ -24,6 +24,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/attestation/choose"
"github.com/edgelesssys/constellation/v2/internal/attestation/simulator"
"github.com/edgelesssys/constellation/v2/internal/attestation/tdx"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
awscloud "github.com/edgelesssys/constellation/v2/internal/cloud/aws"
azurecloud "github.com/edgelesssys/constellation/v2/internal/cloud/azure"
@ -35,7 +36,6 @@ import (
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/kubernetes/kubectl"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/variant"
)
const (

View File

@ -40,12 +40,12 @@ go_test(
deps = [
"//bootstrapper/initproto",
"//internal/atls",
"//internal/attestation/variant",
"//internal/crypto/testvector",
"//internal/file",
"//internal/kms/setup",
"//internal/kms/uri",
"//internal/logger",
"//internal/variant",
"//internal/versions/components",
"@com_github_spf13_afero//:afero",
"@com_github_stretchr_testify//assert",

View File

@ -19,12 +19,12 @@ import (
"github.com/edgelesssys/constellation/v2/bootstrapper/initproto"
"github.com/edgelesssys/constellation/v2/internal/atls"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/crypto/testvector"
"github.com/edgelesssys/constellation/v2/internal/file"
kmssetup "github.com/edgelesssys/constellation/v2/internal/kms/setup"
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions/components"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"

View File

@ -23,12 +23,12 @@ go_library(
"//internal/atls",
"//internal/attestation/choose",
"//internal/attestation/measurements",
"//internal/attestation/variant",
"//internal/cloud/cloudprovider",
"//internal/cloud/gcpshared",
"//internal/config",
"//internal/constants",
"//internal/imagefetcher",
"//internal/variant",
"@com_github_azure_azure_sdk_for_go//profiles/latest/attestation/attestation",
"@com_github_azure_azure_sdk_for_go_sdk_azcore//policy",
"@com_github_azure_azure_sdk_for_go_sdk_azidentity//:azidentity",
@ -53,10 +53,10 @@ go_test(
"//cli/internal/iamid",
"//cli/internal/terraform",
"//internal/attestation/measurements",
"//internal/attestation/variant",
"//internal/cloud/cloudprovider",
"//internal/cloud/gcpshared",
"//internal/config",
"//internal/variant",
"@com_github_hashicorp_terraform_json//:terraform-json",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",

View File

@ -11,8 +11,8 @@ import (
"io"
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/variant"
tfjson "github.com/hashicorp/terraform-json"
)

View File

@ -12,8 +12,8 @@ import (
"testing"
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/variant"
tfjson "github.com/hashicorp/terraform-json"
"go.uber.org/goleak"

View File

@ -21,11 +21,11 @@ import (
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
"github.com/edgelesssys/constellation/v2/cli/internal/libvirt"
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"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/imagefetcher"
"github.com/edgelesssys/constellation/v2/internal/variant"
)
// Creator creates cloud resources.
@ -143,6 +143,7 @@ func (c *Creator) createAWS(ctx context.Context, cl terraformClient, opts Create
IAMProfileControlPlane: opts.Config.Provider.AWS.IAMProfileControlPlane,
IAMProfileWorkerNodes: opts.Config.Provider.AWS.IAMProfileWorkerNodes,
Debug: opts.Config.IsDebugCluster(),
EnableSNP: opts.Config.GetAttestationConfig().GetVariant().Equal(variant.AWSSEVSNP{}),
}
if err := cl.PrepareWorkspace(path.Join("terraform", strings.ToLower(cloudprovider.AWS.String())), &vars); err != nil {

View File

@ -16,8 +16,8 @@ import (
"github.com/edgelesssys/constellation/v2/internal/atls"
"github.com/edgelesssys/constellation/v2/internal/attestation/choose"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/spf13/cobra"
)
@ -31,7 +31,7 @@ func UpdateInitMeasurements(config config.AttestationCfg, ownerID, clusterID str
m := config.GetMeasurements()
switch config.GetVariant() {
case variant.AWSNitroTPM{}, variant.AzureTrustedLaunch{}, variant.AzureSEVSNP{}, variant.GCPSEVES{}, variant.QEMUVTPM{}:
case variant.AWSNitroTPM{}, variant.AWSSEVSNP{}, variant.AzureTrustedLaunch{}, variant.AzureSEVSNP{}, variant.GCPSEVES{}, variant.QEMUVTPM{}:
if err := updateMeasurementTPM(m, uint32(measurements.PCRIndexOwnerID), ownerID); err != nil {
return err
}

View File

@ -53,6 +53,7 @@ go_library(
"//internal/api/versionsapi",
"//internal/atls",
"//internal/attestation/measurements",
"//internal/attestation/variant",
"//internal/cloud/azureshared",
"//internal/cloud/cloudprovider",
"//internal/cloud/gcpshared",
@ -74,7 +75,6 @@ go_library(
"//internal/retry",
"//internal/semver",
"//internal/sigstore",
"//internal/variant",
"//internal/versions",
"//operators/constellation-node-operator/api/v1alpha1",
"//verify/verifyproto",
@ -140,6 +140,7 @@ go_test(
"//internal/api/versionsapi",
"//internal/atls",
"//internal/attestation/measurements",
"//internal/attestation/variant",
"//internal/cloud/cloudprovider",
"//internal/cloud/gcpshared",
"//internal/config",
@ -152,7 +153,6 @@ go_test(
"//internal/kms/uri",
"//internal/license",
"//internal/logger",
"//internal/variant",
"//internal/versions",
"//operators/constellation-node-operator/api/v1alpha1",
"//verify/verifyproto",

View File

@ -10,12 +10,12 @@ import (
"fmt"
"strings"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/compatibility"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
"github.com/spf13/afero"

View File

@ -11,12 +11,12 @@ import (
"fmt"
"testing"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"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/file"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/spf13/afero"
"github.com/spf13/cobra"
@ -216,7 +216,11 @@ func TestValidProviderAttestationCombination(t *testing.T) {
variant.AzureSEVSNP{},
config.AttestationConfig{AzureSEVSNP: defaultAttestation.AzureSEVSNP},
},
{
cloudprovider.AWS,
variant.AWSSEVSNP{},
config.AttestationConfig{AWSSEVSNP: defaultAttestation.AWSSEVSNP},
},
{
cloudprovider.AWS,
variant.AWSNitroTPM{},
@ -227,7 +231,6 @@ func TestValidProviderAttestationCombination(t *testing.T) {
variant.GCPSEVES{},
config.AttestationConfig{GCPSEVES: defaultAttestation.GCPSEVES},
},
{
cloudprovider.QEMU,
variant.QEMUVTPM{},

View File

@ -14,11 +14,11 @@ import (
"github.com/edgelesssys/constellation/v2/cli/internal/cloudcmd"
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"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/file"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/spf13/afero"
"github.com/spf13/cobra"
)

View File

@ -21,6 +21,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
"github.com/edgelesssys/constellation/v2/internal/atls"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/compatibility"
"github.com/spf13/afero"
@ -121,6 +122,10 @@ func (i *initCmd) initialize(cmd *cobra.Command, newDialer func(validator atls.V
return err
}
if conf.GetAttestationConfig().GetVariant().Equal(variant.AWSSEVSNP{}) {
cmd.PrintErrln("WARNING: SNP based attestation is still under active development. Please do not use in production.")
}
i.log.Debugf("Checking cluster ID file")
var idFile clusterid.File
if err := fileHandler.ReadJSON(constants.ClusterIDsFileName, &idFile); err != nil {

View File

@ -23,6 +23,7 @@ import (
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
"github.com/edgelesssys/constellation/v2/internal/atls"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/cloud/gcpshared"
"github.com/edgelesssys/constellation/v2/internal/config"
@ -34,7 +35,6 @@ import (
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
"github.com/edgelesssys/constellation/v2/internal/license"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"

View File

@ -20,13 +20,13 @@ import (
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
"github.com/edgelesssys/constellation/v2/cli/internal/upgrade"
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/compatibility"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/imagefetcher"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/spf13/afero"
"github.com/spf13/cobra"

View File

@ -16,12 +16,12 @@ import (
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
"github.com/edgelesssys/constellation/v2/cli/internal/kubernetes"
"github.com/edgelesssys/constellation/v2/cli/internal/upgrade"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"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/file"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

View File

@ -22,6 +22,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/api/fetcher"
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/compatibility"
"github.com/edgelesssys/constellation/v2/internal/config"
@ -30,7 +31,6 @@ import (
"github.com/edgelesssys/constellation/v2/internal/kubernetes/kubectl"
conSemver "github.com/edgelesssys/constellation/v2/internal/semver"
"github.com/edgelesssys/constellation/v2/internal/sigstore"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
"github.com/spf13/afero"

View File

@ -17,12 +17,12 @@ import (
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"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/file"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

View File

@ -20,6 +20,7 @@ import (
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
"github.com/edgelesssys/constellation/v2/internal/atls"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/constants"
@ -27,7 +28,6 @@ import (
"github.com/edgelesssys/constellation/v2/internal/grpc/dialer"
"github.com/edgelesssys/constellation/v2/internal/grpc/testdialer"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/verify/verifyproto"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"

View File

@ -16,6 +16,7 @@ go_library(
"//cli/internal/upgrade",
"//internal/api/versionsapi",
"//internal/attestation/measurements",
"//internal/attestation/variant",
"//internal/cloud/cloudprovider",
"//internal/compatibility",
"//internal/config",
@ -24,7 +25,6 @@ go_library(
"//internal/imagefetcher",
"//internal/kubernetes",
"//internal/kubernetes/kubectl",
"//internal/variant",
"//internal/versions",
"//internal/versions/components",
"//operators/constellation-node-operator/api/v1alpha1",
@ -46,12 +46,12 @@ go_test(
embed = [":kubernetes"],
deps = [
"//internal/attestation/measurements",
"//internal/attestation/variant",
"//internal/cloud/cloudprovider",
"//internal/compatibility",
"//internal/config",
"//internal/constants",
"//internal/logger",
"//internal/variant",
"//internal/versions",
"//internal/versions/components",
"//operators/constellation-node-operator/api/v1alpha1",

View File

@ -21,6 +21,7 @@ import (
"github.com/edgelesssys/constellation/v2/cli/internal/upgrade"
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/compatibility"
"github.com/edgelesssys/constellation/v2/internal/config"
@ -29,7 +30,6 @@ import (
"github.com/edgelesssys/constellation/v2/internal/imagefetcher"
internalk8s "github.com/edgelesssys/constellation/v2/internal/kubernetes"
"github.com/edgelesssys/constellation/v2/internal/kubernetes/kubectl"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/edgelesssys/constellation/v2/internal/versions/components"
updatev1alpha1 "github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/api/v1alpha1"

View File

@ -14,12 +14,12 @@ import (
"testing"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/compatibility"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/edgelesssys/constellation/v2/internal/versions/components"
updatev1alpha1 "github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/api/v1alpha1"

View File

@ -237,6 +237,7 @@ module "instance_group_control_plane" {
security_groups = [aws_security_group.security_group.id]
subnetwork = module.public_private_subnet.private_subnet_id
iam_instance_profile = var.iam_instance_profile_control_plane
enable_snp = var.enable_snp
tags = merge(
local.tags,
{ Name = local.name },
@ -261,6 +262,7 @@ module "instance_group_worker_nodes" {
target_group_arns = []
security_groups = [aws_security_group.security_group.id]
iam_instance_profile = var.iam_instance_profile_worker_nodes
enable_snp = var.enable_snp
tags = merge(
local.tags,
{ Name = local.name },

View File

@ -44,6 +44,11 @@ resource "aws_launch_template" "launch_template" {
image_id, # required. update procedure modifies the image id externally
]
}
# See: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template#cpu-options
cpu_options {
amd_sev_snp = var.enable_snp ? "enabled" : "disabled"
}
}
resource "aws_autoscaling_group" "autoscaling_group" {

View File

@ -62,3 +62,9 @@ variable "tags" {
type = map(string)
description = "The tags to add to the instance group."
}
variable "enable_snp" {
type = bool
default = true
description = "Enable AMD SEV SNP. Setting this to true sets the cpu-option AmdSevSnp to enable."
}

View File

@ -69,3 +69,9 @@ variable "debug" {
default = false
description = "Enable debug mode. This opens up a debugd port that can be used to deploy a custom bootstrapper."
}
variable "enable_snp" {
type = bool
default = true
description = "Enable AMD SEV SNP. Setting this to true sets the cpu-option AmdSevSnp to enable."
}

View File

@ -39,7 +39,7 @@ func (v *CommonVariables) String() string {
return b.String()
}
// AWSClusterVariables is user configuration for creating a cluster with Terraform on GCP.
// AWSClusterVariables is user configuration for creating a cluster with Terraform on AWS.
type AWSClusterVariables struct {
// CommonVariables contains common variables.
CommonVariables
@ -59,6 +59,8 @@ type AWSClusterVariables struct {
IAMProfileWorkerNodes string
// Debug is true if debug mode is enabled.
Debug bool
// EnableSNP controls enablement of the EC2 cpu-option "AmdSevSnp".
EnableSNP bool
}
func (v *AWSClusterVariables) String() string {
@ -72,6 +74,7 @@ func (v *AWSClusterVariables) String() string {
writeLinef(b, "iam_instance_profile_control_plane = %q", v.IAMProfileControlPlane)
writeLinef(b, "iam_instance_profile_worker_nodes = %q", v.IAMProfileWorkerNodes)
writeLinef(b, "debug = %t", v.Debug)
writeLinef(b, "enable_snp = %t", v.EnableSNP)
return b.String()
}

View File

@ -13,6 +13,7 @@ go_library(
"//disk-mapper/internal/setup",
"//internal/attestation/choose",
"//internal/attestation/tdx",
"//internal/attestation/variant",
"//internal/attestation/vtpm",
"//internal/cloud/aws",
"//internal/cloud/azure",
@ -26,7 +27,6 @@ go_library(
"//internal/kms/setup",
"//internal/logger",
"//internal/role",
"//internal/variant",
"@com_github_spf13_afero//:afero",
"@org_uber_go_zap//:zap",
],

View File

@ -20,6 +20,7 @@ import (
"github.com/edgelesssys/constellation/v2/disk-mapper/internal/setup"
"github.com/edgelesssys/constellation/v2/internal/attestation/choose"
"github.com/edgelesssys/constellation/v2/internal/attestation/tdx"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
awscloud "github.com/edgelesssys/constellation/v2/internal/cloud/aws"
azurecloud "github.com/edgelesssys/constellation/v2/internal/cloud/azure"
@ -33,7 +34,6 @@ import (
kmssetup "github.com/edgelesssys/constellation/v2/internal/kms/setup"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/role"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/spf13/afero"
"go.uber.org/zap"
)

View File

@ -28,11 +28,11 @@ go_test(
deps = [
"//disk-mapper/recoverproto",
"//internal/atls",
"//internal/attestation/variant",
"//internal/grpc/dialer",
"//internal/grpc/testdialer",
"//internal/kms/kms",
"//internal/logger",
"//internal/variant",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
"@org_uber_go_goleak//:goleak",

View File

@ -15,11 +15,11 @@ import (
"github.com/edgelesssys/constellation/v2/disk-mapper/recoverproto"
"github.com/edgelesssys/constellation/v2/internal/atls"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/grpc/dialer"
"github.com/edgelesssys/constellation/v2/internal/grpc/testdialer"
"github.com/edgelesssys/constellation/v2/internal/kms/kms"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"

View File

@ -75,7 +75,7 @@ constellation config generate {aws|azure|gcp|openstack|qemu|stackit} [flags]
### Options
```
-a, --attestation string attestation variant to use {aws-nitro-tpm|azure-sev-snp|azure-trustedlaunch|gcp-sev-es|qemu-vtpm}. If not specified, the default for the cloud provider is used
-a, --attestation string attestation variant to use {aws-sev-snp|aws-nitro-tpm|azure-sev-snp|azure-trustedlaunch|gcp-sev-es|qemu-vtpm}. If not specified, the default for the cloud provider is used
-f, --file string path to output file, or '-' for stdout (default "constellation-conf.yaml")
-h, --help help for generate
-k, --kubernetes string Kubernetes version to use in format MAJOR.MINOR (default "v1.26")

View File

@ -13,11 +13,11 @@ go_library(
deps = [
"//internal/api/versionsapi",
"//internal/attestation/measurements",
"//internal/attestation/variant",
"//internal/cloud/cloudprovider",
"//internal/constants",
"//internal/imagefetcher",
"//internal/logger",
"//internal/variant",
"@sh_helm_helm_v3//pkg/action",
"@sh_helm_helm_v3//pkg/cli",
],

View File

@ -14,9 +14,9 @@ import (
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/imagefetcher"
"github.com/edgelesssys/constellation/v2/internal/variant"
)
type upgradeInfo struct {

View File

@ -14,11 +14,11 @@ go_library(
deps = [
"//internal/api/client",
"//internal/api/fetcher",
"//internal/attestation/variant",
"//internal/constants",
"//internal/logger",
"//internal/sigstore",
"//internal/staticupload",
"//internal/variant",
],
)

View File

@ -13,8 +13,8 @@ import (
"sort"
"strings"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/variant"
)
// attestationURLPath is the URL path to the attestation versions.

View File

@ -12,10 +12,10 @@ import (
"time"
apiclient "github.com/edgelesssys/constellation/v2/internal/api/client"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/sigstore"
"github.com/edgelesssys/constellation/v2/internal/staticupload"
"github.com/edgelesssys/constellation/v2/internal/variant"
)
// Client manages (modifies) the version information for the attestation variants.

View File

@ -7,8 +7,8 @@ go_library(
importpath = "github.com/edgelesssys/constellation/v2/internal/atls",
visibility = ["//:__subpackages__"],
deps = [
"//internal/attestation/variant",
"//internal/crypto",
"//internal/variant",
],
)
@ -17,7 +17,7 @@ go_test(
srcs = ["atls_test.go"],
embed = [":atls"],
deps = [
"//internal/variant",
"//internal/attestation/variant",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
"@org_uber_go_goleak//:goleak",

View File

@ -12,7 +12,7 @@ The protocol can be used by clients to verify a server certificate, by a server
1. The client sends a ClientHello message, setting ServerName to a random nonce.
2. The server generates an attestation statement using the clients nonce and its CC capabilities.
* The attestation is embedded in the server certificate using x509 certificate extensions with an object identifier (OID) to identify the CC attestation type. Take a look at the [`variant`](../variant/variant.go) package for implementation details.
* The attestation is embedded in the server certificate using x509 certificate extensions with an object identifier (OID) to identify the CC attestation type. Take a look at the [`variant`](../attestation/variant/variant.go) package for implementation details.
3. The client verifies the attestation statement.

View File

@ -25,8 +25,8 @@ import (
"math/big"
"time"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/crypto"
"github.com/edgelesssys/constellation/v2/internal/variant"
)
const attestationTimeout = 30 * time.Second

View File

@ -15,7 +15,7 @@ import (
"net/http/httptest"
"testing"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"

View File

@ -1,51 +1,8 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//bazel/go:go_test.bzl", "go_test")
go_library(
name = "aws",
srcs = [
"aws.go",
"issuer.go",
"validator.go",
],
srcs = ["aws.go"],
importpath = "github.com/edgelesssys/constellation/v2/internal/attestation/aws",
visibility = ["//:__subpackages__"],
deps = [
"//internal/attestation",
"//internal/attestation/vtpm",
"//internal/config",
"//internal/variant",
"@com_github_aws_aws_sdk_go_v2_config//:config",
"@com_github_aws_aws_sdk_go_v2_feature_ec2_imds//:imds",
"@com_github_aws_aws_sdk_go_v2_service_ec2//:ec2",
"@com_github_google_go_tpm//tpm2",
"@com_github_google_go_tpm_tools//client",
"@com_github_google_go_tpm_tools//proto/attest",
],
)
go_test(
name = "aws_test",
srcs = [
"issuer_test.go",
"validator_test.go",
],
embed = [":aws"],
# keep
gotags = select({
"//bazel/settings:tpm_simulator_enabled": [],
"//conditions:default": ["disable_tpm_simulator"],
}),
deps = [
"//internal/attestation/simulator",
"//internal/attestation/vtpm",
"@com_github_aws_aws_sdk_go_v2_feature_ec2_imds//:imds",
"@com_github_aws_aws_sdk_go_v2_service_ec2//:ec2",
"@com_github_aws_aws_sdk_go_v2_service_ec2//types",
"@com_github_aws_smithy_go//middleware",
"@com_github_google_go_tpm_tools//client",
"@com_github_google_go_tpm_tools//proto/attest",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
],
)

View File

@ -7,24 +7,17 @@ SPDX-License-Identifier: AGPL-3.0-only
/*
# Amazon Web Services attestation
Attestation for AWS using [NitroTPM].
Constellation supports multiple attestation technologies on AWS.
AWS currently does not support confidential VMs, but offers a TPM 2.0 compliant vTPM integration.
We use this to enable a TPM based measured boot Constellation deployment.
- SEV - Secure Nested Paging (SEV-SNP)
# Issuer
TPM attestation verified using an SEV-SNP attestation statement.
The TPM runs outside the confidential context.
The initial firmware measurement included in the SNP report can be calculated idependently.
The source code of the firmware is publicly available.
The TPM attestation is signed by the NitroTPM's RSA attestation key.
Additionally to the TPM attestation, we attach a node's [instance identity document] to the attestation document.
- NitroTPM
# Validator
Currently, the NitroTPM provides no endorsement certificate for its attestation key, nor does AWS offer a secondary of of verifying it.
For now we have to blindly trust the key.
Additionally to verifying the TPM attestation, we also check the instance identity document for consistency.
[NitroTPM]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nitrotpm.html
[instance identity document]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html
No confidential computing. Attestation via a TPM 2.0 compliant vTPM.
*/
package aws

View File

@ -0,0 +1,72 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//bazel/go:go_test.bzl", "go_test")
go_library(
name = "nitrotpm",
srcs = [
"issuer.go",
"nitrotpm.go",
"validator.go",
],
importpath = "github.com/edgelesssys/constellation/v2/internal/attestation/aws/nitrotpm",
visibility = ["//:__subpackages__"],
deps = [
"//internal/attestation",
"//internal/attestation/variant",
"//internal/attestation/vtpm",
"//internal/config",
"@com_github_aws_aws_sdk_go_v2_config//:config",
"@com_github_aws_aws_sdk_go_v2_feature_ec2_imds//:imds",
"@com_github_aws_aws_sdk_go_v2_service_ec2//:ec2",
"@com_github_google_go_tpm//tpm2",
"@com_github_google_go_tpm_tools//client",
"@com_github_google_go_tpm_tools//proto/attest",
],
)
go_test(
name = "nitro_test",
srcs = [
"issuer_test.go",
"validator_test.go",
],
embed = [":nitrotpm"],
# keep
gotags = select({
"//bazel/settings:tpm_simulator_enabled": [],
"//conditions:default": ["disable_tpm_simulator"],
}),
deps = [
"//internal/attestation/simulator",
"//internal/attestation/vtpm",
"@com_github_aws_aws_sdk_go_v2_feature_ec2_imds//:imds",
"@com_github_aws_aws_sdk_go_v2_service_ec2//:ec2",
"@com_github_aws_aws_sdk_go_v2_service_ec2//types",
"@com_github_aws_smithy_go//middleware",
"@com_github_google_go_tpm_tools//client",
"@com_github_google_go_tpm_tools//proto/attest",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
],
)
go_test(
name = "nitrotpm_test",
srcs = [
"issuer_test.go",
"validator_test.go",
],
embed = [":nitrotpm"],
deps = [
"//internal/attestation/simulator",
"//internal/attestation/vtpm",
"@com_github_aws_aws_sdk_go_v2_feature_ec2_imds//:imds",
"@com_github_aws_aws_sdk_go_v2_service_ec2//:ec2",
"@com_github_aws_aws_sdk_go_v2_service_ec2//types",
"@com_github_aws_smithy_go//middleware",
"@com_github_google_go_tpm_tools//client",
"@com_github_google_go_tpm_tools//proto/attest",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
],
)

View File

@ -4,19 +4,18 @@ Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package aws
package nitrotpm
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/google/go-tpm-tools/client"
tpmclient "github.com/google/go-tpm-tools/client"
@ -28,7 +27,7 @@ type Issuer struct {
*vtpm.Issuer
}
// NewIssuer creates a new OpenVTPM based issuer for AWS.
// NewIssuer creates a TPM based issuer for AWS.
func NewIssuer(log attestation.Logger) *Issuer {
return &Issuer{
Issuer: vtpm.NewIssuer(
@ -44,8 +43,7 @@ func NewIssuer(log attestation.Logger) *Issuer {
func getAttestationKey(tpm io.ReadWriter) (*tpmclient.Key, error) {
tpmAk, err := client.AttestationKeyRSA(tpm)
if err != nil {
log.Fatalf("error creating RSA Endorsement key!")
return nil, err
return nil, fmt.Errorf("error creating RSA Endorsement key: %w", err)
}
return tpmAk, nil
@ -54,10 +52,10 @@ func getAttestationKey(tpm io.ReadWriter) (*tpmclient.Key, error) {
// getInstanceInfo returns information about the current instance using the aws Metadata SDK.
// The returned bytes will be written into the attestation document.
func getInstanceInfo(client awsMetaData) func(context.Context, io.ReadWriteCloser, []byte) ([]byte, error) {
return func(context.Context, io.ReadWriteCloser, []byte) ([]byte, error) {
ec2InstanceIdentityOutput, err := client.GetInstanceIdentityDocument(context.Background(), &imds.GetInstanceIdentityDocumentInput{})
return func(ctx context.Context, _ io.ReadWriteCloser, _ []byte) ([]byte, error) {
ec2InstanceIdentityOutput, err := client.GetInstanceIdentityDocument(ctx, &imds.GetInstanceIdentityDocumentInput{})
if err != nil {
return nil, errors.New("unable to fetch instance identity document")
return nil, fmt.Errorf("fetching instance identity document: %w", err)
}
return json.Marshal(ec2InstanceIdentityOutput.InstanceIdentityDocument)
}

View File

@ -0,0 +1,118 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package nitrotpm
import (
"context"
"errors"
"testing"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/aws/smithy-go/middleware"
"github.com/edgelesssys/constellation/v2/internal/attestation/simulator"
tpmclient "github.com/google/go-tpm-tools/client"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGetAttestationKey(t *testing.T) {
require := require.New(t)
assert := assert.New(t)
tpm, err := simulator.OpenSimulatedTPM()
require.NoError(err)
defer tpm.Close()
// create the attestation ket in RSA format
tpmAk, err := tpmclient.AttestationKeyRSA(tpm)
assert.NoError(err)
assert.NotNil(tpmAk)
// get the cached, already created key
getAk, err := getAttestationKey(tpm)
assert.NoError(err)
assert.NotNil(getAk)
// if everything worked fine, tpmAk and getAk are the same key
assert.Equal(tpmAk, getAk)
}
func TestGetInstanceInfo(t *testing.T) {
testCases := map[string]struct {
client stubMetadataAPI
wantErr bool
}{
"invalid region": {
client: stubMetadataAPI{
instanceDoc: imds.InstanceIdentityDocument{
Region: "invalid-region",
},
instanceErr: errors.New("failed"),
},
wantErr: true,
},
"valid region": {
client: stubMetadataAPI{
instanceDoc: imds.InstanceIdentityDocument{
Region: "us-east-2",
},
},
},
"invalid imageID": {
client: stubMetadataAPI{
instanceDoc: imds.InstanceIdentityDocument{
ImageID: "ami-fail",
},
instanceErr: errors.New("failed"),
},
wantErr: true,
},
"valid imageID": {
client: stubMetadataAPI{
instanceDoc: imds.InstanceIdentityDocument{
ImageID: "ami-09e7c7f5617a47830",
},
},
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
tpm, err := simulator.OpenSimulatedTPM()
assert.NoError(err)
defer tpm.Close()
instanceInfoFunc := getInstanceInfo(&tc.client)
assert.NotNil(instanceInfoFunc)
info, err := instanceInfoFunc(context.Background(), tpm, nil)
if tc.wantErr {
assert.Error(err)
assert.Nil(info)
} else {
assert.Nil(err)
assert.NotNil(info)
}
})
}
}
type stubMetadataAPI struct {
instanceDoc imds.InstanceIdentityDocument
instanceErr error
}
func (c *stubMetadataAPI) GetInstanceIdentityDocument(context.Context, *imds.GetInstanceIdentityDocumentInput, ...func(*imds.Options)) (*imds.GetInstanceIdentityDocumentOutput, error) {
output := &imds.InstanceIdentityDocument{}
return &imds.GetInstanceIdentityDocumentOutput{
InstanceIdentityDocument: *output,
ResultMetadata: middleware.Metadata{},
}, c.instanceErr
}

View File

@ -0,0 +1,29 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
/*
# NitroTPM Attestation.
Uses NitroTPM to enable a TPM based measured boot Constellation deployment.
The origin of the attesation statement can not be verified.
# Issuer
The TPM attestation is signed by the NitroTPM's RSA attestation key.
Additionally to the TPM attestation, we attach a node's [instance identity document] to the attestation document.
# Validator
Currently, the NitroTPM provides no endorsement certificate for its attestation key, nor does AWS offer an alternative way of verifying it.
For now we have to blindly trust the key.
Additionally to verifying the TPM attestation, we also check the instance identity document for consistency.
[instance identity document]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html
[NitroTPM]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nitrotpm.html
*/
package nitrotpm

View File

@ -4,7 +4,7 @@ Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package aws
package nitrotpm
import (
"context"
@ -16,9 +16,9 @@ import (
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/google/go-tpm-tools/proto/attest"
"github.com/google/go-tpm/tpm2"
)

View File

@ -0,0 +1,146 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package nitrotpm
import (
"context"
"encoding/json"
"errors"
"testing"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/aws/aws-sdk-go-v2/service/ec2/types"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/google/go-tpm-tools/proto/attest"
"github.com/stretchr/testify/assert"
)
func TestGeTrustedKey(t *testing.T) {
testCases := map[string]struct {
akPub []byte
info []byte
wantErr bool
}{
"nul byte docs": {
akPub: []byte{0x00, 0x00, 0x00, 0x00},
info: []byte{0x00, 0x00, 0x00, 0x00},
wantErr: true,
},
"nil": {
akPub: nil,
info: nil,
wantErr: true,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
out, err := getTrustedKey(
context.Background(),
vtpm.AttestationDocument{
Attestation: &attest.Attestation{
AkPub: tc.akPub,
},
InstanceInfo: tc.info,
},
nil,
)
if tc.wantErr {
assert.Error(err)
} else {
assert.NoError(err)
}
assert.Nil(out)
})
}
}
func TestTpmEnabled(t *testing.T) {
idDocNoTPM := imds.InstanceIdentityDocument{
ImageID: "ami-tpm-disabled",
}
userDataNoTPM, _ := json.Marshal(idDocNoTPM)
attDocNoTPM := vtpm.AttestationDocument{
InstanceInfo: userDataNoTPM,
}
idDocTPM := imds.InstanceIdentityDocument{
ImageID: "ami-tpm-enabled",
}
userDataTPM, _ := json.Marshal(idDocTPM)
attDocTPM := vtpm.AttestationDocument{
InstanceInfo: userDataTPM,
}
testCases := map[string]struct {
attDoc vtpm.AttestationDocument
awsAPI awsMetadataAPI
wantErr bool
}{
"ami with tpm": {
attDoc: attDocNoTPM,
awsAPI: &stubDescribeAPI{describeImagesTPMSupport: "v2.0"},
},
"ami without tpm": {
attDoc: attDocTPM,
awsAPI: &stubDescribeAPI{describeImagesTPMSupport: "v1.0"},
wantErr: true,
},
"ami undefined": {
attDoc: vtpm.AttestationDocument{},
awsAPI: &stubDescribeAPI{describeImagesErr: errors.New("failed")},
wantErr: true,
},
"invalid json instanceIdentityDocument": {
attDoc: vtpm.AttestationDocument{
UserData: []byte("{invalid}"),
},
awsAPI: &stubDescribeAPI{describeImagesErr: errors.New("failed")},
wantErr: true,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
v := Validator{
getDescribeClient: func(context.Context, string) (awsMetadataAPI, error) {
return tc.awsAPI, nil
},
}
err := v.tpmEnabled(tc.attDoc, nil)
if tc.wantErr {
assert.Error(err)
} else {
assert.Nil(err)
}
})
}
}
type stubDescribeAPI struct {
describeImagesErr error
describeImagesTPMSupport string
}
func (a *stubDescribeAPI) DescribeImages(
_ context.Context, _ *ec2.DescribeImagesInput, _ ...func(*ec2.Options),
) (*ec2.DescribeImagesOutput, error) {
output := &ec2.DescribeImagesOutput{
Images: []types.Image{
{TpmSupport: types.TpmSupportValues(a.describeImagesTPMSupport)},
},
}
return output, a.describeImagesErr
}

View File

@ -0,0 +1,51 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//bazel/go:go_test.bzl", "go_test")
go_library(
name = "snp",
srcs = [
"issuer.go",
"snp.go",
"validator.go",
],
importpath = "github.com/edgelesssys/constellation/v2/internal/attestation/aws/snp",
visibility = ["//:__subpackages__"],
deps = [
"//internal/attestation",
"//internal/attestation/variant",
"//internal/attestation/vtpm",
"//internal/config",
"@com_github_aws_aws_sdk_go_v2_config//:config",
"@com_github_aws_aws_sdk_go_v2_feature_ec2_imds//:imds",
"@com_github_aws_aws_sdk_go_v2_service_ec2//:ec2",
"@com_github_google_go_tpm//tpm2",
"@com_github_google_go_tpm_tools//client",
"@com_github_google_go_tpm_tools//proto/attest",
],
)
go_test(
name = "snp_test",
srcs = [
"issuer_test.go",
"validator_test.go",
],
embed = [":snp"],
# keep
gotags = select({
"//bazel/settings:tpm_simulator_enabled": [],
"//conditions:default": ["disable_tpm_simulator"],
}),
deps = [
"//internal/attestation/simulator",
"//internal/attestation/vtpm",
"@com_github_aws_aws_sdk_go_v2_feature_ec2_imds//:imds",
"@com_github_aws_aws_sdk_go_v2_service_ec2//:ec2",
"@com_github_aws_aws_sdk_go_v2_service_ec2//types",
"@com_github_aws_smithy_go//middleware",
"@com_github_google_go_tpm_tools//client",
"@com_github_google_go_tpm_tools//proto/attest",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
],
)

View File

@ -0,0 +1,66 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package snp
import (
"context"
"encoding/json"
"fmt"
"io"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/google/go-tpm-tools/client"
tpmclient "github.com/google/go-tpm-tools/client"
)
// Issuer for AWS SNP attestation.
type Issuer struct {
variant.AWSSEVSNP
*vtpm.Issuer
}
// NewIssuer creates a SEV-SNP based issuer for AWS.
func NewIssuer(log attestation.Logger) *Issuer {
return &Issuer{
Issuer: vtpm.NewIssuer(
vtpm.OpenVTPM,
getAttestationKey,
getInstanceInfo(imds.New(imds.Options{})),
log,
),
}
}
// getAttestationKey returns a new attestation key.
func getAttestationKey(tpm io.ReadWriter) (*tpmclient.Key, error) {
tpmAk, err := client.AttestationKeyRSA(tpm)
if err != nil {
return nil, fmt.Errorf("error creating RSA Endorsement key: %w", err)
}
return tpmAk, nil
}
// getInstanceInfo returns information about the current instance using the aws Metadata SDK.
// The returned bytes will be written into the attestation document.
func getInstanceInfo(client awsMetaData) func(context.Context, io.ReadWriteCloser, []byte) ([]byte, error) {
return func(ctx context.Context, _ io.ReadWriteCloser, _ []byte) ([]byte, error) {
ec2InstanceIdentityOutput, err := client.GetInstanceIdentityDocument(ctx, &imds.GetInstanceIdentityDocumentInput{})
if err != nil {
return nil, fmt.Errorf("fetching instance identity document: %w", err)
}
return json.Marshal(ec2InstanceIdentityOutput.InstanceIdentityDocument)
}
}
type awsMetaData interface {
GetInstanceIdentityDocument(context.Context, *imds.GetInstanceIdentityDocumentInput, ...func(*imds.Options)) (*imds.GetInstanceIdentityDocumentOutput, error)
}

View File

@ -4,7 +4,7 @@ Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package aws
package snp
import (
"context"

View File

@ -0,0 +1,52 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
/*
--------- WARNING! ---------
THIS PACKAGE DOES CURRENTLY NOT IMPLEMENT ANY SNP ATTESTATION.
It exists to implement required interfaces while implementing other parts of the AWS SNP attestation variant within Constellation.
----------------------------
# SNP
Attestation based on TPMs and AMD SEV-SNP.
The TPM is used to generate runtime measurements and sign them with an attestation key.
The TPM currently runs outside the confidential context. This is a limitation imposed by the AWS implementation.
# Issuer
Generates a TPM attestation using an attestation key saved inside the TPM.
Additionally loads the SEV-SNP attestation report and AMD VLEK certificate chain, and adds them to the attestation document.
The SNP report includes a measurement of the initial firmware inside the CVM, which can be precalculated independently for verification.
The report also includes the attestation key.
# Validator
Verifies the SNP report by verifying the VLEK certificate chain and the report's signature.
This estabilishes trust in the attestation key and the CVM's initial firmware.
However, since the TPM is outside the confidential context, it has to be trusted without verification.
Thus, the hypervisor is still included in the trusted computing base.
# Glossary
This section explains abbreviations used in SNP implementation.
- Attestation Key (AK)
- AMD Root Key (ARK)
- AMD Signing Key (ASK)
- Versioned Chip Endorsement Key (VCEK)
- Versioned Loaded Endorsement Key (VLEK)
For more information see [SNP WhitePaper]
[SNP WhitePaper]: https://www.amd.com/system/files/TechDocs/SEV-SNP-strengthening-vm-isolation-with-integrity-protection-and-more.pdf
*/
package snp

View File

@ -0,0 +1,101 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package snp
import (
"context"
"crypto"
"encoding/json"
"fmt"
awsConfig "github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/google/go-tpm-tools/proto/attest"
"github.com/google/go-tpm/tpm2"
)
// Validator for AWS TPM attestation.
type Validator struct {
variant.AWSSEVSNP
*vtpm.Validator
getDescribeClient func(context.Context, string) (awsMetadataAPI, error)
}
// NewValidator create a new Validator structure and returns it.
func NewValidator(cfg *config.AWSSEVSNP, log attestation.Logger) *Validator {
v := &Validator{}
v.Validator = vtpm.NewValidator(
cfg.Measurements,
getTrustedKey,
v.tpmEnabled,
log,
)
v.getDescribeClient = getEC2Client
return v
}
// getTrustedKeys return the public area of the provides attestation key.
// Normally, here the trust of this key should be verified, but currently AWS does not provide this feature.
func getTrustedKey(_ context.Context, attDoc vtpm.AttestationDocument, _ []byte) (crypto.PublicKey, error) {
// Copied from https://github.com/edgelesssys/constellation/blob/main/internal/attestation/qemu/validator.go
pubArea, err := tpm2.DecodePublic(attDoc.Attestation.AkPub)
if err != nil {
return nil, err
}
return pubArea.Key()
}
// tpmEnabled verifies if the virtual machine has the tpm2.0 feature enabled.
func (v *Validator) tpmEnabled(attestation vtpm.AttestationDocument, _ *attest.MachineState) error {
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/verify-nitrotpm-support-on-ami.html
// 1. Get the vm's ami (from IdentiTyDocument.imageId)
// 2. Check the value of key "TpmSupport": {"Value": "v2.0"}"
ctx := context.Background()
idDocument := imds.InstanceIdentityDocument{}
err := json.Unmarshal(attestation.InstanceInfo, &idDocument)
if err != nil {
return err
}
imageID := idDocument.ImageID
client, err := v.getDescribeClient(ctx, idDocument.Region)
if err != nil {
return err
}
// Currently, there seems to be a problem with retrieving image attributes directly.
// Alternatively, parse it from the general output.
imageOutput, err := client.DescribeImages(ctx, &ec2.DescribeImagesInput{ImageIds: []string{imageID}})
if err != nil {
return err
}
if imageOutput.Images[0].TpmSupport == "v2.0" {
return nil
}
return fmt.Errorf("iam image %s does not support TPM v2.0", imageID)
}
func getEC2Client(ctx context.Context, region string) (awsMetadataAPI, error) {
client, err := awsConfig.LoadDefaultConfig(ctx, awsConfig.WithRegion(region))
if err != nil {
return nil, err
}
return ec2.NewFromConfig(client), nil
}
type awsMetadataAPI interface {
DescribeImages(ctx context.Context, params *ec2.DescribeImagesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeImagesOutput, error)
}

View File

@ -4,7 +4,7 @@ Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package aws
package snp
import (
"context"

View File

@ -16,11 +16,11 @@ go_library(
deps = [
"//internal/attestation",
"//internal/attestation/idkeydigest",
"//internal/attestation/variant",
"//internal/attestation/vtpm",
"//internal/cloud/azure",
"//internal/config",
"//internal/crypto",
"//internal/variant",
"@com_github_edgelesssys_go_azguestattestation//maa",
"@com_github_google_go_tpm//tpm2",
"@com_github_google_go_tpm_tools//client",

View File

@ -13,8 +13,8 @@ import (
"io"
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/go-azguestattestation/maa"
tpmclient "github.com/google/go-tpm-tools/client"
)

View File

@ -22,10 +22,10 @@ import (
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/config"
internalCrypto "github.com/edgelesssys/constellation/v2/internal/crypto"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/google/go-tpm-tools/proto/attest"
"github.com/google/go-tpm/tpm2"
)

View File

@ -12,10 +12,10 @@ go_library(
visibility = ["//:__subpackages__"],
deps = [
"//internal/attestation",
"//internal/attestation/variant",
"//internal/attestation/vtpm",
"//internal/config",
"//internal/crypto",
"//internal/variant",
"@com_github_google_go_tpm//tpm2",
"@com_github_google_go_tpm_tools//client",
"@com_github_google_go_tpm_tools//proto/attest",

View File

@ -16,8 +16,8 @@ import (
"net/http"
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/variant"
tpmclient "github.com/google/go-tpm-tools/client"
"github.com/google/go-tpm/tpm2"
)

View File

@ -16,10 +16,10 @@ import (
"fmt"
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/config"
certutil "github.com/edgelesssys/constellation/v2/internal/crypto"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/google/go-tpm-tools/proto/attest"
"github.com/google/go-tpm/tpm2"
)

View File

@ -9,14 +9,15 @@ go_library(
deps = [
"//internal/atls",
"//internal/attestation",
"//internal/attestation/aws",
"//internal/attestation/aws/nitrotpm",
"//internal/attestation/aws/snp",
"//internal/attestation/azure/snp",
"//internal/attestation/azure/trustedlaunch",
"//internal/attestation/gcp",
"//internal/attestation/qemu",
"//internal/attestation/tdx",
"//internal/attestation/variant",
"//internal/config",
"//internal/variant",
],
)
@ -26,8 +27,8 @@ go_test(
embed = [":choose"],
deps = [
"//internal/attestation/measurements",
"//internal/attestation/variant",
"//internal/config",
"//internal/variant",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
],

View File

@ -11,25 +11,28 @@ import (
"github.com/edgelesssys/constellation/v2/internal/atls"
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/attestation/aws"
"github.com/edgelesssys/constellation/v2/internal/attestation/azure/snp"
"github.com/edgelesssys/constellation/v2/internal/attestation/aws/nitrotpm"
awssnp "github.com/edgelesssys/constellation/v2/internal/attestation/aws/snp"
azuresnp "github.com/edgelesssys/constellation/v2/internal/attestation/azure/snp"
"github.com/edgelesssys/constellation/v2/internal/attestation/azure/trustedlaunch"
"github.com/edgelesssys/constellation/v2/internal/attestation/gcp"
"github.com/edgelesssys/constellation/v2/internal/attestation/qemu"
"github.com/edgelesssys/constellation/v2/internal/attestation/tdx"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/variant"
)
// Issuer returns the issuer for the given variant.
func Issuer(attestationVariant variant.Variant, log attestation.Logger) (atls.Issuer, error) {
switch attestationVariant {
case variant.AWSSEVSNP{}:
return awssnp.NewIssuer(log), nil
case variant.AWSNitroTPM{}:
return aws.NewIssuer(log), nil
return nitrotpm.NewIssuer(log), nil
case variant.AzureTrustedLaunch{}:
return trustedlaunch.NewIssuer(log), nil
case variant.AzureSEVSNP{}:
return snp.NewIssuer(log), nil
return azuresnp.NewIssuer(log), nil
case variant.GCPSEVES{}:
return gcp.NewIssuer(log), nil
case variant.QEMUVTPM{}:
@ -46,12 +49,14 @@ func Issuer(attestationVariant variant.Variant, log attestation.Logger) (atls.Is
// Validator returns the validator for the given variant.
func Validator(cfg config.AttestationCfg, log attestation.Logger) (atls.Validator, error) {
switch cfg := cfg.(type) {
case *config.AWSSEVSNP:
return awssnp.NewValidator(cfg, log), nil
case *config.AWSNitroTPM:
return aws.NewValidator(cfg, log), nil
return nitrotpm.NewValidator(cfg, log), nil
case *config.AzureTrustedLaunch:
return trustedlaunch.NewValidator(cfg, log), nil
case *config.AzureSEVSNP:
return snp.NewValidator(cfg, log), nil
return azuresnp.NewValidator(cfg, log), nil
case *config.GCPSEVES:
return gcp.NewValidator(cfg, log), nil
case *config.QEMUVTPM:

View File

@ -11,8 +11,8 @@ import (
"testing"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -22,6 +22,9 @@ func TestIssuer(t *testing.T) {
variant variant.Variant
wantErr bool
}{
"aws-sev-snp": {
variant: variant.AWSSEVSNP{},
},
"aws-nitro-tpm": {
variant: variant.AWSNitroTPM{},
},

View File

@ -12,9 +12,9 @@ go_library(
visibility = ["//:__subpackages__"],
deps = [
"//internal/attestation",
"//internal/attestation/variant",
"//internal/attestation/vtpm",
"//internal/config",
"//internal/variant",
"@com_github_google_go_tpm_tools//client",
"@com_github_google_go_tpm_tools//proto/attest",
"@com_github_googleapis_gax_go_v2//:gax-go",

View File

@ -14,8 +14,8 @@ import (
"cloud.google.com/go/compute/metadata"
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/variant"
tpmclient "github.com/google/go-tpm-tools/client"
"github.com/google/go-tpm-tools/proto/attest"
)

View File

@ -17,9 +17,9 @@ import (
compute "cloud.google.com/go/compute/apiv1"
"cloud.google.com/go/compute/apiv1/computepb"
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/google/go-tpm-tools/proto/attest"
"github.com/googleapis/gax-go/v2"
"google.golang.org/api/option"

View File

@ -14,9 +14,9 @@ go_library(
visibility = ["//:__subpackages__"],
deps = [
"//internal/api/versionsapi",
"//internal/attestation/variant",
"//internal/cloud/cloudprovider",
"//internal/sigstore",
"//internal/variant",
"@com_github_google_go_tpm//tpmutil",
"@com_github_siderolabs_talos_pkg_machinery//config/encoder",
"@in_gopkg_yaml_v3//:yaml_v3",
@ -29,9 +29,9 @@ go_test(
embed = [":measurements"],
deps = [
"//internal/api/versionsapi",
"//internal/attestation/variant",
"//internal/cloud/cloudprovider",
"//internal/sigstore",
"//internal/variant",
"@com_github_siderolabs_talos_pkg_machinery//config/encoder",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",

View File

@ -9,9 +9,9 @@ go_library(
deps = [
"//internal/api/versionsapi",
"//internal/attestation/measurements",
"//internal/attestation/variant",
"//internal/cloud/cloudprovider",
"//internal/sigstore",
"//internal/variant",
"@org_golang_x_tools//go/ast/astutil",
],
)

View File

@ -25,9 +25,9 @@ import (
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/sigstore"
"github.com/edgelesssys/constellation/v2/internal/variant"
"golang.org/x/tools/go/ast/astutil"
)
@ -249,6 +249,8 @@ func attestationVariantFromGoIdentifier(identifier string) (variant.Variant, err
switch identifier {
case "Dummy":
return variant.Dummy{}, nil
case "AWSSEVSNP":
return variant.AWSSEVSNP{}, nil
case "AWSNitroTPM":
return variant.AWSNitroTPM{}, nil
case "GCPSEVES":

View File

@ -27,14 +27,14 @@ import (
"sort"
"strconv"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/sigstore"
"github.com/google/go-tpm/tpmutil"
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
"gopkg.in/yaml.v3"
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/sigstore"
"github.com/edgelesssys/constellation/v2/internal/variant"
)
//go:generate measurement-generator
@ -467,6 +467,9 @@ func DefaultsFor(provider cloudprovider.Provider, attestationVariant variant.Var
case provider == cloudprovider.AWS && attestationVariant == variant.AWSNitroTPM{}:
return aws_AWSNitroTPM.Copy()
case provider == cloudprovider.AWS && attestationVariant == variant.AWSSEVSNP{}:
return aws_AWSSEVSNP.Copy()
case provider == cloudprovider.Azure && attestationVariant == variant.AzureSEVSNP{}:
return azure_AzureSEVSNP.Copy()

View File

@ -17,6 +17,7 @@ package measurements
// revive:disable:var-naming
var (
aws_AWSNitroTPM = M{0: {Expected: []byte{0x73, 0x7f, 0x76, 0x7a, 0x12, 0xf5, 0x4e, 0x70, 0xee, 0xcb, 0xc8, 0x68, 0x40, 0x11, 0x32, 0x3a, 0xe2, 0xfe, 0x2d, 0xd9, 0xf9, 0x07, 0x85, 0x57, 0x79, 0x69, 0xd7, 0xa2, 0x01, 0x3e, 0x8c, 0x12}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0xe0, 0x6b, 0x6d, 0x04, 0x8c, 0x0f, 0x0f, 0x39, 0x66, 0x0f, 0x0b, 0xd5, 0xff, 0xb9, 0xc6, 0xf1, 0x44, 0xf2, 0x05, 0x0b, 0x9d, 0x57, 0xe9, 0xed, 0xb9, 0x63, 0x45, 0x60, 0x20, 0x73, 0x7c, 0x2d}, ValidationOpt: Enforce}, 6: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 7: {Expected: []byte{0x12, 0x0e, 0x49, 0x8d, 0xb2, 0xa2, 0x24, 0xbd, 0x51, 0x2b, 0x6e, 0xfc, 0x9b, 0x02, 0x34, 0xf8, 0x43, 0xe1, 0x0b, 0xf0, 0x61, 0xeb, 0x7a, 0x76, 0xec, 0xca, 0x55, 0x09, 0xa2, 0x23, 0x89, 0x01}, ValidationOpt: WarnOnly}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x9e, 0x31, 0x6d, 0x07, 0x03, 0xde, 0xc5, 0x56, 0x30, 0x67, 0x29, 0x42, 0x65, 0x15, 0x07, 0x9e, 0xd9, 0xba, 0x6f, 0x21, 0x8d, 0x65, 0x92, 0xfb, 0xa9, 0x69, 0xd0, 0xca, 0x6f, 0x91, 0x9a, 0x82}, ValidationOpt: Enforce}, 11: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 12: {Expected: []byte{0xda, 0xc1, 0x49, 0x8b, 0x42, 0xd3, 0x77, 0x49, 0x69, 0xba, 0xdd, 0xa8, 0xa0, 0x1a, 0xe4, 0x94, 0xbc, 0x5c, 0x3f, 0x9d, 0x08, 0x09, 0x64, 0xc1, 0x60, 0xff, 0xac, 0x45, 0x17, 0xe6, 0x5e, 0xba}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0xd7, 0xc4, 0xcc, 0x7f, 0xf7, 0x93, 0x30, 0x22, 0xf0, 0x13, 0xe0, 0x3b, 0xde, 0xe8, 0x75, 0xb9, 0x17, 0x20, 0xb5, 0xb8, 0x6c, 0xf1, 0x75, 0x3c, 0xad, 0x83, 0x0f, 0x95, 0xe7, 0x91, 0x92, 0x6f}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
aws_AWSSEVSNP = M{0: {Expected: []byte{0x73, 0x7f, 0x76, 0x7a, 0x12, 0xf5, 0x4e, 0x70, 0xee, 0xcb, 0xc8, 0x68, 0x40, 0x11, 0x32, 0x3a, 0xe2, 0xfe, 0x2d, 0xd9, 0xf9, 0x07, 0x85, 0x57, 0x79, 0x69, 0xd7, 0xa2, 0x01, 0x3e, 0x8c, 0x12}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0xf4, 0xe9, 0x30, 0x3d, 0xf3, 0x34, 0x41, 0x55, 0xdd, 0x14, 0x2d, 0x4d, 0xd8, 0xef, 0xfa, 0x20, 0xf4, 0x21, 0x39, 0x09, 0x9c, 0xc5, 0x2b, 0xca, 0x25, 0xd2, 0x86, 0xe9, 0x26, 0xbd, 0x61, 0x51}, ValidationOpt: Enforce}, 6: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 7: {Expected: []byte{0x12, 0x0e, 0x49, 0x8d, 0xb2, 0xa2, 0x24, 0xbd, 0x51, 0x2b, 0x6e, 0xfc, 0x9b, 0x02, 0x34, 0xf8, 0x43, 0xe1, 0x0b, 0xf0, 0x61, 0xeb, 0x7a, 0x76, 0xec, 0xca, 0x55, 0x09, 0xa2, 0x23, 0x89, 0x01}, ValidationOpt: WarnOnly}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x9e, 0x31, 0x6d, 0x07, 0x03, 0xde, 0xc5, 0x56, 0x30, 0x67, 0x29, 0x42, 0x65, 0x15, 0x07, 0x9e, 0xd9, 0xba, 0x6f, 0x21, 0x8d, 0x65, 0x92, 0xfb, 0xa9, 0x69, 0xd0, 0xca, 0x6f, 0x91, 0x9a, 0x82}, ValidationOpt: Enforce}, 11: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 12: {Expected: []byte{0xbb, 0xa3, 0x3c, 0xc6, 0xe8, 0xa9, 0xfd, 0xef, 0xb4, 0x56, 0x8a, 0x04, 0x7d, 0xad, 0x27, 0x96, 0xcc, 0x81, 0x6d, 0x1a, 0x50, 0x57, 0xc5, 0xe7, 0x31, 0xe4, 0x5d, 0xa2, 0x8a, 0x56, 0xf0, 0xfa}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0xd7, 0xc4, 0xcc, 0x7f, 0xf7, 0x93, 0x30, 0x22, 0xf0, 0x13, 0xe0, 0x3b, 0xde, 0xe8, 0x75, 0xb9, 0x17, 0x20, 0xb5, 0xb8, 0x6c, 0xf1, 0x75, 0x3c, 0xad, 0x83, 0x0f, 0x95, 0xe7, 0x91, 0x92, 0x6f}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
azure_AzureSEVSNP = M{1: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0x25, 0xf8, 0x89, 0x54, 0x69, 0xac, 0xbf, 0x28, 0x64, 0x48, 0xe4, 0x80, 0xdc, 0x33, 0x74, 0x80, 0x47, 0xd7, 0x56, 0x75, 0xaa, 0x83, 0x8b, 0xfd, 0x85, 0x58, 0xd4, 0xd7, 0x0c, 0x69, 0x13, 0xb5}, ValidationOpt: Enforce}, 7: {Expected: []byte{0x34, 0x65, 0x47, 0xa8, 0xce, 0x59, 0x57, 0xaf, 0x27, 0xe5, 0x52, 0x42, 0x7d, 0x6b, 0x9e, 0x6d, 0x9c, 0xb5, 0x02, 0xf0, 0x15, 0x6e, 0x91, 0x55, 0x38, 0x04, 0x51, 0xee, 0xa1, 0xb3, 0xf0, 0xed}, ValidationOpt: WarnOnly}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x99, 0x35, 0x5b, 0xbe, 0xb0, 0xa6, 0xff, 0x67, 0x6c, 0x51, 0x0a, 0xfb, 0xab, 0xe0, 0x5f, 0x84, 0x26, 0x17, 0x7b, 0xc7, 0xd6, 0x5c, 0xb7, 0xc1, 0xc3, 0xda, 0x8b, 0x00, 0xa2, 0x29, 0x57, 0x54}, ValidationOpt: Enforce}, 11: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x0f, 0xdb, 0x9d, 0xb0, 0x1a, 0x73, 0x9d, 0xa2, 0x3e, 0xd9, 0xbe, 0x68, 0xff, 0x86, 0xbd, 0x8c, 0xfc, 0x48, 0x54, 0x32, 0x13, 0x8c, 0xf3, 0xba, 0x77, 0x10, 0xff, 0x40, 0x35, 0xea, 0x10, 0x74}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0xd7, 0xc4, 0xcc, 0x7f, 0xf7, 0x93, 0x30, 0x22, 0xf0, 0x13, 0xe0, 0x3b, 0xde, 0xe8, 0x75, 0xb9, 0x17, 0x20, 0xb5, 0xb8, 0x6c, 0xf1, 0x75, 0x3c, 0xad, 0x83, 0x0f, 0x95, 0xe7, 0x91, 0x92, 0x6f}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
azure_AzureTrustedLaunch M
gcp_GCPSEVES = M{1: {Expected: []byte{0x74, 0x5f, 0x2f, 0xb4, 0x23, 0x5e, 0x46, 0x47, 0xaa, 0x0a, 0xd5, 0xac, 0xe7, 0x81, 0xcd, 0x92, 0x9e, 0xb6, 0x8c, 0x28, 0x87, 0x0e, 0x7d, 0xd5, 0xd1, 0xa1, 0x53, 0x58, 0x54, 0x32, 0x5e, 0x56}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0xf8, 0xd7, 0x95, 0xe3, 0x27, 0x4d, 0x8d, 0x32, 0x78, 0xe2, 0xcc, 0xb5, 0x29, 0xfd, 0x7b, 0xce, 0x70, 0xef, 0x0e, 0x67, 0x99, 0xe4, 0xaa, 0x21, 0x7e, 0xac, 0x17, 0x42, 0xdf, 0xfc, 0x1d, 0xce}, ValidationOpt: Enforce}, 6: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 7: {Expected: []byte{0xb1, 0xe9, 0xb3, 0x05, 0x32, 0x5c, 0x51, 0xb9, 0x3d, 0xa5, 0x8c, 0xbf, 0x7f, 0x92, 0x51, 0x2d, 0x8e, 0xeb, 0xfa, 0x01, 0x14, 0x3e, 0x4d, 0x88, 0x44, 0xe4, 0x0e, 0x06, 0x2e, 0x9b, 0x6c, 0xd5}, ValidationOpt: WarnOnly}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x99, 0x35, 0x5b, 0xbe, 0xb0, 0xa6, 0xff, 0x67, 0x6c, 0x51, 0x0a, 0xfb, 0xab, 0xe0, 0x5f, 0x84, 0x26, 0x17, 0x7b, 0xc7, 0xd6, 0x5c, 0xb7, 0xc1, 0xc3, 0xda, 0x8b, 0x00, 0xa2, 0x29, 0x57, 0x54}, ValidationOpt: Enforce}, 11: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 12: {Expected: []byte{0xab, 0x50, 0x0c, 0x4b, 0xc9, 0x4b, 0xb3, 0xa8, 0x7c, 0x47, 0x92, 0x23, 0x58, 0x1f, 0xcd, 0x03, 0xae, 0xb1, 0xc6, 0x87, 0xa4, 0x6a, 0x6b, 0x98, 0xaf, 0xce, 0x1c, 0x52, 0x43, 0x87, 0xd8, 0xed}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0xd7, 0xc4, 0xcc, 0x7f, 0xf7, 0x93, 0x30, 0x22, 0xf0, 0x13, 0xe0, 0x3b, 0xde, 0xe8, 0x75, 0xb9, 0x17, 0x20, 0xb5, 0xb8, 0x6c, 0xf1, 0x75, 0x3c, 0xad, 0x83, 0x0f, 0x95, 0xe7, 0x91, 0x92, 0x6f}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}

View File

@ -19,6 +19,17 @@ var (
13: WithAllBytes(0x00, Enforce, PCRMeasurementLength),
uint32(PCRIndexClusterID): WithAllBytes(0x00, Enforce, PCRMeasurementLength),
}
aws_AWSSEVSNP = M{
4: PlaceHolderMeasurement(PCRMeasurementLength),
8: WithAllBytes(0x00, Enforce, PCRMeasurementLength),
9: PlaceHolderMeasurement(PCRMeasurementLength),
11: WithAllBytes(0x00, Enforce, PCRMeasurementLength),
12: PlaceHolderMeasurement(PCRMeasurementLength),
13: WithAllBytes(0x00, Enforce, PCRMeasurementLength),
uint32(PCRIndexClusterID): WithAllBytes(0x00, Enforce, PCRMeasurementLength),
}
azure_AzureSEVSNP = M{
4: PlaceHolderMeasurement(PCRMeasurementLength),
8: WithAllBytes(0x00, Enforce, PCRMeasurementLength),

View File

@ -21,9 +21,9 @@ import (
"gopkg.in/yaml.v3"
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/sigstore"
"github.com/edgelesssys/constellation/v2/internal/variant"
)
func TestMarshal(t *testing.T) {

View File

@ -11,9 +11,9 @@ go_library(
visibility = ["//:__subpackages__"],
deps = [
"//internal/attestation",
"//internal/attestation/variant",
"//internal/attestation/vtpm",
"//internal/config",
"//internal/variant",
"@com_github_google_go_tpm//tpm2",
"@com_github_google_go_tpm_tools//client",
"@com_github_google_go_tpm_tools//proto/attest",

View File

@ -11,8 +11,8 @@ import (
"io"
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/variant"
tpmclient "github.com/google/go-tpm-tools/client"
)

View File

@ -11,9 +11,9 @@ import (
"crypto"
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/google/go-tpm-tools/proto/attest"
"github.com/google/go-tpm/tpm2"
)

View File

@ -12,8 +12,8 @@ go_library(
deps = [
"//internal/attestation",
"//internal/attestation/measurements",
"//internal/attestation/variant",
"//internal/config",
"//internal/variant",
"@com_github_edgelesssys_go_tdx_qpl//tdx",
"@com_github_edgelesssys_go_tdx_qpl//verification",
"@com_github_edgelesssys_go_tdx_qpl//verification/types",

View File

@ -12,7 +12,7 @@ import (
"fmt"
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/go-tdx-qpl/tdx"
)

View File

@ -14,8 +14,8 @@ import (
"github.com/edgelesssys/constellation/v2/internal/attestation"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/go-tdx-qpl/verification"
"github.com/edgelesssys/go-tdx-qpl/verification/types"
)

View File

@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "variant",
srcs = ["variant.go"],
importpath = "github.com/edgelesssys/constellation/v2/internal/variant",
importpath = "github.com/edgelesssys/constellation/v2/internal/attestation/variant",
visibility = ["//:__subpackages__"],
deps = ["//internal/cloud/cloudprovider"],
)

View File

@ -42,6 +42,7 @@ import (
const (
dummy = "dummy"
awsNitroTPM = "aws-nitro-tpm"
awsSEVSNP = "aws-sev-snp"
gcpSEVES = "gcp-sev-es"
azureSEVSNP = "azure-sev-snp"
azureTrustedLaunch = "azure-trustedlaunch"
@ -50,7 +51,7 @@ const (
)
var providerAttestationMapping = map[cloudprovider.Provider][]Variant{
cloudprovider.AWS: {AWSNitroTPM{}},
cloudprovider.AWS: {AWSSEVSNP{}, AWSNitroTPM{}},
cloudprovider.Azure: {AzureSEVSNP{}, AzureTrustedLaunch{}},
cloudprovider.GCP: {GCPSEVES{}},
cloudprovider.QEMU: {QEMUVTPM{}},
@ -102,6 +103,8 @@ func FromString(oid string) (Variant, error) {
switch oid {
case dummy:
return Dummy{}, nil
case awsSEVSNP:
return AWSSEVSNP{}, nil
case awsNitroTPM:
return AWSNitroTPM{}, nil
case gcpSEVES:
@ -167,6 +170,24 @@ func (AWSNitroTPM) Equal(other Getter) bool {
return other.OID().Equal(AWSNitroTPM{}.OID())
}
// AWSSEVSNP holds the AWS nitro TPM OID.
type AWSSEVSNP struct{}
// OID returns the struct's object identifier.
func (AWSSEVSNP) OID() asn1.ObjectIdentifier {
return asn1.ObjectIdentifier{1, 3, 9900, 2, 2}
}
// String returns the string representation of the OID.
func (AWSSEVSNP) String() string {
return awsSEVSNP
}
// Equal returns true if the other variant is also AWSSEVSNP.
func (AWSSEVSNP) Equal(other Getter) bool {
return other.OID().Equal(AWSSEVSNP{}.OID())
}
// GCPSEVES holds the GCP SEV-ES OID.
type GCPSEVES struct{}

View File

@ -21,13 +21,13 @@ go_library(
"//internal/api/versionsapi",
"//internal/attestation/idkeydigest",
"//internal/attestation/measurements",
"//internal/attestation/variant",
"//internal/cloud/cloudprovider",
"//internal/compatibility",
"//internal/config/imageversion",
"//internal/config/instancetypes",
"//internal/constants",
"//internal/file",
"//internal/variant",
"//internal/versions",
"@com_github_go_playground_locales//en",
"@com_github_go_playground_universal_translator//:universal-translator",
@ -51,12 +51,12 @@ go_test(
deps = [
"//internal/api/attestationconfigapi",
"//internal/attestation/measurements",
"//internal/attestation/variant",
"//internal/cloud/cloudprovider",
"//internal/config/instancetypes",
"//internal/constants",
"//internal/file",
"//internal/semver",
"//internal/variant",
"//internal/versions",
"@com_github_go_playground_locales//en",
"@com_github_go_playground_universal_translator//:universal-translator",

View File

@ -13,7 +13,7 @@ import (
"fmt"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
)
// AttestationCfg is the common interface for passing attestation configs.
@ -33,6 +33,8 @@ func UnmarshalAttestationConfig(data []byte, attestVariant variant.Variant) (Att
switch attestVariant {
case variant.AWSNitroTPM{}:
return unmarshalTypedConfig[*AWSNitroTPM](data)
case variant.AWSSEVSNP{}:
return unmarshalTypedConfig[*AWSSEVSNP](data)
case variant.AzureSEVSNP{}:
return unmarshalTypedConfig[*AzureSEVSNP](data)
case variant.AzureTrustedLaunch{}:

View File

@ -12,8 +12,8 @@ import (
"testing"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
@ -26,6 +26,9 @@ func TestUnmarshalAttestationConfig(t *testing.T) {
testCases := map[string]struct {
cfg AttestationCfg
}{
"AWSSEVSNP": {
cfg: &AWSSEVSNP{Measurements: measurements.DefaultsFor(cloudprovider.AWS, variant.AWSSEVSNP{}), LaunchMeasurement: measurements.PlaceHolderMeasurement(48)},
},
"AWSNitroTPM": {
cfg: &AWSNitroTPM{Measurements: measurements.DefaultsFor(cloudprovider.AWS, variant.AWSNitroTPM{})},
},

View File

@ -37,12 +37,12 @@ import (
"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"
"github.com/edgelesssys/constellation/v2/internal/compatibility"
"github.com/edgelesssys/constellation/v2/internal/config/imageversion"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions"
)
@ -279,6 +279,9 @@ type QEMUConfig struct {
// Fields should remain pointer-types so custom specific configs can nil them
// if not required.
type AttestationConfig struct {
// description: |
// AWS SEV-SNP attestation. WARNING: NOT PRODUCTION READY, TESTING ONLY, NO MEANINGFUL ATTESTATION.
AWSSEVSNP *AWSSEVSNP `yaml:"awsSEVSNP,omitempty" validate:"omitempty,dive"`
// description: |
// AWS Nitro TPM attestation.
AWSNitroTPM *AWSNitroTPM `yaml:"awsNitroTPM,omitempty" validate:"omitempty,dive"`
@ -359,6 +362,7 @@ func Default() *Config {
// AWS uses aws-nitro-tpm as attestation variant
// AWS will have aws-sev-snp as attestation variant
Attestation: AttestationConfig{
AWSSEVSNP: &AWSSEVSNP{Measurements: measurements.DefaultsFor(cloudprovider.AWS, variant.AWSSEVSNP{}), LaunchMeasurement: measurements.WithAllBytes(0x00, measurements.Enforce, measurements.PCRMeasurementLength)},
AWSNitroTPM: &AWSNitroTPM{Measurements: measurements.DefaultsFor(cloudprovider.AWS, variant.AWSNitroTPM{})},
AzureSEVSNP: DefaultForAzureSEVSNP(),
AzureTrustedLaunch: &AzureTrustedLaunch{Measurements: measurements.DefaultsFor(cloudprovider.Azure, variant.AzureTrustedLaunch{})},
@ -447,6 +451,9 @@ func (c *Config) HasProvider(provider cloudprovider.Provider) bool {
// UpdateMeasurements overwrites measurements in config with the provided ones.
func (c *Config) UpdateMeasurements(newMeasurements measurements.M) {
if c.Attestation.AWSSEVSNP != nil {
c.Attestation.AWSSEVSNP.Measurements.CopyFrom(newMeasurements)
}
if c.Attestation.AWSNitroTPM != nil {
c.Attestation.AWSNitroTPM.Measurements.CopyFrom(newMeasurements)
}
@ -500,6 +507,8 @@ func (c *Config) SetAttestation(attestation variant.Variant) {
switch attestation.(type) {
case variant.AzureSEVSNP:
c.Attestation = AttestationConfig{AzureSEVSNP: currentAttetationConfigs.AzureSEVSNP}
case variant.AWSSEVSNP:
c.Attestation = AttestationConfig{AWSSEVSNP: currentAttetationConfigs.AWSSEVSNP}
case variant.AWSNitroTPM:
c.Attestation = AttestationConfig{AWSNitroTPM: currentAttetationConfigs.AWSNitroTPM}
case variant.AzureTrustedLaunch:
@ -546,6 +555,9 @@ func (c *Config) GetProvider() cloudprovider.Provider {
// GetAttestationConfig returns the configured attestation config.
func (c *Config) GetAttestationConfig() AttestationCfg {
if c.Attestation.AWSSEVSNP != nil {
return c.Attestation.AWSSEVSNP
}
if c.Attestation.AWSNitroTPM != nil {
return c.Attestation.AWSNitroTPM
}
@ -708,6 +720,7 @@ func (c *Config) Validate(force bool) error {
return err
}
validate.RegisterStructValidation(validateMeasurement, measurements.Measurement{})
validate.RegisterStructValidation(validateAttestation, AttestationConfig{})
err := validate.Struct(c)
@ -751,6 +764,47 @@ func (c *Config) WithOpenStackProviderDefaults(openStackProvider string) *Config
return c
}
// AWSSEVSNP is the configuration for AWS SEV-SNP attestation.
type AWSSEVSNP struct {
// description: |
// Expected TPM measurements.
Measurements measurements.M `json:"measurements" yaml:"measurements" validate:"required,no_placeholders"`
// description: |
// Expected launch measurement in SNP report.
LaunchMeasurement measurements.Measurement `json:"launchMeasurement" yaml:"launchMeasurement" validate:"required"`
}
// GetVariant returns aws-sev-snp as the variant.
func (AWSSEVSNP) GetVariant() variant.Variant {
return variant.AWSSEVSNP{}
}
// GetMeasurements returns the measurements used for attestation.
func (c AWSSEVSNP) GetMeasurements() measurements.M {
return c.Measurements
}
// SetMeasurements updates a config's measurements using the given measurements.
func (c *AWSSEVSNP) SetMeasurements(m measurements.M) {
c.Measurements = m
}
// EqualTo returns true if the config is equal to the given config.
func (c AWSSEVSNP) EqualTo(other AttestationCfg) (bool, error) {
otherCfg, ok := other.(*AWSSEVSNP)
if !ok {
return false, fmt.Errorf("cannot compare %T with %T", c, other)
}
if !bytes.Equal(c.LaunchMeasurement.Expected, otherCfg.LaunchMeasurement.Expected) {
return false, nil
}
if c.LaunchMeasurement.ValidationOpt != otherCfg.LaunchMeasurement.ValidationOpt {
return false, nil
}
return c.Measurements.EqualTo(otherCfg.Measurements), nil
}
// AWSNitroTPM is the configuration for AWS Nitro TPM attestation.
type AWSNitroTPM struct {
// description: |

View File

@ -19,6 +19,7 @@ var (
OpenStackConfigDoc encoder.Doc
QEMUConfigDoc encoder.Doc
AttestationConfigDoc encoder.Doc
AWSSEVSNPDoc encoder.Doc
AWSNitroTPMDoc encoder.Doc
SNPFirmwareSignerConfigDoc encoder.Doc
GCPSEVESDoc encoder.Doc
@ -429,37 +430,63 @@ func init() {
FieldName: "attestation",
},
}
AttestationConfigDoc.Fields = make([]encoder.Doc, 6)
AttestationConfigDoc.Fields[0].Name = "awsNitroTPM"
AttestationConfigDoc.Fields[0].Type = "AWSNitroTPM"
AttestationConfigDoc.Fields = make([]encoder.Doc, 7)
AttestationConfigDoc.Fields[0].Name = "awsSEVSNP"
AttestationConfigDoc.Fields[0].Type = "AWSSEVSNP"
AttestationConfigDoc.Fields[0].Note = ""
AttestationConfigDoc.Fields[0].Description = "AWS Nitro TPM attestation."
AttestationConfigDoc.Fields[0].Comments[encoder.LineComment] = "AWS Nitro TPM attestation."
AttestationConfigDoc.Fields[1].Name = "azureSEVSNP"
AttestationConfigDoc.Fields[1].Type = "AzureSEVSNP"
AttestationConfigDoc.Fields[0].Description = "AWS SEV-SNP attestation. WARNING: NOT PRODUCTION READY, TESTING ONLY, NO MEANINGFUL ATTESTATION."
AttestationConfigDoc.Fields[0].Comments[encoder.LineComment] = "AWS SEV-SNP attestation. WARNING: NOT PRODUCTION READY, TESTING ONLY, NO MEANINGFUL ATTESTATION."
AttestationConfigDoc.Fields[1].Name = "awsNitroTPM"
AttestationConfigDoc.Fields[1].Type = "AWSNitroTPM"
AttestationConfigDoc.Fields[1].Note = ""
AttestationConfigDoc.Fields[1].Description = "Azure SEV-SNP attestation.\nFor details see: https://docs.edgeless.systems/constellation/architecture/attestation#cvm-verification"
AttestationConfigDoc.Fields[1].Comments[encoder.LineComment] = "Azure SEV-SNP attestation.\nFor details see: https://docs.edgeless.systems/constellation/architecture/attestation#cvm-verification"
AttestationConfigDoc.Fields[2].Name = "azureTrustedLaunch"
AttestationConfigDoc.Fields[2].Type = "AzureTrustedLaunch"
AttestationConfigDoc.Fields[1].Description = "AWS Nitro TPM attestation."
AttestationConfigDoc.Fields[1].Comments[encoder.LineComment] = "AWS Nitro TPM attestation."
AttestationConfigDoc.Fields[2].Name = "azureSEVSNP"
AttestationConfigDoc.Fields[2].Type = "AzureSEVSNP"
AttestationConfigDoc.Fields[2].Note = ""
AttestationConfigDoc.Fields[2].Description = "Azure TPM attestation (Trusted Launch)."
AttestationConfigDoc.Fields[2].Comments[encoder.LineComment] = "Azure TPM attestation (Trusted Launch)."
AttestationConfigDoc.Fields[3].Name = "gcpSEVES"
AttestationConfigDoc.Fields[3].Type = "GCPSEVES"
AttestationConfigDoc.Fields[2].Description = "Azure SEV-SNP attestation.\nFor details see: https://docs.edgeless.systems/constellation/architecture/attestation#cvm-verification"
AttestationConfigDoc.Fields[2].Comments[encoder.LineComment] = "Azure SEV-SNP attestation.\nFor details see: https://docs.edgeless.systems/constellation/architecture/attestation#cvm-verification"
AttestationConfigDoc.Fields[3].Name = "azureTrustedLaunch"
AttestationConfigDoc.Fields[3].Type = "AzureTrustedLaunch"
AttestationConfigDoc.Fields[3].Note = ""
AttestationConfigDoc.Fields[3].Description = "GCP SEV-ES attestation."
AttestationConfigDoc.Fields[3].Comments[encoder.LineComment] = "GCP SEV-ES attestation."
AttestationConfigDoc.Fields[4].Name = "qemuTDX"
AttestationConfigDoc.Fields[4].Type = "QEMUTDX"
AttestationConfigDoc.Fields[3].Description = "Azure TPM attestation (Trusted Launch)."
AttestationConfigDoc.Fields[3].Comments[encoder.LineComment] = "Azure TPM attestation (Trusted Launch)."
AttestationConfigDoc.Fields[4].Name = "gcpSEVES"
AttestationConfigDoc.Fields[4].Type = "GCPSEVES"
AttestationConfigDoc.Fields[4].Note = ""
AttestationConfigDoc.Fields[4].Description = "QEMU tdx attestation."
AttestationConfigDoc.Fields[4].Comments[encoder.LineComment] = "QEMU tdx attestation."
AttestationConfigDoc.Fields[5].Name = "qemuVTPM"
AttestationConfigDoc.Fields[5].Type = "QEMUVTPM"
AttestationConfigDoc.Fields[4].Description = "GCP SEV-ES attestation."
AttestationConfigDoc.Fields[4].Comments[encoder.LineComment] = "GCP SEV-ES attestation."
AttestationConfigDoc.Fields[5].Name = "qemuTDX"
AttestationConfigDoc.Fields[5].Type = "QEMUTDX"
AttestationConfigDoc.Fields[5].Note = ""
AttestationConfigDoc.Fields[5].Description = "QEMU vTPM attestation."
AttestationConfigDoc.Fields[5].Comments[encoder.LineComment] = "QEMU vTPM attestation."
AttestationConfigDoc.Fields[5].Description = "QEMU tdx attestation."
AttestationConfigDoc.Fields[5].Comments[encoder.LineComment] = "QEMU tdx attestation."
AttestationConfigDoc.Fields[6].Name = "qemuVTPM"
AttestationConfigDoc.Fields[6].Type = "QEMUVTPM"
AttestationConfigDoc.Fields[6].Note = ""
AttestationConfigDoc.Fields[6].Description = "QEMU vTPM attestation."
AttestationConfigDoc.Fields[6].Comments[encoder.LineComment] = "QEMU vTPM attestation."
AWSSEVSNPDoc.Type = "AWSSEVSNP"
AWSSEVSNPDoc.Comments[encoder.LineComment] = "AWSSEVSNP is the configuration for AWS SEV-SNP attestation."
AWSSEVSNPDoc.Description = "AWSSEVSNP is the configuration for AWS SEV-SNP attestation."
AWSSEVSNPDoc.AppearsIn = []encoder.Appearance{
{
TypeName: "AttestationConfig",
FieldName: "awsSEVSNP",
},
}
AWSSEVSNPDoc.Fields = make([]encoder.Doc, 2)
AWSSEVSNPDoc.Fields[0].Name = "measurements"
AWSSEVSNPDoc.Fields[0].Type = "M"
AWSSEVSNPDoc.Fields[0].Note = ""
AWSSEVSNPDoc.Fields[0].Description = "Expected TPM measurements."
AWSSEVSNPDoc.Fields[0].Comments[encoder.LineComment] = "Expected TPM measurements."
AWSSEVSNPDoc.Fields[1].Name = "launchMeasurement"
AWSSEVSNPDoc.Fields[1].Type = "Measurement"
AWSSEVSNPDoc.Fields[1].Note = ""
AWSSEVSNPDoc.Fields[1].Description = "Expected launch measurement in SNP report."
AWSSEVSNPDoc.Fields[1].Comments[encoder.LineComment] = "Expected launch measurement in SNP report."
AWSNitroTPMDoc.Type = "AWSNitroTPM"
AWSNitroTPMDoc.Comments[encoder.LineComment] = "AWSNitroTPM is the configuration for AWS Nitro TPM attestation."
@ -646,6 +673,10 @@ func (_ AttestationConfig) Doc() *encoder.Doc {
return &AttestationConfigDoc
}
func (_ AWSSEVSNP) Doc() *encoder.Doc {
return &AWSSEVSNPDoc
}
func (_ AWSNitroTPM) Doc() *encoder.Doc {
return &AWSNitroTPMDoc
}
@ -688,6 +719,7 @@ func GetConfigurationDoc() *encoder.FileDoc {
&OpenStackConfigDoc,
&QEMUConfigDoc,
&AttestationConfigDoc,
&AWSSEVSNPDoc,
&AWSNitroTPMDoc,
&SNPFirmwareSignerConfigDoc,
&GCPSEVESDoc,

View File

@ -276,7 +276,7 @@ func TestNewWithDefaultOptions(t *testing.T) {
}
func TestValidate(t *testing.T) {
const defaultErrCount = 32 // expect this number of error messages by default because user-specific values are not set and multiple providers are defined by default
const defaultErrCount = 33 // expect this number of error messages by default because user-specific values are not set and multiple providers are defined by default
const azErrCount = 7
const gcpErrCount = 6
@ -499,11 +499,11 @@ func TestConfig_UpdateMeasurements(t *testing.T) {
{ // AWS
conf := Default()
conf.RemoveProviderAndAttestationExcept(cloudprovider.AWS)
for k := range conf.Attestation.AWSNitroTPM.Measurements {
delete(conf.Attestation.AWSNitroTPM.Measurements, k)
for k := range conf.Attestation.AWSSEVSNP.Measurements {
delete(conf.Attestation.AWSSEVSNP.Measurements, k)
}
conf.UpdateMeasurements(newMeasurements)
assert.Equal(newMeasurements, conf.Attestation.AWSNitroTPM.Measurements)
assert.Equal(newMeasurements, conf.Attestation.AWSSEVSNP.Measurements)
}
{ // Azure
conf := Default()

View File

@ -8,8 +8,8 @@ go_library(
deps = [
"//internal/attestation/idkeydigest",
"//internal/attestation/measurements",
"//internal/attestation/variant",
"//internal/config",
"//internal/file",
"//internal/variant",
],
)

View File

@ -15,9 +15,9 @@ import (
"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/config"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/variant"
)
const (

View File

@ -21,11 +21,11 @@ import (
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/compatibility"
"github.com/edgelesssys/constellation/v2/internal/config/instancetypes"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions"
)
@ -144,6 +144,9 @@ func validateAttestation(sl validator.StructLevel) {
attestation := sl.Current().Interface().(AttestationConfig)
attestationCount := 0
if attestation.AWSSEVSNP != nil {
attestationCount++
}
if attestation.AWSNitroTPM != nil {
attestationCount++
}
@ -174,7 +177,7 @@ func translateNoAttestationError(ut ut.Translator, fe validator.FieldError) stri
}
func registerNoAttestationError(ut ut.Translator) error {
return ut.Add("no_attestation", "{0}: No attestation has been defined (requires either AWSNitroTPM, AzureSEVSNP, AzureTrustedLaunch, GCPSEVES, or QEMUVTPM)", true)
return ut.Add("no_attestation", "{0}: No attestation has been defined (requires either awsSEVSNP, awsNitroTPM, azureSEVSNP, azureTrustedLaunch, gcpSEVES, or qemuVTPM)", true)
}
func registerMoreThanOneAttestationError(ut ut.Translator) error {
@ -187,6 +190,9 @@ func (c *Config) translateMoreThanOneAttestationError(ut ut.Translator, fe valid
if c.Attestation.AWSNitroTPM != nil {
definedAttestations = append(definedAttestations, "AWSNitroTPM")
}
if c.Attestation.AWSSEVSNP != nil {
definedAttestations = append(definedAttestations, "AWSSEVSNP")
}
if c.Attestation.AzureSEVSNP != nil {
definedAttestations = append(definedAttestations, "AzureSEVSNP")
}
@ -360,15 +366,31 @@ func validateNoPlaceholder(fl validator.FieldLevel) bool {
return len(getPlaceholderEntries(fl.Field().Interface().(measurements.M))) == 0
}
// validateMeasurement acts like validateNoPlaceholder, but is used for the measurements.Measurement type.
func validateMeasurement(sl validator.StructLevel) {
measurement := sl.Current().Interface().(measurements.Measurement)
actual := measurement.Expected
placeHolder := measurements.PlaceHolderMeasurement(measurements.PCRMeasurementLength).Expected
if bytes.Equal(actual, placeHolder) {
sl.ReportError(measurement, "launchMeasurement", "launchMeasurement", "no_placeholders", "")
}
}
func registerContainsPlaceholderError(ut ut.Translator) error {
return ut.Add("no_placeholders", "{0} placeholder values (repeated 1234...)", true)
}
func translateContainsPlaceholderError(ut ut.Translator, fe validator.FieldError) string {
placeholders := getPlaceholderEntries(fe.Value().(measurements.M))
msg := fmt.Sprintf("Measurements %v contain", placeholders)
if len(placeholders) == 1 {
msg = fmt.Sprintf("Measurement %v contains", placeholders)
var msg string
switch fe.Field() {
case "launchMeasurement":
msg = "launchMeasurement contains"
case "measurements":
placeholders := getPlaceholderEntries(fe.Value().(measurements.M))
msg = fmt.Sprintf("measurements %v contain", placeholders)
if len(placeholders) == 1 {
msg = fmt.Sprintf("measurement %v contains", placeholders)
}
}
t, _ := ut.T("no_placeholders", msg)

View File

@ -20,9 +20,9 @@ go_test(
embed = [":dialer"],
deps = [
"//internal/atls",
"//internal/attestation/variant",
"//internal/grpc/atlscredentials",
"//internal/grpc/testdialer",
"//internal/variant",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
"@org_golang_google_grpc//:go_default_library",

View File

@ -11,9 +11,9 @@ import (
"testing"
"github.com/edgelesssys/constellation/v2/internal/atls"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/grpc/atlscredentials"
"github.com/edgelesssys/constellation/v2/internal/grpc/testdialer"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"

View File

@ -12,8 +12,8 @@ go_library(
deps = [
"//internal/api/fetcher",
"//internal/api/versionsapi",
"//internal/attestation/variant",
"//internal/cloud/cloudprovider",
"//internal/variant",
"@com_github_schollz_progressbar_v3//:progressbar",
"@com_github_spf13_afero//:afero",
],
@ -28,9 +28,9 @@ go_test(
embed = [":imagefetcher"],
deps = [
"//internal/api/versionsapi",
"//internal/attestation/variant",
"//internal/cloud/cloudprovider",
"//internal/file",
"//internal/variant",
"@com_github_spf13_afero//:afero",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",

View File

@ -21,8 +21,8 @@ import (
"github.com/edgelesssys/constellation/v2/internal/api/fetcher"
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/spf13/afero"
)

Some files were not shown because too many files have changed in this diff Show More