diff --git a/.travis.yml b/.travis.yml index 38458180..aec855ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,9 +5,18 @@ rust: - nightly - 1.14.0 +before_install: + - sudo apt-get -qq update + - sudo apt-get install -y binutils-dev libunwind8-dev + install: - git clone https://github.com/bitcoin/secp256k1.git - cd secp256k1 - ./autogen.sh && ./configure && make && sudo make install - sudo ldconfig /usr/local/lib + - cd .. +script: + - cargo build --verbose + - cargo test --verbose + - if [ "$(rustup show | grep default | grep stable)" != "" ]; then cd fuzz && cargo test --verbose && ./travis-fuzz.sh; fi diff --git a/Cargo.toml b/Cargo.toml index 2c8a65f4..114b43a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ path = "src/lib.rs" [features] bitcoinconsenus = ["bitcoinconsensus"] +fuzztarget = ["secp256k1/fuzztarget"] [dependencies] bitcoin-bech32 = "0.5.1" @@ -29,7 +30,5 @@ strason = "0.3" bitcoinconsensus = { version = "0.16", optional=true } [dependencies.secp256k1] -version = "0.8" -features = [ "rand", "serde" ] - - +version = "0.9" +features = [ "rand" ] diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 4a9439ff..51437b21 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -1,4 +1,3 @@ - [package] name = "bitcoin-fuzz" version = "0.0.1" @@ -8,15 +7,31 @@ publish = false [package.metadata] cargo-fuzz = true -[dependencies.bitcoin] -path = ".." -[dependencies.libfuzzer-sys] -git = "https://github.com/rust-fuzz/libfuzzer-sys.git" +[features] +afl_fuzz = ["afl"] +honggfuzz_fuzz = ["honggfuzz"] + +[dependencies] +honggfuzz = { version = "0.5", optional = true } +afl = { version = "0.3", optional = true } +bitcoin = { path = "..", features = ["fuzztarget"] } # Prevent this from interfering with workspaces [workspace] members = ["."] [[bin]] -name = "fuzzer_script_1" -path = "fuzzers/fuzzer_script_1.rs" +name = "deserialize_block" +path = "fuzz_targets/deserialize_block.rs" + +[[bin]] +name = "deserialize_script" +path = "fuzz_targets/deserialize_script.rs" + +[[bin]] +name = "deserialize_transaction" +path = "fuzz_targets/deserialize_transaction.rs" + +[[bin]] +name = "deserialize_address" +path = "fuzz_targets/deserialize_address.rs" diff --git a/fuzz/fuzz_targets/deserialize_address.rs b/fuzz/fuzz_targets/deserialize_address.rs new file mode 100644 index 00000000..9bb71fe6 --- /dev/null +++ b/fuzz/fuzz_targets/deserialize_address.rs @@ -0,0 +1,57 @@ +extern crate bitcoin; +use std::str::FromStr; +fn do_test(data: &[u8]) { + let data_str = String::from_utf8_lossy(data); + let addr = match bitcoin::util::address::Address::from_str(&data_str) { + Ok(addr) => addr, + Err(_) => return, + }; + assert_eq!(addr.to_string(), data_str); +} + +#[cfg(feature = "afl")] +extern crate afl; +#[cfg(feature = "afl")] +fn main() { + afl::read_stdio_bytes(|data| { + do_test(&data); + }); +} + +#[cfg(feature = "honggfuzz")] +#[macro_use] extern crate honggfuzz; +#[cfg(feature = "honggfuzz")] +fn main() { + loop { + fuzz!(|data| { + do_test(data); + }); + } +} + +#[cfg(test)] +mod tests { + fn extend_vec_from_hex(hex: &str, out: &mut Vec) { + let mut b = 0; + for (idx, c) in hex.as_bytes().iter().enumerate() { + b <<= 4; + match *c { + b'A'...b'F' => b |= c - b'A' + 10, + b'a'...b'f' => b |= c - b'a' + 10, + b'0'...b'9' => b |= c - b'0', + _ => panic!("Bad hex"), + } + if (idx & 1) == 1 { + out.push(b); + b = 0; + } + } + } + + #[test] + fn duplicate_crash() { + let mut a = Vec::new(); + extend_vec_from_hex("00000000", &mut a); + super::do_test(&a); + } +} diff --git a/fuzz/fuzz_targets/deserialize_block.rs b/fuzz/fuzz_targets/deserialize_block.rs new file mode 100644 index 00000000..52ba0cb3 --- /dev/null +++ b/fuzz/fuzz_targets/deserialize_block.rs @@ -0,0 +1,52 @@ +extern crate bitcoin; +type BResult = Result; +fn do_test(data: &[u8]) { + let _: BResult = bitcoin::network::serialize::deserialize(data); +} + +#[cfg(feature = "afl")] +extern crate afl; +#[cfg(feature = "afl")] +fn main() { + afl::read_stdio_bytes(|data| { + do_test(&data); + }); +} + +#[cfg(feature = "honggfuzz")] +#[macro_use] extern crate honggfuzz; +#[cfg(feature = "honggfuzz")] +fn main() { + loop { + fuzz!(|data| { + do_test(data); + }); + } +} + +#[cfg(test)] +mod tests { + fn extend_vec_from_hex(hex: &str, out: &mut Vec) { + let mut b = 0; + for (idx, c) in hex.as_bytes().iter().enumerate() { + b <<= 4; + match *c { + b'A'...b'F' => b |= c - b'A' + 10, + b'a'...b'f' => b |= c - b'a' + 10, + b'0'...b'9' => b |= c - b'0', + _ => panic!("Bad hex"), + } + if (idx & 1) == 1 { + out.push(b); + b = 0; + } + } + } + + #[test] + fn duplicate_crash() { + let mut a = Vec::new(); + extend_vec_from_hex("00", &mut a); + super::do_test(&a); + } +} diff --git a/fuzz/fuzz_targets/deserialize_script.rs b/fuzz/fuzz_targets/deserialize_script.rs new file mode 100644 index 00000000..b336af06 --- /dev/null +++ b/fuzz/fuzz_targets/deserialize_script.rs @@ -0,0 +1,52 @@ +extern crate bitcoin; +type BResult = Result; +fn do_test(data: &[u8]) { + let _: BResult = bitcoin::network::serialize::deserialize(data); +} + +#[cfg(feature = "afl")] +extern crate afl; +#[cfg(feature = "afl")] +fn main() { + afl::read_stdio_bytes(|data| { + do_test(&data); + }); +} + +#[cfg(feature = "honggfuzz")] +#[macro_use] extern crate honggfuzz; +#[cfg(feature = "honggfuzz")] +fn main() { + loop { + fuzz!(|data| { + do_test(data); + }); + } +} + +#[cfg(test)] +mod tests { + fn extend_vec_from_hex(hex: &str, out: &mut Vec) { + let mut b = 0; + for (idx, c) in hex.as_bytes().iter().enumerate() { + b <<= 4; + match *c { + b'A'...b'F' => b |= c - b'A' + 10, + b'a'...b'f' => b |= c - b'a' + 10, + b'0'...b'9' => b |= c - b'0', + _ => panic!("Bad hex"), + } + if (idx & 1) == 1 { + out.push(b); + b = 0; + } + } + } + + #[test] + fn duplicate_crash() { + let mut a = Vec::new(); + extend_vec_from_hex("00", &mut a); + super::do_test(&a); + } +} diff --git a/fuzz/fuzz_targets/deserialize_transaction.rs b/fuzz/fuzz_targets/deserialize_transaction.rs new file mode 100644 index 00000000..13c6772e --- /dev/null +++ b/fuzz/fuzz_targets/deserialize_transaction.rs @@ -0,0 +1,52 @@ +extern crate bitcoin; +type BResult = Result; +fn do_test(data: &[u8]) { + let _: BResult = bitcoin::network::serialize::deserialize(data); +} + +#[cfg(feature = "afl")] +extern crate afl; +#[cfg(feature = "afl")] +fn main() { + afl::read_stdio_bytes(|data| { + do_test(&data); + }); +} + +#[cfg(feature = "honggfuzz")] +#[macro_use] extern crate honggfuzz; +#[cfg(feature = "honggfuzz")] +fn main() { + loop { + fuzz!(|data| { + do_test(data); + }); + } +} + +#[cfg(test)] +mod tests { + fn extend_vec_from_hex(hex: &str, out: &mut Vec) { + let mut b = 0; + for (idx, c) in hex.as_bytes().iter().enumerate() { + b <<= 4; + match *c { + b'A'...b'F' => b |= c - b'A' + 10, + b'a'...b'f' => b |= c - b'a' + 10, + b'0'...b'9' => b |= c - b'0', + _ => panic!("Bad hex"), + } + if (idx & 1) == 1 { + out.push(b); + b = 0; + } + } + } + + #[test] + fn duplicate_crash() { + let mut a = Vec::new(); + extend_vec_from_hex("00", &mut a); + super::do_test(&a); + } +} diff --git a/fuzz/fuzzers/fuzzer_script_1.rs b/fuzz/fuzzers/fuzzer_script_1.rs deleted file mode 100644 index d99c60cb..00000000 --- a/fuzz/fuzzers/fuzzer_script_1.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![no_main] -#[macro_use] extern crate libfuzzer_sys; -extern crate bitcoin; - -type BResult = Result; -//type BResult = Result; -//type BResult = Result; -//type BResult = Result; -//type BResult = Result; - -fuzz_target!(|data: &[u8]| { - let _: BResult = bitcoin::network::serialize::deserialize(data); -}); diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/6c8f7030ea53686eec1c6271d137cb31.000000b2.honggfuzz.cov b/fuzz/hfuzz_workspace/deserialize_script/input/6c8f7030ea53686eec1c6271d137cb31.000000b2.honggfuzz.cov new file mode 100644 index 00000000..89126025 Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/6c8f7030ea53686eec1c6271d137cb31.000000b2.honggfuzz.cov differ diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000000,orig:e17a1beeeeeeeeee8affeeeeeeee1b1b.00000009.honggfuzz.cov b/fuzz/hfuzz_workspace/deserialize_script/input/id:000000,orig:e17a1beeeeeeeeee8affeeeeeeee1b1b.00000009.honggfuzz.cov new file mode 100644 index 00000000..046c235b --- /dev/null +++ b/fuzz/hfuzz_workspace/deserialize_script/input/id:000000,orig:e17a1beeeeeeeeee8affeeeeeeee1b1b.00000009.honggfuzz.cov @@ -0,0 +1 @@ +EEE \ No newline at end of file diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000001,orig:9160b19ef1200000910e61f021200000.00000005.honggfuzz.cov b/fuzz/hfuzz_workspace/deserialize_script/input/id:000001,orig:9160b19ef1200000910e61f021200000.00000005.honggfuzz.cov new file mode 100644 index 00000000..7e0506df --- /dev/null +++ b/fuzz/hfuzz_workspace/deserialize_script/input/id:000001,orig:9160b19ef1200000910e61f021200000.00000005.honggfuzz.cov @@ -0,0 +1 @@ +2q \ No newline at end of file diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000002,orig:01b1b0000000000001b1b00000000000.00000002.honggfuzz.cov b/fuzz/hfuzz_workspace/deserialize_script/input/id:000002,orig:01b1b0000000000001b1b00000000000.00000002.honggfuzz.cov new file mode 100644 index 00000000..40fdece9 --- /dev/null +++ b/fuzz/hfuzz_workspace/deserialize_script/input/id:000002,orig:01b1b0000000000001b1b00000000000.00000002.honggfuzz.cov @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000003,orig:2a351d800d8000000d800dc53a700000.00000005.honggfuzz.cov b/fuzz/hfuzz_workspace/deserialize_script/input/id:000003,orig:2a351d800d8000000d800dc53a700000.00000005.honggfuzz.cov new file mode 100644 index 00000000..b58f0ac2 Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/id:000003,orig:2a351d800d8000000d800dc53a700000.00000005.honggfuzz.cov differ diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000004,orig:00000000000000000000000000000000.00000001.honggfuzz.cov b/fuzz/hfuzz_workspace/deserialize_script/input/id:000004,orig:00000000000000000000000000000000.00000001.honggfuzz.cov new file mode 100644 index 00000000..f76dd238 Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/id:000004,orig:00000000000000000000000000000000.00000001.honggfuzz.cov differ diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000005,orig:00b125700000000085c1a00000000000.00000003.honggfuzz.cov b/fuzz/hfuzz_workspace/deserialize_script/input/id:000005,orig:00b125700000000085c1a00000000000.00000003.honggfuzz.cov new file mode 100644 index 00000000..88a97b1b Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/id:000005,orig:00b125700000000085c1a00000000000.00000003.honggfuzz.cov differ diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000006,orig:39d67a2d05965308ce0891358594659c.00000b1d.honggfuzz.cov b/fuzz/hfuzz_workspace/deserialize_script/input/id:000006,orig:39d67a2d05965308ce0891358594659c.00000b1d.honggfuzz.cov new file mode 100644 index 00000000..65b3d28b Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/id:000006,orig:39d67a2d05965308ce0891358594659c.00000b1d.honggfuzz.cov differ diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000007,orig:90900000000000009090000000000000.00000001.honggfuzz.cov b/fuzz/hfuzz_workspace/deserialize_script/input/id:000007,orig:90900000000000009090000000000000.00000001.honggfuzz.cov new file mode 100644 index 00000000..ce542efa --- /dev/null +++ b/fuzz/hfuzz_workspace/deserialize_script/input/id:000007,orig:90900000000000009090000000000000.00000001.honggfuzz.cov @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000008,orig:91200000000000009120000000000000.00000001.honggfuzz.cov b/fuzz/hfuzz_workspace/deserialize_script/input/id:000008,orig:91200000000000009120000000000000.00000001.honggfuzz.cov new file mode 100644 index 00000000..050ac90e --- /dev/null +++ b/fuzz/hfuzz_workspace/deserialize_script/input/id:000008,orig:91200000000000009120000000000000.00000001.honggfuzz.cov @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000009,orig:93f000000000000093f0000000000000.00000001.honggfuzz.cov b/fuzz/hfuzz_workspace/deserialize_script/input/id:000009,orig:93f000000000000093f0000000000000.00000001.honggfuzz.cov new file mode 100644 index 00000000..39e8d660 --- /dev/null +++ b/fuzz/hfuzz_workspace/deserialize_script/input/id:000009,orig:93f000000000000093f0000000000000.00000001.honggfuzz.cov @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000010,orig:b508300000000000b885b00000000000.00000002.honggfuzz.cov b/fuzz/hfuzz_workspace/deserialize_script/input/id:000010,orig:b508300000000000b885b00000000000.00000002.honggfuzz.cov new file mode 100644 index 00000000..e97e4f0a --- /dev/null +++ b/fuzz/hfuzz_workspace/deserialize_script/input/id:000010,orig:b508300000000000b885b00000000000.00000002.honggfuzz.cov @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000011,orig:b518ccc0e0000000e05c88c5b0000000.00000004.honggfuzz.cov b/fuzz/hfuzz_workspace/deserialize_script/input/id:000011,orig:b518ccc0e0000000e05c88c5b0000000.00000004.honggfuzz.cov new file mode 100644 index 00000000..322cd7d9 --- /dev/null +++ b/fuzz/hfuzz_workspace/deserialize_script/input/id:000011,orig:b518ccc0e0000000e05c88c5b0000000.00000004.honggfuzz.cov @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000012,orig:e540000000000000e540000000000000.00000001.honggfuzz.cov b/fuzz/hfuzz_workspace/deserialize_script/input/id:000012,orig:e540000000000000e540000000000000.00000001.honggfuzz.cov new file mode 100644 index 00000000..d77740a5 --- /dev/null +++ b/fuzz/hfuzz_workspace/deserialize_script/input/id:000012,orig:e540000000000000e540000000000000.00000001.honggfuzz.cov @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000016,src:000000,op:havoc,rep:32 b/fuzz/hfuzz_workspace/deserialize_script/input/id:000016,src:000000,op:havoc,rep:32 new file mode 100644 index 00000000..e589eb18 Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/id:000016,src:000000,op:havoc,rep:32 differ diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000017,src:000000,op:havoc,rep:128 b/fuzz/hfuzz_workspace/deserialize_script/input/id:000017,src:000000,op:havoc,rep:128 new file mode 100644 index 00000000..e5128bb0 --- /dev/null +++ b/fuzz/hfuzz_workspace/deserialize_script/input/id:000017,src:000000,op:havoc,rep:128 @@ -0,0 +1 @@ +CCCACCCތCCCACCCACPC,3·CCCC \ No newline at end of file diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000018,src:000000,op:havoc,rep:32 b/fuzz/hfuzz_workspace/deserialize_script/input/id:000018,src:000000,op:havoc,rep:32 new file mode 100644 index 00000000..33105847 Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/id:000018,src:000000,op:havoc,rep:32 differ diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000019,src:000000,op:havoc,rep:64 b/fuzz/hfuzz_workspace/deserialize_script/input/id:000019,src:000000,op:havoc,rep:64 new file mode 100644 index 00000000..8d3c0bff Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/id:000019,src:000000,op:havoc,rep:64 differ diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000022,src:000007,op:havoc,rep:8 b/fuzz/hfuzz_workspace/deserialize_script/input/id:000022,src:000007,op:havoc,rep:8 new file mode 100644 index 00000000..db3f9a17 Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/id:000022,src:000007,op:havoc,rep:8 differ diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000023,src:000007,op:havoc,rep:128 b/fuzz/hfuzz_workspace/deserialize_script/input/id:000023,src:000007,op:havoc,rep:128 new file mode 100644 index 00000000..6f68c34a --- /dev/null +++ b/fuzz/hfuzz_workspace/deserialize_script/input/id:000023,src:000007,op:havoc,rep:128 @@ -0,0 +1 @@ +ԳԳԳ \ No newline at end of file diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000024,src:000022,op:havoc,rep:64 b/fuzz/hfuzz_workspace/deserialize_script/input/id:000024,src:000022,op:havoc,rep:64 new file mode 100644 index 00000000..020cc92b Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/id:000024,src:000022,op:havoc,rep:64 differ diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000025,src:000023,op:havoc,rep:16 b/fuzz/hfuzz_workspace/deserialize_script/input/id:000025,src:000023,op:havoc,rep:16 new file mode 100644 index 00000000..33bb0c0d Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/id:000025,src:000023,op:havoc,rep:16 differ diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000026,src:000011,op:int16,pos:2,val:+0 b/fuzz/hfuzz_workspace/deserialize_script/input/id:000026,src:000011,op:int16,pos:2,val:+0 new file mode 100644 index 00000000..0fcb929f Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/id:000026,src:000011,op:int16,pos:2,val:+0 differ diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000027,src:000011,op:int32,pos:1,val:+256 b/fuzz/hfuzz_workspace/deserialize_script/input/id:000027,src:000011,op:int32,pos:1,val:+256 new file mode 100644 index 00000000..1b45325a Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/id:000027,src:000011,op:int32,pos:1,val:+256 differ diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000028,src:000011,op:havoc,rep:2 b/fuzz/hfuzz_workspace/deserialize_script/input/id:000028,src:000011,op:havoc,rep:2 new file mode 100644 index 00000000..8b30fd92 Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/id:000028,src:000011,op:havoc,rep:2 differ diff --git a/fuzz/hfuzz_workspace/deserialize_script/input/id:000030,src:000011,op:havoc,rep:16 b/fuzz/hfuzz_workspace/deserialize_script/input/id:000030,src:000011,op:havoc,rep:16 new file mode 100644 index 00000000..9e4de105 Binary files /dev/null and b/fuzz/hfuzz_workspace/deserialize_script/input/id:000030,src:000011,op:havoc,rep:16 differ diff --git a/fuzz/travis-fuzz.sh b/fuzz/travis-fuzz.sh new file mode 100755 index 00000000..e0e9dd47 --- /dev/null +++ b/fuzz/travis-fuzz.sh @@ -0,0 +1,15 @@ +#!/bin/bash +cargo install honggfuzz +set +e +for TARGET in fuzz_targets/*; do + FILENAME=$(basename $TARGET) + FILE="${FILENAME%.*}" + HFUZZ_BUILD_ARGS="--features honggfuzz_fuzz" HFUZZ_RUN_ARGS="-N1000000 --exit_upon_crash -v" cargo hfuzz run $FILE + if [ -f hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT ]; then + cat hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT + for CASE in hfuzz_workspace/$FILE/SIG*; do + cat $CASE | xxd -p + done + exit 1 + fi +done diff --git a/src/blockdata/script.rs b/src/blockdata/script.rs index 585521de..88be676d 100644 --- a/src/blockdata/script.rs +++ b/src/blockdata/script.rs @@ -28,7 +28,6 @@ use std::default::Default; use std::{error, fmt}; use crypto::digest::Digest; -use crypto::sha2::Sha256; use serde; use blockdata::opcodes; @@ -39,6 +38,9 @@ use util::hash::Hash160; #[cfg(feature="bitcoinconsensus")] use std::convert; #[cfg(feature="bitcoinconsensus")] use util::hash::Sha256dHash; +#[cfg(feature="fuzztarget")] use util::sha2::Sha256; +#[cfg(not(feature="fuzztarget"))] use crypto::sha2::Sha256; + #[derive(Clone, PartialEq, Eq, Hash)] /// A Bitcoin script pub struct Script(Box<[u8]>); diff --git a/src/util/address.rs b/src/util/address.rs index d4efde07..95cf6e24 100644 --- a/src/util/address.rs +++ b/src/util/address.rs @@ -241,8 +241,9 @@ impl FromStr for Address { fn from_str(s: &str) -> Result { // bech32 (note that upper or lowercase is allowed but NOT mixed case) - if &s.as_bytes()[0..3] == b"bc1" || &s.as_bytes()[0..3] == b"tb1" || - &s.as_bytes()[0..3] == b"BC1" || &s.as_bytes()[0..3] == b"TB1" { + if s.len() >= 3 && + (&s.as_bytes()[0..3] == b"bc1" || &s.as_bytes()[0..3] == b"tb1" || + &s.as_bytes()[0..3] == b"BC1" || &s.as_bytes()[0..3] == b"TB1") { let witprog = try!(WitnessProgram::from_address(s)); let network = match witprog.network() { bitcoin_bech32::constants::Network::Bitcoin => Network::Bitcoin, diff --git a/src/util/bip32.rs b/src/util/bip32.rs index 7834c7e2..ff785dcb 100644 --- a/src/util/bip32.rs +++ b/src/util/bip32.rs @@ -28,14 +28,15 @@ use crypto::digest::Digest; use crypto::hmac::Hmac; use crypto::mac::Mac; use crypto::ripemd160::Ripemd160; -use crypto::sha2::Sha256; -use crypto::sha2::Sha512; use secp256k1::key::{PublicKey, SecretKey}; use secp256k1::{self, Secp256k1}; use network::constants::Network; use util::base58; +#[cfg(feature="fuzztarget")] use util::sha2::{Sha256, Sha512}; +#[cfg(not(feature="fuzztarget"))] use crypto::sha2::{Sha256, Sha512}; + /// A chain code pub struct ChainCode([u8; 32]); impl_array_newtype!(ChainCode, u8, 32); diff --git a/src/util/contracthash.rs b/src/util/contracthash.rs index 666aa546..1a13fff0 100644 --- a/src/util/contracthash.rs +++ b/src/util/contracthash.rs @@ -20,7 +20,7 @@ use secp256k1::{self, Secp256k1}; use secp256k1::key::{PublicKey, SecretKey}; use blockdata::{opcodes, script}; -use crypto::{hmac, sha2}; +use crypto::hmac; use crypto::mac::Mac; use std::{error, fmt}; @@ -28,6 +28,9 @@ use std::{error, fmt}; use network::constants::Network; use util::{address, hash}; +#[cfg(feature="fuzztarget")] use util::sha2; +#[cfg(not(feature="fuzztarget"))] use crypto::sha2; + /// Encoding of "pubkey here" in script; from bitcoin core `src/script/script.h` static PUBKEY: u8 = 0xFE; diff --git a/src/util/hash.rs b/src/util/hash.rs index ccde8a22..9f1d6743 100644 --- a/src/util/hash.rs +++ b/src/util/hash.rs @@ -26,13 +26,15 @@ use serde; use byteorder::{LittleEndian, WriteBytesExt}; use crypto::digest::Digest; -use crypto::sha2::Sha256; use crypto::ripemd160::Ripemd160; use network::encodable::{ConsensusDecodable, ConsensusEncodable}; use network::serialize::{SimpleEncoder, RawEncoder, BitcoinHash}; use util::uint::Uint256; +#[cfg(feature="fuzztarget")] use util::sha2::Sha256; +#[cfg(not(feature="fuzztarget"))] use crypto::sha2::Sha256; + /// Hex deserialization error #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum HexError { diff --git a/src/util/mod.rs b/src/util/mod.rs index 77e91cce..58f7c79f 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -28,6 +28,9 @@ pub mod iter; pub mod misc; pub mod uint; +#[cfg(feature = "fuzztarget")] +pub mod sha2; + use std::{error, fmt, io}; use bitcoin_bech32; diff --git a/src/util/sha2.rs b/src/util/sha2.rs new file mode 100644 index 00000000..7c819ffb --- /dev/null +++ b/src/util/sha2.rs @@ -0,0 +1,64 @@ +//! fuzztarget-only Sha2 context with a dummy Sha256 and Sha512 hashers. + +use crypto::digest::Digest; +use crypto::sha2; + +#[derive(Clone, Copy)] +/// Dummy Sha256 that hashes the input, but only returns the first byte of output, masking the +/// rest to 0s. +pub struct Sha256 { + state: sha2::Sha256, +} + +impl Sha256 { + /// Constructs a new dummy Sha256 context + pub fn new() -> Sha256 { + Sha256 { + state: sha2::Sha256::new(), + } + } +} + +impl Digest for Sha256 { + fn result(&mut self, data: &mut [u8]) { + self.state.result(data); + for i in 1..32 { + data[i] = 0; + } + } + + fn input(&mut self, data: &[u8]) { self.state.input(data); } + fn reset(&mut self) { self.state.reset(); } + fn output_bits(&self) -> usize { self.state.output_bits() } + fn block_size(&self) -> usize { self.state.block_size() } +} + +#[derive(Clone, Copy)] +/// Dummy Sha512 that hashes the input, but only returns the first byte of output, masking the +/// rest to 0s. +pub struct Sha512 { + state: sha2::Sha512, +} + +impl Sha512 { + /// Constructs a new dummy Sha512 context + pub fn new() -> Sha512 { + Sha512 { + state: sha2::Sha512::new(), + } + } +} + +impl Digest for Sha512 { + fn result(&mut self, data: &mut [u8]) { + self.state.result(data); + for i in 1..64 { + data[i] = 0; + } + } + + fn input(&mut self, data: &[u8]) { self.state.input(data); } + fn reset(&mut self) { self.state.reset(); } + fn output_bits(&self) -> usize { self.state.output_bits() } + fn block_size(&self) -> usize { self.state.block_size() } +}