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

keymanager/src/churp: Fetch key shares and recover key #5715

Merged
merged 12 commits into from
Jul 9, 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
1 change: 1 addition & 0 deletions .changelog/5715.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
keymanager/src/churp: Fetch key shares and recover key
26 changes: 26 additions & 0 deletions go/consensus/cometbft/apps/keymanager/churp/txs.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,18 @@ import (
kmCommon "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/apps/keymanager/common"
registryState "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/apps/registry/state"
stakingState "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/apps/staking/state"
"github.com/oasisprotocol/oasis-core/go/consensus/cometbft/features"
"github.com/oasisprotocol/oasis-core/go/keymanager/churp"
"github.com/oasisprotocol/oasis-core/go/registry/api"
staking "github.com/oasisprotocol/oasis-core/go/staking/api"
)

func (ext *churpExt) create(ctx *tmapi.Context, req *churp.CreateRequest) error {
// Make sure the `MayQuery` field is empty until the next breaking upgrade.
if err := verifyPolicy(ctx, &req.Policy); err != nil {
return err
}

// Prepare state.
state := churpState.NewMutableState(ctx.State())

Expand Down Expand Up @@ -125,6 +131,11 @@ func (ext *churpExt) create(ctx *tmapi.Context, req *churp.CreateRequest) error
}

