FoxIO JA4+ conformance vectors
==============================

Almost every file in this directory is not the work of the ja4plus authors. Those
files are copied without change from the FoxIO JA4+ repository, so that the
conformance suite compares ja4plus against the reference output without network
access. The section `Captures the ja4plus authors built` names the exception.

Upstream repository: https://github.com/FoxIO-LLC/ja4
Upstream commit:     27f0cbf9fd3000c072f82a0f7d0361dc99acf6c8

Source paths in that repository:

    pcap/<capture>                  ->  tests/foxio_vectors/<capture>
    python/test/testdata/<capture>.json  ->  tests/foxio_vectors/<capture>.json

This directory holds 37 captures and 37 expected-output files.

`dtls-udp.notest.cap` is present upstream but is not copied here. It carries a
`notest` marker and has no expected-output file, so it is not a vector.

The subdirectory `wireshark_expected/` holds 26 more expected-output
files:

    wireshark/test/testdata/<capture>.json
        ->  tests/foxio_vectors/wireshark_expected/<capture>.json

for each of these captures:

    dhcp.pcapng
    dhcpv6.pcap
    CVE-2018-6794.pcap
    badcurveball.pcap
    browsers-x509.pcapng
    chrome-cloudflare-quic-with-secrets.pcapng
    gre-erspan-vxlan.pcap
    http-empty-useragent.pcap
    http1-with-cookies.pcapng
    http2-with-cookies.pcapng
    https-connect.pcap
    https3-301-get.pcap
    ipv6.pcapng
    latest.pcapng
    socks-https-example.pcap
    socks4-https.pcap
    ssh-r.pcap
    ssh-scp-1050.pcap
    ssh2-malformed.pcap
    ssh2-moloch-crash.pcap
    ssh2.pcapng
    sshv1.pcap
    tcpdump-geneve.pcap
    tls-alpn-h2.pcap
    tls3.pcapng
    v6.pcap

The FoxIO Python implementation emits no JA4D and no JA4D6, so the two DHCP files
under `python/test/testdata` hold an empty array. The Wireshark dissector is the only FoxIO
implementation that writes a reference value for the two methods.
`docs/implementation_notes.md` records the reading.

The 24 files after the two DHCP captures hold the 58 JA4TS values the dissector
writes. The FoxIO Python implementation writes no JA4TS value for any capture, so
these files and the Zeek baselines below are the whole FoxIO reference the method
reaches. `tests/test_foxio_wireshark_ja4ts.py` compares all 58, and issue #515
measured the directory and committed them.

The subdirectory `rust_expected/` holds 11 more expected-output files:

    rust/ja4/src/snapshots/ja4__insta@<capture>.snap
        ->  tests/foxio_vectors/rust_expected/ja4__insta@<capture>.snap

for each of these captures:

    browsers-x509.pcapng
    chrome-cloudflare-quic-with-secrets.pcapng
    gre-erspan-vxlan.pcap
    https-connect.pcap
    latest.pcapng
    quic-tls-handshake.pcapng
    quic-with-several-tls-frames.pcapng
    ssh2.pcapng
    tls-handshake.pcapng
    tls-sni.pcapng
    tls3.pcapng

The FoxIO Python implementation reads no QUIC handshake, it reads no TLS on a port
it does not know, and it reads no ServerHello whose handshake record spans several
TCP segments. The FoxIO Rust implementation reads all three, so each snapshot above
holds a stream that `python/test/testdata/<capture>.json` omits. Issue #138 settles the
first two gaps, issue #151 settles the third, and `tests/test_foxio_rust_parity.py`
holds the measurement.

`gre-erspan-vxlan.pcap` is here for a fourth reason. The FoxIO Python implementation
writes no JA4T value for any capture, so its snapshot holds the one local JA4T value
that reaches D1 of `docs/specs/foxio/JA4T.md`. The two references name that stream by
different addresses, and issue #242 records the pair.

The subdirectory `zeek_expected/` holds 7 btest baselines:

    zeek/tests/Traces/<directory>/<log>
        ->  tests/foxio_vectors/zeek_expected/<directory>/<log>

for each of these baselines:

    Scripts.ja4-conn/conn.log
    Scripts.ja4-conn-tls3/conn.log
    Scripts.ja4-conn-quic/conn.log
    Scripts.ja4-dhcp/ja4d.log
    Scripts.ja4-http1-with-cookies/http.log
    Scripts.ja4-ssh2/ja4ssh.log
    Scripts.ja4-tls-handshake/ssl.log

The FoxIO Zeek package is the one FoxIO implementation that publishes a JA4TS
value, so these baselines hold the only FoxIO reference the method reaches.
`tests/test_foxio_zeek_ja4ts.py` compares the nine values this project adopts, and
`tests/compare_zeek_baselines.py` reads all seven files with no external checkout.
`docs/specs/foxio/zeek.md` records which baseline is usable as a vector, and issue
#515 committed the copies.

The conformance suite reads only the top level of this directory, so no
subdirectory adds a case to it.

Captures the ja4plus authors built
----------------------------------

`alpn-condition.pcap` is not FoxIO material. The ja4plus authors built it for #141,
and `tests/build_alpn_condition_capture.py` writes it. The FoxIO vector set holds no
capture that separates the JA4 ALPN rules, so #141 built one.

`alpn-condition.pcap.json` holds a measurement, not a copy. It records what the FoxIO
Python implementation writes for the capture at the commit above. The FoxIO Rust
implementation writes the same two JA4 values. `docs/implementation_notes.md` holds
both commands and their output.

This script does not write these two files, and it does not delete them.

To move to a newer upstream commit, change FOXIO_COMMIT in
tests/download_test_vectors.py and run that script. The script rewrites this
file.

License
-------

The FoxIO repository publishes two licenses, and both apply to this directory.

JA4S, JA4H, JA4L, JA4LS, JA4X, JA4T, JA4TS, JA4TScan, JA4D, JA4D6, JA4SScan,
JA4E and JA4SSH are under the FoxIO License 1.1:

    https://github.com/FoxIO-LLC/ja4/blob/27f0cbf9fd3000c072f82a0f7d0361dc99acf6c8/LICENSE

JA4 itself, which is TLS client fingerprinting, is under a BSD 3-Clause license:

    https://github.com/FoxIO-LLC/ja4/blob/27f0cbf9fd3000c072f82a0f7d0361dc99acf6c8/LICENSE-JA4

Copyright (c) 2026 FoxIO. The ja4plus project is not affiliated with FoxIO, LLC
and claims no right in the FoxIO material.
