Skip to content

Commit

Permalink
Merge pull request #1096 from scrtlabs/lior-ibc-tests
Browse files Browse the repository at this point in the history
IBC packet receive tests and bag fixes
  • Loading branch information
liorbond authored Aug 29, 2022
2 parents a0b0bba + b49d664 commit 498d961
Show file tree
Hide file tree
Showing 13 changed files with 299 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ pub fn init(
let ValidatedMessage {
validated_msg,
reply_params,
} = validate_msg(&decrypted_msg, &contract_hash, None)?;
} = validate_msg(&decrypted_msg, &contract_hash, None, None)?;

let mut engine = start_engine(
context,
Expand Down Expand Up @@ -191,10 +191,10 @@ pub fn handle(
contract_hash_for_validation,
} = parse_message(msg, &parsed_sig_info, &parsed_handle_type)?;

let mut canonical_sender_address = CanonicalAddr::from_vec(vec![]);
if should_validate_sig_info || was_msg_encrypted {
canonical_sender_address = to_canonical(sender)?;
}
let canonical_sender_address = match to_canonical(sender) {
Ok(can) => can,
Err(_) => CanonicalAddr::from_vec(vec![]),
};

// There is no signature to verify when the input isn't signed.
// Receiving unsigned messages is only possible in Handle. (Init tx are always signed)
Expand All @@ -215,7 +215,12 @@ pub fn handle(
let mut validated_msg = decrypted_msg.clone();
let mut reply_params: Option<ReplyParams> = None;
if was_msg_encrypted {
let x = validate_msg(&decrypted_msg, &contract_hash, contract_hash_for_validation)?;
let x = validate_msg(
&decrypted_msg,
&contract_hash,
contract_hash_for_validation,
Some(parsed_handle_type.clone()),
)?;
validated_msg = x.validated_msg;
reply_params = x.reply_params;
}
Expand Down Expand Up @@ -337,7 +342,7 @@ pub fn query(
let decrypted_msg = secret_msg.decrypt()?;

let ValidatedMessage { validated_msg, .. } =
validate_msg(&decrypted_msg, &contract_hash, None)?;
validate_msg(&decrypted_msg, &contract_hash, None, None)?;

let mut engine = start_engine(
context,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use cw_types_v1::ibc::IbcPacketReceiveMsg;
use cw_types_v1::results::REPLY_ENCRYPTION_MAGIC_BYTES;
use log::*;

use enclave_ffi_types::EnclaveError;

use cw_types_v010::types::{CanonicalAddr, Coin, HumanAddr};
use enclave_cosmos_types::traits::CosmosAminoPubkey;
use enclave_cosmos_types::types::{
ContractCode, CosmWasmMsg, CosmosPubKey, SigInfo, SignDoc, StdSignDoc,
ContractCode, CosmWasmMsg, CosmosPubKey, HandleType, SigInfo, SignDoc, StdSignDoc,
};
use enclave_crypto::traits::VerifyingKey;
use enclave_crypto::{sha_256, AESKey, Hmac, Kdf, HASH_SIZE, KEY_MANAGER};
use enclave_ffi_types::EnclaveError;

use crate::io::create_callback_signature;
use crate::message::is_ibc_msg;
use crate::types::SecretMessage;

pub type ContractKey = [u8; CONTRACT_KEY_LENGTH];
Expand Down Expand Up @@ -121,6 +122,64 @@ pub fn validate_msg(
msg: &[u8],
contract_hash: &[u8; HASH_SIZE],
contract_hash_for_validation: Option<Vec<u8>>,
handle_type: Option<HandleType>,
) -> Result<ValidatedMessage, EnclaveError> {
match handle_type {
None => validate_basic_msg(msg, contract_hash, contract_hash_for_validation),
Some(h) => match is_ibc_msg(h.clone()) {
false => validate_basic_msg(msg, contract_hash, contract_hash_for_validation),
true => validate_ibc_msg(msg, contract_hash, contract_hash_for_validation, h),
},
}
}

pub fn validate_ibc_msg(
msg: &[u8],
contract_hash: &[u8; HASH_SIZE],
contract_hash_for_validation: Option<Vec<u8>>,
handle_type: HandleType,
) -> Result<ValidatedMessage, EnclaveError> {
match handle_type {
HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => {
let mut parsed_ibc_packet: IbcPacketReceiveMsg =
serde_json::from_slice(&msg.to_vec()).map_err(|err| {
warn!(
"IbcPacketReceive msg got an error while trying to deserialize msg input bytes into json {:?}: {}",
String::from_utf8_lossy(&msg),
err
);
EnclaveError::FailedToDeserialize
})?;

let validated_msg = validate_basic_msg(
parsed_ibc_packet.packet.data.as_slice(),
contract_hash,
contract_hash_for_validation,
)?;
parsed_ibc_packet.packet.data = validated_msg.validated_msg.as_slice().into();

Ok(ValidatedMessage{
validated_msg: serde_json::to_vec(&parsed_ibc_packet).map_err(|err| {
warn!(
"got an error while trying to serialize parsed_ibc_packet msg into bytes {:?}: {}",
parsed_ibc_packet, err
);
EnclaveError::FailedToSerialize
})?,
reply_params: validated_msg.reply_params,
})
}
_ => {
warn!("Malformed message - in IBC, only packet receive message can be encrypted");
Err(EnclaveError::ValidationFailure)
}
}
}

pub fn validate_basic_msg(
msg: &[u8],
contract_hash: &[u8; HASH_SIZE],
contract_hash_for_validation: Option<Vec<u8>>,
) -> Result<ValidatedMessage, EnclaveError> {
if contract_hash_for_validation.is_none() && msg.len() < HEX_ENCODED_HASH_SIZE {
warn!("Malformed message - expected contract code hash to be prepended to the msg");
Expand Down
2 changes: 1 addition & 1 deletion cosmwasm/enclaves/shared/contract-engine/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ pub fn encrypt_output(

if let Some(data) = &mut ok.data {
if is_ibc_output {
warn!("IBC output should not containt any data");
warn!("IBC output should not contain any data");
return Err(EnclaveError::InternalError);
}

Expand Down
6 changes: 3 additions & 3 deletions cosmwasm/enclaves/shared/contract-engine/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,19 +505,19 @@ pub fn parse_message(
})
}
HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => {
// LIORRR TODO: Maybe mark whether the message was encrypted or not.
// TODO: Maybe mark whether the message was encrypted or not.
parse_ibc_packet(
IbcPacketReceiveMsg::default(),
message,
"ibc_packet_receive",
)
}
HandleType::HANDLE_TYPE_IBC_PACKET_ACK => {
// LIORRR TODO: Maybe mark whether the message was encrypted or not.
// TODO: Maybe mark whether the message was encrypted or not.
parse_ibc_packet(IbcPacketAckMsg::default(), message, "ibc_packet_receive")
}
HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => {
// LIORRR TODO: Maybe mark whether the message was encrypted or not.
// TODO: Maybe mark whether the message was encrypted or not.
parse_ibc_packet(
IbcPacketTimeoutMsg::default(),
message,
Expand Down
1 change: 1 addition & 0 deletions cosmwasm/enclaves/shared/cosmwasm-types/v0.10/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ pub struct ContractInfo {

// This should be in correlation with cosmwasm-std/init_handle's InitResponse and HandleResponse
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct ContractResult {
pub messages: Vec<CosmosMsg>,
pub log: Vec<LogAttribute>,
Expand Down
1 change: 1 addition & 0 deletions cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ impl IbcBasicResponse<Empty> {
// the calling chain. (Returning ContractResult::Err will abort processing of this packet
// and not inform the calling chain).
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct IbcReceiveResponse<T = Empty>
where
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ use super::{Event, SubMsg};
/// }
/// ```
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct Response<T = Empty>
where
T: Clone + fmt::Debug + PartialEq,
Expand Down
1 change: 0 additions & 1 deletion go-cosmwasm/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ func (w *Wasmer) Execute(
return nil, gasUsed, err
}

fmt.Printf("LIORRR data %+v", data)
var resp ContractExecResponse
err = json.Unmarshal(data, &resp)

Expand Down
Loading

0 comments on commit 498d961

Please sign in to comment.