Skip to content

Commit

Permalink
[WIP] Add Store Interface basics
Browse files Browse the repository at this point in the history
Signed-off-by: Yogesh Deshpande <[email protected]>
  • Loading branch information
yogeshbdeshpande committed Mar 7, 2024
1 parent 8e55820 commit c5d9aa8
Show file tree
Hide file tree
Showing 6 changed files with 338 additions and 27 deletions.
4 changes: 2 additions & 2 deletions handler/ievidencehandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

// IEvidenceHandler defines the interface to functionality for working with
// attestation scheme specific evidence tokens. This includes validating token
// integrity, and extracting an appraising claims.
// integrity, extracting and appraising claims.
type IEvidenceHandler interface {
plugin.IPluggable

Expand Down Expand Up @@ -48,7 +48,7 @@ type IEvidenceHandler interface {
endorsementsStrings []string,
) error

// AppraiseEvidence evaluates the specified EvidenceContext against
// AppraiseEvidence evaluates the specified EvidenceContext against
// the specified endorsements, and returns an AttestationResult.
AppraiseEvidence(
ec *proto.EvidenceContext,
Expand Down
29 changes: 29 additions & 0 deletions handler/istorehandler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2021-2024 Contributors to the Veraison project.
// SPDX-License-Identifier: Apache-2.0
package handler

import (
"github.com/veraison/services/plugin"
"github.com/veraison/services/proto"
)

// IStoreHandler defines the interface to functionality for working with
// attestation scheme specific store interfaces. This includes extracting
// Trust Anchor IDs from attestation token, and synthesizing,
// Reference Value and TrustAnchor Keys from supplied endorsements
type IStoreHandler interface {
plugin.IPluggable

// GetTrustAnchorIDs returns an array of trust anchor identifiers used
// to retrieve the trust anchors associated with this token. The trust anchors may be necessary to validate the
// entire token and/or extract its claims (if it is encrypted).
GetTrustAnchorIDs(token *proto.AttestationToken) ([]string, error)

// SynthKeysFromRefValue synthesizes lookup key(s) for the
// provided reference value endorsement.
SynthKeysFromRefValue(tenantID string, refVal *Endorsement) ([]string, error)

// SynthKeysFromTrustAnchor synthesizes lookup key(s) for the provided
// trust anchor.
SynthKeysFromTrustAnchor(tenantID string, ta *Endorsement) ([]string, error)
}
240 changes: 240 additions & 0 deletions handler/store_rpc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
// Copyright 2022-2024 Contributors to the Veraison project.
// SPDX-License-Identifier: Apache-2.0
package handler

import (
"encoding/json"
"fmt"
"net/rpc"

"github.com/veraison/services/plugin"
"github.com/veraison/services/proto"
)

/*
Server-side RPC adapter around the Decoder plugin implementation
(plugin-side)
*/

var StoreHandlerRPC = &plugin.RPCChannel[IStoreHandler]{
GetClient: getStoreClient,
GetServer: getStoreServer,
}

func getStoreClient(c *rpc.Client) interface{} {
return &StoreRPCClient{client: c}
}

func getStoreServer(i IStoreHandler) interface{} {
return &StoreRPCServer{Impl: i}
}

type StoreRPCServer struct {
Impl IStoreHandler
}

// TO DO Check, do we need store Init/Close() Methods?
/*
func (s StoreRPCServer) Close(unused0 interface{}, unused1 interface{}) error {
return s.Impl.Close()
}
*/

func (s *StoreRPCServer) GetName(args interface{}, resp *string) error {
*resp = s.Impl.GetName()
return nil
}

func (s *StoreRPCServer) GetAttestationScheme(args interface{}, resp *string) error {
*resp = s.Impl.GetAttestationScheme()
return nil
}

func (s *StoreRPCServer) GetSupportedMediaTypes(args interface{}, resp *[]string) error {
*resp = s.Impl.GetSupportedMediaTypes()
return nil
}

// TO DO Retain the Name
type SynthKeysArgs1 struct {
TenantID string
EndorsementJSON []byte
}

func (s *StoreRPCServer) SynthKeysFromRefValue(args SynthKeysArgs1, resp *[]string) error {
var (
err error
swComp Endorsement
)

err = json.Unmarshal(args.EndorsementJSON, &swComp)
if err != nil {
return fmt.Errorf("unmarshaling software component: %w", err)
}

*resp, err = s.Impl.SynthKeysFromRefValue(args.TenantID, &swComp)

return err
}

func (s *StoreRPCServer) SynthKeysFromTrustAnchor(args SynthKeysArgs1, resp *[]string) error {
var (
err error
ta Endorsement
)

err = json.Unmarshal(args.EndorsementJSON, &ta)
if err != nil {
return fmt.Errorf("unmarshaling trust anchor: %w", err)
}

*resp, err = s.Impl.SynthKeysFromTrustAnchor(args.TenantID, &ta)

return err
}

func (s *StoreRPCServer) GetTrustAnchorIDs(data []byte, resp *[]string) error {
var (
err error
token proto.AttestationToken
)

err = json.Unmarshal(data, &token)
if err != nil {
return fmt.Errorf("unmarshaling attestation token: %w", err)
}

*resp, err = s.Impl.GetTrustAnchorIDs(&token)

return err
}

/*
RPC client
(plugin caller side)
*/

type StoreRPCClient struct {
client *rpc.Client
}

func (c StoreRPCClient) Close() error {
var (
unused0 interface{}
unused1 interface{}
)

return c.client.Call("Plugin.Close", unused0, unused1)
}

func (c StoreRPCClient) GetName() string {
var (
err error
resp string
unused interface{}
)

err = c.client.Call("Plugin.GetName", &unused, &resp)
if err != nil {
return ""
}

return resp
}

func (c StoreRPCClient) GetAttestationScheme() string {
var (
err error
resp string
unused interface{}
)

err = c.client.Call("Plugin.GetAttestationScheme", &unused, &resp)
if err != nil {
return ""
}

return resp
}

func (c StoreRPCClient) GetSupportedMediaTypes() []string {
var (
err error
resp []string
unused interface{}
)

err = c.client.Call("Plugin.GetSupportedMediaTypes", &unused, &resp)
if err != nil {
return nil
}

return resp
}

func (s *StoreRPCClient) SynthKeysFromRefValue(tenantID string, swComp *Endorsement) ([]string, error) {
var (
err error
resp []string
args SynthKeysArgs
)

args.TenantID = tenantID

args.EndorsementJSON, err = json.Marshal(swComp)
if err != nil {
return nil, fmt.Errorf("marshaling software component: %w", err)
}

err = s.client.Call("Plugin.SynthKeysFromRefValue", args, &resp)
if err != nil {
err = ParseError(err)
return nil, fmt.Errorf("Plugin.SynthKeysFromRefValue RPC call failed: %w", err) // nolint
}

return resp, nil
}

func (s *StoreRPCClient) SynthKeysFromTrustAnchor(tenantID string, ta *Endorsement) ([]string, error) {
var (
err error
resp []string
args SynthKeysArgs
)

args.TenantID = tenantID

args.EndorsementJSON, err = json.Marshal(ta)
if err != nil {
return nil, fmt.Errorf("marshaling trust anchor: %w", err)
}

err = s.client.Call("Plugin.SynthKeysFromTrustAnchor", args, &resp)
if err != nil {
err = ParseError(err)
return nil, fmt.Errorf("Plugin.SynthKeysFromTrustAnchor RPC call failed: %w", err) // nolint
}

return resp, nil
}

func (s *StoreRPCClient) GetTrustAnchorIDs(token *proto.AttestationToken) ([]string, error) {
var (
err error
data []byte
resp []string
)

data, err = json.Marshal(token)
if err != nil {
return []string{""}, fmt.Errorf("marshaling token: %w", err)
}

err = s.client.Call("Plugin.GetTrustAnchorIDs", data, &resp)
if err != nil {
err = ParseError(err)
return []string{""}, fmt.Errorf("Plugin.GetTrustAnchorIDs RPC call failed: %w", err) // nolint
}

return resp, nil
}
19 changes: 17 additions & 2 deletions vts/cmd/vts-service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func main() {
log.Info("loading attestation schemes")
var evPluginManager plugin.IManager[handler.IEvidenceHandler]
var endPluginManager plugin.IManager[handler.IEndorsementHandler]
var storePluginManager plugin.IManager[handler.IStoreHandler]

psubs, err := config.GetSubs(subs["plugin"], "*go-plugin", "*builtin")
if err != nil {
Expand Down Expand Up @@ -95,6 +96,14 @@ func main() {
if err != nil {
log.Fatalf("could not create endorsement PluginManagerWithLoader: %v", err)
}
storePluginManager, err = plugin.CreateGoPluginManagerWithLoader(
loader,
"store-handler",
log.Named("plugin"),
handler.StoreHandlerRPC)
if err != nil {
log.Fatalf("could not create store PluginManagerWithLoader: %v", err)
}
} else if config.SchemeLoader == "builtin" {
loader, err := builtin.CreateBuiltinLoader(
psubs["builtin"].AllSettings(),
Expand All @@ -114,6 +123,12 @@ func main() {
if err != nil {
log.Fatalf("could not create BuiltinManagerWithLoader: %v", err)
}
storePluginManager, err = builtin.CreateBuiltinManagerWithLoader[handler.IStoreHandler](
loader, log.Named("builtin"),
"store-handler")
if err != nil {
log.Fatalf("could not create BuiltinManagerWithLoader: %v", err)
}
} else {
log.Panicw("invalid SchemeLoader value", "SchemeLoader", config.SchemeLoader)
}
Expand All @@ -138,9 +153,9 @@ func main() {
// from this point onwards taStore, enStore, evPluginManager, endPluginManager,
// policyManager and earSigner are owned by vts
vts := trustedservices.NewGRPC(taStore, enStore,
evPluginManager, endPluginManager, policyManager, earSigner, log.Named("vts"))
evPluginManager, endPluginManager, storePluginManager, policyManager, earSigner, log.Named("vts"))

if err = vts.Init(subs["vts"], evPluginManager, endPluginManager); err != nil {
if err = vts.Init(subs["vts"], evPluginManager, endPluginManager, storePluginManager); err != nil {
log.Fatalf("VTS initialisation failed: %v", err)
}

Expand Down
7 changes: 6 additions & 1 deletion vts/trustedservices/itrustedservices.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ import (
)

type ITrustedServices interface {
Init(cfg *viper.Viper, pm plugin.IManager[handler.IEvidenceHandler], em plugin.IManager[handler.IEndorsementHandler]) error
Init(
cfg *viper.Viper,
evm plugin.IManager[handler.IEvidenceHandler],
endm plugin.IManager[handler.IEndorsementHandler],
stm plugin.IManager[handler.IStoreHandler],
) error
Close() error
Run() error

Expand Down
Loading

0 comments on commit c5d9aa8

Please sign in to comment.