mirror of
https://github.com/ultravioletrs/cocos.git
synced 2026-06-23 04:10:25 +00:00
PRISM-821 - Fix attestation policy for azure cvms (#437)
* Refactor attestation handling: update logging messages, adjust command arguments, and enhance provider initialization with MaaURL support Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add default PcrConfig to attestation policy generation Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Remove unused validateClaims function and its dependencies from snp.go Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Fix GenerateAttestationPolicy: update TCB composition handling and remove unused minimalTCB assignment Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Refactor vtpm provider initialization: remove unused MaaURL parameter and update related function calls Signed-off-by: Sammy Oina <sammyoina@gmail.com> --------- Signed-off-by: Sammy Oina <sammyoina@gmail.com>
This commit is contained in:
committed by
GitHub
parent
94c169febb
commit
90807d9576
@@ -134,7 +134,7 @@ func (lm *loggingMiddleware) IMAMeasurements(ctx context.Context) (file []byte,
|
||||
|
||||
func (lm *loggingMiddleware) AttestationResult(ctx context.Context, nonce [vtpm.Nonce]byte, attType attestation.PlatformType) (response []byte, err error) {
|
||||
defer func(begin time.Time) {
|
||||
message := fmt.Sprintf("Method Attestation took %s to complete", time.Since(begin))
|
||||
message := fmt.Sprintf("Method AttestationResult took %s to complete", time.Since(begin))
|
||||
if err != nil {
|
||||
lm.logger.Warn(fmt.Sprintf("%s with error: %s", message, err))
|
||||
return
|
||||
|
||||
@@ -232,8 +232,8 @@ func (cli *CLI) NewAzureAttestationPolicy() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "azure",
|
||||
Short: "Get attestation policy for Azure CVM",
|
||||
Example: `azure <azure_maa_token_file> <token_nonce> <product_name>`,
|
||||
Args: cobra.ExactArgs(3),
|
||||
Example: `azure <azure_maa_token_file> <product_name>`,
|
||||
Args: cobra.ExactArgs(2),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
token, err := os.ReadFile(args[0])
|
||||
if err != nil {
|
||||
@@ -241,10 +241,9 @@ func (cli *CLI) NewAzureAttestationPolicy() *cobra.Command {
|
||||
return
|
||||
}
|
||||
|
||||
nonce := []byte(args[1])
|
||||
product := args[2]
|
||||
product := args[1]
|
||||
|
||||
config, err := azure.GenerateAttestationPolicy(string(token), product, policy, nonce)
|
||||
config, err := azure.GenerateAttestationPolicy(string(token), product, policy)
|
||||
if err != nil {
|
||||
printError(cmd, "Error generating attestation policy: %v ❌ ", err)
|
||||
return
|
||||
|
||||
+8
-8
@@ -43,15 +43,15 @@ const (
|
||||
)
|
||||
|
||||
type config struct {
|
||||
LogLevel string `env:"AGENT_LOG_LEVEL" envDefault:"debug"`
|
||||
Vmpl int `env:"AGENT_VMPL" envDefault:"2"`
|
||||
AgentGrpcHost string `env:"AGENT_GRPC_HOST" envDefault:"0.0.0.0"`
|
||||
LogLevel string `env:"AGENT_LOG_LEVEL" envDefault:"debug"`
|
||||
Vmpl int `env:"AGENT_VMPL" envDefault:"2"`
|
||||
AgentGrpcHost string `env:"AGENT_GRPC_HOST" envDefault:"0.0.0.0"`
|
||||
CAUrl string `env:"AGENT_CVM_CA_URL" envDefault:""`
|
||||
CVMId string `env:"AGENT_CVM_ID" envDefault:""`
|
||||
AgentMaaURL string `env:"AGENT_MAA_URL" envDefault:"https://sharedeus2.eus2.attest.azure.net"`
|
||||
AgentOSBuild string `env:"AGENT_OS_BUILD" envDefault:"UVC"`
|
||||
AgentOSDistro string `env:"AGENT_OS_DISTRO" envDefault:"UVC"`
|
||||
AgentOSType string `env:"AGENT_OS_TYPE" envDefault:"UVC"`
|
||||
CVMId string `env:"AGENT_CVM_ID" envDefault:""`
|
||||
AgentMaaURL string `env:"AGENT_MAA_URL" envDefault:"https://sharedeus2.eus2.attest.azure.net"`
|
||||
AgentOSBuild string `env:"AGENT_OS_BUILD" envDefault:"UVC"`
|
||||
AgentOSDistro string `env:"AGENT_OS_DISTRO" envDefault:"UVC"`
|
||||
AgentOSType string `env:"AGENT_OS_TYPE" envDefault:"UVC"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -27,6 +27,7 @@ func InitializeDefaultMAAVars(config *EnvConfig) {
|
||||
maa.OSBuild = config.OSBuild
|
||||
maa.OSType = config.OSType
|
||||
maa.OSDistro = config.OSDistro
|
||||
MaaURL = config.MaaURL
|
||||
}
|
||||
|
||||
func (c *EnvConfig) InitializeOSVars(build, osType, osDistro string) {
|
||||
|
||||
@@ -5,7 +5,6 @@ package azure
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -117,7 +116,7 @@ func (a provider) VerifyAttestation(report []byte, teeNonce []byte, vTpmNonce []
|
||||
}
|
||||
|
||||
func (a provider) AzureAttestationToken(tokenNonce []byte) ([]byte, error) {
|
||||
quote, err := vtpm.FetchAzureAttestation(tokenNonce)
|
||||
quote, err := FetchAzureAttestationToken(tokenNonce, MaaURL)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(vtpm.ErrFetchAzureToken, err)
|
||||
}
|
||||
@@ -125,16 +124,12 @@ func (a provider) AzureAttestationToken(tokenNonce []byte) ([]byte, error) {
|
||||
return quote, nil
|
||||
}
|
||||
|
||||
func GenerateAttestationPolicy(token string, product string, policy uint64, nonce []byte) (*attestation.Config, error) {
|
||||
func GenerateAttestationPolicy(token, product string, policy uint64) (*attestation.Config, error) {
|
||||
claims, err := validateToken(token)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to validate token: %w", err)
|
||||
}
|
||||
|
||||
if err := validateClaims(claims, nonce); err != nil {
|
||||
return nil, fmt.Errorf("failed to validate claims: %w", err)
|
||||
}
|
||||
|
||||
tee, ok := claims["x-ms-isolation-tee"].(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to get tee from claims")
|
||||
@@ -195,7 +190,8 @@ func GenerateAttestationPolicy(token string, product string, policy uint64, nonc
|
||||
UcodeSpl: uint8(microcodeVersion),
|
||||
}
|
||||
|
||||
minimalTCB, err := kds.ComposeTCBParts(minimalTCBParts)
|
||||
// Minimum TCB at the moment is not valid and will be fixed in the future.
|
||||
_, err = kds.ComposeTCBParts(minimalTCBParts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to compose TCB parts: %w", err)
|
||||
}
|
||||
@@ -235,16 +231,24 @@ func GenerateAttestationPolicy(token string, product string, policy uint64, nonc
|
||||
FamilyId: familyId,
|
||||
Measurement: measurement,
|
||||
MinimumGuestSvn: uint32(guestSVN),
|
||||
MinimumTcb: uint64(minimalTCB),
|
||||
TrustedIdKeyHashes: [][]byte{idKeyDigest},
|
||||
ReportId: reportID,
|
||||
Product: &sevsnp.SevProduct{Name: sevProduct},
|
||||
Policy: policy,
|
||||
},
|
||||
},
|
||||
PcrConfig: &attestation.PcrConfig{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func FetchAzureAttestationToken(tokenNonce []byte, maaURL string) ([]byte, error) {
|
||||
token, err := maa.Attest(context.Background(), tokenNonce, maaURL, http.DefaultClient)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching azure token: %w", err)
|
||||
}
|
||||
return []byte(token), nil
|
||||
}
|
||||
|
||||
func validateToken(token string) (map[string]interface{}, error) {
|
||||
unverifiedToken, _, err := new(jwt.Parser).ParseUnverified(token, jwt.MapClaims{})
|
||||
if err != nil {
|
||||
@@ -273,26 +277,3 @@ func validateToken(token string) (map[string]interface{}, error) {
|
||||
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
func validateClaims(claims map[string]interface{}, nonce []byte) error {
|
||||
runtime, ok := claims["x-ms-runtime"].(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to get runtime from claims")
|
||||
}
|
||||
|
||||
payload, ok := runtime["client-payload"].(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to get client payload from claims")
|
||||
}
|
||||
|
||||
tokenNonce, ok := payload["nonce"].(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to get nonce from claims")
|
||||
}
|
||||
|
||||
if tokenNonce != base64.StdEncoding.EncodeToString(nonce) {
|
||||
return fmt.Errorf("nonce mismatch: expected %s, got %s", base64.StdEncoding.EncodeToString(nonce), tokenNonce)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -5,19 +5,16 @@ package vtpm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
"github.com/edgelesssys/go-azguestattestation/maa"
|
||||
"github.com/google/go-sev-guest/abi"
|
||||
"github.com/google/go-sev-guest/proto/sevsnp"
|
||||
"github.com/google/go-tpm-tools/client"
|
||||
@@ -147,12 +144,7 @@ func (v provider) VerifyAttestation(report []byte, teeNonce []byte, vTpmNonce []
|
||||
}
|
||||
|
||||
func (v provider) AzureAttestationToken(tokenNonce []byte) ([]byte, error) {
|
||||
quote, err := FetchAzureAttestation(tokenNonce)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ErrFetchQuote, err)
|
||||
}
|
||||
|
||||
return quote, nil
|
||||
return nil, errors.New("Azure attestation token is not supported")
|
||||
}
|
||||
|
||||
func Attest(teeNonce []byte, vTPMNonce []byte, teeAttestaion bool, vmpl uint) ([]byte, error) {
|
||||
@@ -171,14 +163,6 @@ func Attest(teeNonce []byte, vTPMNonce []byte, teeAttestaion bool, vmpl uint) ([
|
||||
return marshalQuote(attestation)
|
||||
}
|
||||
|
||||
func FetchAzureAttestation(tokenNonce []byte) ([]byte, error) {
|
||||
token, err := maa.Attest(context.Background(), tokenNonce, os.Getenv("AgentMaaURL"), http.DefaultClient)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching azure token: %w", err)
|
||||
}
|
||||
return []byte(token), nil
|
||||
}
|
||||
|
||||
func VTPMVerify(quote []byte, pubKeyTLS []byte, teeNonce []byte, vtpmNonce []byte, writer io.Writer) error {
|
||||
if err := VerifyQuote(quote, pubKeyTLS, vtpmNonce, writer); err != nil {
|
||||
return fmt.Errorf("failed to verify vTPM quote: %v", err)
|
||||
|
||||
Reference in New Issue
Block a user