From dc83aee72b664f9aad91c81f76037e7b1a876263 Mon Sep 17 00:00:00 2001 From: Christian Langenbacher Date: Fri, 4 Oct 2024 13:22:26 +0200 Subject: [PATCH] [app-libs/stf] implement trusted getter/call verification for an extension-dapp signed getter --- app-libs/stf/src/getter.rs | 44 +++++++++++++++++++++++++++++++- app-libs/stf/src/helpers.rs | 19 ++++++++++++++ app-libs/stf/src/trusted_call.rs | 11 ++++++-- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/app-libs/stf/src/getter.rs b/app-libs/stf/src/getter.rs index 77fe561e05..8da030307e 100644 --- a/app-libs/stf/src/getter.rs +++ b/app-libs/stf/src/getter.rs @@ -34,6 +34,7 @@ use ita_sgx_runtime::{AddressMapping, HashedAddressMapping}; #[cfg(feature = "evm")] use crate::evm_helpers::{get_evm_account, get_evm_account_codes, get_evm_account_storages}; +use crate::helpers::wrap_bytes; use itp_stf_primitives::traits::PoolTransactionValidation; #[cfg(feature = "evm")] use sp_core::{H160, H256}; @@ -143,8 +144,15 @@ impl TrustedGetterSigned { } pub fn verify_signature(&self) -> bool { + let encoded = self.getter.encode(); + + if self.signature.verify(encoded.as_slice(), self.getter.sender_account()) { + return true + }; + + // check if the signature is from an extension-dapp signer. self.signature - .verify(self.getter.encode().as_slice(), self.getter.sender_account()) + .verify(wrap_bytes(&encoded).as_slice(), self.getter.sender_account()) } } @@ -235,3 +243,37 @@ impl ExecuteGetter for PublicGetter { Vec::new() } } + +mod tests { + use super::*; + + #[test] + fn extension_dapp_signature_works() { + // This is a getter, which has been signed in the browser with the `signRaw` interface, + // which wraps the data in `...` + // + // see: https://github.com/polkadot-js/extension/pull/743 + let dapp_extension_signed_getter: Vec = vec![ + 1, 0, 6, 72, 250, 19, 15, 144, 30, 85, 114, 224, 117, 219, 65, 218, 30, 241, 136, 74, + 157, 10, 202, 233, 233, 100, 255, 63, 64, 102, 81, 215, 65, 60, 1, 192, 224, 67, 233, + 49, 104, 156, 159, 245, 26, 136, 60, 88, 123, 174, 171, 67, 215, 124, 223, 112, 16, + 133, 35, 138, 241, 36, 68, 27, 41, 63, 14, 103, 132, 201, 130, 216, 43, 81, 123, 71, + 149, 215, 191, 100, 58, 182, 123, 229, 188, 245, 130, 66, 202, 126, 51, 137, 140, 56, + 44, 176, 239, 51, 131, + ]; + let getter = Getter::decode(&mut dapp_extension_signed_getter.as_slice()).unwrap(); + + if let Getter::trusted(trusted) = getter { + let g = &trusted.getter; + let signature = &trusted.signature; + + // check the signature check itself works + assert!(signature.verify(wrap_bytes(&g.encode()).as_slice(), g.sender_account())); + + // check that the trusted getters method works + assert!(trusted.verify_signature()) + } else { + panic!("invalid getter") + } + } +} diff --git a/app-libs/stf/src/helpers.rs b/app-libs/stf/src/helpers.rs index af3f97f992..fafb0e1472 100644 --- a/app-libs/stf/src/helpers.rs +++ b/app-libs/stf/src/helpers.rs @@ -160,3 +160,22 @@ pub fn shard_creation_info() -> ShardCreationInfo { target_b: maybe_target_b_info, } } + +const PREFIX: &[u8] = b""; +const POSTFIX: &[u8] = b""; + +/// This function reproduces the wrapping that occurs when the +/// `signRaw` interface is used with a signer that is injected +/// from a dapp-extension. +/// +/// See: https://github.com/polkadot-js/extension/pull/743 +pub fn wrap_bytes(data: &[u8]) -> Vec { + let total_len = PREFIX.len() + data.len() + POSTFIX.len(); + let mut bytes_wrapped = Vec::with_capacity(total_len); + + bytes_wrapped.extend_from_slice(PREFIX); + bytes_wrapped.extend_from_slice(data); + bytes_wrapped.extend_from_slice(POSTFIX); + + bytes_wrapped +} diff --git a/app-libs/stf/src/trusted_call.rs b/app-libs/stf/src/trusted_call.rs index 201a098110..262c68d9ea 100644 --- a/app-libs/stf/src/trusted_call.rs +++ b/app-libs/stf/src/trusted_call.rs @@ -24,7 +24,7 @@ use std::vec::Vec; #[cfg(feature = "evm")] use crate::evm_helpers::{create_code_hash, evm_create2_address, evm_create_address}; use crate::{ - helpers::{enclave_signer_account, ensure_enclave_signer_account, shard_vault}, + helpers::{enclave_signer_account, ensure_enclave_signer_account, shard_vault, wrap_bytes}, Getter, }; use codec::{Compact, Decode, Encode}; @@ -199,7 +199,14 @@ impl TrustedCallVerification for TrustedCallSigned { payload.append(&mut self.nonce.encode()); payload.append(&mut mrenclave.encode()); payload.append(&mut shard.encode()); - self.signature.verify(payload.as_slice(), self.call.sender_account()) + + if self.signature.verify(payload.as_slice(), self.call.sender_account()) { + return true + }; + + // check if the signature is from an extension-dapp signer. + self.signature + .verify(wrap_bytes(&payload).as_slice(), self.call.sender_account()) } }