mirror of
https://github.com/ultravioletrs/cocos.git
synced 2026-08-07 07:14:50 +00:00
NOISSUE - Add FetchKbsToken RPC support, update protobuf generation, and include additional binaries in CI workflow. (#610)
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
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>
This commit is contained in:
committed by
GitHub
parent
cbf2a44c6a
commit
13f7e97d82
@@ -34,7 +34,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up protoc
|
- name: Set up protoc
|
||||||
run: |
|
run: |
|
||||||
PROTOC_VERSION=33.1
|
PROTOC_VERSION=35.0
|
||||||
PROTOC_GEN_VERSION=v1.36.11
|
PROTOC_GEN_VERSION=v1.36.11
|
||||||
PROTOC_GRPC_VERSION=v1.6.0
|
PROTOC_GRPC_VERSION=v1.6.0
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ jobs:
|
|||||||
- name: Checkout cocos
|
- name: Checkout cocos
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: "ultravioletrs/cocos"
|
|
||||||
path: cocos
|
path: cocos
|
||||||
|
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
@@ -78,6 +77,12 @@ jobs:
|
|||||||
files: |
|
files: |
|
||||||
buildroot/output/images/bzImage
|
buildroot/output/images/bzImage
|
||||||
buildroot/output/images/rootfs.cpio.gz
|
buildroot/output/images/rootfs.cpio.gz
|
||||||
cocos/build/cocos-agent
|
cocos/build/cocos-agent
|
||||||
cocos/build/cocos-cli
|
cocos/build/cocos-cli
|
||||||
cocos/build/cocos-manager
|
cocos/build/cocos-manager
|
||||||
|
cocos/build/cocos-attestation-service
|
||||||
|
cocos/build/cocos-log-forwarder
|
||||||
|
cocos/build/cocos-computation-runner
|
||||||
|
cocos/build/cocos-egress-proxy
|
||||||
|
cocos/build/cocos-ingress-proxy
|
||||||
|
cocos/build/igvmmeasure
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v6.33.1
|
// protoc v7.35.0
|
||||||
// source: agent/agent.proto
|
// source: agent/agent.proto
|
||||||
|
|
||||||
package agent
|
package agent
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.0
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
// - protoc v6.33.1
|
// - protoc v7.35.0
|
||||||
// source: agent/agent.proto
|
// source: agent/agent.proto
|
||||||
|
|
||||||
package agent
|
package agent
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v6.33.1
|
// protoc v7.35.0
|
||||||
// source: agent/cvms/cvms.proto
|
// source: agent/cvms/cvms.proto
|
||||||
|
|
||||||
package cvms
|
package cvms
|
||||||
@@ -1123,8 +1123,8 @@ func (x *Algorithm) GetKbs() *KBSConfig {
|
|||||||
|
|
||||||
type Source struct {
|
type Source struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // Type of source: "oci-image" (only OCI images supported for CoCo)
|
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // Type of source: "oci-image", "s3", "gcs", "https", "http"
|
||||||
Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` // URL of the OCI image (e.g., docker://registry/repo:tag)
|
Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` // URL of the resource (e.g., docker://registry/repo:tag, s3://bucket/key, https://host/path)
|
||||||
KbsResourcePath string `protobuf:"bytes,3,opt,name=kbs_resource_path,json=kbsResourcePath,proto3" json:"kbs_resource_path,omitempty"` // Path to decryption key in KBS (e.g., "default/key/my-key")
|
KbsResourcePath string `protobuf:"bytes,3,opt,name=kbs_resource_path,json=kbsResourcePath,proto3" json:"kbs_resource_path,omitempty"` // Path to decryption key in KBS (e.g., "default/key/my-key")
|
||||||
Encrypted bool `protobuf:"varint,4,opt,name=encrypted,proto3" json:"encrypted,omitempty"` // Whether the resource is encrypted (requires KBS)
|
Encrypted bool `protobuf:"varint,4,opt,name=encrypted,proto3" json:"encrypted,omitempty"` // Whether the resource is encrypted (requires KBS)
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.0
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
// - protoc v6.33.1
|
// - protoc v7.35.0
|
||||||
// source: agent/cvms/cvms.proto
|
// source: agent/cvms/cvms.proto
|
||||||
|
|
||||||
package cvms
|
package cvms
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v6.33.1
|
// protoc v7.35.0
|
||||||
// source: agent/events/events.proto
|
// source: agent/events/events.proto
|
||||||
|
|
||||||
package events
|
package events
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v6.33.1
|
// protoc v7.35.0
|
||||||
// source: agent/log/log.proto
|
// source: agent/log/log.proto
|
||||||
|
|
||||||
package log
|
package log
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.0
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
// - protoc v6.33.1
|
// - protoc v7.35.0
|
||||||
// source: agent/log/log.proto
|
// source: agent/log/log.proto
|
||||||
|
|
||||||
package log
|
package log
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ func (m *MockAttestationClient) GetAzureToken(ctx context.Context, nonce [32]byt
|
|||||||
return args.Get(0).([]byte), args.Error(1)
|
return args.Get(0).([]byte), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *MockAttestationClient) GetKbsToken(ctx context.Context) ([]byte, error) {
|
||||||
|
args := m.Called(ctx)
|
||||||
|
return args.Get(0).([]byte), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *MockAttestationClient) Close() error {
|
func (m *MockAttestationClient) Close() error {
|
||||||
args := m.Called()
|
args := m.Called()
|
||||||
return args.Error(0)
|
return args.Error(0)
|
||||||
|
|||||||
+11
-3
@@ -51,9 +51,13 @@ func TestDownloadAndDecryptGenericResource(t *testing.T) {
|
|||||||
mockDownloader.On("Type").Return(resource.SourceTypeHTTP)
|
mockDownloader.On("Type").Return(resource.SourceTypeHTTP)
|
||||||
registry.Register(mockDownloader)
|
registry.Register(mockDownloader)
|
||||||
|
|
||||||
|
attestationClient := new(MockAttestationClient)
|
||||||
|
attestationClient.On("GetKbsToken", mock.Anything).Return([]byte("mockToken"), nil).Maybe()
|
||||||
|
|
||||||
svc := &agentService{
|
svc := &agentService{
|
||||||
logger: slog.Default(),
|
logger: slog.Default(),
|
||||||
resourceRegistry: registry,
|
resourceRegistry: registry,
|
||||||
|
attestationClient: attestationClient,
|
||||||
computation: Computation{
|
computation: Computation{
|
||||||
Algorithm: &Algorithm{
|
Algorithm: &Algorithm{
|
||||||
KBS: &KBSConfig{
|
KBS: &KBSConfig{
|
||||||
@@ -122,8 +126,12 @@ func TestDownloadAndDecryptGenericResource(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetKeyFromKBS(t *testing.T) {
|
func TestGetKeyFromKBS(t *testing.T) {
|
||||||
|
attestationClient := new(MockAttestationClient)
|
||||||
|
attestationClient.On("GetKbsToken", mock.Anything).Return([]byte("mockToken"), nil).Maybe()
|
||||||
|
|
||||||
svc := &agentService{
|
svc := &agentService{
|
||||||
logger: slog.Default(),
|
logger: slog.Default(),
|
||||||
|
attestationClient: attestationClient,
|
||||||
computation: Computation{
|
computation: Computation{
|
||||||
Algorithm: &Algorithm{
|
Algorithm: &Algorithm{
|
||||||
KBS: &KBSConfig{
|
KBS: &KBSConfig{
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v6.33.1
|
// protoc v7.35.0
|
||||||
// source: agent/runner/runner.proto
|
// source: agent/runner/runner.proto
|
||||||
|
|
||||||
package runner
|
package runner
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.0
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
// - protoc v6.33.1
|
// - protoc v7.35.0
|
||||||
// source: agent/runner/runner.proto
|
// source: agent/runner/runner.proto
|
||||||
|
|
||||||
package runner
|
package runner
|
||||||
|
|||||||
+78
-8
@@ -5,7 +5,11 @@ package agent
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/ecdh"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/x509"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
@@ -29,6 +33,7 @@ import (
|
|||||||
"github.com/ultravioletrs/cocos/pkg/attestation/vtpm"
|
"github.com/ultravioletrs/cocos/pkg/attestation/vtpm"
|
||||||
attestation_client "github.com/ultravioletrs/cocos/pkg/clients/grpc/attestation"
|
attestation_client "github.com/ultravioletrs/cocos/pkg/clients/grpc/attestation"
|
||||||
runner_client "github.com/ultravioletrs/cocos/pkg/clients/grpc/runner"
|
runner_client "github.com/ultravioletrs/cocos/pkg/clients/grpc/runner"
|
||||||
|
"github.com/ultravioletrs/cocos/pkg/crypto"
|
||||||
"github.com/ultravioletrs/cocos/pkg/oci"
|
"github.com/ultravioletrs/cocos/pkg/oci"
|
||||||
"github.com/ultravioletrs/cocos/pkg/resource"
|
"github.com/ultravioletrs/cocos/pkg/resource"
|
||||||
"golang.org/x/crypto/sha3"
|
"golang.org/x/crypto/sha3"
|
||||||
@@ -762,26 +767,91 @@ func (as *agentService) getKeyFromKBS(ctx context.Context, kbsURL, resourcePath
|
|||||||
|
|
||||||
as.logger.Info("fetching key from KBS", "url", kbsResourceURL)
|
as.logger.Info("fetching key from KBS", "url", kbsResourceURL)
|
||||||
|
|
||||||
// Use a simple HTTP GET to KBS for now.
|
// Fetch token from attestation service via the initialized client
|
||||||
// In a full CoCo deployment, this would go through the Attestation Agent
|
tokenBytes, err := as.attestationClient.GetKbsToken(ctx)
|
||||||
// which performs attestation before KBS releases the key.
|
if err != nil {
|
||||||
// For non-OCI resources, the AA/KBS handshake may need to be handled
|
return nil, fmt.Errorf("failed to retrieve token from attestation service: %w", err)
|
||||||
// differently than via ocicrypt.
|
}
|
||||||
resp, err := kbsHTTPGet(ctx, kbsResourceURL)
|
|
||||||
|
// Unmarshal the JSON from attestation service containing token and private key
|
||||||
|
var msg struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
TeeKeyPair string `json:"tee_keypair"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var token string
|
||||||
|
var teeKeyPairPem string
|
||||||
|
if err := json.Unmarshal(tokenBytes, &msg); err == nil {
|
||||||
|
token = strings.TrimSpace(msg.Token)
|
||||||
|
teeKeyPairPem = msg.TeeKeyPair
|
||||||
|
as.logger.Info("retrieved token and keypair from attestation service successfully")
|
||||||
|
} else {
|
||||||
|
// Fallback for non-JSON token bytes
|
||||||
|
token = strings.TrimSpace(string(tokenBytes))
|
||||||
|
as.logger.Warn("attestation service token is not in JSON format; using raw token without local JWE decryption fallback", "error", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := kbsHTTPGet(ctx, kbsResourceURL, token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to fetch key from KBS at %s: %w", kbsResourceURL, err)
|
return nil, fmt.Errorf("failed to fetch key from KBS at %s: %w", kbsResourceURL, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
// If we don't have a private key, return the response as is (could be plaintext)
|
||||||
|
if teeKeyPairPem == "" {
|
||||||
|
as.logger.Info("no session keypair found, returning KBS response directly")
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse JWE response
|
||||||
|
encryptedRes, err := crypto.ParseEncryptedResource(resp)
|
||||||
|
if err != nil {
|
||||||
|
as.logger.Warn("failed to parse JWE resource response, returning raw response", "error", err)
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse PKCS#8 private key PEM
|
||||||
|
block, _ := pem.Decode([]byte(teeKeyPairPem))
|
||||||
|
if block == nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode private key PEM")
|
||||||
|
}
|
||||||
|
|
||||||
|
privKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse private key PKCS8: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var ecdhKey *ecdh.PrivateKey
|
||||||
|
switch k := privKey.(type) {
|
||||||
|
case *ecdsa.PrivateKey:
|
||||||
|
ecdhKey, err = k.ECDH()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get ECDH private key: %w", err)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("private key is not ECDSA (unsupported curve or type)")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypt JWE resource using the private key
|
||||||
|
decryptedKey, err := crypto.DecryptWithWrappedKey(*encryptedRes, ecdhKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to decrypt KBS resource: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
as.logger.Info("successfully decrypted KBS key", "key_len", len(decryptedKey))
|
||||||
|
return decryptedKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// kbsHTTPGet performs an HTTP GET to the KBS endpoint.
|
// kbsHTTPGet performs an HTTP GET to the KBS endpoint.
|
||||||
func kbsHTTPGet(ctx context.Context, url string) ([]byte, error) {
|
func kbsHTTPGet(ctx context.Context, url string, token string) ([]byte, error) {
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if token != "" {
|
||||||
|
req.Header.Set("Authorization", "Bearer "+token)
|
||||||
|
}
|
||||||
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1893,6 +1893,6 @@ func TestEnsureDir_Error(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestKbsHTTPGet_Error(t *testing.T) {
|
func TestKbsHTTPGet_Error(t *testing.T) {
|
||||||
_, err := kbsHTTPGet(context.Background(), "%%")
|
_, err := kbsHTTPGet(context.Background(), "%%", "")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -409,7 +409,7 @@ func convertPlatformType(pt attestationpb.PlatformType) attestation.PlatformType
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) GetAzureToken(ctx context.Context, req *attestationpb.AzureTokenRequest) (*attestationpb.AzureTokenResponse, error) {
|
func (s *service) FetchAzureToken(ctx context.Context, req *attestationpb.AzureTokenRequest) (*attestationpb.AzureTokenResponse, error) {
|
||||||
var nonce [32]byte
|
var nonce [32]byte
|
||||||
copy(nonce[:], req.Nonce)
|
copy(nonce[:], req.Nonce)
|
||||||
token, err := s.provider.AzureAttestationToken(nonce[:])
|
token, err := s.provider.AzureAttestationToken(nonce[:])
|
||||||
@@ -418,3 +418,14 @@ func (s *service) GetAzureToken(ctx context.Context, req *attestationpb.AzureTok
|
|||||||
}
|
}
|
||||||
return &attestationpb.AzureTokenResponse{Token: token}, nil
|
return &attestationpb.AzureTokenResponse{Token: token}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *service) FetchKbsToken(ctx context.Context, req *attestationpb.KbsTokenRequest) (*attestationpb.KbsTokenResponse, error) {
|
||||||
|
s.logger.Info("[ATTESTATION-SERVICE] FetchKbsToken RPC called")
|
||||||
|
token, err := s.provider.KbsToken()
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Error(fmt.Sprintf("[ATTESTATION-SERVICE] FetchKbsToken failed: %v", err))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s.logger.Info(fmt.Sprintf("[ATTESTATION-SERVICE] FetchKbsToken succeeded, token len: %d", len(token)))
|
||||||
|
return &attestationpb.KbsTokenResponse{Token: token}, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v6.33.1
|
// protoc v7.35.0
|
||||||
// source: internal/proto/attestation-agent/attestation-agent.proto
|
// source: internal/proto/attestation-agent/attestation-agent.proto
|
||||||
|
|
||||||
package attestation_agent
|
package attestation_agent
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.0
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
// - protoc v6.33.1
|
// - protoc v7.35.0
|
||||||
// source: internal/proto/attestation-agent/attestation-agent.proto
|
// source: internal/proto/attestation-agent/attestation-agent.proto
|
||||||
|
|
||||||
package attestation_agent
|
package attestation_agent
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v6.33.1
|
// protoc v7.35.0
|
||||||
// source: internal/proto/attestation/v1/attestation.proto
|
// source: internal/proto/attestation/v1/attestation.proto
|
||||||
|
|
||||||
package attestation
|
package attestation
|
||||||
@@ -82,6 +82,86 @@ func (PlatformType) EnumDescriptor() ([]byte, []int) {
|
|||||||
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{0}
|
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type KbsTokenRequest struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *KbsTokenRequest) Reset() {
|
||||||
|
*x = KbsTokenRequest{}
|
||||||
|
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[0]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *KbsTokenRequest) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*KbsTokenRequest) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *KbsTokenRequest) 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 KbsTokenRequest.ProtoReflect.Descriptor instead.
|
||||||
|
func (*KbsTokenRequest) Descriptor() ([]byte, []int) {
|
||||||
|
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{0}
|
||||||
|
}
|
||||||
|
|
||||||
|
type KbsTokenResponse 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 *KbsTokenResponse) Reset() {
|
||||||
|
*x = KbsTokenResponse{}
|
||||||
|
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[1]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *KbsTokenResponse) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*KbsTokenResponse) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *KbsTokenResponse) 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 KbsTokenResponse.ProtoReflect.Descriptor instead.
|
||||||
|
func (*KbsTokenResponse) Descriptor() ([]byte, []int) {
|
||||||
|
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *KbsTokenResponse) GetToken() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.Token
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type AttestationRequest struct {
|
type AttestationRequest struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
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
|
ReportData []byte `protobuf:"bytes,1,opt,name=report_data,json=reportData,proto3" json:"report_data,omitempty"` // 64 bytes for SNP/TDX
|
||||||
@@ -93,7 +173,7 @@ type AttestationRequest struct {
|
|||||||
|
|
||||||
func (x *AttestationRequest) Reset() {
|
func (x *AttestationRequest) Reset() {
|
||||||
*x = AttestationRequest{}
|
*x = AttestationRequest{}
|
||||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[0]
|
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[2]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -105,7 +185,7 @@ func (x *AttestationRequest) String() string {
|
|||||||
func (*AttestationRequest) ProtoMessage() {}
|
func (*AttestationRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *AttestationRequest) ProtoReflect() protoreflect.Message {
|
func (x *AttestationRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[0]
|
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[2]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -118,7 +198,7 @@ func (x *AttestationRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use AttestationRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use AttestationRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*AttestationRequest) Descriptor() ([]byte, []int) {
|
func (*AttestationRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{0}
|
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{2}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *AttestationRequest) GetReportData() []byte {
|
func (x *AttestationRequest) GetReportData() []byte {
|
||||||
@@ -151,7 +231,7 @@ type AttestationResponse struct {
|
|||||||
|
|
||||||
func (x *AttestationResponse) Reset() {
|
func (x *AttestationResponse) Reset() {
|
||||||
*x = AttestationResponse{}
|
*x = AttestationResponse{}
|
||||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[1]
|
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[3]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -163,7 +243,7 @@ func (x *AttestationResponse) String() string {
|
|||||||
func (*AttestationResponse) ProtoMessage() {}
|
func (*AttestationResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *AttestationResponse) ProtoReflect() protoreflect.Message {
|
func (x *AttestationResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[1]
|
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[3]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -176,7 +256,7 @@ func (x *AttestationResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use AttestationResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use AttestationResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*AttestationResponse) Descriptor() ([]byte, []int) {
|
func (*AttestationResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{1}
|
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{3}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *AttestationResponse) GetEatToken() []byte {
|
func (x *AttestationResponse) GetEatToken() []byte {
|
||||||
@@ -195,7 +275,7 @@ type RawEvidenceResponse struct {
|
|||||||
|
|
||||||
func (x *RawEvidenceResponse) Reset() {
|
func (x *RawEvidenceResponse) Reset() {
|
||||||
*x = RawEvidenceResponse{}
|
*x = RawEvidenceResponse{}
|
||||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[2]
|
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[4]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -207,7 +287,7 @@ func (x *RawEvidenceResponse) String() string {
|
|||||||
func (*RawEvidenceResponse) ProtoMessage() {}
|
func (*RawEvidenceResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *RawEvidenceResponse) ProtoReflect() protoreflect.Message {
|
func (x *RawEvidenceResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[2]
|
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[4]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -220,7 +300,7 @@ func (x *RawEvidenceResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use RawEvidenceResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use RawEvidenceResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*RawEvidenceResponse) Descriptor() ([]byte, []int) {
|
func (*RawEvidenceResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{2}
|
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{4}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RawEvidenceResponse) GetEvidence() []byte {
|
func (x *RawEvidenceResponse) GetEvidence() []byte {
|
||||||
@@ -239,7 +319,7 @@ type AzureTokenRequest struct {
|
|||||||
|
|
||||||
func (x *AzureTokenRequest) Reset() {
|
func (x *AzureTokenRequest) Reset() {
|
||||||
*x = AzureTokenRequest{}
|
*x = AzureTokenRequest{}
|
||||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[3]
|
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[5]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -251,7 +331,7 @@ func (x *AzureTokenRequest) String() string {
|
|||||||
func (*AzureTokenRequest) ProtoMessage() {}
|
func (*AzureTokenRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *AzureTokenRequest) ProtoReflect() protoreflect.Message {
|
func (x *AzureTokenRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[3]
|
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[5]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -264,7 +344,7 @@ func (x *AzureTokenRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use AzureTokenRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use AzureTokenRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*AzureTokenRequest) Descriptor() ([]byte, []int) {
|
func (*AzureTokenRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{3}
|
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{5}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *AzureTokenRequest) GetNonce() []byte {
|
func (x *AzureTokenRequest) GetNonce() []byte {
|
||||||
@@ -283,7 +363,7 @@ type AzureTokenResponse struct {
|
|||||||
|
|
||||||
func (x *AzureTokenResponse) Reset() {
|
func (x *AzureTokenResponse) Reset() {
|
||||||
*x = AzureTokenResponse{}
|
*x = AzureTokenResponse{}
|
||||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[4]
|
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[6]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -295,7 +375,7 @@ func (x *AzureTokenResponse) String() string {
|
|||||||
func (*AzureTokenResponse) ProtoMessage() {}
|
func (*AzureTokenResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *AzureTokenResponse) ProtoReflect() protoreflect.Message {
|
func (x *AzureTokenResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[4]
|
mi := &file_internal_proto_attestation_v1_attestation_proto_msgTypes[6]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -308,7 +388,7 @@ func (x *AzureTokenResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use AzureTokenResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use AzureTokenResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*AzureTokenResponse) Descriptor() ([]byte, []int) {
|
func (*AzureTokenResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{4}
|
return file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP(), []int{6}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *AzureTokenResponse) GetToken() []byte {
|
func (x *AzureTokenResponse) GetToken() []byte {
|
||||||
@@ -322,7 +402,10 @@ var File_internal_proto_attestation_v1_attestation_proto protoreflect.FileDescri
|
|||||||
|
|
||||||
const file_internal_proto_attestation_v1_attestation_proto_rawDesc = "" +
|
const file_internal_proto_attestation_v1_attestation_proto_rawDesc = "" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"/internal/proto/attestation/v1/attestation.proto\x12\x0eattestation.v1\"\x8e\x01\n" +
|
"/internal/proto/attestation/v1/attestation.proto\x12\x0eattestation.v1\"\x11\n" +
|
||||||
|
"\x0fKbsTokenRequest\"(\n" +
|
||||||
|
"\x10KbsTokenResponse\x12\x14\n" +
|
||||||
|
"\x05token\x18\x01 \x01(\fR\x05token\"\x8e\x01\n" +
|
||||||
"\x12AttestationRequest\x12\x1f\n" +
|
"\x12AttestationRequest\x12\x1f\n" +
|
||||||
"\vreport_data\x18\x01 \x01(\fR\n" +
|
"\vreport_data\x18\x01 \x01(\fR\n" +
|
||||||
"reportData\x12\x14\n" +
|
"reportData\x12\x14\n" +
|
||||||
@@ -343,11 +426,12 @@ const file_internal_proto_attestation_v1_attestation_proto_rawDesc = "" +
|
|||||||
"\x12PLATFORM_TYPE_VTPM\x10\x03\x12\x1a\n" +
|
"\x12PLATFORM_TYPE_VTPM\x10\x03\x12\x1a\n" +
|
||||||
"\x16PLATFORM_TYPE_SNP_VTPM\x10\x04\x12\x17\n" +
|
"\x16PLATFORM_TYPE_SNP_VTPM\x10\x04\x12\x17\n" +
|
||||||
"\x13PLATFORM_TYPE_AZURE\x10\x05\x12\x17\n" +
|
"\x13PLATFORM_TYPE_AZURE\x10\x05\x12\x17\n" +
|
||||||
"\x13PLATFORM_TYPE_NO_CC\x10\x062\xa8\x02\n" +
|
"\x13PLATFORM_TYPE_NO_CC\x10\x062\xfc\x02\n" +
|
||||||
"\x12AttestationService\x12[\n" +
|
"\x12AttestationService\x12[\n" +
|
||||||
"\x10FetchAttestation\x12\".attestation.v1.AttestationRequest\x1a#.attestation.v1.AttestationResponse\x12[\n" +
|
"\x10FetchAttestation\x12\".attestation.v1.AttestationRequest\x1a#.attestation.v1.AttestationResponse\x12[\n" +
|
||||||
"\x10FetchRawEvidence\x12\".attestation.v1.AttestationRequest\x1a#.attestation.v1.RawEvidenceResponse\x12X\n" +
|
"\x10FetchRawEvidence\x12\".attestation.v1.AttestationRequest\x1a#.attestation.v1.RawEvidenceResponse\x12X\n" +
|
||||||
"\x0fFetchAzureToken\x12!.attestation.v1.AzureTokenRequest\x1a\".attestation.v1.AzureTokenResponseBJZHgithub.com/ultravioletrs/cocos/internal/proto/attestation/v1;attestationb\x06proto3"
|
"\x0fFetchAzureToken\x12!.attestation.v1.AzureTokenRequest\x1a\".attestation.v1.AzureTokenResponse\x12R\n" +
|
||||||
|
"\rFetchKbsToken\x12\x1f.attestation.v1.KbsTokenRequest\x1a .attestation.v1.KbsTokenResponseBJZHgithub.com/ultravioletrs/cocos/internal/proto/attestation/v1;attestationb\x06proto3"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
file_internal_proto_attestation_v1_attestation_proto_rawDescOnce sync.Once
|
file_internal_proto_attestation_v1_attestation_proto_rawDescOnce sync.Once
|
||||||
@@ -362,25 +446,29 @@ func file_internal_proto_attestation_v1_attestation_proto_rawDescGZIP() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var file_internal_proto_attestation_v1_attestation_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
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, 5)
|
var file_internal_proto_attestation_v1_attestation_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||||
var file_internal_proto_attestation_v1_attestation_proto_goTypes = []any{
|
var file_internal_proto_attestation_v1_attestation_proto_goTypes = []any{
|
||||||
(PlatformType)(0), // 0: attestation.v1.PlatformType
|
(PlatformType)(0), // 0: attestation.v1.PlatformType
|
||||||
(*AttestationRequest)(nil), // 1: attestation.v1.AttestationRequest
|
(*KbsTokenRequest)(nil), // 1: attestation.v1.KbsTokenRequest
|
||||||
(*AttestationResponse)(nil), // 2: attestation.v1.AttestationResponse
|
(*KbsTokenResponse)(nil), // 2: attestation.v1.KbsTokenResponse
|
||||||
(*RawEvidenceResponse)(nil), // 3: attestation.v1.RawEvidenceResponse
|
(*AttestationRequest)(nil), // 3: attestation.v1.AttestationRequest
|
||||||
(*AzureTokenRequest)(nil), // 4: attestation.v1.AzureTokenRequest
|
(*AttestationResponse)(nil), // 4: attestation.v1.AttestationResponse
|
||||||
(*AzureTokenResponse)(nil), // 5: attestation.v1.AzureTokenResponse
|
(*RawEvidenceResponse)(nil), // 5: attestation.v1.RawEvidenceResponse
|
||||||
|
(*AzureTokenRequest)(nil), // 6: attestation.v1.AzureTokenRequest
|
||||||
|
(*AzureTokenResponse)(nil), // 7: attestation.v1.AzureTokenResponse
|
||||||
}
|
}
|
||||||
var file_internal_proto_attestation_v1_attestation_proto_depIdxs = []int32{
|
var file_internal_proto_attestation_v1_attestation_proto_depIdxs = []int32{
|
||||||
0, // 0: attestation.v1.AttestationRequest.platform_type:type_name -> attestation.v1.PlatformType
|
0, // 0: attestation.v1.AttestationRequest.platform_type:type_name -> attestation.v1.PlatformType
|
||||||
1, // 1: attestation.v1.AttestationService.FetchAttestation:input_type -> attestation.v1.AttestationRequest
|
3, // 1: attestation.v1.AttestationService.FetchAttestation:input_type -> attestation.v1.AttestationRequest
|
||||||
1, // 2: attestation.v1.AttestationService.FetchRawEvidence:input_type -> attestation.v1.AttestationRequest
|
3, // 2: attestation.v1.AttestationService.FetchRawEvidence:input_type -> attestation.v1.AttestationRequest
|
||||||
4, // 3: attestation.v1.AttestationService.FetchAzureToken:input_type -> attestation.v1.AzureTokenRequest
|
6, // 3: attestation.v1.AttestationService.FetchAzureToken:input_type -> attestation.v1.AzureTokenRequest
|
||||||
2, // 4: attestation.v1.AttestationService.FetchAttestation:output_type -> attestation.v1.AttestationResponse
|
1, // 4: attestation.v1.AttestationService.FetchKbsToken:input_type -> attestation.v1.KbsTokenRequest
|
||||||
3, // 5: attestation.v1.AttestationService.FetchRawEvidence:output_type -> attestation.v1.RawEvidenceResponse
|
4, // 5: attestation.v1.AttestationService.FetchAttestation:output_type -> attestation.v1.AttestationResponse
|
||||||
5, // 6: attestation.v1.AttestationService.FetchAzureToken:output_type -> attestation.v1.AzureTokenResponse
|
5, // 6: attestation.v1.AttestationService.FetchRawEvidence:output_type -> attestation.v1.RawEvidenceResponse
|
||||||
4, // [4:7] is the sub-list for method output_type
|
7, // 7: attestation.v1.AttestationService.FetchAzureToken:output_type -> attestation.v1.AzureTokenResponse
|
||||||
1, // [1:4] is the sub-list for method input_type
|
2, // 8: attestation.v1.AttestationService.FetchKbsToken:output_type -> attestation.v1.KbsTokenResponse
|
||||||
|
5, // [5:9] is the sub-list for method output_type
|
||||||
|
1, // [1:5] 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 type_name
|
||||||
1, // [1:1] is the sub-list for extension extendee
|
1, // [1:1] is the sub-list for extension extendee
|
||||||
0, // [0:1] is the sub-list for field type_name
|
0, // [0:1] is the sub-list for field type_name
|
||||||
@@ -397,7 +485,7 @@ func file_internal_proto_attestation_v1_attestation_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
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)),
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_internal_proto_attestation_v1_attestation_proto_rawDesc), len(file_internal_proto_attestation_v1_attestation_proto_rawDesc)),
|
||||||
NumEnums: 1,
|
NumEnums: 1,
|
||||||
NumMessages: 5,
|
NumMessages: 7,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,6 +8,13 @@ service AttestationService {
|
|||||||
rpc FetchAttestation (AttestationRequest) returns (AttestationResponse);
|
rpc FetchAttestation (AttestationRequest) returns (AttestationResponse);
|
||||||
rpc FetchRawEvidence (AttestationRequest) returns (RawEvidenceResponse);
|
rpc FetchRawEvidence (AttestationRequest) returns (RawEvidenceResponse);
|
||||||
rpc FetchAzureToken (AzureTokenRequest) returns (AzureTokenResponse);
|
rpc FetchAzureToken (AzureTokenRequest) returns (AzureTokenResponse);
|
||||||
|
rpc FetchKbsToken (KbsTokenRequest) returns (KbsTokenResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message KbsTokenRequest {}
|
||||||
|
|
||||||
|
message KbsTokenResponse {
|
||||||
|
bytes token = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AttestationRequest {
|
message AttestationRequest {
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.0
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
// - protoc v6.33.1
|
// - protoc v7.35.0
|
||||||
// source: internal/proto/attestation/v1/attestation.proto
|
// source: internal/proto/attestation/v1/attestation.proto
|
||||||
|
|
||||||
package attestation
|
package attestation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
context "context"
|
context "context"
|
||||||
|
|
||||||
grpc "google.golang.org/grpc"
|
grpc "google.golang.org/grpc"
|
||||||
codes "google.golang.org/grpc/codes"
|
codes "google.golang.org/grpc/codes"
|
||||||
status "google.golang.org/grpc/status"
|
status "google.golang.org/grpc/status"
|
||||||
@@ -23,6 +22,7 @@ const (
|
|||||||
AttestationService_FetchAttestation_FullMethodName = "/attestation.v1.AttestationService/FetchAttestation"
|
AttestationService_FetchAttestation_FullMethodName = "/attestation.v1.AttestationService/FetchAttestation"
|
||||||
AttestationService_FetchRawEvidence_FullMethodName = "/attestation.v1.AttestationService/FetchRawEvidence"
|
AttestationService_FetchRawEvidence_FullMethodName = "/attestation.v1.AttestationService/FetchRawEvidence"
|
||||||
AttestationService_FetchAzureToken_FullMethodName = "/attestation.v1.AttestationService/FetchAzureToken"
|
AttestationService_FetchAzureToken_FullMethodName = "/attestation.v1.AttestationService/FetchAzureToken"
|
||||||
|
AttestationService_FetchKbsToken_FullMethodName = "/attestation.v1.AttestationService/FetchKbsToken"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AttestationServiceClient is the client API for AttestationService service.
|
// AttestationServiceClient is the client API for AttestationService service.
|
||||||
@@ -32,6 +32,7 @@ type AttestationServiceClient interface {
|
|||||||
FetchAttestation(ctx context.Context, in *AttestationRequest, opts ...grpc.CallOption) (*AttestationResponse, error)
|
FetchAttestation(ctx context.Context, in *AttestationRequest, opts ...grpc.CallOption) (*AttestationResponse, error)
|
||||||
FetchRawEvidence(ctx context.Context, in *AttestationRequest, opts ...grpc.CallOption) (*RawEvidenceResponse, error)
|
FetchRawEvidence(ctx context.Context, in *AttestationRequest, opts ...grpc.CallOption) (*RawEvidenceResponse, error)
|
||||||
FetchAzureToken(ctx context.Context, in *AzureTokenRequest, opts ...grpc.CallOption) (*AzureTokenResponse, error)
|
FetchAzureToken(ctx context.Context, in *AzureTokenRequest, opts ...grpc.CallOption) (*AzureTokenResponse, error)
|
||||||
|
FetchKbsToken(ctx context.Context, in *KbsTokenRequest, opts ...grpc.CallOption) (*KbsTokenResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type attestationServiceClient struct {
|
type attestationServiceClient struct {
|
||||||
@@ -72,6 +73,16 @@ func (c *attestationServiceClient) FetchAzureToken(ctx context.Context, in *Azur
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *attestationServiceClient) FetchKbsToken(ctx context.Context, in *KbsTokenRequest, opts ...grpc.CallOption) (*KbsTokenResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(KbsTokenResponse)
|
||||||
|
err := c.cc.Invoke(ctx, AttestationService_FetchKbsToken_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
// AttestationServiceServer is the server API for AttestationService service.
|
// AttestationServiceServer is the server API for AttestationService service.
|
||||||
// All implementations must embed UnimplementedAttestationServiceServer
|
// All implementations must embed UnimplementedAttestationServiceServer
|
||||||
// for forward compatibility.
|
// for forward compatibility.
|
||||||
@@ -79,6 +90,7 @@ type AttestationServiceServer interface {
|
|||||||
FetchAttestation(context.Context, *AttestationRequest) (*AttestationResponse, error)
|
FetchAttestation(context.Context, *AttestationRequest) (*AttestationResponse, error)
|
||||||
FetchRawEvidence(context.Context, *AttestationRequest) (*RawEvidenceResponse, error)
|
FetchRawEvidence(context.Context, *AttestationRequest) (*RawEvidenceResponse, error)
|
||||||
FetchAzureToken(context.Context, *AzureTokenRequest) (*AzureTokenResponse, error)
|
FetchAzureToken(context.Context, *AzureTokenRequest) (*AzureTokenResponse, error)
|
||||||
|
FetchKbsToken(context.Context, *KbsTokenRequest) (*KbsTokenResponse, error)
|
||||||
mustEmbedUnimplementedAttestationServiceServer()
|
mustEmbedUnimplementedAttestationServiceServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,6 +110,9 @@ func (UnimplementedAttestationServiceServer) FetchRawEvidence(context.Context, *
|
|||||||
func (UnimplementedAttestationServiceServer) FetchAzureToken(context.Context, *AzureTokenRequest) (*AzureTokenResponse, error) {
|
func (UnimplementedAttestationServiceServer) FetchAzureToken(context.Context, *AzureTokenRequest) (*AzureTokenResponse, error) {
|
||||||
return nil, status.Error(codes.Unimplemented, "method FetchAzureToken not implemented")
|
return nil, status.Error(codes.Unimplemented, "method FetchAzureToken not implemented")
|
||||||
}
|
}
|
||||||
|
func (UnimplementedAttestationServiceServer) FetchKbsToken(context.Context, *KbsTokenRequest) (*KbsTokenResponse, error) {
|
||||||
|
return nil, status.Error(codes.Unimplemented, "method FetchKbsToken not implemented")
|
||||||
|
}
|
||||||
func (UnimplementedAttestationServiceServer) mustEmbedUnimplementedAttestationServiceServer() {}
|
func (UnimplementedAttestationServiceServer) mustEmbedUnimplementedAttestationServiceServer() {}
|
||||||
func (UnimplementedAttestationServiceServer) testEmbeddedByValue() {}
|
func (UnimplementedAttestationServiceServer) testEmbeddedByValue() {}
|
||||||
|
|
||||||
@@ -173,6 +188,24 @@ func _AttestationService_FetchAzureToken_Handler(srv interface{}, ctx context.Co
|
|||||||
return interceptor(ctx, in, info, handler)
|
return interceptor(ctx, in, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _AttestationService_FetchKbsToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(KbsTokenRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(AttestationServiceServer).FetchKbsToken(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: AttestationService_FetchKbsToken_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(AttestationServiceServer).FetchKbsToken(ctx, req.(*KbsTokenRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
// AttestationService_ServiceDesc is the grpc.ServiceDesc for AttestationService service.
|
// AttestationService_ServiceDesc is the grpc.ServiceDesc for AttestationService service.
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
// and not to be introspected or modified (even as a copy)
|
// and not to be introspected or modified (even as a copy)
|
||||||
@@ -192,6 +225,10 @@ var AttestationService_ServiceDesc = grpc.ServiceDesc{
|
|||||||
MethodName: "FetchAzureToken",
|
MethodName: "FetchAzureToken",
|
||||||
Handler: _AttestationService_FetchAzureToken_Handler,
|
Handler: _AttestationService_FetchAzureToken_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "FetchKbsToken",
|
||||||
|
Handler: _AttestationService_FetchKbsToken_Handler,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Streams: []grpc.StreamDesc{},
|
Streams: []grpc.StreamDesc{},
|
||||||
Metadata: "internal/proto/attestation/v1/attestation.proto",
|
Metadata: "internal/proto/attestation/v1/attestation.proto",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v6.33.1
|
// protoc v7.35.0
|
||||||
// source: manager/manager.proto
|
// source: manager/manager.proto
|
||||||
|
|
||||||
package manager
|
package manager
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.6.0
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
// - protoc v6.33.1
|
// - protoc v7.35.0
|
||||||
// source: manager/manager.proto
|
// source: manager/manager.proto
|
||||||
|
|
||||||
package manager
|
package manager
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ type Provider interface {
|
|||||||
TeeAttestation(teeNonce []byte) ([]byte, error)
|
TeeAttestation(teeNonce []byte) ([]byte, error)
|
||||||
VTpmAttestation(vTpmNonce []byte) ([]byte, error)
|
VTpmAttestation(vTpmNonce []byte) ([]byte, error)
|
||||||
AzureAttestationToken(tokenNonce []byte) ([]byte, error)
|
AzureAttestationToken(tokenNonce []byte) ([]byte, error)
|
||||||
|
KbsToken() ([]byte, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Verifier interface {
|
type Verifier interface {
|
||||||
|
|||||||
@@ -134,6 +134,10 @@ func (a provider) AzureAttestationToken(tokenNonce []byte) ([]byte, error) {
|
|||||||
return []byte(token), nil
|
return []byte(token), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a provider) KbsToken() ([]byte, error) {
|
||||||
|
return nil, fmt.Errorf("KbsToken not supported on Azure provider")
|
||||||
|
}
|
||||||
|
|
||||||
type verifier struct {
|
type verifier struct {
|
||||||
writer io.Writer
|
writer io.Writer
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,3 +129,21 @@ func (p *Provider) AzureAttestationToken(nonce []byte) ([]byte, error) {
|
|||||||
|
|
||||||
return resp.Token, 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
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,3 +31,7 @@ func (e *EmptyProvider) VTpmAttestation(vTpmNonce []byte) ([]byte, error) {
|
|||||||
func (e *EmptyProvider) AzureAttestationToken(nonce []byte) ([]byte, error) {
|
func (e *EmptyProvider) AzureAttestationToken(nonce []byte) ([]byte, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *EmptyProvider) KbsToken() ([]byte, error) {
|
||||||
|
return nil, fmt.Errorf("KbsToken not supported on EmptyProvider")
|
||||||
|
}
|
||||||
|
|||||||
@@ -72,6 +72,10 @@ func (v provider) AzureAttestationToken(tokenNonce []byte) ([]byte, error) {
|
|||||||
return nil, errors.New("Azure attestation token is not supported")
|
return nil, errors.New("Azure attestation token is not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v provider) KbsToken() ([]byte, error) {
|
||||||
|
return nil, errors.New("KbsToken is not supported on TDX provider")
|
||||||
|
}
|
||||||
|
|
||||||
type verifier struct {
|
type verifier struct {
|
||||||
Policy *checkconfig.Config
|
Policy *checkconfig.Config
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,10 @@ func (v provider) AzureAttestationToken(tokenNonce []byte) ([]byte, error) {
|
|||||||
return nil, errors.New("Azure attestation token is not supported")
|
return nil, errors.New("Azure attestation token is not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v provider) KbsToken() ([]byte, error) {
|
||||||
|
return nil, errors.New("KbsToken is not supported on vTPM provider")
|
||||||
|
}
|
||||||
|
|
||||||
type verifier struct {
|
type verifier struct {
|
||||||
writer io.Writer
|
writer io.Writer
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ type Client interface {
|
|||||||
GetAttestation(ctx context.Context, reportData [64]byte, nonce [32]byte, attType attestation.PlatformType) ([]byte, error)
|
GetAttestation(ctx context.Context, reportData [64]byte, nonce [32]byte, attType attestation.PlatformType) ([]byte, error)
|
||||||
GetRawEvidence(ctx context.Context, reportData [64]byte, nonce [32]byte, attType attestation.PlatformType) ([]byte, error)
|
GetRawEvidence(ctx context.Context, reportData [64]byte, nonce [32]byte, attType attestation.PlatformType) ([]byte, error)
|
||||||
GetAzureToken(ctx context.Context, nonce [32]byte) ([]byte, error)
|
GetAzureToken(ctx context.Context, nonce [32]byte) ([]byte, error)
|
||||||
|
GetKbsToken(ctx context.Context) ([]byte, error)
|
||||||
Close() error
|
Close() error
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,3 +133,15 @@ func (c *client) GetAzureToken(ctx context.Context, nonce [32]byte) ([]byte, err
|
|||||||
|
|
||||||
return resp.Token, nil
|
return resp.Token, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *client) GetKbsToken(ctx context.Context) ([]byte, error) {
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
resp, err := c.client.FetchKbsToken(ctx, &attestation_v1.KbsTokenRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.Token, nil
|
||||||
|
}
|
||||||
|
|||||||
+145
-10
@@ -10,9 +10,9 @@ import (
|
|||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/absmach/magistrala/pkg/errors"
|
"github.com/absmach/magistrala/pkg/errors"
|
||||||
"golang.org/x/crypto/hkdf"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -117,12 +117,26 @@ func DecryptWithWrappedKey(encryptedResource EncryptedResource, privateKey *ecdh
|
|||||||
return nil, errors.Wrap(ErrDecryptionFailed, err)
|
return nil, errors.Wrap(ErrDecryptionFailed, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Derive KEK (Key Encryption Key) using HKDF
|
// Derive KEK (Key Encryption Key) using Concat KDF (NIST SP 800-56A)
|
||||||
kek := make([]byte, 32)
|
algStr := "ECDH-ES+A256KW"
|
||||||
kdf := hkdf.New(sha256.New, sharedSecret, nil, nil)
|
otherInfo := make([]byte, 0, 4+len(algStr)+4+4+4)
|
||||||
if _, err := kdf.Read(kek); err != nil {
|
algLen := uint32(len(algStr))
|
||||||
return nil, errors.Wrap(ErrDecryptionFailed, err)
|
otherInfo = append(otherInfo, byte(algLen>>24), byte(algLen>>16), byte(algLen>>8), byte(algLen))
|
||||||
}
|
otherInfo = append(otherInfo, algStr...)
|
||||||
|
otherInfo = append(otherInfo, 0, 0, 0, 0) // PartyUInfo
|
||||||
|
otherInfo = append(otherInfo, 0, 0, 0, 0) // PartyVInfo
|
||||||
|
otherInfo = append(otherInfo, 0, 0, 1, 0) // SuppPubInfo (256 bits BE)
|
||||||
|
|
||||||
|
// Since we need a 32-byte KEK, and SHA-256 produces 32 bytes, we run exactly 1 iteration (counter = 1)
|
||||||
|
counter := uint32(1)
|
||||||
|
hashInput := make([]byte, 0, 4+len(sharedSecret)+len(otherInfo))
|
||||||
|
hashInput = append(hashInput, byte(counter>>24), byte(counter>>16), byte(counter>>8), byte(counter))
|
||||||
|
hashInput = append(hashInput, sharedSecret...)
|
||||||
|
hashInput = append(hashInput, otherInfo...)
|
||||||
|
|
||||||
|
h := sha256.New()
|
||||||
|
h.Write(hashInput)
|
||||||
|
kek := h.Sum(nil)
|
||||||
|
|
||||||
// Unwrap the content encryption key (CEK)
|
// Unwrap the content encryption key (CEK)
|
||||||
cek, err := unwrapKey(encryptedResource.EncryptedKey, kek)
|
cek, err := unwrapKey(encryptedResource.EncryptedKey, kek)
|
||||||
@@ -201,13 +215,134 @@ func unwrapKey(wrappedKey, kek []byte) ([]byte, error) {
|
|||||||
return unwrapped, nil
|
return unwrapped, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeBase64(s string) ([]byte, error) {
|
||||||
|
if d, err := base64.StdEncoding.DecodeString(s); err == nil {
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
if d, err := base64.URLEncoding.DecodeString(s); err == nil {
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
if d, err := base64.RawURLEncoding.DecodeString(s); err == nil {
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
if d, err := base64.RawStdEncoding.DecodeString(s); err == nil {
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
return nil, errors.New("invalid base64 encoding")
|
||||||
|
}
|
||||||
|
|
||||||
// ParseEncryptedResource parses a JSON-encoded encrypted resource.
|
// ParseEncryptedResource parses a JSON-encoded encrypted resource.
|
||||||
func ParseEncryptedResource(data []byte) (*EncryptedResource, error) {
|
func ParseEncryptedResource(data []byte) (*EncryptedResource, error) {
|
||||||
var resource EncryptedResource
|
var jwe struct {
|
||||||
if err := json.Unmarshal(data, &resource); err != nil {
|
Protected string `json:"protected"`
|
||||||
|
EncryptedKey string `json:"encrypted_key"`
|
||||||
|
IV string `json:"iv"`
|
||||||
|
Ciphertext string `json:"ciphertext"`
|
||||||
|
Tag string `json:"tag"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(data, &jwe); err != nil {
|
||||||
return nil, errors.Wrap(ErrInvalidFormat, err)
|
return nil, errors.Wrap(ErrInvalidFormat, err)
|
||||||
}
|
}
|
||||||
return &resource, nil
|
|
||||||
|
// JWE structure check: if it lacks protected header, try legacy standard struct unmarshal
|
||||||
|
if jwe.Protected == "" {
|
||||||
|
var legacy struct {
|
||||||
|
Ciphertext string `json:"ciphertext"`
|
||||||
|
EncryptedKey string `json:"encrypted_key"`
|
||||||
|
IV string `json:"iv"`
|
||||||
|
Tag string `json:"tag"`
|
||||||
|
AAD string `json:"aad,omitempty"`
|
||||||
|
EPK *EphemeralPublicKey `json:"epk,omitempty"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(data, &legacy); err != nil {
|
||||||
|
return nil, errors.Wrap(ErrInvalidFormat, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ciphertext, err := decodeBase64(legacy.Ciphertext)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(ErrInvalidFormat, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
encryptedKey, err := decodeBase64(legacy.EncryptedKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(ErrInvalidFormat, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
iv, err := decodeBase64(legacy.IV)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(ErrInvalidFormat, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tag, err := decodeBase64(legacy.Tag)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(ErrInvalidFormat, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var aad []byte
|
||||||
|
if legacy.AAD != "" {
|
||||||
|
aad, err = decodeBase64(legacy.AAD)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(ErrInvalidFormat, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &EncryptedResource{
|
||||||
|
Ciphertext: ciphertext,
|
||||||
|
EncryptedKey: encryptedKey,
|
||||||
|
IV: iv,
|
||||||
|
Tag: tag,
|
||||||
|
AAD: aad,
|
||||||
|
EPK: legacy.EPK,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Decode Protected Header JSON
|
||||||
|
protectedJSON, err := decodeBase64(jwe.Protected)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(ErrInvalidFormat, fmt.Errorf("failed to decode JWE protected header: %w", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Parse Ephemeral Public Key (EPK) from Protected Header
|
||||||
|
var header struct {
|
||||||
|
Alg string `json:"alg"`
|
||||||
|
EPK *EphemeralPublicKey `json:"epk"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(protectedJSON, &header); err != nil {
|
||||||
|
return nil, errors.Wrap(ErrInvalidFormat, fmt.Errorf("failed to parse JWE header JSON: %w", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Decode main crypto fields
|
||||||
|
ciphertext, err := decodeBase64(jwe.Ciphertext)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(ErrInvalidFormat, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
encryptedKey, err := decodeBase64(jwe.EncryptedKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(ErrInvalidFormat, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
iv, err := decodeBase64(jwe.IV)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(ErrInvalidFormat, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tag, err := decodeBase64(jwe.Tag)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(ErrInvalidFormat, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// In JWE, AAD is the ASCII bytes of the protected header string
|
||||||
|
aad := []byte(jwe.Protected)
|
||||||
|
|
||||||
|
return &EncryptedResource{
|
||||||
|
Ciphertext: ciphertext,
|
||||||
|
EncryptedKey: encryptedKey,
|
||||||
|
IV: iv,
|
||||||
|
Tag: tag,
|
||||||
|
AAD: aad,
|
||||||
|
EPK: header.EPK,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// zeroBytes securely zeros out a byte slice.
|
// zeroBytes securely zeros out a byte slice.
|
||||||
|
|||||||
+27
-14
@@ -15,9 +15,31 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"golang.org/x/crypto/hkdf"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// testConcatKDF derives a KEK using Concat KDF (NIST SP 800-56A), matching
|
||||||
|
// the exact implementation in DecryptWithWrappedKey.
|
||||||
|
func testConcatKDF(sharedSecret []byte) []byte {
|
||||||
|
algStr := "ECDH-ES+A256KW"
|
||||||
|
otherInfo := make([]byte, 0, 4+len(algStr)+4+4+4)
|
||||||
|
algLen := uint32(len(algStr))
|
||||||
|
otherInfo = append(otherInfo, byte(algLen>>24), byte(algLen>>16), byte(algLen>>8), byte(algLen))
|
||||||
|
otherInfo = append(otherInfo, algStr...)
|
||||||
|
otherInfo = append(otherInfo, 0, 0, 0, 0) // PartyUInfo
|
||||||
|
otherInfo = append(otherInfo, 0, 0, 0, 0) // PartyVInfo
|
||||||
|
otherInfo = append(otherInfo, 0, 0, 1, 0) // SuppPubInfo (256 bits BE)
|
||||||
|
|
||||||
|
counter := uint32(1)
|
||||||
|
hashInput := make([]byte, 0, 4+len(sharedSecret)+len(otherInfo))
|
||||||
|
hashInput = append(hashInput, byte(counter>>24), byte(counter>>16), byte(counter>>8), byte(counter))
|
||||||
|
hashInput = append(hashInput, sharedSecret...)
|
||||||
|
hashInput = append(hashInput, otherInfo...)
|
||||||
|
|
||||||
|
h := sha256.New()
|
||||||
|
h.Write(hashInput)
|
||||||
|
return h.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
// testAESKeyWrap implements RFC 3394 AES Key Wrap for use in test setup.
|
// testAESKeyWrap implements RFC 3394 AES Key Wrap for use in test setup.
|
||||||
func testAESKeyWrap(kek, key []byte) ([]byte, error) {
|
func testAESKeyWrap(kek, key []byte) ([]byte, error) {
|
||||||
block, err := aes.NewCipher(kek)
|
block, err := aes.NewCipher(kek)
|
||||||
@@ -527,11 +549,8 @@ func TestDecryptWithWrappedKeyFullRoundTrip(t *testing.T) {
|
|||||||
sharedSecret, err := ephemeralKey.ECDH(recipientKey.PublicKey())
|
sharedSecret, err := ephemeralKey.ECDH(recipientKey.PublicKey())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Derive KEK using HKDF (same as in DecryptWithWrappedKey)
|
// Derive KEK using Concat KDF (same as in DecryptWithWrappedKey)
|
||||||
kek := make([]byte, 32)
|
kek := testConcatKDF(sharedSecret)
|
||||||
kdf := hkdf.New(sha256.New, sharedSecret, nil, nil)
|
|
||||||
_, err = kdf.Read(kek)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Generate random CEK (32 bytes)
|
// Generate random CEK (32 bytes)
|
||||||
cek := make([]byte, 32)
|
cek := make([]byte, 32)
|
||||||
@@ -589,10 +608,7 @@ func TestDecryptWithWrappedKeyFullRoundTrip(t *testing.T) {
|
|||||||
sharedSecret, err := ephemeralKey.ECDH(recipientKey.PublicKey())
|
sharedSecret, err := ephemeralKey.ECDH(recipientKey.PublicKey())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
kek := make([]byte, 32)
|
kek := testConcatKDF(sharedSecret)
|
||||||
kdf := hkdf.New(sha256.New, sharedSecret, nil, nil)
|
|
||||||
_, err = kdf.Read(kek)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
cek := make([]byte, 16) // 16-byte CEK (AES-128)
|
cek := make([]byte, 16) // 16-byte CEK (AES-128)
|
||||||
_, err = rand.Read(cek)
|
_, err = rand.Read(cek)
|
||||||
@@ -650,10 +666,7 @@ func TestDecryptWithWrappedKeyFullRoundTrip(t *testing.T) {
|
|||||||
sharedSecret, err := ephemeralKey.ECDH(recipientKey.PublicKey())
|
sharedSecret, err := ephemeralKey.ECDH(recipientKey.PublicKey())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
kek := make([]byte, 32)
|
kek := testConcatKDF(sharedSecret)
|
||||||
kdf := hkdf.New(sha256.New, sharedSecret, nil, nil)
|
|
||||||
_, err = kdf.Read(kek)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
cek := make([]byte, 32)
|
cek := make([]byte, 32)
|
||||||
_, err = rand.Read(cek)
|
_, err = rand.Read(cek)
|
||||||
|
|||||||
@@ -1,5 +1,25 @@
|
|||||||
import os
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
def install(package):
|
||||||
|
subprocess.check_call([sys.executable, "-m", "pip", "install", package])
|
||||||
|
|
||||||
|
try:
|
||||||
|
import pandas
|
||||||
|
except ImportError:
|
||||||
|
install("pandas")
|
||||||
|
|
||||||
|
try:
|
||||||
|
import sklearn
|
||||||
|
except ImportError:
|
||||||
|
install("scikit-learn")
|
||||||
|
|
||||||
|
try:
|
||||||
|
import joblib
|
||||||
|
except ImportError:
|
||||||
|
install("joblib")
|
||||||
|
|
||||||
|
import os
|
||||||
import joblib
|
import joblib
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from sklearn.model_selection import train_test_split
|
from sklearn.model_selection import train_test_split
|
||||||
|
|||||||
Reference in New Issue
Block a user