Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go/runtime/registry/host: Ignore key manager quote policy update feature #5759

Merged
merged 3 commits into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changelog/5759.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
go/runtime/registry/host: Ignore key manager quote policy update feature

If the key manager policy and status update watcher started before
the runtime active version was ready, it failed to fetch the runtime
info and stopped. Therefore, the key manager status and quote policy
were never updated, causing the key manager runtime client to reject
incoming Noise session requests since the policy was not set.
3 changes: 1 addition & 2 deletions go/runtime/host/composite/composite.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ func shouldPropagateToComponent(body *protocol.Body) bool {
// Consensus view of all components should be up to date as otherwise signed attestations
// will be stale, resulting in them being rejected.
return true
case body.RuntimeKeyManagerPolicyUpdateRequest != nil,
body.RuntimeKeyManagerStatusUpdateRequest != nil,
case body.RuntimeKeyManagerStatusUpdateRequest != nil,
body.RuntimeKeyManagerQuotePolicyUpdateRequest != nil:
// Key manager updates should be propagated.
return true
Expand Down
3 changes: 1 addition & 2 deletions go/runtime/host/loadbalance/loadbalance.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ func shouldPropagateToAll(body *protocol.Body) bool {
// Consensus view of all instances should be up to date as otherwise signed attestations
// will be stale, resulting in them being rejected.
return true
case body.RuntimeKeyManagerPolicyUpdateRequest != nil,
body.RuntimeKeyManagerStatusUpdateRequest != nil,
case body.RuntimeKeyManagerStatusUpdateRequest != nil,
body.RuntimeKeyManagerQuotePolicyUpdateRequest != nil:
// Key manager updates should be propagated.
return true
Expand Down
3 changes: 1 addition & 2 deletions go/runtime/host/multi/multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,7 @@ func shouldPropagateToNextVersion(body *protocol.Body) bool {
// Consensus view of the next version should be up to date as otherwise signed attestations
// will be stale, resulting in them being rejected by the consensus layer.
return true
case body.RuntimeKeyManagerPolicyUpdateRequest != nil,
body.RuntimeKeyManagerStatusUpdateRequest != nil,
case body.RuntimeKeyManagerStatusUpdateRequest != nil,
body.RuntimeKeyManagerQuotePolicyUpdateRequest != nil:
// Key manager updates should be propagated so that the runtime is ready when activated.
return true
Expand Down
7 changes: 0 additions & 7 deletions go/runtime/host/protocol/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ type Body struct {
RuntimeAbortResponse *Empty `json:",omitempty"`
RuntimeKeyManagerStatusUpdateRequest *RuntimeKeyManagerStatusUpdateRequest `json:",omitempty"`
RuntimeKeyManagerStatusUpdateResponse *Empty `json:",omitempty"`
RuntimeKeyManagerPolicyUpdateRequest *RuntimeKeyManagerPolicyUpdateRequest `json:",omitempty"`
RuntimeKeyManagerPolicyUpdateResponse *Empty `json:",omitempty"`
RuntimeKeyManagerQuotePolicyUpdateRequest *RuntimeKeyManagerQuotePolicyUpdateRequest `json:",omitempty"`
RuntimeKeyManagerQuotePolicyUpdateResponse *Empty `json:",omitempty"`
RuntimeQueryRequest *RuntimeQueryRequest `json:",omitempty"`
Expand Down Expand Up @@ -447,11 +445,6 @@ type RuntimeKeyManagerStatusUpdateRequest struct {
Status secrets.Status `json:"status"`
}

// RuntimeKeyManagerPolicyUpdateRequest is a runtime key manager policy update request message body.
type RuntimeKeyManagerPolicyUpdateRequest struct {
SignedPolicyRaw []byte `json:"signed_policy_raw"`
}

// RuntimeKeyManagerQuotePolicyUpdateRequest is a runtime key manager quote policy update request
// message body.
type RuntimeKeyManagerQuotePolicyUpdateRequest struct {
Expand Down
34 changes: 26 additions & 8 deletions go/runtime/host/tests/tester.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/stretchr/testify/require"

"github.com/oasisprotocol/oasis-core/go/common"
"github.com/oasisprotocol/oasis-core/go/common/cbor"
"github.com/oasisprotocol/oasis-core/go/common/crypto/signature"
"github.com/oasisprotocol/oasis-core/go/common/logging"
Expand Down Expand Up @@ -90,8 +91,13 @@ func TestProvisioner(
}
}

func mockKeyManagerPolicyRequest() (*protocol.Body, error) {
// Generate a dummy key manager policy for tests.
func mockRuntimeKeyManagerStatusUpdateRequest() (*protocol.Body, error) {
// Generate a dummy key manager status for tests.
var keymanagerID common.Namespace
if err := keymanagerID.UnmarshalHex("c000000000000000fffffffffffffffffffffffffffffffffffffffffffffffe"); err != nil {
return nil, err
}

policy := secrets.PolicySGX{
Serial: 1,
Enclaves: map[sgx.EnclaveIdentity]*secrets.EnclavePolicySGX{},
Expand All @@ -108,8 +114,20 @@ func mockKeyManagerPolicyRequest() (*protocol.Body, error) {
sigPolicy.Signatures = append(sigPolicy.Signatures, *sig)
}

return &protocol.Body{RuntimeKeyManagerPolicyUpdateRequest: &protocol.RuntimeKeyManagerPolicyUpdateRequest{
SignedPolicyRaw: cbor.Marshal(sigPolicy),
status := secrets.Status{
ID: keymanagerID,
IsInitialized: true,
IsSecure: true,
Generation: 1,
RotationEpoch: 0,
Checksum: []byte{1, 2, 3},
Nodes: nil,
Policy: &sigPolicy,
RSK: nil,
}

return &protocol.Body{RuntimeKeyManagerStatusUpdateRequest: &protocol.RuntimeKeyManagerStatusUpdateRequest{
Status: status,
}}, nil
}

Expand Down Expand Up @@ -139,12 +157,12 @@ func testBasic(t *testing.T, cfg host.Config, p host.Provisioner) {
require.NoError(err, "Call")
require.NotNil(rsp.Empty, "runtime response to RuntimePingRequest should return an Empty body")

req, err := mockKeyManagerPolicyRequest()
require.NoError(err, "mockKeyManagerPolicyRequest")
req, err := mockRuntimeKeyManagerStatusUpdateRequest()
require.NoError(err, "mockKeyManagerStatusRequest")

rsp, err = r.Call(ctx, req)
require.NoError(err, "KeyManagerPolicyRequest Call")
require.NotNil(rsp.RuntimeKeyManagerPolicyUpdateResponse, "runtime response to KeyManagerPolicyRequest should return an RuntimeKeyManagerPolicyUpdateResponse body")
require.NoError(err, "KeyManagerStatusRequest Call")
require.NotNil(rsp.RuntimeKeyManagerStatusUpdateResponse, "runtime response to RuntimeKeyManagerStatusUpdate should return a RuntimeKeyManagerStatusUpdateResponse body")

// Request the runtime to stop.
r.Stop()
Expand Down
59 changes: 12 additions & 47 deletions go/runtime/registry/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -663,46 +663,34 @@ func (n *runtimeHostNotifier) watchKmPolicyUpdates(ctx context.Context, kmRtID *
var (
statusUpdated = true
quotePolicyUpdated = true
runtimeInfoUpdated = false
)

var (
st *secrets.Status
sc *node.SGXConstraints
vi *registry.VersionInfo
ri *protocol.RuntimeInfoResponse
)

for {
// Fetch runtime info so that we know which features the current runtime version supports.
if !runtimeInfoUpdated {
if ri, err = n.host.GetInfo(ctx); err != nil {
n.logger.Error("failed to fetch runtime info",
"err", err,
)
return
}
runtimeInfoUpdated = true
}

// Make sure that we actually have a new status.
if !statusUpdated && st != nil {
switch {
case ri.Features.KeyManagerStatusUpdates:
if err = n.updateKeyManagerStatus(ctx, st); err == nil {
statusUpdated = true
}
case st.Policy != nil:
if err = n.updateKeyManagerPolicy(ctx, st.Policy); err == nil {
statusUpdated = true
}
if err = n.updateKeyManagerStatus(ctx, st); err != nil {
n.logger.Error("failed to update key manager status",
"err", err,
)
} else {
statusUpdated = true
}
}

// Make sure that we actually have a new quote policy and that the current runtime version
// supports quote policy updates.
if !quotePolicyUpdated && sc != nil && sc.Policy != nil && ri.Features.KeyManagerQuotePolicyUpdates {
if err = n.updateKeyManagerQuotePolicy(ctx, sc.Policy); err == nil {
if !quotePolicyUpdated && sc != nil && sc.Policy != nil {
if err = n.updateKeyManagerQuotePolicy(ctx, sc.Policy); err != nil {
n.logger.Error("failed to update key manager quote policy",
"err", err,
)
} else {
quotePolicyUpdated = true
}
}
Expand Down Expand Up @@ -763,7 +751,6 @@ func (n *runtimeHostNotifier) watchKmPolicyUpdates(ctx context.Context, kmRtID *

statusUpdated = false
quotePolicyUpdated = false
runtimeInfoUpdated = false
case <-retryTicker.C:
// Retry updates if some of them failed. When using CometBFT as a backend service
// the host will see the new state one block before the consensus verifier as the former
Expand Down Expand Up @@ -795,28 +782,6 @@ func (n *runtimeHostNotifier) updateKeyManagerStatus(ctx context.Context, status
return nil
}

func (n *runtimeHostNotifier) updateKeyManagerPolicy(ctx context.Context, policy *secrets.SignedPolicySGX) error {
n.logger.Debug("got key manager policy update", "policy", policy)

raw := cbor.Marshal(policy)
req := &protocol.Body{RuntimeKeyManagerPolicyUpdateRequest: &protocol.RuntimeKeyManagerPolicyUpdateRequest{
SignedPolicyRaw: raw,
}}

ctx, cancel := context.WithTimeout(ctx, notifyTimeout)
defer cancel()

if _, err := n.host.Call(ctx, req); err != nil {
n.logger.Error("failed dispatching key manager policy update to runtime",
"err", err,
)
return err
}

n.logger.Debug("key manager policy update dispatched")
return nil
}

func (n *runtimeHostNotifier) updateKeyManagerQuotePolicy(ctx context.Context, policy *quote.Policy) error {
n.logger.Debug("got key manager quote policy update", "policy", policy)

Expand Down
Loading