pqc-audit 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pqc_audit-0.1.0/LICENSE +21 -0
- pqc_audit-0.1.0/PKG-INFO +196 -0
- pqc_audit-0.1.0/README.md +162 -0
- pqc_audit-0.1.0/pyproject.toml +56 -0
- pqc_audit-0.1.0/setup.cfg +4 -0
- pqc_audit-0.1.0/src/pqc_audit.egg-info/PKG-INFO +196 -0
- pqc_audit-0.1.0/src/pqc_audit.egg-info/SOURCES.txt +32 -0
- pqc_audit-0.1.0/src/pqc_audit.egg-info/dependency_links.txt +1 -0
- pqc_audit-0.1.0/src/pqc_audit.egg-info/entry_points.txt +3 -0
- pqc_audit-0.1.0/src/pqc_audit.egg-info/requires.txt +9 -0
- pqc_audit-0.1.0/src/pqc_audit.egg-info/top_level.txt +1 -0
- pqc_audit-0.1.0/src/pqc_scanner/__init__.py +20 -0
- pqc_audit-0.1.0/src/pqc_scanner/__main__.py +6 -0
- pqc_audit-0.1.0/src/pqc_scanner/core.py +39 -0
- pqc_audit-0.1.0/src/pqc_scanner/detectors/__init__.py +12 -0
- pqc_audit-0.1.0/src/pqc_scanner/detectors/ast_engine.py +385 -0
- pqc_audit-0.1.0/src/pqc_scanner/detectors/dependencies.py +306 -0
- pqc_audit-0.1.0/src/pqc_scanner/detectors/discovery.py +124 -0
- pqc_audit-0.1.0/src/pqc_scanner/findings.py +62 -0
- pqc_audit-0.1.0/src/pqc_scanner/interfaces/__init__.py +6 -0
- pqc_audit-0.1.0/src/pqc_scanner/interfaces/cli.py +115 -0
- pqc_audit-0.1.0/src/pqc_scanner/interfaces/mcp_server.py +64 -0
- pqc_audit-0.1.0/src/pqc_scanner/outputs/__init__.py +6 -0
- pqc_audit-0.1.0/src/pqc_scanner/outputs/cbom.py +200 -0
- pqc_audit-0.1.0/src/pqc_scanner/outputs/report.py +81 -0
- pqc_audit-0.1.0/src/pqc_scanner/rules.py +280 -0
- pqc_audit-0.1.0/tests/test_ast_engine.py +534 -0
- pqc_audit-0.1.0/tests/test_cbom.py +190 -0
- pqc_audit-0.1.0/tests/test_cli.py +65 -0
- pqc_audit-0.1.0/tests/test_dependencies.py +209 -0
- pqc_audit-0.1.0/tests/test_discovery.py +78 -0
- pqc_audit-0.1.0/tests/test_mcp.py +51 -0
- pqc_audit-0.1.0/tests/test_report.py +48 -0
- pqc_audit-0.1.0/tests/test_smoke.py +20 -0
pqc_audit-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Aaron Vives
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
pqc_audit-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pqc-audit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Scans local repositories for quantum-vulnerable cryptography and produces an exposure report with post-quantum migration targets.
|
|
5
|
+
Author-email: Aaron Vives <aaronvives@icloud.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/rauleteee/pqc-scanner
|
|
8
|
+
Project-URL: Repository, https://github.com/rauleteee/pqc-scanner
|
|
9
|
+
Project-URL: Issues, https://github.com/rauleteee/pqc-scanner/issues
|
|
10
|
+
Keywords: pqc,post-quantum,cryptography,security,sast,cbom
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Topic :: Security :: Cryptography
|
|
17
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: rich>=13.0
|
|
27
|
+
Provides-Extra: mcp
|
|
28
|
+
Requires-Dist: mcp>=1.2; extra == "mcp"
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
31
|
+
Requires-Dist: jsonschema>=4.0; extra == "dev"
|
|
32
|
+
Requires-Dist: mcp>=1.2; extra == "dev"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# PQC Scanner
|
|
36
|
+
|
|
37
|
+
Open-source CLI that scans a local repository for cryptography vulnerable to
|
|
38
|
+
quantum computing (RSA, ECC, ...) and produces an exposure report with concrete
|
|
39
|
+
post-quantum migration targets.
|
|
40
|
+
|
|
41
|
+
> You can't migrate what you can't see. PQC Scanner is the inventory/visibility
|
|
42
|
+
> step of a post-quantum migration: it finds where quantum-vulnerable
|
|
43
|
+
> cryptography lives in your code and dependencies, and tells you what to move it to.
|
|
44
|
+
|
|
45
|
+
> **Status:** v1, Python only. AST detection engine, dependency-manifest
|
|
46
|
+
> complement, rule base, CycloneDX CBOM output and CLI are in place.
|
|
47
|
+
|
|
48
|
+
## What it detects
|
|
49
|
+
|
|
50
|
+
Two static detectors feed one report:
|
|
51
|
+
|
|
52
|
+
- **Source code (AST) — high signal.** Parses Python with the standard `ast`
|
|
53
|
+
module and reports *real uses* of vulnerable primitives (a crypto import **plus**
|
|
54
|
+
a matching call), so comments or variable names never trigger a finding.
|
|
55
|
+
Extracts detail: RSA/DSA/DH key size, EC curve (normalized across libraries —
|
|
56
|
+
`SECP256R1`/`P-256`/`prime256v1` → `P-256`), AES key length, PQC scheme.
|
|
57
|
+
- **Dependency manifests — complement.** Parses `requirements.txt`,
|
|
58
|
+
`pyproject.toml` (PEP 621 + Poetry), `poetry.lock` and `Pipfile.lock` and flags
|
|
59
|
+
declared cryptographic libraries with their version. Low signal on its own (it
|
|
60
|
+
says a library is present, not that a primitive is used), but it seeds the CBOM.
|
|
61
|
+
|
|
62
|
+
Each finding carries: location, algorithm, usage context, quantum classification
|
|
63
|
+
(Shor / Grover / already-PQC), severity, origin (code location | package+version)
|
|
64
|
+
and a **suggested PQC migration target** (key exchange → ML-KEM, signatures → ML-DSA).
|
|
65
|
+
|
|
66
|
+
## Installation
|
|
67
|
+
|
|
68
|
+
With [pipx](https://pipx.pypa.io) for an isolated CLI:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pipx install pqc-audit
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Or from a local clone:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
git clone https://github.com/rauleteee/pqc-scanner
|
|
78
|
+
cd pqc-scanner
|
|
79
|
+
pipx install . # isolated, adds the `pqc-audit` command
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Or for development:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
python -m venv .venv && source .venv/bin/activate
|
|
86
|
+
pip install -e ".[dev]"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Usage
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pqc-audit [PATH] # colored terminal summary (default PATH: .)
|
|
93
|
+
pqc-audit [PATH] --json # CycloneDX 1.6 CBOM to stdout
|
|
94
|
+
python -m pqc_scanner [PATH] # equivalent, without installing
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Running it against the bundled `examples/` (Python source + a `requirements.txt`):
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
pqc-audit 0.1.0 · scanned examples
|
|
101
|
+
CRITICAL: 5 MEDIUM: 1 INFO: 1
|
|
102
|
+
┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
103
|
+
┃ Severity ┃ Algorithm ┃ Usage ┃ Location ┃ Migrate to ┃
|
|
104
|
+
┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
|
|
105
|
+
│ CRITICAL │ RSA/ECC/DH/Ed25519 │ dependency │ examples/requirements │ ML-KEM / ML-DSA │
|
|
106
|
+
│ CRITICAL │ RSA/ECC (OpenSSL) │ dependency │ examples/requirements │ ML-KEM / ML-DSA │
|
|
107
|
+
│ CRITICAL │ RSA/ECDSA (SSH) │ dependency │ examples/requirements │ ML-KEM / ML-DSA │
|
|
108
|
+
│ CRITICAL │ RSA-2048 │ key_generation │ examples/vulnerable_… │ ML-KEM / ML-DSA │
|
|
109
|
+
│ CRITICAL │ ECC-P-256 │ key_generation │ examples/vulnerable_… │ ML-KEM (ECDH) / ML-DSA │
|
|
110
|
+
│ MEDIUM │ AES │ encryption │ examples/vulnerable_… │ AES-256 │
|
|
111
|
+
│ INFO │ ML-KEM/ML-DSA │ dependency │ examples/requirements │ already post-quantum │
|
|
112
|
+
└──────────┴────────────────────┴────────────────┴───────────────────────┴────────────────────────┘
|
|
113
|
+
Verdict: quantum-critical cryptography in use — migration needed.
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The header count (`CRITICAL: 5 MEDIUM: 1 INFO: 1`) is the at-a-glance verdict.
|
|
117
|
+
|
|
118
|
+
### JSON / CBOM output
|
|
119
|
+
|
|
120
|
+
`--json` emits a **CycloneDX 1.6 CBOM** (Cryptography Bill of Materials),
|
|
121
|
+
validated against the official schema. Code findings become `cryptographic-asset`
|
|
122
|
+
components; dependency findings become `library` components (with `purl` and
|
|
123
|
+
version). The scanner's assessment (severity, quantum classification, migration
|
|
124
|
+
target) rides along as namespaced `properties`.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
pqc-audit path/to/repo --json > cbom.json
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## MCP server (for AI agents)
|
|
131
|
+
|
|
132
|
+
The same engine is exposed over the [Model Context Protocol](https://modelcontextprotocol.io),
|
|
133
|
+
so any MCP-capable agent (Claude, Cursor, …) can scan a local repo conversationally.
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pip install ".[mcp]" # installs the optional MCP SDK
|
|
137
|
+
pqc-audit-mcp # runs the server over stdio
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Register it with Claude Code:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
claude mcp add pqc-audit -- pqc-audit-mcp
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Or add it to a client config (e.g. Claude Desktop `claude_desktop_config.json`):
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"mcpServers": {
|
|
151
|
+
"pqc-audit": { "command": "pqc-audit-mcp" }
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
It exposes two tools:
|
|
157
|
+
|
|
158
|
+
- **`scan_repository(path)`** — an at-a-glance verdict, severity counts, and the
|
|
159
|
+
findings, each with its location and suggested post-quantum migration target.
|
|
160
|
+
- **`generate_cbom(path)`** — the full CycloneDX 1.6 CBOM.
|
|
161
|
+
|
|
162
|
+
## Architecture
|
|
163
|
+
|
|
164
|
+
The engine is a **library**; the interfaces are **thin wrappers**. All detection
|
|
165
|
+
logic lives in the `pqc_scanner` core, exposed through a small public API:
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from pqc_scanner import scan, to_cbom
|
|
169
|
+
findings = scan(path) # list[Finding] (code + dependency findings)
|
|
170
|
+
cbom = to_cbom(findings) # CycloneDX 1.6 CBOM dict
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The CLI and the MCP server are just thin faces of the same engine (a skill is next).
|
|
174
|
+
|
|
175
|
+
## Tests
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
pytest
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## v1 scope
|
|
182
|
+
|
|
183
|
+
- **Python** ecosystem only.
|
|
184
|
+
- **Static** analysis of local files: source code (AST) + dependency manifests.
|
|
185
|
+
- Outputs: colored terminal summary + JSON aligned with CycloneDX CBOM.
|
|
186
|
+
|
|
187
|
+
**Known limit (by design):** the AST engine detects direct, statically-resolvable
|
|
188
|
+
use; strong indirection (dependency injection, factories, dynamic `getattr`) is
|
|
189
|
+
out of scope until a future data-flow/taint layer. The dependency complement is a
|
|
190
|
+
presence lookup, not proof a primitive is used.
|
|
191
|
+
|
|
192
|
+
See [`CLAUDE.md`](CLAUDE.md) for the full design and build plan.
|
|
193
|
+
|
|
194
|
+
## License
|
|
195
|
+
|
|
196
|
+
MIT — see [`LICENSE`](LICENSE).
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# PQC Scanner
|
|
2
|
+
|
|
3
|
+
Open-source CLI that scans a local repository for cryptography vulnerable to
|
|
4
|
+
quantum computing (RSA, ECC, ...) and produces an exposure report with concrete
|
|
5
|
+
post-quantum migration targets.
|
|
6
|
+
|
|
7
|
+
> You can't migrate what you can't see. PQC Scanner is the inventory/visibility
|
|
8
|
+
> step of a post-quantum migration: it finds where quantum-vulnerable
|
|
9
|
+
> cryptography lives in your code and dependencies, and tells you what to move it to.
|
|
10
|
+
|
|
11
|
+
> **Status:** v1, Python only. AST detection engine, dependency-manifest
|
|
12
|
+
> complement, rule base, CycloneDX CBOM output and CLI are in place.
|
|
13
|
+
|
|
14
|
+
## What it detects
|
|
15
|
+
|
|
16
|
+
Two static detectors feed one report:
|
|
17
|
+
|
|
18
|
+
- **Source code (AST) — high signal.** Parses Python with the standard `ast`
|
|
19
|
+
module and reports *real uses* of vulnerable primitives (a crypto import **plus**
|
|
20
|
+
a matching call), so comments or variable names never trigger a finding.
|
|
21
|
+
Extracts detail: RSA/DSA/DH key size, EC curve (normalized across libraries —
|
|
22
|
+
`SECP256R1`/`P-256`/`prime256v1` → `P-256`), AES key length, PQC scheme.
|
|
23
|
+
- **Dependency manifests — complement.** Parses `requirements.txt`,
|
|
24
|
+
`pyproject.toml` (PEP 621 + Poetry), `poetry.lock` and `Pipfile.lock` and flags
|
|
25
|
+
declared cryptographic libraries with their version. Low signal on its own (it
|
|
26
|
+
says a library is present, not that a primitive is used), but it seeds the CBOM.
|
|
27
|
+
|
|
28
|
+
Each finding carries: location, algorithm, usage context, quantum classification
|
|
29
|
+
(Shor / Grover / already-PQC), severity, origin (code location | package+version)
|
|
30
|
+
and a **suggested PQC migration target** (key exchange → ML-KEM, signatures → ML-DSA).
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
With [pipx](https://pipx.pypa.io) for an isolated CLI:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pipx install pqc-audit
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or from a local clone:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
git clone https://github.com/rauleteee/pqc-scanner
|
|
44
|
+
cd pqc-scanner
|
|
45
|
+
pipx install . # isolated, adds the `pqc-audit` command
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Or for development:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
python -m venv .venv && source .venv/bin/activate
|
|
52
|
+
pip install -e ".[dev]"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Usage
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pqc-audit [PATH] # colored terminal summary (default PATH: .)
|
|
59
|
+
pqc-audit [PATH] --json # CycloneDX 1.6 CBOM to stdout
|
|
60
|
+
python -m pqc_scanner [PATH] # equivalent, without installing
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Running it against the bundled `examples/` (Python source + a `requirements.txt`):
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
pqc-audit 0.1.0 · scanned examples
|
|
67
|
+
CRITICAL: 5 MEDIUM: 1 INFO: 1
|
|
68
|
+
┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
69
|
+
┃ Severity ┃ Algorithm ┃ Usage ┃ Location ┃ Migrate to ┃
|
|
70
|
+
┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
|
|
71
|
+
│ CRITICAL │ RSA/ECC/DH/Ed25519 │ dependency │ examples/requirements │ ML-KEM / ML-DSA │
|
|
72
|
+
│ CRITICAL │ RSA/ECC (OpenSSL) │ dependency │ examples/requirements │ ML-KEM / ML-DSA │
|
|
73
|
+
│ CRITICAL │ RSA/ECDSA (SSH) │ dependency │ examples/requirements │ ML-KEM / ML-DSA │
|
|
74
|
+
│ CRITICAL │ RSA-2048 │ key_generation │ examples/vulnerable_… │ ML-KEM / ML-DSA │
|
|
75
|
+
│ CRITICAL │ ECC-P-256 │ key_generation │ examples/vulnerable_… │ ML-KEM (ECDH) / ML-DSA │
|
|
76
|
+
│ MEDIUM │ AES │ encryption │ examples/vulnerable_… │ AES-256 │
|
|
77
|
+
│ INFO │ ML-KEM/ML-DSA │ dependency │ examples/requirements │ already post-quantum │
|
|
78
|
+
└──────────┴────────────────────┴────────────────┴───────────────────────┴────────────────────────┘
|
|
79
|
+
Verdict: quantum-critical cryptography in use — migration needed.
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The header count (`CRITICAL: 5 MEDIUM: 1 INFO: 1`) is the at-a-glance verdict.
|
|
83
|
+
|
|
84
|
+
### JSON / CBOM output
|
|
85
|
+
|
|
86
|
+
`--json` emits a **CycloneDX 1.6 CBOM** (Cryptography Bill of Materials),
|
|
87
|
+
validated against the official schema. Code findings become `cryptographic-asset`
|
|
88
|
+
components; dependency findings become `library` components (with `purl` and
|
|
89
|
+
version). The scanner's assessment (severity, quantum classification, migration
|
|
90
|
+
target) rides along as namespaced `properties`.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pqc-audit path/to/repo --json > cbom.json
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## MCP server (for AI agents)
|
|
97
|
+
|
|
98
|
+
The same engine is exposed over the [Model Context Protocol](https://modelcontextprotocol.io),
|
|
99
|
+
so any MCP-capable agent (Claude, Cursor, …) can scan a local repo conversationally.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
pip install ".[mcp]" # installs the optional MCP SDK
|
|
103
|
+
pqc-audit-mcp # runs the server over stdio
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Register it with Claude Code:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
claude mcp add pqc-audit -- pqc-audit-mcp
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Or add it to a client config (e.g. Claude Desktop `claude_desktop_config.json`):
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"mcpServers": {
|
|
117
|
+
"pqc-audit": { "command": "pqc-audit-mcp" }
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
It exposes two tools:
|
|
123
|
+
|
|
124
|
+
- **`scan_repository(path)`** — an at-a-glance verdict, severity counts, and the
|
|
125
|
+
findings, each with its location and suggested post-quantum migration target.
|
|
126
|
+
- **`generate_cbom(path)`** — the full CycloneDX 1.6 CBOM.
|
|
127
|
+
|
|
128
|
+
## Architecture
|
|
129
|
+
|
|
130
|
+
The engine is a **library**; the interfaces are **thin wrappers**. All detection
|
|
131
|
+
logic lives in the `pqc_scanner` core, exposed through a small public API:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from pqc_scanner import scan, to_cbom
|
|
135
|
+
findings = scan(path) # list[Finding] (code + dependency findings)
|
|
136
|
+
cbom = to_cbom(findings) # CycloneDX 1.6 CBOM dict
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The CLI and the MCP server are just thin faces of the same engine (a skill is next).
|
|
140
|
+
|
|
141
|
+
## Tests
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
pytest
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## v1 scope
|
|
148
|
+
|
|
149
|
+
- **Python** ecosystem only.
|
|
150
|
+
- **Static** analysis of local files: source code (AST) + dependency manifests.
|
|
151
|
+
- Outputs: colored terminal summary + JSON aligned with CycloneDX CBOM.
|
|
152
|
+
|
|
153
|
+
**Known limit (by design):** the AST engine detects direct, statically-resolvable
|
|
154
|
+
use; strong indirection (dependency injection, factories, dynamic `getattr`) is
|
|
155
|
+
out of scope until a future data-flow/taint layer. The dependency complement is a
|
|
156
|
+
presence lookup, not proof a primitive is used.
|
|
157
|
+
|
|
158
|
+
See [`CLAUDE.md`](CLAUDE.md) for the full design and build plan.
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
MIT — see [`LICENSE`](LICENSE).
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pqc-audit"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Scans local repositories for quantum-vulnerable cryptography and produces an exposure report with post-quantum migration targets."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Aaron Vives", email = "aaronvives@icloud.com" }]
|
|
13
|
+
keywords = ["pqc", "post-quantum", "cryptography", "security", "sast", "cbom"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Environment :: Console",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
"Topic :: Security :: Cryptography",
|
|
21
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Programming Language :: Python :: 3.13",
|
|
27
|
+
]
|
|
28
|
+
dependencies = [
|
|
29
|
+
"rich>=13.0",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
mcp = [
|
|
34
|
+
"mcp>=1.2", # Model Context Protocol SDK, for the MCP server interface
|
|
35
|
+
]
|
|
36
|
+
dev = [
|
|
37
|
+
"pytest>=7.0",
|
|
38
|
+
"jsonschema>=4.0", # validates CBOM output against the CycloneDX schema
|
|
39
|
+
"mcp>=1.2", # exercised by the MCP interface tests
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.urls]
|
|
43
|
+
Homepage = "https://github.com/rauleteee/pqc-scanner"
|
|
44
|
+
Repository = "https://github.com/rauleteee/pqc-scanner"
|
|
45
|
+
Issues = "https://github.com/rauleteee/pqc-scanner/issues"
|
|
46
|
+
|
|
47
|
+
[project.scripts]
|
|
48
|
+
pqc-audit = "pqc_scanner.interfaces.cli:main"
|
|
49
|
+
pqc-audit-mcp = "pqc_scanner.interfaces.mcp_server:main"
|
|
50
|
+
|
|
51
|
+
[tool.setuptools.packages.find]
|
|
52
|
+
where = ["src"]
|
|
53
|
+
include = ["pqc_scanner*"]
|
|
54
|
+
|
|
55
|
+
[tool.pytest.ini_options]
|
|
56
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pqc-audit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Scans local repositories for quantum-vulnerable cryptography and produces an exposure report with post-quantum migration targets.
|
|
5
|
+
Author-email: Aaron Vives <aaronvives@icloud.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/rauleteee/pqc-scanner
|
|
8
|
+
Project-URL: Repository, https://github.com/rauleteee/pqc-scanner
|
|
9
|
+
Project-URL: Issues, https://github.com/rauleteee/pqc-scanner/issues
|
|
10
|
+
Keywords: pqc,post-quantum,cryptography,security,sast,cbom
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Topic :: Security :: Cryptography
|
|
17
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: rich>=13.0
|
|
27
|
+
Provides-Extra: mcp
|
|
28
|
+
Requires-Dist: mcp>=1.2; extra == "mcp"
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
31
|
+
Requires-Dist: jsonschema>=4.0; extra == "dev"
|
|
32
|
+
Requires-Dist: mcp>=1.2; extra == "dev"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# PQC Scanner
|
|
36
|
+
|
|
37
|
+
Open-source CLI that scans a local repository for cryptography vulnerable to
|
|
38
|
+
quantum computing (RSA, ECC, ...) and produces an exposure report with concrete
|
|
39
|
+
post-quantum migration targets.
|
|
40
|
+
|
|
41
|
+
> You can't migrate what you can't see. PQC Scanner is the inventory/visibility
|
|
42
|
+
> step of a post-quantum migration: it finds where quantum-vulnerable
|
|
43
|
+
> cryptography lives in your code and dependencies, and tells you what to move it to.
|
|
44
|
+
|
|
45
|
+
> **Status:** v1, Python only. AST detection engine, dependency-manifest
|
|
46
|
+
> complement, rule base, CycloneDX CBOM output and CLI are in place.
|
|
47
|
+
|
|
48
|
+
## What it detects
|
|
49
|
+
|
|
50
|
+
Two static detectors feed one report:
|
|
51
|
+
|
|
52
|
+
- **Source code (AST) — high signal.** Parses Python with the standard `ast`
|
|
53
|
+
module and reports *real uses* of vulnerable primitives (a crypto import **plus**
|
|
54
|
+
a matching call), so comments or variable names never trigger a finding.
|
|
55
|
+
Extracts detail: RSA/DSA/DH key size, EC curve (normalized across libraries —
|
|
56
|
+
`SECP256R1`/`P-256`/`prime256v1` → `P-256`), AES key length, PQC scheme.
|
|
57
|
+
- **Dependency manifests — complement.** Parses `requirements.txt`,
|
|
58
|
+
`pyproject.toml` (PEP 621 + Poetry), `poetry.lock` and `Pipfile.lock` and flags
|
|
59
|
+
declared cryptographic libraries with their version. Low signal on its own (it
|
|
60
|
+
says a library is present, not that a primitive is used), but it seeds the CBOM.
|
|
61
|
+
|
|
62
|
+
Each finding carries: location, algorithm, usage context, quantum classification
|
|
63
|
+
(Shor / Grover / already-PQC), severity, origin (code location | package+version)
|
|
64
|
+
and a **suggested PQC migration target** (key exchange → ML-KEM, signatures → ML-DSA).
|
|
65
|
+
|
|
66
|
+
## Installation
|
|
67
|
+
|
|
68
|
+
With [pipx](https://pipx.pypa.io) for an isolated CLI:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pipx install pqc-audit
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Or from a local clone:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
git clone https://github.com/rauleteee/pqc-scanner
|
|
78
|
+
cd pqc-scanner
|
|
79
|
+
pipx install . # isolated, adds the `pqc-audit` command
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Or for development:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
python -m venv .venv && source .venv/bin/activate
|
|
86
|
+
pip install -e ".[dev]"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Usage
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pqc-audit [PATH] # colored terminal summary (default PATH: .)
|
|
93
|
+
pqc-audit [PATH] --json # CycloneDX 1.6 CBOM to stdout
|
|
94
|
+
python -m pqc_scanner [PATH] # equivalent, without installing
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Running it against the bundled `examples/` (Python source + a `requirements.txt`):
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
pqc-audit 0.1.0 · scanned examples
|
|
101
|
+
CRITICAL: 5 MEDIUM: 1 INFO: 1
|
|
102
|
+
┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
103
|
+
┃ Severity ┃ Algorithm ┃ Usage ┃ Location ┃ Migrate to ┃
|
|
104
|
+
┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
|
|
105
|
+
│ CRITICAL │ RSA/ECC/DH/Ed25519 │ dependency │ examples/requirements │ ML-KEM / ML-DSA │
|
|
106
|
+
│ CRITICAL │ RSA/ECC (OpenSSL) │ dependency │ examples/requirements │ ML-KEM / ML-DSA │
|
|
107
|
+
│ CRITICAL │ RSA/ECDSA (SSH) │ dependency │ examples/requirements │ ML-KEM / ML-DSA │
|
|
108
|
+
│ CRITICAL │ RSA-2048 │ key_generation │ examples/vulnerable_… │ ML-KEM / ML-DSA │
|
|
109
|
+
│ CRITICAL │ ECC-P-256 │ key_generation │ examples/vulnerable_… │ ML-KEM (ECDH) / ML-DSA │
|
|
110
|
+
│ MEDIUM │ AES │ encryption │ examples/vulnerable_… │ AES-256 │
|
|
111
|
+
│ INFO │ ML-KEM/ML-DSA │ dependency │ examples/requirements │ already post-quantum │
|
|
112
|
+
└──────────┴────────────────────┴────────────────┴───────────────────────┴────────────────────────┘
|
|
113
|
+
Verdict: quantum-critical cryptography in use — migration needed.
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The header count (`CRITICAL: 5 MEDIUM: 1 INFO: 1`) is the at-a-glance verdict.
|
|
117
|
+
|
|
118
|
+
### JSON / CBOM output
|
|
119
|
+
|
|
120
|
+
`--json` emits a **CycloneDX 1.6 CBOM** (Cryptography Bill of Materials),
|
|
121
|
+
validated against the official schema. Code findings become `cryptographic-asset`
|
|
122
|
+
components; dependency findings become `library` components (with `purl` and
|
|
123
|
+
version). The scanner's assessment (severity, quantum classification, migration
|
|
124
|
+
target) rides along as namespaced `properties`.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
pqc-audit path/to/repo --json > cbom.json
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## MCP server (for AI agents)
|
|
131
|
+
|
|
132
|
+
The same engine is exposed over the [Model Context Protocol](https://modelcontextprotocol.io),
|
|
133
|
+
so any MCP-capable agent (Claude, Cursor, …) can scan a local repo conversationally.
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pip install ".[mcp]" # installs the optional MCP SDK
|
|
137
|
+
pqc-audit-mcp # runs the server over stdio
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Register it with Claude Code:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
claude mcp add pqc-audit -- pqc-audit-mcp
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Or add it to a client config (e.g. Claude Desktop `claude_desktop_config.json`):
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"mcpServers": {
|
|
151
|
+
"pqc-audit": { "command": "pqc-audit-mcp" }
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
It exposes two tools:
|
|
157
|
+
|
|
158
|
+
- **`scan_repository(path)`** — an at-a-glance verdict, severity counts, and the
|
|
159
|
+
findings, each with its location and suggested post-quantum migration target.
|
|
160
|
+
- **`generate_cbom(path)`** — the full CycloneDX 1.6 CBOM.
|
|
161
|
+
|
|
162
|
+
## Architecture
|
|
163
|
+
|
|
164
|
+
The engine is a **library**; the interfaces are **thin wrappers**. All detection
|
|
165
|
+
logic lives in the `pqc_scanner` core, exposed through a small public API:
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from pqc_scanner import scan, to_cbom
|
|
169
|
+
findings = scan(path) # list[Finding] (code + dependency findings)
|
|
170
|
+
cbom = to_cbom(findings) # CycloneDX 1.6 CBOM dict
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The CLI and the MCP server are just thin faces of the same engine (a skill is next).
|
|
174
|
+
|
|
175
|
+
## Tests
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
pytest
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## v1 scope
|
|
182
|
+
|
|
183
|
+
- **Python** ecosystem only.
|
|
184
|
+
- **Static** analysis of local files: source code (AST) + dependency manifests.
|
|
185
|
+
- Outputs: colored terminal summary + JSON aligned with CycloneDX CBOM.
|
|
186
|
+
|
|
187
|
+
**Known limit (by design):** the AST engine detects direct, statically-resolvable
|
|
188
|
+
use; strong indirection (dependency injection, factories, dynamic `getattr`) is
|
|
189
|
+
out of scope until a future data-flow/taint layer. The dependency complement is a
|
|
190
|
+
presence lookup, not proof a primitive is used.
|
|
191
|
+
|
|
192
|
+
See [`CLAUDE.md`](CLAUDE.md) for the full design and build plan.
|
|
193
|
+
|
|
194
|
+
## License
|
|
195
|
+
|
|
196
|
+
MIT — see [`LICENSE`](LICENSE).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/pqc_audit.egg-info/PKG-INFO
|
|
5
|
+
src/pqc_audit.egg-info/SOURCES.txt
|
|
6
|
+
src/pqc_audit.egg-info/dependency_links.txt
|
|
7
|
+
src/pqc_audit.egg-info/entry_points.txt
|
|
8
|
+
src/pqc_audit.egg-info/requires.txt
|
|
9
|
+
src/pqc_audit.egg-info/top_level.txt
|
|
10
|
+
src/pqc_scanner/__init__.py
|
|
11
|
+
src/pqc_scanner/__main__.py
|
|
12
|
+
src/pqc_scanner/core.py
|
|
13
|
+
src/pqc_scanner/findings.py
|
|
14
|
+
src/pqc_scanner/rules.py
|
|
15
|
+
src/pqc_scanner/detectors/__init__.py
|
|
16
|
+
src/pqc_scanner/detectors/ast_engine.py
|
|
17
|
+
src/pqc_scanner/detectors/dependencies.py
|
|
18
|
+
src/pqc_scanner/detectors/discovery.py
|
|
19
|
+
src/pqc_scanner/interfaces/__init__.py
|
|
20
|
+
src/pqc_scanner/interfaces/cli.py
|
|
21
|
+
src/pqc_scanner/interfaces/mcp_server.py
|
|
22
|
+
src/pqc_scanner/outputs/__init__.py
|
|
23
|
+
src/pqc_scanner/outputs/cbom.py
|
|
24
|
+
src/pqc_scanner/outputs/report.py
|
|
25
|
+
tests/test_ast_engine.py
|
|
26
|
+
tests/test_cbom.py
|
|
27
|
+
tests/test_cli.py
|
|
28
|
+
tests/test_dependencies.py
|
|
29
|
+
tests/test_discovery.py
|
|
30
|
+
tests/test_mcp.py
|
|
31
|
+
tests/test_report.py
|
|
32
|
+
tests/test_smoke.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|