constellation/coordinator/attestation/gcp/noncvm.go
Leonard Cohnen 2d8fcd9bf4 monorepo
Co-authored-by: Malte Poll <mp@edgeless.systems>
Co-authored-by: katexochen <katexochen@users.noreply.github.com>
Co-authored-by: Daniel Weiße <dw@edgeless.systems>
Co-authored-by: Thomas Tendyck <tt@edgeless.systems>
Co-authored-by: Benedict Schlueter <bs@edgeless.systems>
Co-authored-by: leongross <leon.gross@rub.de>
Co-authored-by: Moritz Eckert <m1gh7ym0@gmail.com>
2022-03-22 16:09:39 +01:00

92 lines
2.3 KiB
Go

package gcp
import (
"context"
"fmt"
"time"
compute "cloud.google.com/go/compute/apiv1"
"cloud.google.com/go/compute/metadata"
"github.com/edgelesssys/constellation/coordinator/attestation/vtpm"
"github.com/edgelesssys/constellation/coordinator/oid"
tpmclient "github.com/google/go-tpm-tools/client"
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
)
// NonCVMValidator is a validator for regular GCP VMs with vTPM.
// TODO: Remove once we no longer use non cvms.
type NonCVMValidator struct {
oid.GCPNonCVM
*vtpm.Validator
}
// NewNonCVMValidator initializes a new non CVM GCP validator with the provided PCR values.
// TODO: Remove once we no longer use non cvms.
func NewNonCVMValidator(pcrs map[uint32][]byte) *NonCVMValidator {
return &NonCVMValidator{
Validator: vtpm.NewValidator(
pcrs,
trustedKeyFromGCEAPI(newInstanceClient),
func(attestation vtpm.AttestationDocument) error { return nil },
vtpm.VerifyPKCS1v15,
),
}
}
// NonCVNMIssuer for GCP confindetial VM attestation.
// TODO: Remove once we no longer use non cvms.
type NonCVMIssuer struct {
oid.GCPNonCVM
*vtpm.Issuer
}
// NewNonCVNMIssuer initializes a new GCP Issuer.
// TODO: Remove once we no longer use non cvms.
func NewNonCVMIssuer() *NonCVMIssuer {
return &NonCVMIssuer{
Issuer: vtpm.NewIssuer(
vtpm.OpenVTPM,
tpmclient.GceAttestationKeyRSA,
getGCEInstanceInfo(metadataClient{}),
),
}
}
// IsCVM returns true if the VM has confidential computing capabilities enabled.
func IsCVM() (bool, error) {
project, err := metadata.ProjectID()
if err != nil {
return false, err
}
zone, err := metadata.Zone()
if err != nil {
return false, err
}
instance, err := metadata.InstanceName()
if err != nil {
return false, err
}
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
client, err := compute.NewInstancesRESTClient(ctx)
if err != nil {
return false, err
}
defer client.Close()
infos, err := client.Get(ctx, &computepb.GetInstanceRequest{
Instance: instance,
Project: project,
Zone: zone,
})
if err != nil {
return false, err
}
if infos.ConfidentialInstanceConfig == nil {
return false, fmt.Errorf("received empty confidential instance config")
}
return *infos.ConfidentialInstanceConfig.EnableConfidentialCompute, nil
}