@quantakrypto/core 0.5.0 → 0.7.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/dist/crypto-agility.d.ts +158 -0
- package/dist/crypto-agility.d.ts.map +1 -0
- package/dist/crypto-agility.js +285 -0
- package/dist/crypto-agility.js.map +1 -0
- package/dist/dependencies.d.ts.map +1 -1
- package/dist/dependencies.js +180 -18
- package/dist/dependencies.js.map +1 -1
- package/dist/detectors/source.d.ts.map +1 -1
- package/dist/detectors/source.js +52 -0
- package/dist/detectors/source.js.map +1 -1
- package/dist/hndl.d.ts +241 -0
- package/dist/hndl.d.ts.map +1 -0
- package/dist/hndl.js +752 -0
- package/dist/hndl.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/mandates.d.ts +138 -0
- package/dist/mandates.d.ts.map +1 -0
- package/dist/mandates.js +228 -0
- package/dist/mandates.js.map +1 -0
- package/dist/parallel.d.ts.map +1 -1
- package/dist/parallel.js +22 -23
- package/dist/parallel.js.map +1 -1
- package/dist/report.d.ts +8 -0
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +75 -19
- package/dist/report.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/walk.d.ts +31 -1
- package/dist/walk.d.ts.map +1 -1
- package/dist/walk.js +30 -9
- package/dist/walk.js.map +1 -1
- package/package.json +1 -1
- package/src/crypto-agility.ts +407 -0
- package/src/dependencies.ts +182 -16
- package/src/detectors/source.ts +62 -0
- package/src/hndl.ts +1012 -0
- package/src/index.ts +71 -0
- package/src/mandates.ts +365 -0
- package/src/parallel.ts +21 -20
- package/src/report.ts +84 -19
- package/src/types.ts +9 -1
- package/src/version.ts +1 -1
- package/src/walk.ts +47 -10
package/src/detectors/source.ts
CHANGED
|
@@ -47,6 +47,15 @@ import { CWE_BROKEN_CRYPTO, CWE_CERT_VALIDATION, CWE_WEAK_STRENGTH } from "../cw
|
|
|
47
47
|
// (ordered alternation would otherwise match `rsa` and reject the `-pss` tail).
|
|
48
48
|
const RE_GENERATE_KEYPAIR =
|
|
49
49
|
/generateKeyPair(?:Sync)?\s*\(\s*['"`](rsa-pss|rsa|ec|dsa|dh|x25519|x448|ed25519|ed448)['"`]/g;
|
|
50
|
+
// Variable-typed key generation: `generateKeyPair(kind, …)` where the algorithm
|
|
51
|
+
// argument is an IDENTIFIER (a variable), not a quoted literal, so the concrete
|
|
52
|
+
// family is unknown at scan time but a classical key is still being generated.
|
|
53
|
+
// The lookbehind anchors the call to a word boundary so it does not fire inside
|
|
54
|
+
// a longer identifier (e.g. `myGenerateKeyPair(`); the first argument must be a
|
|
55
|
+
// bare identifier immediately followed by `,` or `)` so a quoted-literal call
|
|
56
|
+
// (handled by RE_GENERATE_KEYPAIR) never matches here.
|
|
57
|
+
const RE_GENERATE_KEYPAIR_VAR =
|
|
58
|
+
/(?<![\w$])generateKeyPair(?:Sync)?\s*\(\s*([A-Za-z_$][\w$]*)\s*[,)]/g;
|
|
50
59
|
|
|
51
60
|
/** Per-key-type classification for `generateKeyPair(Sync)('<type>', …)`. Hoisted
|
|
52
61
|
* to module scope so the direct matcher AND the import-alias pass (below) share
|
|
@@ -177,6 +186,20 @@ function escapeRe(s: string): string {
|
|
|
177
186
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
178
187
|
}
|
|
179
188
|
const RE_CREATE_SIGN_VERIFY = /create(?:Sign|Verify)\s*\(/g;
|
|
189
|
+
// Computed-member (bracket) access to a Node `crypto` method:
|
|
190
|
+
// `crypto['createSign'](…)`, `c["createECDH"](…)`. Bracket access defeats the
|
|
191
|
+
// dotted-call regexes above (which require `name(`), so match a quoted method
|
|
192
|
+
// name inside a `[ '…' ]( ` computed call and route it to the right rule. The
|
|
193
|
+
// method names here take no key-type argument, so no argument parsing is needed;
|
|
194
|
+
// `generateKeyPair(Sync)` bracket access is handled separately (it carries the
|
|
195
|
+
// key-type literal). None of these overlap the dotted regexes (those require the
|
|
196
|
+
// name immediately before `(`, whereas here it is followed by a closing quote).
|
|
197
|
+
const RE_BRACKET_CRYPTO_METHOD =
|
|
198
|
+
/\[\s*['"`](createSign|createVerify|createECDH|createDiffieHellman|createDiffieHellmanGroup|publicEncrypt|privateDecrypt)['"`]\s*\]\s*\(/g;
|
|
199
|
+
// `crypto['generateKeyPairSync']('rsa', …)`: bracket access carrying the quoted
|
|
200
|
+
// key-type literal, classified exactly like the dotted `generateKeyPair` call.
|
|
201
|
+
const RE_BRACKET_KEYGEN =
|
|
202
|
+
/\[\s*['"`]generateKeyPair(?:Sync)?['"`]\s*\]\s*\(\s*['"`](rsa-pss|rsa|ec|dsa|dh|x25519|x448|ed25519|ed448)['"`]/g;
|
|
180
203
|
// One-shot crypto.sign/verify(algorithm, data, key). A LOOKBEHIND (not a
|
|
181
204
|
// consumed char) anchors it so it doesn't fire inside identifiers like `assign(`
|
|
182
205
|
// or `createSign(` (handled by the dedicated createSign/createVerify rule) —
|
|
@@ -375,6 +398,28 @@ const nodeCryptoDetector: Detector = {
|
|
|
375
398
|
pushKeygenFinding(findings, m[1], file, content, m.index, m[0].length);
|
|
376
399
|
});
|
|
377
400
|
|
|
401
|
+
// generateKeyPair(Sync)(<variable>, …): key type passed as a variable, so the
|
|
402
|
+
// family is unknown; emit the generic keygen rule (unknown / key-exchange /
|
|
403
|
+
// HNDL-conservative) rather than missing the classical key generation.
|
|
404
|
+
eachMatch(RE_GENERATE_KEYPAIR_VAR, content, (m) => {
|
|
405
|
+
findings.push(
|
|
406
|
+
findingFromRule(
|
|
407
|
+
RULE_NODE_KEYGEN,
|
|
408
|
+
{ file, content, index: m.index, matchLength: m[0].length },
|
|
409
|
+
{
|
|
410
|
+
title: "Classical key generation (variable key type)",
|
|
411
|
+
message:
|
|
412
|
+
"Generates a classical asymmetric key pair (key type passed as a variable), which is not quantum-safe.",
|
|
413
|
+
},
|
|
414
|
+
),
|
|
415
|
+
);
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// Bracket (computed-member) key generation: crypto['generateKeyPairSync']('rsa').
|
|
419
|
+
eachMatch(RE_BRACKET_KEYGEN, content, (m) => {
|
|
420
|
+
pushKeygenFinding(findings, m[1], file, content, m.index, m[0].length);
|
|
421
|
+
});
|
|
422
|
+
|
|
378
423
|
// Import-alias resolution: follow `import { generateKeyPairSync as gk }` (and
|
|
379
424
|
// the CommonJS destructure-rename) so an aliased call still detects. Only the
|
|
380
425
|
// keygen / ECDH / DH constructors are resolved — their classification is
|
|
@@ -432,6 +477,23 @@ const nodeCryptoDetector: Detector = {
|
|
|
432
477
|
);
|
|
433
478
|
});
|
|
434
479
|
|
|
480
|
+
// Bracket (computed-member) access to argument-free crypto methods:
|
|
481
|
+
// crypto['createSign'](…), c["createECDH"](…). Route each to its rule.
|
|
482
|
+
eachMatch(RE_BRACKET_CRYPTO_METHOD, content, (m) => {
|
|
483
|
+
const loc = { file, content, index: m.index, matchLength: m[0].length };
|
|
484
|
+
const method = m[1];
|
|
485
|
+
if (method === "createSign" || method === "createVerify") {
|
|
486
|
+
findings.push(findingFromRule(RULE_NODE_SIGN, loc));
|
|
487
|
+
} else if (method === "createECDH") {
|
|
488
|
+
findings.push(findingFromRule(RULE_NODE_ECDH, loc));
|
|
489
|
+
} else if (method === "publicEncrypt" || method === "privateDecrypt") {
|
|
490
|
+
findings.push(findingFromRule(RULE_NODE_RSA_ENCRYPT, loc));
|
|
491
|
+
} else {
|
|
492
|
+
// createDiffieHellman / createDiffieHellmanGroup: finite-field DH.
|
|
493
|
+
findings.push(findingFromRule(RULE_NODE_DH, loc));
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
|
|
435
497
|
// One-shot crypto.sign(algorithm, data, key) / crypto.verify(...) (Node ≥ 12).
|
|
436
498
|
eachMatch(RE_ONESHOT_SIGN_VERIFY, content, (m) => {
|
|
437
499
|
findings.push(
|