mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-01-11 15:39:33 -05:00
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:
parent
947d0cb20a
commit
8f21972aec
@ -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
|
||||
|
2
.github/actions/e2e_test/action.yml
vendored
2
.github/actions/e2e_test/action.yml
vendored
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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 (
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
)
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
|
@ -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{},
|
||||
|
@ -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"
|
||||
)
|
||||
|
@ -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 {
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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 },
|
||||
|
@ -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" {
|
||||
|
@ -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."
|
||||
}
|
||||
|
@ -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."
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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",
|
||||
],
|
||||
|
@ -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"
|
||||
)
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
|
@ -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")
|
||||
|
@ -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",
|
||||
],
|
||||
|
@ -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 {
|
||||
|
0
internal/api/attestationconfig/BUILD.bazel
Normal file
0
internal/api/attestationconfig/BUILD.bazel
Normal file
0
internal/api/attestationconfig/client/BUILD.bazel
Normal file
0
internal/api/attestationconfig/client/BUILD.bazel
Normal 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",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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",
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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",
|
||||
],
|
||||
)
|
||||
|
@ -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
|
||||
|
72
internal/attestation/aws/nitrotpm/BUILD.bazel
Normal file
72
internal/attestation/aws/nitrotpm/BUILD.bazel
Normal 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",
|
||||
],
|
||||
)
|
@ -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)
|
||||
}
|
118
internal/attestation/aws/nitrotpm/issuer_test.go
Normal file
118
internal/attestation/aws/nitrotpm/issuer_test.go
Normal 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
|
||||
}
|
29
internal/attestation/aws/nitrotpm/nitrotpm.go
Normal file
29
internal/attestation/aws/nitrotpm/nitrotpm.go
Normal 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
|
@ -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"
|
||||
)
|
146
internal/attestation/aws/nitrotpm/validator_test.go
Normal file
146
internal/attestation/aws/nitrotpm/validator_test.go
Normal 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
|
||||
}
|
51
internal/attestation/aws/snp/BUILD.bazel
Normal file
51
internal/attestation/aws/snp/BUILD.bazel
Normal 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",
|
||||
],
|
||||
)
|
66
internal/attestation/aws/snp/issuer.go
Normal file
66
internal/attestation/aws/snp/issuer.go
Normal 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)
|
||||
}
|
@ -4,7 +4,7 @@ Copyright (c) Edgeless Systems GmbH
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package aws
|
||||
package snp
|
||||
|
||||
import (
|
||||
"context"
|
52
internal/attestation/aws/snp/snp.go
Normal file
52
internal/attestation/aws/snp/snp.go
Normal 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
|
101
internal/attestation/aws/snp/validator.go
Normal file
101
internal/attestation/aws/snp/validator.go
Normal 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)
|
||||
}
|
@ -4,7 +4,7 @@ Copyright (c) Edgeless Systems GmbH
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package aws
|
||||
package snp
|
||||
|
||||
import (
|
||||
"context"
|
@ -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",
|
||||
|
@ -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"
|
||||
)
|
||||
|
@ -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"
|
||||
)
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
)
|
||||
|
@ -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"
|
||||
)
|
||||
|
@ -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",
|
||||
],
|
||||
|
@ -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:
|
||||
|
@ -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{},
|
||||
},
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
)
|
||||
|
@ -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"
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
],
|
||||
)
|
||||
|
@ -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":
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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}}
|
||||
|
@ -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),
|
||||
|
@ -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) {
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
)
|
||||
|
||||
|
@ -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"
|
||||
)
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
)
|
||||
|
||||
|
@ -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"
|
||||
)
|
||||
|
@ -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"],
|
||||
)
|
@ -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{}
|
||||
|
@ -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",
|
||||
|
@ -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{}:
|
||||
|
@ -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{})},
|
||||
},
|
||||
|
@ -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: |
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
@ -8,8 +8,8 @@ go_library(
|
||||
deps = [
|
||||
"//internal/attestation/idkeydigest",
|
||||
"//internal/attestation/measurements",
|
||||
"//internal/attestation/variant",
|
||||
"//internal/config",
|
||||
"//internal/file",
|
||||
"//internal/variant",
|
||||
],
|
||||
)
|
||||
|
@ -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 (
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
|
@ -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",
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user