Skip to content

Commit

Permalink
Merge pull request #5715 from oasisprotocol/peternose/feature/churp-k…
Browse files Browse the repository at this point in the history
…ey-shares

keymanager/src/churp: Fetch key shares and recover key
  • Loading branch information
peternose authored Jul 9, 2024
2 parents ce84c8e + 8812ba2 commit ab5b0b7
Show file tree
Hide file tree
Showing 65 changed files with 1,558 additions and 704 deletions.
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")
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

0 comments on commit ab5b0b7

Please sign in to comment.