Version: v7.3.3 | Author: Gilles Biagomba | License: GPL-3.0
Handshaker is a native Rust secure-transport posture engine that probes TLS, SSH, and RDP endpoints without shelling out to external tools. It produces stable, machine-parseable finding IDs, SSL Labs–style grades, CVSS v3.1 risk scores, and supports compliance evaluation, benchmarking, longitudinal diffing, and AI-powered analysis.
- Features
- Installation
- Flags
- Usage
- Finding Reference
- Finding Audit Matrix
- Testssl-Class Coverage Matrix
- Running Tests
- Using Docker
- Using the Makefile
- Contributing
- License
- Native protocol probing for TLS (all versions), STARTTLS (SMTP/IMAP/POP3/FTP/LDAP), SSH, and RDP — no
opensslCLI or external binaries required - Stable finding IDs (
HS-{PROTOCOL}-{CATEGORY}-{NNNN}) for reliable CI gating and longitudinal tracking - SSL Labs–style scoring — Certificate, Protocol, Key Exchange, Cipher Strength categories and A+/A/B/C/D/F grades
- CVSS v3.1 configuration risk scoring — max and weighted aggregate scores across all findings
- Compliance evaluation against YAML policies (PCI-DSS, NIST 800-52r2, CIS-like profiles)
- Benchmarking and diffing across scan runs to track remediation progress and detect regressions
- Multiple output formats: JSON, Text, Table, HTML, CSV, SQLite — with optional file output and database persistence
- Unified file import with
handshaker scan --fileauto-detection for plain targets, nmap grep/XML, nuclei JSON(L), and testssl JSON - Vendor-calibrated finding catalog for all 68 findings, aligned against NVD, Tenable, RFC, and related standards references where applicable
- Documentation integrity tooling to keep
FINDING_INDEX.MDandFINDING_AUDIT_MATRIX.mdsynchronized with the Rust catalog
Download the binary for your platform from the Releases page:
| OS | Arch | Asset name |
|---|---|---|
| Linux | x86_64 | handshaker-linux-x86_64 |
| Linux | aarch64 | handshaker-linux-aarch64 |
| macOS | x86_64 | handshaker-macos-x86_64 |
| macOS | aarch64 | handshaker-macos-aarch64 |
| Windows | x86_64 | handshaker-windows-x86_64.exe |
cargo install --git https://github.com/gbiagomba/WeakSSLgit clone https://github.com/gbiagomba/WeakSSL.git
cd WeakSSL
cargo build --release
# Binary at: target/release/handshaker# Linux / macOS
bash scripts/install.sh
# Windows (PowerShell)
.\scripts\install.ps1| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--target |
-t |
string | — | Single target: hostname, IP, host:port, or URL |
--file |
-f |
string | — | File input: plain targets, nmap grep/XML, nuclei JSON(L), or testssl JSON |
--stdin |
— | bool | false | Read targets from stdin (one per line) |
--ports |
-p |
list | — | Comma-separated port list (e.g. 443,8443,25) |
--output |
— | enum | json |
Output format: json|text|table|html|csv|sqlite |
--out |
-o |
string | — | Write output to file instead of stdout |
--concurrency |
— | number | 32 |
Max parallel scans |
--timeout-secs |
— | number | 10 |
Per-target connection timeout in seconds |
--policy |
— | string | — | YAML policy file for compliance evaluation |
--fail-on-noncompliant |
— | bool | false | Exit non-zero when any policy finding fails |
--benchmark |
— | string | — | YAML benchmark profile to evaluate results against |
--db |
— | string | — | SQLite database path to persist results |
| Argument | Description |
|---|---|
<ID> |
Finding ID to look up (e.g. HS-TLS-PROTOCOL-0003) |
| Flag | Type | Description |
|---|---|---|
--input |
string | Path to JSON results file |
| Flag | Type | Description |
|---|---|---|
--input |
string | Path to JSON results file |
--profile |
string | Path to benchmark YAML profile |
| Flag | Type | Description |
|---|---|---|
--left |
string | Baseline JSON results file |
--right |
string | New JSON results file to compare against baseline |
| Flag | Type | Description |
|---|---|---|
--input |
string | Path to JSON results file |
--provider |
string | AI provider name (default: built-in) |
| Subcommand | Flag | Type | Description |
|---|---|---|---|
init |
--path |
string | Path to SQLite database file to initialize |
list |
--path |
string | Path to SQLite database file |
export |
--path |
string | Path to SQLite database file |
export |
--run-id |
string | Run ID to export (from db list) |
handshaker --help
handshaker scan --help
handshaker db init --helphandshaker help
handshaker help scan
handshaker help db# Single HTTPS target
handshaker scan --target example.com --ports 443
# Multiple ports including STARTTLS
handshaker scan --target mail.example.com --ports 25,587,465,993
# Scan a list of hosts and write an HTML report
handshaker scan --file hosts.txt --output html --out report.html
# Import targets from nmap XML output
handshaker scan --file scan.xml --output json --out results.json
# Import targets from nuclei JSONL output
handshaker scan --file nuclei.jsonl
# Import targets from testssl JSON output
handshaker scan --file testssl.json
# Read targets from stdin
cat hosts.txt | handshaker scan --stdin
# Compliance check with CI gate
handshaker scan --target example.com --policy pci.yaml --fail-on-noncompliant
# Scan and benchmark simultaneously
handshaker scan --target example.com --policy pci.yaml --benchmark profile.yaml --db results.dbhandshaker explain HS-TLS-PROTOCOL-0003
handshaker explain HS-SSH-HOSTKEY-0105
handshaker explain HS-TLS-CIPHER-0001handshaker score --input results.jsonhandshaker benchmark --input results.json --profile default.yaml
handshaker benchmark --input results.json --profile pci-dss.yaml# Track remediation progress
handshaker diff --left before.json --right after.json
# Detect weekly regressions
handshaker diff --left week1.json --right week2.jsonhandshaker ai --input results.json
handshaker ai --input results.json --provider openai# Initialize a new database
handshaker db init --path handshaker.db
# Store scan results
handshaker scan --target example.com --db handshaker.db
# List stored runs
handshaker db list --path handshaker.db
# Export a specific run as JSON
handshaker db export --path handshaker.db --run-id <RUN-ID>FINDING_INDEX.MD is the authoritative reference for all 68 security findings Handshaker can detect. For each finding it lists:
- ID — stable identifier in
HS-{PROTOCOL}-{CATEGORY}-{NNNN}format - Title and Severity (Critical / High / Medium / Low / Info)
- CVSS 3.1 score and vector
- Description — what the finding means and why it matters
- Testssl-class mapping — which testssl.sh check category it corresponds to
- Policy coverage — whether it is enforced under Default, PCI-DSS, NIST 800-52r2, or CIS-Like profiles
Quick lookup from the CLI:
handshaker explain HS-TLS-PROTOCOL-0003FINDING_AUDIT_MATRIX.md is the compact audit companion to FINDING_INDEX.MD.
It maps every finding to:
- current severity
- current CVSS vector
- external source basis used during calibration
Generate it from the Rust catalog:
python3 scripts/generate_finding_audit_matrix.pyVerify both finding documents are still synchronized with src/findings/catalog.rs:
python3 scripts/check_finding_index_sync.py| testssl class | Handshaker implementation |
|---|---|
| protocol enumeration | TLS version probing in src/protocols/tls/versions.rs |
| cipher enumeration | Cipher list probing in src/protocols/tls/ciphers.rs |
| weak ciphers | NULL/aNULL/EXPORT/RC4/3DES/MEDIUM checks |
| certificate validation | Expired/not-yet-valid/self-signed/hostname/SHA1/RSA size checks |
| hostname mismatch | HS-TLS-CERT-0004 |
| RSA key size | HS-TLS-CERT-0006 |
| SHA1 signature | HS-TLS-CERT-0005 |
| forward secrecy indicators | HS-TLS-CIPHER-0009 |
| renegotiation posture | HS-TLS-PROTOCOL-0008 |
| TLS compression | HS-TLS-PROTOCOL-0009 |
| session resumption indicators | HS-TLS-SCENARIO-0003 |
| downgrade resilience testing | HS-TLS-SCENARIO-0001/0002 |
| SWEET32 exposure | HS-TLS-SCENARIO-0005 |
| BEAST exposure | HS-TLS-SCENARIO-0006 |
| Logjam weak DH | HS-TLS-SCENARIO-0004 |
# Run the full test suite
make test
# or
cargo test --all
# Run with CI lint + format check
make ci
# equivalent to: cargo fmt --all && cargo test --all && cargo build --releaseCurrent suite size: 101 tests.
# Build the image
docker build -t handshaker .
# Scan a target
docker run --rm handshaker scan --target example.com --ports 443
# Scan a local file (mount current directory)
docker run --rm -v "$(pwd)":/data handshaker scan --file /data/hosts.txt --output html --out /data/report.html| Target | Description |
|---|---|
make build |
Compile release binary (target/release/handshaker) |
make debug |
Compile debug binary |
make run ARGS="..." |
Build and run with arguments |
make install |
Run install script (scripts/install.sh) |
make test |
Run the full test suite |
make verify-docs |
Verify FINDING_INDEX.MD and FINDING_AUDIT_MATRIX.md against the Rust catalog |
make generate-audit-matrix |
Regenerate FINDING_AUDIT_MATRIX.md from src/findings/catalog.rs |
make fmt |
Format all Rust source files |
make ci |
Run fmt + test + build (for CI pipelines) |
make clean |
Remove build artifacts |
- Fork the repository on GitHub
- Create a feature branch:
git checkout -b feature/my-change - Make your changes and add tests
- Ensure
make cipasses without errors - Commit with a descriptive message following Conventional Commits
- Open a pull request against
maindescribing the change and its motivation
Please report bugs and request features via GitHub Issues.
Handshaker is released under the GNU General Public License v3.0 (GPL-3.0). See the LICENSE file for the full terms.
For commercial use cases that require a different licensing arrangement, contact the author.
