mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-06-25 06:30:45 -04:00
Enable CLI verify with JSON output for Azure TDX
Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
parent
574a0812b0
commit
3e91f1a53f
5 changed files with 53 additions and 23 deletions
|
@ -111,6 +111,9 @@ go_library(
|
||||||
"@io_k8s_sigs_yaml//:yaml",
|
"@io_k8s_sigs_yaml//:yaml",
|
||||||
"@org_golang_x_mod//semver",
|
"@org_golang_x_mod//semver",
|
||||||
"@org_golang_google_grpc//:grpc",
|
"@org_golang_google_grpc//:grpc",
|
||||||
|
"@com_github_google_go_tdx_guest//abi",
|
||||||
|
"@com_github_google_go_tdx_guest//proto/tdx",
|
||||||
|
"//internal/attestation/azure/tdx",
|
||||||
] + select({
|
] + select({
|
||||||
"@io_bazel_rules_go//go/platform:android_amd64": [
|
"@io_bazel_rules_go//go/platform:android_amd64": [
|
||||||
"@org_golang_x_sys//unix",
|
"@org_golang_x_sys//unix",
|
||||||
|
|
|
@ -21,10 +21,9 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
tpmProto "github.com/google/go-tpm-tools/proto/tpm"
|
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/atls"
|
"github.com/edgelesssys/constellation/v2/internal/atls"
|
||||||
|
azuretdx "github.com/edgelesssys/constellation/v2/internal/attestation/azure/tdx"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/choose"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/choose"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/attestation/snp"
|
"github.com/edgelesssys/constellation/v2/internal/attestation/snp"
|
||||||
|
@ -38,6 +37,10 @@ import (
|
||||||
"github.com/edgelesssys/constellation/v2/internal/grpc/dialer"
|
"github.com/edgelesssys/constellation/v2/internal/grpc/dialer"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/verify"
|
"github.com/edgelesssys/constellation/v2/internal/verify"
|
||||||
"github.com/edgelesssys/constellation/v2/verify/verifyproto"
|
"github.com/edgelesssys/constellation/v2/verify/verifyproto"
|
||||||
|
|
||||||
|
"github.com/google/go-tdx-guest/abi"
|
||||||
|
"github.com/google/go-tdx-guest/proto/tdx"
|
||||||
|
tpmProto "github.com/google/go-tpm-tools/proto/tpm"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
@ -189,8 +192,9 @@ func (c *verifyCmd) verify(cmd *cobra.Command, verifyClient verifyClient, config
|
||||||
case "json":
|
case "json":
|
||||||
if !(attConfig.GetVariant().Equal(variant.AzureSEVSNP{}) ||
|
if !(attConfig.GetVariant().Equal(variant.AzureSEVSNP{}) ||
|
||||||
attConfig.GetVariant().Equal(variant.AWSSEVSNP{}) ||
|
attConfig.GetVariant().Equal(variant.AWSSEVSNP{}) ||
|
||||||
attConfig.GetVariant().Equal(variant.GCPSEVSNP{})) {
|
attConfig.GetVariant().Equal(variant.GCPSEVSNP{}) ||
|
||||||
return errors.New("json output is only supported for SEV-SNP")
|
attConfig.GetVariant().Equal(variant.AzureTDX{})) {
|
||||||
|
return errors.New("json output is only supported for SEV-SNP and TDX variants")
|
||||||
}
|
}
|
||||||
|
|
||||||
attDocOutput, err = formatJSON(cmd.Context(), rawAttestationDoc, attConfig, c.log)
|
attDocOutput, err = formatJSON(cmd.Context(), rawAttestationDoc, attConfig, c.log)
|
||||||
|
@ -247,13 +251,24 @@ func (c *verifyCmd) validateEndpointFlag(cmd *cobra.Command, stateFile *state.St
|
||||||
// formatJSON returns the json formatted attestation doc.
|
// formatJSON returns the json formatted attestation doc.
|
||||||
func formatJSON(ctx context.Context, docString string, attestationCfg config.AttestationCfg, log debugLog,
|
func formatJSON(ctx context.Context, docString string, attestationCfg config.AttestationCfg, log debugLog,
|
||||||
) (string, error) {
|
) (string, error) {
|
||||||
var doc attestationDoc
|
var doc vtpm.AttestationDocument
|
||||||
if err := json.Unmarshal([]byte(docString), &doc); err != nil {
|
if err := json.Unmarshal([]byte(docString), &doc); err != nil {
|
||||||
return "", fmt.Errorf("unmarshalling attestation document: %w", err)
|
return "", fmt.Errorf("unmarshalling attestation document: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (attestationCfg.GetVariant().Equal(variant.AWSSEVSNP{}) ||
|
||||||
|
attestationCfg.GetVariant().Equal(variant.AzureSEVSNP{}) ||
|
||||||
|
attestationCfg.GetVariant().Equal(variant.GCPSEVSNP{})) {
|
||||||
|
return snpFormatJSON(ctx, doc.InstanceInfo, attestationCfg, log)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tdxFormatJSON(doc.InstanceInfo, attestationCfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func snpFormatJSON(ctx context.Context, instanceInfoRaw []byte, attestationCfg config.AttestationCfg, log debugLog,
|
||||||
|
) (string, error) {
|
||||||
var instanceInfo snp.InstanceInfo
|
var instanceInfo snp.InstanceInfo
|
||||||
if err := json.Unmarshal(doc.InstanceInfo, &instanceInfo); err != nil {
|
if err := json.Unmarshal(instanceInfoRaw, &instanceInfo); err != nil {
|
||||||
return "", fmt.Errorf("unmarshalling instance info: %w", err)
|
return "", fmt.Errorf("unmarshalling instance info: %w", err)
|
||||||
}
|
}
|
||||||
report, err := verify.NewReport(ctx, instanceInfo, attestationCfg, log)
|
report, err := verify.NewReport(ctx, instanceInfo, attestationCfg, log)
|
||||||
|
@ -262,17 +277,40 @@ func formatJSON(ctx context.Context, docString string, attestationCfg config.Att
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonBytes, err := json.Marshal(report)
|
jsonBytes, err := json.Marshal(report)
|
||||||
|
|
||||||
return string(jsonBytes), err
|
return string(jsonBytes), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tdxFormatJSON(instanceInfoRaw []byte, attestationCfg config.AttestationCfg) (string, error) {
|
||||||
|
var rawQuote []byte
|
||||||
|
|
||||||
|
if attestationCfg.GetVariant().Equal(variant.AzureTDX{}) {
|
||||||
|
var instanceInfo azuretdx.InstanceInfo
|
||||||
|
if err := json.Unmarshal(instanceInfoRaw, &instanceInfo); err != nil {
|
||||||
|
return "", fmt.Errorf("unmarshalling instance info: %w", err)
|
||||||
|
}
|
||||||
|
rawQuote = instanceInfo.AttestationReport
|
||||||
|
}
|
||||||
|
|
||||||
|
tdxQuote, err := abi.QuoteToProto(rawQuote)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("converting quote to proto: %w", err)
|
||||||
|
}
|
||||||
|
quote, ok := tdxQuote.(*tdx.QuoteV4)
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("unexpected quote type: %T", tdxQuote)
|
||||||
|
}
|
||||||
|
|
||||||
|
quoteJSON, err := json.Marshal(quote)
|
||||||
|
return string(quoteJSON), err
|
||||||
|
}
|
||||||
|
|
||||||
// format returns the formatted attestation doc.
|
// format returns the formatted attestation doc.
|
||||||
func formatDefault(ctx context.Context, docString string, attestationCfg config.AttestationCfg, log debugLog,
|
func formatDefault(ctx context.Context, docString string, attestationCfg config.AttestationCfg, log debugLog,
|
||||||
) (string, error) {
|
) (string, error) {
|
||||||
b := &strings.Builder{}
|
b := &strings.Builder{}
|
||||||
b.WriteString("Attestation Document:\n")
|
b.WriteString("Attestation Document:\n")
|
||||||
|
|
||||||
var doc attestationDoc
|
var doc vtpm.AttestationDocument
|
||||||
if err := json.Unmarshal([]byte(docString), &doc); err != nil {
|
if err := json.Unmarshal([]byte(docString), &doc); err != nil {
|
||||||
return "", fmt.Errorf("unmarshal attestation document: %w", err)
|
return "", fmt.Errorf("unmarshal attestation document: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -330,18 +368,6 @@ func parseQuotes(b *strings.Builder, quotes []*tpmProto.Quote, expectedPCRs meas
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// attestationDoc is the attestation document returned by the verifier.
|
|
||||||
type attestationDoc struct {
|
|
||||||
Attestation struct {
|
|
||||||
AkPub string `json:"ak_pub"`
|
|
||||||
Quotes []*tpmProto.Quote `json:"quotes"`
|
|
||||||
EventLog string `json:"event_log"`
|
|
||||||
TeeAttestation interface{} `json:"TeeAttestation"`
|
|
||||||
} `json:"Attestation"`
|
|
||||||
InstanceInfo []byte `json:"InstanceInfo"`
|
|
||||||
UserData []byte `json:"UserData"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type constellationVerifier struct {
|
type constellationVerifier struct {
|
||||||
dialer grpcInsecureDialer
|
dialer grpcInsecureDialer
|
||||||
log debugLog
|
log debugLog
|
||||||
|
|
|
@ -90,7 +90,7 @@ func (i *Issuer) getInstanceInfo(ctx context.Context, tpm io.ReadWriteCloser, _
|
||||||
return nil, fmt.Errorf("getting quote: %w", err)
|
return nil, fmt.Errorf("getting quote: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
instanceInfo := instanceInfo{
|
instanceInfo := InstanceInfo{
|
||||||
AttestationReport: quote,
|
AttestationReport: quote,
|
||||||
RuntimeData: runtimeData,
|
RuntimeData: runtimeData,
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,8 @@ More specifically:
|
||||||
*/
|
*/
|
||||||
package tdx
|
package tdx
|
||||||
|
|
||||||
type instanceInfo struct {
|
// InstanceInfo wraps the TDX report with additional Azure specific runtime data.
|
||||||
|
type InstanceInfo struct {
|
||||||
AttestationReport []byte
|
AttestationReport []byte
|
||||||
RuntimeData []byte
|
RuntimeData []byte
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ func NewValidator(cfg *config.AzureTDX, log attestation.Logger) *Validator {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Validator) getTrustedTPMKey(_ context.Context, attDoc vtpm.AttestationDocument, _ []byte) (crypto.PublicKey, error) {
|
func (v *Validator) getTrustedTPMKey(_ context.Context, attDoc vtpm.AttestationDocument, _ []byte) (crypto.PublicKey, error) {
|
||||||
var instanceInfo instanceInfo
|
var instanceInfo InstanceInfo
|
||||||
if err := json.Unmarshal(attDoc.InstanceInfo, &instanceInfo); err != nil {
|
if err := json.Unmarshal(attDoc.InstanceInfo, &instanceInfo); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue