Skip to content

Commit

Permalink
manifest: implement & use generator for TDXOptions
Browse files Browse the repository at this point in the history
We don't call any callbacks yet, so the coordinator doesn't work yet,
but the set command already succeeds :)
  • Loading branch information
Freax13 committed Aug 26, 2024
1 parent e976036 commit 54ee2e9
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 14 deletions.
14 changes: 12 additions & 2 deletions cli/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/edgelesssys/contrast/internal/atls"
"github.com/edgelesssys/contrast/internal/attestation/certcache"
"github.com/edgelesssys/contrast/internal/attestation/snp"
"github.com/edgelesssys/contrast/internal/attestation/tdx"
"github.com/edgelesssys/contrast/internal/fsstore"
"github.com/edgelesssys/contrast/internal/logger"
"github.com/edgelesssys/contrast/internal/manifest"
Expand Down Expand Up @@ -91,16 +92,25 @@ func validatorsFromManifest(m *manifest.Manifest, log *slog.Logger, hostData []b
kdsCache := fsstore.New(kdsDir, log.WithGroup("kds-cache"))
kdsGetter := certcache.NewCachedHTTPSGetter(kdsCache, certcache.NeverGCTicker, log.WithGroup("kds-getter"))

var validators []atls.Validator

opts, err := m.SNPValidateOpts(kdsGetter)
if err != nil {
return nil, fmt.Errorf("getting SNP validate options: %w", err)
}

var validators []atls.Validator
for _, opt := range opts {
validators = append(validators, snp.NewValidator(opt.VerifyOpts, opt.ValidateOpts, []manifest.HexString{manifest.NewHexString(hostData)},
logger.NewWithAttrs(logger.NewNamed(log, "validator"), map[string]string{"tee-type": "snp"}),
))
}

tdxOpts, err := m.TDXValidateOpts()
if err != nil {
return nil, fmt.Errorf("generating TDX validation options: %w", err)
}
for _, opt := range tdxOpts {
validators = append(validators, tdx.NewValidator(&tdx.StaticValidateOptsGenerator{Opts: opt}, logger.NewWithAttrs(logger.NewNamed(log, "validator"), map[string]string{"tee-type": "tdx"})))
}

return validators, nil
}
14 changes: 13 additions & 1 deletion coordinator/internal/authority/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/edgelesssys/contrast/internal/atls"
"github.com/edgelesssys/contrast/internal/attestation/certcache"
"github.com/edgelesssys/contrast/internal/attestation/snp"
"github.com/edgelesssys/contrast/internal/attestation/tdx"
"github.com/edgelesssys/contrast/internal/logger"
"github.com/edgelesssys/contrast/internal/manifest"
"github.com/edgelesssys/contrast/internal/memstore"
Expand Down Expand Up @@ -76,6 +77,8 @@ func (c *Credentials) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.A
State: state,
}

var validators []atls.Validator

opts, err := state.Manifest.SNPValidateOpts(c.kdsGetter)
if err != nil {
return nil, nil, fmt.Errorf("generating SNP validation options: %w", err)
Expand All @@ -86,13 +89,22 @@ func (c *Credentials) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.A
allowedHostDataEntries = append(allowedHostDataEntries, entry)
}

var validators []atls.Validator
for _, opt := range opts {
validator := snp.NewValidatorWithCallbacks(opt.VerifyOpts, opt.ValidateOpts, allowedHostDataEntries,
logger.NewWithAttrs(logger.NewNamed(c.logger, "validator"), map[string]string{"tee-type": "snp"}),
&authInfo)
validators = append(validators, validator)
}

tdxOpts, err := state.Manifest.TDXValidateOpts()
if err != nil {
return nil, nil, fmt.Errorf("generating TDX validation options: %w", err)
}
for _, opt := range tdxOpts {
validators = append(validators, tdx.NewValidator(&tdx.StaticValidateOptsGenerator{Opts: opt},
logger.NewWithAttrs(logger.NewNamed(c.logger, "validator"), map[string]string{"tee-type": "tdx"})))
}

serverCfg, err := atls.CreateAttestationServerTLSConfig(c.issuer, validators, c.attestationFailuresCounter)
if err != nil {
return nil, nil, err
Expand Down
84 changes: 73 additions & 11 deletions internal/manifest/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import (

"github.com/google/go-sev-guest/abi"
"github.com/google/go-sev-guest/kds"
"github.com/google/go-sev-guest/validate"
snpvalidate "github.com/google/go-sev-guest/validate"
"github.com/google/go-sev-guest/verify"
"github.com/google/go-sev-guest/verify/trust"
tdxvalidate "github.com/google/go-tdx-guest/validate"
)

// Manifest is the Coordinator manifest and contains the reference values of the deployment.
Expand Down Expand Up @@ -191,16 +192,12 @@ func (m *Manifest) Validate() error {
// by a Validator.
type ValidatorOptions struct {
VerifyOpts *verify.Options
ValidateOpts *validate.Options
ValidateOpts *snpvalidate.Options
}

// SNPValidateOpts returns validate options generators populated with the manifest's
// SNP reference values and trusted measurement for the given runtime.
func (m *Manifest) SNPValidateOpts(kdsGetter trust.HTTPSGetter) ([]ValidatorOptions, error) {
if len(m.ReferenceValues.SNP) == 0 {
return nil, errors.New("reference values cannot be empty")
}

if err := m.Validate(); err != nil {
return nil, fmt.Errorf("validating manifest: %w", err)
}
Expand All @@ -224,7 +221,7 @@ func (m *Manifest) SNPValidateOpts(kdsGetter trust.HTTPSGetter) ([]ValidatorOpti
verifyOpts.CheckRevocations = true
verifyOpts.Getter = kdsGetter

validateOpts := validate.Options{
validateOpts := snpvalidate.Options{
Measurement: trustedMeasurement,
GuestPolicy: abi.SnpPolicy{
Debug: false,
Expand All @@ -249,10 +246,6 @@ func (m *Manifest) SNPValidateOpts(kdsGetter trust.HTTPSGetter) ([]ValidatorOpti
out = append(out, ValidatorOptions{VerifyOpts: verifyOpts, ValidateOpts: &validateOpts})
}

if len(out) == 0 {
return nil, errors.New("no SNP reference values found in manifest")
}

return out, nil
}

Expand Down Expand Up @@ -287,3 +280,72 @@ func trustedRoots(productName ProductName) (map[string][]*trust.AMDRootCerts, er

return trustedRoots, nil
}

// The QE Vendor ID used by Intel.
var intelQeVendorID = []byte{0x93, 0x9a, 0x72, 0x33, 0xf7, 0x9c, 0x4c, 0xa9, 0x94, 0x0a, 0x0d, 0xb3, 0x95, 0x7f, 0x06, 0x07}

// TDXValidateOpts returns validate options generators populated with the manifest's
// TDX reference values and trusted measurement for the given runtime.
func (m *Manifest) TDXValidateOpts() ([]*tdxvalidate.Options, error) {
if err := m.Validate(); err != nil {
return nil, fmt.Errorf("validating manifest: %w", err)
}

var out []*tdxvalidate.Options
for _, refVal := range m.ReferenceValues.TDX {
mrTd, err := refVal.MrTd.Bytes()
if err != nil {
return nil, fmt.Errorf("failed to convert MrTd from manifest to byte slices: %w", err)
}

minimumTeeTcbSvn, err := refVal.MinimumTeeTcbSvn.Bytes()
if err != nil {
return nil, fmt.Errorf("failed to convert MinimumTeeTcbSvn from manifest to byte slices: %w", err)
}

mrSeam, err := refVal.MrSeam.Bytes()
if err != nil {
return nil, fmt.Errorf("failed to convert MrSeam from manifest to byte slices: %w", err)
}

tdAttributes, err := refVal.TdAttributes.Bytes()
if err != nil {
return nil, fmt.Errorf("failed to convert TdAttributes from manifest to byte slices: %w", err)
}

xfam, err := refVal.Xfam.Bytes()
if err != nil {
return nil, fmt.Errorf("failed to convert Xfam from manifest to byte slices: %w", err)
}

var rtmrs [4][]byte
for i, rtmr := range refVal.Rtrms {
bytes, err := rtmr.Bytes()
if err != nil {
return nil, fmt.Errorf("failed to convert Rtmr[%d] from manifest to byte slices: %w", i, err)
}
rtmrs[i] = bytes
}

out = append(out, &tdxvalidate.Options{
HeaderOptions: tdxvalidate.HeaderOptions{
MinimumQeSvn: *refVal.MinimumQeSvn,
MinimumPceSvn: *refVal.MinimumPceSvn,
QeVendorID: intelQeVendorID,
},
TdQuoteBodyOptions: tdxvalidate.TdQuoteBodyOptions{
MinimumTeeTcbSvn: minimumTeeTcbSvn,
MrSeam: mrSeam,
TdAttributes: tdAttributes,
Xfam: xfam,
// TODO(freax13): Re-enable validation of those fields once we figure out how to calculate the launch measurement.
// MrTd: mrTd,
// Rtmrs: rtmrs[:],
},
})
_ = mrTd
_ = rtmrs
}

return out, nil
}

0 comments on commit 54ee2e9

Please sign in to comment.