diff --git a/core/src/libtx/slate.rs b/core/src/libtx/slate.rs index 8816d028f..693ac9a99 100644 --- a/core/src/libtx/slate.rs +++ b/core/src/libtx/slate.rs @@ -351,8 +351,8 @@ impl Slate { /// Verifies any messages in the slate's participant data match their signatures pub fn verify_messages(&self, secp: &secp::Secp256k1) -> Result<(), Error> { for p in self.participant_data.iter() { - if let Some(m) = p.message.clone() { - let hashed = blake2b(secp::constants::MESSAGE_SIZE, &[], &m.as_bytes()[..]); + if let Some(msg) = p.message.clone() { + let hashed = blake2b(secp::constants::MESSAGE_SIZE, &[], &msg.as_bytes()[..]); let m = secp::Message::from_slice(&hashed.as_bytes())?; if !aggsig::verify_single( secp, @@ -363,9 +363,16 @@ impl Slate { None, false, ) { + error!("verify_messages - participant message doesn't match signature. Message: \"{}\"", + String::from_utf8_lossy(&msg.as_bytes()[..])); return Err(ErrorKind::Signature( "Optional participant messages do not match signatures".to_owned(), ))?; + } else { + info!( + "verify_messages - signature verified ok. Participant message: \"{}\"", + String::from_utf8_lossy(&msg.as_bytes()[..]) + ); } } } diff --git a/wallet/src/adapters/keybase.rs b/wallet/src/adapters/keybase.rs index 0edbcefcf..aa9353c1c 100644 --- a/wallet/src/adapters/keybase.rs +++ b/wallet/src/adapters/keybase.rs @@ -236,6 +236,10 @@ impl WalletCommAdapter for KeybaseWalletCommAdapter { Ok(mut slate) => { println!("Received message from channel {}", channel); match controller::foreign_single_use(wallet.clone(), |api| { + if let Err(e) = api.verify_slate_messages(&slate) { + error!("Error validating participant messages: {}", e); + return Err(e); + } api.receive_tx(&mut slate, None, None)?; Ok(()) }) { diff --git a/wallet/src/command.rs b/wallet/src/command.rs index 35d9b9fc3..a59daecc2 100644 --- a/wallet/src/command.rs +++ b/wallet/src/command.rs @@ -282,6 +282,10 @@ pub fn receive( let adapter = FileWalletCommAdapter::new(); let mut slate = adapter.receive_tx_async(&args.input)?; controller::foreign_single_use(wallet, |api| { + if let Err(e) = api.verify_slate_messages(&slate) { + error!("Error validating participant messages: {}", e); + return Err(e); + } api.receive_tx(&mut slate, Some(&g_args.account), args.message.clone())?; Ok(()) })?; diff --git a/wallet/src/controller.rs b/wallet/src/controller.rs index b19014a49..60b581f3e 100644 --- a/wallet/src/controller.rs +++ b/wallet/src/controller.rs @@ -563,11 +563,18 @@ where ) -> Box<dyn Future<Item = Slate, Error = Error> + Send> { Box::new(parse_body(req).and_then( //TODO: No way to insert a message from the params - move |mut slate| match api.receive_tx(&mut slate, None, None) { - Ok(_) => ok(slate.clone()), - Err(e) => { - error!("receive_tx: failed with error: {}", e); + move |mut slate| { + if let Err(e) = api.verify_slate_messages(&slate) { + error!("Error validating participant messages: {}", e); err(e) + } else { + match api.receive_tx(&mut slate, None, None) { + Ok(_) => ok(slate.clone()), + Err(e) => { + error!("receive_tx: failed with error: {}", e); + err(e) + } + } } }, )) diff --git a/wallet/src/libwallet/api.rs b/wallet/src/libwallet/api.rs index a253a1de3..13af170b5 100644 --- a/wallet/src/libwallet/api.rs +++ b/wallet/src/libwallet/api.rs @@ -830,6 +830,13 @@ where res } + /// Verifies all messages in the slate match their public keys + pub fn verify_slate_messages(&mut self, slate: &Slate) -> Result<(), Error> { + let secp = Secp256k1::with_caps(ContextFlag::VerifyOnly); + slate.verify_messages(&secp)?; + Ok(()) + } + /// Receive a transaction from a sender pub fn receive_tx( &mut self,