@cyclonedx/cdxgen 12.4.0 → 12.4.2
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 +6 -4
- package/bin/cdxgen.js +32 -11
- package/bin/convert.js +12 -8
- package/bin/evinse.js +15 -0
- package/bin/hbom.js +13 -8
- package/bin/repl.js +14 -10
- package/bin/validate.js +10 -13
- package/bin/verify.js +7 -29
- package/data/cyclonedx-2.0-bundled.schema.json +7182 -0
- package/lib/audit/index.js +2 -1
- package/lib/cli/index.js +77 -16
- package/lib/cli/index.poku.js +197 -0
- package/lib/evinser/evinser.js +118 -3
- package/lib/helpers/bomUtils.js +155 -1
- package/lib/helpers/bomUtils.poku.js +79 -1
- package/lib/helpers/cbomutils.js +162 -2
- package/lib/helpers/cbomutils.poku.js +100 -0
- package/lib/helpers/ciParsers/githubActions.js +15 -3
- package/lib/helpers/ciParsers/githubActions.poku.js +52 -0
- package/lib/helpers/dosai.js +433 -0
- package/lib/helpers/dosai.poku.js +302 -0
- package/lib/helpers/dosaiParsers.js +103 -0
- package/lib/helpers/plugins.js +17 -16
- package/lib/helpers/protobom.js +53 -0
- package/lib/helpers/protobom.poku.js +44 -1
- package/lib/helpers/protobomLoader.js +43 -0
- package/lib/helpers/protobomLoader.poku.js +31 -0
- package/lib/helpers/utils.js +130 -1
- package/lib/helpers/utils.poku.js +295 -0
- package/lib/server/server.js +2 -1
- package/lib/stages/postgen/annotator.js +2 -1
- package/lib/stages/postgen/annotator.poku.js +28 -0
- package/lib/stages/postgen/postgen.js +219 -12
- package/lib/stages/postgen/postgen.poku.js +163 -0
- package/lib/validator/bomValidator.js +90 -38
- package/lib/validator/bomValidator.poku.js +90 -0
- package/lib/validator/complianceRules.js +4 -2
- package/lib/validator/index.poku.js +14 -0
- package/package.json +12 -12
- package/types/bin/repl.d.ts +1 -1
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/evinser/evinser.d.ts +15 -0
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/helpers/bomUtils.d.ts +8 -0
- package/types/lib/helpers/bomUtils.d.ts.map +1 -1
- package/types/lib/helpers/cbomutils.d.ts +1 -0
- package/types/lib/helpers/cbomutils.d.ts.map +1 -1
- package/types/lib/helpers/ciParsers/githubActions.d.ts.map +1 -1
- package/types/lib/helpers/dosai.d.ts +24 -0
- package/types/lib/helpers/dosai.d.ts.map +1 -0
- package/types/lib/helpers/dosaiParsers.d.ts +8 -0
- package/types/lib/helpers/dosaiParsers.d.ts.map +1 -0
- package/types/lib/helpers/hbomAnalysis.d.ts +14 -0
- package/types/lib/helpers/hbomAnalysis.d.ts.map +1 -1
- package/types/lib/helpers/hostTopology.d.ts.map +1 -1
- package/types/lib/helpers/plugins.d.ts.map +1 -1
- package/types/lib/helpers/protobom.d.ts +2 -0
- package/types/lib/helpers/protobom.d.ts.map +1 -1
- package/types/lib/helpers/protobomLoader.d.ts +17 -0
- package/types/lib/helpers/protobomLoader.d.ts.map +1 -0
- package/types/lib/helpers/utils.d.ts.map +1 -1
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/third-party/arborist/lib/node.d.ts +23 -0
- package/types/lib/third-party/arborist/lib/node.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
- package/types/lib/validator/complianceRules.d.ts.map +1 -1
package/README.md
CHANGED
|
@@ -136,16 +136,18 @@ Installing `@cyclonedx/cdxgen` exposes these commands:
|
|
|
136
136
|
| `cdx-verify` | Verify BOM signatures | yes |
|
|
137
137
|
| `cdxi` | Open the interactive REPL | no |
|
|
138
138
|
| `evinse` | Add evidence, reachability, and service context | no |
|
|
139
|
-
| `cbom` | Alias for CBOM-oriented `cdxgen` defaults |
|
|
140
|
-
| `obom` | Alias for `cdxgen -t os` |
|
|
141
|
-
| `saasbom` | Alias for SaaSBOM-oriented `cdxgen` defaults |
|
|
139
|
+
| `cbom` | Alias for CBOM-oriented `cdxgen` defaults | yes |
|
|
140
|
+
| `obom` | Alias for `cdxgen -t os` | yes |
|
|
141
|
+
| `saasbom` | Alias for SaaSBOM-oriented `cdxgen` defaults | yes |
|
|
142
142
|
| `spdxgen` | Alias for `cdxgen --format spdx` | use `cdxgen` |
|
|
143
143
|
| `cdxgen-secure` | Alias for hardened `cdxgen` defaults | use `cdxgen` |
|
|
144
144
|
|
|
145
|
-
Standalone GitHub release binaries are published for `cdxgen`, `cdxgen-slim`, `hbom`, `hbom-slim`, `cdx-audit`, `cdx-convert`, `cdx-sign`, `cdx-validate`, and `cdx-verify`.
|
|
145
|
+
Standalone GitHub release binaries are published for `cdxgen`, `cdxgen-slim`, `cbom`, `obom`, `saasbom`, `hbom`, `hbom-slim`, `cdx-audit`, `cdx-convert`, `cdx-sign`, `cdx-validate`, and `cdx-verify`.
|
|
146
146
|
|
|
147
147
|
`hbom` release binaries bundle both `@cdxgen/cdx-hbom` and the matching `@cdxgen/cdxgen-plugins-bin*` companion helpers for the target platform. `hbom-slim` keeps the dedicated hardware collector (`@cdxgen/cdx-hbom`) but omits the companion plugin bundle when you want the smallest single-file HBOM executable.
|
|
148
148
|
|
|
149
|
+
The `cbom` and `saasbom` release binaries bundle the Atom analysis stack (`@appthreat/atom` and `@appthreat/atom-parsetools`) plus protobuf export support (`@appthreat/cdx-proto` and `@bufbuild/protobuf`). The `obom` release binary bundles the matching platform plugin package, pruned to runtime OS inventory helpers, plus the same protobuf export support. These aliases therefore support `--export-proto --proto-bin-file <file>` without requiring a separate npm install.
|
|
150
|
+
|
|
149
151
|
`cdx-audit` is designed to accelerate upstream dependency review with explainable, evidence-backed risk prioritization. It complements provenance, reproducibility, and manual investigation rather than replacing them.
|
|
150
152
|
|
|
151
153
|
For host inventories, `hbom --include-runtime` produces a merged HBOM + OBOM view with strict topology links such as interface-name, driver-module, storage/runtime, and explicit secure-boot trust matches, plus a `host-topology` BOM audit pack for higher-confidence host findings. When the live hardware collector reports missing utilities or permission-sensitive enrichments, use `hbom diagnostics` (or inspect the derived `cdx:hbom:analysis:*` summary properties) before deciding whether a rerun with `--privileged` is justified.
|
package/bin/cdxgen.js
CHANGED
|
@@ -20,6 +20,7 @@ import { hideBin } from "yargs/helpers";
|
|
|
20
20
|
|
|
21
21
|
import { createBom, submitBom } from "../lib/cli/index.js";
|
|
22
22
|
import { signBom, verifyBom } from "../lib/helpers/bomSigner.js";
|
|
23
|
+
import { isCycloneDxBom } from "../lib/helpers/bomUtils.js";
|
|
23
24
|
import {
|
|
24
25
|
displaySelfThreatModel,
|
|
25
26
|
printActivitySummary,
|
|
@@ -45,6 +46,7 @@ import {
|
|
|
45
46
|
isHbomOnlyProjectTypes,
|
|
46
47
|
} from "../lib/helpers/hbom.js";
|
|
47
48
|
import { TRACE_MODE, thoughtEnd, thoughtLog } from "../lib/helpers/logger.js";
|
|
49
|
+
import { importProtobomModule } from "../lib/helpers/protobomLoader.js";
|
|
48
50
|
import {
|
|
49
51
|
cleanupSourceDir,
|
|
50
52
|
findGitRefForPurlVersion,
|
|
@@ -129,6 +131,10 @@ for (const configPattern of configPaths) {
|
|
|
129
131
|
}
|
|
130
132
|
|
|
131
133
|
const _yargs = yargs(hideBin(process.argv));
|
|
134
|
+
const invokedCommandName = basename(process.argv[1] || "cdxgen").replace(
|
|
135
|
+
/\.(?:[cm]?js|exe)$/u,
|
|
136
|
+
"",
|
|
137
|
+
);
|
|
132
138
|
|
|
133
139
|
const args = _yargs
|
|
134
140
|
.env("CDXGEN")
|
|
@@ -338,7 +344,7 @@ const args = _yargs
|
|
|
338
344
|
description: "CycloneDX Specification version to use. Defaults to 1.7",
|
|
339
345
|
default: 1.7,
|
|
340
346
|
type: "number",
|
|
341
|
-
choices: [1.4, 1.5, 1.6, 1.7],
|
|
347
|
+
choices: [1.4, 1.5, 1.6, 1.7, 2.0],
|
|
342
348
|
})
|
|
343
349
|
.option("filter", {
|
|
344
350
|
description:
|
|
@@ -586,7 +592,7 @@ const args = _yargs
|
|
|
586
592
|
])
|
|
587
593
|
.epilogue("for documentation, visit https://cdxgen.github.io/cdxgen")
|
|
588
594
|
.config(config)
|
|
589
|
-
.scriptName("cdxgen")
|
|
595
|
+
.scriptName(invokedCommandName || "cdxgen")
|
|
590
596
|
.version(retrieveCdxgenVersion())
|
|
591
597
|
.alias("v", "version")
|
|
592
598
|
.help(false)
|
|
@@ -666,13 +672,13 @@ if (
|
|
|
666
672
|
}
|
|
667
673
|
}
|
|
668
674
|
// Support for obom/cbom aliases
|
|
669
|
-
if (
|
|
670
|
-
args.type = "os";
|
|
675
|
+
if (invokedCommandName.includes("obom") && !args.type) {
|
|
676
|
+
args.type = ["os"];
|
|
671
677
|
thoughtLog(
|
|
672
678
|
"Ok, the user wants to generate an Operations Bill-of-Materials (OBOM).",
|
|
673
679
|
);
|
|
674
680
|
}
|
|
675
|
-
if (
|
|
681
|
+
if (invokedCommandName.includes("spdxgen") && !args.format) {
|
|
676
682
|
args.format = "spdx";
|
|
677
683
|
thoughtLog("Ok, defaulting the export format to SPDX.");
|
|
678
684
|
}
|
|
@@ -732,13 +738,13 @@ if (!options.projectType) {
|
|
|
732
738
|
);
|
|
733
739
|
}
|
|
734
740
|
// Handle dedicated cbom and saasbom commands
|
|
735
|
-
if (["cbom", "saasbom"].includes(
|
|
736
|
-
if (
|
|
741
|
+
if (["cbom", "saasbom"].includes(invokedCommandName)) {
|
|
742
|
+
if (invokedCommandName.includes("cbom")) {
|
|
737
743
|
thoughtLog(
|
|
738
744
|
"Ok, the user wants to generate Cryptographic Bill-of-Materials (CBOM).",
|
|
739
745
|
);
|
|
740
746
|
options.includeCrypto = true;
|
|
741
|
-
} else if (
|
|
747
|
+
} else if (invokedCommandName.includes("saasbom")) {
|
|
742
748
|
thoughtLog(
|
|
743
749
|
"Ok, the user wants to generate a Software as a Service Bill-of-Materials (SaaSBOM). I should carefully collect the services, endpoints, and data flows.",
|
|
744
750
|
);
|
|
@@ -752,7 +758,7 @@ if (["cbom", "saasbom"].includes(process.argv[1])) {
|
|
|
752
758
|
options.specVersion = 1.7;
|
|
753
759
|
options.deep = true;
|
|
754
760
|
}
|
|
755
|
-
if (
|
|
761
|
+
if (invokedCommandName.includes("cdxgen-secure")) {
|
|
756
762
|
thoughtLog(
|
|
757
763
|
"Ok, the user wants cdxgen to run in secure mode by default. Let's try and use the permissions api.",
|
|
758
764
|
);
|
|
@@ -1710,7 +1716,7 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
1710
1716
|
if (
|
|
1711
1717
|
outputPlan.formats.has("spdx") &&
|
|
1712
1718
|
bomNSData?.bomJson &&
|
|
1713
|
-
bomNSData
|
|
1719
|
+
isCycloneDxBom(bomNSData.bomJson)
|
|
1714
1720
|
) {
|
|
1715
1721
|
thoughtLog(
|
|
1716
1722
|
"Preparing the SPDX 3.0.1 export from the validated CycloneDX BOM.",
|
|
@@ -1840,7 +1846,22 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
1840
1846
|
target: options.protoBinFile,
|
|
1841
1847
|
});
|
|
1842
1848
|
} else {
|
|
1843
|
-
const protobomModule = await
|
|
1849
|
+
const protobomModule = await importProtobomModule(
|
|
1850
|
+
invokedCommandName || "cdxgen",
|
|
1851
|
+
"protobuf export",
|
|
1852
|
+
);
|
|
1853
|
+
try {
|
|
1854
|
+
protobomModule.assertProtoSupportedSpecVersion(
|
|
1855
|
+
bomNSData?.bomJson?.specVersion || options.specVersion,
|
|
1856
|
+
"protobuf export",
|
|
1857
|
+
);
|
|
1858
|
+
} catch (error) {
|
|
1859
|
+
console.error(error.message);
|
|
1860
|
+
if (cleanup) {
|
|
1861
|
+
cleanupSourceDir(srcDir);
|
|
1862
|
+
}
|
|
1863
|
+
process.exit(1);
|
|
1864
|
+
}
|
|
1844
1865
|
protobomModule.writeBinary(bomNSData.bomJson, options.protoBinFile);
|
|
1845
1866
|
thoughtLog("BOM file is also available in .proto format!");
|
|
1846
1867
|
}
|
package/bin/convert.js
CHANGED
|
@@ -10,8 +10,13 @@ import { hideBin } from "yargs/helpers";
|
|
|
10
10
|
import {
|
|
11
11
|
getNonCycloneDxErrorMessage,
|
|
12
12
|
isCycloneDxBom,
|
|
13
|
+
toCycloneDxSpecVersionString,
|
|
13
14
|
} from "../lib/helpers/bomUtils.js";
|
|
14
15
|
import { deriveSpdxOutputPath } from "../lib/helpers/exportUtils.js";
|
|
16
|
+
import {
|
|
17
|
+
importProtobomModule,
|
|
18
|
+
isProtoBomPath,
|
|
19
|
+
} from "../lib/helpers/protobomLoader.js";
|
|
15
20
|
import {
|
|
16
21
|
retrieveCdxgenVersion,
|
|
17
22
|
safeExistsSync,
|
|
@@ -56,14 +61,13 @@ const loadCycloneDxBom = async (inputPath) => {
|
|
|
56
61
|
console.error(`Input file '${inputPath}' not found.`);
|
|
57
62
|
process.exit(1);
|
|
58
63
|
}
|
|
59
|
-
const
|
|
60
|
-
const isProtoInput =
|
|
61
|
-
normalizedInputPath.endsWith(".cdx") ||
|
|
62
|
-
normalizedInputPath.endsWith(".cdx.bin") ||
|
|
63
|
-
normalizedInputPath.endsWith(".proto");
|
|
64
|
+
const isProtoInput = isProtoBomPath(inputPath);
|
|
64
65
|
try {
|
|
65
66
|
if (isProtoInput) {
|
|
66
|
-
const { readBinary } = await
|
|
67
|
+
const { readBinary } = await importProtobomModule(
|
|
68
|
+
"cdx-convert",
|
|
69
|
+
"protobuf BOM input",
|
|
70
|
+
);
|
|
67
71
|
return readBinary(inputPath, true);
|
|
68
72
|
}
|
|
69
73
|
return JSON.parse(fs.readFileSync(inputPath, "utf8"));
|
|
@@ -82,8 +86,8 @@ if (!isCycloneDxBom(bomJson)) {
|
|
|
82
86
|
console.error(getNonCycloneDxErrorMessage(bomJson, "cdx-convert"));
|
|
83
87
|
process.exit(1);
|
|
84
88
|
}
|
|
85
|
-
const cdxSpecVersion =
|
|
86
|
-
if (![1.6, 1.7].includes(cdxSpecVersion)) {
|
|
89
|
+
const cdxSpecVersion = toCycloneDxSpecVersionString(bomJson?.specVersion);
|
|
90
|
+
if (!["1.6", "1.7"].includes(cdxSpecVersion)) {
|
|
87
91
|
console.error(
|
|
88
92
|
`Unsupported CycloneDX specVersion '${bomJson?.specVersion}'. cdx-convert currently supports CycloneDX 1.6 or 1.7 input and exports SPDX 3.0.1.`,
|
|
89
93
|
);
|
package/bin/evinse.js
CHANGED
|
@@ -51,15 +51,30 @@ const args = yargs(hideBin(process.argv))
|
|
|
51
51
|
"py",
|
|
52
52
|
"python",
|
|
53
53
|
"android",
|
|
54
|
+
"csharp",
|
|
55
|
+
"cs",
|
|
54
56
|
"c",
|
|
55
57
|
"cpp",
|
|
58
|
+
"dotnet",
|
|
56
59
|
"php",
|
|
57
60
|
"swift",
|
|
58
61
|
"ios",
|
|
59
62
|
"ruby",
|
|
60
63
|
"scala",
|
|
64
|
+
"vb",
|
|
65
|
+
"vbnet",
|
|
66
|
+
"visualbasic",
|
|
67
|
+
"f#",
|
|
68
|
+
"fs",
|
|
69
|
+
"fsharp",
|
|
61
70
|
],
|
|
62
71
|
})
|
|
72
|
+
.option("profile", {
|
|
73
|
+
description:
|
|
74
|
+
"Evidence profile. The research profile enables dosai data-flow and crypto analysis for .NET projects.",
|
|
75
|
+
default: "generic",
|
|
76
|
+
choices: ["generic", "research"],
|
|
77
|
+
})
|
|
63
78
|
.option("db-path", {
|
|
64
79
|
description: "Atom slices DB path. Unused",
|
|
65
80
|
default: undefined,
|
package/bin/hbom.js
CHANGED
|
@@ -16,6 +16,10 @@ import {
|
|
|
16
16
|
} from "../lib/helpers/hbom.js";
|
|
17
17
|
import { getHbomSummary } from "../lib/helpers/hbomAnalysis.js";
|
|
18
18
|
import { thoughtLog } from "../lib/helpers/logger.js";
|
|
19
|
+
import {
|
|
20
|
+
importProtobomModule,
|
|
21
|
+
isProtoBomPath,
|
|
22
|
+
} from "../lib/helpers/protobomLoader.js";
|
|
19
23
|
import {
|
|
20
24
|
DEBUG_MODE,
|
|
21
25
|
isDryRun,
|
|
@@ -317,13 +321,11 @@ async function loadBomFromInputFile(inputFile) {
|
|
|
317
321
|
if (!inputFile || !safeExistsSync(inputFile)) {
|
|
318
322
|
throw new Error(`HBOM input file not found: ${inputFile}`);
|
|
319
323
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
) {
|
|
326
|
-
const { readBinary } = await import("../lib/helpers/protobom.js");
|
|
324
|
+
if (isProtoBomPath(inputFile)) {
|
|
325
|
+
const { readBinary } = await importProtobomModule(
|
|
326
|
+
hbomCommandName,
|
|
327
|
+
"protobuf BOM input",
|
|
328
|
+
);
|
|
327
329
|
return readBinary(inputFile, true);
|
|
328
330
|
}
|
|
329
331
|
return JSON.parse(readFileSync(inputFile, { encoding: "utf8" }));
|
|
@@ -471,7 +473,10 @@ async function runDiagnosticsCommand() {
|
|
|
471
473
|
if (protoOutputDirectory && !safeExistsSync(protoOutputDirectory)) {
|
|
472
474
|
safeMkdirSync(protoOutputDirectory, { recursive: true });
|
|
473
475
|
}
|
|
474
|
-
const { writeBinary } = await
|
|
476
|
+
const { writeBinary } = await importProtobomModule(
|
|
477
|
+
hbomCommandName,
|
|
478
|
+
"protobuf export",
|
|
479
|
+
);
|
|
475
480
|
writeBinary(bomJson, options.protoBinFile);
|
|
476
481
|
thoughtLog(
|
|
477
482
|
`Let's also save the HBOM protobuf binary to '${options.protoBinFile}'.`,
|
package/bin/repl.js
CHANGED
|
@@ -32,7 +32,10 @@ import {
|
|
|
32
32
|
getUnpackagedExecutableComponents,
|
|
33
33
|
getUnpackagedSharedLibraryComponents,
|
|
34
34
|
} from "../lib/helpers/inventoryStats.js";
|
|
35
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
importProtobomModule,
|
|
37
|
+
isProtoBomPath,
|
|
38
|
+
} from "../lib/helpers/protobomLoader.js";
|
|
36
39
|
import {
|
|
37
40
|
getProvenanceComponents,
|
|
38
41
|
getTrustedComponents,
|
|
@@ -360,7 +363,7 @@ if (!process.env.CDXGEN_REPL_HISTORY && !safeExistsSync(historyConfigDir)) {
|
|
|
360
363
|
historyFile = join(historyConfigDir, ".repl_history");
|
|
361
364
|
}
|
|
362
365
|
|
|
363
|
-
export const importSbom = (sbomOrPath) => {
|
|
366
|
+
export const importSbom = async (sbomOrPath) => {
|
|
364
367
|
const importTarget = String(sbomOrPath || "").trim();
|
|
365
368
|
if (!importTarget) {
|
|
366
369
|
console.log("⚠ An SBOM path or image reference is required.");
|
|
@@ -403,10 +406,11 @@ export const importSbom = (sbomOrPath) => {
|
|
|
403
406
|
`⚠ Unable to import the BOM from ${importTarget} due to ${e}`,
|
|
404
407
|
);
|
|
405
408
|
}
|
|
406
|
-
} else if (
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
409
|
+
} else if (isProtoBomPath(importTarget) && safeExistsSync(importTarget)) {
|
|
410
|
+
const { readBinary } = await importProtobomModule(
|
|
411
|
+
"cdxi",
|
|
412
|
+
"protobuf BOM input",
|
|
413
|
+
);
|
|
410
414
|
sbom = readBinary(importTarget, true);
|
|
411
415
|
printSummary(sbom);
|
|
412
416
|
} else if (isSupportedSbomRegistryReference(importTarget)) {
|
|
@@ -430,7 +434,7 @@ export const importSbom = (sbomOrPath) => {
|
|
|
430
434
|
};
|
|
431
435
|
// Load any sbom passed from the command line
|
|
432
436
|
if (process.argv.length > 2) {
|
|
433
|
-
importSbom(process.argv[process.argv.length - 1]);
|
|
437
|
+
await importSbom(process.argv[process.argv.length - 1]);
|
|
434
438
|
console.log("💭 Type .print to view the BOM as a table");
|
|
435
439
|
console.log("💭 Type .trusted to list components with trusted publishing.");
|
|
436
440
|
console.log(
|
|
@@ -448,7 +452,7 @@ if (process.argv.length > 2) {
|
|
|
448
452
|
}
|
|
449
453
|
} else if (safeExistsSync("bom.json")) {
|
|
450
454
|
// If the current directory has a bom.json load it
|
|
451
|
-
importSbom("bom.json");
|
|
455
|
+
await importSbom("bom.json");
|
|
452
456
|
} else {
|
|
453
457
|
console.log("💭 Use .create <path> to create an SBOM for the given path.");
|
|
454
458
|
console.log("💭 Use .import <json> to import an existing BOM.");
|
|
@@ -518,9 +522,9 @@ cdxgenRepl.defineCommand("create", {
|
|
|
518
522
|
});
|
|
519
523
|
cdxgenRepl.defineCommand("import", {
|
|
520
524
|
help: "import an existing BOM",
|
|
521
|
-
action(sbomOrPath) {
|
|
525
|
+
async action(sbomOrPath) {
|
|
522
526
|
this.clearBufferedCommand();
|
|
523
|
-
importSbom(sbomOrPath);
|
|
527
|
+
await importSbom(sbomOrPath);
|
|
524
528
|
this.displayPrompt();
|
|
525
529
|
},
|
|
526
530
|
});
|
package/bin/validate.js
CHANGED
|
@@ -23,6 +23,10 @@ import {
|
|
|
23
23
|
getNonCycloneDxErrorMessage,
|
|
24
24
|
isCycloneDxBom,
|
|
25
25
|
} from "../lib/helpers/bomUtils.js";
|
|
26
|
+
import {
|
|
27
|
+
importProtobomModule,
|
|
28
|
+
isProtoBomPath,
|
|
29
|
+
} from "../lib/helpers/protobomLoader.js";
|
|
26
30
|
import {
|
|
27
31
|
dirNameStr,
|
|
28
32
|
retrieveCdxgenVersion,
|
|
@@ -131,14 +135,12 @@ const args = _yargs
|
|
|
131
135
|
|
|
132
136
|
async function loadBom(input, platform) {
|
|
133
137
|
if (safeExistsSync(input)) {
|
|
134
|
-
const normalizedInput = `${input}`.toLowerCase();
|
|
135
138
|
try {
|
|
136
|
-
if (
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const { readBinary } = await import("../lib/helpers/protobom.js");
|
|
139
|
+
if (isProtoBomPath(input)) {
|
|
140
|
+
const { readBinary } = await importProtobomModule(
|
|
141
|
+
"cdx-validate",
|
|
142
|
+
"protobuf BOM input",
|
|
143
|
+
);
|
|
142
144
|
return readBinary(input, true);
|
|
143
145
|
}
|
|
144
146
|
return JSON.parse(fs.readFileSync(input, "utf8"));
|
|
@@ -193,12 +195,7 @@ function isLocalProtoBomInput(input) {
|
|
|
193
195
|
if (!safeExistsSync(input)) {
|
|
194
196
|
return false;
|
|
195
197
|
}
|
|
196
|
-
|
|
197
|
-
return (
|
|
198
|
-
normalizedInput.endsWith(".cdx") ||
|
|
199
|
-
normalizedInput.endsWith(".cdx.bin") ||
|
|
200
|
-
normalizedInput.endsWith(".proto")
|
|
201
|
-
);
|
|
198
|
+
return isProtoBomPath(input);
|
|
202
199
|
}
|
|
203
200
|
|
|
204
201
|
const bomJson = await loadBom(args.input, args.platform);
|
package/bin/verify.js
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
getNonCycloneDxErrorMessage,
|
|
13
13
|
isCycloneDxBom,
|
|
14
14
|
} from "../lib/helpers/bomUtils.js";
|
|
15
|
+
import { isProtoBomPath } from "../lib/helpers/protobomLoader.js";
|
|
15
16
|
import {
|
|
16
17
|
dirNameStr,
|
|
17
18
|
retrieveCdxgenVersion,
|
|
@@ -78,16 +79,13 @@ if (process.env?.CDXGEN_NODE_OPTIONS) {
|
|
|
78
79
|
|
|
79
80
|
async function getBom(args) {
|
|
80
81
|
if (safeExistsSync(args.input)) {
|
|
81
|
-
|
|
82
|
+
if (isProtoBomPath(args.input)) {
|
|
83
|
+
console.log(
|
|
84
|
+
"cdx-verify: protobuf BOM input does not currently preserve JSF signature blocks. Verify signatures against the source JSON BOM instead.",
|
|
85
|
+
);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
82
88
|
try {
|
|
83
|
-
if (
|
|
84
|
-
normalizedInput.endsWith(".cdx") ||
|
|
85
|
-
normalizedInput.endsWith(".cdx.bin") ||
|
|
86
|
-
normalizedInput.endsWith(".proto")
|
|
87
|
-
) {
|
|
88
|
-
const { readBinary } = await import("../lib/helpers/protobom.js");
|
|
89
|
-
return readBinary(args.input, true);
|
|
90
|
-
}
|
|
91
89
|
return JSON.parse(fs.readFileSync(args.input, "utf8"));
|
|
92
90
|
} catch (error) {
|
|
93
91
|
console.log(`Failed to parse '${args.input}': ${error.message}`);
|
|
@@ -104,20 +102,7 @@ async function getBom(args) {
|
|
|
104
102
|
return undefined;
|
|
105
103
|
}
|
|
106
104
|
|
|
107
|
-
function isLocalProtoBomInput(input) {
|
|
108
|
-
if (!safeExistsSync(input)) {
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
const normalizedInput = `${input}`.toLowerCase();
|
|
112
|
-
return (
|
|
113
|
-
normalizedInput.endsWith(".cdx") ||
|
|
114
|
-
normalizedInput.endsWith(".cdx.bin") ||
|
|
115
|
-
normalizedInput.endsWith(".proto")
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
105
|
const bomJson = await getBom(args);
|
|
120
|
-
const inputIsLocalProtoBom = isLocalProtoBomInput(args.input);
|
|
121
106
|
|
|
122
107
|
if (!bomJson) {
|
|
123
108
|
console.log(`${args.input} is invalid!`);
|
|
@@ -128,13 +113,6 @@ if (!isCycloneDxBom(bomJson)) {
|
|
|
128
113
|
process.exit(1);
|
|
129
114
|
}
|
|
130
115
|
|
|
131
|
-
if (inputIsLocalProtoBom) {
|
|
132
|
-
console.log(
|
|
133
|
-
"cdx-verify: protobuf BOM input does not currently preserve JSF signature blocks. Verify signatures against the source JSON BOM instead.",
|
|
134
|
-
);
|
|
135
|
-
process.exit(1);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
116
|
if (bomJson && !safeExistsSync(args.publicKey)) {
|
|
139
117
|
console.log("Public key for signature verification is missing!");
|
|
140
118
|
process.exit(1);
|