constellation/internal/attestation/azure/snp/maa.go
Daniel Weiße 5a0234b3f2
attestation: add option for MAA fallback to verify azure's snp-sev id key digest (#1257)
* Convert enforceIDKeyDigest setting to enum

* Use MAA fallback in Azure SNP attestation

* Only create MAA provider if MAA fallback is enabled

---------

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
Co-authored-by: Thomas Tendyck <tt@edgeless.systems>
2023-03-21 12:46:49 +01:00

81 lines
2.0 KiB
Go

/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package snp
import (
"context"
"encoding/base64"
"errors"
"fmt"
"io"
"net/http"
"github.com/edgelesssys/go-azguestattestation/maa"
)
type maaClient struct {
client *http.Client
}
func newMAAClient() *maaClient {
return &maaClient{
client: &http.Client{Transport: &http.Transport{Proxy: nil}},
}
}
func (m *maaClient) newParameters(ctx context.Context, nonce []byte, tpmHandle io.ReadWriter) (maa.Parameters, error) {
return maa.NewParameters(ctx, nonce, m.client, tpmHandle)
}
func (m *maaClient) createToken(
ctx context.Context, tpm io.ReadWriter, maaURL string, data []byte, params maa.Parameters,
) (string, error) {
tokenEnc, err := maa.GetEncryptedToken(ctx, params, data, maaURL, m.client)
if err != nil {
return "", fmt.Errorf("getting encrypted token: %w", err)
}
token, err := maa.DecryptToken(tokenEnc, tpm)
if err != nil {
return "", fmt.Errorf("decrypting token: %w", err)
}
return token, nil
}
func (m *maaClient) validateToken(ctx context.Context, maaURL, token string, extraData []byte) error {
keySet, err := maa.GetKeySet(ctx, maaURL, m.client)
if err != nil {
return fmt.Errorf("getting key set from MAA: %w", err)
}
claims, err := maa.ValidateToken(token, keySet)
if err != nil {
return fmt.Errorf("validating token: %w", err)
}
return m.validateClaims(claims, extraData)
}
func (m *maaClient) validateClaims(claims map[string]interface{}, extraData []byte) error {
runtime, ok := claims["x-ms-runtime"].(map[string]interface{})
if !ok {
return errors.New("invalid claims: missing x-ms-runtime")
}
payload, ok := runtime["client-payload"].(map[string]interface{})
if !ok {
return errors.New("invalid claims: missing client-payload")
}
nonce, ok := payload["nonce"].(string)
if !ok {
return errors.New("invalid claims: missing nonce")
}
if nonce != base64.StdEncoding.EncodeToString(extraData) {
return errors.New("invalid claims: nonce does not match extra data")
}
return nil
}