mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-04-21 23:59:09 -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
@ -111,6 +111,9 @@ go_library(
|
||||
"@io_k8s_sigs_yaml//:yaml",
|
||||
"@org_golang_x_mod//semver",
|
||||
"@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({
|
||||
"@io_bazel_rules_go//go/platform:android_amd64": [
|
||||
"@org_golang_x_sys//unix",
|
||||
|
@ -21,10 +21,9 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
tpmProto "github.com/google/go-tpm-tools/proto/tpm"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
|
||||
"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/measurements"
|
||||
"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/verify"
|
||||
"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/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
@ -189,8 +192,9 @@ func (c *verifyCmd) verify(cmd *cobra.Command, verifyClient verifyClient, config
|
||||
case "json":
|
||||
if !(attConfig.GetVariant().Equal(variant.AzureSEVSNP{}) ||
|
||||
attConfig.GetVariant().Equal(variant.AWSSEVSNP{}) ||
|
||||
attConfig.GetVariant().Equal(variant.GCPSEVSNP{})) {
|
||||
return errors.New("json output is only supported for SEV-SNP")
|
||||
attConfig.GetVariant().Equal(variant.GCPSEVSNP{}) ||
|
||||
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)
|
||||
@ -247,13 +251,24 @@ func (c *verifyCmd) validateEndpointFlag(cmd *cobra.Command, stateFile *state.St
|
||||
// formatJSON returns the json formatted attestation doc.
|
||||
func formatJSON(ctx context.Context, docString string, attestationCfg config.AttestationCfg, log debugLog,
|
||||
) (string, error) {
|
||||
var doc attestationDoc
|
||||
var doc vtpm.AttestationDocument
|
||||
if err := json.Unmarshal([]byte(docString), &doc); err != nil {
|
||||
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
|
||||
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)
|
||||
}
|
||||
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)
|
||||
|
||||
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.
|
||||
func formatDefault(ctx context.Context, docString string, attestationCfg config.AttestationCfg, log debugLog,
|
||||
) (string, error) {
|
||||
b := &strings.Builder{}
|
||||
b.WriteString("Attestation Document:\n")
|
||||
|
||||
var doc attestationDoc
|
||||
var doc vtpm.AttestationDocument
|
||||
if err := json.Unmarshal([]byte(docString), &doc); err != nil {
|
||||
return "", fmt.Errorf("unmarshal attestation document: %w", err)
|
||||
}
|
||||
@ -330,18 +368,6 @@ func parseQuotes(b *strings.Builder, quotes []*tpmProto.Quote, expectedPCRs meas
|
||||
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 {
|
||||
dialer grpcInsecureDialer
|
||||
log debugLog
|
||||
|
@ -90,7 +90,7 @@ func (i *Issuer) getInstanceInfo(ctx context.Context, tpm io.ReadWriteCloser, _
|
||||
return nil, fmt.Errorf("getting quote: %w", err)
|
||||
}
|
||||
|
||||
instanceInfo := instanceInfo{
|
||||
instanceInfo := InstanceInfo{
|
||||
AttestationReport: quote,
|
||||
RuntimeData: runtimeData,
|
||||
}
|
||||
|
@ -19,7 +19,8 @@ More specifically:
|
||||
*/
|
||||
package tdx
|
||||
|
||||
type instanceInfo struct {
|
||||
// InstanceInfo wraps the TDX report with additional Azure specific runtime data.
|
||||
type InstanceInfo struct {
|
||||
AttestationReport []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) {
|
||||
var instanceInfo instanceInfo
|
||||
var instanceInfo InstanceInfo
|
||||
if err := json.Unmarshal(attDoc.InstanceInfo, &instanceInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user