Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All IBC tests #1097

Merged
merged 4 commits into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ pub fn handle(
let ParsedMessage {
should_validate_sig_info,
was_msg_encrypted,
should_encrypt_output,
secret_msg,
decrypted_msg,
contract_hash_for_validation,
Expand Down Expand Up @@ -262,7 +263,7 @@ pub fn handle(
secret_msg.nonce, secret_msg.user_public_key
);

if was_msg_encrypted {
if should_encrypt_output {
output = encrypt_output(
output,
&secret_msg,
Expand Down
13 changes: 11 additions & 2 deletions cosmwasm/enclaves/shared/contract-engine/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,10 @@ pub fn encrypt_output(
// More info in: https://github.com/CosmWasm/cosmwasm/blob/v1.0.0/packages/std/src/results/submessages.rs#L192-L198
let encryption_key = calc_encryption_key(&secret_msg.nonce, &secret_msg.user_public_key);
trace!(
"Output before encryption: {:?}",
String::from_utf8_lossy(&output)
"Output before encryption: {:?} {:?} {:?}",
String::from_utf8_lossy(&output),
secret_msg.nonce,
secret_msg.user_public_key
);

let mut output: RawWasmOutput = serde_json::from_slice(&output).map_err(|err| {
Expand Down Expand Up @@ -449,6 +451,7 @@ pub fn encrypt_output(
let reply = Reply {
id: msg_id.unwrap(),
result: SubMsgResult::Err(encrypted_err),
was_msg_encrypted: true,
};
let reply_as_vec = serde_json::to_vec(&reply).map_err(|err| {
warn!(
Expand Down Expand Up @@ -537,6 +540,7 @@ pub fn encrypt_output(
events,
data: ok.data.clone(),
}),
was_msg_encrypted: true,
};

let reply_as_vec = serde_json::to_vec(&reply).map_err(|err| {
Expand Down Expand Up @@ -580,6 +584,8 @@ pub fn encrypt_output(
// We don't encrypt it here to remain with the same type (u64)
sub_msg.id = 0;
}

sub_msg.was_msg_encrypted = true;
}

// v1: The attributes that will be emitted as part of a "wasm" event.
Expand Down Expand Up @@ -649,6 +655,7 @@ pub fn encrypt_output(
events,
data: ok.data.clone(),
}),
was_msg_encrypted: true,
};

let reply_as_vec = serde_json::to_vec(&reply).map_err(|err| {
Expand Down Expand Up @@ -689,6 +696,8 @@ pub fn encrypt_output(
// We don't encrypt it here to remain with the same type (u64)
sub_msg.id = 0;
}

sub_msg.was_msg_encrypted = true;
}

// v1: The attributes that will be emitted as part of a "wasm" event.
Expand Down
157 changes: 61 additions & 96 deletions cosmwasm/enclaves/shared/contract-engine/src/message.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use log::{trace, warn};
use serde::de::DeserializeOwned;
use serde::Serialize;

use cosmos_proto::tx::signing::SignMode;
use cw_types_v010::encoding::Binary;
use cw_types_v1::ibc::{IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcPacketTrait};
use cw_types_v1::ibc::IbcPacketReceiveMsg;
use cw_types_v1::results::{DecryptedReply, Event, Reply, SubMsgResponse, SubMsgResult};
use enclave_cosmos_types::types::{HandleType, SigInfo};
use enclave_ffi_types::EnclaveError;
Expand All @@ -16,6 +14,7 @@ const HEX_ENCODED_HASH_SIZE: usize = 64;
pub struct ParsedMessage {
pub should_validate_sig_info: bool,
pub was_msg_encrypted: bool,
pub should_encrypt_output: bool,
pub secret_msg: SecretMessage,
pub decrypted_msg: Vec<u8>,
pub contract_hash_for_validation: Option<Vec<u8>>,
Expand Down Expand Up @@ -91,81 +90,6 @@ pub fn try_get_decrypted_secret_msg(message: &[u8]) -> Option<DecryptedSecretMes
}
}

pub fn parse_ibc_packet<T>(
_t: T,
message: &[u8],
function_name: &str,
) -> Result<ParsedMessage, EnclaveError>
where
T: IbcPacketTrait<Data = Binary> + Serialize + DeserializeOwned + core::fmt::Debug,
{
let mut parsed_encrypted_ibc_packet: T =
serde_json::from_slice(&message.to_vec()).map_err(|err| {
warn!(
"{} msg got an error while trying to deserialize msg input bytes into json {:?}: {}",
function_name,
String::from_utf8_lossy(&message),
err
);
EnclaveError::FailedToDeserialize
})?;

let tmp_secret_data = get_secret_msg(parsed_encrypted_ibc_packet.get_packet().as_slice());
let mut was_msg_encrypted = false;
let mut orig_secret_msg = tmp_secret_data;

match orig_secret_msg.decrypt() {
Ok(decrypted_msg) => {
// IBC packet was encrypted

trace!(
"{} data before decryption: {:?}",
function_name,
base64::encode(&message)
);

parsed_encrypted_ibc_packet.set_packet(decrypted_msg.as_slice().into());
was_msg_encrypted = true;
}
Err(_) => {
// assume data is not encrypted

trace!(
"{} data was plaintext: {:?}",
function_name,
base64::encode(&message)
);
}
}

let ack = parsed_encrypted_ibc_packet.get_ack();
let tmp_secret_ack = get_secret_msg(ack.unwrap_or(Binary::from(vec![].as_slice())).as_slice());

match tmp_secret_ack.decrypt() {
Ok(ack_data) => {
parsed_encrypted_ibc_packet.set_ack(ack_data.as_slice().into());
was_msg_encrypted = true;

orig_secret_msg = tmp_secret_ack;
}
Err(_) => {}
}

Ok(ParsedMessage {
should_validate_sig_info: false,
was_msg_encrypted,
secret_msg: orig_secret_msg,
decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet).map_err(|err| {
warn!(
"got an error while trying to serialize {} msg into bytes {:?}: {}",
function_name, parsed_encrypted_ibc_packet, err
);
EnclaveError::FailedToSerialize
})?,
contract_hash_for_validation: None,
})
}

// Parse the message that was passed to handle (Based on the assumption that it might be a reply or IBC as well)
pub fn parse_message(
message: &[u8],
Expand All @@ -183,6 +107,7 @@ pub fn parse_message(
Ok(ParsedMessage {
should_validate_sig_info: true,
was_msg_encrypted: true,
should_encrypt_output: true,
secret_msg: decrypted_secret_msg.secret_msg,
decrypted_msg: decrypted_secret_msg.decrypted_msg,
contract_hash_for_validation: None,
Expand All @@ -200,6 +125,7 @@ pub fn parse_message(
Ok(ParsedMessage {
should_validate_sig_info: false,
was_msg_encrypted: false,
should_encrypt_output: false,
secret_msg,
decrypted_msg,
contract_hash_for_validation: None,
Expand Down Expand Up @@ -273,6 +199,7 @@ pub fn parse_message(
return Ok(ParsedMessage {
should_validate_sig_info: false,
was_msg_encrypted: false,
should_encrypt_output: reply.was_msg_encrypted,
secret_msg: reply_secret_msg,
decrypted_msg: serialized_reply,
contract_hash_for_validation: None,
Expand Down Expand Up @@ -377,6 +304,7 @@ pub fn parse_message(
Ok(ParsedMessage {
should_validate_sig_info: true,
was_msg_encrypted: true,
should_encrypt_output: true,
secret_msg: reply_secret_msg,
decrypted_msg: decrypted_reply_as_vec,
contract_hash_for_validation: Some(
Expand Down Expand Up @@ -470,6 +398,7 @@ pub fn parse_message(
Ok(ParsedMessage {
should_validate_sig_info: true,
was_msg_encrypted: true,
should_encrypt_output: true,
secret_msg: reply_secret_msg,
decrypted_msg: decrypted_reply_as_vec,
contract_hash_for_validation: Some(
Expand All @@ -481,7 +410,9 @@ pub fn parse_message(
}
HandleType::HANDLE_TYPE_IBC_CHANNEL_OPEN
| HandleType::HANDLE_TYPE_IBC_CHANNEL_CONNECT
| HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE => {
| HandleType::HANDLE_TYPE_IBC_CHANNEL_CLOSE
| HandleType::HANDLE_TYPE_IBC_PACKET_ACK
| HandleType::HANDLE_TYPE_IBC_PACKET_TIMEOUT => {
trace!(
"parsing {} msg (Should always be plaintext): {:?}",
HandleType::to_export_name(&handle_type),
Expand All @@ -499,30 +430,64 @@ pub fn parse_message(
Ok(ParsedMessage {
should_validate_sig_info: false,
was_msg_encrypted: false,
should_encrypt_output: false,
secret_msg: scrt_msg,
decrypted_msg,
contract_hash_for_validation: None,
})
}
HandleType::HANDLE_TYPE_IBC_PACKET_RECEIVE => {
// 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 => {
// 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 => {
// TODO: Maybe mark whether the message was encrypted or not.
parse_ibc_packet(
IbcPacketTimeoutMsg::default(),
message,
"ibc_packet_timeout",
)
let mut parsed_encrypted_ibc_packet: IbcPacketReceiveMsg =
serde_json::from_slice(&message.to_vec()).map_err(|err| {
warn!(
"Got an error while trying to deserialize input bytes msg into IbcPacketReceiveMsg message {:?}: {}",
String::from_utf8_lossy(&message),
err
);
EnclaveError::FailedToDeserialize
})?;

let tmp_secret_data =
get_secret_msg(parsed_encrypted_ibc_packet.packet.data.as_slice());
let mut was_msg_encrypted = false;
let orig_secret_msg = tmp_secret_data;

match orig_secret_msg.decrypt() {
Ok(decrypted_msg) => {
// IBC packet was encrypted

trace!(
"ibc_packet_receive data before decryption: {:?}",
base64::encode(&message)
);

parsed_encrypted_ibc_packet.packet.data = decrypted_msg.as_slice().into();
was_msg_encrypted = true;
}
Err(_) => {
// assume data is not encrypted

trace!(
"ibc_packet_receive data was plaintext: {:?}",
base64::encode(&message)
);
}
}
Ok(ParsedMessage {
should_validate_sig_info: false,
was_msg_encrypted,
should_encrypt_output: was_msg_encrypted,
secret_msg: orig_secret_msg,
decrypted_msg: serde_json::to_vec(&parsed_encrypted_ibc_packet).map_err(|err| {
warn!(
"got an error while trying to serialize IbcPacketReceive msg into bytes {:?}: {}",
parsed_encrypted_ibc_packet, err
);
EnclaveError::FailedToSerialize
})?,
contract_hash_for_validation: None,
})
}
};
}
Expand Down
46 changes: 0 additions & 46 deletions cosmwasm/enclaves/shared/cosmwasm-types/v1.0/src/ibc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,52 +179,6 @@ pub struct IbcPacketReceiveMsg {
pub relayer: Addr,
}

pub trait IbcPacketTrait {
type Data;
fn get_packet(&self) -> &Self::Data;
fn set_packet(&mut self, data: Self::Data);
fn get_ack(&self) -> Option<Self::Data>;
fn set_ack(&mut self, data: Self::Data);
}

macro_rules! impl_IbcPacketTrait {
($($t:ty),+) => {
$(impl IbcPacketTrait for $t {
type Data = Binary;
fn get_packet(&self) -> &Self::Data {
&self.packet.data
}
fn set_packet(&mut self, data: Self::Data) {
self.packet.data = data;
}
fn get_ack(&self) -> Option<Self::Data> {
return None;
}
fn set_ack(&mut self, _: Self::Data) {
// Nothing to do here
}
})*
}
}

impl_IbcPacketTrait! {IbcPacketReceiveMsg, IbcPacketTimeoutMsg}

impl IbcPacketTrait for IbcPacketAckMsg {
type Data = Binary;
fn get_packet(&self) -> &Self::Data {
&self.original_packet.data
}
fn set_packet(&mut self, data: Self::Data) {
self.original_packet.data = data;
}
fn get_ack(&self) -> Option<Self::Data> {
Some(self.acknowledgement.data.clone())
}
fn set_ack(&mut self, data: Self::Data) {
self.acknowledgement.data = data;
}
}

impl IbcPacketReceiveMsg {
pub fn default() -> Self {
Self {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ pub enum ReplyOn {
Never,
}

fn bool_false() -> bool {
false
}

/// A submessage that will guarantee a `reply` call on success or error, depending on
/// the `reply_on` setting. If you do not need to process the result, use regular messages instead.
///
Expand All @@ -38,6 +42,11 @@ where
pub msg: CosmosMsg<T>,
pub gas_limit: Option<u64>,
pub reply_on: ReplyOn,
// An indication that will be passed to the reply that will indicate wether the original message,
// which is the one who create the submessages, was encrypted or not.
// Plaintext replies will be encrypted only if the original message was.
#[serde(default = "bool_false")]
pub was_msg_encrypted: bool,
}

/// The information we get back from a successful sub message execution,
Expand Down Expand Up @@ -65,6 +74,7 @@ pub struct Reply {
/// Use this to identify which submessage triggered the `reply`.
pub id: Binary,
pub result: SubMsgResult,
pub was_msg_encrypted: bool,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct DecryptedReply {
Expand Down
Loading