postquant 0.1.2 → 0.2.0
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.
- package/README.md +58 -8
- package/dist/commands/analyze.d.ts +9 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +119 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/index.js +45 -2
- package/dist/index.js.map +1 -1
- package/dist/output/cbom.d.ts +3 -0
- package/dist/output/cbom.d.ts.map +1 -0
- package/dist/output/cbom.js +235 -0
- package/dist/output/cbom.js.map +1 -0
- package/dist/output/json-code.d.ts +3 -0
- package/dist/output/json-code.d.ts.map +1 -0
- package/dist/output/json-code.js +29 -0
- package/dist/output/json-code.js.map +1 -0
- package/dist/output/sarif.d.ts +3 -0
- package/dist/output/sarif.d.ts.map +1 -0
- package/dist/output/sarif.js +240 -0
- package/dist/output/sarif.js.map +1 -0
- package/dist/output/terminal-code.d.ts +7 -0
- package/dist/output/terminal-code.d.ts.map +1 -0
- package/dist/output/terminal-code.js +95 -0
- package/dist/output/terminal-code.js.map +1 -0
- package/dist/output/terminal.d.ts.map +1 -1
- package/dist/output/terminal.js +14 -2
- package/dist/output/terminal.js.map +1 -1
- package/dist/scanner/code/classifier.d.ts +9 -0
- package/dist/scanner/code/classifier.d.ts.map +1 -0
- package/dist/scanner/code/classifier.js +19 -0
- package/dist/scanner/code/classifier.js.map +1 -0
- package/dist/scanner/code/discovery.d.ts +17 -0
- package/dist/scanner/code/discovery.d.ts.map +1 -0
- package/dist/scanner/code/discovery.js +167 -0
- package/dist/scanner/code/discovery.js.map +1 -0
- package/dist/scanner/code/grader.d.ts +27 -0
- package/dist/scanner/code/grader.d.ts.map +1 -0
- package/dist/scanner/code/grader.js +115 -0
- package/dist/scanner/code/grader.js.map +1 -0
- package/dist/scanner/code/matcher.d.ts +11 -0
- package/dist/scanner/code/matcher.d.ts.map +1 -0
- package/dist/scanner/code/matcher.js +208 -0
- package/dist/scanner/code/matcher.js.map +1 -0
- package/dist/scanner/code/patterns/go.d.ts +3 -0
- package/dist/scanner/code/patterns/go.d.ts.map +1 -0
- package/dist/scanner/code/patterns/go.js +226 -0
- package/dist/scanner/code/patterns/go.js.map +1 -0
- package/dist/scanner/code/patterns/index.d.ts +11 -0
- package/dist/scanner/code/patterns/index.d.ts.map +1 -0
- package/dist/scanner/code/patterns/index.js +20 -0
- package/dist/scanner/code/patterns/index.js.map +1 -0
- package/dist/scanner/code/patterns/java.d.ts +3 -0
- package/dist/scanner/code/patterns/java.d.ts.map +1 -0
- package/dist/scanner/code/patterns/java.js +239 -0
- package/dist/scanner/code/patterns/java.js.map +1 -0
- package/dist/scanner/code/patterns/javascript.d.ts +3 -0
- package/dist/scanner/code/patterns/javascript.d.ts.map +1 -0
- package/dist/scanner/code/patterns/javascript.js +243 -0
- package/dist/scanner/code/patterns/javascript.js.map +1 -0
- package/dist/scanner/code/patterns/python.d.ts +3 -0
- package/dist/scanner/code/patterns/python.d.ts.map +1 -0
- package/dist/scanner/code/patterns/python.js +255 -0
- package/dist/scanner/code/patterns/python.js.map +1 -0
- package/dist/types/index.d.ts +118 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
# PostQuant
|
|
2
2
|
|
|
3
|
-
**Find quantum-vulnerable cryptography in your TLS endpoints.**
|
|
3
|
+
**Find quantum-vulnerable cryptography in your TLS endpoints and source code.**
|
|
4
4
|
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://www.npmjs.com/package/postquant)
|
|
7
7
|
|
|
8
|
-
PostQuant scans TLS connections and reports which algorithms are vulnerable to quantum attacks
|
|
9
|
-
|
|
10
|
-
> **Early development.** The TLS scanner works. Code scanning and CBOM generation are planned.
|
|
8
|
+
PostQuant scans TLS connections and source code, reports which algorithms are vulnerable to quantum attacks, grades them A+ through F, and tells you what to migrate to. Supports Python, JavaScript/TypeScript, Go, and Java.
|
|
11
9
|
|
|
12
10
|
## Why
|
|
13
11
|
|
|
@@ -38,8 +36,18 @@ Output:
|
|
|
38
36
|
|
|
39
37
|
Most sites today score C+ or C. That's expected — almost nobody has deployed post-quantum cryptography yet.
|
|
40
38
|
|
|
39
|
+
### Scan Source Code
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx postquant analyze ./src
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Scans Python, JavaScript/TypeScript, Go, and Java files for quantum-vulnerable cryptographic patterns (RSA, ECDSA, ECDH, DH, DSA, MD5, SHA-1, DES/3DES, AES-128) and reports findings with migration recommendations.
|
|
46
|
+
|
|
41
47
|
## Usage
|
|
42
48
|
|
|
49
|
+
### TLS Scanning
|
|
50
|
+
|
|
43
51
|
```bash
|
|
44
52
|
# Scan a single host
|
|
45
53
|
postquant scan example.com
|
|
@@ -60,6 +68,37 @@ postquant scan --file hosts.txt
|
|
|
60
68
|
postquant scan example.com --timeout 5000
|
|
61
69
|
```
|
|
62
70
|
|
|
71
|
+
### Code Scanning
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Scan a directory
|
|
75
|
+
postquant analyze ./src
|
|
76
|
+
|
|
77
|
+
# Scan a single file
|
|
78
|
+
postquant analyze ./src/auth.py
|
|
79
|
+
|
|
80
|
+
# Filter by language
|
|
81
|
+
postquant analyze ./src --language python
|
|
82
|
+
|
|
83
|
+
# JSON output
|
|
84
|
+
postquant analyze ./src --format json
|
|
85
|
+
|
|
86
|
+
# SARIF output (for GitHub Code Scanning)
|
|
87
|
+
postquant analyze ./src --format sarif > results.sarif
|
|
88
|
+
|
|
89
|
+
# CycloneDX CBOM output
|
|
90
|
+
postquant analyze ./src --format cbom > cbom.json
|
|
91
|
+
|
|
92
|
+
# Exclude directories
|
|
93
|
+
postquant analyze . --ignore "vendor/**" --ignore "test/**"
|
|
94
|
+
|
|
95
|
+
# Set fail threshold for CI
|
|
96
|
+
postquant analyze ./src --fail-grade D
|
|
97
|
+
|
|
98
|
+
# Show all findings including safe ones
|
|
99
|
+
postquant analyze ./src --verbose
|
|
100
|
+
```
|
|
101
|
+
|
|
63
102
|
## Grading
|
|
64
103
|
|
|
65
104
|
| Grade | Meaning |
|
|
@@ -75,13 +114,24 @@ postquant scan example.com --timeout 5000
|
|
|
75
114
|
|
|
76
115
|
+/- modifiers reflect classical crypto hygiene within each grade band.
|
|
77
116
|
|
|
117
|
+
### GitHub Actions
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
- run: npx postquant analyze . --format sarif > results.sarif
|
|
121
|
+
- uses: github/codeql-action/upload-sarif@v3
|
|
122
|
+
with:
|
|
123
|
+
sarif_file: results.sarif
|
|
124
|
+
category: postquant
|
|
125
|
+
```
|
|
126
|
+
|
|
78
127
|
## Development
|
|
79
128
|
|
|
80
129
|
```bash
|
|
81
130
|
npm install # Install dependencies
|
|
82
131
|
npm run build # Compile TypeScript
|
|
83
132
|
npm test # Run tests
|
|
84
|
-
npm run dev -- scan example.com
|
|
133
|
+
npm run dev -- scan example.com # TLS scan from source
|
|
134
|
+
npm run dev -- analyze ./src # Code scan from source
|
|
85
135
|
```
|
|
86
136
|
|
|
87
137
|
## Roadmap
|
|
@@ -89,9 +139,9 @@ npm run dev -- scan example.com # Run from source
|
|
|
89
139
|
| Phase | Target | Status |
|
|
90
140
|
|-------|--------|--------|
|
|
91
141
|
| TLS scanner CLI | March 2026 | v0.1.0 |
|
|
92
|
-
| Code scanner (Python, JS, Go, Java) |
|
|
93
|
-
|
|
|
94
|
-
| Web dashboard |
|
|
142
|
+
| Code scanner (Python, JS, Go, Java) | March 2026 | v0.2.0 |
|
|
143
|
+
| Migration playbook engine | April 2026 | Planned |
|
|
144
|
+
| Web dashboard | May 2026 | Planned |
|
|
95
145
|
|
|
96
146
|
See [docs/ROADMAP.md](docs/ROADMAP.md) for details.
|
|
97
147
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AnalyzeOptions, Grade } from '../types/index.js';
|
|
2
|
+
interface AnalyzeResult {
|
|
3
|
+
exitCode: number;
|
|
4
|
+
output: string;
|
|
5
|
+
grade: Grade | null;
|
|
6
|
+
}
|
|
7
|
+
export declare function analyzeCommand(targetPath: string, options: AnalyzeOptions): Promise<AnalyzeResult>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=analyze.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAyB,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAmBtF,UAAU,aAAa;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CAgGxB"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { stat } from 'node:fs/promises';
|
|
2
|
+
import { join, resolve, basename, extname } from 'node:path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { discoverFiles } from '../scanner/code/discovery.js';
|
|
5
|
+
import { matchFile } from '../scanner/code/matcher.js';
|
|
6
|
+
import { classifyCodeFindings } from '../scanner/code/classifier.js';
|
|
7
|
+
import { gradeCodeScan, shouldFailForCodeGrade } from '../scanner/code/grader.js';
|
|
8
|
+
import { formatCodeTerminal } from '../output/terminal-code.js';
|
|
9
|
+
import { formatCodeJson } from '../output/json-code.js';
|
|
10
|
+
import { formatSarif } from '../output/sarif.js';
|
|
11
|
+
import { formatCbom } from '../output/cbom.js';
|
|
12
|
+
/** Extension → Language mapping (duplicated from discovery for single-file mode). */
|
|
13
|
+
const EXTENSION_MAP = {
|
|
14
|
+
'.py': 'python',
|
|
15
|
+
'.pyw': 'python',
|
|
16
|
+
'.pyi': 'python',
|
|
17
|
+
'.js': 'javascript',
|
|
18
|
+
'.mjs': 'javascript',
|
|
19
|
+
'.cjs': 'javascript',
|
|
20
|
+
'.jsx': 'javascript',
|
|
21
|
+
'.ts': 'javascript',
|
|
22
|
+
'.mts': 'javascript',
|
|
23
|
+
'.cts': 'javascript',
|
|
24
|
+
'.tsx': 'javascript',
|
|
25
|
+
'.go': 'go',
|
|
26
|
+
'.java': 'java',
|
|
27
|
+
};
|
|
28
|
+
export async function analyzeCommand(targetPath, options) {
|
|
29
|
+
const absPath = resolve(targetPath);
|
|
30
|
+
let fileStat;
|
|
31
|
+
try {
|
|
32
|
+
fileStat = await stat(absPath);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return {
|
|
36
|
+
exitCode: 1,
|
|
37
|
+
output: chalk.red(`Error: path does not exist: ${targetPath}`),
|
|
38
|
+
grade: null,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const startTime = Date.now();
|
|
42
|
+
const allFindings = [];
|
|
43
|
+
let filesScanned = 0;
|
|
44
|
+
if (fileStat.isFile()) {
|
|
45
|
+
// Single file mode
|
|
46
|
+
const ext = extname(absPath);
|
|
47
|
+
const lang = EXTENSION_MAP[ext];
|
|
48
|
+
if (lang && (!options.language || options.language === lang)) {
|
|
49
|
+
const findings = await matchFile(absPath, lang);
|
|
50
|
+
// Normalize file paths to be relative-ish (just the basename for single files)
|
|
51
|
+
for (const f of findings) {
|
|
52
|
+
f.file = basename(absPath);
|
|
53
|
+
}
|
|
54
|
+
allFindings.push(...findings);
|
|
55
|
+
filesScanned = 1;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
filesScanned = 1;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
// Directory mode
|
|
63
|
+
const discovered = await discoverFiles(absPath, {
|
|
64
|
+
ignore: options.ignore,
|
|
65
|
+
ignoreFile: options.ignoreFile,
|
|
66
|
+
maxFiles: options.maxFiles,
|
|
67
|
+
language: options.language,
|
|
68
|
+
});
|
|
69
|
+
filesScanned = discovered.length;
|
|
70
|
+
for (const file of discovered) {
|
|
71
|
+
const fullPath = join(absPath, file.path);
|
|
72
|
+
try {
|
|
73
|
+
const findings = await matchFile(fullPath, file.language);
|
|
74
|
+
// Normalize to relative path from scan root
|
|
75
|
+
for (const f of findings) {
|
|
76
|
+
f.file = file.path;
|
|
77
|
+
}
|
|
78
|
+
allFindings.push(...findings);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// Skip files that can't be read
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const durationMs = Date.now() - startTime;
|
|
86
|
+
const scanRoot = fileStat.isFile() ? absPath : absPath;
|
|
87
|
+
// Pipeline: classify → grade → format
|
|
88
|
+
const classified = classifyCodeFindings(allFindings, scanRoot, filesScanned, durationMs);
|
|
89
|
+
const graded = gradeCodeScan(classified);
|
|
90
|
+
// Format output
|
|
91
|
+
let output;
|
|
92
|
+
switch (options.format) {
|
|
93
|
+
case 'json':
|
|
94
|
+
output = formatCodeJson(graded);
|
|
95
|
+
break;
|
|
96
|
+
case 'sarif':
|
|
97
|
+
output = formatSarif(graded);
|
|
98
|
+
break;
|
|
99
|
+
case 'cbom':
|
|
100
|
+
output = formatCbom(graded);
|
|
101
|
+
break;
|
|
102
|
+
case 'terminal':
|
|
103
|
+
default:
|
|
104
|
+
output = formatCodeTerminal(graded, {
|
|
105
|
+
verbose: options.verbose,
|
|
106
|
+
noMigration: options.noMigration,
|
|
107
|
+
});
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
// Determine exit code
|
|
111
|
+
const shouldFail = shouldFailForCodeGrade(graded.baseGrade, options.failGrade);
|
|
112
|
+
const exitCode = shouldFail ? 1 : 0;
|
|
113
|
+
return {
|
|
114
|
+
exitCode,
|
|
115
|
+
output,
|
|
116
|
+
grade: graded.grade,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=analyze.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import { scanCommand } from './commands/scan.js';
|
|
4
|
+
import { analyzeCommand } from './commands/analyze.js';
|
|
4
5
|
const VALID_GRADES = ['A+', 'A', 'B', 'C', 'D', 'F'];
|
|
6
|
+
const VALID_ANALYZE_FORMATS = ['terminal', 'json', 'sarif', 'cbom'];
|
|
7
|
+
const VALID_LANGUAGES = ['python', 'javascript', 'go', 'java'];
|
|
5
8
|
const program = new Command();
|
|
6
9
|
program
|
|
7
10
|
.name('postquant')
|
|
8
|
-
.description('Scan TLS endpoints for quantum-vulnerable cryptography')
|
|
9
|
-
.version('0.
|
|
11
|
+
.description('Scan TLS endpoints and source code for quantum-vulnerable cryptography')
|
|
12
|
+
.version('0.2.0');
|
|
10
13
|
program
|
|
11
14
|
.command('scan')
|
|
12
15
|
.description('Scan one or more TLS endpoints for quantum readiness')
|
|
@@ -36,5 +39,45 @@ program
|
|
|
36
39
|
});
|
|
37
40
|
process.exit(exitCode);
|
|
38
41
|
});
|
|
42
|
+
program
|
|
43
|
+
.command('analyze')
|
|
44
|
+
.description('Scan source code for quantum-vulnerable cryptography')
|
|
45
|
+
.argument('<path>', 'Directory or file to scan')
|
|
46
|
+
.option('-f, --format <format>', 'Output format (terminal, json, sarif, cbom)', 'terminal')
|
|
47
|
+
.option('-l, --language <language>', 'Filter by language (python, javascript, go, java)')
|
|
48
|
+
.option('--fail-grade <grade>', 'Exit non-zero at this grade or worse', 'C')
|
|
49
|
+
.option('--ignore <patterns...>', 'Glob patterns to exclude')
|
|
50
|
+
.option('--ignore-file <path>', 'File with ignore patterns', '.postquantignore')
|
|
51
|
+
.option('--max-files <count>', 'Maximum files to scan', '10000')
|
|
52
|
+
.option('--verbose', 'Show all findings including safe ones', false)
|
|
53
|
+
.option('--no-migration', 'Hide migration recommendations')
|
|
54
|
+
.action(async (targetPath, opts) => {
|
|
55
|
+
const format = opts.format;
|
|
56
|
+
if (!VALID_ANALYZE_FORMATS.includes(format)) {
|
|
57
|
+
console.error(`Invalid format: ${format}. Use one of: ${VALID_ANALYZE_FORMATS.join(', ')}`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
if (opts.language && !VALID_LANGUAGES.includes(opts.language)) {
|
|
61
|
+
console.error(`Invalid language: ${opts.language}. Use one of: ${VALID_LANGUAGES.join(', ')}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
const failGrade = opts.failGrade;
|
|
65
|
+
if (!VALID_GRADES.includes(failGrade)) {
|
|
66
|
+
console.error(`Invalid fail-grade: ${failGrade}. Use one of: ${VALID_GRADES.join(', ')}`);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
const { exitCode, output } = await analyzeCommand(targetPath, {
|
|
70
|
+
format,
|
|
71
|
+
language: opts.language,
|
|
72
|
+
failGrade,
|
|
73
|
+
ignore: opts.ignore ?? [],
|
|
74
|
+
ignoreFile: opts.ignoreFile,
|
|
75
|
+
maxFiles: parseInt(opts.maxFiles, 10),
|
|
76
|
+
verbose: opts.verbose,
|
|
77
|
+
noMigration: !opts.migration,
|
|
78
|
+
});
|
|
79
|
+
console.log(output);
|
|
80
|
+
process.exit(exitCode);
|
|
81
|
+
});
|
|
39
82
|
program.parse();
|
|
40
83
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cbom.d.ts","sourceRoot":"","sources":["../../src/output/cbom.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAA+B,MAAM,mBAAmB,CAAC;AA0EvF,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAiF3D"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
function getVersion() {
|
|
6
|
+
try {
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', 'package.json'), 'utf-8'));
|
|
9
|
+
return pkg.version;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return '0.1.1';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
// --- Category → CycloneDX primitive mapping (Section 7.3) ---
|
|
16
|
+
function categoryToPrimitive(category) {
|
|
17
|
+
switch (category) {
|
|
18
|
+
case 'asymmetric-encryption':
|
|
19
|
+
return 'pke';
|
|
20
|
+
case 'digital-signature':
|
|
21
|
+
return 'signature';
|
|
22
|
+
case 'key-exchange':
|
|
23
|
+
return 'kex';
|
|
24
|
+
case 'weak-symmetric':
|
|
25
|
+
case 'safe-symmetric':
|
|
26
|
+
case 'broken-cipher':
|
|
27
|
+
return 'ae';
|
|
28
|
+
case 'weak-hash':
|
|
29
|
+
case 'safe-hash':
|
|
30
|
+
return 'hash';
|
|
31
|
+
case 'pqc-algorithm':
|
|
32
|
+
return 'kem'; // default for PQC; could vary by algorithm
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// --- NIST Quantum Security Level mapping (Section 7.4) ---
|
|
36
|
+
function nistQuantumSecurityLevel(finding) {
|
|
37
|
+
// Level 0: broken by quantum computer (all critical asymmetric, weak-hash, broken-cipher)
|
|
38
|
+
if (finding.risk === 'critical')
|
|
39
|
+
return 0;
|
|
40
|
+
// Level 5: AES-256, SHA-384, SHA-512, SHA-3, ChaCha20
|
|
41
|
+
const algoUpper = finding.algorithm.toUpperCase();
|
|
42
|
+
if (algoUpper.includes('AES-256') ||
|
|
43
|
+
algoUpper.includes('SHA-384') ||
|
|
44
|
+
algoUpper.includes('SHA-512') ||
|
|
45
|
+
algoUpper.includes('SHA3') ||
|
|
46
|
+
algoUpper.includes('SHA-3') ||
|
|
47
|
+
algoUpper.includes('CHACHA20')) {
|
|
48
|
+
return 5;
|
|
49
|
+
}
|
|
50
|
+
// Moderate (AES-128): effectively ~level 1 post-Grover
|
|
51
|
+
if (algoUpper.includes('AES-128'))
|
|
52
|
+
return 1;
|
|
53
|
+
// PQC algorithms
|
|
54
|
+
if (finding.category === 'pqc-algorithm') {
|
|
55
|
+
if (algoUpper.includes('512') || algoUpper.includes('-44'))
|
|
56
|
+
return 1;
|
|
57
|
+
if (algoUpper.includes('768') || algoUpper.includes('-65'))
|
|
58
|
+
return 3;
|
|
59
|
+
if (algoUpper.includes('1024') || algoUpper.includes('-87'))
|
|
60
|
+
return 5;
|
|
61
|
+
return 3; // default PQC
|
|
62
|
+
}
|
|
63
|
+
// Safe hash/symmetric defaults
|
|
64
|
+
if (finding.risk === 'safe')
|
|
65
|
+
return 5;
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
// --- Public API ---
|
|
69
|
+
export function formatCbom(result) {
|
|
70
|
+
// Group findings by algorithm name
|
|
71
|
+
const byAlgorithm = new Map();
|
|
72
|
+
for (const f of result.findings) {
|
|
73
|
+
const list = byAlgorithm.get(f.algorithm) ?? [];
|
|
74
|
+
list.push(f);
|
|
75
|
+
byAlgorithm.set(f.algorithm, list);
|
|
76
|
+
}
|
|
77
|
+
// Build components
|
|
78
|
+
const components = [];
|
|
79
|
+
const componentRefs = [];
|
|
80
|
+
for (const [algorithm, findings] of byAlgorithm) {
|
|
81
|
+
const ref = randomUUID();
|
|
82
|
+
componentRefs.push(ref);
|
|
83
|
+
const representative = findings[0];
|
|
84
|
+
const occurrences = findings.map((f) => ({
|
|
85
|
+
location: f.file,
|
|
86
|
+
line: f.line,
|
|
87
|
+
additionalContext: f.matchedLine,
|
|
88
|
+
}));
|
|
89
|
+
components.push({
|
|
90
|
+
type: 'cryptographic-asset',
|
|
91
|
+
name: algorithm,
|
|
92
|
+
'bom-ref': ref,
|
|
93
|
+
evidence: { occurrences },
|
|
94
|
+
cryptoProperties: {
|
|
95
|
+
assetType: 'algorithm',
|
|
96
|
+
algorithmProperties: {
|
|
97
|
+
primitive: categoryToPrimitive(representative.category),
|
|
98
|
+
parameterSetIdentifier: extractParameterSet(representative),
|
|
99
|
+
cryptoFunctions: inferCryptoFunctions(representative),
|
|
100
|
+
classicalSecurityLevel: classicalSecurityLevel(representative),
|
|
101
|
+
nistQuantumSecurityLevel: nistQuantumSecurityLevel(representative),
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const cbom = {
|
|
107
|
+
bomFormat: 'CycloneDX',
|
|
108
|
+
specVersion: '1.6',
|
|
109
|
+
version: 1,
|
|
110
|
+
serialNumber: `urn:uuid:${randomUUID()}`,
|
|
111
|
+
metadata: {
|
|
112
|
+
timestamp: new Date().toISOString(),
|
|
113
|
+
tools: {
|
|
114
|
+
components: [
|
|
115
|
+
{
|
|
116
|
+
type: 'application',
|
|
117
|
+
name: 'postquant',
|
|
118
|
+
version: getVersion(),
|
|
119
|
+
description: 'Quantum readiness scanner',
|
|
120
|
+
externalReferences: [
|
|
121
|
+
{
|
|
122
|
+
type: 'website',
|
|
123
|
+
url: 'https://postquant.dev',
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
component: {
|
|
130
|
+
type: 'application',
|
|
131
|
+
name: extractProjectName(result.scanRoot),
|
|
132
|
+
'bom-ref': 'scanned-project',
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
components,
|
|
136
|
+
dependencies: [
|
|
137
|
+
{
|
|
138
|
+
ref: 'scanned-project',
|
|
139
|
+
dependsOn: componentRefs,
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
};
|
|
143
|
+
return JSON.stringify(cbom, null, 2);
|
|
144
|
+
}
|
|
145
|
+
// --- Helpers ---
|
|
146
|
+
function extractProjectName(scanRoot) {
|
|
147
|
+
const parts = scanRoot.split('/').filter(Boolean);
|
|
148
|
+
return parts[parts.length - 1] || 'unknown-project';
|
|
149
|
+
}
|
|
150
|
+
function extractParameterSet(finding) {
|
|
151
|
+
if (finding.keySize)
|
|
152
|
+
return String(finding.keySize);
|
|
153
|
+
// Try to pull numbers from algorithm name (e.g., "RSA-2048" → "2048")
|
|
154
|
+
const match = finding.algorithm.match(/(\d+)/);
|
|
155
|
+
return match ? match[1] : '';
|
|
156
|
+
}
|
|
157
|
+
function inferCryptoFunctions(finding) {
|
|
158
|
+
const id = finding.patternId.toLowerCase();
|
|
159
|
+
if (id.includes('keygen') || id.includes('generate'))
|
|
160
|
+
return ['keygen'];
|
|
161
|
+
if (id.includes('sign'))
|
|
162
|
+
return ['sign', 'verify'];
|
|
163
|
+
if (id.includes('encrypt') || id.includes('cipher'))
|
|
164
|
+
return ['encrypt', 'decrypt'];
|
|
165
|
+
if (id.includes('exchange') || id.includes('dh') || id.includes('ecdh'))
|
|
166
|
+
return ['keyexchange'];
|
|
167
|
+
if (id.includes('hash') || id.includes('md5') || id.includes('sha'))
|
|
168
|
+
return ['digest'];
|
|
169
|
+
// Default based on category
|
|
170
|
+
switch (finding.category) {
|
|
171
|
+
case 'asymmetric-encryption':
|
|
172
|
+
return ['keygen', 'encrypt', 'decrypt'];
|
|
173
|
+
case 'digital-signature':
|
|
174
|
+
return ['sign', 'verify'];
|
|
175
|
+
case 'key-exchange':
|
|
176
|
+
return ['keyexchange'];
|
|
177
|
+
case 'weak-hash':
|
|
178
|
+
case 'safe-hash':
|
|
179
|
+
return ['digest'];
|
|
180
|
+
case 'weak-symmetric':
|
|
181
|
+
case 'safe-symmetric':
|
|
182
|
+
case 'broken-cipher':
|
|
183
|
+
return ['encrypt', 'decrypt'];
|
|
184
|
+
case 'pqc-algorithm':
|
|
185
|
+
return ['keygen'];
|
|
186
|
+
default:
|
|
187
|
+
return ['unknown'];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function classicalSecurityLevel(finding) {
|
|
191
|
+
const algoUpper = finding.algorithm.toUpperCase();
|
|
192
|
+
// RSA key sizes
|
|
193
|
+
if (algoUpper.includes('RSA')) {
|
|
194
|
+
if (algoUpper.includes('4096'))
|
|
195
|
+
return 140;
|
|
196
|
+
if (algoUpper.includes('3072'))
|
|
197
|
+
return 128;
|
|
198
|
+
if (algoUpper.includes('2048'))
|
|
199
|
+
return 112;
|
|
200
|
+
if (algoUpper.includes('1024'))
|
|
201
|
+
return 80;
|
|
202
|
+
return 112;
|
|
203
|
+
}
|
|
204
|
+
// ECC curves
|
|
205
|
+
if (algoUpper.includes('P-521') || algoUpper.includes('SECP521'))
|
|
206
|
+
return 256;
|
|
207
|
+
if (algoUpper.includes('P-384') || algoUpper.includes('SECP384'))
|
|
208
|
+
return 192;
|
|
209
|
+
if (algoUpper.includes('P-256') || algoUpper.includes('SECP256') || algoUpper.includes('ED25519') || algoUpper.includes('X25519'))
|
|
210
|
+
return 128;
|
|
211
|
+
// Symmetric
|
|
212
|
+
if (algoUpper.includes('AES-256') || algoUpper.includes('CHACHA20'))
|
|
213
|
+
return 256;
|
|
214
|
+
if (algoUpper.includes('AES-192'))
|
|
215
|
+
return 192;
|
|
216
|
+
if (algoUpper.includes('AES-128'))
|
|
217
|
+
return 128;
|
|
218
|
+
if (algoUpper.includes('3DES'))
|
|
219
|
+
return 112;
|
|
220
|
+
if (algoUpper.includes('DES'))
|
|
221
|
+
return 56;
|
|
222
|
+
// Hashes
|
|
223
|
+
if (algoUpper.includes('SHA-512') || algoUpper.includes('SHA3-512'))
|
|
224
|
+
return 256;
|
|
225
|
+
if (algoUpper.includes('SHA-384') || algoUpper.includes('SHA3-384'))
|
|
226
|
+
return 192;
|
|
227
|
+
if (algoUpper.includes('SHA-256') || algoUpper.includes('SHA3-256'))
|
|
228
|
+
return 128;
|
|
229
|
+
if (algoUpper.includes('SHA-1') || algoUpper === 'SHA1')
|
|
230
|
+
return 80;
|
|
231
|
+
if (algoUpper.includes('MD5'))
|
|
232
|
+
return 64;
|
|
233
|
+
return 0;
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=cbom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cbom.js","sourceRoot":"","sources":["../../src/output/cbom.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-code.d.ts","sourceRoot":"","sources":["../../src/output/json-code.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAc1D,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAe/D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
function getVersion() {
|
|
5
|
+
try {
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', 'package.json'), 'utf-8'));
|
|
8
|
+
return pkg.version;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return '0.1.1';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function formatCodeJson(result) {
|
|
15
|
+
const output = {
|
|
16
|
+
version: getVersion(),
|
|
17
|
+
timestamp: new Date().toISOString(),
|
|
18
|
+
scanRoot: result.scanRoot,
|
|
19
|
+
grade: result.grade,
|
|
20
|
+
baseGrade: result.baseGrade,
|
|
21
|
+
modifier: result.modifier,
|
|
22
|
+
findings: result.findings,
|
|
23
|
+
summary: result.summary,
|
|
24
|
+
migrationNotes: result.migrationNotes,
|
|
25
|
+
fileBreakdown: result.fileBreakdown,
|
|
26
|
+
};
|
|
27
|
+
return JSON.stringify(output, null, 2);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=json-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-code.js","sourceRoot":"","sources":["../../src/output/json-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG1C,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CACnE,CAAC;QACF,OAAO,GAAG,CAAC,OAAO,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAwB;IACrD,MAAM,MAAM,GAAG;QACb,OAAO,EAAE,UAAU,EAAE;QACrB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,aAAa,EAAE,MAAM,CAAC,aAAa;KACpC,CAAC;IAEF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif.d.ts","sourceRoot":"","sources":["../../src/output/sarif.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAA0C,MAAM,mBAAmB,CAAC;AA+MlG,wBAAgB,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CA0D5D"}
|