diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..9bb449e --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,92 @@ +# Borrowed from https://github.com/jonhoo/rust-ci-conf/blob/6332a3af21a58f811a681a98cd44d0f5da8a1891/.github/workflows/check.yml +# See the [screencast] by Jon Gjengset. +# +# [screencast]: https://www.youtube.com/watch?v=xUH-4y92jPg + +name: check + +permissions: + contents: read + +on: + push: + branches: [main] + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + fmt: + name: stable / fmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install stable + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - name: cargo fmt --check --all + run: cargo fmt --check --all + working-directory: rust/ + + clippy: + name: ${{ matrix.toolchain }} / clippy + runs-on: ubuntu-latest + permissions: + contents: read + checks: write + strategy: + fail-fast: false + matrix: + toolchain: [stable, beta] + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install ${{ matrix.toolchain }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.toolchain }} + components: clippy + - name: cargo clippy + uses: actions-rs/clippy-check@v1 + with: + # Github Actions don't support `working-dir` in the `uses` context. + # Specify `--manifest-path` as a workaround. + # + # See https://github.com/actions-rs/clippy-check/issues/28 + args: --all-features --workspace --manifest-path rust/Cargo.toml + token: ${{ secrets.GITHUB_TOKEN }} + + doc: + name: nightly / doc + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install nightly + uses: dtolnay/rust-toolchain@nightly + - name: cargo doc + run: cargo doc --no-deps --all-features --document-private-items --workspace + working-directory: rust/ + + hack: + name: ubuntu / stable / features + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install stable + uses: dtolnay/rust-toolchain@stable + - name: cargo install cargo-hack + uses: taiki-e/install-action@cargo-hack + # Intentionally no target specifier; see https://github.com/jonhoo/rust-ci-conf/pull/4 + - name: cargo hack + run: cargo hack --feature-powerset --workspace check + working-directory: rust/ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..78004bc --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,82 @@ +name: release + +on: + workflow_dispatch: + inputs: + tag: + description: 'Tag to build release binaries for' + required: true + type: string + push: + tags: + - v[0-9]+.* + release: + types: [created] + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +env: + RUSTFLAGS: --deny warnings -Cdebuginfo=0 + RUSTDOCFLAGS: --deny warnings + +jobs: + create-release: + name: Create GitHub release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: taiki-e/create-gh-release-action@v1 + with: + changelog: rust/CHANGELOG.md + token: ${{ secrets.GITHUB_TOKEN }} + + build-and-upload: + name: ${{ matrix.job.target }} + runs-on: ${{ matrix.job.os }} + strategy: + fail-fast: false + matrix: + job: + # NOTE: Use compute resources sparingly. Don't use GitHub-hosted macOS runners + # in a non-public repository -- they consume CI/CD minutes like crazy; see + # https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#minute-multipliers + - { os: ubuntu-latest, target: x86_64-unknown-linux-musl } + - { os: windows-latest, target: x86_64-pc-windows-msvc } + #- { os: ubuntu-latest, target: x86_64-unknown-linux-gnu } + #- { os: ubuntu-latest, target: aarch64-unknown-linux-gnu } + #- { os: ubuntu-latest, target: aarch64-unknown-linux-musl } + #- { os: macos-latest, target: x86_64-apple-darwin } + #- { os: macos-latest, target: aarch64-apple-darwin } + #- { os: macos-latest, target: universal-apple-darwin } + + steps: + - name: Check for release + id: is-release + shell: bash + run: | + is_release=false + if [[ $GITHUB_REF =~ ^refs/tags/v[0-9].* ]]; then + is_release=true + fi + echo "is_release=$is_release" >> $GITHUB_OUTPUT + + - uses: actions/checkout@v4 + if: steps.is-release.outputs.is_release + with: + submodules: true + - uses: actions/checkout@v4 + if: ${{ !steps.is-release.outputs.is_release }} + with: + ref: ${{ inputs.tag }} + submodules: true + + - uses: taiki-e/upload-rust-binary-action@v1 + with: + bin: ja4,ja4x + archive: ja4-$tag-$target + target: ${{ matrix.job.target }} + include: rust/ja4/README.md + token: ${{ secrets.GITHUB_TOKEN }} + manifest_path: rust/Cargo.toml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..d7ed5e8 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,85 @@ +# Borrowed from https://github.com/jonhoo/rust-ci-conf/blob/6332a3af21a58f811a681a98cd44d0f5da8a1891/.github/workflows/test.yml +# See the [screencast] by Jon Gjengset. +# +# [screencast]: https://www.youtube.com/watch?v=xUH-4y92jPg + +name: test + +permissions: + contents: read + +on: + push: + branches: [main] + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + required: + name: ubuntu / ${{ matrix.toolchain }} + runs-on: ubuntu-latest + strategy: + matrix: + toolchain: [stable, beta] + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install ${{ matrix.toolchain }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.toolchain }} + - run: cargo generate-lockfile + if: hashFiles('rust/Cargo.lock') == '' + # https://twitter.com/jonhoo/status/1571290371124260865 + - name: cargo test + run: cargo test --locked --all-features --all-targets --workspace + working-directory: rust/ + # https://github.com/rust-lang/cargo/issues/6669 + - name: cargo test --doc + run: cargo test --locked --all-features --doc --workspace + working-directory: rust/ + + minimal: + name: ubuntu / stable / minimal-versions + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install stable + uses: dtolnay/rust-toolchain@stable + - name: Install nightly for -Zminimal-versions + uses: dtolnay/rust-toolchain@nightly + - run: rustup default stable + - run: cargo +nightly update -Zminimal-versions --workspace + working-directory: rust/ + - run: cargo test --locked --all-features --all-targets --workspace + working-directory: rust/ + + os-check: + name: ${{ matrix.os }} / stable + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: + # NOTE: Don't use GitHub-hosted macOS runners in a non-public repository -- + # they consume CI/CD minutes like crazy; see + # https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#minute-multipliers + - windows-latest + #- macos-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install stable + uses: dtolnay/rust-toolchain@stable + - run: cargo generate-lockfile + if: hashFiles('rust/Cargo.lock') == '' + - name: cargo test + run: cargo test --locked --all-features --all-targets --workspace + working-directory: rust/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40b79c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +.DS_Store +.vscode/ diff --git a/rust/CHANGELOG.md b/rust/CHANGELOG.md new file mode 100644 index 0000000..ad070da --- /dev/null +++ b/rust/CHANGELOG.md @@ -0,0 +1,17 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.14.0] - 2023-10-04 + +### Added + +- Add Rust sources of `ja4` and `ja4x` CLI tools. + +[unreleased]: https://github.com/FoxIO-LLC/ja4/compare/v0.14.0...HEAD +[0.14.0]: https://github.com/FoxIO-LLC/ja4/releases/tag/v0.14.0 diff --git a/rust/Cargo.lock b/rust/Cargo.lock new file mode 100644 index 0000000..65c72ef --- /dev/null +++ b/rust/Cargo.lock @@ -0,0 +1,1199 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "anstream" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff2cf94a3dbe2d57cbd56485e1bd7436455058034d6c2d47be51d4e5e4bc6ab" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" + +[[package]] +name = "anstyle-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0238ca56c96dfa37bdf7c373c8886dd591322500aceeeccdb2216fe06dc2f796" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "asn1-rs" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "async-trait" +version = "0.1.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +dependencies = [ + "android-tzdata", + "num-traits", +] + +[[package]] +name = "clap" +version = "4.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "clap_lex" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" + +[[package]] +name = "color-eyre" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "config" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" +dependencies = [ + "async-trait", + "lazy_static", + "nom", + "pathdiff", + "serde", + "toml", +] + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "data-encoding" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + +[[package]] +name = "der-parser" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "deranged" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "dissimilar" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" + +[[package]] +name = "duct" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ae3fc31835f74c2a7ceda3aeede378b0ae2e74c8f1c36559fcc9ae2a4e7d3e" +dependencies = [ + "libc", + "once_cell", + "os_pipe", + "shared_child", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "expect-test" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d9eafeadd538e68fb28016364c9732d78e420b9ff8853fa5e4058861e9f8d3" +dependencies = [ + "dissimilar", + "once_cell", +] + +[[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fs-err" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "hashbrown" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +dependencies = [ + "equivalent", + "hashbrown", + "serde", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "ja4" +version = "0.14.0" +dependencies = [ + "clap", + "color-eyre", + "config", + "duct", + "expect-test", + "fs-err", + "hex", + "indexmap", + "itertools", + "ja4x", + "owo-colors", + "pretty_assertions", + "rtshark", + "semver", + "serde", + "serde_json", + "serde_yaml", + "sha2", + "thiserror", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "ja4x" +version = "0.14.0" +dependencies = [ + "clap", + "color-eyre", + "fs-err", + "hex", + "indexmap", + "itertools", + "serde", + "serde_json", + "serde_yaml", + "sha2", + "tracing", + "tracing-subscriber", + "x509-parser", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" +dependencies = [ + "memchr", +] + +[[package]] +name = "oid-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +dependencies = [ + "asn1-rs", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "os_pipe" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae859aa07428ca9a929b936690f8b12dc5f11dd8c6992a18ca93919f28bc177" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "pin-project-lite" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" + +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi", +] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quick-xml" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.3.6", + "regex-syntax 0.7.4", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.4", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" + +[[package]] +name = "rtshark" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc612769da19e0bbf9c2011fb9c3b3dbffb9558330175035fa5ac6ae8e06966b" +dependencies = [ + "chrono", + "quick-xml", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "semver" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "serde_json" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shared_child" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "thiserror" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb39ee79a6d8de55f48f2293a830e040392f1c5f16e336bdd1788cd0aadce07" +dependencies = [ + "deranged", + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733d258752e9303d392b94b75230d07b0b9c489350c69b851fc6c065fde3e8f9" +dependencies = [ + "time-core", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "unsafe-libyaml" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "x509-parser" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" diff --git a/rust/Cargo.toml b/rust/Cargo.toml new file mode 100644 index 0000000..e2f8ee0 --- /dev/null +++ b/rust/Cargo.toml @@ -0,0 +1,22 @@ +[workspace] +members = ["ja4", "ja4x"] +resolver = "2" + +[workspace.package] +version = "0.14.0" +license = "LicenseRef-FoxIO-Proprietary" +repository = "https://github.com/FoxIO-LLC/ja4" + +[workspace.dependencies] +clap = { version = "4.4", features = ["derive"] } +color-eyre = "0.6" +fs-err = "2.9" +hex = "0.4" +indexmap = "2.0" +itertools = "0.11" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +serde_yaml = "0.9" +sha2 = "0.10" +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/rust/README.md b/rust/README.md new file mode 100644 index 0000000..8ddc709 --- /dev/null +++ b/rust/README.md @@ -0,0 +1,58 @@ +# JA4 fingerprinting + +JA4 is a suite of passive network fingerprinting methods that supersede the aging [JA3/S][JA3] standard. + +[JA3]: https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967/ + +## Nomenclature + +Name | Meaning +--- | --- +JA4 | TLS client fingerprint (supersedes JA3) +JA4S | TLS server fingerprint (supersedes JA3S) +JA4L-C/S | Light distance/location fingerprint +JA4H | HTTP client fingerprint +JA4SSH | SSH traffic fingerprint +JA4X | X.509 fingerprint + +## Usage + +``` +Usage: ja4 [OPTIONS] + +Arguments: + + The capture file to process + +Options: + -j, --json + JSON output (default is YAML) + + -r, --with-raw + Include raw (unhashed) fingerprints in the output + + -O, --original-order + Preserve the original order of values. + + JA4 (TLS client): disable sorting of ciphers and TLS extensions. + + JA4H (HTTP client): disable sorting of headers and cookies. + + --keylog-file + The key log file that enables decryption of TLS traffic. + + This file is generated by the browser when `SSLKEYLOGFILE` environment variable is set. See for more details. + + Note that you can embed the TLS key log file in a capture file: `editcap --inject-secrets tls,keys.txt in.pcap out-dsb.pcapng` + + -n, --with-packet-numbers + Include packet numbers (`pkt_*` fields) in the output. + + This information is useful for debugging. + + -h, --help + Print help (see a summary with '-h') + + -V, --version + Print version +``` diff --git a/rust/ja4/Cargo.toml b/rust/ja4/Cargo.toml index 1563e9b..eaa3ec4 100644 --- a/rust/ja4/Cargo.toml +++ b/rust/ja4/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "ja4" -description = "JA4 suite of passive network fingerprint methods" +description = "JA4 suite of passive network fingerprinting methods" version.workspace = true edition = "2021" authors = ["Valeriy V. Vorotyntsev "] -license-file.workspace = true +license.workspace = true repository.workspace = true keywords = ["ja4", "fingerprint", "pcap"] categories = ["network-programming"] diff --git a/rust/ja4/src/conf.rs b/rust/ja4/src/conf.rs index fe26cea..417bbe0 100644 --- a/rust/ja4/src/conf.rs +++ b/rust/ja4/src/conf.rs @@ -1,3 +1,10 @@ +// Copyright (c) 2023, FoxIO, LLC. +// All rights reserved. +// Patent Pending +// JA4 is Open-Source, Licensed under BSD 3-Clause +// JA4+ (JA4S, JA4H, JA4L, JA4X, JA4SSH) are licenced under the FoxIO License 1.1. +// For full license text, see the repo root. + use fs_err::File; use serde::Deserialize; diff --git a/rust/ja4/src/error.rs b/rust/ja4/src/error.rs index 938cf88..c4b062f 100644 --- a/rust/ja4/src/error.rs +++ b/rust/ja4/src/error.rs @@ -1,3 +1,10 @@ +// Copyright (c) 2023, FoxIO, LLC. +// All rights reserved. +// Patent Pending +// JA4 is Open-Source, Licensed under BSD 3-Clause +// JA4+ (JA4S, JA4H, JA4L, JA4X, JA4SSH) are licenced under the FoxIO License 1.1. +// For full license text, see the repo root. + use std::{io, path::PathBuf}; use ja4x::x509_parser; diff --git a/rust/ja4/src/http.rs b/rust/ja4/src/http.rs index 07a0fbd..7ef0b47 100644 --- a/rust/ja4/src/http.rs +++ b/rust/ja4/src/http.rs @@ -1,3 +1,10 @@ +// Copyright (c) 2023, FoxIO, LLC. +// All rights reserved. +// Patent Pending +// JA4 is Open-Source, Licensed under BSD 3-Clause +// JA4+ (JA4S, JA4H, JA4L, JA4X, JA4SSH) are licenced under the FoxIO License 1.1. +// For full license text, see the repo root. + //! JA4H -- HTTP client fingerprinting use std::fmt; diff --git a/rust/ja4/src/lib.rs b/rust/ja4/src/lib.rs index a2a73a1..956f4bb 100644 --- a/rust/ja4/src/lib.rs +++ b/rust/ja4/src/lib.rs @@ -1,3 +1,10 @@ +// Copyright (c) 2023, FoxIO, LLC. +// All rights reserved. +// Patent Pending +// JA4 is Open-Source, Licensed under BSD 3-Clause +// JA4+ (JA4S, JA4H, JA4L, JA4X, JA4SSH) are licenced under the FoxIO License 1.1. +// For full license text, see the repo root. + mod conf; mod error; mod http; diff --git a/rust/ja4/src/main.rs b/rust/ja4/src/main.rs index 2e8fae0..92f6a5a 100644 --- a/rust/ja4/src/main.rs +++ b/rust/ja4/src/main.rs @@ -1,3 +1,10 @@ +// Copyright (c) 2023, FoxIO, LLC. +// All rights reserved. +// Patent Pending +// JA4 is Open-Source, Licensed under BSD 3-Clause +// JA4+ (JA4S, JA4H, JA4L, JA4X, JA4SSH) are licenced under the FoxIO License 1.1. +// For full license text, see the repo root. + use std::io; use clap::Parser as _; diff --git a/rust/ja4/src/pcap.rs b/rust/ja4/src/pcap.rs index aa08ed5..56955e6 100644 --- a/rust/ja4/src/pcap.rs +++ b/rust/ja4/src/pcap.rs @@ -1,3 +1,10 @@ +// Copyright (c) 2023, FoxIO, LLC. +// All rights reserved. +// Patent Pending +// JA4 is Open-Source, Licensed under BSD 3-Clause +// JA4+ (JA4S, JA4H, JA4L, JA4X, JA4SSH) are licenced under the FoxIO License 1.1. +// For full license text, see the repo root. + //! Capture file abstractions use std::fmt; diff --git a/rust/ja4/src/ssh.rs b/rust/ja4/src/ssh.rs index df5ad26..eb45fe2 100644 --- a/rust/ja4/src/ssh.rs +++ b/rust/ja4/src/ssh.rs @@ -1,3 +1,10 @@ +// Copyright (c) 2023, FoxIO, LLC. +// All rights reserved. +// Patent Pending +// JA4 is Open-Source, Licensed under BSD 3-Clause +// JA4+ (JA4S, JA4H, JA4L, JA4X, JA4SSH) are licenced under the FoxIO License 1.1. +// For full license text, see the repo root. + //! JA4SSH -- SSH traffic fingerprinting use std::collections::HashMap; diff --git a/rust/ja4/src/stream.rs b/rust/ja4/src/stream.rs index 00d9a8a..1b4bc0f 100644 --- a/rust/ja4/src/stream.rs +++ b/rust/ja4/src/stream.rs @@ -1,3 +1,10 @@ +// Copyright (c) 2023, FoxIO, LLC. +// All rights reserved. +// Patent Pending +// JA4 is Open-Source, Licensed under BSD 3-Clause +// JA4+ (JA4S, JA4H, JA4L, JA4X, JA4SSH) are licenced under the FoxIO License 1.1. +// For full license text, see the repo root. + use indexmap::IndexMap; use serde::Serialize; diff --git a/rust/ja4/src/time.rs b/rust/ja4/src/time.rs index 9bb8f6a..4987bfc 100644 --- a/rust/ja4/src/time.rs +++ b/rust/ja4/src/time.rs @@ -1,3 +1,10 @@ +// Copyright (c) 2023, FoxIO, LLC. +// All rights reserved. +// Patent Pending +// JA4 is Open-Source, Licensed under BSD 3-Clause +// JA4+ (JA4S, JA4H, JA4L, JA4X, JA4SSH) are licenced under the FoxIO License 1.1. +// For full license text, see the repo root. + //! Light distance (latency) fingerprints -- JA4L-C (client), JA4L-S (server) mod tcp; diff --git a/rust/ja4/src/time/tcp.rs b/rust/ja4/src/time/tcp.rs index dab32d0..9dcfc7d 100644 --- a/rust/ja4/src/time/tcp.rs +++ b/rust/ja4/src/time/tcp.rs @@ -1,3 +1,10 @@ +// Copyright (c) 2023, FoxIO, LLC. +// All rights reserved. +// Patent Pending +// JA4 is Open-Source, Licensed under BSD 3-Clause +// JA4+ (JA4S, JA4H, JA4L, JA4X, JA4SSH) are licenced under the FoxIO License 1.1. +// For full license text, see the repo root. + //! Timestamps obtained from a TCP handshake use crate::{ diff --git a/rust/ja4/src/time/udp.rs b/rust/ja4/src/time/udp.rs index 0f18461..df3d212 100644 --- a/rust/ja4/src/time/udp.rs +++ b/rust/ja4/src/time/udp.rs @@ -1,3 +1,10 @@ +// Copyright (c) 2023, FoxIO, LLC. +// All rights reserved. +// Patent Pending +// JA4 is Open-Source, Licensed under BSD 3-Clause +// JA4+ (JA4S, JA4H, JA4L, JA4X, JA4SSH) are licenced under the FoxIO License 1.1. +// For full license text, see the repo root. + //! Timestamps obtained from a QUIC stream use crate::{ diff --git a/rust/ja4/src/tls.rs b/rust/ja4/src/tls.rs index 4c5ad78..71c8ab4 100644 --- a/rust/ja4/src/tls.rs +++ b/rust/ja4/src/tls.rs @@ -1,3 +1,10 @@ +// Copyright (c) 2023, FoxIO, LLC. +// All rights reserved. +// Patent Pending +// JA4 is Open-Source, Licensed under BSD 3-Clause +// JA4+ (JA4S, JA4H, JA4L, JA4X, JA4SSH) are licenced under the FoxIO License 1.1. +// For full license text, see the repo root. + //! JA4 (TLS client), JA4S (TLS server), and JA4X (X.509 certificate) fingerprinting use std::fmt; diff --git a/rust/ja4x/Cargo.toml b/rust/ja4x/Cargo.toml index 529e697..813edf9 100644 --- a/rust/ja4x/Cargo.toml +++ b/rust/ja4x/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "ja4x" -description = "generate JA4X fingerprint for a X.509 certificate" +description = "generate JA4X fingerprints for X.509 certificates" version.workspace = true edition = "2021" authors = ["Valeriy V. Vorotyntsev "] -license-file.workspace = true +license.workspace = true repository.workspace = true keywords = ["ja4x", "ja4", "fingerprint", "x509", "der"] categories = ["command-line-utilities"] diff --git a/rust/ja4x/src/lib.rs b/rust/ja4x/src/lib.rs index 7af9491..ba725c6 100644 --- a/rust/ja4x/src/lib.rs +++ b/rust/ja4x/src/lib.rs @@ -1,3 +1,10 @@ +// Copyright (c) 2023, FoxIO, LLC. +// All rights reserved. +// Patent Pending +// JA4 is Open-Source, Licensed under BSD 3-Clause +// JA4+ (JA4S, JA4H, JA4L, JA4X, JA4SSH) are licenced under the FoxIO License 1.1. +// For full license text, see the repo root. + pub use x509_parser; use indexmap::IndexMap; diff --git a/rust/ja4x/src/main.rs b/rust/ja4x/src/main.rs index 08e1b3c..ca19fef 100644 --- a/rust/ja4x/src/main.rs +++ b/rust/ja4x/src/main.rs @@ -1,3 +1,10 @@ +// Copyright (c) 2023, FoxIO, LLC. +// All rights reserved. +// Patent Pending +// JA4 is Open-Source, Licensed under BSD 3-Clause +// JA4+ (JA4S, JA4H, JA4L, JA4X, JA4SSH) are licenced under the FoxIO License 1.1. +// For full license text, see the repo root. + use std::{ io::{self, Write as _}, path::PathBuf,