mirror of
https://github.com/ultravioletrs/cocos.git
synced 2026-08-07 07:14:50 +00:00
13f7e97d82
CI / checkproto (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (agent) (push) Has been cancelled
CI / test (cli) (push) Has been cancelled
CI / test (cmd) (push) Has been cancelled
CI / test (internal) (push) Has been cancelled
CI / test (manager, true) (push) Has been cancelled
CI / test (pkg) (push) Has been cancelled
CI / upload-coverage (push) Has been cancelled
* feat: add FetchKbsToken RPC support, update protobuf generation, and include additional binaries in CI workflow. Signed-off-by: Sammy Oina <sammyoina@gmail.com> * chore: update protoc version and add GetKbsToken mock method with updated kbsHTTPGet signature Signed-off-by: Sammy Oina <sammyoina@gmail.com> * test: inject mock attestation client into agentService for resource and KBS tests Signed-off-by: Sammy Oina <sammyoina@gmail.com> * test: update key derivation in tests to use Concat KDF instead of HKDF Signed-off-by: Sammy Oina <sammyoina@gmail.com> --------- Signed-off-by: Sammy Oina <sammyoina@gmail.com>
150 lines
4.7 KiB
Go
150 lines
4.7 KiB
Go
// Copyright (c) Ultraviolet
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
package ccaa
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
attestation_agent "github.com/ultravioletrs/cocos/internal/proto/attestation-agent"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials/insecure"
|
|
)
|
|
|
|
// Provider implements attestation.Provider interface by delegating to CC attestation-agent.
|
|
type Provider struct {
|
|
client attestation_agent.AttestationAgentServiceClient
|
|
conn *grpc.ClientConn
|
|
addr string
|
|
}
|
|
|
|
// NewProvider creates a new CC attestation-agent provider.
|
|
// addr should be in the format "host:port" (e.g., "127.0.0.1:50002").
|
|
func NewProvider(addr string) (*Provider, error) {
|
|
conn, err := grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to connect to CC attestation-agent at %s: %w", addr, err)
|
|
}
|
|
|
|
client := attestation_agent.NewAttestationAgentServiceClient(conn)
|
|
|
|
// Test connection by getting TEE type
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
_, err = client.GetTeeType(ctx, &attestation_agent.GetTeeTypeRequest{})
|
|
if err != nil {
|
|
conn.Close()
|
|
return nil, fmt.Errorf("failed to verify CC attestation-agent connection: %w", err)
|
|
}
|
|
|
|
return &Provider{
|
|
client: client,
|
|
conn: conn,
|
|
addr: addr,
|
|
}, nil
|
|
}
|
|
|
|
// Close closes the gRPC connection to CC attestation-agent.
|
|
func (p *Provider) Close() error {
|
|
if p.conn != nil {
|
|
return p.conn.Close()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// TeeAttestation retrieves TEE attestation evidence using report data.
|
|
// For TDX/SNP, reportData should be 64 bytes.
|
|
func (p *Provider) TeeAttestation(reportData []byte) ([]byte, error) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
resp, err := p.client.GetEvidence(ctx, &attestation_agent.GetEvidenceRequest{
|
|
RuntimeData: reportData,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("CC attestation-agent GetEvidence failed: %w", err)
|
|
}
|
|
|
|
return resp.Evidence, nil
|
|
}
|
|
|
|
// VTpmAttestation retrieves vTPM attestation evidence using nonce.
|
|
// For vTPM, nonce should be 32 bytes.
|
|
func (p *Provider) VTpmAttestation(nonce []byte) ([]byte, error) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
resp, err := p.client.GetEvidence(ctx, &attestation_agent.GetEvidenceRequest{
|
|
RuntimeData: nonce,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("CC attestation-agent GetEvidence failed: %w", err)
|
|
}
|
|
|
|
return resp.Evidence, nil
|
|
}
|
|
|
|
// Attestation retrieves combined attestation evidence using both report data and nonce.
|
|
// This is used for SNP+vTPM scenarios.
|
|
func (p *Provider) Attestation(reportData []byte, nonce []byte) ([]byte, error) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Combine reportData and nonce into RuntimeData
|
|
runtimeData := append(reportData, nonce...)
|
|
|
|
resp, err := p.client.GetEvidence(ctx, &attestation_agent.GetEvidenceRequest{
|
|
RuntimeData: runtimeData,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("CC attestation-agent GetEvidence failed: %w", err)
|
|
}
|
|
|
|
return resp.Evidence, nil
|
|
}
|
|
|
|
// AzureAttestationToken retrieves Azure-specific attestation token.
|
|
// Note: CC attestation-agent may not support Azure tokens in the same way.
|
|
// This implementation attempts to use GetToken with "Azure" token type.
|
|
func (p *Provider) AzureAttestationToken(nonce []byte) ([]byte, error) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Try to get Azure token via GetToken method
|
|
resp, err := p.client.GetToken(ctx, &attestation_agent.GetTokenRequest{
|
|
TokenType: "Azure",
|
|
})
|
|
if err != nil {
|
|
// Fallback: try GetEvidence with nonce
|
|
evidenceResp, evidenceErr := p.client.GetEvidence(ctx, &attestation_agent.GetEvidenceRequest{
|
|
RuntimeData: nonce,
|
|
})
|
|
if evidenceErr != nil {
|
|
return nil, fmt.Errorf("CC attestation-agent Azure token not supported: GetToken failed: %w, GetEvidence fallback failed: %v", err, evidenceErr)
|
|
}
|
|
return evidenceResp.Evidence, nil
|
|
}
|
|
|
|
return resp.Token, nil
|
|
}
|
|
|
|
// KbsToken retrieves the official KBS-signed token from the attestation agent.
|
|
func (p *Provider) KbsToken() ([]byte, error) {
|
|
fmt.Println("[CCAA-PROVIDER] KbsToken called, querying attestation-agent...")
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
resp, err := p.client.GetToken(ctx, &attestation_agent.GetTokenRequest{
|
|
TokenType: "kbs",
|
|
})
|
|
if err != nil {
|
|
fmt.Printf("[CCAA-PROVIDER] GetToken failed: %v\n", err)
|
|
return nil, fmt.Errorf("CC attestation-agent GetToken failed for kbs: %w", err)
|
|
}
|
|
|
|
fmt.Printf("[CCAA-PROVIDER] GetToken succeeded! Return raw JSON message, len: %d\n", len(resp.Token))
|
|
return resp.Token, nil
|
|
}
|