@cyclonedx/cdxgen 12.1.5 → 12.2.1
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 +51 -40
- package/bin/cdxgen.js +194 -97
- package/bin/evinse.js +4 -4
- package/bin/repl.js +1 -1
- package/bin/sign.js +102 -0
- package/bin/validate.js +233 -0
- package/bin/verify.js +69 -28
- package/data/queries.json +1 -1
- package/data/rules/ci-permissions.yaml +186 -0
- package/data/rules/dependency-sources.yaml +123 -0
- package/data/rules/package-integrity.yaml +135 -0
- package/data/rules/vscode-extensions.yaml +228 -0
- package/lib/cli/index.js +449 -429
- package/lib/cli/index.poku.js +117 -0
- package/lib/evinser/db.js +137 -0
- package/lib/{helpers → evinser}/db.poku.js +2 -6
- package/lib/evinser/evinser.js +2 -14
- package/lib/helpers/analyzer.js +606 -3
- package/lib/helpers/analyzer.poku.js +230 -0
- package/lib/helpers/bomSigner.js +312 -0
- package/lib/helpers/bomSigner.poku.js +156 -0
- package/lib/helpers/ciParsers/azurePipelines.js +295 -0
- package/lib/helpers/ciParsers/azurePipelines.poku.js +253 -0
- package/lib/helpers/ciParsers/circleCi.js +286 -0
- package/lib/helpers/ciParsers/circleCi.poku.js +230 -0
- package/lib/helpers/ciParsers/common.js +24 -0
- package/lib/helpers/ciParsers/githubActions.js +636 -0
- package/lib/helpers/ciParsers/githubActions.poku.js +802 -0
- package/lib/helpers/ciParsers/gitlabCi.js +213 -0
- package/lib/helpers/ciParsers/gitlabCi.poku.js +247 -0
- package/lib/helpers/ciParsers/jenkins.js +181 -0
- package/lib/helpers/ciParsers/jenkins.poku.js +197 -0
- package/lib/helpers/depsUtils.js +219 -0
- package/lib/helpers/depsUtils.poku.js +207 -0
- package/lib/helpers/display.js +426 -5
- package/lib/helpers/envcontext.js +18 -3
- package/lib/helpers/formulationParsers.js +351 -0
- package/lib/helpers/logger.js +14 -0
- package/lib/helpers/protobom.js +9 -9
- package/lib/helpers/pythonutils.js +9 -0
- package/lib/helpers/remote/dependency-track.js +84 -0
- package/lib/helpers/remote/dependency-track.poku.js +119 -0
- package/lib/helpers/table.js +384 -0
- package/lib/helpers/table.poku.js +186 -0
- package/lib/helpers/utils.js +865 -416
- package/lib/helpers/utils.poku.js +172 -265
- package/lib/helpers/versutils.js +202 -0
- package/lib/helpers/versutils.poku.js +315 -0
- package/lib/helpers/vsixutils.js +1061 -0
- package/lib/helpers/vsixutils.poku.js +2247 -0
- package/lib/managers/binary.js +19 -19
- package/lib/managers/docker.js +108 -1
- package/lib/managers/oci.js +10 -0
- package/lib/managers/piptree.js +3 -9
- package/lib/parsers/npmrc.js +17 -13
- package/lib/parsers/npmrc.poku.js +41 -5
- package/lib/server/openapi.yaml +34 -1
- package/lib/server/server.js +50 -13
- package/lib/server/server.poku.js +332 -144
- package/lib/stages/postgen/annotator.js +1 -1
- package/lib/stages/postgen/auditBom.js +196 -0
- package/lib/stages/postgen/auditBom.poku.js +378 -0
- package/lib/stages/postgen/postgen.js +54 -1
- package/lib/stages/postgen/postgen.poku.js +90 -1
- package/lib/stages/postgen/ruleEngine.js +369 -0
- package/lib/stages/pregen/envAudit.js +299 -0
- package/lib/stages/pregen/envAudit.poku.js +572 -0
- package/lib/stages/pregen/pregen.js +12 -8
- package/lib/{helpers/validator.js → validator/bomValidator.js} +107 -47
- package/lib/validator/complianceEngine.js +241 -0
- package/lib/validator/complianceEngine.poku.js +168 -0
- package/lib/validator/complianceRules.js +1610 -0
- package/lib/validator/complianceRules.poku.js +328 -0
- package/lib/validator/index.js +222 -0
- package/lib/validator/index.poku.js +144 -0
- package/lib/validator/reporters/annotations.js +121 -0
- package/lib/validator/reporters/console.js +149 -0
- package/lib/validator/reporters/index.js +41 -0
- package/lib/validator/reporters/json.js +37 -0
- package/lib/validator/reporters/sarif.js +184 -0
- package/lib/validator/reporters.poku.js +150 -0
- package/package.json +8 -9
- package/types/bin/sign.d.ts +3 -0
- package/types/bin/sign.d.ts.map +1 -0
- package/types/bin/validate.d.ts +3 -0
- package/types/bin/validate.d.ts.map +1 -0
- package/types/helpers/utils.d.ts +0 -1
- package/types/lib/cli/index.d.ts +49 -52
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/evinser/db.d.ts +34 -0
- package/types/lib/evinser/db.d.ts.map +1 -0
- package/types/lib/evinser/evinser.d.ts +63 -16
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/helpers/analyzer.d.ts.map +1 -1
- package/types/lib/helpers/bomSigner.d.ts +27 -0
- package/types/lib/helpers/bomSigner.d.ts.map +1 -0
- package/types/lib/helpers/ciParsers/azurePipelines.d.ts +17 -0
- package/types/lib/helpers/ciParsers/azurePipelines.d.ts.map +1 -0
- package/types/lib/helpers/ciParsers/circleCi.d.ts +17 -0
- package/types/lib/helpers/ciParsers/circleCi.d.ts.map +1 -0
- package/types/lib/helpers/ciParsers/common.d.ts +11 -0
- package/types/lib/helpers/ciParsers/common.d.ts.map +1 -0
- package/types/lib/helpers/ciParsers/githubActions.d.ts +34 -0
- package/types/lib/helpers/ciParsers/githubActions.d.ts.map +1 -0
- package/types/lib/helpers/ciParsers/gitlabCi.d.ts +17 -0
- package/types/lib/helpers/ciParsers/gitlabCi.d.ts.map +1 -0
- package/types/lib/helpers/ciParsers/jenkins.d.ts +17 -0
- package/types/lib/helpers/ciParsers/jenkins.d.ts.map +1 -0
- package/types/lib/helpers/depsUtils.d.ts +21 -0
- package/types/lib/helpers/depsUtils.d.ts.map +1 -0
- package/types/lib/helpers/display.d.ts +111 -11
- package/types/lib/helpers/display.d.ts.map +1 -1
- package/types/lib/helpers/envcontext.d.ts +19 -7
- package/types/lib/helpers/envcontext.d.ts.map +1 -1
- package/types/lib/helpers/formulationParsers.d.ts +50 -0
- package/types/lib/helpers/formulationParsers.d.ts.map +1 -0
- package/types/lib/helpers/logger.d.ts +15 -1
- package/types/lib/helpers/logger.d.ts.map +1 -1
- package/types/lib/helpers/protobom.d.ts +2 -2
- package/types/lib/helpers/pythonutils.d.ts +10 -1
- package/types/lib/helpers/pythonutils.d.ts.map +1 -1
- package/types/lib/helpers/remote/dependency-track.d.ts +16 -0
- package/types/lib/helpers/remote/dependency-track.d.ts.map +1 -0
- package/types/lib/helpers/table.d.ts +6 -0
- package/types/lib/helpers/table.d.ts.map +1 -0
- package/types/lib/helpers/utils.d.ts +533 -128
- package/types/lib/helpers/utils.d.ts.map +1 -1
- package/types/lib/helpers/versutils.d.ts +8 -0
- package/types/lib/helpers/versutils.d.ts.map +1 -0
- package/types/lib/helpers/vsixutils.d.ts +130 -0
- package/types/lib/helpers/vsixutils.d.ts.map +1 -0
- package/types/lib/managers/docker.d.ts +12 -31
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/managers/oci.d.ts +11 -1
- package/types/lib/managers/oci.d.ts.map +1 -1
- package/types/lib/managers/piptree.d.ts.map +1 -1
- package/types/lib/parsers/npmrc.d.ts +4 -1
- package/types/lib/parsers/npmrc.d.ts.map +1 -1
- package/types/lib/server/server.d.ts +22 -2
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/auditBom.d.ts +20 -0
- package/types/lib/stages/postgen/auditBom.d.ts.map +1 -0
- package/types/lib/stages/postgen/postgen.d.ts +8 -1
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts +18 -0
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -0
- package/types/lib/stages/pregen/envAudit.d.ts +8 -0
- package/types/lib/stages/pregen/envAudit.d.ts.map +1 -0
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/{helpers/validator.d.ts → validator/bomValidator.d.ts} +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -0
- package/types/lib/validator/complianceEngine.d.ts +66 -0
- package/types/lib/validator/complianceEngine.d.ts.map +1 -0
- package/types/lib/validator/complianceRules.d.ts +70 -0
- package/types/lib/validator/complianceRules.d.ts.map +1 -0
- package/types/lib/validator/index.d.ts +70 -0
- package/types/lib/validator/index.d.ts.map +1 -0
- package/types/lib/validator/reporters/annotations.d.ts +31 -0
- package/types/lib/validator/reporters/annotations.d.ts.map +1 -0
- package/types/lib/validator/reporters/console.d.ts +30 -0
- package/types/lib/validator/reporters/console.d.ts.map +1 -0
- package/types/lib/validator/reporters/index.d.ts +21 -0
- package/types/lib/validator/reporters/index.d.ts.map +1 -0
- package/types/lib/validator/reporters/json.d.ts +11 -0
- package/types/lib/validator/reporters/json.d.ts.map +1 -0
- package/types/lib/validator/reporters/sarif.d.ts +16 -0
- package/types/lib/validator/reporters/sarif.d.ts.map +1 -0
- package/lib/helpers/db.js +0 -162
- package/lib/stages/pregen/env-audit.js +0 -34
- package/lib/stages/pregen/env-audit.poku.js +0 -290
- package/types/helpers/db.d.ts +0 -35
- package/types/helpers/db.d.ts.map +0 -1
- package/types/lib/helpers/db.d.ts +0 -35
- package/types/lib/helpers/db.d.ts.map +0 -1
- package/types/lib/helpers/validator.d.ts.map +0 -1
- package/types/lib/stages/pregen/env-audit.d.ts +0 -2
- package/types/lib/stages/pregen/env-audit.d.ts.map +0 -1
- package/types/managers/binary.d.ts +0 -37
- package/types/managers/binary.d.ts.map +0 -1
- package/types/managers/docker.d.ts +0 -56
- package/types/managers/docker.d.ts.map +0 -1
- package/types/managers/oci.d.ts +0 -2
- package/types/managers/oci.d.ts.map +0 -1
- package/types/managers/piptree.d.ts +0 -2
- package/types/managers/piptree.d.ts.map +0 -1
- package/types/server/server.d.ts +0 -34
- package/types/server/server.d.ts.map +0 -1
- package/types/stages/postgen/annotator.d.ts +0 -27
- package/types/stages/postgen/annotator.d.ts.map +0 -1
- package/types/stages/postgen/postgen.d.ts +0 -51
- package/types/stages/postgen/postgen.d.ts.map +0 -1
- package/types/stages/pregen/pregen.d.ts +0 -59
- package/types/stages/pregen/pregen.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
[](https://github.com/cdxgen/cdxgen)
|
|
2
|
+
[](./AI-DECLARATION.md)
|
|
2
3
|
[![JSR][badge-jsr]][jsr-cdxgen]
|
|
3
4
|
[![NPM][badge-npm]][npmjs-cdxgen]
|
|
4
5
|
[![GitHub Releases][badge-github-releases]][github-releases]
|
|
@@ -11,7 +12,7 @@
|
|
|
11
12
|
|
|
12
13
|
<img src="./docs/_media/cdxgen.png" width="200" height="auto" />
|
|
13
14
|
|
|
14
|
-
cdxgen is a CLI tool, library, [REPL](./ADVANCED.md), and server to create
|
|
15
|
+
cdxgen is a CLI tool, library, [REPL](./ADVANCED.md), and server to create, validate, sign, and verify [CycloneDX][cyclonedx-homepage] Bill of Materials (BOM) containing an aggregate of all project dependencies in JSON format. CycloneDX is a full-stack BOM specification that is easily created, human and machine-readable, and simple to parse. The tool supports CycloneDX specification versions from 1.5 - 1.7.
|
|
15
16
|
|
|
16
17
|
Supported BOM formats:
|
|
17
18
|
|
|
@@ -31,8 +32,8 @@ Most SBOM tools are like simple barcode scanners. For easy applications, they ca
|
|
|
31
32
|
- _Explainability:_ Don't list, but explain with evidence.
|
|
32
33
|
- _Precision:_ Try using multiple techniques to improve precision, even if it takes extra time.
|
|
33
34
|
- _Personas:_ Cater to the needs of a range of personas such as security researchers, compliance auditors, developers, and SOC.
|
|
34
|
-
- _Lifecycle:_ Support BOM generation for various product lifecycles.
|
|
35
35
|
- _Machine Learning:_ Optimize the generated data for Machine Learning (ML) purposes by considering the various model properties.
|
|
36
|
+
- _Safety:_ Execute external build tools and handle untrusted inputs defensively, with hardened defaults and a [secure mode](docs/PERMISSIONS.md) for sensitive environments.
|
|
36
37
|
|
|
37
38
|
## Documentation
|
|
38
39
|
|
|
@@ -47,6 +48,8 @@ Sections include:
|
|
|
47
48
|
- [Environment Variables][docs-env-vars]
|
|
48
49
|
- [Advanced Usage][docs-advanced-usage]
|
|
49
50
|
- [Permissions][docs-permissions]
|
|
51
|
+
- [Security Policy](SECURITY.md)
|
|
52
|
+
- [Threat Model](docs/THREAT_MODEL.md)
|
|
50
53
|
- [Support (Enterprise & Community)][docs-support]
|
|
51
54
|
|
|
52
55
|
## Usage
|
|
@@ -104,7 +107,7 @@ docker run --rm -e CDXGEN_DEBUG_MODE=debug -v /tmp:/tmp -v $(pwd):/app:rw -t ghc
|
|
|
104
107
|
In deno applications, cdxgen could be directly imported without any conversion. Please see the section on [integration as a library](#integration-as-library)
|
|
105
108
|
|
|
106
109
|
```ts
|
|
107
|
-
import { createBom, submitBom } from "npm:@cyclonedx/cdxgen@^12.1
|
|
110
|
+
import { createBom, submitBom } from "npm:@cyclonedx/cdxgen@^12.2.1";
|
|
108
111
|
```
|
|
109
112
|
|
|
110
113
|
## Getting Help
|
|
@@ -136,7 +139,10 @@ Options:
|
|
|
136
139
|
--project-tag Dependency track project tag. Multiple values allowed. [array]
|
|
137
140
|
--project-id Dependency track project id. Either provide the id or the project name and version tog
|
|
138
141
|
ether [string]
|
|
139
|
-
--parent-project-id Dependency track parent project id
|
|
142
|
+
--parent-project-id Dependency track parent project id. You must provide the id or both
|
|
143
|
+
parent project name and parent project version. [string]
|
|
144
|
+
--parent-project-name Dependency track parent project name [string]
|
|
145
|
+
--parent-project-version Dependency track parent project version [string]
|
|
140
146
|
--required-only Include only the packages with required scope on the SBOM. Would set compositions.aggr
|
|
141
147
|
egate to incomplete unless --no-auto-compositions is passed. [boolean]
|
|
142
148
|
--fail-on-error Fail if any dependency extractor fails. [boolean]
|
|
@@ -153,8 +159,8 @@ Options:
|
|
|
153
159
|
--validate Validate the generated SBOM using json schema. Defaults to true. Pass --no-validate to
|
|
154
160
|
disable. [boolean] [default: true]
|
|
155
161
|
--evidence Generate SBOM with evidence for supported languages. [boolean] [default: false]
|
|
156
|
-
--spec-version CycloneDX Specification version to use. Defaults to 1.
|
|
157
|
-
[number] [choices: 1.4, 1.5, 1.6, 1.7] [default: 1.
|
|
162
|
+
--spec-version CycloneDX Specification version to use. Defaults to 1.7
|
|
163
|
+
[number] [choices: 1.4, 1.5, 1.6, 1.7] [default: 1.7]
|
|
158
164
|
--filter Filter components containing this word in purl or component.properties.value. Multiple
|
|
159
165
|
values allowed. [array]
|
|
160
166
|
--only Include components only containing this word in purl. Useful to generate BOM with firs
|
|
@@ -217,11 +223,11 @@ To recursively generate a single BOM for all languages pass `-r` argument.
|
|
|
217
223
|
cdxgen -r -o bom.json
|
|
218
224
|
```
|
|
219
225
|
|
|
220
|
-
The default specification used by cdxgen is 1.
|
|
226
|
+
The default specification used by cdxgen is 1.7. To generate BOM for a different specification version, such as 1.5 or 1.6, pass the version number using the `--spec-version` argument.
|
|
221
227
|
|
|
222
228
|
```shell
|
|
223
|
-
# 1.
|
|
224
|
-
cdxgen -r -o bom.json --spec-version 1.
|
|
229
|
+
# 1.6 is supported by most tools
|
|
230
|
+
cdxgen -r -o bom.json --spec-version 1.6
|
|
225
231
|
```
|
|
226
232
|
|
|
227
233
|
To generate SBOM for C or Python, ensure Java >= 21 is installed.
|
|
@@ -418,60 +424,65 @@ cbom -t java
|
|
|
418
424
|
|
|
419
425
|
See [evinse mode](./ADVANCED.md) in the advanced documentation.
|
|
420
426
|
|
|
427
|
+
---
|
|
428
|
+
|
|
421
429
|
## BOM signing
|
|
422
430
|
|
|
423
|
-
cdxgen
|
|
431
|
+
cdxgen features a best-in-class, native **JSON Signature Format (JSF)** implementation for BOM signing, providing robust authenticity and non-repudiation capabilities. Unlike basic signing tools, our implementation fully supports granular signatures (signing individual components, services, and annotations), parallel Multi-Signatures (`signers`), and sequential Signature Chains (`chain`).
|
|
432
|
+
|
|
433
|
+
To enable automatic signing during BOM generation, set the following environment variables:
|
|
434
|
+
|
|
435
|
+
- `SBOM_SIGN_ALGORITHM`: JSF Algorithm. Examples: `RS512`, `ES256`, `Ed25519`, `HS256`
|
|
436
|
+
- `SBOM_SIGN_PRIVATE_KEY`: Location of the private key (PEM format)
|
|
437
|
+
- `SBOM_SIGN_PUBLIC_KEY`: Optional. Location of the public key
|
|
438
|
+
- `SBOM_SIGN_MODE`: Optional. Signature mode (`replace`, `signers`, `chain`). Default is `replace`.
|
|
439
|
+
|
|
440
|
+
To quickly generate test public/private key pairs and sign your first BOM, you can run cdxgen with the `--generate-key-and-sign` argument.
|
|
424
441
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
-
|
|
442
|
+
### Advanced Signing with `cdx-sign`
|
|
443
|
+
|
|
444
|
+
For complex supply chain orchestration, use the bundled `cdx-sign` CLI. This tool allows multiple entities (e.g., a Builder and an Auditor) to co-sign an existing BOM without modifying its original data.
|
|
445
|
+
|
|
446
|
+
```shell
|
|
447
|
+
# Append a parallel multi-signature (Auditor co-signing)
|
|
448
|
+
# Note: Granular component signing is disabled to preserve the Builder's original signature payload.
|
|
449
|
+
cdx-sign -i bom.json -k auditor_private.pem -a ES256 --key-id "auditor-qa" --mode signers --no-sign-components
|
|
450
|
+
```
|
|
428
451
|
|
|
429
|
-
|
|
452
|
+
### Validating CycloneDX BOMs
|
|
430
453
|
|
|
431
|
-
|
|
454
|
+
Use the bundled `cdx-validate` command to validate CycloneDX BOMs against **structural**, **deep**, and **compliance** checks. Refer to this [document](./docs/CDX_VALIDATE.md) for usage.
|
|
432
455
|
|
|
433
456
|
### Verifying the signature
|
|
434
457
|
|
|
435
|
-
Use the bundled `cdx-verify` command,
|
|
458
|
+
Use the bundled `cdx-verify` command to validate BOM signatures. By default, `cdx-verify` performs a **strict deep verification**, meaning it mathematically validates the top-level BOM signature _and_ the signatures of every nested component, service, and annotation against the provided public key. Refer to this [lesson](./docs/LESSON6.md) for the usage of sign and verify commands.
|
|
436
459
|
|
|
437
460
|
```shell
|
|
438
461
|
npm install -g @cyclonedx/cdxgen
|
|
462
|
+
|
|
463
|
+
# Perform strict deep verification (default)
|
|
439
464
|
cdx-verify -i bom.json --public-key public.key
|
|
465
|
+
|
|
466
|
+
# Verify ONLY the top-level root signature (useful for verifying a multi-signer who didn't sign nested components)
|
|
467
|
+
cdx-verify -i bom.json --public-key auditor_public.key --no-deep
|
|
440
468
|
```
|
|
441
469
|
|
|
442
470
|
### Verifying the signature (pnpm)
|
|
443
471
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
You can run it directly using pnpm (no global install needed):
|
|
472
|
+
You can run the verification tools directly using pnpm (no global install needed):
|
|
447
473
|
|
|
448
474
|
```shell
|
|
449
475
|
pnpm dlx @cyclonedx/cdxgen cdx-verify -i bom.json --public-key public.key
|
|
450
476
|
```
|
|
451
477
|
|
|
452
|
-
|
|
478
|
+
You can also use pnpm to invoke the signing tool:
|
|
453
479
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
```js
|
|
457
|
-
# npm install jws
|
|
458
|
-
const jws = require("jws");
|
|
459
|
-
const fs = require("fs");
|
|
460
|
-
// Location of the SBOM json file
|
|
461
|
-
const bomJsonFile = "bom.json";
|
|
462
|
-
// Location of the public key
|
|
463
|
-
const publicKeyFile = "public.key";
|
|
464
|
-
const bomJson = JSON.parse(fs.readFileSync(bomJsonFile, "utf8"));
|
|
465
|
-
// Retrieve the signature
|
|
466
|
-
const bomSignature = bomJson.signature.value;
|
|
467
|
-
const validationResult = jws.verify(bomSignature, bomJson.signature.algorithm, fs.readFileSync(publicKeyFile, "utf8"));
|
|
468
|
-
if (validationResult) {
|
|
469
|
-
console.log("Signature is valid!");
|
|
470
|
-
} else {
|
|
471
|
-
console.log("SBOM signature is invalid :(");
|
|
472
|
-
}
|
|
480
|
+
```shell
|
|
481
|
+
pnpm dlx @cyclonedx/cdxgen cdx-sign -i bom.json -k private.key
|
|
473
482
|
```
|
|
474
483
|
|
|
484
|
+
---
|
|
485
|
+
|
|
475
486
|
## Automatic usage detection
|
|
476
487
|
|
|
477
488
|
For node.js projects, lock files are parsed initially, so the SBOM would include all dependencies, including dev ones. An AST parser powered by babel-parser is then used to detect packages that are imported and used by non-test code. Such imported packages would automatically set their scope property to `required` in the resulting SBOM. You can turn off this analysis by passing the argument `--no-babel`. Scope property would then be set based on the `dev` attribute in the lock file.
|
|
@@ -568,7 +579,7 @@ Use `pnpm add -g` command to quickly test the main branch.
|
|
|
568
579
|
```shell
|
|
569
580
|
corepack pnpm bin -g
|
|
570
581
|
corepack pnpm setup
|
|
571
|
-
corepack pnpm add -g
|
|
582
|
+
corepack pnpm add -g https://github.com/cdxgen/cdxgen
|
|
572
583
|
cdxgen --help
|
|
573
584
|
```
|
|
574
585
|
|
package/bin/cdxgen.js
CHANGED
|
@@ -7,13 +7,14 @@ import https from "node:https";
|
|
|
7
7
|
import { basename, dirname, join, resolve } from "node:path";
|
|
8
8
|
import process from "node:process";
|
|
9
9
|
|
|
10
|
-
import jws from "jws";
|
|
11
10
|
import { parse as _load } from "yaml";
|
|
12
11
|
import yargs from "yargs";
|
|
13
12
|
import { hideBin } from "yargs/helpers";
|
|
14
13
|
|
|
15
14
|
import { createBom, submitBom } from "../lib/cli/index.js";
|
|
15
|
+
import { signBom, verifyBom } from "../lib/helpers/bomSigner.js";
|
|
16
16
|
import {
|
|
17
|
+
displaySelfThreatModel,
|
|
17
18
|
printCallStack,
|
|
18
19
|
printDependencyTree,
|
|
19
20
|
printFormulation,
|
|
@@ -26,7 +27,6 @@ import {
|
|
|
26
27
|
} from "../lib/helpers/display.js";
|
|
27
28
|
import { TRACE_MODE, thoughtEnd, thoughtLog } from "../lib/helpers/logger.js";
|
|
28
29
|
import {
|
|
29
|
-
ATOM_DB,
|
|
30
30
|
commandsExecuted,
|
|
31
31
|
DEBUG_MODE,
|
|
32
32
|
getTmpDir,
|
|
@@ -39,11 +39,12 @@ import {
|
|
|
39
39
|
remoteHostsAccessed,
|
|
40
40
|
retrieveCdxgenVersion,
|
|
41
41
|
safeExistsSync,
|
|
42
|
+
toCamel,
|
|
42
43
|
} from "../lib/helpers/utils.js";
|
|
43
|
-
import { validateBom } from "../lib/helpers/validator.js";
|
|
44
44
|
import { postProcess } from "../lib/stages/postgen/postgen.js";
|
|
45
|
-
import { auditEnvironment } from "../lib/stages/pregen/
|
|
45
|
+
import { auditEnvironment } from "../lib/stages/pregen/envAudit.js";
|
|
46
46
|
import { prepareEnv } from "../lib/stages/pregen/pregen.js";
|
|
47
|
+
import { validateBom } from "../lib/validator/bomValidator.js";
|
|
47
48
|
|
|
48
49
|
// Support for config files
|
|
49
50
|
const configPaths = [
|
|
@@ -64,6 +65,18 @@ for (const configPattern of configPaths) {
|
|
|
64
65
|
} else {
|
|
65
66
|
config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
66
67
|
}
|
|
68
|
+
if (isSecureMode || DEBUG_MODE) {
|
|
69
|
+
console.log(`Config file '${configPath}' loaded successfully.`);
|
|
70
|
+
}
|
|
71
|
+
const sensitiveOptions = ["server-url", "include-formulation"];
|
|
72
|
+
for (const opt of sensitiveOptions) {
|
|
73
|
+
if (config[opt] !== undefined || config[toCamel(opt)] !== undefined) {
|
|
74
|
+
const foundKey = config[opt] !== undefined ? opt : toCamel(opt);
|
|
75
|
+
console.warn(
|
|
76
|
+
`SECURE MODE: Config file sets '${foundKey}'. Verify this is intentional.`,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
67
80
|
} catch (_e) {
|
|
68
81
|
console.log("Invalid config file", configPath);
|
|
69
82
|
}
|
|
@@ -76,6 +89,9 @@ const args = _yargs
|
|
|
76
89
|
.parserConfiguration({
|
|
77
90
|
"greedy-arrays": false,
|
|
78
91
|
"short-option-groups": false,
|
|
92
|
+
"dot-notation": false,
|
|
93
|
+
"parse-numbers": true,
|
|
94
|
+
"boolean-negation": true,
|
|
79
95
|
})
|
|
80
96
|
.option("output", {
|
|
81
97
|
alias: "o",
|
|
@@ -120,6 +136,7 @@ const args = _yargs
|
|
|
120
136
|
})
|
|
121
137
|
.option("server-url", {
|
|
122
138
|
description: "Dependency track url. Eg: https://deptrack.cyclonedx.io",
|
|
139
|
+
type: "string",
|
|
123
140
|
})
|
|
124
141
|
.option("skip-dt-tls-check", {
|
|
125
142
|
type: "boolean",
|
|
@@ -128,6 +145,7 @@ const args = _yargs
|
|
|
128
145
|
})
|
|
129
146
|
.option("api-key", {
|
|
130
147
|
description: "Dependency track api key",
|
|
148
|
+
type: "string",
|
|
131
149
|
})
|
|
132
150
|
.option("project-group", {
|
|
133
151
|
description: "Dependency track project group",
|
|
@@ -153,6 +171,24 @@ const args = _yargs
|
|
|
153
171
|
description: "Dependency track parent project id",
|
|
154
172
|
type: "string",
|
|
155
173
|
})
|
|
174
|
+
.option("parent-project-name", {
|
|
175
|
+
description: "Dependency track parent project name",
|
|
176
|
+
type: "string",
|
|
177
|
+
})
|
|
178
|
+
.option("parent-project-version", {
|
|
179
|
+
description: "Dependency track parent project version",
|
|
180
|
+
type: "string",
|
|
181
|
+
})
|
|
182
|
+
.option("auto-create", {
|
|
183
|
+
description: "Dependency track autoCreate value for BOM uploads",
|
|
184
|
+
type: "boolean",
|
|
185
|
+
hidden: true,
|
|
186
|
+
})
|
|
187
|
+
.option("is-latest", {
|
|
188
|
+
description: "Dependency track isLatest value for BOM uploads",
|
|
189
|
+
type: "boolean",
|
|
190
|
+
hidden: true,
|
|
191
|
+
})
|
|
156
192
|
.option("required-only", {
|
|
157
193
|
type: "boolean",
|
|
158
194
|
description:
|
|
@@ -180,10 +216,12 @@ const args = _yargs
|
|
|
180
216
|
.option("server-host", {
|
|
181
217
|
description: "Listen address",
|
|
182
218
|
default: "127.0.0.1",
|
|
219
|
+
type: "string",
|
|
183
220
|
})
|
|
184
221
|
.option("server-port", {
|
|
185
222
|
description: "Listen port",
|
|
186
|
-
default:
|
|
223
|
+
default: 9090,
|
|
224
|
+
type: "number",
|
|
187
225
|
})
|
|
188
226
|
.option("install-deps", {
|
|
189
227
|
type: "boolean",
|
|
@@ -229,8 +267,8 @@ const args = _yargs
|
|
|
229
267
|
hidden: true,
|
|
230
268
|
})
|
|
231
269
|
.option("spec-version", {
|
|
232
|
-
description: "CycloneDX Specification version to use. Defaults to 1.
|
|
233
|
-
default: 1.
|
|
270
|
+
description: "CycloneDX Specification version to use. Defaults to 1.7",
|
|
271
|
+
default: 1.7,
|
|
234
272
|
type: "number",
|
|
235
273
|
choices: [1.4, 1.5, 1.6, 1.7],
|
|
236
274
|
})
|
|
@@ -355,6 +393,46 @@ const args = _yargs
|
|
|
355
393
|
default: "CLEAR",
|
|
356
394
|
hidden: true,
|
|
357
395
|
})
|
|
396
|
+
.option("env-audit", {
|
|
397
|
+
type: "boolean",
|
|
398
|
+
description:
|
|
399
|
+
"Display a pre-generation environment and configuration security assessment",
|
|
400
|
+
default: false,
|
|
401
|
+
hidden: true,
|
|
402
|
+
})
|
|
403
|
+
.option("bom-audit", {
|
|
404
|
+
type: "boolean",
|
|
405
|
+
description: "Perform post-generation security audit of BOM data",
|
|
406
|
+
default: false,
|
|
407
|
+
hidden: true,
|
|
408
|
+
})
|
|
409
|
+
.option("bom-audit-rules-dir", {
|
|
410
|
+
description:
|
|
411
|
+
"Directory containing additional YAML audit rules (merged with built-in)",
|
|
412
|
+
type: "string",
|
|
413
|
+
hidden: true,
|
|
414
|
+
})
|
|
415
|
+
.option("bom-audit-categories", {
|
|
416
|
+
description:
|
|
417
|
+
"Comma-separated list of rule categories to enable (default: all)",
|
|
418
|
+
type: "string",
|
|
419
|
+
hidden: true,
|
|
420
|
+
})
|
|
421
|
+
.option("bom-audit-min-severity", {
|
|
422
|
+
description:
|
|
423
|
+
"Minimum severity to report: low, medium, or high (default: low)",
|
|
424
|
+
type: "string",
|
|
425
|
+
choices: ["low", "medium", "high"],
|
|
426
|
+
default: "low",
|
|
427
|
+
hidden: true,
|
|
428
|
+
})
|
|
429
|
+
.option("bom-audit-fail-severity", {
|
|
430
|
+
description: "Severity threshold for secure mode failure (default: high)",
|
|
431
|
+
type: "string",
|
|
432
|
+
choices: ["high", "medium", "low"],
|
|
433
|
+
default: "high",
|
|
434
|
+
hidden: true,
|
|
435
|
+
})
|
|
358
436
|
.completion("completion", "Generate bash/zsh completion")
|
|
359
437
|
.array("type")
|
|
360
438
|
.array("excludeType")
|
|
@@ -520,7 +598,7 @@ if (["cbom", "saasbom"].includes(process.argv[1])) {
|
|
|
520
598
|
}
|
|
521
599
|
}
|
|
522
600
|
options.evidence = true;
|
|
523
|
-
options.specVersion = 1.
|
|
601
|
+
options.specVersion = 1.7;
|
|
524
602
|
options.deep = true;
|
|
525
603
|
}
|
|
526
604
|
if (process.argv[1].includes("cdxgen-secure")) {
|
|
@@ -534,16 +612,29 @@ if (process.argv[1].includes("cdxgen-secure")) {
|
|
|
534
612
|
process.env.CDXGEN_SECURE_MODE = true;
|
|
535
613
|
}
|
|
536
614
|
if (options.standard) {
|
|
537
|
-
options.specVersion = 1.
|
|
615
|
+
options.specVersion = 1.7;
|
|
538
616
|
}
|
|
539
617
|
if (options.includeFormulation) {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
618
|
+
if (options.serverUrl) {
|
|
619
|
+
thoughtLog(
|
|
620
|
+
"Wait, the user specified a server URL and wants to include formulation data. Let's warn about accidentally disclosing sensitive data to a remote server.",
|
|
621
|
+
);
|
|
622
|
+
console.warn(
|
|
623
|
+
`\x1b[1;35mWARNING: The formulation section may include sensitive data such as emails and secrets. This data will be submitted to '${options.serverUrl}' automatically.\x1b[0m`,
|
|
624
|
+
);
|
|
625
|
+
if (isSecureMode) {
|
|
626
|
+
process.exit(1);
|
|
627
|
+
}
|
|
628
|
+
} else {
|
|
629
|
+
thoughtLog(
|
|
630
|
+
"Wait, the user wants to include formulation data. Let's warn about accidentally disclosing sensitive data via the generated BOM.",
|
|
631
|
+
);
|
|
632
|
+
console.log(
|
|
633
|
+
"NOTE: The formulation section may include sensitive data such as emails and secrets.\nPlease review the generated SBOM before distribution or LLM training.\n",
|
|
634
|
+
);
|
|
635
|
+
}
|
|
546
636
|
}
|
|
637
|
+
|
|
547
638
|
/**
|
|
548
639
|
* Method to apply advanced options such as profile and lifecycles
|
|
549
640
|
*
|
|
@@ -560,11 +651,13 @@ const applyAdvancedOptions = (options) => {
|
|
|
560
651
|
switch (options.profile) {
|
|
561
652
|
case "appsec":
|
|
562
653
|
options.deep = true;
|
|
654
|
+
options.bomAudit = true;
|
|
563
655
|
break;
|
|
564
656
|
case "research":
|
|
565
657
|
options.deep = true;
|
|
566
658
|
options.evidence = true;
|
|
567
659
|
options.includeCrypto = true;
|
|
660
|
+
options.bomAudit = true;
|
|
568
661
|
process.env.CDX_MAVEN_INCLUDE_TEST_SCOPE = "true";
|
|
569
662
|
process.env.ASTGEN_IGNORE_DIRS = "";
|
|
570
663
|
process.env.ASTGEN_IGNORE_FILE_PATTERN = "";
|
|
@@ -575,10 +668,12 @@ const applyAdvancedOptions = (options) => {
|
|
|
575
668
|
} else {
|
|
576
669
|
options.projectType = ["os"];
|
|
577
670
|
}
|
|
671
|
+
options.bomAudit = true;
|
|
578
672
|
break;
|
|
579
673
|
case "threat-modeling":
|
|
580
674
|
options.deep = true;
|
|
581
675
|
options.evidence = true;
|
|
676
|
+
options.bomAudit = true;
|
|
582
677
|
break;
|
|
583
678
|
case "license-compliance":
|
|
584
679
|
process.env.FETCH_LICENSE = "true";
|
|
@@ -589,6 +684,7 @@ const applyAdvancedOptions = (options) => {
|
|
|
589
684
|
options.evidence = false;
|
|
590
685
|
options.includeCrypto = false;
|
|
591
686
|
options.installDeps = false;
|
|
687
|
+
options.bomAudit = false;
|
|
592
688
|
break;
|
|
593
689
|
case "machine-learning":
|
|
594
690
|
case "ml":
|
|
@@ -605,6 +701,7 @@ const applyAdvancedOptions = (options) => {
|
|
|
605
701
|
options.evidence = true;
|
|
606
702
|
options.includeCrypto = true;
|
|
607
703
|
options.installDeps = !isSecureMode;
|
|
704
|
+
options.bomAudit = true;
|
|
608
705
|
break;
|
|
609
706
|
default:
|
|
610
707
|
break;
|
|
@@ -640,7 +737,7 @@ const applyAdvancedOptions = (options) => {
|
|
|
640
737
|
].includes(options.projectType[0])
|
|
641
738
|
) {
|
|
642
739
|
console.log(
|
|
643
|
-
"PREVIEW: post-build lifecycle SBOM generation is supported only for
|
|
740
|
+
"PREVIEW: post-build lifecycle SBOM generation is supported only for limited project types.",
|
|
644
741
|
);
|
|
645
742
|
process.exit(1);
|
|
646
743
|
}
|
|
@@ -670,10 +767,23 @@ const applyAdvancedOptions = (options) => {
|
|
|
670
767
|
"I must avoid any package installations and focus solely on the available artefacts, such as lock files.",
|
|
671
768
|
);
|
|
672
769
|
}
|
|
770
|
+
if (options.bomAudit) {
|
|
771
|
+
if (!options.includeFormulation) {
|
|
772
|
+
console.log(
|
|
773
|
+
"NOTE: Automatically collecting formulation information. The section may include sensitive data such as emails and secrets.\nPlease review the generated SBOM before distribution or LLM training.\n",
|
|
774
|
+
);
|
|
775
|
+
}
|
|
776
|
+
options.includeFormulation = true;
|
|
777
|
+
}
|
|
673
778
|
return options;
|
|
674
779
|
};
|
|
675
780
|
applyAdvancedOptions(options);
|
|
676
781
|
|
|
782
|
+
const envAuditFindings = auditEnvironment();
|
|
783
|
+
if (options.envAudit) {
|
|
784
|
+
displaySelfThreatModel(filePath, config, options, envAuditFindings);
|
|
785
|
+
}
|
|
786
|
+
|
|
677
787
|
/**
|
|
678
788
|
* Check for node >= 20 permissions
|
|
679
789
|
*
|
|
@@ -786,22 +896,6 @@ const checkPermissions = (filePath, options) => {
|
|
|
786
896
|
return false;
|
|
787
897
|
}
|
|
788
898
|
}
|
|
789
|
-
if (!process.permission.has("fs.write", process.env.ATOM_DB || ATOM_DB)) {
|
|
790
|
-
console.log(
|
|
791
|
-
`SECURE MODE: FileSystemWrite permission is required to create the output slices file. Please invoke cdxgen with the argument --allow-fs-write="${process.env.ATOM_DB || ATOM_DB}"`,
|
|
792
|
-
);
|
|
793
|
-
return false;
|
|
794
|
-
}
|
|
795
|
-
console.log(
|
|
796
|
-
"TIP: Invoke cdxgen with `--allow-addons` to allow the use of sqlite3 native addon. This addon is required for evidence mode.",
|
|
797
|
-
);
|
|
798
|
-
} else {
|
|
799
|
-
if (process.permission.has("fs.write", process.env.ATOM_DB || ATOM_DB)) {
|
|
800
|
-
console.log(
|
|
801
|
-
`SECURE MODE: FileSystemWrite permission is not required for the directory "${process.env.ATOM_DB || ATOM_DB}" in non-evidence mode. Consider removing the argument --allow-fs-write="${process.env.ATOM_DB || ATOM_DB}".`,
|
|
802
|
-
);
|
|
803
|
-
return false;
|
|
804
|
-
}
|
|
805
899
|
}
|
|
806
900
|
if (!process.permission.has("fs.write", getTmpDir())) {
|
|
807
901
|
console.log(
|
|
@@ -843,12 +937,15 @@ const needsBomSigning = ({ generateKeyAndSign }) =>
|
|
|
843
937
|
printSponsorBanner(options);
|
|
844
938
|
// Our quest to audit and check the SBOM generation environment to prevent our users from getting exploited
|
|
845
939
|
// during SBOM generation.
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
console.log(`SECURE MODE: ${w}`);
|
|
940
|
+
if (envAuditFindings?.length) {
|
|
941
|
+
for (const f of envAuditFindings) {
|
|
942
|
+
console.log(`SECURE MODE: ${f.variable}: ${f.message}`);
|
|
850
943
|
}
|
|
851
|
-
|
|
944
|
+
// Only abort in secure mode for high or critical findings; low/medium are informational.
|
|
945
|
+
if (
|
|
946
|
+
isSecureMode &&
|
|
947
|
+
envAuditFindings.some((f) => ["high", "critical"].includes(f.severity))
|
|
948
|
+
) {
|
|
852
949
|
process.exit(1);
|
|
853
950
|
}
|
|
854
951
|
}
|
|
@@ -873,7 +970,38 @@ const needsBomSigning = ({ generateKeyAndSign }) =>
|
|
|
873
970
|
);
|
|
874
971
|
}
|
|
875
972
|
// Add extra metadata and annotations with post processing
|
|
876
|
-
bomNSData = postProcess(bomNSData, options);
|
|
973
|
+
bomNSData = postProcess(bomNSData, options, filePath);
|
|
974
|
+
if (options.bomAudit && bomNSData?.bomJson) {
|
|
975
|
+
const {
|
|
976
|
+
auditBom,
|
|
977
|
+
formatAnnotations,
|
|
978
|
+
formatConsoleOutput,
|
|
979
|
+
hasCriticalFindings,
|
|
980
|
+
} = await import("../lib/stages/postgen/auditBom.js");
|
|
981
|
+
thoughtLog("Let's run security audit...");
|
|
982
|
+
const postAuditFindings = await auditBom(bomNSData.bomJson, options);
|
|
983
|
+
if (postAuditFindings.length) {
|
|
984
|
+
formatConsoleOutput(postAuditFindings);
|
|
985
|
+
} else if (DEBUG_MODE) {
|
|
986
|
+
console.log("BOM audit: No findings");
|
|
987
|
+
}
|
|
988
|
+
if (postAuditFindings.length && options.specVersion >= 1.4) {
|
|
989
|
+
bomNSData.bomJson.annotations = [
|
|
990
|
+
...(bomNSData.bomJson.annotations || []),
|
|
991
|
+
...formatAnnotations(postAuditFindings, bomNSData.bomJson),
|
|
992
|
+
];
|
|
993
|
+
thoughtLog(
|
|
994
|
+
`Embedded ${postAuditFindings.length} audit findings as CycloneDX annotations`,
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
if (isSecureMode && hasCriticalFindings(postAuditFindings, options)) {
|
|
998
|
+
console.error("\nSecure mode: Critical audit findings detected.");
|
|
999
|
+
console.error(
|
|
1000
|
+
"Review findings above or adjust --bom-audit-fail-severity to proceed.",
|
|
1001
|
+
);
|
|
1002
|
+
process.exit(1);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
877
1005
|
if (
|
|
878
1006
|
options.output &&
|
|
879
1007
|
(typeof options.output === "string" || options.output instanceof String)
|
|
@@ -972,71 +1100,41 @@ const needsBomSigning = ({ generateKeyAndSign }) =>
|
|
|
972
1100
|
}
|
|
973
1101
|
}
|
|
974
1102
|
try {
|
|
975
|
-
// Sign the individual components
|
|
976
|
-
// Let's leave the services unsigned for now since it might require additional cleansing
|
|
977
1103
|
const bomJsonUnsignedObj = JSON.parse(jsonPayload);
|
|
978
|
-
|
|
979
|
-
const compSignature = jws.sign({
|
|
980
|
-
header: { alg },
|
|
981
|
-
payload: comp,
|
|
982
|
-
privateKey: privateKeyToUse,
|
|
983
|
-
});
|
|
984
|
-
const compSignatureBlock = {
|
|
985
|
-
algorithm: alg,
|
|
986
|
-
value: compSignature,
|
|
987
|
-
};
|
|
988
|
-
if (jwkPublicKey) {
|
|
989
|
-
compSignatureBlock.publicKey = jwkPublicKey;
|
|
990
|
-
}
|
|
991
|
-
comp.signature = compSignatureBlock;
|
|
992
|
-
}
|
|
993
|
-
const signature = jws.sign({
|
|
994
|
-
header: { alg },
|
|
995
|
-
payload: JSON.stringify(bomJsonUnsignedObj, null, 2),
|
|
1104
|
+
const signOptions = {
|
|
996
1105
|
privateKey: privateKeyToUse,
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
// Verifying this signature
|
|
1018
|
-
const signatureVerification = jws.verify(
|
|
1019
|
-
signature,
|
|
1106
|
+
algorithm: alg,
|
|
1107
|
+
publicKeyJwk: jwkPublicKey,
|
|
1108
|
+
mode: process.env.SBOM_SIGN_MODE || "replace",
|
|
1109
|
+
signComponents: true,
|
|
1110
|
+
signServices: true,
|
|
1111
|
+
signAnnotations: true,
|
|
1112
|
+
};
|
|
1113
|
+
thoughtLog(`Signing the BOM file "${jsonFile}".`);
|
|
1114
|
+
const signedBom = signBom(bomJsonUnsignedObj, signOptions);
|
|
1115
|
+
fs.writeFileSync(
|
|
1116
|
+
jsonFile,
|
|
1117
|
+
JSON.stringify(signedBom, null, options.jsonPretty ? 2 : null),
|
|
1118
|
+
);
|
|
1119
|
+
if (publicKeyFile) {
|
|
1120
|
+
const publicKeyStr = fs.readFileSync(publicKeyFile, "utf8");
|
|
1121
|
+
const signatureVerification = verifyBom(signedBom, publicKeyStr);
|
|
1122
|
+
if (signatureVerification) {
|
|
1123
|
+
console.log(
|
|
1124
|
+
"SBOM signature is verifiable natively with the public key and the algorithm",
|
|
1125
|
+
publicKeyFile,
|
|
1020
1126
|
alg,
|
|
1021
|
-
fs.readFileSync(publicKeyFile, "utf8"),
|
|
1022
1127
|
);
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
publicKeyFile,
|
|
1027
|
-
alg,
|
|
1028
|
-
);
|
|
1029
|
-
} else {
|
|
1030
|
-
console.log("SBOM signature verification was unsuccessful");
|
|
1031
|
-
console.log(
|
|
1032
|
-
"Check if the public key was exported in PEM format",
|
|
1033
|
-
);
|
|
1034
|
-
}
|
|
1128
|
+
} else {
|
|
1129
|
+
console.log("SBOM signature verification was unsuccessful");
|
|
1130
|
+
console.log("Check if the public key was exported in PEM format");
|
|
1035
1131
|
}
|
|
1036
1132
|
}
|
|
1037
1133
|
} catch (ex) {
|
|
1038
|
-
console.log("SBOM signing was unsuccessful", ex);
|
|
1039
|
-
console.log(
|
|
1134
|
+
console.log("SBOM signing was unsuccessful:", ex.message);
|
|
1135
|
+
console.log(
|
|
1136
|
+
"Check if the private key was exported in PEM format and the algorithm is JSF-compliant.",
|
|
1137
|
+
);
|
|
1040
1138
|
}
|
|
1041
1139
|
}
|
|
1042
1140
|
}
|
|
@@ -1068,7 +1166,6 @@ const needsBomSigning = ({ generateKeyAndSign }) =>
|
|
|
1068
1166
|
input: options.output,
|
|
1069
1167
|
output: options.evinseOutput,
|
|
1070
1168
|
language: options.projectType,
|
|
1071
|
-
dbPath: process.env.ATOM_DB || ATOM_DB,
|
|
1072
1169
|
skipMavenCollector: false,
|
|
1073
1170
|
force: false,
|
|
1074
1171
|
withReachables: options.deep,
|