Merge pull request #3 from informalsystems/hu55a1n1/24-bootstrap-key-manager
Key manager bootstrap
This commit is contained in:
commit
32e9156410
6 changed files with 134 additions and 36 deletions
4
bisenzone-cw-mvp/.gitignore
vendored
4
bisenzone-cw-mvp/.gitignore
vendored
|
@ -1,7 +1,7 @@
|
||||||
# Build results
|
# Build results
|
||||||
/artifacts
|
/artifacts
|
||||||
/target
|
target/
|
||||||
/schema
|
schema/
|
||||||
|
|
||||||
# Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327)
|
# Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327)
|
||||||
.cargo-ok
|
.cargo-ok
|
||||||
|
|
|
@ -5,7 +5,30 @@ the [Key managers proposal v1](https://github.com/informalsystems/tee-mtcs/issue
|
||||||
|
|
||||||
## Testing instructions
|
## 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='{
|
export EXECUTE='{
|
||||||
|
|
|
@ -4,7 +4,7 @@ use cosmwasm_std::{
|
||||||
use cw2::set_contract_version;
|
use cw2::set_contract_version;
|
||||||
|
|
||||||
use crate::error::ContractError;
|
use crate::error::ContractError;
|
||||||
use crate::msg::execute::JoinComputeNodeMsg;
|
use crate::msg::execute::{BootstrapKeyManagerMsg, JoinComputeNodeMsg};
|
||||||
use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
|
use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
|
||||||
use crate::state::{State, STATE};
|
use crate::state::{State, STATE};
|
||||||
|
|
||||||
|
@ -38,6 +38,13 @@ pub fn execute(
|
||||||
msg: ExecuteMsg,
|
msg: ExecuteMsg,
|
||||||
) -> Result<Response, ContractError> {
|
) -> Result<Response, ContractError> {
|
||||||
match msg {
|
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 {
|
ExecuteMsg::JoinComputeNode(JoinComputeNodeMsg {
|
||||||
io_exchange_key,
|
io_exchange_key,
|
||||||
address,
|
address,
|
||||||
|
@ -50,9 +57,46 @@ pub mod execute {
|
||||||
use cosmwasm_std::{DepsMut, Response};
|
use cosmwasm_std::{DepsMut, Response};
|
||||||
use k256::ecdsa::VerifyingKey;
|
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::state::{Request, REQUESTS};
|
||||||
use crate::ContractError;
|
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<Response, ContractError> {
|
||||||
|
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(
|
pub fn enqueue_join_request(
|
||||||
deps: DepsMut,
|
deps: DepsMut,
|
||||||
|
@ -64,11 +108,12 @@ pub mod execute {
|
||||||
let _ = deps.api.addr_validate(&address)?;
|
let _ = deps.api.addr_validate(&address)?;
|
||||||
let _ = hex::decode(&nonce);
|
let _ = hex::decode(&nonce);
|
||||||
|
|
||||||
REQUESTS.save(
|
let mut requests = REQUESTS.may_load(deps.storage)?.unwrap_or_default();
|
||||||
deps.storage,
|
requests.push((
|
||||||
&nonce,
|
nonce,
|
||||||
&Request::JoinComputeNode((io_exchange_key.clone(), address)),
|
Request::JoinComputeNode((io_exchange_key.clone(), address)),
|
||||||
)?;
|
));
|
||||||
|
REQUESTS.save(deps.storage, &requests)?;
|
||||||
|
|
||||||
Ok(Response::new()
|
Ok(Response::new()
|
||||||
.add_attribute("action", "enqueue_request")
|
.add_attribute("action", "enqueue_request")
|
||||||
|
@ -79,21 +124,32 @@ pub mod execute {
|
||||||
#[cfg_attr(not(feature = "library"), entry_point)]
|
#[cfg_attr(not(feature = "library"), entry_point)]
|
||||||
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
|
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
|
||||||
match msg {
|
match msg {
|
||||||
|
QueryMsg::GetSgxState {} => to_json_binary(&query::get_sgx_state(deps)?),
|
||||||
QueryMsg::GetRequests {} => to_json_binary(&query::get_requests(deps)?),
|
QueryMsg::GetRequests {} => to_json_binary(&query::get_requests(deps)?),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod query {
|
pub mod query {
|
||||||
use cosmwasm_std::{Deps, Order, StdResult};
|
use cosmwasm_std::{Deps, StdResult};
|
||||||
|
|
||||||
use crate::msg::query::GetRequestsResponse;
|
use crate::msg::query::{GetRequestsResponse, GetSgxStateResponse};
|
||||||
use crate::state::{RawNonce, Request, REQUESTS};
|
use crate::state::{SgxState, REQUESTS, SGX_STATE};
|
||||||
|
|
||||||
|
pub fn get_sgx_state(deps: Deps) -> StdResult<GetSgxStateResponse> {
|
||||||
|
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<GetRequestsResponse> {
|
pub fn get_requests(deps: Deps) -> StdResult<GetRequestsResponse> {
|
||||||
Ok(GetRequestsResponse {
|
Ok(GetRequestsResponse {
|
||||||
requests: REQUESTS
|
requests: REQUESTS.load(deps.storage)?,
|
||||||
.range(deps.storage, None, None, Order::Ascending)
|
|
||||||
.collect::<StdResult<Vec<(RawNonce, Request)>>>()?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,33 +11,24 @@ pub enum ContractError {
|
||||||
#[error("Unauthorized")]
|
#[error("Unauthorized")]
|
||||||
Unauthorized,
|
Unauthorized,
|
||||||
|
|
||||||
#[error("Invalid pubkey")]
|
|
||||||
InvalidPubKey(PublicKeyError),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
|
||||||
pub enum PublicKeyError {
|
|
||||||
#[error("Not Secp256K1")]
|
#[error("Not Secp256K1")]
|
||||||
K256(K256Error),
|
K256(K256Error),
|
||||||
|
|
||||||
#[error("Invalid hex")]
|
#[error("Invalid hex")]
|
||||||
Hex(FromHexError),
|
Hex(FromHexError),
|
||||||
|
|
||||||
|
#[error("Invalid length")]
|
||||||
|
BadLength,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Into<PublicKeyError>> From<T> for ContractError {
|
impl From<K256Error> for ContractError {
|
||||||
fn from(e: T) -> Self {
|
|
||||||
let e = e.into();
|
|
||||||
Self::InvalidPubKey(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<K256Error> for PublicKeyError {
|
|
||||||
fn from(e: K256Error) -> Self {
|
fn from(e: K256Error) -> Self {
|
||||||
PublicKeyError::K256(e)
|
ContractError::K256(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<FromHexError> for PublicKeyError {
|
impl From<FromHexError> for ContractError {
|
||||||
fn from(e: FromHexError) -> Self {
|
fn from(e: FromHexError) -> Self {
|
||||||
PublicKeyError::Hex(e)
|
ContractError::Hex(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,20 @@ pub struct InstantiateMsg;
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
pub enum ExecuteMsg {
|
pub enum ExecuteMsg {
|
||||||
|
BootstrapKeyManager(execute::BootstrapKeyManagerMsg),
|
||||||
JoinComputeNode(execute::JoinComputeNodeMsg),
|
JoinComputeNode(execute::JoinComputeNodeMsg),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod execute {
|
pub mod execute {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[cw_serde]
|
||||||
|
pub struct BootstrapKeyManagerMsg {
|
||||||
|
pub compute_mrenclave: String,
|
||||||
|
pub key_manager_mrenclave: String,
|
||||||
|
pub tcb_info: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
pub struct JoinComputeNodeMsg {
|
pub struct JoinComputeNodeMsg {
|
||||||
pub io_exchange_key: String,
|
pub io_exchange_key: String,
|
||||||
|
@ -22,6 +30,8 @@ pub mod execute {
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
#[derive(QueryResponses)]
|
#[derive(QueryResponses)]
|
||||||
pub enum QueryMsg {
|
pub enum QueryMsg {
|
||||||
|
#[returns(query::GetSgxStateResponse)]
|
||||||
|
GetSgxState {},
|
||||||
#[returns(query::GetRequestsResponse)]
|
#[returns(query::GetRequestsResponse)]
|
||||||
GetRequests {},
|
GetRequests {},
|
||||||
}
|
}
|
||||||
|
@ -29,7 +39,13 @@ pub enum QueryMsg {
|
||||||
pub mod query {
|
pub mod query {
|
||||||
use super::*;
|
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]
|
#[cw_serde]
|
||||||
pub struct GetRequestsResponse {
|
pub struct GetRequestsResponse {
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
use cosmwasm_schema::cw_serde;
|
use cosmwasm_schema::cw_serde;
|
||||||
use cw_storage_plus::{Item, Map};
|
use cw_storage_plus::Item;
|
||||||
|
|
||||||
pub type RawNonce = String;
|
pub type RawNonce = String;
|
||||||
pub type RawPublicKey = String;
|
pub type RawPublicKey = String;
|
||||||
pub type RawAddress = String;
|
pub type RawAddress = String;
|
||||||
|
pub type RawMrenclave = String;
|
||||||
|
pub type RawTcbInfo = String;
|
||||||
|
|
||||||
|
pub type Mrenclave = [u8; 32];
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
pub struct State {
|
pub struct State {
|
||||||
|
@ -15,5 +19,13 @@ pub enum Request {
|
||||||
JoinComputeNode((RawPublicKey, RawAddress)),
|
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<State> = Item::new("state");
|
pub const STATE: Item<State> = Item::new("state");
|
||||||
pub const REQUESTS: Map<&RawNonce, Request> = Map::new("requests");
|
pub const REQUESTS: Item<Vec<(RawNonce, Request)>> = Item::new("requests");
|
||||||
|
pub const SGX_STATE: Item<SgxState> = Item::new("sgxstate");
|
||||||
|
|
Loading…
Reference in a new issue