diff --git a/tests/pcap/Cargo.toml b/tests/pcap/Cargo.toml index afb782980ee..d2b3e8891f1 100644 --- a/tests/pcap/Cargo.toml +++ b/tests/pcap/Cargo.toml @@ -6,7 +6,13 @@ publish = false [features] default = [] -ja4 = [] # Older versions of tshark do not support JA4 +# tshark >= 3.7.0 is required for JA3 support +# JA3 support was added to earlier versions, but did not correctly ignore grease values. +# See https://github.com/wireshark/wireshark/commit/03afef0a566ed649ead587fb4c02fc2d8539f3b7 +ja3 = [] +# tshark >= 4.2.0 is required for JA4 support +# See https://gitlab.com/wireshark/wireshark/-/issues/19370 +ja4 = [] download = [] # Download additional pcaps from a list of configured urls [build-dependencies] @@ -14,6 +20,7 @@ anyhow = "1.0.86" bytes = "1.7.1" hex = "0.4.3" reqwest = { version = "0.12.7", features = ["blocking"] } +semver = "1.0.23" [dependencies] anyhow = "1.0.86" diff --git a/tests/pcap/build.rs b/tests/pcap/build.rs index 9d809a85962..92592901ac2 100644 --- a/tests/pcap/build.rs +++ b/tests/pcap/build.rs @@ -4,10 +4,13 @@ use anyhow::*; use bytes::Buf; use bytes::Bytes; +use semver::Version; +use semver::VersionReq; use std::collections::HashMap; use std::fs::File; use std::io::copy; use std::path::Path; +use std::process::Command; use std::thread; use std::time::Duration; @@ -101,7 +104,42 @@ fn download(url: &str) -> Result { bail!("Unable to download: {}", url); } +fn assert_tshark_version() -> Result<()> { + let output = Command::new("tshark").args(["--version"]).output(); + let version = output.ok().and_then(|output| { + let message = std::str::from_utf8(&output.stdout).ok(); + message.and_then(|msg| msg.split_whitespace().find_map(|s| Version::parse(s).ok())) + }); + + let ja3_req = VersionReq::parse(">= 3.7.0")?; + let ja4_req = VersionReq::parse(">= 4.2.0")?; + if let Some(version) = version { + println!("tshark version: {:?}", version); + if cfg!(feature = "ja3") { + assert!( + ja3_req.matches(&version), + "tshark {} required for ja3, {} found", + ja3_req, + version + ); + } + if cfg!(feature = "ja4") { + assert!( + ja4_req.matches(&version), + "tshark {} required for ja4, {} found", + ja4_req, + version + ); + } + } else { + println!("cargo:warning=Unable to determine tshark version"); + } + Ok(()) +} + fn main() -> Result<()> { + assert_tshark_version()?; + let out_dir = std::env::var("OUT_DIR")?; let download_path = Path::new(&out_dir).join("downloaded_pcaps"); diff --git a/tests/pcap/src/handshake_message.rs b/tests/pcap/src/handshake_message.rs index 5b2105aeddc..ec6b9ca7dfa 100644 --- a/tests/pcap/src/handshake_message.rs +++ b/tests/pcap/src/handshake_message.rs @@ -165,6 +165,13 @@ impl Builder { // We currently don't support QUIC let filter = filter + " && !quic"; + // We currently don't support SSLv2. + // Newer versions of tshark automatically filter out SSLv2 by marking + // SSLv2 handshake messages as "tls.ssl2" rather than just "tls". + // To support SSLv2, we'd need to search for both "tls" and "tls.ssl2". + // Instead, let's just explicitly ignore SSLv2 for now. + let filter = filter + " && tls.record.version != 0x0002"; + // tshark associates a LOT of metadata with each packet. Filtering that // metadata (like by using `metadata_whitelist`) significantly improves // both performance and memory usage. diff --git a/tests/pcap/tests/s2n_client_hellos.rs b/tests/pcap/tests/s2n_client_hellos.rs index a68293c7092..ddd395f49c9 100644 --- a/tests/pcap/tests/s2n_client_hellos.rs +++ b/tests/pcap/tests/s2n_client_hellos.rs @@ -42,6 +42,7 @@ fn parsing() -> Result<()> { test_all_client_hellos(|_, _| Ok(())) } +#[cfg(feature = "ja3")] #[test] #[allow(deprecated)] fn ja3_fingerprints() -> Result<()> {