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

feat: verify particle signatures [NET-539] #1811

Merged
merged 12 commits into from
Oct 11, 2023
11 changes: 11 additions & 0 deletions aquamarine/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

use humantime::FormattedDuration;
use particle_protocol::ParticleError;
justprosh marked this conversation as resolved.
Show resolved Hide resolved
use thiserror::Error;

#[derive(Debug, Error)]
Expand Down Expand Up @@ -44,6 +45,11 @@ pub enum AquamarineApiError {
"AquamarineApiError::AquamarineQueueFull: can't send particle {particle_id:?} to Aquamarine"
)]
AquamarineQueueFull { particle_id: Option<String> },
#[error("AquamarineApiError::SignatureVerificationFailed: particle_id = {particle_id}, error = {err}")]
SignatureVerificationFailed {
particle_id: String,
err: ParticleError,
},
}

impl AquamarineApiError {
Expand All @@ -52,6 +58,11 @@ impl AquamarineApiError {
AquamarineApiError::ParticleExpired { particle_id } => Some(particle_id),
AquamarineApiError::OneshotCancelled { particle_id } => Some(particle_id),
AquamarineApiError::ExecutionTimedOut { particle_id, .. } => Some(particle_id),
// Should it be `None` considering usage of signature as particle id?
// It can compromise valid particles into thinking they are invalid.
// But still there can be a case when signature was generated wrong
// and client will never know about it.
akim-bow marked this conversation as resolved.
Show resolved Hide resolved
AquamarineApiError::SignatureVerificationFailed { .. } => None,
AquamarineApiError::AquamarineDied { particle_id } => particle_id,
AquamarineApiError::AquamarineQueueFull { particle_id, .. } => particle_id,
}
Expand Down
10 changes: 10 additions & 0 deletions aquamarine/src/plumber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ impl<RT: AquaRuntime, F: ParticleFunctionStatic> Plumber<RT, F> {
return;
}

if let Err(err) = particle.verify() {
justprosh marked this conversation as resolved.
Show resolved Hide resolved
tracing::warn!(target: "signature", particle_id = particle.id, "Particle signature verification failed: {err:?}");
self.events
.push_back(Err(AquamarineApiError::SignatureVerificationFailed {
particle_id: particle.id,
err,
}));
return;
}

let builtins = &self.builtins;
let key = (particle.id.clone(), worker_id);
let entry = self.actors.entry(key);
Expand Down
8 changes: 6 additions & 2 deletions crates/local-vm/src/local_vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,15 +303,19 @@ pub fn make_particle(

tracing::info!(particle_id = id, "Made a particle");

Particle {
let mut particle = Particle {
id,
init_peer_id: peer_id,
timestamp,
ttl,
script,
signature: vec![],
data: particle_data,
}
};

particle.sign(key_pair).expect("sign particle");

particle
}

pub fn read_args(
Expand Down
2 changes: 1 addition & 1 deletion crates/nox-tests/tests/local_vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fn make() {
&mut local_vm_a,
false,
Duration::from_secs(20),
&keypair_b,
&keypair_a,
);

let args = read_args(particle, client_b, &mut local_vm_b, &keypair_b)
Expand Down
2 changes: 0 additions & 2 deletions particle-protocol/src/particle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,12 @@ impl Particle {
/// return immutable particle fields in bytes for signing
/// concatenation of:
/// - id as bytes
/// - init_peer_id in base58 as bytes
/// - timestamp u64 as little-endian bytes
/// - ttl u32 as little-endian bytes
/// - script as bytes
fn as_bytes(&self) -> Vec<u8> {
let mut bytes = vec![];
bytes.extend(self.id.as_bytes());
bytes.extend(self.init_peer_id.to_base58().as_bytes());
bytes.extend(self.timestamp.to_le_bytes());
bytes.extend(self.ttl.to_le_bytes());
bytes.extend(self.script.as_bytes());
Expand Down
Empty file added script-storage/Cargo.toml
justprosh marked this conversation as resolved.
Show resolved Hide resolved
Empty file.
1 change: 1 addition & 0 deletions script-storage/src/script_storage.rs
justprosh marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Loading