Prevent potential signature reuse (#667)

* patch audit findings #42

* extend msg signature for substrate relay

* signature verification test

* make proof dependet on call_dispatch crate

* silence clippy

* revert deny exception

* address code review

* since it's not really a proof, call it digest
This commit is contained in:
Andreas Doerr
2021-01-26 14:32:59 +01:00
committed by Bastian Köcher
parent 9414c0d6fe
commit 926520292e
4 changed files with 140 additions and 15 deletions
+64 -10
View File
@@ -297,10 +297,13 @@ async fn run_command(command: cli::Command) -> Result<(), String> {
call: rialto_call.encode(),
},
cli::Origins::Target => {
let mut rialto_origin_signature_message = Vec::new();
rialto_call.encode_to(&mut rialto_origin_signature_message);
millau_account_id.encode_to(&mut rialto_origin_signature_message);
let rialto_origin_signature = rialto_sign.signer.sign(&rialto_origin_signature_message);
let digest = millau_runtime::rialto_account_ownership_digest(
rialto_call.clone(),
millau_account_id.clone(),
rialto_runtime::VERSION.spec_version,
);
let digest_signature = rialto_sign.signer.sign(&digest);
MessagePayload {
spec_version: rialto_runtime::VERSION.spec_version,
@@ -308,7 +311,7 @@ async fn run_command(command: cli::Command) -> Result<(), String> {
origin: CallOrigin::TargetAccount(
millau_account_id,
rialto_origin_public.into(),
rialto_origin_signature.into(),
digest_signature.into(),
),
call: rialto_call.encode(),
}
@@ -445,10 +448,13 @@ async fn run_command(command: cli::Command) -> Result<(), String> {
call: millau_call.encode(),
},
cli::Origins::Target => {
let mut millau_origin_signature_message = Vec::new();
millau_call.encode_to(&mut millau_origin_signature_message);
rialto_account_id.encode_to(&mut millau_origin_signature_message);
let millau_origin_signature = millau_sign.signer.sign(&millau_origin_signature_message);
let digest = rialto_runtime::millau_account_ownership_digest(
millau_call.clone(),
rialto_account_id.clone(),
millau_runtime::VERSION.spec_version,
);
let digest_signature = millau_sign.signer.sign(&digest);
MessagePayload {
spec_version: millau_runtime::VERSION.spec_version,
@@ -456,7 +462,7 @@ async fn run_command(command: cli::Command) -> Result<(), String> {
origin: CallOrigin::TargetAccount(
rialto_account_id,
millau_origin_public.into(),
millau_origin_signature.into(),
digest_signature.into(),
),
call: millau_call.encode(),
}
@@ -517,3 +523,51 @@ async fn estimate_message_delivery_and_dispatch_fee<Fee: Decode, C: Chain, P: En
Decode::decode(&mut &encoded_response.0[..]).map_err(relay_substrate_client::Error::ResponseParseFailed)?;
Ok(decoded_response)
}
#[cfg(test)]
mod tests {
use sp_core::Pair;
use sp_runtime::traits::{IdentifyAccount, Verify};
#[test]
fn millau_signature_is_valid_on_rialto() {
let millau_sign = relay_millau_client::SigningParams::from_suri("//Dave", None).unwrap();
let call = rialto_runtime::Call::System(rialto_runtime::SystemCall::remark(vec![]));
let millau_public: bp_millau::AccountSigner = millau_sign.signer.public().clone().into();
let millau_account_id: bp_millau::AccountId = millau_public.into_account();
let digest = millau_runtime::rialto_account_ownership_digest(
call,
millau_account_id,
rialto_runtime::VERSION.spec_version,
);
let rialto_signer = relay_rialto_client::SigningParams::from_suri("//Dave", None).unwrap();
let signature = rialto_signer.signer.sign(&digest);
assert!(signature.verify(&digest[..], &rialto_signer.signer.public()));
}
#[test]
fn rialto_signature_is_valid_on_millau() {
let rialto_sign = relay_rialto_client::SigningParams::from_suri("//Dave", None).unwrap();
let call = millau_runtime::Call::System(millau_runtime::SystemCall::remark(vec![]));
let rialto_public: bp_rialto::AccountSigner = rialto_sign.signer.public().clone().into();
let rialto_account_id: bp_rialto::AccountId = rialto_public.into_account();
let digest = rialto_runtime::millau_account_ownership_digest(
call,
rialto_account_id,
millau_runtime::VERSION.spec_version,
);
let millau_signer = relay_millau_client::SigningParams::from_suri("//Dave", None).unwrap();
let signature = millau_signer.signer.sign(&digest);
assert!(signature.verify(&digest[..], &millau_signer.signer.public()));
}
}