diff --git a/.github/workflows/ci_rust.yml b/.github/workflows/ci_rust.yml index 48e93cd8aa8..3c49b90c9cb 100644 --- a/.github/workflows/ci_rust.yml +++ b/.github/workflows/ci_rust.yml @@ -272,7 +272,7 @@ jobs: run: grep "rust-version = \"$(cat ${{env.ROOT_PATH}}/rust-toolchain)\"" ${{env.ROOT_PATH}}/s2n-tls-tokio/Cargo.toml pcaps: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v3 with: @@ -285,7 +285,9 @@ jobs: rustup override set stable - name: Install tshark - run: sudo apt-get install -y tshark + run: | + sudo apt-get install -y tshark + tshark --version - name: Generate bindings working-directory: ${{env.ROOT_PATH}} @@ -299,4 +301,4 @@ jobs: - name: Run tests working-directory: ${{env.PCAP_TEST_PATH}} - run: cargo test + run: cargo test --all-features diff --git a/tests/pcap/Cargo.toml b/tests/pcap/Cargo.toml index bc5aa1bbc2a..5623b854d1e 100644 --- a/tests/pcap/Cargo.toml +++ b/tests/pcap/Cargo.toml @@ -4,6 +4,10 @@ version = "0.1.0" edition = "2021" publish = false +[features] +default = [] +ja4 = [] # Older versions of tshark do not support JA4 + [dependencies] anyhow = "1.0.86" hex = "0.4.3" diff --git a/tests/pcap/src/client_hello.rs b/tests/pcap/src/client_hello.rs index 563d5e37104..c6728ed49a3 100644 --- a/tests/pcap/src/client_hello.rs +++ b/tests/pcap/src/client_hello.rs @@ -23,6 +23,16 @@ impl ClientHello { self.0.packet.metadata(Self::JA3_STR).map(str::to_owned) } + const JA4_HASH: &'static str = "tls.handshake.ja4"; + pub fn ja4_hash(&self) -> Option { + self.0.packet.metadata(Self::JA4_HASH).map(str::to_owned) + } + + const JA4_STR: &'static str = "tls.handshake.ja4_r"; + pub fn ja4_string(&self) -> Option { + self.0.packet.metadata(Self::JA4_STR).map(str::to_owned) + } + pub fn message(&self) -> &HandshakeMessage { &self.0 } diff --git a/tests/pcap/tests/s2n_client_hellos.rs b/tests/pcap/tests/s2n_client_hellos.rs index 1f073aefc33..a68293c7092 100644 --- a/tests/pcap/tests/s2n_client_hellos.rs +++ b/tests/pcap/tests/s2n_client_hellos.rs @@ -14,9 +14,9 @@ fn get_s2n_hello(pcap_hello: &PcapHello) -> Result> { Ok(r?) } -fn test_all_client_hellos(test_fn: F) -> Result<()> +fn test_all_client_hellos(mut test_fn: F) -> Result<()> where - F: FnOnce(PcapHello, Box) -> Result<()> + Copy, + F: FnMut(PcapHello, Box) -> Result<()>, { let pcaps = all_pcaps(); for pcap in pcaps { @@ -62,3 +62,29 @@ fn ja3_fingerprints() -> Result<()> { Ok(()) }) } + +#[cfg(feature = "ja4")] +#[test] +fn ja4_fingerprints() -> Result<()> { + use s2n_tls::fingerprint; + + let mut builder = fingerprint::Builder::new(FingerprintType::JA4)?; + + test_all_client_hellos(|pcap_hello, s2n_hello| { + let mut fingerprint = builder.build(&s2n_hello)?; + + let s2n_ja4_hash = fingerprint + .hash() + .context("s2n failed to calculate ja4 hash")? + .to_owned(); + + let s2n_ja4_str = fingerprint + .raw() + .context("s2n failed to calculate ja4 string")? + .to_owned(); + + assert_eq!(pcap_hello.ja4_hash(), Some(s2n_ja4_hash)); + assert_eq!(pcap_hello.ja4_string(), Some(s2n_ja4_str)); + Ok(()) + }) +}