diff --git a/.github/workflows/build-deploy-docs.yml b/.github/workflows/build-deploy-docs.yml index e9399acd8..2611594a8 100644 --- a/.github/workflows/build-deploy-docs.yml +++ b/.github/workflows/build-deploy-docs.yml @@ -14,8 +14,6 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 - with: - submodules: 'recursive' - name: Setup uses: ./.github/actions/setup - name: Setup mdBook diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index b45183cda..f040be490 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -31,8 +31,6 @@ jobs: name: Build "${{ inputs.name }}" steps: - uses: actions/checkout@v3 - with: - submodules: 'recursive' - name: Setup Git shell: bash run: | diff --git a/.github/workflows/run-benchmarks.yml b/.github/workflows/run-benchmarks.yml index 8a2e70a15..3c869e1a5 100644 --- a/.github/workflows/run-benchmarks.yml +++ b/.github/workflows/run-benchmarks.yml @@ -9,8 +9,6 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 - with: - submodules: 'recursive' - name: Setup uses: ./.github/actions/setup - name: Benchmark diff --git a/.github/workflows/run-checks.yml b/.github/workflows/run-checks.yml index 1c91e3dbb..4a8442209 100644 --- a/.github/workflows/run-checks.yml +++ b/.github/workflows/run-checks.yml @@ -9,8 +9,6 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 - with: - submodules: 'recursive' - name: Setup uses: ./.github/actions/setup - name: Format diff --git a/Cargo.toml b/Cargo.toml index f084740e1..9c7e39972 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,10 @@ members = [ "tlspuffin", "sshpuffin", "tlspuffin-claims", +] + +exclude = [ + "crates/openssl-src-111", "crates/libressl-src", "crates/wolfssl", "crates/wolfssl-sys", @@ -14,7 +18,6 @@ members = [ "crates/libssh-sys", ] -exclude = ["crates/openssl-src-111"] [workspace.package] version = "0.1.0" @@ -33,6 +36,7 @@ wolfssl-sys = { path = "crates/wolfssl-sys" } wolfssl-src = { path = "crates/wolfssl-src" } openssl-src = { path = "crates/openssl-src-111" } libressl-src = { path = "crates/libressl-src" } +libssh-sys = { path = "crates/libssh-sys" } security-claims = { path = "tlspuffin-claims" } [profile.release] diff --git a/README.md b/README.md index 21e0a3fd2..19c1951f6 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@
- Stability - + Build status @@ -44,20 +44,20 @@ _Disclaimer: The term "symbolic-model-guided" should not be confused with symbol ## Description Fuzzing implementations of cryptographic protocols is challenging. -In contrast to traditional fuzzing of file formats, cryptographic protocols require a +In contrast to traditional fuzzing of file formats, cryptographic protocols require a specific flow of cryptographic and mutually dependent messages to reach deep protocol states. -The specification of the TLS protocol describes sound flows of messages and cryptographic +The specification of the TLS protocol describes sound flows of messages and cryptographic operations. -Although the specification has been formally verified multiple times with significant -results, a gap has emerged from the fact that implementations of the same protocol have +Although the specification has been formally verified multiple times with significant +results, a gap has emerged from the fact that implementations of the same protocol have not undergone the same logical analysis. -Because the development of cryptographic protocols is error-prone, multiple security -vulnerabilities have already been discovered in implementations in TLS which are not +Because the development of cryptographic protocols is error-prone, multiple security +vulnerabilities have already been discovered in implementations in TLS which are not present in its specification. -Inspired by symbolic protocol verification, we present a reference implementation of a -fuzzer named tlspuffin which employs a concrete semantic to execute TLS 1.2 and 1.3 symbolic traces. +Inspired by symbolic protocol verification, we present a reference implementation of a +fuzzer named tlspuffin which employs a concrete semantic to execute TLS 1.2 and 1.3 symbolic traces. In fact attacks which mix \TLS versions are in scope of this implementation. This method allows us to utilize a genetic fuzzing algorithm to fuzz protocol flows, which is described by the following three stages. @@ -67,14 +67,14 @@ which is described by the following three stages. * A security violation oracle supervises executions for the absence of vulnerabilities. -The novel approach allows rediscovering known vulnerabilities, which are out-of-scope for -classical bit-level fuzzers. This proves that it is capable of reaching critical protocol +The novel approach allows rediscovering known vulnerabilities, which are out-of-scope for +classical bit-level fuzzers. This proves that it is capable of reaching critical protocol states. -In contrast to the promising methodology no new vulnerabilities were found by tlspuffin. -This can can be explained by the fact that the implementation effort of TLS protocol -primitives and extensions is high and not all features of the specification have been +In contrast to the promising methodology no new vulnerabilities were found by tlspuffin. +This can can be explained by the fact that the implementation effort of TLS protocol +primitives and extensions is high and not all features of the specification have been implemented. -Nonetheless, the innovating approach is promising in terms of quickly reaching high edge +Nonetheless, the innovating approach is promising in terms of quickly reaching high edge coverage, expressiveness of executable protocol traces and stable and extensible implementation. @@ -83,11 +83,11 @@ coverage, expressiveness of executable protocol traces and stable and extensible * Uses the [LibAFL fuzzing framework](https://github.com/AFLplusplus/LibAFL) * Fuzzer which is inspired by the [Dolev-Yao symbolic model](https://en.wikipedia.org/wiki/Dolev%E2%80%93Yao_model) used in protocol verification * Domain specific mutators for Protocol Fuzzing! -* Supported Libraries Under Test: +* Supported Libraries Under Test: * OpenSSL 1.0.1f, 1.0.2u, 1.1.1k * LibreSSL 3.3.3 * wolfSSL 5.1.0 - 5.4.0 -* Reproducible for each LUT. We use Git submodules to link to forks this are in the [tlspuffin organisation](https://github.com/tlspuffin) +* Reproducible for each LUT. We use sources from forks this are in the [tlspuffin organisation](https://github.com/tlspuffin) * 70% Test Coverage * Writtin in Rust! @@ -115,7 +115,6 @@ Build the project: ```bash git clone https://github.com/tlspuffin/tlspuffin.git -git submodule update --init --recursive cargo build ``` @@ -190,7 +189,7 @@ ASAN_OPTIONS=abort_on_error=1 \ cargo run --bin tlspuffin --features asan -- --cores 0-3 ``` -It is important to enable `abort_on_error`, +It is important to enable `abort_on_error`, else the fuzzer workers fail to restart on crashes. #### Compiling with ASAN using rustc @@ -278,4 +277,3 @@ Note that tlspuffin also contains code/modification from external projects. See Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. - diff --git a/crates/libressl-src/Cargo.toml b/crates/libressl-src/Cargo.toml index 837d0a305..02d3b20b9 100644 --- a/crates/libressl-src/Cargo.toml +++ b/crates/libressl-src/Cargo.toml @@ -11,11 +11,13 @@ exclude = ['libressl/*'] [features] default = [ ] sancov = [] -vendored-libressl333 = [] asan = [] # TODO gcov_analysis = [] # TODO llvm_cov_analysis = [] # TODO +libressl333 = [] +libresslmaster = [] + [dependencies] -security-claims = "0.1.0" +security-claims = { path = "../../tlspuffin-claims" } autotools = "0.2" diff --git a/crates/libressl-src/src/lib.rs b/crates/libressl-src/src/lib.rs index 647bd65a2..dd3523a78 100644 --- a/crates/libressl-src/src/lib.rs +++ b/crates/libressl-src/src/lib.rs @@ -8,10 +8,12 @@ use std::{ process::Command, }; -const REF: &str = if cfg!(feature = "vendored-libressl333") { +const REF: &str = if cfg!(feature = "libressl333") { "fuzz-v3.3.3" -} else { +} else if cfg!(feature = "libresslmaster") { "master" +} else { + panic!("Unknown version of LibreSSL requested!") }; fn clone(dest: &PathBuf) -> std::io::Result<()> { diff --git a/crates/libssh-sys/Cargo.toml b/crates/libssh-sys/Cargo.toml index 5e0638c81..e73b3c559 100644 --- a/crates/libssh-sys/Cargo.toml +++ b/crates/libssh-sys/Cargo.toml @@ -5,8 +5,8 @@ edition = "2021" build = "build.rs" [features] - -vendored-libssh0104 = [] +libssh0104 = [] +libsshmaster = [] [dependencies] diff --git a/crates/libssh-sys/build.rs b/crates/libssh-sys/build.rs index f018f70b2..ab8e23b35 100644 --- a/crates/libssh-sys/build.rs +++ b/crates/libssh-sys/build.rs @@ -15,10 +15,12 @@ impl bindgen::callbacks::ParseCallbacks for IgnoreMacros { } } -const REF: &str = if cfg!(feature = "vendored-libssh0104") { +const REF: &str = if cfg!(feature = "libssh0104") { "libssh-0.10.4" -} else { +} else if cfg!(feature = "libsshmaster") { "master" +} else { + panic!("Unknown version of libssh requested!") }; fn clone(dest: &str) -> std::io::Result<()> { diff --git a/crates/openssl-src-111/Cargo.toml b/crates/openssl-src-111/Cargo.toml index 98a7365f3..375fe52bd 100644 --- a/crates/openssl-src-111/Cargo.toml +++ b/crates/openssl-src-111/Cargo.toml @@ -48,24 +48,19 @@ asan = ["libressl-src?/asan"] # Export coverage during runtime gcov_analysis = ["libressl-src?/gcov_analysis"] llvm_cov_analysis = ["libressl-src?/llvm_cov_analysis"] -# Use openssl101f submodule + openssl101f = [] -# Use openssl102u submodule openssl102u = [] openssl111k = [] openssl111j = [] openssl111u = [] openssl312 = [] -libressl333 = ["libressl-src", "libressl", "libressl-src/vendored-libressl333"] +libressl333 = ["libressl-src", "libressl", "libressl-src/libressl333"] libressl = [] -[workspace] -members = ['testcrate'] -exclude = ['target'] - [dependencies] cc = "1.0" bindgen = "0.69.1" -security-claims = "0.1.0" -libressl-src = { version = "111.0.0", optional = true } +security-claims = { path = "../../tlspuffin-claims" } +libressl-src = { path = "../libressl-src", optional = true } diff --git a/crates/openssl-src-111/src/combined.rs b/crates/openssl-src-111/src/combined.rs index 31c1568ce..c7c167892 100644 --- a/crates/openssl-src-111/src/combined.rs +++ b/crates/openssl-src-111/src/combined.rs @@ -1,3 +1,59 @@ +#[cfg(not(any( + feature = "libressl", + feature = "openssl101f", + feature = "openssl102u", + feature = "openssl111k", + feature = "openssl111j", + feature = "openssl111u", + feature = "openssl312" +)))] +compile_error!(concat!( + "You need to select one feature in [", + "'libressl', ", + "'openssl101f', ", + "'openssl102u', ", + "'openssl111k', ", + "'openssl111j', ", + "'openssl111u', ", + "'openssl312'", + "]" +)); + +#[cfg(any( + all(feature = "libressl", feature = "openssl101f"), + all(feature = "libressl", feature = "openssl102u"), + all(feature = "libressl", feature = "openssl111k"), + all(feature = "libressl", feature = "openssl111j"), + all(feature = "libressl", feature = "openssl111u"), + all(feature = "libressl", feature = "openssl312"), + all(feature = "openssl101f", feature = "openssl102u"), + all(feature = "openssl101f", feature = "openssl111k"), + all(feature = "openssl101f", feature = "openssl111j"), + all(feature = "openssl101f", feature = "openssl111u"), + all(feature = "openssl101f", feature = "openssl312"), + all(feature = "openssl102u", feature = "openssl111k"), + all(feature = "openssl102u", feature = "openssl111j"), + all(feature = "openssl102u", feature = "openssl111u"), + all(feature = "openssl102u", feature = "openssl312"), + all(feature = "openssl111k", feature = "openssl111j"), + all(feature = "openssl111k", feature = "openssl111u"), + all(feature = "openssl111k", feature = "openssl312"), + all(feature = "openssl111j", feature = "openssl111u"), + all(feature = "openssl111j", feature = "openssl312"), + all(feature = "openssl111u", feature = "openssl312"), +))] +compile_error!(concat!( + "Incompatible features requested. Only one of [", + "'libressl', ", + "'openssl101f', ", + "'openssl102u', ", + "'openssl111k', ", + "'openssl111j', ", + "'openssl111u', ", + "'openssl312'", + "] can be enabled at the same time." +)); + #[cfg_attr(feature = "libressl", path = "libressl.rs")] mod openssl; diff --git a/crates/openssl-src-111/src/openssl.rs b/crates/openssl-src-111/src/openssl.rs index d85f985d5..4cd6d1a85 100644 --- a/crates/openssl-src-111/src/openssl.rs +++ b/crates/openssl-src-111/src/openssl.rs @@ -21,20 +21,12 @@ const REF: &str = if cfg!(feature = "openssl101f") { "fuzz-OpenSSL_1_1_1u" } else if cfg!(feature = "openssl312") { "fuzz-OpenSSL_3_1_2" -} else { +} else if cfg!(feature = "master") { "master" +} else { + panic!("Unknown version of OpenSSL requested!") }; -#[cfg(not(any( - feature = "openssl101f", - feature = "openssl102u", - feature = "openssl111k", - feature = "openssl111j", - feature = "openssl111u", - feature = "openssl312" -)))] -compile_error!("You need to choose an OpenSSL version!"); - fn clone_repo(dest: &str) -> std::io::Result<()> { std::fs::remove_dir_all(dest)?; Command::new("git") diff --git a/crates/wolfssl-src/src/lib.rs b/crates/wolfssl-src/src/lib.rs index dfbcab68b..4f79f7ba5 100644 --- a/crates/wolfssl-src/src/lib.rs +++ b/crates/wolfssl-src/src/lib.rs @@ -58,7 +58,6 @@ fn patch_wolfssl>( } fn clone_wolfssl>(dest: &P, options: &WolfSSLOptions) -> std::io::Result<()> { - //return Ok(()); std::fs::remove_dir_all(dest)?; let status = Command::new("git") .arg("clone") diff --git a/crates/wolfssl-sys/Cargo.toml b/crates/wolfssl-sys/Cargo.toml index be4c36e07..d9d1c3a4b 100644 --- a/crates/wolfssl-sys/Cargo.toml +++ b/crates/wolfssl-sys/Cargo.toml @@ -6,7 +6,7 @@ authors = [] links = "wolfssl" [build-dependencies] -wolfssl-src = "0.1.0" +wolfssl-src = { path = "../wolfssl-src" } [features] @@ -16,12 +16,12 @@ fix-CVE-2022-39173 = [] fix-CVE-2022-42905 = [] wolfssl-disable-postauth = [] -vendored-wolfssl430 = [] -vendored-wolfssl510 = [] -vendored-wolfssl520 = [] -vendored-wolfssl530 = [] -vendored-wolfssl540 = [] -vendored-master = [] +wolfssl430 = [] +wolfssl510 = [] +wolfssl520 = [] +wolfssl530 = [] +wolfssl540 = [] +master = [] sancov = [] asan = [] diff --git a/crates/wolfssl-sys/build.rs b/crates/wolfssl-sys/build.rs index 6c3c42432..cf4789bea 100644 --- a/crates/wolfssl-sys/build.rs +++ b/crates/wolfssl-sys/build.rs @@ -1,21 +1,68 @@ +#[cfg(not(any( + feature = "wolfssl540", + feature = "wolfssl530", + feature = "wolfssl520", + feature = "wolfssl510", + feature = "wolfssl430", + feature = "master", +)))] +compile_error!(concat!( + "You need to select one feature in [", + "'wolfssl430', ", + "'wolfssl510', ", + "'wolfssl520', ", + "'wolfssl530', ", + "'wolfssl540', ", + "'master'", + "]" +)); + +#[cfg(any( + all(feature = "wolfssl430", feature = "wolfssl510"), + all(feature = "wolfssl430", feature = "wolfssl520"), + all(feature = "wolfssl430", feature = "wolfssl530"), + all(feature = "wolfssl430", feature = "wolfssl540"), + all(feature = "wolfssl430", feature = "master"), + all(feature = "wolfssl510", feature = "wolfssl520"), + all(feature = "wolfssl510", feature = "wolfssl530"), + all(feature = "wolfssl510", feature = "wolfssl540"), + all(feature = "wolfssl510", feature = "master"), + all(feature = "wolfssl520", feature = "wolfssl530"), + all(feature = "wolfssl520", feature = "wolfssl540"), + all(feature = "wolfssl520", feature = "master"), + all(feature = "wolfssl530", feature = "wolfssl540"), + all(feature = "wolfssl530", feature = "master"), + all(feature = "wolfssl540", feature = "master"), +))] +compile_error!(concat!( + "Incompatible features requested. Only one of [", + "'wolfssl430', ", + "'wolfssl510', ", + "'wolfssl520', ", + "'wolfssl530', ", + "'wolfssl540', ", + "'master'", + "] can be enabled at the same time." +)); + use std::{env, path::PathBuf}; use wolfssl_src::{build, WolfSSLOptions}; -const REF: &str = if cfg!(feature = "vendored-wolfssl540") { +const REF: &str = if cfg!(feature = "wolfssl540") { "v5.4.0-stable" -} else if cfg!(feature = "vendored-wolfssl530") { +} else if cfg!(feature = "wolfssl530") { "v5.3.0-stable" -} else if cfg!(feature = "vendored-wolfssl520") { +} else if cfg!(feature = "wolfssl520") { "v5.2.0-stable" -} else if cfg!(feature = "vendored-wolfssl510") { +} else if cfg!(feature = "wolfssl510") { "v5.1.0-stable" -} else if cfg!(feature = "vendored-wolfssl430") { +} else if cfg!(feature = "wolfssl430") { "v4.3.0-stable" -} else if cfg!(feature = "vendored-master") { +} else if cfg!(feature = "master") { "master" } else { - "master" + panic!("Unknown version of WolfSSL requested!") }; fn main() { diff --git a/crates/wolfssl/Cargo.toml b/crates/wolfssl/Cargo.toml index ad5cdd3b6..08e5d0e8c 100644 --- a/crates/wolfssl/Cargo.toml +++ b/crates/wolfssl/Cargo.toml @@ -8,14 +8,10 @@ edition = "2021" wolfssl430 = [] [dependencies] -wolfssl-sys = "0.1.7" +wolfssl-sys = { path = "../wolfssl-sys" } libc = { version = "0.2.126" } foreign-types = { version = "0.5.0" } bitflags = { version = "1.3.2" } log = "0.4.17" - -[dev-dependencies] - -[build-dependencies] diff --git a/puffin/src/lib.rs b/puffin/src/lib.rs index af38609e0..378db3723 100644 --- a/puffin/src/lib.rs +++ b/puffin/src/lib.rs @@ -1,8 +1,5 @@ #![allow(unused_doc_comments)] -#[cfg(all(feature = "openssl-binding", feature = "wolfssl-binding"))] -compile_error!("`Only one binding at the same time is currently supported."); - pub mod agent; pub mod algebra; pub mod claims; diff --git a/sshpuffin/Cargo.toml b/sshpuffin/Cargo.toml index 69ec11350..93acd0755 100644 --- a/sshpuffin/Cargo.toml +++ b/sshpuffin/Cargo.toml @@ -16,7 +16,7 @@ categories.workspace = true claims = ['puffin/claims'] [dependencies] -libssh-sys = { path = "../crates/libssh-sys", features = ["vendored-libssh0104"] } +libssh-sys = { path = "../crates/libssh-sys", features = ["libssh0104"] } puffin = { path = "../puffin" } log = "0.4" diff --git a/tlspuffin/Cargo.toml b/tlspuffin/Cargo.toml index 7779e7fd2..1a6377aa2 100644 --- a/tlspuffin/Cargo.toml +++ b/tlspuffin/Cargo.toml @@ -110,7 +110,7 @@ libressl = [ ] wolfssl430 = [ - "wolfssl-sys/vendored-wolfssl430", + "wolfssl-sys/wolfssl430", "wolfssl/wolfssl430", "tls12", "tls13", @@ -121,7 +121,7 @@ wolfssl430 = [ ] wolfssl510 = [ - "wolfssl-sys/vendored-wolfssl510", + "wolfssl-sys/wolfssl510", "tls12", "tls13", "wolfssl-binding", @@ -133,7 +133,7 @@ wolfssl510 = [ ] wolfssl520 = [ - "wolfssl-sys/vendored-wolfssl520", + "wolfssl-sys/wolfssl520", "tls12", "tls13", "wolfssl-binding", @@ -145,7 +145,7 @@ wolfssl520 = [ ] wolfssl530 = [ - "wolfssl-sys/vendored-wolfssl530", + "wolfssl-sys/wolfssl530", "tls12", "tls13", "wolfssl-binding", @@ -157,7 +157,7 @@ wolfssl530 = [ ] wolfssl540 = [ - "wolfssl-sys/vendored-wolfssl540", + "wolfssl-sys/wolfssl540", "tls12", "tls13", "wolfssl-binding", @@ -175,7 +175,7 @@ fix-CVE-2022-42905 = ["wolfssl-sys?/fix-CVE-2022-42905"] wolfssl-disable-postauth = ["wolfssl-sys?/wolfssl-disable-postauth"] wolfsslmaster = [ - "wolfssl-sys/vendored-master", + "wolfssl-sys/master", "tls12", "tls13", "wolfssl-binding", @@ -244,18 +244,12 @@ ring = { version = "0.16.20", features = ["std"] } webpki = { version = "0.22.0", features = ["alloc", "std"] } sct = "0.7.0" - - # OpenSSL # Up to verison 111 openssl = { version = "0.10.41", features = ["vendored"], optional = true } openssl-sys = { version = "*", features = ["vendored"], optional = true } -# For openssl 305 -#openssl = { git = "https://github.com/tlspuffin/rust-openssl.git", branch = "fuzz-305", features = ["vendored"], optional = true } -#openssl-sys = { git = "https://github.com/tlspuffin/rust-openssl.git", branch = "fuzz-305", features = ["vendored"], optional = true } - foreign-types-openssl = { version = "0.3.1", package = "foreign-types", optional = true } security-claims = { version = "0.1.0", optional = false } diff --git a/tlspuffin/build.rs b/tlspuffin/build.rs index c8646228f..ac25786ef 100644 --- a/tlspuffin/build.rs +++ b/tlspuffin/build.rs @@ -1,5 +1,8 @@ use std::process::Command; +#[cfg(all(feature = "openssl-binding", feature = "wolfssl-binding"))] +compile_error!("Selecting multiple vendored PUT is currently not supported: openssl/libressl and wolfssl feature flags are mutually exclusive."); + fn main() { if cfg!(feature = "asan") { // NOTE adding compiler-rt to rpath for libasan is not straightforward