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

[Feature]: signatures on WSTS packets need to be verified before feeding them into the state machines #578

Open
2 tasks
xoloki opened this issue Sep 27, 2024 · 4 comments
Assignees
Labels
sbtc bootstrap signer The sBTC Bootstrap Signer. signer communication Communication across sBTC bootstrap signers.

Comments

@xoloki
Copy link
Contributor

xoloki commented Sep 27, 2024

Feature - Verify WSTS packet signatures

1. Description

Applications which use wsts state machines must verify the signatures on the packets before processing them.

1.1 Context & Purpose

All wsts network packets are signed, to guarantee that they come from the purported source, and have not been tampered with. So they must be verified before processing.

But wsts applications typically run both coordinator and signer state machines, so it’s better to verify them outside the state machines themselves. Also, coordinator selection is external to the state machines.

2. Technical Details:

Call Packet::verify with the current signer and coordinator public keys after receiving packets, before feeding them into the machines. Bad packets should be dropped.

2.1 Acceptance Criteria:

  • all packets are verified
  • tests added

3. Related Issues and Pull Requests (optional):

@djordon djordon added the duplicate This issue or pull request already exists label Sep 27, 2024
@djordon
Copy link
Contributor

djordon commented Sep 27, 2024

I think that this is a duplicate of #296.

@djordon djordon added sbtc bootstrap signer The sBTC Bootstrap Signer. signer communication Communication across sBTC bootstrap signers. labels Sep 27, 2024
@djordon djordon added this to the sBTC Release Ready milestone Sep 27, 2024
@xoloki
Copy link
Contributor Author

xoloki commented Sep 27, 2024

I think that this is a duplicate of #296.

I don’t think so. 296 is about signing bitcoin transactions AFAICT.

@djordon
Copy link
Contributor

djordon commented Sep 27, 2024

Oh yeah you are right. It is not a duplicate.

@djordon
Copy link
Contributor

djordon commented Sep 27, 2024

Oh man, we do here

async fn handle_signer_message(&mut self, msg: &network::Msg) -> Result<(), Error> {
if !msg.verify() {
tracing::warn!("unable to verify message");
return Err(Error::InvalidSignature);
}
but do not here
async fn relay_messages_to_wsts_state_machine_until_signature_created(
&mut self,
bitcoin_chain_tip: &model::BitcoinBlockHash,
coordinator_state_machine: &mut wsts_state_machine::CoordinatorStateMachine,
txid: bitcoin::Txid,
) -> Result<wsts::taproot::SchnorrProof, Error> {
loop {
let msg = self.network.receive().await?;
if &msg.bitcoin_chain_tip != bitcoin_chain_tip {
tracing::warn!(?msg, "concurrent wsts signing round message observed");
continue;
}
let message::Payload::WstsMessage(wsts_msg) = msg.inner.payload else {
continue;
};
let packet = wsts::net::Packet {
msg: wsts_msg.inner,
sig: Vec::new(),
};
let (outbound_packet, operation_result) =
match coordinator_state_machine.process_message(&packet) {
Ok(val) => val,
Err(err) => {
tracing::warn!(?packet, reason = %err, "ignoring packet");
continue;
}
};
if let Some(packet) = outbound_packet {
let msg = message::WstsMessage { txid, inner: packet.msg };
self.send_message(msg, bitcoin_chain_tip).await?;
}
match operation_result {
Some(wsts::state_machine::OperationResult::SignTaproot(signature)) => {
return Ok(signature)
}
None => continue,
Some(_) => return Err(Error::UnexpectedOperationResult),
}
}
}

Okay, that fell through the cracks. I think the best place to do this is here:

async fn receive(&mut self) -> Result<Msg, Error> {
loop {
tokio::select! {
_ = self.term.wait_for_shutdown() => {
return Err(Error::SignerShutdown);
},
recv = self.signal_rx.recv() => {
match recv {
Ok(SignerSignal::Event(SignerEvent::P2P(P2PEvent::MessageReceived(msg)))) => {
return Ok(msg);
},
// We're only interested in the above messages, so we ignore
// the rest.
_ => continue,
}
}
}
}
}

That way we won't need to track everything down all the time. Hmmm, this might be straightforward.

@djordon djordon self-assigned this Sep 27, 2024
@djordon djordon removed the duplicate This issue or pull request already exists label Sep 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sbtc bootstrap signer The sBTC Bootstrap Signer. signer communication Communication across sBTC bootstrap signers.
Projects
None yet
Development

No branches or pull requests

2 participants