Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit

Permalink
Merge pull request #25 from garious/verify-historian-input
Browse files Browse the repository at this point in the history
Verify event signatures before adding log entries
  • Loading branch information
garious authored Feb 28, 2018
2 parents 9009d1b + c3bb207 commit f3dd479
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 7 deletions.
26 changes: 24 additions & 2 deletions src/historian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use std::thread::JoinHandle;
use std::sync::mpsc::{Receiver, Sender};
use std::time::{Duration, SystemTime};
use log::{hash, hash_event, Entry, Event, Sha256Hash};
use log::{hash, hash_event, verify_event, Entry, Event, Sha256Hash};
use serde::Serialize;

pub struct Historian<T> {
Expand Down Expand Up @@ -61,7 +61,9 @@ fn log_events<T: Serialize + Clone>(
}
match receiver.try_recv() {
Ok(event) => {
log_event(sender, num_hashes, end_hash, event)?;
if verify_event(&event) {
log_event(sender, num_hashes, end_hash, event)?;
}
}
Err(TryRecvError::Empty) => {
return Ok(());
Expand Down Expand Up @@ -184,4 +186,24 @@ mod tests {
assert!(entries.len() > 1);
assert!(verify_slice(&entries, &zero));
}

#[test]
fn test_bad_event_attack() {
let zero = Sha256Hash::default();
let hist = Historian::new(&zero, None);
let keypair = generate_keypair();
let mut event0 = sign_hash(hash(b"hello, world"), &keypair);
if let Event::Claim { key, sig, .. } = event0 {
let data = hash(b"goodbye cruel world");
event0 = Event::Claim { key, data, sig };
}
hist.sender.send(event0).unwrap();
drop(hist.sender);
assert_eq!(
hist.thread_hdl.join().unwrap().1,
ExitReason::RecvDisconnected
);
let entries: Vec<Entry<Sha256Hash>> = hist.receiver.iter().collect();
assert_eq!(entries.len(), 0);
}
}
17 changes: 12 additions & 5 deletions src/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,9 @@ pub fn next_tick<T: Serialize>(start_hash: &Sha256Hash, num_hashes: u64) -> Entr
next_entry(start_hash, num_hashes, Event::Tick)
}

/// Verifies self.end_hash is the result of hashing a 'start_hash' 'self.num_hashes' times.
/// If the event is not a Tick, then hash that as well.
pub fn verify_entry<T: Serialize>(entry: &Entry<T>, start_hash: &Sha256Hash) -> bool {
pub fn verify_event<T: Serialize>(event: &Event<T>) -> bool {
use bincode::serialize;
if let Event::Claim { key, ref data, sig } = entry.event {
if let Event::Claim { key, ref data, sig } = *event {
let mut claim_data = serialize(&data).unwrap();
if !verify_signature(&key, &claim_data, &sig) {
return false;
Expand All @@ -202,14 +200,23 @@ pub fn verify_entry<T: Serialize>(entry: &Entry<T>, start_hash: &Sha256Hash) ->
to,
ref data,
sig,
} = entry.event
} = *event
{
let mut sign_data = serialize(&data).unwrap();
sign_data.extend_from_slice(&to);
if !verify_signature(&from, &sign_data, &sig) {
return false;
}
}
true
}

/// Verifies self.end_hash is the result of hashing a 'start_hash' 'self.num_hashes' times.
/// If the event is not a Tick, then hash that as well.
pub fn verify_entry<T: Serialize>(entry: &Entry<T>, start_hash: &Sha256Hash) -> bool {
if !verify_event(&entry.event) {
return false;
}
entry.end_hash == next_hash(start_hash, entry.num_hashes, &entry.event)
}

Expand Down

0 comments on commit f3dd479

Please sign in to comment.