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

frost-client: force encryption when using HTTP #398

Open
wants to merge 1 commit into
base: key-auth-cleanup
Choose a base branch
from
Open
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
7 changes: 1 addition & 6 deletions coordinator/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ pub struct Args {
#[arg(long, default_value_t = false)]
pub cli: bool,

/// HTTP mode. If enabled, it will use HTTP communication with a
/// FROST server.
#[arg(long, default_value_t = false)]
pub http: bool,

/// The comma-separated usernames of the signers to use in HTTP mode.
/// If HTTP mode is enabled and this is empty, then the session ID
/// will be printed and will have to be shared manually.
Expand Down Expand Up @@ -178,7 +173,7 @@ impl<C: Ciphersuite + 'static> ProcessedArgs<C> {

Ok(ProcessedArgs {
cli: args.cli,
http: args.http,
http: false,
signers,
num_signers,
public_key_package,
Expand Down
148 changes: 72 additions & 76 deletions coordinator/src/comms/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,44 +294,40 @@ impl<C: Ciphersuite> HTTPComms<C> {
})
}

// Encrypts a message for a given recipient if encryption is enabled.
fn encrypt_if_needed(
&mut self,
recipient: &Vec<u8>,
msg: Vec<u8>,
) -> Result<Vec<u8>, Box<dyn Error>> {
if let Some(noise_map) = &mut self.send_noise {
let noise = noise_map
.get_mut(recipient)
.ok_or_eyre("unknown recipient")?;
let mut encrypted = vec![0; 65535];
let len = noise.write_message(&msg, &mut encrypted)?;
encrypted.truncate(len);
Ok(encrypted)
} else {
Ok(msg)
}
// Encrypts a message for a given recipient.
fn encrypt(&mut self, recipient: &Vec<u8>, msg: Vec<u8>) -> Result<Vec<u8>, Box<dyn Error>> {
let noise_map = self
.send_noise
.as_mut()
.expect("send_noise must have been set previously");
let noise = noise_map
.get_mut(recipient)
.ok_or_eyre("unknown recipient")?;
let mut encrypted = vec![0; 65535];
let len = noise.write_message(&msg, &mut encrypted)?;
encrypted.truncate(len);
Ok(encrypted)
}

// Decrypts a message if encryption is enabled.
// Decrypts a message.
// Note that this authenticates the `sender` in the `Msg` struct; if the
// sender is tampered with, the message would fail to decrypt.
fn decrypt_if_needed(&mut self, msg: Msg) -> Result<Msg, Box<dyn Error>> {
if let Some(noise_map) = &mut self.recv_noise {
let noise = noise_map
.get_mut(&msg.sender)
.ok_or_eyre("unknown sender")?;
let mut decrypted = vec![0; 65535];
decrypted.resize(65535, 0);
let len = noise.read_message(&msg.msg, &mut decrypted)?;
decrypted.truncate(len);
Ok(Msg {
sender: msg.sender,
msg: decrypted,
})
} else {
Ok(msg)
}
fn decrypt(&mut self, msg: Msg) -> Result<Msg, Box<dyn Error>> {
let noise_map = self
.recv_noise
.as_mut()
.expect("recv_noise must have been set previously");
let noise = noise_map
.get_mut(&msg.sender)
.ok_or_eyre("unknown sender")?;
let mut decrypted = vec![0; 65535];
decrypted.resize(65535, 0);
let len = noise.read_message(&msg.msg, &mut decrypted)?;
decrypted.truncate(len);
Ok(Msg {
sender: msg.sender,
msg: decrypted,
})
}
}

Expand Down Expand Up @@ -409,48 +405,49 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
self.session_id = Some(r.session_id);
self.num_signers = num_signers;

// If encryption is enabled, create the Noise objects
(self.send_noise, self.recv_noise) = if let (
Some(comm_privkey),
Some(comm_participant_pubkey_getter),
) = (
let (Some(comm_privkey), Some(comm_participant_pubkey_getter)) = (
&self.args.comm_privkey,
&self.args.comm_participant_pubkey_getter,
) {
let mut send_noise_map = HashMap::new();
let mut recv_noise_map = HashMap::new();
for pubkey in &self.args.signers {
let comm_participant_pubkey = comm_participant_pubkey_getter(pubkey).ok_or_eyre("A participant in specified FROST session is not registered in the coordinator's address book")?;
let builder = snow::Builder::new(
"Noise_K_25519_ChaChaPoly_BLAKE2s"
.parse()
.expect("should be a valid cipher"),
);
let send_noise = Noise::new(
builder
.local_private_key(comm_privkey)
.remote_public_key(&comm_participant_pubkey)
.build_initiator()?,
);
let builder = snow::Builder::new(
"Noise_K_25519_ChaChaPoly_BLAKE2s"
.parse()
.expect("should be a valid cipher"),
);
let recv_noise = Noise::new(
builder
.local_private_key(comm_privkey)
.remote_public_key(&comm_participant_pubkey)
.build_responder()?,
);
send_noise_map.insert(pubkey.clone(), send_noise);
recv_noise_map.insert(pubkey.clone(), recv_noise);
}
(Some(send_noise_map), Some(recv_noise_map))
} else {
(None, None)
) else {
return Err(
eyre!("comm_privkey and comm_participant_pubkey_getter must be specified").into(),
);
};

// If encryption is enabled, create the Noise objects

let mut send_noise_map = HashMap::new();
let mut recv_noise_map = HashMap::new();
for pubkey in &self.args.signers {
let comm_participant_pubkey = comm_participant_pubkey_getter(pubkey).ok_or_eyre("A participant in specified FROST session is not registered in the coordinator's address book")?;
let builder = snow::Builder::new(
"Noise_K_25519_ChaChaPoly_BLAKE2s"
.parse()
.expect("should be a valid cipher"),
);
let send_noise = Noise::new(
builder
.local_private_key(comm_privkey)
.remote_public_key(&comm_participant_pubkey)
.build_initiator()?,
);
let builder = snow::Builder::new(
"Noise_K_25519_ChaChaPoly_BLAKE2s"
.parse()
.expect("should be a valid cipher"),
);
let recv_noise = Noise::new(
builder
.local_private_key(comm_privkey)
.remote_public_key(&comm_participant_pubkey)
.build_responder()?,
);
send_noise_map.insert(pubkey.clone(), send_noise);
recv_noise_map.insert(pubkey.clone(), recv_noise);
}
self.send_noise = Some(send_noise_map);
self.recv_noise = Some(recv_noise_map);

eprint!("Waiting for participants to send their commitments...");

loop {
Expand All @@ -467,7 +464,7 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
.json::<server::ReceiveOutput>()
.await?;
for msg in r.msgs {
let msg = self.decrypt_if_needed(msg)?;
let msg = self.decrypt(msg)?;
self.state.recv(msg)?;
}
tokio::time::sleep(Duration::from_secs(2)).await;
Expand Down Expand Up @@ -503,8 +500,7 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
// individually for each recipient.
let pubkeys: Vec<_> = self.pubkeys.keys().cloned().collect();
for recipient in pubkeys {
let msg = self
.encrypt_if_needed(&recipient, serde_json::to_vec(&send_signing_package_args)?)?;
let msg = self.encrypt(&recipient, serde_json::to_vec(&send_signing_package_args)?)?;
let _r = self
.client
.post(format!("{}/send", self.host_port))
Expand Down Expand Up @@ -544,7 +540,7 @@ impl<C: Ciphersuite + 'static> Comms<C> for HTTPComms<C> {
.json::<server::ReceiveOutput>()
.await?;
for msg in r.msgs {
let msg = self.decrypt_if_needed(msg)?;
let msg = self.decrypt(msg)?;
self.state.recv(msg)?;
}
tokio::time::sleep(Duration::from_secs(2)).await;
Expand Down
7 changes: 1 addition & 6 deletions participant/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ pub struct Args {
#[arg(long, default_value_t = false)]
pub cli: bool,

/// HTTP mode. If enabled, it will use HTTP communication with a
/// FROST server.
#[arg(long, default_value_t = false)]
pub http: bool,

/// Public key package to use. Can be a file with a JSON-encoded
/// package, or "". If the file does not exist or if "" is specified,
/// then it will be read from standard input.
Expand Down Expand Up @@ -110,7 +105,7 @@ impl<C: Ciphersuite + 'static> ProcessedArgs<C> {

Ok(ProcessedArgs {
cli: args.cli,
http: args.http,
http: false,
key_package,
ip: args.ip.clone(),
port: args.port,
Expand Down
Loading