verify message signature on wallet (#2203)

* add verify_slate_messages for wallet receive

* log the message content

* rustfmt

* verify the sender's message signature when receive_tx in wallet listen

* verify the sender's message signature when send by keybase
This commit is contained in:
Gary Yu 2018-12-23 07:25:02 +08:00 committed by GitHub
parent 7a52c0ecd5
commit 45ca7cff79
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 6 deletions

View file

@ -351,8 +351,8 @@ impl Slate {
/// Verifies any messages in the slate's participant data match their signatures /// Verifies any messages in the slate's participant data match their signatures
pub fn verify_messages(&self, secp: &secp::Secp256k1) -> Result<(), Error> { pub fn verify_messages(&self, secp: &secp::Secp256k1) -> Result<(), Error> {
for p in self.participant_data.iter() { for p in self.participant_data.iter() {
if let Some(m) = p.message.clone() { if let Some(msg) = p.message.clone() {
let hashed = blake2b(secp::constants::MESSAGE_SIZE, &[], &m.as_bytes()[..]); let hashed = blake2b(secp::constants::MESSAGE_SIZE, &[], &msg.as_bytes()[..]);
let m = secp::Message::from_slice(&hashed.as_bytes())?; let m = secp::Message::from_slice(&hashed.as_bytes())?;
if !aggsig::verify_single( if !aggsig::verify_single(
secp, secp,
@ -363,9 +363,16 @@ impl Slate {
None, None,
false, false,
) { ) {
error!("verify_messages - participant message doesn't match signature. Message: \"{}\"",
String::from_utf8_lossy(&msg.as_bytes()[..]));
return Err(ErrorKind::Signature( return Err(ErrorKind::Signature(
"Optional participant messages do not match signatures".to_owned(), "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()[..])
);
} }
} }
} }

View file

@ -236,6 +236,10 @@ impl WalletCommAdapter for KeybaseWalletCommAdapter {
Ok(mut slate) => { Ok(mut slate) => {
println!("Received message from channel {}", channel); println!("Received message from channel {}", channel);
match controller::foreign_single_use(wallet.clone(), |api| { 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)?; api.receive_tx(&mut slate, None, None)?;
Ok(()) Ok(())
}) { }) {

View file

@ -282,6 +282,10 @@ pub fn receive(
let adapter = FileWalletCommAdapter::new(); let adapter = FileWalletCommAdapter::new();
let mut slate = adapter.receive_tx_async(&args.input)?; let mut slate = adapter.receive_tx_async(&args.input)?;
controller::foreign_single_use(wallet, |api| { 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())?; api.receive_tx(&mut slate, Some(&g_args.account), args.message.clone())?;
Ok(()) Ok(())
})?; })?;

View file

@ -563,12 +563,19 @@ where
) -> Box<dyn Future<Item = Slate, Error = Error> + Send> { ) -> Box<dyn Future<Item = Slate, Error = Error> + Send> {
Box::new(parse_body(req).and_then( Box::new(parse_body(req).and_then(
//TODO: No way to insert a message from the params //TODO: No way to insert a message from the params
move |mut slate| match api.receive_tx(&mut slate, None, None) { 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()), Ok(_) => ok(slate.clone()),
Err(e) => { Err(e) => {
error!("receive_tx: failed with error: {}", e); error!("receive_tx: failed with error: {}", e);
err(e) err(e)
} }
}
}
}, },
)) ))
} }

View file

@ -830,6 +830,13 @@ where
res 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 /// Receive a transaction from a sender
pub fn receive_tx( pub fn receive_tx(
&mut self, &mut self,