func (ext *churpExt) update(ctx *tmapi.Context, req *churp.UpdateRequest) error {
// Make sure the `MayQuery` field is empty until the next breaking upgrade.
if err := verifyPolicy(ctx, req.Policy); err != nil {
return err
}

// Prepare state.
state := churpState.NewMutableState(ctx.State())

Expand Down Expand Up @@ -545,3 +556,18 @@ func resetHandoff(status *churp.Status, nextHandoff beacon.EpochTime) {
status.NextChecksum = nil
status.Applications = nil
}

func verifyPolicy(ctx *tmapi.Context, policy *churp.SignedPolicySGX) error {
// Allow non-empty `MayQuery` field with the 24.2 release.
enabled, err := features.IsFeatureVersion(ctx, "24.2")
kostko marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return err
}
if enabled {
return nil
}
if policy != nil && policy.Policy.MayQuery != nil {
return api.ErrInvalidArgument
}
return nil
}
6 changes: 6 additions & 0 deletions go/consensus/cometbft/apps/keymanager/churp/txs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ import (
"github.com/oasisprotocol/oasis-core/go/common/entity"
"github.com/oasisprotocol/oasis-core/go/common/node"
"github.com/oasisprotocol/oasis-core/go/common/quantity"
consensusState "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/abci/state"
abciAPI "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/api"
churpState "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/apps/keymanager/churp/state"
registryState "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/apps/registry/state"
stakingState "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/apps/staking/state"
consensusGenesis "github.com/oasisprotocol/oasis-core/go/consensus/genesis"
"github.com/oasisprotocol/oasis-core/go/keymanager/churp"
registry "github.com/oasisprotocol/oasis-core/go/registry/api"
staking "github.com/oasisprotocol/oasis-core/go/staking/api"
Expand Down Expand Up @@ -56,6 +58,7 @@ type TxTestSuite struct {
state *churpState.MutableState
regState *registryState.MutableState
stakeState *stakingState.MutableState
consState *consensusState.MutableState

nodes []*testNode
computeRuntimes []*registry.Runtime
Expand All @@ -79,6 +82,7 @@ func (s *TxTestSuite) SetupTest() {
s.state = churpState.NewMutableState(s.ctx.State())
s.regState = registryState.NewMutableState(s.ctx.State())
s.stakeState = stakingState.NewMutableState(s.ctx.State())
s.consState = consensusState.NewMutableState(s.ctx.State())

// Set up default consensus parameters.
err := s.state.SetConsensusParameters(s.ctx, &churp.DefaultConsensusParameters)
Expand All @@ -87,6 +91,8 @@ func (s *TxTestSuite) SetupTest() {
require.NoError(s.T(), err)
err = s.stakeState.SetConsensusParameters(s.ctx, &staking.ConsensusParameters{})
require.NoError(s.T(), err)
err = s.consState.SetConsensusParameters(s.ctx, &consensusGenesis.Parameters{})
require.NoError(s.T(), err)

// Prepare nodes.
s.nodes = make([]*testNode, 0, numNodes)
Expand Down
2 changes: 1 addition & 1 deletion go/consensus/cometbft/features/features.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package api
package features

import (
"fmt"
Expand Down
10 changes: 8 additions & 2 deletions go/keymanager/churp/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package churp
import (
"fmt"

"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/sgx"
Expand All @@ -12,20 +13,25 @@ import (
var PolicySGXSignatureContext = signature.NewContext("oasis-core/keymanager/churp: policy")

// PolicySGX represents an SGX access control policy used to authenticate
// key manager enclaves during handoffs.
// key manager enclaves during handoffs and remote client enclaves when
// querying key shares.
type PolicySGX struct {
Identity

// Serial is the monotonically increasing policy serial number.
Serial uint32 `json:"serial"`

// MayShare is the vector of enclave identities from which a share can be
// obtained during handouts.
// obtained during handoffs.
MayShare []sgx.EnclaveIdentity `json:"may_share"`

// MayJoin is the vector of enclave identities that may form the new
// committee in the next handoffs.
MayJoin []sgx.EnclaveIdentity `json:"may_join"`

// MayQuery is the map of runtime identities to the vector of enclave
// identities that may query key shares.
MayQuery map[common.Namespace][]sgx.EnclaveIdentity `json:"may_query,omitempty"`
}

// SanityCheck verifies the validity of the policy.
Expand Down
3 changes: 3 additions & 0 deletions go/keymanager/churp/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ var (

// RPCMethodBivariateShare is the name of the `bivariate_share` method.
RPCMethodBivariateShare = "churp/bivariate_share"

// RPCMethodSGXPolicyKeyShare is the name of the `sgx_policy_key_share` method.
RPCMethodSGXPolicyKeyShare = "churp/sgx_policy_key_share"
)

// HandoffRequest represents a handoff request.
Expand Down
6 changes: 4 additions & 2 deletions go/keymanager/secrets/policy_sgx.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ type EnclavePolicySGX struct {
MayQuery map[common.Namespace][]sgx.EnclaveIdentity `json:"may_query"`

// MayReplicate is the vector of enclave IDs that may retrieve the master
// secret (Note: Each enclave ID may always implicitly replicate from other
// instances of itself).
// secret.
//
// NOTE: Each enclave ID may always implicitly replicate from other
// instances of itself.
MayReplicate []sgx.EnclaveIdentity `json:"may_replicate"`
}

Expand Down
2 changes: 1 addition & 1 deletion go/oasis-test-runner/scenario/e2e/runtime/archive_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
var ArchiveAPI scenario.Scenario = &archiveAPI{
Scenario: *NewScenario(
"archive-api",
NewTestClient().WithScenario(InsertTransferKeyValueScenario),
NewTestClient().WithScenario(InsertTransferScenario),
),
}

Expand Down
4 changes: 2 additions & 2 deletions go/oasis-test-runner/scenario/e2e/runtime/dump_restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func newDumpRestoreImpl(
sc := &dumpRestoreImpl{
Scenario: *NewScenario(
name,
NewTestClient().WithScenario(InsertKeyValueScenario),
NewTestClient().WithScenario(InsertScenario),
),
mapGenesisDocumentFn: mapGenesisDocumentFn,
}
Expand Down Expand Up @@ -188,6 +188,6 @@ func (sc *dumpRestoreImpl) Run(ctx context.Context, childEnv *env.Env) error {
}

// Check that everything works with restored state.
sc.Scenario.TestClient = NewTestClient().WithSeed("seed2").WithScenario(RemoveKeyValueScenario)
sc.Scenario.TestClient = NewTestClient().WithSeed("seed2").WithScenario(RemoveScenario)
return sc.Scenario.Run(ctx, childEnv)
}
2 changes: 1 addition & 1 deletion go/oasis-test-runner/scenario/e2e/runtime/gas_fees.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func (sc *gasFeesRuntimesImpl) Run(ctx context.Context, _ *env.Env) error {

// Submit a runtime transaction to check whether transaction processing works.
sc.Logger.Info("submitting transaction to runtime")
if _, err := sc.submitKeyValueRuntimeInsertTx(ctx, KeyValueRuntimeID, 0, "hello", "non-free world", false, 0); err != nil {
if _, err := sc.submitKeyValueRuntimeInsertTx(ctx, KeyValueRuntimeID, 0, "hello", "non-free world", 0, 0, plaintextTxKind); err != nil {
return err
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func newGovernanceConsensusUpgradeImpl(correctUpgradeVersion, cancelUpgrade bool
sc := &governanceConsensusUpgradeImpl{
Scenario: *NewScenario(
name,
NewTestClient().WithScenario(InsertTransferKeyValueScenario),
NewTestClient().WithScenario(InsertTransferScenario),
),
correctUpgradeVersion: correctUpgradeVersion,
shouldCancelUpgrade: cancelUpgrade,
Expand Down Expand Up @@ -465,6 +465,6 @@ func (sc *governanceConsensusUpgradeImpl) Run(ctx context.Context, childEnv *env
}

// Check that runtime still works after the upgrade.
sc.Scenario.TestClient = NewTestClient().WithSeed("seed2").WithScenario(RemoveKeyValueScenario)
sc.Scenario.TestClient = NewTestClient().WithSeed("seed2").WithScenario(RemoveScenario)
return sc.Scenario.Run(ctx, childEnv)
}
4 changes: 2 additions & 2 deletions go/oasis-test-runner/scenario/e2e/runtime/halt_restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func newHaltRestoreImpl(suspended bool) scenario.Scenario {
return &haltRestoreImpl{
Scenario: *NewScenario(
name,
NewTestClient().WithScenario(InsertTransferKeyValueScenario),
NewTestClient().WithScenario(InsertTransferScenario),
),
haltEpoch: beacon.EpochTime(haltEpoch),
suspendRuntime: suspended,
Expand Down Expand Up @@ -220,7 +220,7 @@ func (sc *haltRestoreImpl) Run(ctx context.Context, childEnv *env.Env) error { /
return err
}

sc.Scenario.TestClient = NewTestClient().WithSeed("seed2").WithScenario(RemoveKeyValueScenario)
sc.Scenario.TestClient = NewTestClient().WithSeed("seed2").WithScenario(RemoveScenario)

// Start the new network again and run the test client.
if err = sc.StartNetworkAndWaitForClientSync(ctx); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func newHaltRestoreNonMockImpl() scenario.Scenario {
return &haltRestoreNonMockImpl{
Scenario: *NewScenario(
name,
NewTestClient().WithScenario(InsertTransferKeyValueScenario),
NewTestClient().WithScenario(InsertTransferScenario),
),
haltEpoch: 8,
}
Expand Down Expand Up @@ -133,7 +133,7 @@ func (sc *haltRestoreNonMockImpl) Run(ctx context.Context, childEnv *env.Env) er
return err
}

sc.Scenario.TestClient = NewTestClient().WithSeed("seed2").WithScenario(RemoveKeyValueScenario)
sc.Scenario.TestClient = NewTestClient().WithSeed("seed2").WithScenario(RemoveScenario)

// Start the new network again and run the test client.
if err = sc.StartNetworkAndTestClient(ctx, childEnv); err != nil {
Expand Down
5 changes: 5 additions & 0 deletions go/oasis-test-runner/scenario/e2e/runtime/helpers_churp.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"

beacon "github.com/oasisprotocol/oasis-core/go/beacon/api"
"github.com/oasisprotocol/oasis-core/go/common"
"github.com/oasisprotocol/oasis-core/go/common/sgx"
"github.com/oasisprotocol/oasis-core/go/consensus/api/transaction"
"github.com/oasisprotocol/oasis-core/go/keymanager/api"
Expand Down Expand Up @@ -35,6 +36,10 @@ func (sc *Scenario) createChurp(ctx context.Context, id uint8, threshold uint8,
req.Policy.Policy.MayShare = []sgx.EnclaveIdentity{*enclaveID}
}

if enclaveID := sc.Net.Runtimes()[1].GetEnclaveIdentity(0); enclaveID != nil {
req.Policy.Policy.MayQuery = map[common.Namespace][]sgx.EnclaveIdentity{KeyValueRuntimeID: {*enclaveID}}
}

if err := req.Policy.Sign(api.TestSigners); err != nil {
return err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func newHistoryReindexImpl() scenario.Scenario {
return &historyReindexImpl{
Scenario: *NewScenario(
"history-reindex",
NewTestClient().WithScenario(InsertRemoveKeyValueEncScenario),
NewTestClient().WithScenario(InsertRemoveEncWithSecretsScenario),
),
}
}
Expand Down
Loading
Loading