Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Validating sha3 of a dapp bundle (#1993)
Browse files Browse the repository at this point in the history
* Validating sha3 of a file

* sha3 in utils

* Removing devtools
  • Loading branch information
tomusdrw authored and gavofyork committed Aug 24, 2016
1 parent 3dd1bdd commit 33e0a23
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 16 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 15 additions & 5 deletions dapps/src/apps/fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ use hyper::Control;
use hyper::status::StatusCode;

use random_filename;
use util::Mutex;
use util::{Mutex, H256};
use util::sha3::sha3;
use page::LocalPageEndpoint;
use handlers::{ContentHandler, AppFetcherHandler, DappHandler};
use endpoint::{Endpoint, EndpointPath, Handler};
Expand Down Expand Up @@ -137,10 +138,12 @@ impl<R: URLHint> AppFetcher<R> {

#[derive(Debug)]
pub enum ValidationError {
ManifestNotFound,
ManifestSerialization(String),
Io(io::Error),
Zip(zip::result::ZipError),
InvalidDappId,
ManifestNotFound,
ManifestSerialization(String),
HashMismatch { expected: H256, got: H256, },
}

impl From<io::Error> for ValidationError {
Expand Down Expand Up @@ -198,8 +201,15 @@ impl DappHandler for DappInstaller {

fn validate_and_install(&self, app_path: PathBuf) -> Result<Manifest, ValidationError> {
trace!(target: "dapps", "Opening dapp bundle at {:?}", app_path);
// TODO [ToDr] Validate file hash
let file = try!(fs::File::open(app_path));
let mut file = try!(fs::File::open(app_path));
let hash = try!(sha3(&mut file));
let dapp_id = try!(self.dapp_id.as_str().parse().map_err(|_| ValidationError::InvalidDappId));
if dapp_id != hash {
return Err(ValidationError::HashMismatch {
expected: dapp_id,
got: hash,
});
}
// Unpack archive
let mut zip = try!(zip::ZipArchive::new(file));
// First find manifest file
Expand Down
4 changes: 2 additions & 2 deletions dapps/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ extern crate rand;
extern crate ethabi;
extern crate jsonrpc_core;
extern crate jsonrpc_http_server;
extern crate mime_guess;
extern crate rustc_serialize;
extern crate parity_dapps;
extern crate ethcore_rpc;
extern crate ethcore_util as util;
extern crate mime_guess;
extern crate rustc_serialize;

mod endpoint;
mod apps;
Expand Down
12 changes: 10 additions & 2 deletions devtools/src/random_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,18 @@ impl RandomTempPath {
}
}

impl AsRef<Path> for RandomTempPath {
fn as_ref(&self) -> &Path {
self.as_path()
}
}

impl Drop for RandomTempPath {
fn drop(&mut self) {
if let Err(e) = fs::remove_dir_all(self.as_path()) {
panic!("Failed to remove temp directory. Here's what prevented this from happening: ({})", e);
if let Err(_) = fs::remove_dir_all(&self) {
if let Err(e) = fs::remove_file(&self) {
panic!("Failed to remove temp directory. Here's what prevented this from happening: ({})", e);
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions util/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ parking_lot = "0.2.6"
using_queue = { path = "using_queue" }
table = { path = "table" }
ansi_term = "0.7"
tiny-keccak= "1.0"

[features]
default = []
Expand Down
1 change: 1 addition & 0 deletions util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ extern crate parking_lot;
pub extern crate using_queue;
pub extern crate table;
extern crate ansi_term;
extern crate tiny_keccak;

pub mod bloom;
pub mod standard;
Expand Down
60 changes: 53 additions & 7 deletions util/src/sha3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
//! Wrapper around tiny-keccak crate.
extern crate sha3 as sha3_ext;

use std::io;
use std::mem::uninitialized;
use tiny_keccak::Keccak;
use bytes::{BytesConvertable, Populatable};
use hash::{H256, FixedHash};
use self::sha3_ext::*;
Expand Down Expand Up @@ -64,12 +66,56 @@ impl<T> Hashable for T where T: BytesConvertable {
}
}

#[test]
fn sha3_empty() {
assert_eq!([0u8; 0].sha3(), SHA3_EMPTY);
}
#[test]
fn sha3_as() {
assert_eq!([0x41u8; 32].sha3(), From::from("59cad5948673622c1d64e2322488bf01619f7ff45789741b15a9f782ce9290a8"));
/// Calculate SHA3 of given stream.
pub fn sha3<R: io::Read>(r: &mut R) -> Result<H256, io::Error> {
let mut output = [0u8; 32];
let mut input = [0u8; 1024];
let mut sha3 = Keccak::new_keccak256();

// read file
loop {
let some = try!(r.read(&mut input));
if some == 0 {
break;
}
sha3.update(&input[0..some]);
}

sha3.finalize(&mut output);
Ok(output.into())
}

#[cfg(test)]
mod tests {
use std::fs;
use std::io::Write;
use super::*;

#[test]
fn sha3_empty() {
assert_eq!([0u8; 0].sha3(), SHA3_EMPTY);
}
#[test]
fn sha3_as() {
assert_eq!([0x41u8; 32].sha3(), From::from("59cad5948673622c1d64e2322488bf01619f7ff45789741b15a9f782ce9290a8"));
}

#[test]
fn should_sha3_a_file() {
// given
use devtools::RandomTempPath;
let path = RandomTempPath::new();
// Prepare file
{
let mut file = fs::File::create(&path).unwrap();
file.write_all(b"something").unwrap();
}

let mut file = fs::File::open(&path).unwrap();
// when
let hash = sha3(&mut file).unwrap();

// then
assert_eq!(format!("{:?}", hash), "68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87");
}
}

0 comments on commit 33e0a23

Please sign in to comment.