diff --git a/enclave/src/attestation.rs b/enclave/src/attestation.rs index 0444d229fe..6520bfaac9 100644 --- a/enclave/src/attestation.rs +++ b/enclave/src/attestation.rs @@ -543,8 +543,6 @@ pub fn create_attestation_report( let (attn_report, sig, cert) = get_report_from_intel(ias_sock, quote_vec)?; Ok((attn_report, sig, cert)) - - //TODO: return context as well } fn load_spid(filename: &str) -> SgxResult { diff --git a/stf/Cargo.toml b/stf/Cargo.toml index d8173b27f1..e00e4b74ed 100644 --- a/stf/Cargo.toml +++ b/stf/Cargo.toml @@ -19,7 +19,10 @@ std = [ "clap-nested", "log", "base58", - "sc-keystore" + "sc-keystore", + "system/std", + "metadata/std", + "sp-core/std" ] [dependencies] @@ -91,4 +94,3 @@ optional = true [dev-dependencies.sp-keyring] version = '2.0.0-alpha.7' - diff --git a/stf/src/lib.rs b/stf/src/lib.rs index f96def342d..e29e515ac8 100644 --- a/stf/src/lib.rs +++ b/stf/src/lib.rs @@ -186,7 +186,6 @@ pub struct Stf {} mod tests { use super::*; use sp_keyring::AccountKeyring; - use std::vec::Vec; #[test] fn verify_signature_works() { @@ -194,7 +193,12 @@ mod tests { let mrenclave = [0u8; 32]; let shard = ShardIdentifier::default(); - let call = TrustedCall::balance_set_balance(AccountId::from(AccountKeyring::Alice), 42, 42); + let call = TrustedCall::balance_set_balance( + AccountKeyring::Alice.public(), + AccountKeyring::Alice.public(), + 42, + 42, + ); let signed_call = call.sign(&AccountKeyring::Alice.pair(), nonce, &mrenclave, &shard); assert!(signed_call.verify_signature(&mrenclave, &shard)); diff --git a/stf/src/sgx.rs b/stf/src/sgx.rs index a2c7f5b71a..145007fe66 100644 --- a/stf/src/sgx.rs +++ b/stf/src/sgx.rs @@ -28,6 +28,10 @@ impl Encode for OpaqueCall { type Index = u32; type AccountData = balances::AccountData; type AccountInfo = system::AccountInfo; +const ALICE_ENCODED: [u8; 32] = [ + 212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, + 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125, +]; impl Stf { pub fn init_state() -> State { @@ -58,6 +62,7 @@ impl Stf { &storage_value_key("Balances", "ExistentialDeposit"), &1u128.encode(), ); + sp_io::storage::set(&storage_value_key("Sudo", "Key"), &ALICE_ENCODED); }); ext } @@ -76,43 +81,41 @@ impl Stf { _nonce: u32, calls: &mut Vec, ) -> Result<(), StfError> { - ext.execute_with(|| { - match call { - TrustedCall::balance_set_balance(_, who, free_balance, reserved_balance) => { - //TODO: ensure this can only be called by ROOT account - sgx_runtime::BalancesCall::::set_balance( - AccountId32::from(who), - free_balance, - reserved_balance, - ) - .dispatch(sgx_runtime::Origin::ROOT) + ext.execute_with(|| match call { + TrustedCall::balance_set_balance(root, who, free_balance, reserved_balance) => { + Self::ensure_root(root)?; + sgx_runtime::BalancesCall::::set_balance( + AccountId32::from(who), + free_balance, + reserved_balance, + ) + .dispatch(sgx_runtime::Origin::ROOT) + .map_err(|_| StfError::Dispatch)?; + Ok(()) + } + TrustedCall::balance_transfer(from, to, value) => { + let origin = sgx_runtime::Origin::signed(AccountId32::from(from)); + sgx_runtime::BalancesCall::::transfer(AccountId32::from(to), value) + .dispatch(origin) .map_err(|_| StfError::Dispatch)?; - Ok(()) - } - TrustedCall::balance_transfer(from, to, value) => { - let origin = sgx_runtime::Origin::signed(AccountId32::from(from)); - sgx_runtime::BalancesCall::::transfer(AccountId32::from(to), value) - .dispatch(origin) - .map_err(|_| StfError::Dispatch)?; - Ok(()) - } - TrustedCall::balance_unshield(account_incognito, beneficiary, value, shard) => { - Self::unshield_funds(account_incognito, value)?; - calls.push(OpaqueCall( - ( - [SUBSRATEE_REGISTRY_MODULE, UNSHIELD], - beneficiary, - value, - shard, - ) - .encode(), - )); - Ok(()) - } - TrustedCall::balance_shield(who, value) => { - Self::shield_funds(who, value)?; - Ok(()) - } + Ok(()) + } + TrustedCall::balance_unshield(account_incognito, beneficiary, value, shard) => { + Self::unshield_funds(account_incognito, value)?; + calls.push(OpaqueCall( + ( + [SUBSRATEE_REGISTRY_MODULE, UNSHIELD], + beneficiary, + value, + shard, + ) + .encode(), + )); + Ok(()) + } + TrustedCall::balance_shield(who, value) => { + Self::shield_funds(who, value)?; + Ok(()) } }) } @@ -138,6 +141,14 @@ impl Stf { }) } + fn ensure_root(account: AccountId) -> Result<(), StfError> { + if sp_io::storage::get(&storage_value_key("Sudo", "Key")).unwrap() == account.encode() { + Ok(()) + } else { + Err(StfError::MissingPrivileges(account)) + } + } + fn shield_funds(account: AccountId, amount: u128) -> Result<(), StfError> { match get_account_info(&account) { Some(account_info) => sgx_runtime::BalancesCall::::set_balance( @@ -276,6 +287,8 @@ fn key_hash(key: &K, hasher: &StorageHasher) -> Vec { #[derive(Debug, Display)] pub enum StfError { + #[display(fmt = "Insufficient privileges {:?}, are you sure you are root?", _0)] + MissingPrivileges(AccountId), #[display(fmt = "Error dispatching runtime call")] Dispatch, #[display(fmt = "Not enough funds to perform operation")] diff --git a/worker/src/enclave/api.rs b/worker/src/enclave/api.rs index f854d57ef1..f9a7adde1b 100644 --- a/worker/src/enclave/api.rs +++ b/worker/src/enclave/api.rs @@ -285,7 +285,7 @@ pub fn enclave_signing_key(eid: sgx_enclave_id_t) -> SgxResult Ok(ed25519::Public::from_raw(pubkey)) } -pub fn enclave_shielding_key(eid: sgx_enclave_id_t) -> SgxResult> { +pub fn enclave_shielding_key(eid: sgx_enclave_id_t) -> SgxResult { let pubkey_size = 8192; let mut pubkey = vec![0u8; pubkey_size as usize]; @@ -300,9 +300,9 @@ pub fn enclave_shielding_key(eid: sgx_enclave_id_t) -> SgxResult> { return Err(result); } - let rsa_pubkey: Rsa3072PubKey = serde_json::from_slice(&pubkey[..]).unwrap(); + let rsa_pubkey: Rsa3072PubKey = serde_json::from_slice(pubkey.as_slice()).unwrap(); debug!("got RSA pubkey {:?}", rsa_pubkey); - Ok(pubkey) + Ok(rsa_pubkey) } pub fn enclave_query_state( diff --git a/worker/src/tests/commons.rs b/worker/src/tests/commons.rs index 93e5ed4265..9477233af9 100644 --- a/worker/src/tests/commons.rs +++ b/worker/src/tests/commons.rs @@ -39,23 +39,17 @@ pub struct Message { pub sha256: sgx_sha256_hash_t, } +/// Who must be root account pub fn encrypted_set_balance(eid: sgx_enclave_id_t, who: AccountKeyring, nonce: u32) -> Vec { info!("*** Get the public key from the TEE\n"); - let rsa_pubkey: Rsa3072PubKey = enclave_shielding_key(eid) - .map(|key| serde_json::from_slice(key.as_slice()).unwrap()) - .unwrap(); + let rsa_pubkey: Rsa3072PubKey = enclave_shielding_key(eid).unwrap(); info!("deserialized rsa key"); - let call = TrustedCall::balance_set_balance( - who.public(), // TODO: this should actually be ROOT acount - who.public(), - 33, - 44, - ); + let call = TrustedCall::balance_set_balance(who.public(), who.public(), 33, 44); encrypt_payload( rsa_pubkey, call.sign( - &who.pair(), // TODO: this should actually be ROOT acount + &who.pair(), nonce, &enclave_mrenclave(eid).unwrap(), &ShardIdentifier::default(), @@ -66,9 +60,7 @@ pub fn encrypted_set_balance(eid: sgx_enclave_id_t, who: AccountKeyring, nonce: pub fn encrypted_unshield(eid: sgx_enclave_id_t, who: AccountKeyring, nonce: u32) -> Vec { info!("*** Get the public key from the TEE\n"); - let rsa_pubkey: Rsa3072PubKey = enclave_shielding_key(eid) - .map(|key| serde_json::from_slice(key.as_slice()).unwrap()) - .unwrap(); + let rsa_pubkey: Rsa3072PubKey = enclave_shielding_key(eid).unwrap(); info!("deserialized rsa key"); let call = @@ -100,9 +92,7 @@ pub fn test_trusted_getter_signed(who: AccountKeyring) -> TrustedGetterSigned { pub fn encrypted_alice(eid: sgx_enclave_id_t) -> Vec { info!("*** Get the public key from the TEE\n"); - let rsa_pubkey: Rsa3072PubKey = enclave_shielding_key(eid) - .map(|key| serde_json::from_slice(key.as_slice()).unwrap()) - .unwrap(); + let rsa_pubkey: Rsa3072PubKey = enclave_shielding_key(eid).unwrap(); encrypt_payload(rsa_pubkey, AccountKeyring::Alice.encode()) } diff --git a/worker/src/tests/ecalls.rs b/worker/src/tests/ecalls.rs index be40db94c3..593e5c50f3 100644 --- a/worker/src/tests/ecalls.rs +++ b/worker/src/tests/ecalls.rs @@ -24,9 +24,6 @@ use sp_keyring::AccountKeyring; use sgx_types::*; use sp_core::hash::H256; -// TODO: test get_ecc_signing_pubkey -// TODO: test get_rsa_encryption_pubkey - pub fn get_state_works(eid: sgx_enclave_id_t) { let alice = AccountKeyring::Alice; let trusted_getter_signed = test_trusted_getter_signed(alice).encode(); diff --git a/worker/src/tests/integration_tests.rs b/worker/src/tests/integration_tests.rs index bbc0891c51..84b824ba80 100644 --- a/worker/src/tests/integration_tests.rs +++ b/worker/src/tests/integration_tests.rs @@ -56,10 +56,11 @@ pub fn call_worker_encrypted_set_balance_works( port: &str, last_synced_head: Header, ) -> Header { - let (api, nonce, shard) = setup(eid, Some(AccountKeyring::Alice), port); + let root = AccountKeyring::Alice; // Alice is configure as root in our STF + let (api, nonce, shard) = setup(eid, Some(root), port); let req = Request { shard, - cyphertext: encrypted_set_balance(eid, AccountKeyring::Alice, nonce.unwrap()), + cyphertext: encrypted_set_balance(eid, root, nonce.unwrap()), }; let xt: UncheckedExtrinsicV4 = @@ -99,7 +100,6 @@ pub fn forward_encrypted_unshield_works( pub fn init_chain_relay(eid: sgx_enclave_id_t, port: &str) -> Header { let (api, _, _) = setup(eid, None, port); - // crate::init_chain_relay(eid, &api) } diff --git a/worker/src/ws_server.rs b/worker/src/ws_server.rs index ff6f3cc106..c2516ed569 100644 --- a/worker/src/ws_server.rs +++ b/worker/src/ws_server.rs @@ -18,7 +18,6 @@ use std::str; use std::thread; -use sgx_crypto_helper::rsa3072::Rsa3072PubKey; use sgx_types::*; use codec::Encode; @@ -88,10 +87,7 @@ fn handle_get_stf_state_msg(eid: sgx_enclave_id_t, getter_str: &str, shard_str: } fn get_worker_pub_key(eid: sgx_enclave_id_t) -> Message { - // request the key - let pubkey = enclave_shielding_key(eid).unwrap(); - let rsa_pubkey: Rsa3072PubKey = - serde_json::from_str(str::from_utf8(&pubkey[..]).unwrap()).unwrap(); + let rsa_pubkey = enclave_shielding_key(eid).unwrap(); debug!(" [WS Server] RSA pubkey {:?}\n", rsa_pubkey); let rsa_pubkey_json = serde_json::to_string(&rsa_pubkey).unwrap();