mirror of
https://github.com/ultravioletrs/cocos.git
synced 2026-06-22 20:00:18 +00:00
NOISSUE - Introduce a dedicated attestation service and refactor agent to use its gRPC client (#558)
* feat: introduce a dedicated attestation service and refactor agent to use its gRPC client Signed-off-by: Sammy Oina <sammyoina@gmail.com> * feat: Source attestation-service from GitHub, updating its build and installation process. Signed-off-by: Sammy Oina <sammyoina@gmail.com> * fix: update protoc version to 33.1 in CI workflow Signed-off-by: Sammy Oina <sammyoina@gmail.com> * refactor: Update Go build tag syntax, octal literals, and simplify agent attestation logic. Signed-off-by: Sammy Oina <sammyoina@gmail.com> * chore: update igvmmeasure script's subdirectory path to tools/igvmmeasure Signed-off-by: Sammy Oina <sammyoina@gmail.com> * refactor: rename AttestationService RPC methods from `Get` to `Fetch` and update corresponding service implementation. Signed-off-by: Sammy Oina <sammyoina@gmail.com> * refactor: rename attestation client methods from `GetX` to `FetchX` 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
3f06971976
commit
c422afe0a6
@@ -34,7 +34,7 @@ jobs:
|
||||
|
||||
- name: Set up protoc
|
||||
run: |
|
||||
PROTOC_VERSION=29.0
|
||||
PROTOC_VERSION=33.1
|
||||
PROTOC_GEN_VERSION=v1.36.8
|
||||
PROTOC_GRPC_VERSION=v1.5.1
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
BUILD_DIR = build
|
||||
SERVICES = manager agent cli
|
||||
SERVICES = manager agent cli attestation-service
|
||||
ATTESTATION_POLICY = attestation_policy
|
||||
CGO_ENABLED ?= 0
|
||||
GOARCH ?= amd64
|
||||
@@ -40,6 +40,7 @@ protoc:
|
||||
protoc -I. --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative manager/manager.proto
|
||||
protoc -I. --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative agent/events/events.proto
|
||||
protoc -I. --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative agent/cvms/cvms.proto
|
||||
protoc -I. --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative internal/proto/attestation/v1/attestation.proto
|
||||
|
||||
mocks:
|
||||
mockery --config ./.mockery.yml
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.8
|
||||
// protoc v5.29.0
|
||||
// protoc v6.33.1
|
||||
// source: agent/agent.proto
|
||||
|
||||
package agent
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc v5.29.0
|
||||
// - protoc v6.33.1
|
||||
// source: agent/agent.proto
|
||||
|
||||
package agent
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build !test
|
||||
// +build !test
|
||||
|
||||
package api
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build !test
|
||||
// +build !test
|
||||
|
||||
package api
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.8
|
||||
// protoc v5.29.0
|
||||
// protoc v6.33.1
|
||||
// source: agent/cvms/cvms.proto
|
||||
|
||||
package cvms
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc v5.29.0
|
||||
// - protoc v6.33.1
|
||||
// source: agent/cvms/cvms.proto
|
||||
|
||||
package cvms
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.8
|
||||
// protoc v5.29.0
|
||||
// protoc v6.33.1
|
||||
// source: agent/events/events.proto
|
||||
|
||||
package events
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) Ultraviolet
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation"
|
||||
)
|
||||
|
||||
type MockAttestationClient struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (m *MockAttestationClient) GetAttestation(ctx context.Context, reportData [64]byte, nonce [32]byte, attType attestation.PlatformType) ([]byte, error) {
|
||||
args := m.Called(ctx, reportData, nonce, attType)
|
||||
return args.Get(0).([]byte), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *MockAttestationClient) GetAzureToken(ctx context.Context, nonce [32]byte) ([]byte, error) {
|
||||
args := m.Called(ctx, nonce)
|
||||
return args.Get(0).([]byte), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *MockAttestationClient) Close() error {
|
||||
args := m.Called()
|
||||
return args.Error(0)
|
||||
}
|
||||
+25
-45
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation/quoteprovider"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation/vtpm"
|
||||
attestation_client "github.com/ultravioletrs/cocos/pkg/clients/grpc/attestation"
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
@@ -128,33 +129,33 @@ type Service interface {
|
||||
}
|
||||
|
||||
type agentService struct {
|
||||
mu sync.Mutex
|
||||
computation Computation // Holds the current computation request details.
|
||||
algorithm algorithm.Algorithm // Filepath to the algorithm received for the computation.
|
||||
result []byte // Stores the result of the computation.
|
||||
sm statemachine.StateMachine // Manages the state transitions of the agent service.
|
||||
runError error // Stores any error encountered during the computation run.
|
||||
eventSvc events.Service // Service for publishing events related to computation.
|
||||
provider attestation.Provider // Provider for generating attestation quotes.
|
||||
logger *slog.Logger // Logger for the agent service.
|
||||
resultsConsumed bool // Indicates if the results have been consumed.
|
||||
cancel context.CancelFunc // Cancels the computation context.
|
||||
vmpl int // VMPL at which the Agent is running.
|
||||
mu sync.Mutex
|
||||
computation Computation // Holds the current computation request details.
|
||||
algorithm algorithm.Algorithm // Filepath to the algorithm received for the computation.
|
||||
result []byte // Stores the result of the computation.
|
||||
sm statemachine.StateMachine // Manages the state transitions of the agent service.
|
||||
runError error // Stores any error encountered during the computation run.
|
||||
eventSvc events.Service // Service for publishing events related to computation.
|
||||
attestationClient attestation_client.Client // Client for attestation service.
|
||||
logger *slog.Logger // Logger for the agent service.
|
||||
resultsConsumed bool // Indicates if the results have been consumed.
|
||||
cancel context.CancelFunc // Cancels the computation context.
|
||||
vmpl int // VMPL at which the Agent is running.
|
||||
}
|
||||
|
||||
var _ Service = (*agentService)(nil)
|
||||
|
||||
// New instantiates the agent service implementation.
|
||||
func New(ctx context.Context, logger *slog.Logger, eventSvc events.Service, provider attestation.Provider, vmlp int) Service {
|
||||
func New(ctx context.Context, logger *slog.Logger, eventSvc events.Service, attestationClient attestation_client.Client, vmlp int) Service {
|
||||
sm := statemachine.NewStateMachine(Idle)
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
svc := &agentService{
|
||||
sm: sm,
|
||||
eventSvc: eventSvc,
|
||||
provider: provider,
|
||||
logger: logger,
|
||||
cancel: cancel,
|
||||
vmpl: vmlp,
|
||||
sm: sm,
|
||||
eventSvc: eventSvc,
|
||||
attestationClient: attestationClient,
|
||||
logger: logger,
|
||||
cancel: cancel,
|
||||
vmpl: vmlp,
|
||||
}
|
||||
|
||||
transitions := []statemachine.Transition{
|
||||
@@ -435,36 +436,15 @@ func (as *agentService) Result(ctx context.Context) ([]byte, error) {
|
||||
}
|
||||
|
||||
func (as *agentService) Attestation(ctx context.Context, reportData [quoteprovider.Nonce]byte, nonce [vtpm.Nonce]byte, attType attestation.PlatformType) ([]byte, error) {
|
||||
switch attType {
|
||||
case attestation.SNP, attestation.TDX:
|
||||
rawQuote, err := as.provider.TeeAttestation(reportData[:])
|
||||
if err != nil {
|
||||
return []byte{}, errors.Wrap(ErrAttestationFailed, err)
|
||||
}
|
||||
return rawQuote, nil
|
||||
case attestation.VTPM:
|
||||
vTPMQuote, err := as.provider.VTpmAttestation(nonce[:])
|
||||
if err != nil {
|
||||
return []byte{}, errors.Wrap(ErrAttestationVTpmFailed, err)
|
||||
}
|
||||
return vTPMQuote, nil
|
||||
case attestation.SNPvTPM:
|
||||
vTPMQuote, err := as.provider.Attestation(reportData[:], nonce[:])
|
||||
if err != nil {
|
||||
return []byte{}, errors.Wrap(ErrAttestationVTpmFailed, err)
|
||||
}
|
||||
return vTPMQuote, nil
|
||||
default:
|
||||
return []byte{}, ErrAttestationType
|
||||
rawQuote, err := as.attestationClient.GetAttestation(ctx, reportData, nonce, attType)
|
||||
if err != nil {
|
||||
return []byte{}, errors.Wrap(ErrAttestationFailed, err)
|
||||
}
|
||||
return rawQuote, nil
|
||||
}
|
||||
|
||||
func (as *agentService) AzureAttestationToken(ctx context.Context, nonce [vtpm.Nonce]byte) ([]byte, error) {
|
||||
if attestation.CCPlatform() != attestation.Azure {
|
||||
return []byte{}, ErrAttestationType
|
||||
}
|
||||
|
||||
token, err := as.provider.AzureAttestationToken(nonce[:])
|
||||
token, err := as.attestationClient.GetAzureToken(ctx, nonce)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
+35
-30
@@ -24,7 +24,6 @@ import (
|
||||
"github.com/ultravioletrs/cocos/agent/statemachine"
|
||||
smmocks "github.com/ultravioletrs/cocos/agent/statemachine/mocks"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation"
|
||||
mocks2 "github.com/ultravioletrs/cocos/pkg/attestation/mocks"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation/quoteprovider"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation/vtpm"
|
||||
"golang.org/x/crypto/sha3"
|
||||
@@ -123,7 +122,8 @@ func TestAlgo(t *testing.T) {
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
svc := New(ctx, mglog.NewMock(), events, &attestation.EmptyProvider{}, 0)
|
||||
client := new(MockAttestationClient)
|
||||
svc := New(ctx, mglog.NewMock(), events, client, 0)
|
||||
|
||||
err := svc.InitComputation(ctx, testComputation(t))
|
||||
require.NoError(t, err)
|
||||
@@ -216,7 +216,8 @@ func TestData(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
svc := New(ctx, mglog.NewMock(), events, &attestation.EmptyProvider{}, 0)
|
||||
client := new(MockAttestationClient)
|
||||
svc := New(ctx, mglog.NewMock(), events, client, 0)
|
||||
|
||||
err := svc.InitComputation(ctx, testComputation(t))
|
||||
require.NoError(t, err)
|
||||
@@ -292,16 +293,18 @@ func TestResult(t *testing.T) {
|
||||
ctx = tc.ctxSetup(ctx)
|
||||
}
|
||||
|
||||
client := new(MockAttestationClient)
|
||||
|
||||
sm := new(smmocks.StateMachine)
|
||||
sm.On("Start", ctx).Return(nil)
|
||||
sm.On("GetState").Return(tc.state)
|
||||
sm.On("SendEvent", mock.Anything).Return()
|
||||
|
||||
svc := &agentService{
|
||||
sm: sm,
|
||||
eventSvc: events,
|
||||
provider: &attestation.EmptyProvider{},
|
||||
computation: testComputation(t),
|
||||
sm: sm,
|
||||
eventSvc: events,
|
||||
attestationClient: client,
|
||||
computation: testComputation(t),
|
||||
}
|
||||
|
||||
go func() {
|
||||
@@ -321,7 +324,7 @@ func TestResult(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAttestation(t *testing.T) {
|
||||
provider := new(mocks2.Provider)
|
||||
client := new(MockAttestationClient)
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
@@ -391,19 +394,13 @@ func TestAttestation(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
getQuote := provider.On("TeeAttestation", mock.Anything).Return(tc.rawQuote, tc.err)
|
||||
vtpmQuote := provider.On("VTpmAttestation", mock.Anything).Return(tc.rawQuote, tc.err)
|
||||
snpVtpm := provider.On("Attestation", mock.Anything, mock.Anything).Return(tc.rawQuote, tc.err)
|
||||
getQuote := client.On("GetAttestation", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.rawQuote, tc.err)
|
||||
if tc.err != ErrAttestationFailed && tc.err != ErrAttestationVTpmFailed {
|
||||
getQuote = provider.On("TeeAttestation", mock.Anything).Return(tc.nonce, nil)
|
||||
vtpmQuote = provider.On("VTpmAttestation", mock.Anything).Return(tc.nonce[:], nil)
|
||||
snpVtpm = provider.On("Attestation", mock.Anything, mock.Anything).Return(tc.nonce[:], nil)
|
||||
getQuote = client.On("GetAttestation", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.nonce[:], nil)
|
||||
}
|
||||
defer getQuote.Unset()
|
||||
defer vtpmQuote.Unset()
|
||||
defer snpVtpm.Unset()
|
||||
|
||||
svc := New(ctx, mglog.NewMock(), events, provider, 0)
|
||||
svc := New(ctx, mglog.NewMock(), events, client, 0)
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
_, err := svc.Attestation(ctx, tc.reportData, tc.nonce, tc.platform)
|
||||
assert.True(t, errors.Contains(err, tc.err), "expected %v, got %v", tc.err, err)
|
||||
@@ -412,7 +409,7 @@ func TestAttestation(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAzureAttestationToken(t *testing.T) {
|
||||
provider := new(mocks2.Provider)
|
||||
client := new(MockAttestationClient)
|
||||
cases := []struct {
|
||||
name string
|
||||
nonce [vtpm.Nonce]byte
|
||||
@@ -423,7 +420,18 @@ func TestAzureAttestationToken(t *testing.T) {
|
||||
name: "Azure token fetch successful",
|
||||
nonce: [32]byte{1, 2, 3}, // any test nonce
|
||||
token: []byte("mockToken"),
|
||||
err: ErrAttestationType,
|
||||
err: nil, // fixed expectation as err was ErrAttestationType in original but logic suggests success if token returns? Wait, orig test had ErrAttestationType? Ah, maybe provider mock returns error.
|
||||
// Re-reading original test:
|
||||
// err: ErrAttestationType
|
||||
// provider.On(...).Return(tc.token, tc.err)
|
||||
// svc.AzureAttestationToken...
|
||||
// In original code, AzureAttestationToken checked `attestation.CCPlatform() != attestation.Azure`.
|
||||
// Since test runs on non-azure, it returns ErrAttestationType.
|
||||
// My new client calls GetAzureToken. The logic for checking platform moved to attestation-service.
|
||||
// So `agent` just calls the client.
|
||||
// So here we should expect whatever the client returns.
|
||||
// Mock client returns tc.err.
|
||||
// If I want to test success, I should set err: nil.
|
||||
},
|
||||
{
|
||||
name: "Azure token fetch failed",
|
||||
@@ -431,12 +439,6 @@ func TestAzureAttestationToken(t *testing.T) {
|
||||
token: []byte{},
|
||||
err: ErrAttestationType,
|
||||
},
|
||||
{
|
||||
name: "Invalid attestation type",
|
||||
nonce: [32]byte{7, 8, 9},
|
||||
token: []byte{},
|
||||
err: ErrAttestationType,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
@@ -444,11 +446,11 @@ func TestAzureAttestationToken(t *testing.T) {
|
||||
events := new(mocks.Service)
|
||||
events.EXPECT().SendEvent(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return()
|
||||
|
||||
provider.On("AzureAttestationToken", tc.nonce[:]).Return(tc.token, tc.err)
|
||||
client.On("GetAzureToken", mock.Anything, tc.nonce).Return(tc.token, tc.err)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
svc := New(ctx, mglog.NewMock(), events, provider, 0)
|
||||
svc := New(ctx, mglog.NewMock(), events, client, 0)
|
||||
|
||||
_, err := svc.AzureAttestationToken(ctx, tc.nonce)
|
||||
assert.True(t, errors.Contains(err, tc.err), "expected error %v, got %v", tc.err, err)
|
||||
@@ -536,7 +538,8 @@ func TestStopComputation(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
svc := New(ctx, mglog.NewMock(), events, &attestation.EmptyProvider{}, 0).(*agentService)
|
||||
client := new(MockAttestationClient)
|
||||
svc := New(ctx, mglog.NewMock(), events, client, 0).(*agentService)
|
||||
|
||||
svc.computation = Computation{
|
||||
ID: "test-computation",
|
||||
@@ -604,7 +607,8 @@ func TestStopComputationIntegration(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
svc := New(ctx, mglog.NewMock(), events, &attestation.EmptyProvider{}, 0)
|
||||
client := new(MockAttestationClient)
|
||||
svc := New(ctx, mglog.NewMock(), events, client, 0)
|
||||
|
||||
computation := Computation{
|
||||
ID: "integration-test",
|
||||
@@ -642,7 +646,8 @@ func TestStopComputationConcurrent(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
svc := New(ctx, mglog.NewMock(), events, &attestation.EmptyProvider{}, 0)
|
||||
client := new(MockAttestationClient)
|
||||
svc := New(ctx, mglog.NewMock(), events, client, 0)
|
||||
|
||||
svc.(*agentService).computation = Computation{
|
||||
ID: "concurrent-test",
|
||||
|
||||
+21
-37
@@ -29,11 +29,9 @@ import (
|
||||
"github.com/ultravioletrs/cocos/pkg/atls"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation/azure"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation/quoteprovider"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation/tdx"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation/vtpm"
|
||||
"github.com/ultravioletrs/cocos/pkg/clients"
|
||||
pkggrpc "github.com/ultravioletrs/cocos/pkg/clients/grpc"
|
||||
attestation_client "github.com/ultravioletrs/cocos/pkg/clients/grpc/attestation"
|
||||
cvmsgrpc "github.com/ultravioletrs/cocos/pkg/clients/grpc/cvm"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
@@ -45,16 +43,17 @@ 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"`
|
||||
CAUrl string `env:"AGENT_CVM_CA_URL" envDefault:""`
|
||||
CVMId string `env:"AGENT_CVM_ID" envDefault:""`
|
||||
CertsToken string `env:"AGENT_CERTS_TOKEN" 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"`
|
||||
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:""`
|
||||
CertsToken string `env:"AGENT_CERTS_TOKEN" 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"`
|
||||
AttestationServiceSocket string `env:"ATTESTATION_SERVICE_SOCKET" envDefault:"/run/cocos/attestation.sock"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -99,20 +98,6 @@ func main() {
|
||||
)
|
||||
azure.InitializeDefaultMAAVars(azureConfig)
|
||||
|
||||
switch ccPlatform {
|
||||
case attestation.SNP:
|
||||
provider = vtpm.NewProvider(false, uint(cfg.Vmpl))
|
||||
case attestation.SNPvTPM:
|
||||
provider = vtpm.NewProvider(true, uint(cfg.Vmpl))
|
||||
case attestation.Azure:
|
||||
provider = azure.NewProvider()
|
||||
case attestation.TDX:
|
||||
provider = tdx.NewProvider()
|
||||
case attestation.NoCC:
|
||||
logger.Info("TEE device not found")
|
||||
provider = &attestation.EmptyProvider{}
|
||||
}
|
||||
|
||||
cvmGrpcConfig := clients.StandardClientConfig{}
|
||||
if err := env.ParseWithOptions(&cvmGrpcConfig, env.Options{Prefix: envPrefixCVMGRPC}); err != nil {
|
||||
logger.Error(fmt.Sprintf("failed to load %s gRPC client configuration : %s", svcName, err))
|
||||
@@ -156,16 +141,15 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
if ccPlatform == attestation.SNP || ccPlatform == attestation.SNPvTPM {
|
||||
err = quoteprovider.FetchCertificates(uint(cfg.Vmpl))
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("failed to fetch certificates: %s", err))
|
||||
exitCode = 1
|
||||
return
|
||||
}
|
||||
attClient, err := attestation_client.NewClient(cfg.AttestationServiceSocket)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("failed to create attestation client: %s", err))
|
||||
exitCode = 1
|
||||
return
|
||||
}
|
||||
defer attClient.Close()
|
||||
|
||||
svc := newService(ctx, logger, eventSvc, provider, cfg.Vmpl)
|
||||
svc := newService(ctx, logger, eventSvc, attClient, cfg.Vmpl)
|
||||
|
||||
if err := os.MkdirAll(storageDir, 0o755); err != nil {
|
||||
logger.Error(fmt.Sprintf("failed to create storage directory: %s", err))
|
||||
@@ -254,8 +238,8 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func newService(ctx context.Context, logger *slog.Logger, eventSvc events.Service, provider attestation.Provider, vmpl int) agent.Service {
|
||||
svc := agent.New(ctx, logger, eventSvc, provider, vmpl)
|
||||
func newService(ctx context.Context, logger *slog.Logger, eventSvc events.Service, attClient attestation_client.Client, vmpl int) agent.Service {
|
||||
svc := agent.New(ctx, logger, eventSvc, attClient, vmpl)
|
||||
|
||||
svc = api.LoggingMiddleware(svc, logger)
|
||||
counter, latency := prometheus.MakeMetrics(svcName, "api")
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
// Copyright (c) Ultraviolet
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
mglog "github.com/absmach/supermq/logger"
|
||||
"github.com/caarlos0/env/v11"
|
||||
attestationpb "github.com/ultravioletrs/cocos/internal/proto/attestation/v1"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation/azure"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation/quoteprovider"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation/tdx"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation/vtpm"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
const (
|
||||
svcName = "attestation-service"
|
||||
socketPath = "/run/cocos/attestation.sock"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
LogLevel string `env:"ATTESTATION_LOG_LEVEL" envDefault:"debug"`
|
||||
Vmpl int `env:"ATTESTATION_VMPL" envDefault:"2"`
|
||||
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() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
var cfg config
|
||||
if err := env.Parse(&cfg); err != nil {
|
||||
fmt.Printf("failed to load %s configuration : %s\n", svcName, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var exitCode int
|
||||
defer mglog.ExitWithError(&exitCode)
|
||||
|
||||
var level slog.Level
|
||||
if err := level.UnmarshalText([]byte(cfg.LogLevel)); err != nil {
|
||||
fmt.Println(err)
|
||||
exitCode = 1
|
||||
return
|
||||
}
|
||||
|
||||
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: level}))
|
||||
|
||||
var provider attestation.Provider
|
||||
ccPlatform := attestation.CCPlatform()
|
||||
|
||||
azureConfig := azure.NewEnvConfigFromAgent(
|
||||
cfg.AgentOSBuild,
|
||||
cfg.AgentOSType,
|
||||
cfg.AgentOSDistro,
|
||||
cfg.AgentMaaURL,
|
||||
)
|
||||
azure.InitializeDefaultMAAVars(azureConfig)
|
||||
|
||||
switch ccPlatform {
|
||||
case attestation.SNP:
|
||||
provider = vtpm.NewProvider(false, uint(cfg.Vmpl))
|
||||
case attestation.SNPvTPM:
|
||||
provider = vtpm.NewProvider(true, uint(cfg.Vmpl))
|
||||
case attestation.Azure:
|
||||
provider = azure.NewProvider()
|
||||
case attestation.TDX:
|
||||
provider = tdx.NewProvider()
|
||||
case attestation.NoCC:
|
||||
logger.Info("TEE device not found")
|
||||
provider = &attestation.EmptyProvider{}
|
||||
}
|
||||
|
||||
if ccPlatform == attestation.SNP || ccPlatform == attestation.SNPvTPM {
|
||||
if err := quoteprovider.FetchCertificates(uint(cfg.Vmpl)); err != nil {
|
||||
logger.Error(fmt.Sprintf("failed to fetch certificates: %s", err))
|
||||
exitCode = 1
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Remove existing socket if it exists
|
||||
if _, err := os.Stat(socketPath); err == nil {
|
||||
if err := os.Remove(socketPath); err != nil {
|
||||
logger.Error(fmt.Sprintf("failed to remove existing socket: %s", err))
|
||||
exitCode = 1
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
dir := socketPath[:len(socketPath)-len("/attestation.sock")]
|
||||
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||
logger.Error(fmt.Sprintf("failed to create socket directory: %s", err))
|
||||
exitCode = 1
|
||||
return
|
||||
}
|
||||
|
||||
l, err := net.Listen("unix", socketPath)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("failed to listen on socket: %s", err))
|
||||
exitCode = 1
|
||||
return
|
||||
}
|
||||
|
||||
if err := os.Chmod(socketPath, 0o777); err != nil {
|
||||
logger.Error(fmt.Sprintf("failed to chmod socket: %s", err))
|
||||
exitCode = 1
|
||||
return
|
||||
}
|
||||
|
||||
grpcServer := grpc.NewServer()
|
||||
svc := &service{
|
||||
provider: provider,
|
||||
logger: logger,
|
||||
}
|
||||
attestationpb.RegisterAttestationServiceServer(grpcServer, svc)
|
||||
|
||||
g.Go(func() error {
|
||||
ch := make(chan os.Signal, 1)
|
||||
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
|
||||
defer signal.Stop(ch)
|
||||
|
||||
select {
|
||||
case <-ch:
|
||||
logger.Info("Received signal, shutting down...")
|
||||
cancel()
|
||||
grpcServer.GracefulStop()
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
})
|
||||
|
||||
g.Go(func() error {
|
||||
logger.Info(fmt.Sprintf("%s started on %s", svcName, socketPath))
|
||||
return grpcServer.Serve(l)
|
||||
})
|
||||
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("%s terminated: %s", svcName, err))
|
||||
}
|
||||
}
|
||||
|
||||
type service struct {
|
||||
attestationpb.UnimplementedAttestationServiceServer
|
||||
provider attestation.Provider
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func (s *service) FetchAttestation(ctx context.Context, req *attestationpb.AttestationRequest) (*attestationpb.AttestationResponse, error) {
|
||||
var quote []byte
|
||||
var err error
|
||||
|
||||
switch req.PlatformType {
|
||||
case attestationpb.PlatformType_PLATFORM_TYPE_SNP, attestationpb.PlatformType_PLATFORM_TYPE_TDX:
|
||||
var reportData [64]byte
|
||||
copy(reportData[:], req.ReportData)
|
||||
quote, err = s.provider.TeeAttestation(reportData[:])
|
||||
case attestationpb.PlatformType_PLATFORM_TYPE_VTPM:
|
||||
var nonce [32]byte
|
||||
copy(nonce[:], req.Nonce)
|
||||
quote, err = s.provider.VTpmAttestation(nonce[:])
|
||||
case attestationpb.PlatformType_PLATFORM_TYPE_SNP_VTPM:
|
||||
var reportData [64]byte
|
||||
copy(reportData[:], req.ReportData)
|
||||
var nonce [32]byte
|
||||
copy(nonce[:], req.Nonce)
|
||||
quote, err = s.provider.Attestation(reportData[:], nonce[:])
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported platform type")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &attestationpb.AttestationResponse{Quote: quote}, nil
|
||||
}
|
||||
|
||||
func (s *service) GetAzureToken(ctx context.Context, req *attestationpb.AzureTokenRequest) (*attestationpb.AzureTokenResponse, error) {
|
||||
var nonce [32]byte
|
||||
copy(nonce[:], req.Nonce)
|
||||
token, err := s.provider.AzureAttestationToken(nonce[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &attestationpb.AzureTokenResponse{Token: token}, nil
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
source "$BR2_EXTERNAL_COCOS_PATH/package/agent/Config.in"
|
||||
source "$BR2_EXTERNAL_COCOS_PATH/package/attestation-service/Config.in"
|
||||
source "$BR2_EXTERNAL_COCOS_PATH/package/wasmedge/Config.in"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
config BR2_PACKAGE_AGENT
|
||||
bool "agent"
|
||||
default y
|
||||
select BR2_PACKAGE_ATTESTATION_SERVICE
|
||||
help
|
||||
Confidential Computing Agent is a state machine capable of
|
||||
receiving datasets and algorithm, running computations, and
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
config BR2_PACKAGE_ATTESTATION_SERVICE
|
||||
bool "attestation-service"
|
||||
help
|
||||
Attestation Service for confidential computing attestation.
|
||||
|
||||
https://github.com/ultravioletrs/cocos
|
||||
@@ -0,0 +1,23 @@
|
||||
################################################################################
|
||||
#
|
||||
# attestation-service
|
||||
#
|
||||
################################################################################
|
||||
|
||||
ATTESTATION_SERVICE_VERSION = main
|
||||
ATTESTATION_SERVICE_SITE = $(call github,ultravioletrs,cocos,$(ATTESTATION_SERVICE_VERSION))
|
||||
|
||||
define ATTESTATION_SERVICE_BUILD_CMDS
|
||||
$(MAKE) -C $(@D) attestation-service
|
||||
endef
|
||||
|
||||
define ATTESTATION_SERVICE_INSTALL_TARGET_CMDS
|
||||
$(INSTALL) -D -m 0755 $(@D)/build/cocos-attestation-service $(TARGET_DIR)/usr/bin/attestation-service
|
||||
endef
|
||||
|
||||
define ATTESTATION_SERVICE_INSTALL_INIT_SYSTEMD
|
||||
$(INSTALL) -D -m 0640 $(@D)/init/systemd/attestation-service.service $(TARGET_DIR)/usr/lib/systemd/system/attestation-service.service
|
||||
$(INSTALL) -D -m 0750 $(@D)/init/systemd/attestation_setup.sh $(TARGET_DIR)/cocos_init/attestation_setup.sh
|
||||
endef
|
||||
|
||||
$(eval $(generic-package))
|
||||
@@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=Cocos Attestation Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/attestation-service
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
Environment=ATTESTATION_LOG_LEVEL=debug
|
||||
Environment=ATTESTATION_SERVICE_SOCKET=/run/cocos/attestation.sock
|
||||
Environment=ATTESTATION_VMPL=2
|
||||
ExecStartPre=/cocos_init/attestation_setup.sh
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Setup permissions for attestation socket directory
|
||||
mkdir -p /run/cocos
|
||||
chmod 755 /run/cocos
|
||||
@@ -1,6 +1,7 @@
|
||||
[Unit]
|
||||
Description=Cocos AI agent
|
||||
After=network.target
|
||||
After=network.target attestation-service.service
|
||||
Requires=attestation-service.service
|
||||
Before=docker.service
|
||||
|
||||
[Service]
|
||||
|
||||
@@ -0,0 +1,362 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.8
|
||||
// protoc v6.33.1
|
||||
// source: internal/proto/attestation/v1/attestation.proto
|
||||
|
||||
package attestation
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type PlatformType int32
|
||||
|
||||
const (
|
||||
PlatformType_PLATFORM_TYPE_UNSPECIFIED PlatformType = 0
|
||||
PlatformType_PLATFORM_TYPE_SNP PlatformType = 1
|
||||
PlatformType_PLATFORM_TYPE_TDX PlatformType = 2
|
||||
PlatformType_PLATFORM_TYPE_VTPM PlatformType = 3
|
||||
PlatformType_PLATFORM_TYPE_SNP_VTPM PlatformType = 4
|
||||
PlatformType_PLATFORM_TYPE_AZURE PlatformType = 5
|
||||
PlatformType_PLATFORM_TYPE_NO_CC PlatformType = 6
|
||||
)
|
||||
|
||||
// Enum value maps for PlatformType.
|
||||
var (
|
||||
PlatformType_name = map[int32]string{
|
||||
0: "PLATFORM_TYPE_UNSPECIFIED",
|
||||
1: "PLATFORM_TYPE_SNP",
|
||||
2: "PLATFORM_TYPE_TDX",
|
||||
3: "PLATFORM_TYPE_VTPM",
|
||||
4: "PLATFORM_TYPE_SNP_VTPM",
|
||||
5: "PLATFORM_TYPE_AZURE",
|
||||
6: "PLATFORM_TYPE_NO_CC",
|
||||
}
|
||||
PlatformType_value = map[string]int32{
|
||||
"PLATFORM_TYPE_UNSPECIFIED": 0,
|
||||
"PLATFORM_TYPE_SNP": 1,
|
||||
"PLATFORM_TYPE_TDX": 2,
|
||||
"PLATFORM_TYPE_VTPM": 3,
|
||||
"PLATFORM_TYPE_SNP_VTPM": 4,
|
||||
"PLATFORM_TYPE_AZURE": 5,
|
||||
"PLATFORM_TYPE_NO_CC": 6,
|
||||
}
|
||||
)
|
||||
|
||||
func (x PlatformType) Enum() *PlatformType {
|
||||
p := new(PlatformType)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x PlatformType) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (PlatformType) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_internal_proto_attestation_v1_attestation_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (PlatformType) Type() protoreflect.EnumType {
|
||||
return &file_internal_proto_attestation_v1_attestation_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x PlatformType) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PlatformType.Descriptor instead.
|
||||
func (PlatformType) EnumDescriptor() ([]byte, []int) {
|
||||
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type AttestationRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ReportData []byte `protobuf:"bytes,1,opt,name=report_data,json=reportData,proto3" json:"report_data,omitempty"` // 64 bytes for SNP/TDX
|
||||
Nonce []byte `protobuf:"bytes,2,opt,name=nonce,proto3" json:"nonce,omitempty"` // Nonce for vTPM
|
||||
PlatformType PlatformType `protobuf:"varint,3,opt,name=platform_type,json=platformType,proto3,enum=attestation.v1.PlatformType" json:"platform_type,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AttestationRequest) Reset() {
|
||||
*x = AttestationRequest{}
|
||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AttestationRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AttestationRequest) ProtoMessage() {}
|
||||
|
||||
func (x *AttestationRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AttestationRequest.ProtoReflect.Descriptor instead.
|
||||
func (*AttestationRequest) Descriptor() ([]byte, []int) {
|
||||
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *AttestationRequest) GetReportData() []byte {
|
||||
if x != nil {
|
||||
return x.ReportData
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *AttestationRequest) GetNonce() []byte {
|
||||
if x != nil {
|
||||
return x.Nonce
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *AttestationRequest) GetPlatformType() PlatformType {
|
||||
if x != nil {
|
||||
return x.PlatformType
|
||||
}
|
||||
return PlatformType_PLATFORM_TYPE_UNSPECIFIED
|
||||
}
|
||||
|
||||
type AttestationResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Quote []byte `protobuf:"bytes,1,opt,name=quote,proto3" json:"quote,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AttestationResponse) Reset() {
|
||||
*x = AttestationResponse{}
|
||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AttestationResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AttestationResponse) ProtoMessage() {}
|
||||
|
||||
func (x *AttestationResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AttestationResponse.ProtoReflect.Descriptor instead.
|
||||
func (*AttestationResponse) Descriptor() ([]byte, []int) {
|
||||
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *AttestationResponse) GetQuote() []byte {
|
||||
if x != nil {
|
||||
return x.Quote
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AzureTokenRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Nonce []byte `protobuf:"bytes,1,opt,name=nonce,proto3" json:"nonce,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AzureTokenRequest) Reset() {
|
||||
*x = AzureTokenRequest{}
|
||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AzureTokenRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AzureTokenRequest) ProtoMessage() {}
|
||||
|
||||
func (x *AzureTokenRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AzureTokenRequest.ProtoReflect.Descriptor instead.
|
||||
func (*AzureTokenRequest) Descriptor() ([]byte, []int) {
|
||||
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *AzureTokenRequest) GetNonce() []byte {
|
||||
if x != nil {
|
||||
return x.Nonce
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AzureTokenResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Token []byte `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AzureTokenResponse) Reset() {
|
||||
*x = AzureTokenResponse{}
|
||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AzureTokenResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AzureTokenResponse) ProtoMessage() {}
|
||||
|
||||
func (x *AzureTokenResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AzureTokenResponse.ProtoReflect.Descriptor instead.
|
||||
func (*AzureTokenResponse) Descriptor() ([]byte, []int) {
|
||||
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *AzureTokenResponse) GetToken() []byte {
|
||||
if x != nil {
|
||||
return x.Token
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_internal_proto_attestation_v1_attestation_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_internal_proto_attestation_v1_attestation_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"/internal/proto/attestation/v1/attestation.proto\x12\x0eattestation.v1\"\x8e\x01\n" +
|
||||
"\x12AttestationRequest\x12\x1f\n" +
|
||||
"\vreport_data\x18\x01 \x01(\fR\n" +
|
||||
"reportData\x12\x14\n" +
|
||||
"\x05nonce\x18\x02 \x01(\fR\x05nonce\x12A\n" +
|
||||
"\rplatform_type\x18\x03 \x01(\x0e2\x1c.attestation.v1.PlatformTypeR\fplatformType\"+\n" +
|
||||
"\x13AttestationResponse\x12\x14\n" +
|
||||
"\x05quote\x18\x01 \x01(\fR\x05quote\")\n" +
|
||||
"\x11AzureTokenRequest\x12\x14\n" +
|
||||
"\x05nonce\x18\x01 \x01(\fR\x05nonce\"*\n" +
|
||||
"\x12AzureTokenResponse\x12\x14\n" +
|
||||
"\x05token\x18\x01 \x01(\fR\x05token*\xc1\x01\n" +
|
||||
"\fPlatformType\x12\x1d\n" +
|
||||
"\x19PLATFORM_TYPE_UNSPECIFIED\x10\x00\x12\x15\n" +
|
||||
"\x11PLATFORM_TYPE_SNP\x10\x01\x12\x15\n" +
|
||||
"\x11PLATFORM_TYPE_TDX\x10\x02\x12\x16\n" +
|
||||
"\x12PLATFORM_TYPE_VTPM\x10\x03\x12\x1a\n" +
|
||||
"\x16PLATFORM_TYPE_SNP_VTPM\x10\x04\x12\x17\n" +
|
||||
"\x13PLATFORM_TYPE_AZURE\x10\x05\x12\x17\n" +
|
||||
"\x13PLATFORM_TYPE_NO_CC\x10\x062\xcb\x01\n" +
|
||||
"\x12AttestationService\x12[\n" +
|
||||
"\x10FetchAttestation\x12\".attestation.v1.AttestationRequest\x1a#.attestation.v1.AttestationResponse\x12X\n" +
|
||||
"\x0fFetchAzureToken\x12!.attestation.v1.AzureTokenRequest\x1a\".attestation.v1.AzureTokenResponseBJZHgithub.com/ultravioletrs/cocos/internal/proto/attestation/v1;attestationb\x06proto3"
|
||||
|
||||
var (
|
||||
file_internal_proto_attestation_v1_attestation_proto_rawDescOnce sync.Once
|
||||
file_internal_proto_attestation_v1_attestation_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP() []byte {
|
||||
file_internal_proto_attestation_v1_attestation_proto_rawDescOnce.Do(func() {
|
||||
file_internal_proto_attestation_v1_attestation_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_internal_proto_attestation_v1_attestation_proto_rawDesc), len(file_internal_proto_attestation_v1_attestation_proto_rawDesc)))
|
||||
})
|
||||
return file_internal_proto_attestation_v1_attestation_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_internal_proto_attestation_v1_attestation_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_internal_proto_attestation_v1_attestation_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_internal_proto_attestation_v1_attestation_proto_goTypes = []any{
|
||||
(PlatformType)(0), // 0: attestation.v1.PlatformType
|
||||
(*AttestationRequest)(nil), // 1: attestation.v1.AttestationRequest
|
||||
(*AttestationResponse)(nil), // 2: attestation.v1.AttestationResponse
|
||||
(*AzureTokenRequest)(nil), // 3: attestation.v1.AzureTokenRequest
|
||||
(*AzureTokenResponse)(nil), // 4: attestation.v1.AzureTokenResponse
|
||||
}
|
||||
var file_internal_proto_attestation_v1_attestation_proto_depIdxs = []int32{
|
||||
0, // 0: attestation.v1.AttestationRequest.platform_type:type_name -> attestation.v1.PlatformType
|
||||
1, // 1: attestation.v1.AttestationService.FetchAttestation:input_type -> attestation.v1.AttestationRequest
|
||||
3, // 2: attestation.v1.AttestationService.FetchAzureToken:input_type -> attestation.v1.AzureTokenRequest
|
||||
2, // 3: attestation.v1.AttestationService.FetchAttestation:output_type -> attestation.v1.AttestationResponse
|
||||
4, // 4: attestation.v1.AttestationService.FetchAzureToken:output_type -> attestation.v1.AzureTokenResponse
|
||||
3, // [3:5] is the sub-list for method output_type
|
||||
1, // [1:3] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_internal_proto_attestation_v1_attestation_proto_init() }
|
||||
func file_internal_proto_attestation_v1_attestation_proto_init() {
|
||||
if File_internal_proto_attestation_v1_attestation_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_internal_proto_attestation_v1_attestation_proto_rawDesc), len(file_internal_proto_attestation_v1_attestation_proto_rawDesc)),
|
||||
NumEnums: 1,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_internal_proto_attestation_v1_attestation_proto_goTypes,
|
||||
DependencyIndexes: file_internal_proto_attestation_v1_attestation_proto_depIdxs,
|
||||
EnumInfos: file_internal_proto_attestation_v1_attestation_proto_enumTypes,
|
||||
MessageInfos: file_internal_proto_attestation_v1_attestation_proto_msgTypes,
|
||||
}.Build()
|
||||
File_internal_proto_attestation_v1_attestation_proto = out.File
|
||||
file_internal_proto_attestation_v1_attestation_proto_goTypes = nil
|
||||
file_internal_proto_attestation_v1_attestation_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package attestation.v1;
|
||||
|
||||
option go_package = "github.com/ultravioletrs/cocos/internal/proto/attestation/v1;attestation";
|
||||
|
||||
service AttestationService {
|
||||
rpc FetchAttestation (AttestationRequest) returns (AttestationResponse);
|
||||
rpc FetchAzureToken (AzureTokenRequest) returns (AzureTokenResponse);
|
||||
}
|
||||
|
||||
message AttestationRequest {
|
||||
bytes report_data = 1; // 64 bytes for SNP/TDX
|
||||
bytes nonce = 2; // Nonce for vTPM
|
||||
PlatformType platform_type = 3;
|
||||
}
|
||||
|
||||
message AttestationResponse {
|
||||
bytes quote = 1;
|
||||
}
|
||||
|
||||
message AzureTokenRequest {
|
||||
bytes nonce = 1;
|
||||
}
|
||||
|
||||
message AzureTokenResponse {
|
||||
bytes token = 1;
|
||||
}
|
||||
|
||||
enum PlatformType {
|
||||
PLATFORM_TYPE_UNSPECIFIED = 0;
|
||||
PLATFORM_TYPE_SNP = 1;
|
||||
PLATFORM_TYPE_TDX = 2;
|
||||
PLATFORM_TYPE_VTPM = 3;
|
||||
PLATFORM_TYPE_SNP_VTPM = 4;
|
||||
PLATFORM_TYPE_AZURE = 5;
|
||||
PLATFORM_TYPE_NO_CC = 6;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc v6.33.1
|
||||
// source: internal/proto/attestation/v1/attestation.proto
|
||||
|
||||
package attestation
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
AttestationService_FetchAttestation_FullMethodName = "/attestation.v1.AttestationService/FetchAttestation"
|
||||
AttestationService_FetchAzureToken_FullMethodName = "/attestation.v1.AttestationService/FetchAzureToken"
|
||||
)
|
||||
|
||||
// AttestationServiceClient is the client API for AttestationService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type AttestationServiceClient interface {
|
||||
FetchAttestation(ctx context.Context, in *AttestationRequest, opts ...grpc.CallOption) (*AttestationResponse, error)
|
||||
FetchAzureToken(ctx context.Context, in *AzureTokenRequest, opts ...grpc.CallOption) (*AzureTokenResponse, error)
|
||||
}
|
||||
|
||||
type attestationServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewAttestationServiceClient(cc grpc.ClientConnInterface) AttestationServiceClient {
|
||||
return &attestationServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *attestationServiceClient) FetchAttestation(ctx context.Context, in *AttestationRequest, opts ...grpc.CallOption) (*AttestationResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(AttestationResponse)
|
||||
err := c.cc.Invoke(ctx, AttestationService_FetchAttestation_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *attestationServiceClient) FetchAzureToken(ctx context.Context, in *AzureTokenRequest, opts ...grpc.CallOption) (*AzureTokenResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(AzureTokenResponse)
|
||||
err := c.cc.Invoke(ctx, AttestationService_FetchAzureToken_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// AttestationServiceServer is the server API for AttestationService service.
|
||||
// All implementations must embed UnimplementedAttestationServiceServer
|
||||
// for forward compatibility.
|
||||
type AttestationServiceServer interface {
|
||||
FetchAttestation(context.Context, *AttestationRequest) (*AttestationResponse, error)
|
||||
FetchAzureToken(context.Context, *AzureTokenRequest) (*AzureTokenResponse, error)
|
||||
mustEmbedUnimplementedAttestationServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedAttestationServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedAttestationServiceServer struct{}
|
||||
|
||||
func (UnimplementedAttestationServiceServer) FetchAttestation(context.Context, *AttestationRequest) (*AttestationResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method FetchAttestation not implemented")
|
||||
}
|
||||
func (UnimplementedAttestationServiceServer) FetchAzureToken(context.Context, *AzureTokenRequest) (*AzureTokenResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method FetchAzureToken not implemented")
|
||||
}
|
||||
func (UnimplementedAttestationServiceServer) mustEmbedUnimplementedAttestationServiceServer() {}
|
||||
func (UnimplementedAttestationServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeAttestationServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to AttestationServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeAttestationServiceServer interface {
|
||||
mustEmbedUnimplementedAttestationServiceServer()
|
||||
}
|
||||
|
||||
func RegisterAttestationServiceServer(s grpc.ServiceRegistrar, srv AttestationServiceServer) {
|
||||
// If the following call pancis, it indicates UnimplementedAttestationServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&AttestationService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _AttestationService_FetchAttestation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AttestationRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AttestationServiceServer).FetchAttestation(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: AttestationService_FetchAttestation_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AttestationServiceServer).FetchAttestation(ctx, req.(*AttestationRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _AttestationService_FetchAzureToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AzureTokenRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AttestationServiceServer).FetchAzureToken(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: AttestationService_FetchAzureToken_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AttestationServiceServer).FetchAzureToken(ctx, req.(*AzureTokenRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// AttestationService_ServiceDesc is the grpc.ServiceDesc for AttestationService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var AttestationService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "attestation.v1.AttestationService",
|
||||
HandlerType: (*AttestationServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "FetchAttestation",
|
||||
Handler: _AttestationService_FetchAttestation_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "FetchAzureToken",
|
||||
Handler: _AttestationService_FetchAzureToken_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "internal/proto/attestation/v1/attestation.proto",
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build !test
|
||||
// +build !test
|
||||
|
||||
package api
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build !test
|
||||
// +build !test
|
||||
|
||||
package api
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build !embed
|
||||
// +build !embed
|
||||
|
||||
package manager
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build embed
|
||||
// +build embed
|
||||
|
||||
package manager
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.8
|
||||
// protoc v5.29.0
|
||||
// protoc v6.33.1
|
||||
// source: manager/manager.proto
|
||||
|
||||
package manager
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc v5.29.0
|
||||
// - protoc v6.33.1
|
||||
// source: manager/manager.proto
|
||||
|
||||
package manager
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build !embed
|
||||
// +build !embed
|
||||
|
||||
package quoteprovider
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build !embed
|
||||
// +build !embed
|
||||
|
||||
package quoteprovider
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build !embed
|
||||
// +build !embed
|
||||
|
||||
package tdx
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) Ultraviolet
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
package attestation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
attestation_v1 "github.com/ultravioletrs/cocos/internal/proto/attestation/v1"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
type Client interface {
|
||||
GetAttestation(ctx context.Context, reportData [64]byte, nonce [32]byte, attType attestation.PlatformType) ([]byte, error)
|
||||
GetAzureToken(ctx context.Context, nonce [32]byte) ([]byte, error)
|
||||
Close() error
|
||||
}
|
||||
|
||||
type client struct {
|
||||
conn *grpc.ClientConn
|
||||
client attestation_v1.AttestationServiceClient
|
||||
}
|
||||
|
||||
func NewClient(socketPath string) (Client, error) {
|
||||
conn, err := grpc.NewClient("unix://"+socketPath, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &client{
|
||||
conn: conn,
|
||||
client: attestation_v1.NewAttestationServiceClient(conn),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *client) Close() error {
|
||||
return c.conn.Close()
|
||||
}
|
||||
|
||||
func (c *client) GetAttestation(ctx context.Context, reportData [64]byte, nonce [32]byte, attType attestation.PlatformType) ([]byte, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var platformType attestation_v1.PlatformType
|
||||
switch attType {
|
||||
case attestation.SNP:
|
||||
platformType = attestation_v1.PlatformType_PLATFORM_TYPE_SNP
|
||||
case attestation.TDX:
|
||||
platformType = attestation_v1.PlatformType_PLATFORM_TYPE_TDX
|
||||
case attestation.VTPM:
|
||||
platformType = attestation_v1.PlatformType_PLATFORM_TYPE_VTPM
|
||||
case attestation.SNPvTPM:
|
||||
platformType = attestation_v1.PlatformType_PLATFORM_TYPE_SNP_VTPM
|
||||
default:
|
||||
platformType = attestation_v1.PlatformType_PLATFORM_TYPE_UNSPECIFIED
|
||||
}
|
||||
|
||||
req := &attestation_v1.AttestationRequest{
|
||||
ReportData: reportData[:],
|
||||
Nonce: nonce[:],
|
||||
PlatformType: platformType,
|
||||
}
|
||||
|
||||
resp, err := c.client.FetchAttestation(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.Quote, nil
|
||||
}
|
||||
|
||||
func (c *client) GetAzureToken(ctx context.Context, nonce [32]byte) ([]byte, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
req := &attestation_v1.AzureTokenRequest{
|
||||
Nonce: nonce[:],
|
||||
}
|
||||
|
||||
resp, err := c.client.FetchAzureToken(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.Token, nil
|
||||
}
|
||||
@@ -8,7 +8,7 @@ mkdir -p "$BUILD_DIR"
|
||||
|
||||
# Define the target directory for cloning inside the build directory
|
||||
TARGET_DIR="$BUILD_DIR/svsm"
|
||||
SUBDIR="igvmmeasure"
|
||||
SUBDIR="tools/igvmmeasure"
|
||||
|
||||
# Clone the repository if it doesn't exist
|
||||
if [ -d "$TARGET_DIR" ]; then
|
||||
|
||||
Reference in New Issue
Block a user