From 1533bb8cd2811db18b668dfaddf4cc26e77957e3 Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Fri, 22 Dec 2023 05:10:51 -0800 Subject: [PATCH 1/3] Key manager bootstrap --- bisenzone-cw-mvp/.gitignore | 4 +- .../contracts/cw-tee-mtcs/README.md | 25 ++++++- .../contracts/cw-tee-mtcs/src/contract.rs | 65 +++++++++++++++++-- .../contracts/cw-tee-mtcs/src/error.rs | 25 +++---- .../contracts/cw-tee-mtcs/src/msg.rs | 18 ++++- .../contracts/cw-tee-mtcs/src/state.rs | 12 ++++ 6 files changed, 124 insertions(+), 25 deletions(-) diff --git a/bisenzone-cw-mvp/.gitignore b/bisenzone-cw-mvp/.gitignore index c7ca55f..52990d7 100644 --- a/bisenzone-cw-mvp/.gitignore +++ b/bisenzone-cw-mvp/.gitignore @@ -1,7 +1,7 @@ # Build results /artifacts -/target -/schema +target/ +schema/ # Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327) .cargo-ok diff --git a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/README.md b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/README.md index 99f6be2..b278a07 100644 --- a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/README.md +++ b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/README.md @@ -5,7 +5,30 @@ the [Key managers proposal v1](https://github.com/informalsystems/tee-mtcs/issue ## Testing instructions -* Upload a cycle of obligations - +* Submit a bootstrap key manager request - + +``` +export EXECUTE='{ + "bootstrap_key_manager": { + "compute_mrenclave": "dc43f8c42d8e5f52c8bbd68f426242153f0be10630ff8cca255129a3ca03d273", + "key_manager_mrenclave": "1cf2e52911410fbf3f199056a98d58795a559a2e800933f7fcd13d048462271c", + "tcb_info": "" + } +}' +wasmd tx wasm execute "$CONTRACT" "$EXECUTE" --from alice --chain-id testing -y +``` + +* Query the bootstrap state - + +``` +wasmd query wasm contract-state raw "$CONTRACT" 7367787374617465 # BIN_HEX('sgx_state') +# OR ---- +wasmd query wasm contract-state smart "$CONTRACT" '{ + "get_sgx_state": { } +}' +``` + +* Submit a join compute node request - ``` export EXECUTE='{ diff --git a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/contract.rs b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/contract.rs index 0bc5c76..2e7793b 100644 --- a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/contract.rs +++ b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/contract.rs @@ -4,7 +4,7 @@ use cosmwasm_std::{ use cw2::set_contract_version; use crate::error::ContractError; -use crate::msg::execute::JoinComputeNodeMsg; +use crate::msg::execute::{BootstrapKeyManagerMsg, JoinComputeNodeMsg}; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{State, STATE}; @@ -38,6 +38,13 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { + ExecuteMsg::BootstrapKeyManager(BootstrapKeyManagerMsg { + compute_mrenclave, + key_manager_mrenclave, + tcb_info, + }) => { + execute::bootstrap_key_manger(deps, compute_mrenclave, key_manager_mrenclave, tcb_info) + } ExecuteMsg::JoinComputeNode(JoinComputeNodeMsg { io_exchange_key, address, @@ -50,9 +57,46 @@ pub mod execute { use cosmwasm_std::{DepsMut, Response}; use k256::ecdsa::VerifyingKey; - use crate::state::{RawAddress, RawNonce, RawPublicKey}; + use crate::state::{ + Mrenclave, RawAddress, RawMrenclave, RawNonce, RawPublicKey, RawTcbInfo, SgxState, + SGX_STATE, + }; use crate::state::{Request, REQUESTS}; use crate::ContractError; + use crate::ContractError::BadLength; + + pub fn bootstrap_key_manger( + deps: DepsMut, + compute_mrenclave: RawMrenclave, + key_manager_mrenclave: RawMrenclave, + tcb_info: RawTcbInfo, + ) -> Result { + let _: Mrenclave = hex::decode(&compute_mrenclave)? + .try_into() + .map_err(|_| BadLength)?; + let _: Mrenclave = hex::decode(&key_manager_mrenclave)? + .try_into() + .map_err(|_| BadLength)?; + // TODO(hu55a1n1): validate TcbInfo + + let sgx_state = SgxState { + compute_mrenclave: compute_mrenclave.clone(), + key_manager_mrenclave: key_manager_mrenclave.clone(), + tcb_info: tcb_info.clone(), + }; + + if SGX_STATE.exists(deps.storage) { + return Err(ContractError::Unauthorized); + } + + SGX_STATE.save(deps.storage, &sgx_state)?; + + Ok(Response::new() + .add_attribute("action", "bootstrap_key_manger") + .add_attribute("compute_mrenclave", compute_mrenclave) + .add_attribute("key_manager_mrenclave", key_manager_mrenclave) + .add_attribute("tcb_info", tcb_info)) + } pub fn enqueue_join_request( deps: DepsMut, @@ -79,6 +123,7 @@ pub mod execute { #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { + QueryMsg::GetSgxState {} => to_json_binary(&query::get_sgx_state(deps)?), QueryMsg::GetRequests {} => to_json_binary(&query::get_requests(deps)?), } } @@ -86,8 +131,20 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { pub mod query { use cosmwasm_std::{Deps, Order, StdResult}; - use crate::msg::query::GetRequestsResponse; - use crate::state::{RawNonce, Request, REQUESTS}; + use crate::msg::query::{GetRequestsResponse, GetSgxStateResponse}; + use crate::state::{RawNonce, Request, SgxState, REQUESTS, SGX_STATE}; + + pub fn get_sgx_state(deps: Deps) -> StdResult { + let SgxState { + compute_mrenclave, + key_manager_mrenclave, + .. + } = SGX_STATE.load(deps.storage)?; + Ok(GetSgxStateResponse { + compute_mrenclave, + key_manager_mrenclave, + }) + } pub fn get_requests(deps: Deps) -> StdResult { Ok(GetRequestsResponse { diff --git a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/error.rs b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/error.rs index 06cf7ce..f482c7b 100644 --- a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/error.rs +++ b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/error.rs @@ -11,33 +11,24 @@ pub enum ContractError { #[error("Unauthorized")] Unauthorized, - #[error("Invalid pubkey")] - InvalidPubKey(PublicKeyError), -} - -#[derive(Error, Debug)] -pub enum PublicKeyError { #[error("Not Secp256K1")] K256(K256Error), + #[error("Invalid hex")] Hex(FromHexError), + + #[error("Invalid length")] + BadLength, } -impl> From for ContractError { - fn from(e: T) -> Self { - let e = e.into(); - Self::InvalidPubKey(e) - } -} - -impl From for PublicKeyError { +impl From for ContractError { fn from(e: K256Error) -> Self { - PublicKeyError::K256(e) + ContractError::K256(e) } } -impl From for PublicKeyError { +impl From for ContractError { fn from(e: FromHexError) -> Self { - PublicKeyError::Hex(e) + ContractError::Hex(e) } } diff --git a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/msg.rs b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/msg.rs index 81508df..b8b69c4 100644 --- a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/msg.rs +++ b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/msg.rs @@ -5,12 +5,20 @@ pub struct InstantiateMsg; #[cw_serde] pub enum ExecuteMsg { + BootstrapKeyManager(execute::BootstrapKeyManagerMsg), JoinComputeNode(execute::JoinComputeNodeMsg), } pub mod execute { use super::*; + #[cw_serde] + pub struct BootstrapKeyManagerMsg { + pub compute_mrenclave: String, + pub key_manager_mrenclave: String, + pub tcb_info: String, + } + #[cw_serde] pub struct JoinComputeNodeMsg { pub io_exchange_key: String, @@ -22,6 +30,8 @@ pub mod execute { #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { + #[returns(query::GetSgxStateResponse)] + GetSgxState {}, #[returns(query::GetRequestsResponse)] GetRequests {}, } @@ -29,7 +39,13 @@ pub enum QueryMsg { pub mod query { use super::*; - use crate::state::{RawNonce, Request}; + use crate::state::{RawMrenclave, RawNonce, Request}; + + #[cw_serde] + pub struct GetSgxStateResponse { + pub compute_mrenclave: RawMrenclave, + pub key_manager_mrenclave: RawMrenclave, + } #[cw_serde] pub struct GetRequestsResponse { diff --git a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/state.rs b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/state.rs index 415b20f..56a0bc6 100644 --- a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/state.rs +++ b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/state.rs @@ -4,6 +4,10 @@ use cw_storage_plus::{Item, Map}; pub type RawNonce = String; pub type RawPublicKey = String; pub type RawAddress = String; +pub type RawMrenclave = String; +pub type RawTcbInfo = String; + +pub type Mrenclave = [u8; 32]; #[cw_serde] pub struct State { @@ -15,5 +19,13 @@ pub enum Request { JoinComputeNode((RawPublicKey, RawAddress)), } +#[cw_serde] +pub struct SgxState { + pub compute_mrenclave: RawMrenclave, + pub key_manager_mrenclave: RawMrenclave, + pub tcb_info: RawTcbInfo, +} + pub const STATE: Item = Item::new("state"); pub const REQUESTS: Map<&RawNonce, Request> = Map::new("requests"); +pub const SGX_STATE: Item = Item::new("sgxstate"); From de5314122ab1654896c6f61ff396f45486e38673 Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Mon, 1 Jan 2024 12:37:08 -0800 Subject: [PATCH 2/3] Use Deque for REQUESTS storage --- .../contracts/cw-tee-mtcs/src/contract.rs | 16 ++++++++-------- .../contracts/cw-tee-mtcs/src/state.rs | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/contract.rs b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/contract.rs index 2e7793b..3c076a3 100644 --- a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/contract.rs +++ b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/contract.rs @@ -108,10 +108,12 @@ pub mod execute { let _ = deps.api.addr_validate(&address)?; let _ = hex::decode(&nonce); - REQUESTS.save( + REQUESTS.push_back( deps.storage, - &nonce, - &Request::JoinComputeNode((io_exchange_key.clone(), address)), + &( + nonce, + Request::JoinComputeNode((io_exchange_key.clone(), address)), + ), )?; Ok(Response::new() @@ -129,10 +131,10 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { } pub mod query { - use cosmwasm_std::{Deps, Order, StdResult}; + use cosmwasm_std::{Deps, StdResult}; use crate::msg::query::{GetRequestsResponse, GetSgxStateResponse}; - use crate::state::{RawNonce, Request, SgxState, REQUESTS, SGX_STATE}; + use crate::state::{SgxState, REQUESTS, SGX_STATE}; pub fn get_sgx_state(deps: Deps) -> StdResult { let SgxState { @@ -148,9 +150,7 @@ pub mod query { pub fn get_requests(deps: Deps) -> StdResult { Ok(GetRequestsResponse { - requests: REQUESTS - .range(deps.storage, None, None, Order::Ascending) - .collect::>>()?, + requests: REQUESTS.iter(deps.storage)?.flat_map(|r| r.ok()).collect(), }) } } diff --git a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/state.rs b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/state.rs index 56a0bc6..3fd17e7 100644 --- a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/state.rs +++ b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/state.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cw_storage_plus::{Item, Map}; +use cw_storage_plus::{Deque, Item}; pub type RawNonce = String; pub type RawPublicKey = String; @@ -27,5 +27,5 @@ pub struct SgxState { } pub const STATE: Item = Item::new("state"); -pub const REQUESTS: Map<&RawNonce, Request> = Map::new("requests"); +pub const REQUESTS: Deque<(RawNonce, Request)> = Deque::new("requests"); pub const SGX_STATE: Item = Item::new("sgxstate"); From 57c14e3ef934e9ed8e9fffb0a344bb4d8b73193f Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Mon, 1 Jan 2024 12:49:32 -0800 Subject: [PATCH 3/3] Use Item for REQUESTS storage --- .../contracts/cw-tee-mtcs/src/contract.rs | 15 +++++++-------- .../contracts/cw-tee-mtcs/src/state.rs | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/contract.rs b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/contract.rs index 3c076a3..5063f10 100644 --- a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/contract.rs +++ b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/contract.rs @@ -108,13 +108,12 @@ pub mod execute { let _ = deps.api.addr_validate(&address)?; let _ = hex::decode(&nonce); - REQUESTS.push_back( - deps.storage, - &( - nonce, - Request::JoinComputeNode((io_exchange_key.clone(), address)), - ), - )?; + let mut requests = REQUESTS.may_load(deps.storage)?.unwrap_or_default(); + requests.push(( + nonce, + Request::JoinComputeNode((io_exchange_key.clone(), address)), + )); + REQUESTS.save(deps.storage, &requests)?; Ok(Response::new() .add_attribute("action", "enqueue_request") @@ -150,7 +149,7 @@ pub mod query { pub fn get_requests(deps: Deps) -> StdResult { Ok(GetRequestsResponse { - requests: REQUESTS.iter(deps.storage)?.flat_map(|r| r.ok()).collect(), + requests: REQUESTS.load(deps.storage)?, }) } } diff --git a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/state.rs b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/state.rs index 3fd17e7..98acc2b 100644 --- a/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/state.rs +++ b/bisenzone-cw-mvp/contracts/cw-tee-mtcs/src/state.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cw_storage_plus::{Deque, Item}; +use cw_storage_plus::Item; pub type RawNonce = String; pub type RawPublicKey = String; @@ -27,5 +27,5 @@ pub struct SgxState { } pub const STATE: Item = Item::new("state"); -pub const REQUESTS: Deque<(RawNonce, Request)> = Deque::new("requests"); +pub const REQUESTS: Item> = Item::new("requests"); pub const SGX_STATE: Item = Item::new("sgxstate");