├── .github └── workflows │ ├── go.yml │ ├── golangci-lint.yml │ └── release.yml ├── .gitignore ├── .golangci.yaml ├── .vscode ├── launch.json └── settings.json ├── CREDITS.md ├── LICENSE ├── Makefile ├── NOTICE.txt ├── README.md ├── cmd ├── document.go ├── errors.go ├── license.go ├── license_expression.go ├── license_expression_test.go ├── license_list.go ├── license_policy.go ├── license_policy_config.go ├── license_policy_test.go ├── license_test.go ├── query.go ├── query_test.go ├── report.go ├── resource.go ├── resource_test.go ├── root.go ├── root_test.go ├── schema.go ├── validate.go ├── validate_cdx_examples_test.go ├── validate_cdx_test.go ├── validate_config_test.go ├── validate_custom.go ├── validate_custom_ibm_test.go ├── validate_custom_test.go ├── validate_properties.go ├── validate_spdx_examples_test.go ├── validate_spdx_test.go ├── validate_test.go ├── validation.json └── version.go ├── config.json ├── custom.json ├── examples ├── README.md ├── cyclonedx │ ├── BOM │ │ ├── juice-shop-11.1.2 │ │ │ └── bom.json │ │ └── laravel-7.12.0 │ │ │ └── bom.1.3.json │ ├── SaaSBOM │ │ └── apigateway-microservices-datastores │ │ │ └── bom.json │ └── usecases │ │ ├── README.md │ │ ├── cdx-use-case-assembly.json │ │ ├── cdx-use-case-authenticity-jsf.json │ │ ├── cdx-use-case-component-known-vulnerabilities.json │ │ ├── cdx-use-case-composition-and-completeness.json │ │ ├── cdx-use-case-dependency-graph.json │ │ ├── cdx-use-case-external-references.json │ │ ├── cdx-use-case-integrity-verification.json │ │ ├── cdx-use-case-inventory.json │ │ ├── cdx-use-case-license-compliance.json │ │ ├── cdx-use-case-openchain-conformance.json │ │ ├── cdx-use-case-package-evaluation.json │ │ ├── cdx-use-case-packaging-and-distribution.json │ │ ├── cdx-use-case-pedigree.json │ │ ├── cdx-use-case-provenance.json │ │ ├── cdx-use-case-security-advisories.json │ │ ├── cdx-use-case-service-defn.json │ │ ├── cdx-use-case-vulnerability-exploitability.json │ │ └── cdx-use-case-vulnerability-remediation.json ├── ibm │ ├── cra │ │ ├── cra-sbom.json │ │ ├── fvt │ │ │ └── data │ │ │ │ └── alpine │ │ │ │ └── expected-cdx.json │ │ ├── npm │ │ │ └── async │ │ │ │ └── cra-discovery.json │ │ └── sample-master-inventory-report.json │ ├── mend │ │ └── whitesource.json │ └── nst │ │ └── nst-sbom.json └── spdx │ ├── README.md │ ├── example1 │ ├── example1.json │ └── example1.spdx │ ├── example2 │ ├── example2-bin.json │ ├── example2-bin.spdx │ ├── example2-src.json │ └── example2-src.spdx │ ├── example5 │ ├── README.md │ ├── example5-bin.json │ ├── example5-bin.spdx │ ├── example5-src.json │ └── example5-src.spdx │ └── example6 │ ├── example6-bin.spdx │ ├── example6-lib.json │ ├── example6-lib.spdx │ ├── example6-src.json │ └── example6-src.spdx ├── go.mod ├── go.sum ├── ibm-requirements.md ├── license.json ├── log ├── format.go ├── log.go └── log_test.go ├── main.go ├── resources ├── resources.go └── schema │ ├── cyclonedx │ ├── 1.2 │ │ ├── bom-1.2-strict.schema.json │ │ └── bom-1.2.schema.json │ ├── 1.3 │ │ ├── bom-1.3-strict.schema.json │ │ ├── bom-1.3.schema.json │ │ └── bom-1.3.schema.json.ori │ ├── 1.4 │ │ ├── bom-1.4.schema.json │ │ └── jsf-0.82.schema.json │ ├── 1.5 │ │ └── bom-1.5-dev.schema.json │ ├── README.md │ └── cdx-schema-delta-by-version.md │ ├── spdx │ ├── 2.2.1 │ │ └── spdx-schema.json │ ├── 2.2.2 │ │ ├── spdx-schema.json │ │ ├── spdx-schema.json.ori │ │ └── spdx-schema.sorted.json │ ├── 2.3.1 │ │ └── spdx-schema.json │ ├── 2.3 │ │ ├── spdx-schema.json │ │ ├── spdx-schema.json.ori │ │ └── spdx-schema.sorted.json │ ├── README.md │ └── spdx-delta-v2.2.2-v2.3.md │ └── test │ ├── bom-1.3-custom.schema.json │ ├── bom-1.4-custom.schema.json │ └── ibm │ ├── bom-1.3-ibm.schema.json │ ├── bom-1.4-ibm-development.schema.json │ └── bom-1.4-ibm-release.schema.json ├── sbom-validation-tests.md ├── schema ├── README.md ├── constants.go ├── schema_custom_validation.go ├── schema_cyclonedx.go └── schema_formats.go ├── test ├── config │ ├── test-base-invalid-format-key-foo.json │ ├── test-cdx-bom-format-invalid.json │ ├── test-cdx-bom-format-missing.json │ ├── test-cdx-spec-version-invalid.json │ ├── test-cdx-spec-version-missing.json │ ├── test-spdx-spdx-id-invalid.json │ └── test-spdx-spdx-version-missing.json ├── custom │ ├── cdx-1-3-test-custom-invalid-composition-components.json │ ├── cdx-1-3-test-custom-invalid-composition-metadata-component.json │ ├── cdx-1-4-invalid-licenses-not-found.json │ ├── cdx-1-4-test-custom-metadata-property-classification-invalid.json │ ├── cdx-1-4-test-custom-metadata-property-classification-missing.json │ ├── cdx-1-4-test-custom-metadata-property-classification-unique.json │ ├── cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json │ ├── cdx-1-4-test-custom-metadata-property-disclaimer-missing.json │ ├── cdx-1-4-test-custom-metadata-property-disclaimer-unique.json │ └── ibm │ │ ├── cdx-1-3-ibm-invalid-composition-components.json │ │ ├── cdx-1-3-ibm-invalid-composition-metadata-component.json │ │ ├── cdx-1-3-ibm-manual-data-example.json │ │ ├── cdx-1-3-ibm-min-required.json │ │ ├── cdx-1-4-ibm-min-required.json │ │ └── cdx-1-4-test-ibm-invalid-disclaimer-missing.json ├── cyclonedx │ ├── cdx-1-2-invalid-license-name-has-expression.json │ ├── cdx-1-3-invalid-license-choice-oneof.json │ ├── cdx-1-3-invalid-spdx-license-id.json │ ├── cdx-1-3-license-list-empty.json │ ├── cdx-1-3-license-list.json │ ├── cdx-1-3-mature-example-1.json │ ├── cdx-1-3-min-required.json │ ├── cdx-1-3-resource-list-none-found.json │ ├── cdx-1-3-resource-list.json │ ├── cdx-1-3-syntax-err-1.json │ ├── cdx-1-3-syntax-err-2.json │ ├── cdx-1-4-invalid-email-format.json │ ├── cdx-1-4-license-policy-invalid-license-name.json │ ├── cdx-1-4-license-policy-invalid-spdx-id.json │ ├── cdx-1-4-mature-example-1.json │ └── cdx-1-4-min-required.json ├── ibm │ └── config │ │ ├── config-ibm.json │ │ ├── custom-ibm.json │ │ └── license-ibm.json ├── policy │ ├── license-policy-family-name-usage-conflict.json │ ├── license-policy-id.json │ └── license-policy-license-expression-test-data.json └── spdx │ ├── README.md │ ├── spdx-2-2-min-required.json │ └── spdx-2-2-missing-creationinfo.json └── utils ├── config.go ├── convert.go └── flags.go /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a golang project 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go 3 | 4 | name: Go 5 | 6 | on: 7 | push: 8 | branches: [ "main" ] 9 | pull_request: 10 | branches: [ "main" ] 11 | 12 | jobs: 13 | 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | - name: Set up Go 20 | uses: actions/setup-go@v3 21 | with: 22 | go-version: 1.18 23 | 24 | - name: Build 25 | run: go build -v ./... 26 | 27 | - name: Test 28 | run: go test -v ./... 29 | -------------------------------------------------------------------------------- /.github/workflows/golangci-lint.yml: -------------------------------------------------------------------------------- 1 | name: golangci-lint 2 | on: 3 | push: 4 | tags: 5 | - v* 6 | branches: 7 | - main 8 | - '**' 9 | pull_request: 10 | branches: [ main ] 11 | 12 | permissions: 13 | contents: read 14 | # Optional: allow read access to pull request. Use with `only-new-issues` option. 15 | # pull-requests: read 16 | jobs: 17 | golangci: 18 | name: lint 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/setup-go@v3 22 | with: 23 | go-version: 1.18 24 | - uses: actions/checkout@v3 25 | - name: golangci-lint 26 | uses: golangci/golangci-lint-action@v3 27 | with: 28 | # Optional: golangci-lint command line arguments. 29 | args: -D errcheck 30 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release Go Binaries 2 | 3 | on: 4 | release: 5 | types: [created] 6 | workflow_dispatch: 7 | 8 | 9 | jobs: 10 | releases-matrix: 11 | name: Release Matrix 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | goos: [darwin, linux, windows] 16 | # NOTE: Intentionally, support legacy architectures for windows and darwin (MacOS) 17 | goarch: [arm64, amd64, ppc64, s390x] 18 | exclude: 19 | # NOTE: PowerPC and System 390 only support Linux 20 | - goos: darwin 21 | goarch: ppc64 22 | - goos: darwin 23 | goarch: s390x 24 | - goos: windows 25 | goarch: ppc64 26 | - goos: windows 27 | goarch: s390x 28 | steps: 29 | - uses: actions/checkout@v3 30 | 31 | # Set build/link environment variables 32 | - name: Set APP_NAME env 33 | # GITHUB_REPOSITORY=CycloneDX/sbom-utility 34 | run: echo APP_NAME=$(echo ${GITHUB_REPOSITORY} | rev | cut -d'/' -f 1 | rev ) >> ${GITHUB_ENV} 35 | - name: Set APP_VERSION env 36 | run: echo "APP_VERSION=${GITHUB_REF_NAME}" >> ${GITHUB_ENV} 37 | - name: Set BUILD_TIME env 38 | run: echo BUILD_TIME=$(date) >> ${GITHUB_ENV} 39 | - name: Set SBOM_NAME env 40 | run: echo "SBOM_NAME=${{env.APP_NAME}}-${{env.APP_VERSION}}.bom.json" >> ${GITHUB_ENV} 41 | - name: List of the GitHub Actions environment variables on Windows 42 | run: env | sort 43 | 44 | # Generate an SBOM 45 | - name: Set up Go 46 | uses: actions/setup-go@v3 47 | with: 48 | go-version: 1.18 49 | - name: Install SBOM generator (latest) 50 | run: go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@latest 51 | - name: Generate SBOM (from `go.mod`) 52 | # run: cyclonedx-gomod mod -json=true "-output ${{env.APP_NAME}}-${{env.APP_VERSION}}.bom.json" . 53 | run: cyclonedx-gomod mod -json=true -output ${{env.SBOM_NAME}} 54 | 55 | # Release binaries in all GOOS/GOARCH combinations (with all config. files) 56 | - uses: wangyoucao577/go-release-action@v1.35 57 | with: 58 | github_token: ${{ secrets.GITHUB_TOKEN }} 59 | goos: ${{ matrix.goos }} 60 | goarch: ${{ matrix.goarch }} 61 | extra_files: LICENSE config.json license.json custom.json ${{env.SBOM_NAME}} 62 | # "auto" will use ZIP for Windows, otherwise default is TAR 63 | compress_assets: auto 64 | # NOTE: This verbose flag may be removed 65 | build_flags: -v 66 | ldflags: -X "main.Version=${{ env.APP_VERSION }}" -X "main.Binary=${{ env.APP_NAME }}" 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # make target file types 2 | sbom-utility* 3 | /release 4 | 5 | # IDEs 6 | *.code-workspace 7 | .vscode/*.log 8 | 9 | # Misc 10 | *.gpg 11 | a.txt 12 | -------------------------------------------------------------------------------- /.golangci.yaml: -------------------------------------------------------------------------------- 1 | # https://golangci-lint.run/usage/configuration/ 2 | run: 3 | issues-exit-code: 2 4 | 5 | # https://golangci-lint.run/usage/false-positives/ 6 | # https://staticcheck.io/docs/ 7 | linters-settings: 8 | staticcheck: 9 | checks: 10 | - all 11 | - '-SA4005' # disable the rule SA1000 12 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "showGlobalVariables": true, 9 | "name": "Query: SELECT * FROM metadata.component", 10 | "type": "go", 11 | "request": "launch", 12 | "mode": "debug", 13 | "program": "main.go", // "program": "${file}", 14 | "args": ["query", "-i", "test/cyclonedx/cdx-1-4-mature-example-1.json", "--select", "*", "--from", "metadata.component"] 15 | }, 16 | { 17 | "showGlobalVariables": true, 18 | "name": "license: list: BAD license exp.", 19 | "type": "go", 20 | "request": "launch", 21 | "mode": "debug", 22 | "program": "main.go", // "program": "${file}", 23 | "args": ["license", "list", "-i", "test/cyclonedx/cdx-1-2-invalid-license-name-has-expression.json", "--summary"] 24 | }, 25 | { 26 | "showGlobalVariables": true, 27 | "name": "license policy", 28 | "type": "go", 29 | "request": "launch", 30 | "mode": "debug", 31 | "program": "main.go", 32 | "args": ["license", "policy", "-t"] 33 | }, 34 | { 35 | "showGlobalVariables": true, 36 | "name": "license policy --format csv", 37 | "type": "go", 38 | "request": "launch", 39 | "mode": "debug", 40 | "program": "main.go", 41 | "args": ["license", "policy", "--format", "csv", "-t"] 42 | }, 43 | { 44 | "showGlobalVariables": true, 45 | "name": "license: list: CDX: test/cyclonedx/cdx-1-3-license-list.json", 46 | "type": "go", 47 | "request": "launch", 48 | "mode": "debug", 49 | "program": "main.go", // "program": "${file}", 50 | "args": ["license", "list", "-i", "test/cyclonedx/cdx-1-3-license-list.json"] 51 | }, 52 | { 53 | "showGlobalVariables": true, 54 | "name": "validate: CDX: test/cyclonedx/cdx-1-3-license-list.json", 55 | "type": "go", 56 | "request": "launch", 57 | "mode": "debug", 58 | "program": "main.go", // "program": "${file}", 59 | "args": ["validate", "-i", "test/cyclonedx/cdx-1-3-license-list.json", "-t"] 60 | }, 61 | { 62 | "showGlobalVariables": true, 63 | "name": "validate: CDX: juice-shop/bom.json: indent", 64 | "type": "go", 65 | "request": "launch", 66 | "mode": "debug", 67 | "program": "main.go", // "program": "${file}", 68 | "args": ["validate", "-i", "examples/cyclonedx/juice-shop/bom.json", "-t", "--indent"] 69 | }, 70 | { 71 | "showGlobalVariables": true, 72 | "name": "validate: CDX: EXAMPLE: juice-shop/bom.json (infer 1.2)", 73 | "type": "go", 74 | "request": "launch", 75 | "mode": "debug", 76 | "program": "main.go", // "program": "${file}", 77 | "args": ["validate", "-i", "examples/cyclonedx/juice-shop/bom.json", "-t"] 78 | }, 79 | { 80 | "showGlobalVariables": true, 81 | "name": "validate: SPDX: spdx-min-required.json (infer 2.2)", 82 | "type": "go", 83 | "request": "launch", 84 | "mode": "debug", 85 | "program": "main.go", // "program": "${file}", 86 | "args": ["validate", "-i", "test/spdx/spdx-min-required.json"] 87 | }, 88 | { 89 | "showGlobalVariables": true, 90 | "name": "validate: SPDX: spdx-min-required-missing-creationinfo.json (infer)", 91 | "type": "go", 92 | "request": "launch", 93 | "mode": "debug", 94 | "program": "main.go", // "program": "${file}", 95 | "args": ["validate", "-i", "test/spdx/spdx-min-required-missing-creationinfo.json"] 96 | }, 97 | { 98 | "showGlobalVariables": true, 99 | "name": "validate: SPDX: EXAMPLE: examples/spdx/example1/example1.json (infer schema)", 100 | "type": "go", 101 | "request": "launch", 102 | "mode": "debug", 103 | "program": "main.go", // "program": "${file}", 104 | "args": ["validate", "-i", "examples/spdx/example1/example1.json"] 105 | }, 106 | ] 107 | } 108 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "ABNF", 4 | "alphanum", 5 | "Antlr", 6 | "APIGW", 7 | "Aptogo", 8 | "autofail", 9 | "backport", 10 | "BOMREF", 11 | "callstack", 12 | "CDLA", 13 | "cdxschema", 14 | "Classpath", 15 | "cwes", 16 | "CYCLONEDX", 17 | "Debugf", 18 | "defn", 19 | "DHTML", 20 | "EMEA", 21 | "Exploitability", 22 | "fatih", 23 | "firstname", 24 | "Freetype", 25 | "Globus", 26 | "gojsonschema", 27 | "gomod", 28 | "GTPL", 29 | "hokaccha", 30 | "HSQLDB", 31 | "Infof", 32 | "Infozip", 33 | "Jaxen", 34 | "JDOM", 35 | "jwangsadinata", 36 | "LARAVEL", 37 | "lastname", 38 | "LDFLAGS", 39 | "losslessly", 40 | "NOASSERTION", 41 | "NTIA", 42 | "Nyffenegger", 43 | "OPENCHAIN", 44 | "OWASP", 45 | "PARENS", 46 | "parms", 47 | "pipelinerun", 48 | "POSIX", 49 | "prettyjson", 50 | "PROPKEY", 51 | "repackager", 52 | "SAAS", 53 | "SAASBOM", 54 | "SBOM", 55 | "SCVS", 56 | "slicemultimap", 57 | "SNMP", 58 | "SPDXID", 59 | "startswith", 60 | "staticcheck", 61 | "structs", 62 | "swid", 63 | "tablewriter", 64 | "Tracef", 65 | "unmarshal", 66 | "unmarshalled", 67 | "unmarshalling", 68 | "unmarshals", 69 | "usecases", 70 | "VULN", 71 | "Warningf" 72 | ] 73 | } 74 | -------------------------------------------------------------------------------- /CREDITS.md: -------------------------------------------------------------------------------- 1 | # IBM Donation to OWASP Foundation 2 | 3 | The sbom-utility was originally designed, created and solely developed by Matt Rutkowski (mrutkows@us.ibm.com) while working for IBM Corporation (http://www.ibm.com/) under an Apache 2 license and donated in January 2023 to the OWASP Foundation's CycloneDX project. 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one or more 3 | # contributor license agreements. See the NOTICE file distributed with 4 | # this work for additional information regarding copyright ownership. 5 | # The ASF licenses this file to You under the Apache License, Version 2.0 6 | # (the "License"); you may not use this file except in compliance with 7 | # the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | SOURCEDIR=. 19 | 20 | SOURCES := $(shell find $(SOURCEDIR) -name '*.go') 21 | BINARY?=sbom-utility 22 | 23 | # LDFLAG values 24 | VERSION?=latest 25 | BUILD=`git rev-parse HEAD` 26 | BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` 27 | RELEASE_DIR=release 28 | 29 | # TODO: automate other flags 30 | # LDFLAGS=-ldflags "-X main.Version=${VERSION} -X main.GitCommit=${BUILD} -X main.BuildDate=${BUILD_DATE} -X main.Build=`git rev-parse HEAD` " 31 | # NOTE: The `-s` (sign) flag MUST be used or the binary will will be rejected on MacOS 32 | # Additionally on MacOS, the binary MUST be moved (i.e., `mv`) not copied (i.e., `cp`) 33 | LDFLAGS=-ldflags "-X main.Version=${VERSION} -X main.Binary=${BINARY} -s" 34 | 35 | # Build the project 36 | build: clean 37 | go build ${LDFLAGS} -o ${BINARY} 38 | 39 | # General supported environments: https://go.dev/doc/install/source#environment 40 | # See latest supported combinations using: 41 | # $ go install golang.org/x/tools/cmd/goimports@latest 42 | # $ go tool dist list 43 | # However, many combinations are not supported "in box" 44 | # See this Gist for details: https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63 45 | # TODO: perhaps create universal binaries for various OS 46 | # TODO: See "lipo" tool for MacOS universal binary 47 | release: clean config sbom 48 | GOOS=darwin GOARCH=amd64 go build ${LDFLAGS} -o ${RELEASE_DIR}/${BINARY}-darwin-amd64 49 | GOOS=darwin GOARCH=arm64 go build ${LDFLAGS} -o ${RELEASE_DIR}/${BINARY}-darwin-arm64 50 | GOOS=linux GOARCH=amd64 go build ${LDFLAGS} -o ${RELEASE_DIR}/${BINARY}-linux-amd64 51 | GOOS=linux GOARCH=arm64 go build ${LDFLAGS} -o ${RELEASE_DIR}/${BINARY}-linux-arm64 52 | GOOS=windows GOARCH=amd64 go build ${LDFLAGS} -o ${RELEASE_DIR}/${BINARY}-windows-amd64 53 | GOOS=windows GOARCH=arm64 go build ${LDFLAGS} -o ${RELEASE_DIR}/${BINARY}-windows-arm64 54 | GOOS=windows GOARCH=arm64 go build ${LDFLAGS} -o ${RELEASE_DIR}/${BINARY}-windows-arm64 55 | GOOS=linux GOARCH=ppc64 go build ${LDFLAGS} -o ${RELEASE_DIR}/${BINARY}-linux-ppc64 56 | GOOS=linux GOARCH=s390x go build ${LDFLAGS} -o ${RELEASE_DIR}/${BINARY}-linux-s390x 57 | cp LICENSE ${RELEASE_DIR}/ 58 | cp config.json ${RELEASE_DIR}/ 59 | cp license.json ${RELEASE_DIR}/ 60 | cp custom.json ${RELEASE_DIR}/ 61 | 62 | sbom: 63 | @echo "Creating Software-Bill-Of-Materials (CycloneDX latest JSON format)" 64 | go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@latest 65 | mkdir -p ${RELEASE_DIR} 66 | cyclonedx-gomod mod -json=true -output ${RELEASE_DIR}/${BINARY}-${VERSION}.bom.json . 67 | 68 | # Clean test cache 69 | test_clean: 70 | go clean -testcache 71 | 72 | # Run all tests 73 | test: test_clean 74 | @echo "Testing" 75 | go test ./... -v 76 | 77 | # Run cmd tests 78 | test_cmd: test_clean 79 | @echo "Testing `cmd` package" 80 | go test ./cmd -v --args --quiet 81 | 82 | # Run the unit tests 83 | unit_tests: test_clean 84 | @echo "Testing -tags=unit" 85 | go test ./... -v -tags=unit 86 | 87 | # Run the integration tests 88 | integration_tests: 89 | @echo "Testing -tags=integration" 90 | go test -v ./... -tags=integration 91 | 92 | format: 93 | @echo "Formatting" 94 | go fmt ./... 95 | 96 | lint: format 97 | @echo "Linting" 98 | golint . 99 | 100 | install: 101 | go install 102 | 103 | # Cleans project up binaries 104 | # if ${BINARY}: covers any manual `go build` executables 105 | # if ${BINARY}: covers `make build` target 106 | # if ${RELEASE_DIR}: covers `make release` target 107 | clean: 108 | @if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi 109 | @if [ -d ${RELEASE_DIR} ] ; then rm -f ${RELEASE_DIR}/${BINARY}* ; rm -f ${RELEASE_DIR}/*.json ; rmdir ${RELEASE_DIR} ; fi 110 | 111 | .PHONY: config clean build release test_clean test test_cmd unit_tests integration_tests format lint install 112 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | OWASP CycloneDX/sbom-utility 2 | @ Copyright 2023-present OWASP Foundation 3 | 4 | This product includes software developed at 5 | The OWASP Foundation's CycloneDX project (https://owasp.org/www-project-cyclonedx/). 6 | 7 | The Initial Developer of the sbom-utility 8 | was Matt Rutkowski (mrutkows@us.ibm.com), working for IBM Corporation (http://www.ibm.com/) 9 | © Copyright IBM Corporation 2022, 2023. 10 | -------------------------------------------------------------------------------- /cmd/document.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package cmd 19 | 20 | import ( 21 | "fmt" 22 | 23 | "github.com/ibm/sbom-utility/schema" 24 | "github.com/ibm/sbom-utility/utils" 25 | ) 26 | 27 | func LoadInputSbomFileAndDetectSchema() (document *schema.Sbom, err error) { 28 | getLogger().Enter() 29 | defer getLogger().Exit() 30 | 31 | // check for required fields on command 32 | getLogger().Tracef("utils.Flags.InputFile: `%s`", utils.GlobalFlags.InputFile) 33 | if utils.GlobalFlags.InputFile == "" { 34 | return nil, fmt.Errorf("invalid input file (-%s): `%s` ", FLAG_FILENAME_INPUT_SHORT, utils.GlobalFlags.InputFile) 35 | } 36 | 37 | // Construct an Sbom object around the input file 38 | document = schema.NewSbom(utils.GlobalFlags.InputFile) 39 | 40 | // Load the raw, candidate SBOM (file) as JSON data 41 | getLogger().Infof("Attempting to load and unmarshal file `%s`...", utils.GlobalFlags.InputFile) 42 | err = document.UnmarshalSBOMAsJsonMap() // i.e., utils.Flags.InputFile 43 | if err != nil { 44 | return 45 | } 46 | getLogger().Infof("Successfully unmarshalled data from: `%s`", utils.GlobalFlags.InputFile) 47 | 48 | // Search the document keys/values for known SBOM formats and schema in the config. file 49 | getLogger().Infof("Determining file's SBOM format and version...") 50 | err = document.FindFormatAndSchema() 51 | if err != nil { 52 | return 53 | } 54 | 55 | // Display detected format, version with (optional) schema variant (i.e., if requested on command line) 56 | getLogger().Infof("Determined SBOM format, version (variant): `%s`, `%s` %s", 57 | document.FormatInfo.CanonicalName, 58 | document.SchemaInfo.Version, 59 | schema.FormatSchemaVariant(document.SchemaInfo.Variant)) 60 | getLogger().Infof("Matching SBOM schema (for validation): %s", document.SchemaInfo.File) 61 | return 62 | } 63 | -------------------------------------------------------------------------------- /cmd/license_expression_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package cmd 19 | 20 | import ( 21 | "reflect" 22 | "testing" 23 | ) 24 | 25 | // TODO: Need tests that include unary operators (e.g., AFL-2.0+) 26 | // which is an outdated concept and replaced by newer approach as seen 27 | // with GPL (e.g., GPL-2.0-or-later) using suffixes "or-later" or "only" (restrict) 28 | 29 | func TestLicenseExpressionTokenizerWhitespaceRemoval(t *testing.T) { 30 | EXP := " Apache-2.0 AND ( MIT OR GPL-2.0-only ) " 31 | VALID := []string{"Apache-2.0", "AND", "(", "MIT", "OR", "GPL-2.0-only", ")"} 32 | 33 | tokens := tokenizeExpression(EXP) 34 | 35 | if !reflect.DeepEqual(tokens, VALID) { 36 | t.Errorf("tokenizeExpression(): returned: %v; expected: %v", tokens, VALID) 37 | } else { 38 | getLogger().Tracef("tokenizeExpression(): returned: %v; matched expected", tokens) 39 | } 40 | } 41 | 42 | func TestLicenseExpressionTokenizerWhitespaceNewlineTabRemoval(t *testing.T) { 43 | EXP := "\n\tApache-2.0 \tAND (\n MIT OR GPL-2.0-only )\t\n" 44 | VALID := []string{"Apache-2.0", "AND", "(", "MIT", "OR", "GPL-2.0-only", ")"} 45 | 46 | tokens := tokenizeExpression(EXP) 47 | 48 | if !reflect.DeepEqual(tokens, VALID) { 49 | t.Errorf("tokenizeExpression(): returned: %v; expected: %v", tokens, VALID) 50 | } else { 51 | getLogger().Tracef("tokenizeExpression(): returned: %v; matched expected", tokens) 52 | } 53 | } 54 | 55 | func TestLicenseExpressionParsingTestBasic(t *testing.T) { 56 | SPDX_LICENSE_EXPRESSION_TEST1 := "Apache-2.0 AND (MIT OR GPL-2.0-only)" 57 | result, _ := parseExpression(SPDX_LICENSE_EXPRESSION_TEST1) 58 | json := getLogger().FormatStruct(result) 59 | getLogger().Infof("expression:\n%s", json) 60 | } 61 | 62 | func TestLicenseExpressionParsingCompoundRightSide(t *testing.T) { 63 | EXP := "Apache-2.0 AND (MIT OR GPL-2.0-only )" 64 | parsedExpression, _ := parseExpression(EXP) 65 | getLogger().Infof("expression:\n%v", parsedExpression) 66 | } 67 | 68 | func TestLicenseExpressionCompoundLeftSide(t *testing.T) { 69 | EXP := "(Apache-1.0 OR Apache-1.1 ) AND 0BSD" 70 | parsedExpression, _ := parseExpression(EXP) 71 | getLogger().Infof("expression:\n%v", parsedExpression) 72 | } 73 | -------------------------------------------------------------------------------- /cmd/report.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package cmd 19 | 20 | import "strings" 21 | 22 | // Text report helpers 23 | // TODO Make function params. variadic 24 | func createTitleRows(titles1 []string, titles2 []string) (titles []string, underlines []string) { 25 | titles = append(titles1, titles2...) 26 | underlines = append(createTitleTextSeparators(titles1), createTitleTextSeparators(titles2)...) 27 | return 28 | } 29 | 30 | func createTitleTextSeparators(titles []string) (separatorLine []string) { 31 | var underline string 32 | for _, title := range titles { 33 | underline = strings.Repeat(LICENSE_LIST_TITLE_ROW_SEPARATOR, len(title)) 34 | separatorLine = append(separatorLine, underline) 35 | } 36 | return 37 | } 38 | 39 | // Markdown report helpers 40 | const ( 41 | MD_COLUMN_SEPARATOR = "|" 42 | MD_ALIGN_LEFT = ":--" 43 | MD_ALIGN_CENTER = "-:-" 44 | MD_ALIGN_RIGHT = "--:" 45 | ) 46 | 47 | func createMarkdownColumnAlignment(titles []string) (alignment []string) { 48 | for range titles { 49 | alignment = append(alignment, MD_ALIGN_LEFT) 50 | } 51 | return 52 | } 53 | 54 | func createMarkdownRow(data []string) string { 55 | return MD_COLUMN_SEPARATOR + 56 | strings.Join(data, MD_COLUMN_SEPARATOR) + 57 | MD_COLUMN_SEPARATOR 58 | } 59 | -------------------------------------------------------------------------------- /cmd/validate_cdx_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package cmd 19 | 20 | import "testing" 21 | 22 | // Consolidate test file name declarations 23 | const ( 24 | // CycloneDX - Test versioned documents meet min. schema requirements 25 | TEST_CDX_1_3_MIN_REQUIRED = "test/cyclonedx/cdx-1-3-min-required.json" 26 | TEST_CDX_1_4_MIN_REQUIRED = "test/cyclonedx/cdx-1-4-min-required.json" 27 | 28 | // (invalid) schema tests 29 | TEST_SCHEMA_CDX_1_3_INVALID_LICENSE_CHOICE = "test/cyclonedx/cdx-1-3-invalid-license-choice-oneof.json" 30 | TEST_SCHEMA_CDX_1_3_INVALID_LICENSE_ID = "test/cyclonedx/cdx-1-3-invalid-spdx-license-id.json" 31 | TEST_SCHEMA_CDX_1_4_INVALID_LICENSE_ID = "test/cyclonedx/cdx-1-3-invalid-spdx-license-id.json" 32 | TEST_SCHEMA_CDX_1_4_INVALID_EMAIL_FORMAT = "test/cyclonedx/cdx-1-4-invalid-email-format.json" 33 | ) 34 | 35 | // ----------------------------------------------------------- 36 | // CycloneDX - Min. req. tests 37 | // ----------------------------------------------------------- 38 | 39 | func TestValidateCdx13MinRequiredBasic(t *testing.T) { 40 | innerValidateError(t, TEST_CDX_1_3_MIN_REQUIRED, SCHEMA_VARIANT_NONE, nil) 41 | } 42 | 43 | func TestValidateCdx14MinRequiredBasic(t *testing.T) { 44 | innerValidateError(t, TEST_CDX_1_4_MIN_REQUIRED, SCHEMA_VARIANT_NONE, nil) 45 | } 46 | 47 | // ----------------------------------------------------------- 48 | // CycloneDX - (invalid) schema tests 49 | // ----------------------------------------------------------- 50 | // NOTE: Schema errors do not have an "inner error", but return "[]gojsonschema.ResultError" 51 | // This means that these "errors" ARE NOT surfaced in the error return from Validate(); instead, 52 | // a `[]gojsonschema.ResultError` (custom error) is returned in the "results" array 53 | // ----------------------------------------------------------- 54 | 55 | // Ensure invalid "id" in a License object is caught (i.e., "UNKNOWN" is not a valid SPDX ID value) 56 | func TestValidateSchemaCdx13InvalidSPDXLicenseId(t *testing.T) { 57 | SCHEMA_ERROR_TYPE := "enum" 58 | SCHEMA_ERROR_FIELD := "components.1.licenses.0.license.id" 59 | SCHEMA_ERROR_VALUE := "UNKNOWN" 60 | 61 | innerTestSchemaErrorAndErrorResults(t, 62 | TEST_SCHEMA_CDX_1_3_INVALID_LICENSE_ID, 63 | SCHEMA_VARIANT_NONE, 64 | SCHEMA_ERROR_TYPE, 65 | SCHEMA_ERROR_FIELD, 66 | SCHEMA_ERROR_VALUE) 67 | } 68 | 69 | // (v1.4+) Ensure invalid email value (format) is caught (i.e., type not "idn-email") 70 | func TestValidateSchemaCdx14InvalidEmailFormat(t *testing.T) { 71 | SCHEMA_ERROR_TYPE := "format" 72 | SCHEMA_ERROR_FIELD := "metadata.supplier.contact.0.email" 73 | SCHEMA_ERROR_VALUE := "https://acme.com" 74 | 75 | innerTestSchemaErrorAndErrorResults(t, 76 | TEST_SCHEMA_CDX_1_4_INVALID_EMAIL_FORMAT, 77 | SCHEMA_VARIANT_NONE, 78 | SCHEMA_ERROR_TYPE, 79 | SCHEMA_ERROR_FIELD, 80 | SCHEMA_ERROR_VALUE) 81 | } 82 | 83 | // (v1.2+) Ensure invalid LicenseChoice object is caught (i.e., has BOTH an "id" and "name") 84 | func TestValidateSchemaCdx13InvalidLicenseChoice(t *testing.T) { 85 | SCHEMA_ERROR_TYPE := "number_one_of" 86 | SCHEMA_ERROR_FIELD := "metadata.component.licenses.0.license" 87 | // Note: the value returned is not a simple string so do not test this 88 | // field of the error results. 89 | SCHEMA_ERROR_VALUE := "" 90 | 91 | innerTestSchemaErrorAndErrorResults(t, 92 | TEST_SCHEMA_CDX_1_3_INVALID_LICENSE_CHOICE, 93 | SCHEMA_VARIANT_NONE, 94 | SCHEMA_ERROR_TYPE, 95 | SCHEMA_ERROR_FIELD, 96 | SCHEMA_ERROR_VALUE) 97 | } 98 | -------------------------------------------------------------------------------- /cmd/validate_config_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package cmd 19 | 20 | import ( 21 | "testing" 22 | 23 | "github.com/ibm/sbom-utility/schema" 24 | ) 25 | 26 | // ----------------------------------------------------------- 27 | // Configuration tests 28 | // ----------------------------------------------------------- 29 | 30 | const ( 31 | // Configuration tests 32 | TEST_INVALID_FORMAT_KEY_FOO = "test/config/test-base-invalid-format-key-foo.json" 33 | TEST_CDX_SPEC_VERSION_INVALID = "test/config/test-cdx-spec-version-invalid.json" 34 | TEST_CDX_BOM_FORMAT_INVALID = "test/config/test-cdx-bom-format-invalid.json" 35 | TEST_CDX_BOM_FORMAT_MISSING = "test/config/test-cdx-bom-format-missing.json" 36 | TEST_CDX_SPEC_VERSION_MISSING = "test/config/test-cdx-spec-version-missing.json" 37 | TEST_SPDX_SPDX_ID_INVALID = "test/config/test-spdx-spdx-id-invalid.json" 38 | TEST_SPDX_SPDX_VERSION_MISSING = "test/config/test-spdx-spdx-version-missing.json" 39 | ) 40 | 41 | func TestValidateConfigInvalidFormatKey(t *testing.T) { 42 | innerValidateError(t, 43 | TEST_INVALID_FORMAT_KEY_FOO, 44 | SCHEMA_VARIANT_NONE, 45 | &schema.UnsupportedFormatError{}) 46 | } 47 | 48 | func TestValidateConfigInvalidVersion(t *testing.T) { 49 | innerValidateError(t, 50 | TEST_CDX_SPEC_VERSION_INVALID, 51 | SCHEMA_VARIANT_NONE, 52 | &schema.UnsupportedSchemaError{}) 53 | } 54 | 55 | func TestValidateConfigInvalidVariant(t *testing.T) { 56 | innerValidateError(t, 57 | TEST_CDX_1_4_MIN_REQUIRED, 58 | "foo", 59 | &schema.UnsupportedSchemaError{}) 60 | } 61 | 62 | func TestValidateConfigCDXBomFormatInvalid(t *testing.T) { 63 | innerValidateError(t, 64 | TEST_CDX_BOM_FORMAT_INVALID, 65 | SCHEMA_VARIANT_NONE, 66 | &schema.UnsupportedFormatError{}) 67 | } 68 | 69 | func TestValidateConfigCDXBomFormatMissing(t *testing.T) { 70 | innerValidateError(t, 71 | TEST_CDX_BOM_FORMAT_MISSING, 72 | SCHEMA_VARIANT_NONE, 73 | &schema.UnsupportedFormatError{}) 74 | } 75 | 76 | func TestValidateConfigCDXSpecVersionMissing(t *testing.T) { 77 | innerValidateError(t, 78 | TEST_CDX_SPEC_VERSION_MISSING, 79 | SCHEMA_VARIANT_NONE, 80 | &schema.UnsupportedSchemaError{}) 81 | } 82 | 83 | func TestValidateConfigSPDXSpdxIdInvalid(t *testing.T) { 84 | innerValidateError(t, 85 | TEST_SPDX_SPDX_ID_INVALID, 86 | SCHEMA_VARIANT_NONE, 87 | &schema.UnsupportedFormatError{}) 88 | } 89 | 90 | func TestValidateConfigSPDXSpdxVersionInvalid(t *testing.T) { 91 | innerValidateError(t, 92 | TEST_SPDX_SPDX_VERSION_MISSING, 93 | SCHEMA_VARIANT_NONE, 94 | &schema.UnsupportedSchemaError{}) 95 | } 96 | -------------------------------------------------------------------------------- /cmd/validate_properties.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package cmd 19 | -------------------------------------------------------------------------------- /cmd/validate_spdx_examples_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package cmd 19 | 20 | import "testing" 21 | 22 | const ( 23 | // SPDX - Examples 24 | TEST_SPDX_2_2_EXAMPLE_1 = "examples/spdx/example1/example1.json" 25 | TEST_SPDX_2_2_EXAMPLE_2_BIN = "examples/spdx/example2/example2-bin.json" 26 | TEST_SPDX_2_2_EXAMPLE_2_SRC = "examples/spdx/example2/example2-src.json" 27 | TEST_SPDX_2_2_EXAMPLE_5_BIN = "examples/spdx/example5/example5-bin.json" 28 | TEST_SPDX_2_2_EXAMPLE_5_SRC = "examples/spdx/example5/example5-src.json" 29 | TEST_SPDX_2_2_EXAMPLE_6_LIB = "examples/spdx/example6/example6-lib.json" 30 | TEST_SPDX_2_2_EXAMPLE_6_SRC = "examples/spdx/example6/example6-src.json" 31 | ) 32 | 33 | // SPDX - Examples 34 | func TestValidateSpdx22Example1(t *testing.T) { 35 | innerValidateError(t, TEST_SPDX_2_2_EXAMPLE_1, SCHEMA_VARIANT_NONE, nil) 36 | } 37 | 38 | func TestValidateSPDX22Example2Bin(t *testing.T) { 39 | innerValidateError(t, TEST_SPDX_2_2_EXAMPLE_2_BIN, SCHEMA_VARIANT_NONE, nil) 40 | } 41 | 42 | func TestValidateSPDX22Example2Src(t *testing.T) { 43 | innerValidateError(t, TEST_SPDX_2_2_EXAMPLE_2_SRC, SCHEMA_VARIANT_NONE, nil) 44 | } 45 | 46 | func TestValidateSPDX22Example5Bin(t *testing.T) { 47 | innerValidateError(t, TEST_SPDX_2_2_EXAMPLE_5_BIN, SCHEMA_VARIANT_NONE, nil) 48 | } 49 | 50 | func TestValidateSPDX22Example5Src(t *testing.T) { 51 | innerValidateError(t, TEST_SPDX_2_2_EXAMPLE_5_SRC, SCHEMA_VARIANT_NONE, nil) 52 | } 53 | 54 | func TestValidateSPDX22Example6Lib(t *testing.T) { 55 | innerValidateError(t, TEST_SPDX_2_2_EXAMPLE_6_LIB, SCHEMA_VARIANT_NONE, nil) 56 | } 57 | 58 | func TestValidateSPDX22Example6Src(t *testing.T) { 59 | innerValidateError(t, TEST_SPDX_2_2_EXAMPLE_6_SRC, SCHEMA_VARIANT_NONE, nil) 60 | } 61 | -------------------------------------------------------------------------------- /cmd/validate_spdx_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package cmd 19 | 20 | import ( 21 | "testing" 22 | ) 23 | 24 | // Consolidate test file name declarations 25 | const ( 26 | // SPDX - Test versioned documents meet min. schema requirements 27 | TEST_SPDX_2_2_MIN_REQUIRED = "test/spdx/spdx-2-2-min-required.json" 28 | 29 | // SPDX - (invalid) Schema tests 30 | TEST_SPDX_2_2_INVALID_CREATION_INFO_MISSING = "test/spdx/spdx-2-2-missing-creationinfo.json" 31 | 32 | // SPDX - Tool samples 33 | //TEST_SPDX_SAMPLE_MEND_PACKAGE_NPM_ASYNC_WS = "test/spdx/samples/whitesource.json" 34 | ) 35 | 36 | // ----------------------------------------------------------- 37 | // SPDX - Min. req. tests 38 | // ----------------------------------------------------------- 39 | 40 | // TODO: Need an SPDX 2.1 variant 41 | // TODO: Need an SPDX 2.2.1 variant 42 | // TODO: Need an SPDX 2.2 "custom" variant 43 | func TestValidateSpdx22MinRequiredBasic(t *testing.T) { 44 | innerValidateError(t, TEST_SPDX_2_2_MIN_REQUIRED, SCHEMA_VARIANT_NONE, nil) 45 | } 46 | 47 | // ----------------------------------------------------------- 48 | // SPDX - (invalid) Schema tests 49 | // ----------------------------------------------------------- 50 | // NOTE: Schema errors do not have an "inner error", but return "[]gojsonschema.ResultError" 51 | // This means that these "errors" ARE NOT surfaced in the error return from Validate(); instead, 52 | // a `[]gojsonschema.ResultError` (custom error) is returned in the "results" array 53 | // ----------------------------------------------------------- 54 | 55 | func TestValidateSchemaSpdx22CreationInfoMissing(t *testing.T) { 56 | // Note: actual error "value" is a structure which we cannot easily recreate here; so do not test that field 57 | SCHEMA_ERROR_TYPE := "required" 58 | SCHEMA_ERROR_FIELD := "(root)" 59 | SCHEMA_ERROR_VALUE := "" 60 | 61 | innerTestSchemaErrorAndErrorResults(t, 62 | TEST_SPDX_2_2_INVALID_CREATION_INFO_MISSING, 63 | SCHEMA_VARIANT_NONE, 64 | SCHEMA_ERROR_TYPE, 65 | SCHEMA_ERROR_FIELD, 66 | SCHEMA_ERROR_VALUE) 67 | } 68 | -------------------------------------------------------------------------------- /cmd/validation.json: -------------------------------------------------------------------------------- 1 | { 2 | "validation": { 3 | "metadata": { 4 | "_selector": "metadata.properties", 5 | "properties": [ 6 | { 7 | "name": "urn:ibm:names:identifier:deliverable:", 8 | "value": ".*\\S.*", 9 | "_validate_description": "non-empty, no whitespace" 10 | }, 11 | { 12 | "name": "urn:ibm:names:identifier:product:", 13 | "value": ".*\\S.*", 14 | "_validate_description": "non-empty, no whitespace" 15 | }, 16 | { 17 | "name": "urn:ibm:legal:disclaimer", 18 | "value": "^(This SBOM is IBM Confidential Information.)", 19 | "_validate_description": "startswith()" 20 | }, 21 | { 22 | "name": "urn:ibm:legal:coverage", 23 | "value": "^(This SBOM is current as of the date it was generated and is subject to change.)", 24 | "_validate_description": "startswith()" 25 | } 26 | ], 27 | "tools": [ 28 | { 29 | "name": "IBM Cloud Continuous Delivery - Code Risk Analyzer", 30 | "vendor": "IBM", 31 | "version": "0.1.17", 32 | "_validate_regex": "name" 33 | }, 34 | { 35 | "name": "IBM PTC Scanning Tool", 36 | "vendor": "IBM", 37 | "version": "1.4.9", 38 | "_validate_regex": "version" 39 | } 40 | ] 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /cmd/version.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package cmd 19 | 20 | import ( 21 | "fmt" 22 | 23 | "github.com/ibm/sbom-utility/utils" 24 | "github.com/spf13/cobra" 25 | ) 26 | 27 | func NewCommandVersion() *cobra.Command { 28 | var command = new(cobra.Command) 29 | command.Use = CMD_VERSION 30 | command.Short = "Display program, binary and version information" 31 | command.Long = "Display program, binary and version information in SemVer format (e.g., ` version `)" 32 | command.Run = func(cmd *cobra.Command, args []string) { 33 | getLogger().Enter() 34 | defer getLogger().Exit() 35 | fmt.Printf("%s version %s\n", utils.GlobalFlags.Project, utils.GlobalFlags.Version) 36 | } 37 | return command 38 | } 39 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "formats": [ 3 | { 4 | "canonicalName": "SPDX", 5 | "propertyKeyFormat": "SPDXID", 6 | "propertyKeyVersion": "spdxVersion", 7 | "propertyValueFormat": "SPDXRef-DOCUMENT", 8 | "schemas": [ 9 | { 10 | "version": "SPDX-2.2", 11 | "name": "schema/spdx/2.2.1/spdx-schema.json", 12 | "file": "schema/spdx/2.2.1/spdx-schema.json", 13 | "url": "https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.1/schemas/spdx-schema.json", 14 | "default": false, 15 | "variant": "2.2.1" 16 | }, 17 | { 18 | "version": "SPDX-2.2", 19 | "name": "schema/spdx/2.2.2/spdx-schema.json", 20 | "file": "schema/spdx/2.2.2/spdx-schema.json", 21 | "url": "https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.2/schemas/spdx-schema.json", 22 | "default": false, 23 | "variant": "" 24 | }, 25 | { 26 | "version": "SPDX-2.3", 27 | "name": "schema/spdx/2.3/spdx-schema.json", 28 | "file": "schema/spdx/2.3/spdx-schema.json", 29 | "url": "https://raw.githubusercontent.com/spdx/spdx-spec/development/v2.3/schemas/spdx-schema.json", 30 | "default": true, 31 | "variant": "" 32 | }, 33 | { 34 | "version": "SPDX-2.3", 35 | "name": "schema/spdx/2.3.1/spdx-schema.json", 36 | "file": "schema/spdx/2.3.1/spdx-schema.json", 37 | "url": "https://raw.githubusercontent.com/spdx/spdx-spec/development/v2.3.1/schemas/spdx-schema.json", 38 | "default": false, 39 | "variant": "development" 40 | } 41 | ] 42 | }, 43 | { 44 | "canonicalName": "CycloneDX", 45 | "propertyKeyFormat": "bomFormat", 46 | "propertyKeyVersion": "specVersion", 47 | "propertyValueFormat": "CycloneDX", 48 | "schemas": [ 49 | { 50 | "version": "1.2", 51 | "name": "bom-1.2.schema.json", 52 | "file": "schema/cyclonedx/1.2/bom-1.2.schema.json", 53 | "url": "https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.2.schema.json", 54 | "default": false, 55 | "variant": "" 56 | }, 57 | { 58 | "version": "1.2", 59 | "name": "bom-1.2-strict.schema.json", 60 | "file": "schema/cyclonedx/1.2/bom-1.2-strict.schema.json", 61 | "url": "https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.2-strict.schema.json", 62 | "default": false, 63 | "variant": "strict" 64 | }, 65 | { 66 | "version": "1.3", 67 | "name": "bom-1.3.schema.json", 68 | "file": "schema/cyclonedx/1.3/bom-1.3.schema.json", 69 | "url": "https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.3.schema.json", 70 | "default": false, 71 | "variant": "" 72 | }, 73 | { 74 | "version": "1.3", 75 | "name": "bom-1.3-strict.schema.json", 76 | "file": "schema/cyclonedx/1.3/bom-1.3-strict.schema.json", 77 | "url": "https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.3-strict.schema.json", 78 | "default": false, 79 | "variant": "strict" 80 | }, 81 | { 82 | "version": "1.4", 83 | "name": "bom-1.4.schema.json", 84 | "file": "schema/cyclonedx/1.4/bom-1.4.schema.json", 85 | "url": "https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.4.schema.json", 86 | "default": true, 87 | "variant": "" 88 | }, 89 | { 90 | "version": "1.5", 91 | "name": "bom-1.5-dev.schema.json", 92 | "file": "schema/cyclonedx/1.5/bom-1.5-dev.schema.json", 93 | "url": "https://raw.githubusercontent.com/CycloneDX/specification/v1.5-dev/schema/bom-1.5.schema.json", 94 | "default": false, 95 | "variant": "development" 96 | }, 97 | { 98 | "version": "1.3", 99 | "name": "bom-1.3-custom.schema.json", 100 | "file": "schema/test/bom-1.3-custom.schema.json", 101 | "url": "", 102 | "default": false, 103 | "variant": "custom" 104 | }, 105 | { 106 | "version": "1.4", 107 | "name": "bom-1.4-custom.schema.json", 108 | "file": "schema/test/bom-1.4-custom.schema.json", 109 | "url": "", 110 | "default": false, 111 | "variant": "custom" 112 | } 113 | ] 114 | } 115 | ] 116 | } -------------------------------------------------------------------------------- /custom.json: -------------------------------------------------------------------------------- 1 | { 2 | "validation": { 3 | "metadata": { 4 | "_selector": "metadata.properties", 5 | "properties": [ 6 | { 7 | "name": "urn:example.com:disclaimer", 8 | "value": "This SBOM is current as of the date it was generated and is subject to change\\.", 9 | "_validate_description": "matches fixed value", 10 | "_validate_key": "name", 11 | "_validate_unique": "name" 12 | }, 13 | { 14 | "name": "urn:example.com:classification", 15 | "value": "This SBOM is Confidential Information. Do not distribute\\.", 16 | "_validate_description": "matches fixed value", 17 | "_validate_key": "name", 18 | "_validate_unique": "name" 19 | } 20 | ] 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/README.md: -------------------------------------------------------------------------------- 1 | # CycloneDX use cases 2 | 3 | ## Canonical use case examples 4 | 5 | Canonical (CycloneDX v1.4, JSON format) use cases with sample code: 6 | 7 | - https://cyclonedx.org/use-cases 8 | 9 | | CDX Version | Use case | Test file (JSON) | Description | 10 | | :-- | :-- | :-- | :-- | 11 | | 1.4| Inventory | [cdx-use-case-inventory.json](cdx-use-case-inventory.json) | Includes all supported component `type` values | 12 | | 1.4 | Known vulnerabilities | [cdx-use-case-component-known-vulnerabilities.json](cdx-use-case-component-known-vulnerabilities.json) | Includes all supported component `type` values | 13 | | 1.4 | Integrity verification | c[cdx-use-case-integrity-verification.json](cdx-use-case-integrity-verification.json) | | 14 | | 1.4 | Authenticity (JSF) | [cdx-use-case-authenticty-jsf.json](cdx-use-case-authenticty-jsf.json) | | 15 | | 1.4 | Package evaluation | [cdx-use-case-package-evaluation.json](cdx-use-case-package-evaluation.json) | | 16 | | 1.4 | License compliance | [cdx-use-case-license-compliance.json](cdx-use-case-license-compliance.json) | | 17 | | 1.4 | Assembly | [cdx-use-case-assembly.json](cdx-use-case-assembly.json) | | 18 | | 1.4 | Dependency graph | [cdx-use-case-dependency-graph.json](cdx-use-case-dependency-graph.json) | | 19 | | 1.4 | Provenance| [cdx-use-case-provenance.json](cdx-use-case-provenance.json) | | 20 | | 1.4 | Pedigree | [cdx-use-case-pedigree.json](cdx-use-case-pedigree.json) | | 21 | | 1.4 | Service definition | [cdx-use-case-service-defn.json](cdx-use-case-service-defn.json) | A complete v1.4 "service" definition | 22 | | 1.4 | Properties | [cdx-use-case-provenance.json](cdx-use-case-provenance.json) | name-value store | 23 | | 1.4 | Packaging and distribution| [cdx-use-case-packaging-and-distribution.json](cdx-use-case-packaging-and-distribution.json) | | 24 | | 1.4 | Composition completeness | [cdx-use-case-composition-and-completeness.json](cdx-use-case-composition-and-completeness.json) | | 25 | | 1.4 | OpenChain conformance | [cdx-use-case-openchain-conformance.json](cdx-use-case-openchain-conformance.json) | | 26 | | 1.4 | Vulnerability remediation | [cdx-use-case-vulnerability-remediation.json](cdx-use-case-vulnerability-remediation.json) | | 27 | | 1.4 | Vulnerability exploitability | [cdx-use-case-vulnerability-exploitability.json](cdx-use-case-vulnerability-exploitability.json) | | 28 | | 1.4 | Security advisories| [cdx-use-case-security-advisories.json](cdx-use-case-security-advisories.json) | | 29 | | 1.4 | External references| [cdx-use-case-external-references.json](cdx-use-case-external-references.json) | | 30 | 31 | ### Use case ideas 32 | 33 | - bom-link (VEX, SaaSBOM) 34 | - Service "known vuln." use case ** 35 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-assembly.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat":"CycloneDX", 3 | "specVersion":"1.4", 4 | "serialNumber":"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version":1, 6 | "components":[ 7 | { 8 | "type":"application", 9 | "name":"Acme Commerce Suite", 10 | "version":"2.0.0", 11 | "swid":{ 12 | "tagId":"swidgen-cebab27e-da95-213c-8b73-d1d3afcb806f_2.0.0", 13 | "name":"Acme Commerce Suite", 14 | "version":"2.0.0" 15 | }, 16 | "components":[ 17 | { 18 | "type":"application", 19 | "name":"Acme Storefront Server", 20 | "version":"3.7.0", 21 | "swid":{ 22 | "tagId":"swidgen-80d7e827-4031-288b-2313-2781923fe86e_3.7.0", 23 | "name":"Acme Storefront Server", 24 | "version":"3.7.0" 25 | } 26 | }, 27 | { 28 | "type":"application", 29 | "name":"Acme Payment Processor", 30 | "version":"3.1.1", 31 | "swid":{ 32 | "tagId":"swidgen-ac2f2eec-05c0-907e-3a54-a6782a24885e_3.1.1", 33 | "name":"Acme Payment Processor", 34 | "version":"3.1.1" 35 | } 36 | } 37 | ] 38 | }, 39 | { 40 | "type":"application", 41 | "name":"Acme Management App", 42 | "version":"2.0.0", 43 | "swid":{ 44 | "tagId":"swidgen-8429d5b6-2dbf-0fde-768b-aaab0e5881c8_2.0.0", 45 | "name":"Acme Management App", 46 | "version":"2.0.0" 47 | } 48 | }, 49 | { 50 | "type":"application", 51 | "name":"Acme License Utility", 52 | "version":"2.0.0", 53 | "swid":{ 54 | "tagId":"swidgen-4332a8dc-13e3-7d44-2f52-0a53f4898995_2.0.0", 55 | "name":"Acme License Utility", 56 | "version":"2.0.0" 57 | } 58 | } 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-authenticity-jsf.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat":"CycloneDX", 3 | "specVersion":"1.4", 4 | "serialNumber":"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version":1, 6 | "components":[ 7 | { 8 | "type":"library", 9 | "publisher":"Apache", 10 | "group":"org.apache.tomcat", 11 | "name":"tomcat-catalina", 12 | "version":"9.0.14", 13 | "hashes":[ 14 | { 15 | "alg":"MD5", 16 | "content":"3942447fac867ae5cdb3229b658f4d48" 17 | }, 18 | { 19 | "alg":"SHA-1", 20 | "content":"e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" 21 | }, 22 | { 23 | "alg":"SHA-256", 24 | "content":"f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" 25 | }, 26 | { 27 | "alg":"SHA-512", 28 | "content":"e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" 29 | } 30 | ], 31 | "licenses":[ 32 | { 33 | "license":{ 34 | "id":"Apache-2.0" 35 | } 36 | } 37 | ], 38 | "purl":"pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14" 39 | } 40 | ], 41 | "signature":{ 42 | "algorithm":"RS512", 43 | "publicKey":{ 44 | "kty":"RSA", 45 | "n":"qOSWbDOGS31lv3aUZVOgqZyLVrKXXRfmxFQxEylcFY_bRqakeY1EYCkvwTkD9kxlLEd_2SSQYWEZZTjYa1EK1SlfyOsKd2eNKjxGtUSSxPkJRvYi_KgVedgp15C5p1Emsd3bKUs5knLebw4k576RxvY69AChXk48u1Pa7_Bicm89Io8JaQaDvSUXWD19j6686EniS6MSqvhsLsgmeS4V0TdKdWvjQIq0wJmPnBtWUy5DJn3glMtbeh_2xuEZ2Dkkjzr5O0W-vJUKVKm_qW2zbgdqP2_XA8LSywrRlZbvuVo_Jq8rWNxRhUDNtI98lXkSJ5hqk0wwXpUGvwjuCSqgZZmnmBCLzWGxbPfgJamnYr8AzudUaXT6PXz0qbAacmTL-ktm1zblDC_kZPfVsiiUzzND02YUS2euGVxIZc95EFlaEpa3MMIpurI-i0VG-SEagN5cURVCOjVysokC2pkKfrd__ThlvS9aywnMO8haNLPC4TEzzIr-KJff4UFYk_vCAsw7K9DjPWYheP1GoBUZbSApVe9HI4dQ6bGY80CEVRmo_LkPyXbX0c-BONyou1NGtlaYaP7eqaC1Z3b-OrZF-Z2BrTFuFnzKA2X5UPaWo77yra9owdcKG-p7FPlU5gHFmcuAQjx_l8nw8P9EhQXVHHiSSbT1iHmBQ1GO6J6bX_s", 46 | "e":"AQAB" 47 | }, 48 | "value":"HGIX_ccdIcqmaOpkxDzKH_j0ozSHUAUyBxGpXS_cCi4Qq34jhXxbKD8qu8r-u4EpX1PzChUqytVD36H-shBEzpr-bgvPONFSMUpsp36ILwTSI0YfsQbJIt1wKt-YiMQW2xQUNo6OpOAryLVFr8ZISf0GmnQ1RENH6wVR8XLkbyqYDN-JNoBrEdcbaANKgdsLBMg9h8tfPxS_C229MrnsershcSs7uiYOTx-Xt8T3yEcZLTTbEN9-jn5SJxS2av3oLp_VaC3bSIg65KoFwqQCweujH0csTr6dD2tCGcHE2xMkUtwscyPXK9He_m-LM4REss_MauAJpOHGacmNgN_auDZ97DZmgC4DX46hgXXqnp2qG-x4QCbrjd5ja3R9e5na7jKBROKqVM5IyYE07jHc9c9Jtma9jo90iVSXp0oSJieG8pDD0zD_Mhx_EOj75L8l5qSd9brJn_MyMkeWXob4eMOQmmVQ9t7zAcdtSCSlZh9lNeFxu2sS5FU-1jqrQM_ewSv292dPDVkx-PmBnfuK9ZasNT-_l3RUfUNPfhRCmK1M7g0REusS2c-jgSi0a3QUvXKfCJg8btbku4IDWqWsUcAIzjUFPlNz5Exyb_pkxy2Ah_hwcfTbGHClzCtVLSy6DCqxcBlTKQSKEGPcP4wUV8Oq0uOQkDokb5xYJVZX4VE" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-component-known-vulnerabilities.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat":"CycloneDX", 3 | "specVersion":"1.4", 4 | "serialNumber":"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version":1, 6 | "components":[ 7 | { 8 | "type":"application", 9 | "name":"Acme Application", 10 | "version":"9.1.1", 11 | "cpe":"cpe:/a:acme:application:9.1.1", 12 | "swid":{ 13 | "tagId":"swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", 14 | "name":"Acme Application", 15 | "version":"9.1.1", 16 | "text":{ 17 | "contentType":"text/xml", 18 | "encoding":"base64", 19 | "content":"PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" 20 | } 21 | } 22 | }, 23 | { 24 | "type":"library", 25 | "group":"org.apache.tomcat", 26 | "name":"tomcat-catalina", 27 | "version":"9.0.14", 28 | "purl":"pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14" 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-composition-and-completeness.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat":"CycloneDX", 3 | "specVersion":"1.4", 4 | "serialNumber":"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version":1, 6 | "metadata":{ 7 | "component":{ 8 | "bom-ref":"acme-application-1.0", 9 | "type":"application", 10 | "name":"Acme Application", 11 | "version":"1.0" 12 | } 13 | }, 14 | "components":[ 15 | { 16 | "bom-ref":"pkg:maven/partner/shaded-library@1.0", 17 | "type":"library", 18 | "name":"Partner Shaded Library", 19 | "version":"1.0", 20 | "purl":"pkg:maven/partner/shaded-library@1.0", 21 | "components":[ 22 | { 23 | "bom-ref":"pkg:maven/ossproject/library@2.0", 24 | "type":"library", 25 | "name":"Some Opensource Library", 26 | "version":"2.0", 27 | "purl":"pkg:maven/ossproject/library@2.0" 28 | } 29 | ] 30 | }, 31 | { 32 | "type":"library", 33 | "name":"Acme Library", 34 | "version":"3.0", 35 | "purl":"pkg:maven/acme/library@3.0" 36 | } 37 | ], 38 | "dependencies":[ 39 | { 40 | "ref":"acme-application-1.0", 41 | "dependsOn":[ 42 | "pkg:maven/partner/shaded-library@1.0", 43 | "pkg:maven/acme/library@3.0" 44 | ] 45 | } 46 | ], 47 | "compositions":[ 48 | { 49 | "aggregate":"complete", 50 | "assemblies":[ 51 | "pkg:maven/partner/shaded-library@1.0" 52 | ], 53 | "dependencies":[ 54 | "acme-application-1.0" 55 | ] 56 | }, 57 | { 58 | "aggregate":"unknown", 59 | "assemblies":[ 60 | "pkg:maven/acme/library@3.0" 61 | ] 62 | } 63 | ] 64 | } 65 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-dependency-graph.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat":"CycloneDX", 3 | "specVersion":"1.4", 4 | "serialNumber":"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version":1, 6 | "metadata":{ 7 | "component":{ 8 | "bom-ref":"acme-app", 9 | "type":"application", 10 | "name":"Acme Application", 11 | "version":"9.1.1" 12 | } 13 | }, 14 | "components":[ 15 | { 16 | "bom-ref":"pkg:maven/org.acme/web-framework@1.0.0", 17 | "type":"library", 18 | "group":"org.acme", 19 | "name":"web-framework", 20 | "version":"1.0.0", 21 | "purl":"pkg:maven/org.acme/web-framework@1.0.0" 22 | }, 23 | { 24 | "bom-ref":"pkg:maven/org.acme/persistence@3.1.0", 25 | "type":"library", 26 | "group":"org.acme", 27 | "name":"persistence", 28 | "version":"3.1.0", 29 | "purl":"pkg:maven/org.acme/persistence@3.1.0" 30 | }, 31 | { 32 | "bom-ref":"pkg:maven/org.acme/common-util@3.0.0", 33 | "type":"library", 34 | "group":"org.acme", 35 | "name":"common-util", 36 | "version":"3.0.0", 37 | "purl":"pkg:maven/org.acme/common-util@3.0.0" 38 | } 39 | ], 40 | "dependencies":[ 41 | { 42 | "ref":"acme-app", 43 | "dependsOn":[ 44 | "pkg:maven/org.acme/web-framework@1.0.0", 45 | "pkg:maven/org.acme/persistence@3.1.0" 46 | ] 47 | }, 48 | { 49 | "ref":"pkg:maven/org.acme/web-framework@1.0.0", 50 | "dependsOn":[ 51 | "pkg:maven/org.acme/common-util@3.0.0" 52 | ] 53 | }, 54 | { 55 | "ref":"pkg:maven/org.acme/persistence@3.1.0", 56 | "dependsOn":[ 57 | "pkg:maven/org.acme/common-util@3.0.0" 58 | ] 59 | }, 60 | { 61 | "ref":"pkg:maven/org.acme/common-util@3.0.0", 62 | "dependsOn":[ 63 | 64 | ] 65 | } 66 | ] 67 | } 68 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-external-references.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat":"CycloneDX", 3 | "specVersion":"1.4", 4 | "serialNumber":"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version":1, 6 | "components":[ 7 | { 8 | "type":"application", 9 | "group":"org.example", 10 | "name":"portal-server", 11 | "version":"1.0.0", 12 | "externalReferences":[ 13 | { 14 | "type":"advisories", 15 | "url":"https://example.org/security/feed/csaf", 16 | "comment":"Security advisories from the vendor" 17 | }, 18 | { 19 | "type":"bom", 20 | "url":"https://example.org/support/sbom/portal-server/1.0.0", 21 | "comment":"An external SBOM that describes what this component includes. Integrity verification should be performed to ensure the BOM has not been tampered with.", 22 | "hashes":[ 23 | { 24 | "alg":"SHA-256", 25 | "content":"708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313" 26 | }, 27 | { 28 | "alg":"SHA-384", 29 | "content":"d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad" 30 | }, 31 | { 32 | "alg":"SHA-512", 33 | "content":"74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6" 34 | } 35 | ] 36 | }, 37 | { 38 | "type":"documentation", 39 | "url":"https://example.org/support/documentation/portal-server/1.0.0", 40 | "comment":"Vendor provided documentation for the product" 41 | } 42 | ] 43 | }, 44 | { 45 | "type":"library", 46 | "group":"org.example", 47 | "name":"persistence", 48 | "version":"5.2.0", 49 | "externalReferences":[ 50 | { 51 | "type":"bom", 52 | "url":"urn:uuid:bdd819e6-ee8f-42d7-a4d0-166ff44d51e8", 53 | "comment":"Refers to a specific BOM with the specified serial number. Integrity verification should be performed to ensure the BOM has not been tampered with.", 54 | "hashes":[ 55 | { 56 | "alg":"SHA-256", 57 | "content":"9048a24d72d3d4a1a0384f8f925566b44f133dd2a0194111a2daeb1cf9f7015b" 58 | }, 59 | { 60 | "alg":"SHA-384", 61 | "content":"8640424aa9bf337678580c55d23e54b973703c6e586987d85700f24d5de383cd1add590ee5b98d1710a01aff212687f3" 62 | }, 63 | { 64 | "alg":"SHA-512", 65 | "content":"45c6e3d03ec4207234e926063c484446d8b55f4bfce3f929f44cbc2320565290cc4b71de70c1d983792c6d63504f47f6b94513d09847dbae69c8f7cdd51ce980" 66 | } 67 | ] 68 | } 69 | ] 70 | } 71 | ] 72 | } 73 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-integrity-verification.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat":"CycloneDX", 3 | "specVersion":"1.4", 4 | "serialNumber":"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version":1, 6 | "components":[ 7 | { 8 | "type":"library", 9 | "name":"acme-example", 10 | "version":"1.0.0", 11 | "hashes":[ 12 | { 13 | "alg":"MD5", 14 | "content":"641b6e166f8b33c5e959e2adcc18b1c7" 15 | }, 16 | { 17 | "alg":"SHA-1", 18 | "content":"9188560f22e0b73070d2efce670c74af2bdf30af" 19 | }, 20 | { 21 | "alg":"SHA-256", 22 | "content":"d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964" 23 | }, 24 | { 25 | "alg":"SHA-384", 26 | "content":"d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad" 27 | }, 28 | { 29 | "alg":"SHA-512", 30 | "content":"74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6" 31 | }, 32 | { 33 | "alg":"SHA3-256", 34 | "content":"7478c7cf41c883a04ee89f1813f687886d53fa86f791fff90690c6221e3853aa" 35 | }, 36 | { 37 | "alg":"SHA3-384", 38 | "content":"a1eea7229716487ad2ebe96b2f997a8408f32f14047994fbcc99b49012cf86c96dbd518e5d57a61b0e57dd37dd0b48f5" 39 | }, 40 | { 41 | "alg":"SHA3-512", 42 | "content":"7d584825bc1767dfabe7e82b45ccb7a1119b145fa17e76b885e71429c706cef0a3171bc6575b968eec5da56a7966c02fec5402fcee55097ac01d40c550de9d20" 43 | }, 44 | { 45 | "alg":"BLAKE2b-256", 46 | "content":"d8779633380c050bccf4e733b763ab2abd8ad2db60b517d47fd29bbf76433237" 47 | }, 48 | { 49 | "alg":"BLAKE2b-384", 50 | "content":"e728ba56c2da995a559a178116c594e8bee4894a79ceb4399d8f479e5563cb1942b85936f646d14170717c576b14db7a" 51 | }, 52 | { 53 | "alg":"BLAKE2b-512", 54 | "content":"f8ce8d612a6c85c96cf7cebc230f6ddef26e6cedcfbc4a41c766033cc08c6ba097d1470948226807fb2d88d2a2b6fc0ff5e5440e93a603086fdd568bafcd1a9d" 55 | }, 56 | { 57 | "alg":"BLAKE3", 58 | "content":"26cdc7fb3fd65fc3b621a4ef70bc7d2489d5c19e70c76cf7ec20e538df0047cf" 59 | } 60 | ] 61 | } 62 | ] 63 | } 64 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-inventory.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat":"CycloneDX", 3 | "specVersion":"1.4", 4 | "serialNumber":"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version":1, 6 | "components":[ 7 | { 8 | "type":"library", 9 | "name":"acme-example", 10 | "version":"1.0.0", 11 | "hashes":[ 12 | { 13 | "alg":"MD5", 14 | "content":"641b6e166f8b33c5e959e2adcc18b1c7" 15 | }, 16 | { 17 | "alg":"SHA-1", 18 | "content":"9188560f22e0b73070d2efce670c74af2bdf30af" 19 | }, 20 | { 21 | "alg":"SHA-256", 22 | "content":"d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964" 23 | }, 24 | { 25 | "alg":"SHA-384", 26 | "content":"d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad" 27 | }, 28 | { 29 | "alg":"SHA-512", 30 | "content":"74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6" 31 | }, 32 | { 33 | "alg":"SHA3-256", 34 | "content":"7478c7cf41c883a04ee89f1813f687886d53fa86f791fff90690c6221e3853aa" 35 | }, 36 | { 37 | "alg":"SHA3-384", 38 | "content":"a1eea7229716487ad2ebe96b2f997a8408f32f14047994fbcc99b49012cf86c96dbd518e5d57a61b0e57dd37dd0b48f5" 39 | }, 40 | { 41 | "alg":"SHA3-512", 42 | "content":"7d584825bc1767dfabe7e82b45ccb7a1119b145fa17e76b885e71429c706cef0a3171bc6575b968eec5da56a7966c02fec5402fcee55097ac01d40c550de9d20" 43 | }, 44 | { 45 | "alg":"BLAKE2b-256", 46 | "content":"d8779633380c050bccf4e733b763ab2abd8ad2db60b517d47fd29bbf76433237" 47 | }, 48 | { 49 | "alg":"BLAKE2b-384", 50 | "content":"e728ba56c2da995a559a178116c594e8bee4894a79ceb4399d8f479e5563cb1942b85936f646d14170717c576b14db7a" 51 | }, 52 | { 53 | "alg":"BLAKE2b-512", 54 | "content":"f8ce8d612a6c85c96cf7cebc230f6ddef26e6cedcfbc4a41c766033cc08c6ba097d1470948226807fb2d88d2a2b6fc0ff5e5440e93a603086fdd568bafcd1a9d" 55 | }, 56 | { 57 | "alg":"BLAKE3", 58 | "content":"26cdc7fb3fd65fc3b621a4ef70bc7d2489d5c19e70c76cf7ec20e538df0047cf" 59 | } 60 | ] 61 | } 62 | ] 63 | } -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-package-evaluation.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat":"CycloneDX", 3 | "specVersion":"1.4", 4 | "serialNumber":"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version":1, 6 | "components":[ 7 | { 8 | "type":"library", 9 | "group":"org.apache.tomcat", 10 | "name":"tomcat-catalina", 11 | "version":"9.0.14", 12 | "purl":"pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14" 13 | }, 14 | { 15 | "type":"library", 16 | "group":"org.acme", 17 | "name":"card-verifier", 18 | "version":"1.0.2", 19 | "purl":"pkg:maven/org.acme/card-verifier@1.0.2?repository_url=repo.acme.org/maven" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-packaging-and-distribution.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat":"CycloneDX", 3 | "specVersion":"1.4", 4 | "serialNumber":"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version":1, 6 | "metadata":{ 7 | "timestamp":"2020-04-13T20:20:39+00:00", 8 | "tools":[ 9 | { 10 | "vendor":"Awesome Vendor", 11 | "name":"Awesome Tool", 12 | "version":"9.1.2", 13 | "hashes":[ 14 | { 15 | "alg":"SHA-1", 16 | "content":"25ed8e31b995bb927966616df2a42b979a2717f0" 17 | }, 18 | { 19 | "alg":"SHA-256", 20 | "content":"a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df" 21 | } 22 | ] 23 | } 24 | ], 25 | "authors":[ 26 | { 27 | "name":"Samantha Wright", 28 | "email":"samantha.wright@example.com", 29 | "phone":"800-555-1212" 30 | } 31 | ], 32 | "component":{ 33 | "type":"application", 34 | "author":"Acme Super Heros", 35 | "name":"Acme Application", 36 | "version":"9.1.1", 37 | "swid":{ 38 | "tagId":"swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", 39 | "name":"Acme Application", 40 | "version":"9.1.1", 41 | "text":{ 42 | "contentType":"text/xml", 43 | "encoding":"base64", 44 | "content":"PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" 45 | } 46 | } 47 | }, 48 | "manufacture":{ 49 | "name":"Acme, Inc.", 50 | "url":[ 51 | "https://example.com" 52 | ], 53 | "contact":[ 54 | { 55 | "name":"Acme Professional Services", 56 | "email":"professional.services@example.com" 57 | } 58 | ] 59 | }, 60 | "supplier":{ 61 | "name":"Acme, Inc.", 62 | "url":[ 63 | "https://example.com" 64 | ], 65 | "contact":[ 66 | { 67 | "name":"Acme Distribution", 68 | "email":"distribution@example.com" 69 | } 70 | ] 71 | } 72 | }, 73 | "components":[ 74 | 75 | ] 76 | } 77 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-pedigree.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat":"CycloneDX", 3 | "specVersion":"1.4", 4 | "serialNumber":"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version":1, 6 | "components":[ 7 | { 8 | "type":"library", 9 | "group":"com.acme", 10 | "name":"sample-library", 11 | "version":"1.0.0", 12 | "pedigree":{ 13 | "ancestors":[ 14 | { 15 | "type":"library", 16 | "group":"org.example", 17 | "name":"sample-library", 18 | "version":"1.0.0" 19 | } 20 | ], 21 | "commits":[ 22 | { 23 | "uid":"7638417db6d59f3c431d3e1f261cc637155684cd", 24 | "url":"https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd", 25 | "author":{ 26 | "timestamp":"2018-11-13T20:20:39+00:00", 27 | "name":"John Doe", 28 | "email":"john.doe@example.com" 29 | }, 30 | "committer":{ 31 | "timestamp":"2018-11-13T20:20:39+00:00", 32 | "name":"Jane Doe", 33 | "email":"jane.doe@example.com" 34 | }, 35 | "message":"Initial commit" 36 | } 37 | ], 38 | "patches":[ 39 | { 40 | "type":"unofficial", 41 | "diff":{ 42 | "text":{ 43 | "contentType":"text/plain", 44 | "encoding":"base64", 45 | "content":"ZXhhbXBsZSBkaWZmIGhlcmU=" 46 | }, 47 | "url":"uri/to/changes.diff" 48 | }, 49 | "resolves":[ 50 | { 51 | "type":"enhancement", 52 | "id":"JIRA-17240", 53 | "description":"Great new feature that does something", 54 | "source":{ 55 | "name":"Acme Org", 56 | "url":"https://issues.acme.org/17240" 57 | } 58 | } 59 | ] 60 | }, 61 | { 62 | "type":"backport", 63 | "diff":{ 64 | "text":{ 65 | "contentType":"text/plain", 66 | "encoding":"base64", 67 | "content":"ZXhhbXBsZSBkaWZmIGhlcmU=" 68 | }, 69 | "url":"uri/to/changes.diff" 70 | }, 71 | "resolves":[ 72 | { 73 | "type":"security", 74 | "id":"CVE-2019-9997", 75 | "name":"CVE-2019-9997", 76 | "description":"Issue description here", 77 | "source":{ 78 | "name":"NVD", 79 | "url":"https://nvd.nist.gov/vuln/detail/CVE-2019-9997" 80 | }, 81 | "references":[ 82 | "http://some/other/site-1", 83 | "http://some/other/site-2" 84 | ] 85 | }, 86 | { 87 | "type":"defect", 88 | "id":"JIRA-874319", 89 | "description":"Description of fix here", 90 | "source":{ 91 | "name":"Example Org", 92 | "url":"https://issues.example.org/874319" 93 | }, 94 | "references":[ 95 | "http://some/other/site-1", 96 | "http://some/other/site-2" 97 | ] 98 | } 99 | ] 100 | } 101 | ] 102 | } 103 | } 104 | ] 105 | } 106 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-provenance.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat":"CycloneDX", 3 | "specVersion":"1.4", 4 | "serialNumber":"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version":1, 6 | "components":[ 7 | { 8 | "type":"library", 9 | "supplier":{ 10 | "name":"Example, Inc.", 11 | "url":[ 12 | "https://example.com", 13 | "https://example.net" 14 | ], 15 | "contact":[ 16 | { 17 | "name":"Example Support AMER Distribution", 18 | "email":"support@example.com", 19 | "phone":"800-555-1212" 20 | }, 21 | { 22 | "name":"Example Support APAC", 23 | "email":"support@apac.example.com" 24 | } 25 | ] 26 | }, 27 | "author":"Example Development Labs - Alpha Team", 28 | "publisher":"Example Development Labs", 29 | "group":"com.example", 30 | "name":"crypto-library", 31 | "version":"3.0.0", 32 | "swid":{ 33 | "tagId":"swidgen-5dcb79af-a1d2-61b3-34fd-536c53b08810_3.0.0", 34 | "name":"Crypto Library", 35 | "version":"3.0.0", 36 | "text":{ 37 | "contentType":"text/xml", 38 | "encoding":"base64", 39 | "content":"PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQ3J5cHRvIExpYnJhcnkiIHZlcnNpb249IjMuMC4wIiAKIHZlcnNpb25TY2hlbWU9Im11bHRpcGFydG51bWVyaWMiIAogdGFnSWQ9InN3aWRnZW4tNWRjYjc5YWYtYTFkMi02MWIzLTM0ZmQtNTM2YzUzYjA4ODEwXzMuMC4wIiAKIHhtbG5zPSJodHRwOi8vc3RhbmRhcmRzLmlzby5vcmcvaXNvLzE5NzcwLy0yLzIwMTUvc2NoZW1hLnhzZCI+IAogeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgCiB4c2k6c2NoZW1hTG9jYXRpb249Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS1jdXJyZW50L3NjaGVtYS54c2Qgc2NoZW1hLnhzZCIgPgogIDxNZXRhIGdlbmVyYXRvcj0iU1dJRCBUYWcgT25saW5lIEdlbmVyYXRvciB2MC4xIiAvPiAKICA8RW50aXR5IG5hbWU9IkV4YW1wbGUsIEluYy4iIHJlZ2lkPSJleGFtcGxlLmNvbSIgcm9sZT0idGFnQ3JlYXRvciIgLz4gCjwvU29mdHdhcmVJZGVudGl0eT4=" 40 | } 41 | }, 42 | "purl":"pkg:maven/com.example/crypto-library@3.0.0?repository_url=repo.example.com" 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-security-advisories.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version": 1, 6 | "components": [ 7 | { 8 | "type": "library", 9 | "group": "org.example", 10 | "name": "mylibrary", 11 | "version": "1.0.0", 12 | "cpe": "cpe:/a:example:mylibrary:1.0.0", 13 | "purl": "pkg:maven/org.example/mylibrary@1.0.0", 14 | "externalReferences": [ 15 | { 16 | "type": "advisories", 17 | "url": "https://example.org/security/advisories.json" 18 | } 19 | ] 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-service-defn.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat":"CycloneDX", 3 | "specVersion":"1.4", 4 | "serialNumber":"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version":1, 6 | "components":[ 7 | { 8 | "bom-ref":"pkg:npm/acme/component@1.0.0", 9 | "type":"library", 10 | "group":"com.acme", 11 | "name":"stock-java-client", 12 | "version":"1.0.12", 13 | "purl":"pkg:maven/com.acme/stock-java-client@1.0.12" 14 | } 15 | ], 16 | "services":[ 17 | { 18 | "bom-ref":"b2a46a4b-8367-4bae-9820-95557cfe03a8", 19 | "provider":{ 20 | "name":"Partner Org", 21 | "url":[ 22 | "https://partner.org" 23 | ], 24 | "contact":[ 25 | { 26 | "name":"Support", 27 | "email":"support@partner", 28 | "phone":"800-555-1212" 29 | } 30 | ] 31 | }, 32 | "group":"org.partner", 33 | "name":"Stock ticker service", 34 | "version":"2020-Q2", 35 | "description":"Provides real-time stock information", 36 | "endpoints":[ 37 | "https://partner.org/api/v1/lookup", 38 | "https://partner.org/api/v1/stock" 39 | ], 40 | "authenticated":true, 41 | "x-trust-boundary":true, 42 | "data":[ 43 | { 44 | "classification":"PII", 45 | "flow":"inbound" 46 | }, 47 | { 48 | "classification":"PIFI", 49 | "flow":"outbound" 50 | }, 51 | { 52 | "classification":"public", 53 | "flow":"bi-directional" 54 | } 55 | ], 56 | "licenses":[ 57 | { 58 | "license":{ 59 | "name":"Partner license" 60 | } 61 | } 62 | ], 63 | "externalReferences":[ 64 | { 65 | "type":"website", 66 | "url":"http://partner.org" 67 | }, 68 | { 69 | "type":"documentation", 70 | "url":"http://api.partner.org/swagger" 71 | } 72 | ] 73 | } 74 | ], 75 | "dependencies":[ 76 | { 77 | "ref":"pkg:maven/com.acme/stock-java-client@1.0.12", 78 | "dependsOn":[ 79 | "b2a46a4b-8367-4bae-9820-95557cfe03a8" 80 | ] 81 | } 82 | ] 83 | } 84 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-vulnerability-exploitability.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "version": 1, 5 | "vulnerabilities": [ 6 | { 7 | "id": "CVE-2018-7489", 8 | "source": { 9 | "name": "NVD", 10 | "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9997" 11 | }, 12 | "ratings": [ 13 | { 14 | "source": { 15 | "name": "NVD", 16 | "url": "https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector=AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H&version=3.0" 17 | }, 18 | "score": 9.8, 19 | "severity": "critical", 20 | "method": "CVSSv3", 21 | "vector": "AN/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" 22 | } 23 | ], 24 | "cwes": [ 25 | 184, 26 | 502 27 | ], 28 | "description": "FasterXML jackson-databind before 2.7.9.3, 2.8.x before 2.8.11.1 and 2.9.x before 2.9.5 allows unauthenticated remote code execution because of an incomplete fix for the CVE-2017-7525 deserialization flaw. This is exploitable by sending maliciously crafted JSON input to the readValue method of the ObjectMapper, bypassing a blacklist that is ineffective if the c3p0 libraries are available in the classpath.", 29 | "recommendation": "Upgrade com.fasterxml.jackson.core:jackson-databind to version 2.6.7.5, 2.8.11.1, 2.9.5 or higher.", 30 | "advisories": [ 31 | { 32 | "title": "GitHub Commit", 33 | "url": "https://github.com/FasterXML/jackson-databind/commit/6799f8f10cc78e9af6d443ed6982d00a13f2e7d2" 34 | }, 35 | { 36 | "title": "GitHub Issue", 37 | "url": "https://github.com/FasterXML/jackson-databind/issues/1931" 38 | } 39 | ], 40 | "created": "2021-01-01T00:00:00.000Z", 41 | "published": "2021-01-01T00:00:00.000Z", 42 | "updated": "2021-01-01T00:00:00.000Z", 43 | "analysis": { 44 | "state": "not_affected", 45 | "justification": "code_not_reachable", 46 | "response": [ 47 | "will_not_fix", 48 | "update" 49 | ], 50 | "detail": "An optional explanation of why the application is not affected by the vulnerable component." 51 | }, 52 | "affects": [ 53 | { 54 | "ref": "urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#jackson-databind-2.8.0" 55 | } 56 | ] 57 | } 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /examples/cyclonedx/usecases/cdx-use-case-vulnerability-remediation.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 5 | "version": 1, 6 | "components": [ 7 | { 8 | "type": "library", 9 | "group": "com.acme", 10 | "name": "sample-library", 11 | "version": "1.0.0", 12 | "pedigree": { 13 | "ancestors": [ 14 | { 15 | "type": "library", 16 | "group": "org.example", 17 | "name": "sample-library", 18 | "version": "1.0.0" 19 | } 20 | ], 21 | "commits": [ 22 | { 23 | "uid": "7638417db6d59f3c431d3e1f261cc637155684cd", 24 | "url": "https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd", 25 | "author": { 26 | "timestamp": "2018-11-13T20:20:39+00:00", 27 | "name": "John Doe", 28 | "email": "john.doe@example.com" 29 | }, 30 | "committer": { 31 | "timestamp": "2018-11-13T20:20:39+00:00", 32 | "name": "Jane Doe", 33 | "email": "jane.doe@example.com" 34 | }, 35 | "message": "Initial commit" 36 | } 37 | ], 38 | "patches": [ 39 | { 40 | "type": "backport", 41 | "diff": { 42 | "text": { 43 | "contentType": "text/plain", 44 | "encoding": "base64", 45 | "content": "ZXhhbXBsZSBkaWZmIGhlcmU=" 46 | }, 47 | "url": "uri/to/changes.diff" 48 | }, 49 | "resolves": [ 50 | { 51 | "type": "security", 52 | "id": "CVE-2019-9997", 53 | "name": "CVE-2019-9997", 54 | "description": "Issue description here", 55 | "source": { 56 | "name": "NVD", 57 | "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9997" 58 | }, 59 | "references": [ 60 | "http://some/other/site-1", 61 | "http://some/other/site-2" 62 | ] 63 | } 64 | ] 65 | } 66 | ] 67 | } 68 | } 69 | ] 70 | } 71 | -------------------------------------------------------------------------------- /examples/ibm/cra/cra-sbom.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "serialNumber": "urn:uuid:92a44fcf-1108-4b6f-8eb0-83b42d4f224e", 5 | "version": 1, 6 | "metadata": { 7 | "timestamp": "2022-09-07T20:20:56Z", 8 | "tools": [ 9 | { 10 | "vendor": "IBM", 11 | "name": "IBM Cloud Continuous Delivery - Code Risk Analyzer", 12 | "version": "1.0.1" 13 | } 14 | ], 15 | "component": { 16 | "type": "application", 17 | "name": "" 18 | } 19 | }, 20 | "components": [ 21 | { 22 | "bom-ref": "file:go.mod", 23 | "type": "file", 24 | "name": "go.mod", 25 | "version": "e38a8e2bdcf053a962fa71c03648e3e9715a9a4add091f45da6aedff564f601b", 26 | "purl": "go.mod", 27 | "properties": [ 28 | { 29 | "name": "ecosystem", 30 | "value": "golang" 31 | } 32 | ] 33 | }, 34 | { 35 | "bom-ref": "pkg:github.com/cpuguy83/go-md2man/v2@2.0.2", 36 | "type": "library", 37 | "name": "github.com/cpuguy83/go-md2man/v2", 38 | "version": "2.0.2", 39 | "licenses": [ 40 | { 41 | "license": { 42 | "id": "MIT" 43 | } 44 | } 45 | ], 46 | "properties": [ 47 | { 48 | "name": "ecosystem", 49 | "value": "golang" 50 | } 51 | ] 52 | }, 53 | { 54 | "bom-ref": "pkg:github.com/russross/blackfriday/v2@2.1.0", 55 | "type": "library", 56 | "name": "github.com/russross/blackfriday/v2", 57 | "version": "2.1.0", 58 | "licenses": [ 59 | { 60 | "license": { 61 | "name": "UNKNOWN" 62 | } 63 | } 64 | ], 65 | "properties": [ 66 | { 67 | "name": "ecosystem", 68 | "value": "golang" 69 | } 70 | ] 71 | }, 72 | { 73 | "bom-ref": "pkg:github.com/spf13/pflag@1.0.5", 74 | "type": "library", 75 | "name": "github.com/spf13/pflag", 76 | "version": "1.0.5", 77 | "licenses": [ 78 | { 79 | "license": { 80 | "id": "BSD-3-Clause" 81 | } 82 | } 83 | ], 84 | "properties": [ 85 | { 86 | "name": "ecosystem", 87 | "value": "golang" 88 | } 89 | ] 90 | }, 91 | { 92 | "bom-ref": "pkg:gopkg.in/yaml.v3@3.0.1", 93 | "type": "library", 94 | "name": "gopkg.in/yaml.v3", 95 | "version": "3.0.1", 96 | "licenses": [ 97 | { 98 | "license": { 99 | "id": "Apache-2.0" 100 | } 101 | }, 102 | { 103 | "license": { 104 | "id": "MIT" 105 | } 106 | } 107 | ], 108 | "properties": [ 109 | { 110 | "name": "ecosystem", 111 | "value": "golang" 112 | } 113 | ] 114 | } 115 | ], 116 | "dependencies": [ 117 | { 118 | "ref": "pkg:github.com/cpuguy83/go-md2man/v2@2.0.2", 119 | "dependsOn": [ 120 | "pkg:github.com/russross/blackfriday/v2@2.1.0" 121 | ] 122 | } 123 | ] 124 | } 125 | -------------------------------------------------------------------------------- /examples/spdx/README.md: -------------------------------------------------------------------------------- 1 | # SPDX examples 2 | 3 | For convenience, examples are copied locally from: 4 | - https://github.com/spdx/spdx-examples -------------------------------------------------------------------------------- /examples/spdx/example1/example1.json: -------------------------------------------------------------------------------- 1 | { 2 | "SPDXID" : "SPDXRef-DOCUMENT", 3 | "spdxVersion" : "SPDX-2.2", 4 | "creationInfo" : { 5 | "created" : "2021-08-26T01:46:00Z", 6 | "creators" : [ "Person: Steve Winslow (steve@swinslow.net)", "Tool: github.com/spdx/tools-golang/builder", "Tool: github.com/spdx/tools-golang/idsearcher" ] 7 | }, 8 | "name" : "hello", 9 | "dataLicense" : "CC0-1.0", 10 | "documentNamespace" : "https://swinslow.net/spdx-examples/example1/hello-v3", 11 | "documentDescribes" : [ "SPDXRef-Package-hello" ], 12 | "packages" : [ { 13 | "SPDXID" : "SPDXRef-Package-hello", 14 | "copyrightText" : "NOASSERTION", 15 | "downloadLocation" : "git+https://github.com/swinslow/spdx-examples.git#example1/content", 16 | "filesAnalyzed" : true, 17 | "hasFiles" : [ "SPDXRef-hello-binary", "SPDXRef-Makefile", "SPDXRef-hello-src" ], 18 | "licenseConcluded" : "GPL-3.0-or-later", 19 | "licenseDeclared" : "GPL-3.0-or-later", 20 | "licenseInfoFromFiles" : [ "GPL-3.0-or-later" ], 21 | "name" : "hello", 22 | "packageVerificationCode" : { 23 | "packageVerificationCodeValue" : "9d20237bb72087e87069f96afb41c6ca2fa2a342" 24 | } 25 | } ], 26 | "files" : [ { 27 | "SPDXID" : "SPDXRef-hello-binary", 28 | "checksums" : [ { 29 | "algorithm" : "SHA1", 30 | "checksumValue" : "20291a81ef065ff891b537b64d4fdccaf6f5ac02" 31 | }, { 32 | "algorithm" : "SHA256", 33 | "checksumValue" : "83a33ff09648bb5fc5272baca88cf2b59fd81ac4cc6817b86998136af368708e" 34 | }, { 35 | "algorithm" : "MD5", 36 | "checksumValue" : "08a12c966d776864cc1eb41fd03c3c3d" 37 | } ], 38 | "copyrightText" : "NOASSERTION", 39 | "fileName" : "/build/hello", 40 | "fileTypes" : [ "BINARY" ], 41 | "licenseConcluded" : "GPL-3.0-or-later", 42 | "licenseInfoInFiles" : [ "NOASSERTION" ] 43 | }, { 44 | "SPDXID" : "SPDXRef-hello-src", 45 | "checksums" : [ { 46 | "algorithm" : "SHA1", 47 | "checksumValue" : "20862a6d08391d07d09344029533ec644fac6b21" 48 | }, { 49 | "algorithm" : "SHA256", 50 | "checksumValue" : "b4e5ca56d1f9110ca94ed0bf4e6d9ac11c2186eb7cd95159c6fdb50e8db5a823" 51 | }, { 52 | "algorithm" : "MD5", 53 | "checksumValue" : "935054fe899ca782e11003bbae5e166c" 54 | } ], 55 | "copyrightText" : "Copyright Contributors to the spdx-examples project.", 56 | "fileName" : "/src/hello.c", 57 | "fileTypes" : [ "SOURCE" ], 58 | "licenseConcluded" : "GPL-3.0-or-later", 59 | "licenseInfoInFiles" : [ "GPL-3.0-or-later" ] 60 | }, { 61 | "SPDXID" : "SPDXRef-Makefile", 62 | "checksums" : [ { 63 | "algorithm" : "SHA1", 64 | "checksumValue" : "69a2e85696fff1865c3f0686d6c3824b59915c80" 65 | }, { 66 | "algorithm" : "SHA256", 67 | "checksumValue" : "5da19033ba058e322e21c90e6d6d859c90b1b544e7840859c12cae5da005e79c" 68 | }, { 69 | "algorithm" : "MD5", 70 | "checksumValue" : "559424589a4f3f75fd542810473d8bc1" 71 | } ], 72 | "copyrightText" : "NOASSERTION", 73 | "fileName" : "/src/Makefile", 74 | "fileTypes" : [ "SOURCE" ], 75 | "licenseConcluded" : "GPL-3.0-or-later", 76 | "licenseInfoInFiles" : [ "GPL-3.0-or-later" ] 77 | } ], 78 | "relationships" : [ { 79 | "spdxElementId" : "SPDXRef-DOCUMENT", 80 | "relatedSpdxElement" : "SPDXRef-Package-hello", 81 | "relationshipType" : "DESCRIBES" 82 | }, { 83 | "spdxElementId" : "SPDXRef-hello-binary", 84 | "relatedSpdxElement" : "SPDXRef-hello-src", 85 | "relationshipType" : "GENERATED_FROM" 86 | }, { 87 | "spdxElementId" : "SPDXRef-hello-binary", 88 | "relatedSpdxElement" : "SPDXRef-Makefile", 89 | "relationshipType" : "GENERATED_FROM" 90 | }, { 91 | "spdxElementId" : "SPDXRef-Makefile", 92 | "relatedSpdxElement" : "SPDXRef-Package-hello", 93 | "relationshipType" : "BUILD_TOOL_OF" 94 | } ] 95 | } -------------------------------------------------------------------------------- /examples/spdx/example1/example1.spdx: -------------------------------------------------------------------------------- 1 | SPDXVersion: SPDX-2.2 2 | DataLicense: CC0-1.0 3 | SPDXID: SPDXRef-DOCUMENT 4 | DocumentName: hello 5 | DocumentNamespace: https://swinslow.net/spdx-examples/example1/hello-v3 6 | Creator: Person: Steve Winslow (steve@swinslow.net) 7 | Creator: Tool: github.com/spdx/tools-golang/builder 8 | Creator: Tool: github.com/spdx/tools-golang/idsearcher 9 | Created: 2021-08-26T01:46:00Z 10 | 11 | ##### Package: hello 12 | 13 | PackageName: hello 14 | SPDXID: SPDXRef-Package-hello 15 | PackageDownloadLocation: git+https://github.com/swinslow/spdx-examples.git#example1/content 16 | FilesAnalyzed: true 17 | PackageVerificationCode: 9d20237bb72087e87069f96afb41c6ca2fa2a342 18 | PackageLicenseConcluded: GPL-3.0-or-later 19 | PackageLicenseInfoFromFiles: GPL-3.0-or-later 20 | PackageLicenseDeclared: GPL-3.0-or-later 21 | PackageCopyrightText: NOASSERTION 22 | 23 | Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-Package-hello 24 | 25 | FileName: /build/hello 26 | SPDXID: SPDXRef-hello-binary 27 | FileType: BINARY 28 | FileChecksum: SHA1: 20291a81ef065ff891b537b64d4fdccaf6f5ac02 29 | FileChecksum: SHA256: 83a33ff09648bb5fc5272baca88cf2b59fd81ac4cc6817b86998136af368708e 30 | FileChecksum: MD5: 08a12c966d776864cc1eb41fd03c3c3d 31 | LicenseConcluded: GPL-3.0-or-later 32 | LicenseInfoInFile: NOASSERTION 33 | FileCopyrightText: NOASSERTION 34 | 35 | FileName: /src/Makefile 36 | SPDXID: SPDXRef-Makefile 37 | FileType: SOURCE 38 | FileChecksum: SHA1: 69a2e85696fff1865c3f0686d6c3824b59915c80 39 | FileChecksum: SHA256: 5da19033ba058e322e21c90e6d6d859c90b1b544e7840859c12cae5da005e79c 40 | FileChecksum: MD5: 559424589a4f3f75fd542810473d8bc1 41 | LicenseConcluded: GPL-3.0-or-later 42 | LicenseInfoInFile: GPL-3.0-or-later 43 | FileCopyrightText: NOASSERTION 44 | 45 | FileName: /src/hello.c 46 | SPDXID: SPDXRef-hello-src 47 | FileType: SOURCE 48 | FileChecksum: SHA1: 20862a6d08391d07d09344029533ec644fac6b21 49 | FileChecksum: SHA256: b4e5ca56d1f9110ca94ed0bf4e6d9ac11c2186eb7cd95159c6fdb50e8db5a823 50 | FileChecksum: MD5: 935054fe899ca782e11003bbae5e166c 51 | LicenseConcluded: GPL-3.0-or-later 52 | LicenseInfoInFile: GPL-3.0-or-later 53 | FileCopyrightText: Copyright Contributors to the spdx-examples project. 54 | 55 | Relationship: SPDXRef-hello-binary GENERATED_FROM SPDXRef-hello-src 56 | Relationship: SPDXRef-hello-binary GENERATED_FROM SPDXRef-Makefile 57 | Relationship: SPDXRef-Makefile BUILD_TOOL_OF SPDXRef-Package-hello 58 | -------------------------------------------------------------------------------- /examples/spdx/example2/example2-bin.json: -------------------------------------------------------------------------------- 1 | { 2 | "SPDXID" : "SPDXRef-DOCUMENT", 3 | "spdxVersion" : "SPDX-2.2", 4 | "creationInfo" : { 5 | "created" : "2021-08-26T01:49:00Z", 6 | "creators" : [ "Person: Steve Winslow (steve@swinslow.net)", "Tool: github.com/spdx/tools-golang/builder", "Tool: github.com/spdx/tools-golang/idsearcher" ] 7 | }, 8 | "name" : "hello-bin", 9 | "dataLicense" : "CC0-1.0", 10 | "externalDocumentRefs" : [ { 11 | "externalDocumentId" : "DocumentRef-hello-src", 12 | "checksum" : { 13 | "algorithm" : "SHA1", 14 | "checksumValue" : "bb991e91fc62ce239d7baf30783c678506f9d17b" 15 | }, 16 | "spdxDocument" : "https://swinslow.net/spdx-examples/example2-hello-src-v3" 17 | } ], 18 | "documentNamespace" : "https://swinslow.net/spdx-examples/example2/hello-bin-v4", 19 | "documentDescribes" : [ "SPDXRef-Package-hello-bin" ], 20 | "packages" : [ { 21 | "SPDXID" : "SPDXRef-Package-hello-bin", 22 | "copyrightText" : "NOASSERTION", 23 | "downloadLocation" : "git+https://github.com/swinslow/spdx-examples.git#example2/content/build", 24 | "filesAnalyzed" : true, 25 | "hasFiles" : [ "SPDXRef-hello-binary" ], 26 | "licenseConcluded" : "GPL-3.0-or-later", 27 | "licenseDeclared" : "NOASSERTION", 28 | "licenseInfoFromFiles" : [ "NOASSERTION" ], 29 | "name" : "hello-bin", 30 | "packageVerificationCode" : { 31 | "packageVerificationCodeValue" : "d7aa17dad30d1d1d468a10ea1ec5e100e471c064" 32 | } 33 | } ], 34 | "files" : [ { 35 | "SPDXID" : "SPDXRef-hello-binary", 36 | "checksums" : [ { 37 | "algorithm" : "SHA1", 38 | "checksumValue" : "20291a81ef065ff891b537b64d4fdccaf6f5ac02" 39 | }, { 40 | "algorithm" : "SHA256", 41 | "checksumValue" : "83a33ff09648bb5fc5272baca88cf2b59fd81ac4cc6817b86998136af368708e" 42 | }, { 43 | "algorithm" : "MD5", 44 | "checksumValue" : "08a12c966d776864cc1eb41fd03c3c3d" 45 | } ], 46 | "copyrightText" : "NOASSERTION", 47 | "fileName" : "/hello", 48 | "fileTypes" : [ "BINARY" ], 49 | "licenseConcluded" : "GPL-3.0-or-later", 50 | "licenseInfoInFiles" : [ "NOASSERTION" ] 51 | } ], 52 | "relationships" : [ { 53 | "spdxElementId" : "SPDXRef-DOCUMENT", 54 | "relatedSpdxElement" : "SPDXRef-Package-hello-bin", 55 | "relationshipType" : "DESCRIBES" 56 | }, { 57 | "spdxElementId" : "SPDXRef-hello-binary", 58 | "relatedSpdxElement" : "DocumentRef-hello-src:SPDXRef-hello-src", 59 | "relationshipType" : "GENERATED_FROM" 60 | }, { 61 | "spdxElementId" : "SPDXRef-hello-binary", 62 | "relatedSpdxElement" : "DocumentRef-hello-src:SPDXRef-Makefile", 63 | "relationshipType" : "GENERATED_FROM" 64 | } ] 65 | } -------------------------------------------------------------------------------- /examples/spdx/example2/example2-bin.spdx: -------------------------------------------------------------------------------- 1 | SPDXVersion: SPDX-2.2 2 | DataLicense: CC0-1.0 3 | SPDXID: SPDXRef-DOCUMENT 4 | DocumentName: hello-bin 5 | DocumentNamespace: https://swinslow.net/spdx-examples/example2/hello-bin-v4 6 | ExternalDocumentRef:DocumentRef-hello-src https://swinslow.net/spdx-examples/example2-hello-src-v3 SHA1: bb991e91fc62ce239d7baf30783c678506f9d17b 7 | Creator: Person: Steve Winslow (steve@swinslow.net) 8 | Creator: Tool: github.com/spdx/tools-golang/builder 9 | Creator: Tool: github.com/spdx/tools-golang/idsearcher 10 | Created: 2021-08-26T01:49:00Z 11 | 12 | ##### Package: hello-bin 13 | 14 | PackageName: hello-bin 15 | SPDXID: SPDXRef-Package-hello-bin 16 | PackageDownloadLocation: git+https://github.com/swinslow/spdx-examples.git#example2/content/build 17 | FilesAnalyzed: true 18 | PackageVerificationCode: d7aa17dad30d1d1d468a10ea1ec5e100e471c064 19 | PackageLicenseConcluded: GPL-3.0-or-later 20 | PackageLicenseInfoFromFiles: NOASSERTION 21 | PackageLicenseDeclared: NOASSERTION 22 | PackageCopyrightText: NOASSERTION 23 | 24 | Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-Package-hello-bin 25 | 26 | FileName: /hello 27 | SPDXID: SPDXRef-hello-binary 28 | FileType: BINARY 29 | FileChecksum: SHA1: 20291a81ef065ff891b537b64d4fdccaf6f5ac02 30 | FileChecksum: SHA256: 83a33ff09648bb5fc5272baca88cf2b59fd81ac4cc6817b86998136af368708e 31 | FileChecksum: MD5: 08a12c966d776864cc1eb41fd03c3c3d 32 | LicenseConcluded: GPL-3.0-or-later 33 | LicenseInfoInFile: NOASSERTION 34 | FileCopyrightText: NOASSERTION 35 | 36 | ##### Relationships 37 | 38 | Relationship: SPDXRef-hello-binary GENERATED_FROM DocumentRef-hello-src:SPDXRef-hello-src 39 | Relationship: SPDXRef-hello-binary GENERATED_FROM DocumentRef-hello-src:SPDXRef-Makefile 40 | 41 | -------------------------------------------------------------------------------- /examples/spdx/example2/example2-src.json: -------------------------------------------------------------------------------- 1 | { 2 | "SPDXID" : "SPDXRef-DOCUMENT", 3 | "spdxVersion" : "SPDX-2.2", 4 | "creationInfo" : { 5 | "created" : "2021-08-26T01:47:00Z", 6 | "creators" : [ "Person: Steve Winslow (steve@swinslow.net)", "Tool: github.com/spdx/tools-golang/builder", "Tool: github.com/spdx/tools-golang/idsearcher" ] 7 | }, 8 | "name" : "hello-src", 9 | "dataLicense" : "CC0-1.0", 10 | "documentNamespace" : "https://swinslow.net/spdx-examples/example2/hello-src-v3", 11 | "documentDescribes" : [ "SPDXRef-Package-hello-src" ], 12 | "packages" : [ { 13 | "SPDXID" : "SPDXRef-Package-hello-src", 14 | "copyrightText" : "NOASSERTION", 15 | "downloadLocation" : "git+https://github.com/swinslow/spdx-examples.git#example2/content/src", 16 | "filesAnalyzed" : true, 17 | "hasFiles" : [ "SPDXRef-Makefile", "SPDXRef-hello-src" ], 18 | "licenseConcluded" : "NOASSERTION", 19 | "licenseDeclared" : "GPL-3.0-or-later", 20 | "licenseInfoFromFiles" : [ "GPL-3.0-or-later" ], 21 | "name" : "hello-src", 22 | "packageVerificationCode" : { 23 | "packageVerificationCodeValue" : "c6cb0949d7cd7439fce8690262a0946374824639" 24 | } 25 | } ], 26 | "files" : [ { 27 | "SPDXID" : "SPDXRef-Makefile", 28 | "checksums" : [ { 29 | "algorithm" : "SHA1", 30 | "checksumValue" : "69a2e85696fff1865c3f0686d6c3824b59915c80" 31 | }, { 32 | "algorithm" : "SHA256", 33 | "checksumValue" : "5da19033ba058e322e21c90e6d6d859c90b1b544e7840859c12cae5da005e79c" 34 | }, { 35 | "algorithm" : "MD5", 36 | "checksumValue" : "559424589a4f3f75fd542810473d8bc1" 37 | } ], 38 | "copyrightText" : "NOASSERTION", 39 | "fileName" : "/Makefile", 40 | "fileTypes" : [ "SOURCE" ], 41 | "licenseConcluded" : "GPL-3.0-or-later", 42 | "licenseInfoInFiles" : [ "GPL-3.0-or-later" ] 43 | }, { 44 | "SPDXID" : "SPDXRef-hello-src", 45 | "checksums" : [ { 46 | "algorithm" : "SHA1", 47 | "checksumValue" : "20862a6d08391d07d09344029533ec644fac6b21" 48 | }, { 49 | "algorithm" : "SHA256", 50 | "checksumValue" : "b4e5ca56d1f9110ca94ed0bf4e6d9ac11c2186eb7cd95159c6fdb50e8db5a823" 51 | }, { 52 | "algorithm" : "MD5", 53 | "checksumValue" : "935054fe899ca782e11003bbae5e166c" 54 | } ], 55 | "copyrightText" : "Copyright Contributors to the spdx-examples project.", 56 | "fileName" : "/hello.c", 57 | "fileTypes" : [ "SOURCE" ], 58 | "licenseConcluded" : "GPL-3.0-or-later", 59 | "licenseInfoInFiles" : [ "GPL-3.0-or-later" ] 60 | } ], 61 | "relationships" : [ { 62 | "spdxElementId" : "SPDXRef-DOCUMENT", 63 | "relatedSpdxElement" : "SPDXRef-Package-hello-src", 64 | "relationshipType" : "DESCRIBES" 65 | }, { 66 | "spdxElementId" : "SPDXRef-Makefile", 67 | "relatedSpdxElement" : "SPDXRef-Package-hello-src", 68 | "relationshipType" : "BUILD_TOOL_OF" 69 | } ] 70 | } -------------------------------------------------------------------------------- /examples/spdx/example2/example2-src.spdx: -------------------------------------------------------------------------------- 1 | SPDXVersion: SPDX-2.2 2 | DataLicense: CC0-1.0 3 | SPDXID: SPDXRef-DOCUMENT 4 | DocumentName: hello-src 5 | DocumentNamespace: https://swinslow.net/spdx-examples/example2/hello-src-v3 6 | Creator: Person: Steve Winslow (steve@swinslow.net) 7 | Creator: Tool: github.com/spdx/tools-golang/builder 8 | Creator: Tool: github.com/spdx/tools-golang/idsearcher 9 | Created: 2021-08-26T01:47:00Z 10 | 11 | ##### Package: hello-src 12 | 13 | PackageName: hello-src 14 | SPDXID: SPDXRef-Package-hello-src 15 | PackageDownloadLocation: git+https://github.com/swinslow/spdx-examples.git#example2/content/src 16 | FilesAnalyzed: true 17 | PackageVerificationCode: c6cb0949d7cd7439fce8690262a0946374824639 18 | PackageLicenseConcluded: NOASSERTION 19 | PackageLicenseInfoFromFiles: GPL-3.0-or-later 20 | PackageLicenseDeclared: GPL-3.0-or-later 21 | PackageCopyrightText: NOASSERTION 22 | 23 | Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-Package-hello-src 24 | 25 | FileName: /Makefile 26 | SPDXID: SPDXRef-Makefile 27 | FileType: SOURCE 28 | FileChecksum: SHA1: 69a2e85696fff1865c3f0686d6c3824b59915c80 29 | FileChecksum: SHA256: 5da19033ba058e322e21c90e6d6d859c90b1b544e7840859c12cae5da005e79c 30 | FileChecksum: MD5: 559424589a4f3f75fd542810473d8bc1 31 | LicenseConcluded: GPL-3.0-or-later 32 | LicenseInfoInFile: GPL-3.0-or-later 33 | FileCopyrightText: NOASSERTION 34 | 35 | FileName: /hello.c 36 | SPDXID: SPDXRef-hello-src 37 | FileType: SOURCE 38 | FileChecksum: SHA1: 20862a6d08391d07d09344029533ec644fac6b21 39 | FileChecksum: SHA256: b4e5ca56d1f9110ca94ed0bf4e6d9ac11c2186eb7cd95159c6fdb50e8db5a823 40 | FileChecksum: MD5: 935054fe899ca782e11003bbae5e166c 41 | LicenseConcluded: GPL-3.0-or-later 42 | LicenseInfoInFile: GPL-3.0-or-later 43 | FileCopyrightText: Copyright Contributors to the spdx-examples project. 44 | 45 | ##### Relationships 46 | 47 | Relationship: SPDXRef-Makefile BUILD_TOOL_OF SPDXRef-Package-hello-src 48 | 49 | -------------------------------------------------------------------------------- /examples/spdx/example5/README.md: -------------------------------------------------------------------------------- 1 | # Example 5 2 | 3 | ## Description 4 | 5 | ``` 6 | content 7 | ├── build 8 | │   └── hello 9 | └── src 10 | ├── Makefile 11 | └── hello.go 12 | ``` 13 | 14 | The content is identical to [example2](../example2), but in Go instead of C: one [Go source file](content/src/hello.go) with a simple "hello world" program, compiled into a [single binary](content/build/hello) with no dependencies via a [Makefile](content/src/Makefile). 15 | 16 | ## Comments 17 | 18 | This is intentionally a trivial example, and the SPDX files are essentially identical to those of [example2](../example2). 19 | Subsequent examples will build upon this to add more detail to this simple case. 20 | -------------------------------------------------------------------------------- /examples/spdx/example5/example5-bin.json: -------------------------------------------------------------------------------- 1 | { 2 | "SPDXID" : "SPDXRef-DOCUMENT", 3 | "spdxVersion" : "SPDX-2.2", 4 | "creationInfo" : { 5 | "created" : "2021-08-26T01:54:00Z", 6 | "creators" : [ "Person: Steve Winslow (steve@swinslow.net)", "Tool: github.com/spdx/tools-golang/builder", "Tool: github.com/spdx/tools-golang/idsearcher" ] 7 | }, 8 | "name" : "hello-go-bin", 9 | "dataLicense" : "CC0-1.0", 10 | "externalDocumentRefs" : [ { 11 | "externalDocumentId" : "DocumentRef-hello-go-src", 12 | "checksum" : { 13 | "algorithm" : "SHA1", 14 | "checksumValue" : "c7ecde060983373ace6ff9cfd1ddc7ccd5ce5e29" 15 | }, 16 | "spdxDocument" : "https://swinslow.net/spdx-examples/example5/hello-go-src-v2" 17 | } ], 18 | "documentNamespace" : "https://swinslow.net/spdx-examples/example5/hello-go-bin-v2", 19 | "documentDescribes" : [ "SPDXRef-Package-hello-go-bin" ], 20 | "packages" : [ { 21 | "SPDXID" : "SPDXRef-Package-hello-go-bin", 22 | "copyrightText" : "NOASSERTION", 23 | "downloadLocation" : "git+https://github.com/swinslow/spdx-examples.git#example5/content/build", 24 | "filesAnalyzed" : true, 25 | "hasFiles" : [ "SPDXRef-hello-go-binary" ], 26 | "licenseConcluded" : "GPL-3.0-or-later", 27 | "licenseDeclared" : "NOASSERTION", 28 | "licenseInfoFromFiles" : [ "NOASSERTION" ], 29 | "name" : "hello-go-bin", 30 | "packageVerificationCode" : { 31 | "packageVerificationCodeValue" : "41acac4b846ee388cb6c1234f04489ccd5daa5a5" 32 | } 33 | } ], 34 | "files" : [ { 35 | "SPDXID" : "SPDXRef-hello-go-binary", 36 | "checksums" : [ { 37 | "algorithm" : "SHA1", 38 | "checksumValue" : "78ed46e8e6f86f19d3a6782979029be5f918235f" 39 | }, { 40 | "algorithm" : "SHA256", 41 | "checksumValue" : "3d51cb6c9a38d437e8ee20a1902a15875ea1d3771a215622e14739532be14949" 42 | }, { 43 | "algorithm" : "MD5", 44 | "checksumValue" : "9ec63d68bdceb2922548e3faa377e7d0" 45 | } ], 46 | "copyrightText" : "NOASSERTION", 47 | "fileName" : "/hello", 48 | "licenseConcluded" : "GPL-3.0-or-later", 49 | "licenseInfoInFiles" : [ "NOASSERTION" ] 50 | } ], 51 | "relationships" : [ { 52 | "spdxElementId" : "SPDXRef-DOCUMENT", 53 | "relatedSpdxElement" : "SPDXRef-Package-hello-go-bin", 54 | "relationshipType" : "DESCRIBES" 55 | }, { 56 | "spdxElementId" : "SPDXRef-hello-go-binary", 57 | "relatedSpdxElement" : "DocumentRef-hello-go-src:SPDXRef-hello-go-src", 58 | "relationshipType" : "GENERATED_FROM" 59 | }, { 60 | "spdxElementId" : "SPDXRef-hello-go-binary", 61 | "relatedSpdxElement" : "DocumentRef-hello-go-src:SPDXRef-Makefile", 62 | "relationshipType" : "GENERATED_FROM" 63 | } ] 64 | } -------------------------------------------------------------------------------- /examples/spdx/example5/example5-bin.spdx: -------------------------------------------------------------------------------- 1 | SPDXVersion: SPDX-2.2 2 | DataLicense: CC0-1.0 3 | SPDXID: SPDXRef-DOCUMENT 4 | DocumentName: hello-go-bin 5 | DocumentNamespace: https://swinslow.net/spdx-examples/example5/hello-go-bin-v2 6 | ExternalDocumentRef:DocumentRef-hello-go-src https://swinslow.net/spdx-examples/example5/hello-go-src-v2 SHA1: c7ecde060983373ace6ff9cfd1ddc7ccd5ce5e29 7 | Creator: Person: Steve Winslow (steve@swinslow.net) 8 | Creator: Tool: github.com/spdx/tools-golang/builder 9 | Creator: Tool: github.com/spdx/tools-golang/idsearcher 10 | Created: 2021-08-26T01:54:00Z 11 | 12 | ##### Package: hello-go-bin 13 | 14 | PackageName: hello-go-bin 15 | SPDXID: SPDXRef-Package-hello-go-bin 16 | PackageDownloadLocation: git+https://github.com/swinslow/spdx-examples.git#example5/content/build 17 | FilesAnalyzed: true 18 | PackageVerificationCode: 41acac4b846ee388cb6c1234f04489ccd5daa5a5 19 | PackageLicenseConcluded: GPL-3.0-or-later 20 | PackageLicenseInfoFromFiles: NOASSERTION 21 | PackageLicenseDeclared: NOASSERTION 22 | PackageCopyrightText: NOASSERTION 23 | 24 | Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-Package-hello-go-bin 25 | 26 | FileName: /hello 27 | SPDXID: SPDXRef-hello-go-binary 28 | FileChecksum: SHA1: 78ed46e8e6f86f19d3a6782979029be5f918235f 29 | FileChecksum: SHA256: 3d51cb6c9a38d437e8ee20a1902a15875ea1d3771a215622e14739532be14949 30 | FileChecksum: MD5: 9ec63d68bdceb2922548e3faa377e7d0 31 | LicenseConcluded: GPL-3.0-or-later 32 | LicenseInfoInFile: NOASSERTION 33 | FileCopyrightText: NOASSERTION 34 | 35 | ##### Relationships 36 | 37 | Relationship: SPDXRef-hello-go-binary GENERATED_FROM DocumentRef-hello-go-src:SPDXRef-hello-go-src 38 | Relationship: SPDXRef-hello-go-binary GENERATED_FROM DocumentRef-hello-go-src:SPDXRef-Makefile 39 | 40 | -------------------------------------------------------------------------------- /examples/spdx/example5/example5-src.json: -------------------------------------------------------------------------------- 1 | { 2 | "SPDXID" : "SPDXRef-DOCUMENT", 3 | "spdxVersion" : "SPDX-2.2", 4 | "creationInfo" : { 5 | "created" : "2021-08-26T01:53:00Z", 6 | "creators" : [ "Person: Steve Winslow (steve@swinslow.net)", "Tool: github.com/spdx/tools-golang/builder", "Tool: github.com/spdx/tools-golang/idsearcher" ] 7 | }, 8 | "name" : "hello-go-src", 9 | "dataLicense" : "CC0-1.0", 10 | "documentNamespace" : "https://swinslow.net/spdx-examples/example5/hello-go-src-v2", 11 | "documentDescribes" : [ "SPDXRef-Package-hello-go-src" ], 12 | "packages" : [ { 13 | "SPDXID" : "SPDXRef-Package-hello-go-src", 14 | "copyrightText" : "NOASSERTION", 15 | "downloadLocation" : "git+https://github.com/swinslow/spdx-examples.git#example5/content/src", 16 | "filesAnalyzed" : true, 17 | "hasFiles" : [ "SPDXRef-Makefile", "SPDXRef-hello-go-src" ], 18 | "licenseConcluded" : "NOASSERTION", 19 | "licenseDeclared" : "GPL-3.0-or-later", 20 | "licenseInfoFromFiles" : [ "GPL-3.0-or-later" ], 21 | "name" : "hello-go-src", 22 | "packageVerificationCode" : { 23 | "packageVerificationCodeValue" : "6486e016b01e9ec8a76998cefd0705144d869234" 24 | } 25 | } ], 26 | "files" : [ { 27 | "SPDXID" : "SPDXRef-hello-go-src", 28 | "checksums" : [ { 29 | "algorithm" : "SHA1", 30 | "checksumValue" : "bb5ae27c76cd4332edd0da834eb4bd8a7c31ca93" 31 | }, { 32 | "algorithm" : "SHA256", 33 | "checksumValue" : "1ce078bb915470348fcf481198b8ab1cdb7d36481564959387153e8d4cd1bbf2" 34 | }, { 35 | "algorithm" : "MD5", 36 | "checksumValue" : "7f4170f33ec5c81492785e1147dfd3af" 37 | } ], 38 | "copyrightText" : "NOASSERTION", 39 | "fileName" : "/hello.go", 40 | "licenseConcluded" : "GPL-3.0-or-later", 41 | "licenseInfoInFiles" : [ "GPL-3.0-or-later" ] 42 | }, { 43 | "SPDXID" : "SPDXRef-Makefile", 44 | "checksums" : [ { 45 | "algorithm" : "SHA1", 46 | "checksumValue" : "5cb1c1c76bd0694fe5be2774c7df8166f52498a0" 47 | }, { 48 | "algorithm" : "SHA256", 49 | "checksumValue" : "23ffc10f988297282e29b32e9c520fd33b4122a487ccaa74c979d225181aa8bf" 50 | }, { 51 | "algorithm" : "MD5", 52 | "checksumValue" : "7c1236d86a868a5762ba16274339c0f8" 53 | } ], 54 | "copyrightText" : "NOASSERTION", 55 | "fileName" : "/Makefile", 56 | "licenseConcluded" : "GPL-3.0-or-later", 57 | "licenseInfoInFiles" : [ "GPL-3.0-or-later" ] 58 | } ], 59 | "relationships" : [ { 60 | "spdxElementId" : "SPDXRef-DOCUMENT", 61 | "relatedSpdxElement" : "SPDXRef-Package-hello-go-src", 62 | "relationshipType" : "DESCRIBES" 63 | }, { 64 | "spdxElementId" : "SPDXRef-Makefile", 65 | "relatedSpdxElement" : "SPDXRef-Package-hello-go-src", 66 | "relationshipType" : "BUILD_TOOL_OF" 67 | } ] 68 | } -------------------------------------------------------------------------------- /examples/spdx/example5/example5-src.spdx: -------------------------------------------------------------------------------- 1 | SPDXVersion: SPDX-2.2 2 | DataLicense: CC0-1.0 3 | SPDXID: SPDXRef-DOCUMENT 4 | DocumentName: hello-go-src 5 | DocumentNamespace: https://swinslow.net/spdx-examples/example5/hello-go-src-v2 6 | Creator: Person: Steve Winslow (steve@swinslow.net) 7 | Creator: Tool: github.com/spdx/tools-golang/builder 8 | Creator: Tool: github.com/spdx/tools-golang/idsearcher 9 | Created: 2021-08-26T01:53:00Z 10 | 11 | ##### Package: hello-go-src 12 | 13 | PackageName: hello-go-src 14 | SPDXID: SPDXRef-Package-hello-go-src 15 | PackageDownloadLocation: git+https://github.com/swinslow/spdx-examples.git#example5/content/src 16 | FilesAnalyzed: true 17 | PackageVerificationCode: 6486e016b01e9ec8a76998cefd0705144d869234 18 | PackageLicenseConcluded: NOASSERTION 19 | PackageLicenseInfoFromFiles: GPL-3.0-or-later 20 | PackageLicenseDeclared: GPL-3.0-or-later 21 | PackageCopyrightText: NOASSERTION 22 | 23 | Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-Package-hello-go-src 24 | 25 | FileName: /Makefile 26 | SPDXID: SPDXRef-Makefile 27 | FileChecksum: SHA1: 5cb1c1c76bd0694fe5be2774c7df8166f52498a0 28 | FileChecksum: SHA256: 23ffc10f988297282e29b32e9c520fd33b4122a487ccaa74c979d225181aa8bf 29 | FileChecksum: MD5: 7c1236d86a868a5762ba16274339c0f8 30 | LicenseConcluded: GPL-3.0-or-later 31 | LicenseInfoInFile: GPL-3.0-or-later 32 | FileCopyrightText: NOASSERTION 33 | 34 | FileName: /hello.go 35 | SPDXID: SPDXRef-hello-go-src 36 | FileChecksum: SHA1: bb5ae27c76cd4332edd0da834eb4bd8a7c31ca93 37 | FileChecksum: SHA256: 1ce078bb915470348fcf481198b8ab1cdb7d36481564959387153e8d4cd1bbf2 38 | FileChecksum: MD5: 7f4170f33ec5c81492785e1147dfd3af 39 | LicenseConcluded: GPL-3.0-or-later 40 | LicenseInfoInFile: GPL-3.0-or-later 41 | FileCopyrightText: NOASSERTION 42 | 43 | ##### Relationships 44 | 45 | Relationship: SPDXRef-Makefile BUILD_TOOL_OF SPDXRef-Package-hello-go-src 46 | 47 | -------------------------------------------------------------------------------- /examples/spdx/example6/example6-src.json: -------------------------------------------------------------------------------- 1 | { 2 | "SPDXID" : "SPDXRef-DOCUMENT", 3 | "spdxVersion" : "SPDX-2.2", 4 | "creationInfo" : { 5 | "created" : "2021-08-26T01:55:30Z", 6 | "creators" : [ "Person: Steve Winslow (steve@swinslow.net)", "Tool: github.com/spdx/tools-golang/builder", "Tool: github.com/spdx/tools-golang/idsearcher" ] 7 | }, 8 | "name" : "hello-go-src", 9 | "dataLicense" : "CC0-1.0", 10 | "documentNamespace" : "https://swinslow.net/spdx-examples/example6/hello-go-src-v2", 11 | "documentDescribes" : [ "SPDXRef-Package-hello-go-src" ], 12 | "packages" : [ { 13 | "SPDXID" : "SPDXRef-Package-hello-go-src", 14 | "copyrightText" : "NOASSERTION", 15 | "downloadLocation" : "git+https://github.com/swinslow/spdx-examples.git#example6/content/src", 16 | "filesAnalyzed" : true, 17 | "hasFiles" : [ "SPDXRef-Makefile", "SPDXRef-hello-go-src" ], 18 | "licenseConcluded" : "NOASSERTION", 19 | "licenseDeclared" : "GPL-3.0-or-later", 20 | "licenseInfoFromFiles" : [ "GPL-3.0-or-later" ], 21 | "name" : "hello-go-src", 22 | "packageVerificationCode" : { 23 | "packageVerificationCodeValue" : "6486e016b01e9ec8a76998cefd0705144d869234" 24 | } 25 | } ], 26 | "files" : [ { 27 | "SPDXID" : "SPDXRef-hello-go-src", 28 | "checksums" : [ { 29 | "algorithm" : "SHA1", 30 | "checksumValue" : "bb5ae27c76cd4332edd0da834eb4bd8a7c31ca93" 31 | }, { 32 | "algorithm" : "SHA256", 33 | "checksumValue" : "1ce078bb915470348fcf481198b8ab1cdb7d36481564959387153e8d4cd1bbf2" 34 | }, { 35 | "algorithm" : "MD5", 36 | "checksumValue" : "7f4170f33ec5c81492785e1147dfd3af" 37 | } ], 38 | "copyrightText" : "NOASSERTION", 39 | "fileName" : "/hello.go", 40 | "licenseConcluded" : "GPL-3.0-or-later", 41 | "licenseInfoInFiles" : [ "GPL-3.0-or-later" ] 42 | }, { 43 | "SPDXID" : "SPDXRef-Makefile", 44 | "checksums" : [ { 45 | "algorithm" : "SHA1", 46 | "checksumValue" : "5cb1c1c76bd0694fe5be2774c7df8166f52498a0" 47 | }, { 48 | "algorithm" : "SHA256", 49 | "checksumValue" : "23ffc10f988297282e29b32e9c520fd33b4122a487ccaa74c979d225181aa8bf" 50 | }, { 51 | "algorithm" : "MD5", 52 | "checksumValue" : "7c1236d86a868a5762ba16274339c0f8" 53 | } ], 54 | "copyrightText" : "NOASSERTION", 55 | "fileName" : "/Makefile", 56 | "licenseConcluded" : "GPL-3.0-or-later", 57 | "licenseInfoInFiles" : [ "GPL-3.0-or-later" ] 58 | } ], 59 | "relationships" : [ { 60 | "spdxElementId" : "SPDXRef-DOCUMENT", 61 | "relatedSpdxElement" : "SPDXRef-Package-hello-go-src", 62 | "relationshipType" : "DESCRIBES" 63 | }, { 64 | "spdxElementId" : "SPDXRef-Makefile", 65 | "relatedSpdxElement" : "SPDXRef-Package-hello-go-src", 66 | "relationshipType" : "BUILD_TOOL_OF" 67 | } ] 68 | } -------------------------------------------------------------------------------- /examples/spdx/example6/example6-src.spdx: -------------------------------------------------------------------------------- 1 | SPDXVersion: SPDX-2.2 2 | DataLicense: CC0-1.0 3 | SPDXID: SPDXRef-DOCUMENT 4 | DocumentName: hello-go-src 5 | DocumentNamespace: https://swinslow.net/spdx-examples/example6/hello-go-src-v2 6 | Creator: Person: Steve Winslow (steve@swinslow.net) 7 | Creator: Tool: github.com/spdx/tools-golang/builder 8 | Creator: Tool: github.com/spdx/tools-golang/idsearcher 9 | Created: 2021-08-26T01:55:30Z 10 | 11 | ##### Package: hello-go-src 12 | 13 | PackageName: hello-go-src 14 | SPDXID: SPDXRef-Package-hello-go-src 15 | PackageDownloadLocation: git+https://github.com/swinslow/spdx-examples.git#example6/content/src 16 | FilesAnalyzed: true 17 | PackageVerificationCode: 6486e016b01e9ec8a76998cefd0705144d869234 18 | PackageLicenseConcluded: NOASSERTION 19 | PackageLicenseInfoFromFiles: GPL-3.0-or-later 20 | PackageLicenseDeclared: GPL-3.0-or-later 21 | PackageCopyrightText: NOASSERTION 22 | 23 | Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-Package-hello-go-src 24 | 25 | FileName: /Makefile 26 | SPDXID: SPDXRef-Makefile 27 | FileChecksum: SHA1: 5cb1c1c76bd0694fe5be2774c7df8166f52498a0 28 | FileChecksum: SHA256: 23ffc10f988297282e29b32e9c520fd33b4122a487ccaa74c979d225181aa8bf 29 | FileChecksum: MD5: 7c1236d86a868a5762ba16274339c0f8 30 | LicenseConcluded: GPL-3.0-or-later 31 | LicenseInfoInFile: GPL-3.0-or-later 32 | FileCopyrightText: NOASSERTION 33 | 34 | FileName: /hello.go 35 | SPDXID: SPDXRef-hello-go-src 36 | FileChecksum: SHA1: bb5ae27c76cd4332edd0da834eb4bd8a7c31ca93 37 | FileChecksum: SHA256: 1ce078bb915470348fcf481198b8ab1cdb7d36481564959387153e8d4cd1bbf2 38 | FileChecksum: MD5: 7f4170f33ec5c81492785e1147dfd3af 39 | LicenseConcluded: GPL-3.0-or-later 40 | LicenseInfoInFile: GPL-3.0-or-later 41 | FileCopyrightText: NOASSERTION 42 | 43 | ##### Relationships 44 | 45 | Relationship: SPDXRef-Makefile BUILD_TOOL_OF SPDXRef-Package-hello-go-src 46 | 47 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ibm/sbom-utility 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/fatih/color v1.14.1 7 | github.com/hokaccha/go-prettyjson v0.0.0-20211117102719-0474bc63780f 8 | github.com/jwangsadinata/go-multimap v0.0.0-20190620162914-c29f3d7f33b6 9 | github.com/spf13/cobra v1.6.1 10 | github.com/stretchr/testify v1.8.1 11 | github.com/xeipuuv/gojsonschema v1.2.0 12 | ) 13 | 14 | require ( 15 | github.com/davecgh/go-spew v1.1.1 // indirect 16 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 17 | github.com/kr/pretty v0.1.0 // indirect 18 | github.com/mattn/go-colorable v0.1.13 // indirect 19 | github.com/mattn/go-isatty v0.0.17 // indirect 20 | github.com/pmezard/go-difflib v1.0.0 // indirect 21 | github.com/spf13/pflag v1.0.5 // indirect 22 | github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect 23 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect 24 | golang.org/x/sys v0.4.0 // indirect 25 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect 26 | gopkg.in/yaml.v3 v3.0.1 // indirect 27 | ) 28 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 4 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= 6 | github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= 7 | github.com/hokaccha/go-prettyjson v0.0.0-20211117102719-0474bc63780f h1:7LYC+Yfkj3CTRcShK0KOL/w6iTiKyqqBA9a41Wnggw8= 8 | github.com/hokaccha/go-prettyjson v0.0.0-20211117102719-0474bc63780f/go.mod h1:pFlLw2CfqZiIBOx6BuCeRLCrfxBJipTY0nIOF/VbGcI= 9 | github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 10 | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= 11 | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 12 | github.com/jwangsadinata/go-multimap v0.0.0-20190620162914-c29f3d7f33b6 h1:OzCtZaD1uI5Fc1C+4oNAp7kZ4ibh5OIgxI29moH/IbE= 13 | github.com/jwangsadinata/go-multimap v0.0.0-20190620162914-c29f3d7f33b6/go.mod h1:CEusGbCRDFcHX9EgEhPsgJX33kpp9CfSFRBAoSGOems= 14 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 15 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 16 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 17 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 18 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 19 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 20 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 21 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 22 | github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= 23 | github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 24 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 25 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 26 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 27 | github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= 28 | github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= 29 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 30 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 31 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 32 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 33 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 34 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 35 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 36 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 37 | github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= 38 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 39 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= 40 | github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= 41 | github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= 42 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= 43 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= 44 | github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= 45 | github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= 46 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 47 | golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= 48 | golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 49 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 50 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 51 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 52 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 53 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 54 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 55 | -------------------------------------------------------------------------------- /ibm-requirements.md: -------------------------------------------------------------------------------- 1 | [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) 2 | 3 | # sbom-utility 4 | 5 | ## IBM SBOM Requirements 6 | 7 | Requirements for tests come from the IBM SBOM Working Group. The group uses the following repository to develop its canonical documentation and track ongoing work and issues: 8 | 9 | - https://github.ibm.com/Supply-Chain-Security/ibm-sbom 10 | 11 | The goal of the tests is to assure that all documented requirements are enforceable by the validation command the `sbom-utility`. 12 | 13 | All requirements appear as subsections under the heading [IBM SBOM requirements](https://github.ibm.com/Supply-Chain-Security/ibm-sbom/blob/master/README.md#ibm-sbom-requirements) and are organized as follows: 14 | 15 | - [IBM SBOM requirements]( https://github.ibm.com/Supply-Chain-Security/ibm-sbom/blob/master/README.md#ibm-sbom-requirements) 16 | - [NTIA minimum required data](https://github.ibm.com/Supply-Chain-Security/ibm-sbom/blob/master/README.md#ntia-minimum-required-data) 17 | - [IBM required and optional data](https://github.ibm.com/Supply-Chain-Security/ibm-sbom/blob/master/README.md#ibm-required-and-optional-data) 18 | 19 | Specifically, most of the requirements have been mapped by the group to CycloneDX here: 20 | 21 | - [IBM SBOM CycloneDX Schema requirements](https://github.ibm.com/Supply-Chain-Security/ibm-sbom/blob/master/ibm-sbom-schema-cdx-requirements.md) 22 | 23 | However, JSON schema cannot currently encode all requirements which we group here under the term "compositional". 24 | 25 | --- 26 | 27 | ### IBM custom test groupings 28 | 29 | - [IBM custom schema tests](#ibm-custom-schema-tests) - ensure the `sbom-utility` can validate "custom" schema requirements and consistently report errors 30 | - [IBM custom composition tests](#ibm-custom-composition-tests) - ensure the `sbom-utility` can validate "custom" schema requirements and consistently report errors 31 | 32 | #### IBM custom schema tests 33 | 34 | | Property | Required | Constraint | Test name | Test input file | 35 | | :-- | :-- | :-- | :-- | :-- | 36 | | `specVersion` | Y | `"enum": ["1.3", "1.4"]` | TODO | | 37 | | `version` | Y | `"minimum": 1, "maximum": 1` | TODO | | 38 | | `serialNumber` | Y | `"pattern": "^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"` | TODO | | 39 | | `metadata` | Y | N/A| TODO| | 40 | | `components` | N | `"minItems": 1`, `"uniqueItems": true` (default)| TODO | | 41 | | `services` | N | `"minItems": 1`, `"uniqueItems": true` (default)| TODO | | 42 | | `dependencies` | N | `"minItems": 1`, `"uniqueItems": true` (default)| TODO | | 43 | | `compositions` | N | `"minItems": 1`, `"uniqueItems": true` (default)| TODO | | 44 | | | | | | 45 | 46 | #### IBM custom composition tests 47 | 48 | | Property | Required | Constraint | Test name | Test input file | 49 | | :-- | :-- | :-- | :-- | :-- | 50 | | | | | | 51 | -------------------------------------------------------------------------------- /log/log_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package log 19 | 20 | import ( 21 | "testing" 22 | 23 | "github.com/stretchr/testify/assert" 24 | ) 25 | 26 | // Test constructors 27 | func TestNewDefaultLogger(t *testing.T) { 28 | logger := NewDefaultLogger() 29 | assert.NotNil(t, logger) 30 | } 31 | 32 | func TestNewLogger(t *testing.T) { 33 | logger := NewLogger(TRACE) 34 | assert.NotNil(t, logger) 35 | } 36 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package main 19 | 20 | import ( 21 | "fmt" 22 | "os" 23 | "path/filepath" 24 | "runtime" 25 | 26 | "github.com/ibm/sbom-utility/cmd" 27 | "github.com/ibm/sbom-utility/log" 28 | "github.com/ibm/sbom-utility/schema" 29 | "github.com/ibm/sbom-utility/utils" 30 | ) 31 | 32 | // Struct used to hold tagged (release) build information 33 | // Which is displayed by the `version` command. 34 | // These values can be overwritten by `go build ${LDFLAGS}` 35 | // for example, LDFLAGS=-ldflags "-X main.Version=${VERSION} 36 | var ( 37 | // public 38 | Project = "sbom-utility" 39 | Binary = "unset" 40 | Version = "x.y.z" 41 | Logger *log.MiniLogger 42 | 43 | // Default configurations 44 | DefaultLogLevel = log.INFO 45 | ) 46 | 47 | func init() { 48 | // Create logger at the earliest 49 | // NOTE: This logger will not apply to `go test` as package "main" will not be loaded 50 | Logger = log.NewLogger(DefaultLogLevel) 51 | 52 | // Check for log-related flags (anywhere) and apply to logger 53 | // as early as possible (before customary Cobra flag formalization) 54 | // NOTE: the last log-level flag found, in order of appearance "wins" 55 | // Set default log level and turn "quiet mode" off 56 | Logger.InitLogLevelAndModeFromFlags() 57 | 58 | // Emit log level used from this point forward 59 | Logger.Tracef("Logger (%T) created: with Level=`%v`", Logger, Logger.GetLevelName()) 60 | 61 | // Provide access to project logger to other modules 62 | cmd.ProjectLogger = Logger 63 | schema.ProjectLogger = Logger 64 | 65 | // Copy program package vars into command flags 66 | utils.GlobalFlags.Project = Project 67 | utils.GlobalFlags.Binary = Binary 68 | utils.GlobalFlags.Version = Version 69 | 70 | // Capture working directory 71 | utils.GlobalFlags.WorkingDir, _ = os.Getwd() 72 | 73 | // Set the executable directory path 74 | execNameWithPath, err := os.Executable() 75 | if err == nil { 76 | utils.GlobalFlags.ExecDir = filepath.Dir(execNameWithPath) 77 | } 78 | } 79 | 80 | func printWelcome() { 81 | if !Logger.QuietModeOn() { 82 | goos := fmt.Sprintf("(%s/%s)", runtime.GOOS, runtime.GOARCH) 83 | echo := fmt.Sprintf("Welcome to the %s! Version `%s` (%s) %s\n", Project, Version, Binary, goos) 84 | // Logger will only print the welcome if log level requested indicates INFO level (or higher) 85 | Logger.DumpString(echo) 86 | // Show intent to not check for error returns as there is no recovery 87 | _, _ = Logger.DumpSeparator('=', len(echo)-1) 88 | } 89 | } 90 | 91 | func main() { 92 | Logger.Enter() 93 | defer Logger.Exit() 94 | printWelcome() 95 | // Use Cobra convention and execute top-level command 96 | cmd.Execute() 97 | } 98 | -------------------------------------------------------------------------------- /resources/resources.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package resources 19 | 20 | import ( 21 | "embed" 22 | ) 23 | 24 | // Embed the JSON schema files used to validate SBOMs 25 | //go:embed schema 26 | var SBOMSchemaFiles embed.FS 27 | -------------------------------------------------------------------------------- /resources/schema/cyclonedx/README.md: -------------------------------------------------------------------------------- 1 | 19 | 20 | ## CycloneDX schemas 21 | 22 | For convenience, schemas are copied locally from: 23 | - https://github.com/CycloneDX/specification/tree/master/schema 24 | 25 | ### Supported releases 26 | 27 | | release tag (variant) | branch | schema file (git format) | 28 | | :-- | :-- | :-- | 29 | | [1.4](https://github.com/CycloneDX/specification/releases/tag/1.4) | https://github.com/CycloneDX/specification (master) | https://github.com/CycloneDX/specification/blob/master/schema/bom-1.4.schema.json | 30 | | [1.3](https://github.com/CycloneDX/specification/releases/tag/1.3) | https://github.com/CycloneDX/specification (master) | https://github.com/CycloneDX/specification/blob/master/schema/bom-1.3.schema.json | 31 | | [1.3 (strict)](https://github.com/CycloneDX/specification/releases/tag/1.3) | https://github.com/CycloneDX/specification (master) | https://github.com/CycloneDX/specification/blob/master/schema/bom-1.3-strict.schema.json | 32 | | [1.2](https://github.com/CycloneDX/specification/releases/tag/1.2) | https://github.com/CycloneDX/specification (master) | https://github.com/CycloneDX/specification/blob/master/schema/bom-1.2.schema.json | 33 | 34 | ### Version comparisons 35 | 36 | - [Document comparing schema 1.3 to 1.4](cdx-schema-delta-by-version.md) 37 | -------------------------------------------------------------------------------- /resources/schema/spdx/README.md: -------------------------------------------------------------------------------- 1 | 19 | 20 | # SPDX schemas 21 | 22 | For convenience, schemas are copied locally from: 23 | - https://github.com/spdx/spdx-spec/ 24 | 25 | Supported schemas by release (tag): 26 | | release tag | branch | schema file (git format) | 27 | | :-- | :-- | :-- | 28 | | [v2.2.1](https://github.com/spdx/spdx-spec/releases/tag/v2.2.1) | https://github.com/spdx/spdx-spec/tree/v2.2.1 | https://github.com/spdx/spdx-spec/blob/v2.2.1/schemas/spdx-schema.json | 29 | 30 | Development branches: 31 | | branch | schema file (git format) | 32 | | :-- | :-- | 33 | | [development/v2.2.2](https://github.com/spdx/spdx-spec/tree/development/v2.2.2) (default) | https://github.com/spdx/spdx-spec/blob/development/v2.2.2/schemas/spdx-schema.json | 34 | -------------------------------------------------------------------------------- /resources/schema/spdx/spdx-delta-v2.2.2-v2.3.md: -------------------------------------------------------------------------------- 1 | Note: did not record any changes that include: 2 | - any changes "description" fields (including addition of a "description" field where one did not exist in the previous version) 3 | - any changes in order that do not affect data changes (e.g., "enum" ordering, property "required" ordering, etc.) 4 | 5 | | Field | Type | 2.3 Change | Description/Notes | 6 | | --- | --- | --- | --- | 7 | |'creationInfo" | Add required field |```"required": [..., "creators"],```|| 8 | |"files" (items) -> "licenseInfoInFiles"|Removed constraint|removed constraint:```"minItems": 1,```|| 9 | |"files" (items) -> "licenseConcluded"|Removed object "licenseConcluded" from "required" data|removed ""licenseConcluded" from "required" data.|This may be a response to the fact not all files have (concluded) licenses?| 10 | |"builtDate"|Added field "builtDate"|```"builtDate": { "description": "...","type": "string"},```|This field provides a place for recording the actual date the package was built."| 11 | |"externalRefs"->"referenceCategory"|Added "PERSISTENT_ID" to enum|```"enum": [...,"PERSISTENT_ID",],```|| 12 | |"packages" (items) -> "primaryPackagePurpose"|Added object "primaryPackagePurpose"|```"primaryPackagePurpose": { "description": "...", "type": "object" },```|Package Purpose is intrinsic to how the package is being used rather than the content of the package.| 13 | |"packages" (items) -> "releaseDate"|Added field "releaseDate"|```"releaseDate": { "description": "...", "type": "string" },```|This field provides a place for recording the date the package was released.| 14 | |"packages" (items) -> "validUntilDate"|Added field "validUntilDate"|```"validUntilDate": { "description": "...", "type": "string" },```|| 15 | |"files" (items) |Removed required properties|removed: ```"licenseConcluded","copyrightText"```|| 16 | |"files" (items)|Added required properties|added: ```"checksums"```|| 17 | |"packages" (items)|Removed required properties|removed:```"licenseConcluded", "licenseDeclared", "copyrightText"```|| 18 | |"relationships" -> "relationshipType"|enum value added:"AMENDS"|added:```"AMENDS"```|| 19 | |"snippets" (items)|Removed required properties|removed:```"licenseConcluded"```|| 20 | -------------------------------------------------------------------------------- /schema/README.md: -------------------------------------------------------------------------------- 1 | 19 | 20 | # Supported schema formats 21 | 22 | Formats MUST be in JSON schema format. 23 | 24 | The following schema formats are supported: 25 | 26 | | Format Name | Format Key | Format ID | Schema repository | 27 | | :-- | :-- | :-- | :-- | 28 | | SPDX | `SPDXID` | `SPDXRef-DOCUMENT` | https://github.com/spdx/spdx-spec | 29 | | CycloneDX | `bomFormat` | `CycloneDx` | https://github.com/CycloneDX/specification | 30 | -------------------------------------------------------------------------------- /schema/constants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package schema 19 | 20 | // Supported schemas will be identified (or "keyed") uniquely using values: 21 | // - Format ID (e.g., "SPDXRef-DOCUMENT", "CycloneDX") - identifies the format/standard 22 | // - Schema version (e.g., "SPDX-2.2", "" ) 23 | // ASSUMPTIONS: 24 | // - Since we see that both SPDX and CycloneDX both support "semver" of their specification versions 25 | // BUT, they only provide the "MAJOR.MINOR" components of "semver" we will use the 26 | // "latest" ".PATCH" version of the JSON schema to test against 27 | // NOTE: If any of these 3 components are not found in an SBOM then the schema is 28 | // not deterministic. 29 | // TODO: support "override" or "supplemental" (defaults) to be provided on 30 | // the command line. 31 | // TODO: Allow for discrete "semver" for a scheam to be provided as an override 32 | // that includes full "MAJOR.MINOR.PATCH" granularity 33 | 34 | // Format ID (key component) 35 | const ( 36 | ID_SPDX = "SPDXRef-DOCUMENT" 37 | ID_CYCLONEDX = "CycloneDX" 38 | ) 39 | 40 | // Document property keys 41 | // JSON document property keys to lookup values in their respective SBOM formats 42 | const ( 43 | // SPDX 44 | PROPKEY_ID_SPDX = "SPDXID" 45 | PROPKEY_VERSION_SPDX = "spdxVersion" 46 | // CycloneDX 47 | PROPKEY_ID_CYCLONEDX = "bomFormat" 48 | PROPKEY_VERSION_CYCLONEDX = "specVersion" 49 | ) 50 | 51 | // Version (key component) 52 | const ( 53 | VERSION_SPDX_2_2 = "SPDX-2.2" 54 | VERSION_CYCLONEDX_1_3 = "1.3" 55 | ) 56 | 57 | // TODO: Support remote schema retrieval as an optional program flag 58 | // However, we want to default to local for performance where possible 59 | // as well as plan for local, secure bundling of schema with this utility 60 | // in CI build systems (towards improved security, isolated builds) 61 | // NOTE: we have also found that standards orgs. freely move their schema files 62 | // within SCM systems thereby being a cause for remote retrieval failures. 63 | const ( 64 | SCHEMA_SPDX_2_2_2_LOCAL = "file://schema/spdx/2.2/spdx-schema.json" 65 | SCHEMA_SPDX_2_2_2_REMOTE = "https://github.com/spdx/spdx-spec/blob/master/schemas/spdx-schema.json" 66 | SCHEMA_CYCLONEDX_1_3_LOCAL = "file://schema/cyclonedx/1.3/bom-1.3.schema.json" 67 | SCHEMA_CYCLONEDX_1_3_REMOTE = "https://github.com/CycloneDX/specification/blob/master/schema/bom-1.3.schema.json" 68 | SCHEMA_CYCLONEDX_1_3_STRICT_LOCAL = "file://schema/cyclonedx/1.3/bom-1.3-strict.schema.json" 69 | SCHEMA_CYCLONEDX_1_3_STRICT_REMOTE = "https://github.com/CycloneDX/specification/blob/master/schema/bom-1.3-strict.schema.json" 70 | ) 71 | -------------------------------------------------------------------------------- /schema/schema_custom_validation.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package schema 19 | 20 | import ( 21 | "encoding/json" 22 | "fmt" 23 | "io/ioutil" 24 | 25 | "github.com/ibm/sbom-utility/utils" 26 | ) 27 | 28 | // Globals 29 | var CustomValidationChecks CustomValidationConfig 30 | 31 | // --------------------------------------------------------------- 32 | // Custom Validation 33 | // --------------------------------------------------------------- 34 | 35 | func LoadCustomValidationConfig(filename string) (err error) { 36 | getLogger().Enter() 37 | defer getLogger().Exit() 38 | 39 | cfgFilename, err := utils.FindVerifyConfigFileAbsPath(getLogger(), filename) 40 | 41 | if err != nil { 42 | return fmt.Errorf("unable to find custom validation config file: `%s`", filename) 43 | } 44 | 45 | // Note we actively supply informative error messages to help user 46 | // understand exactly how the load failed 47 | getLogger().Infof("Loading custom validation config file: `%s`...", cfgFilename) 48 | buffer, err := ioutil.ReadFile(cfgFilename) 49 | if err != nil { 50 | return fmt.Errorf("unable to `ReadFile`: `%s`", cfgFilename) 51 | } 52 | 53 | err = json.Unmarshal(buffer, &CustomValidationChecks) 54 | if err != nil { 55 | return fmt.Errorf("cannot `Unmarshal`: `%s`", cfgFilename) 56 | } 57 | 58 | return 59 | } 60 | 61 | // TODO: return copies 62 | func (config *CustomValidationConfig) GetCustomValidationConfig() *CustomValidation { 63 | return &config.Validation 64 | } 65 | 66 | func (config *CustomValidationConfig) GetCustomValidationMetadata() *CustomValidationMetadata { 67 | 68 | if cfg := config.GetCustomValidationConfig(); cfg != nil { 69 | return &cfg.Metadata 70 | } 71 | return nil 72 | } 73 | 74 | func (config *CustomValidationConfig) GetCustomValidationMetadataProperties() []CustomValidationProperty { 75 | 76 | if metadata := config.GetCustomValidationMetadata(); metadata != nil { 77 | return metadata.Properties 78 | } 79 | return nil 80 | } 81 | 82 | type CustomValidationConfig struct { 83 | Validation CustomValidation `json:"validation"` 84 | } 85 | 86 | // Custom Validation config. 87 | type CustomValidation struct { 88 | Metadata CustomValidationMetadata `json:"metadata"` 89 | } 90 | 91 | type CustomValidationMetadata struct { 92 | Properties []CustomValidationProperty `json:"properties"` 93 | Tools []CustomValidationTool `json:"tools"` 94 | } 95 | 96 | // NOTE: Assumes property "key" is the value in the "name" field 97 | type CustomValidationProperty struct { 98 | CDXProperty 99 | Description string `json:"_validate_description"` 100 | Key string `json:"_validate_key"` 101 | CheckUnique string `json:"_validate_unique"` 102 | CheckRegex string `json:"_validate_regex"` 103 | } 104 | 105 | type CustomValidationTool struct { 106 | CDXTool 107 | Description string `json:"_validate_description"` 108 | } 109 | -------------------------------------------------------------------------------- /test/config/test-base-invalid-format-key-foo.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": "bar" 3 | } 4 | -------------------------------------------------------------------------------- /test/config/test-cdx-bom-format-invalid.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "foo", 3 | "specVersion": "1.2" 4 | } 5 | -------------------------------------------------------------------------------- /test/config/test-cdx-bom-format-missing.json: -------------------------------------------------------------------------------- 1 | { 2 | "specVersion": "1.2" 3 | } 4 | -------------------------------------------------------------------------------- /test/config/test-cdx-spec-version-invalid.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.x", 4 | "version": 1 5 | } 6 | -------------------------------------------------------------------------------- /test/config/test-cdx-spec-version-missing.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX" 3 | } 4 | -------------------------------------------------------------------------------- /test/config/test-spdx-spdx-id-invalid.json: -------------------------------------------------------------------------------- 1 | { 2 | "SPDXID" : "bar", 3 | "spdxVersion" : "SPDX-2.2" 4 | } 5 | -------------------------------------------------------------------------------- /test/config/test-spdx-spdx-version-missing.json: -------------------------------------------------------------------------------- 1 | { 2 | "SPDXID" : "SPDXRef-DOCUMENT" 3 | } 4 | -------------------------------------------------------------------------------- /test/custom/cdx-1-3-test-custom-invalid-composition-components.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.3", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "timestamp": "2021-04-14T07:20:00.000Z", 8 | "component": { 9 | "type": "application", 10 | "bom-ref": "pkg:app/sample@2.0.0", 11 | "purl": "pkg:app/sample@2.0.0", 12 | "name": "sample app", 13 | "version": "2.0.0", 14 | "description": "Sample application" 15 | } 16 | }, 17 | "components": [ 18 | { 19 | "type": "library", 20 | "bom-ref": "pkg:npm/libraryA@1.0.0", 21 | "purl": "pkg:npm/libraryA@1.0.0", 22 | "name": "Library A", 23 | "version": "1.0.0", 24 | "description": "Library A description", 25 | "components": [ 26 | { 27 | "type": "library", 28 | "bom-ref": "pkg:npm/bad-nest@1.0.0", 29 | "purl": "pkg:npm/bad-nest@1.0.0", 30 | "name": "bad nest", 31 | "version": "1.0.0", 32 | "description": "Bad nested library" 33 | } 34 | ] 35 | }, 36 | { 37 | "type": "library", 38 | "bom-ref": "pkg:npm/libraryB@1.0.0", 39 | "purl": "pkg:npm/libraryB@1.0.0", 40 | "name": "Library B", 41 | "version": "1.0.0", 42 | "description": "Library B description." 43 | } 44 | ] 45 | } -------------------------------------------------------------------------------- /test/custom/cdx-1-3-test-custom-invalid-composition-metadata-component.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.3", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "timestamp": "2021-04-14T07:20:00.000Z", 8 | "component": { 9 | "type": "application", 10 | "bom-ref": "pkg:app/sample@2.0.0", 11 | "purl": "pkg:app/sample@2.0.0", 12 | "name": "sample app", 13 | "version": "2.0.0", 14 | "description": "Sample application", 15 | "components": [ 16 | { 17 | "type": "library", 18 | "bom-ref": "pkg:npm/bad-nest@1.0.0", 19 | "purl": "pkg:npm/bad-nest@1.0.0", 20 | "name": "bad nest", 21 | "version": "1.0.0", 22 | "description": "Bad nested library" 23 | } 24 | ] 25 | } 26 | }, 27 | "components": [ 28 | { 29 | "type": "library", 30 | "bom-ref": "pkg:npm/libraryA@1.0.0", 31 | "purl": "pkg:npm/libraryA@1.0.0", 32 | "name": "Library A", 33 | "version": "1.0.0", 34 | "description": "Library A description" 35 | }, 36 | { 37 | "type": "library", 38 | "bom-ref": "pkg:npm/libraryB@1.0.0", 39 | "purl": "pkg:npm/libraryB@1.0.0", 40 | "name": "Library B", 41 | "version": "1.0.0", 42 | "description": "Library B description." 43 | } 44 | ] 45 | } -------------------------------------------------------------------------------- /test/custom/cdx-1-4-invalid-licenses-not-found.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "serialNumber": "urn:uuid:93816a88-307e-495f-8a65-f3422590523b", 5 | "version": 1, 6 | "metadata": { 7 | "timestamp": "2022-07-07T21:29:32Z", 8 | "tools": [ 9 | { 10 | "vendor": "IBM", 11 | "name": "IBM Cloud Continuous Delivery - Code Risk Analyzer", 12 | "version": "0.1.21" 13 | } 14 | ], 15 | "component": { 16 | "type": "application", 17 | "name": "" 18 | } 19 | }, 20 | "components": [ 21 | { 22 | "bom-ref": "file:package-lock.json", 23 | "type": "file", 24 | "name": "package-lock.json", 25 | "version": "185e280a6a913a082ce8f448433d59527c77caf3149873fc8775851a1685a691", 26 | "purl": "package-lock.json", 27 | "properties": [ 28 | { 29 | "name": "ecosystem", 30 | "value": "npm" 31 | } 32 | ] 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /test/custom/cdx-1-4-test-custom-metadata-property-classification-invalid.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "timestamp": "2021-04-14T07:20:00.000Z", 8 | "component": { 9 | "type": "application", 10 | "bom-ref": "pkg:app/sample@2.0.0", 11 | "purl": "pkg:app/sample@2.0.0", 12 | "name": "sample app", 13 | "version": "2.0.0", 14 | "description": "Sample application", 15 | "hashes": [ 16 | { 17 | "alg": "SHA-1", 18 | "content": "1111aaaa2222cccc3333dddd4444eeee5555ffff" 19 | } 20 | ] 21 | }, 22 | "properties": [ 23 | { 24 | "name": "urn:example.com:disclaimer", 25 | "value": "This SBOM is current as of the date it was generated and is subject to change." 26 | }, 27 | { 28 | "name": "urn:example.com:classification", 29 | "value": "This SBOM is Confidential Information." 30 | } 31 | ], 32 | "licenses": [ 33 | { 34 | "license": { 35 | "id": "Apache-2.0" 36 | } 37 | } 38 | ], 39 | "tools": [ 40 | { 41 | "vendor": "Super Duper Security Inc.", 42 | "name": "Super Duper Security Scanner", 43 | "version": "1.2.3", 44 | "hashes": [ 45 | { 46 | "alg": "SHA-1", 47 | "content": "6666ffff7777eeee8888dddd9999cccc0000bbbb" 48 | } 49 | ] 50 | } 51 | ], 52 | "manufacture": { 53 | "name": "Example.com", 54 | "url": [ 55 | "https://example.com" 56 | ], 57 | "contact": [ 58 | { 59 | "email": "support@example.com" 60 | } 61 | ] 62 | }, 63 | "supplier": { 64 | "name": "Example.com", 65 | "url": [ 66 | "https://example.com" 67 | ], 68 | "contact": [ 69 | { 70 | "email": "support@example.com" 71 | } 72 | ] 73 | } 74 | }, 75 | "components": [ 76 | { 77 | "type": "library", 78 | "bom-ref": "pkg:npm/libraryA@1.0.0", 79 | "purl": "pkg:npm/libraryA@1.0.0", 80 | "name": "Library A", 81 | "version": "1.0.0", 82 | "description": "Library A description" 83 | }, 84 | { 85 | "type": "library", 86 | "bom-ref": "pkg:npm/libraryB@1.0.0", 87 | "purl": "pkg:npm/libraryB@1.0.0", 88 | "name": "Library B", 89 | "version": "1.0.0", 90 | "description": "Library B description." 91 | } 92 | ] 93 | } 94 | -------------------------------------------------------------------------------- /test/custom/cdx-1-4-test-custom-metadata-property-classification-missing.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "timestamp": "2021-04-14T07:20:00.000Z", 8 | "component": { 9 | "type": "application", 10 | "bom-ref": "pkg:app/sample@2.0.0", 11 | "purl": "pkg:app/sample@2.0.0", 12 | "name": "sample app", 13 | "version": "2.0.0", 14 | "description": "Sample application", 15 | "hashes": [ 16 | { 17 | "alg": "SHA-1", 18 | "content": "1111aaaa2222cccc3333dddd4444eeee5555ffff" 19 | } 20 | ] 21 | }, 22 | "properties": [ 23 | { 24 | "name": "urn:example.com:disclaimer", 25 | "value": "This SBOM is current as of the date it was generated and is subject to change." 26 | } 27 | ], 28 | "licenses": [ 29 | { 30 | "license": { 31 | "id": "Apache-2.0" 32 | } 33 | } 34 | ], 35 | "tools": [ 36 | { 37 | "vendor": "Super Duper Security Inc.", 38 | "name": "Super Duper Security Scanner", 39 | "version": "1.2.3", 40 | "hashes": [ 41 | { 42 | "alg": "SHA-1", 43 | "content": "6666ffff7777eeee8888dddd9999cccc0000bbbb" 44 | } 45 | ] 46 | } 47 | ], 48 | "manufacture": { 49 | "name": "Example.com", 50 | "url": [ 51 | "https://example.com" 52 | ], 53 | "contact": [ 54 | { 55 | "email": "support@example.com" 56 | } 57 | ] 58 | }, 59 | "supplier": { 60 | "name": "Example.com", 61 | "url": [ 62 | "https://example.com" 63 | ], 64 | "contact": [ 65 | { 66 | "email": "support@example.com" 67 | } 68 | ] 69 | } 70 | }, 71 | "components": [ 72 | { 73 | "type": "library", 74 | "bom-ref": "pkg:npm/libraryA@1.0.0", 75 | "purl": "pkg:npm/libraryA@1.0.0", 76 | "name": "Library A", 77 | "version": "1.0.0", 78 | "description": "Library A description" 79 | }, 80 | { 81 | "type": "library", 82 | "bom-ref": "pkg:npm/libraryB@1.0.0", 83 | "purl": "pkg:npm/libraryB@1.0.0", 84 | "name": "Library B", 85 | "version": "1.0.0", 86 | "description": "Library B description." 87 | } 88 | ] 89 | } 90 | -------------------------------------------------------------------------------- /test/custom/cdx-1-4-test-custom-metadata-property-classification-unique.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "timestamp": "2021-04-14T07:20:00.000Z", 8 | "component": { 9 | "type": "application", 10 | "bom-ref": "pkg:app/sample@2.0.0", 11 | "purl": "pkg:app/sample@2.0.0", 12 | "name": "sample app", 13 | "version": "2.0.0", 14 | "description": "Sample application", 15 | "hashes": [ 16 | { 17 | "alg": "SHA-1", 18 | "content": "1111aaaa2222cccc3333dddd4444eeee5555ffff" 19 | } 20 | ] 21 | }, 22 | "properties": [ 23 | { 24 | "name": "urn:example.com:disclaimer", 25 | "value": "This SBOM is current as of the date it was generated and is subject to change." 26 | }, 27 | { 28 | "name": "urn:example.com:classification", 29 | "value": "This SBOM is Confidential Information. Do not distribute." 30 | }, 31 | { 32 | "name": "urn:example.com:classification", 33 | "value": "This SBOM is Confidential Information. Do not distribute." 34 | } 35 | ], 36 | "licenses": [ 37 | { 38 | "license": { 39 | "id": "Apache-2.0" 40 | } 41 | } 42 | ], 43 | "tools": [ 44 | { 45 | "vendor": "Super Duper Security Inc.", 46 | "name": "Super Duper Security Scanner", 47 | "version": "1.2.3", 48 | "hashes": [ 49 | { 50 | "alg": "SHA-1", 51 | "content": "6666ffff7777eeee8888dddd9999cccc0000bbbb" 52 | } 53 | ] 54 | } 55 | ], 56 | "manufacture": { 57 | "name": "Example.com", 58 | "url": [ 59 | "https://example.com" 60 | ], 61 | "contact": [ 62 | { 63 | "email": "support@example.com" 64 | } 65 | ] 66 | }, 67 | "supplier": { 68 | "name": "Example.com", 69 | "url": [ 70 | "https://example.com" 71 | ], 72 | "contact": [ 73 | { 74 | "email": "support@example.com" 75 | } 76 | ] 77 | } 78 | }, 79 | "components": [ 80 | { 81 | "type": "library", 82 | "bom-ref": "pkg:npm/libraryA@1.0.0", 83 | "purl": "pkg:npm/libraryA@1.0.0", 84 | "name": "Library A", 85 | "version": "1.0.0", 86 | "description": "Library A description" 87 | }, 88 | { 89 | "type": "library", 90 | "bom-ref": "pkg:npm/libraryB@1.0.0", 91 | "purl": "pkg:npm/libraryB@1.0.0", 92 | "name": "Library B", 93 | "version": "1.0.0", 94 | "description": "Library B description." 95 | } 96 | ] 97 | } 98 | -------------------------------------------------------------------------------- /test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "timestamp": "2021-04-14T07:20:00.000Z", 8 | "component": { 9 | "type": "application", 10 | "bom-ref": "pkg:app/sample@2.0.0", 11 | "purl": "pkg:app/sample@2.0.0", 12 | "name": "sample app", 13 | "version": "2.0.0", 14 | "description": "Sample application", 15 | "hashes": [ 16 | { 17 | "alg": "SHA-1", 18 | "content": "1111aaaa2222cccc3333dddd4444eeee5555ffff" 19 | } 20 | ] 21 | }, 22 | "properties": [ 23 | { 24 | "name": "urn:example.com:disclaimer", 25 | "value": "This SBOM is current as of the date it was generated." 26 | }, 27 | { 28 | "name": "urn:example.com:classification", 29 | "value": "This SBOM is Confidential Information. Do not distribute." 30 | } 31 | ], 32 | "licenses": [ 33 | { 34 | "license": { 35 | "id": "Apache-2.0" 36 | } 37 | } 38 | ], 39 | "tools": [ 40 | { 41 | "vendor": "Super Duper Security Inc.", 42 | "name": "Super Duper Security Scanner", 43 | "version": "1.2.3", 44 | "hashes": [ 45 | { 46 | "alg": "SHA-1", 47 | "content": "6666ffff7777eeee8888dddd9999cccc0000bbbb" 48 | } 49 | ] 50 | } 51 | ], 52 | "manufacture": { 53 | "name": "Example.com", 54 | "url": [ 55 | "https://example.com" 56 | ], 57 | "contact": [ 58 | { 59 | "email": "support@example.com" 60 | } 61 | ] 62 | }, 63 | "supplier": { 64 | "name": "Example.com", 65 | "url": [ 66 | "https://example.com" 67 | ], 68 | "contact": [ 69 | { 70 | "email": "support@example.com" 71 | } 72 | ] 73 | } 74 | }, 75 | "components": [ 76 | { 77 | "type": "library", 78 | "bom-ref": "pkg:npm/libraryA@1.0.0", 79 | "purl": "pkg:npm/libraryA@1.0.0", 80 | "name": "Library A", 81 | "version": "1.0.0", 82 | "description": "Library A description" 83 | }, 84 | { 85 | "type": "library", 86 | "bom-ref": "pkg:npm/libraryB@1.0.0", 87 | "purl": "pkg:npm/libraryB@1.0.0", 88 | "name": "Library B", 89 | "version": "1.0.0", 90 | "description": "Library B description." 91 | } 92 | ] 93 | } 94 | -------------------------------------------------------------------------------- /test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-missing.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "timestamp": "2021-04-14T07:20:00.000Z", 8 | "component": { 9 | "type": "application", 10 | "bom-ref": "pkg:app/sample@2.0.0", 11 | "purl": "pkg:app/sample@2.0.0", 12 | "name": "sample app", 13 | "version": "2.0.0", 14 | "description": "Sample application", 15 | "hashes": [ 16 | { 17 | "alg": "SHA-1", 18 | "content": "1111aaaa2222cccc3333dddd4444eeee5555ffff" 19 | } 20 | ] 21 | }, 22 | "properties": [ 23 | { 24 | "name": "urn:example.com:classification", 25 | "value": "This SBOM is Confidential Information. Do not distribute." 26 | } 27 | ], 28 | "licenses": [ 29 | { 30 | "license": { 31 | "id": "Apache-2.0" 32 | } 33 | } 34 | ], 35 | "tools": [ 36 | { 37 | "vendor": "Super Duper Security Inc.", 38 | "name": "Super Duper Security Scanner", 39 | "version": "1.2.3", 40 | "hashes": [ 41 | { 42 | "alg": "SHA-1", 43 | "content": "6666ffff7777eeee8888dddd9999cccc0000bbbb" 44 | } 45 | ] 46 | } 47 | ], 48 | "manufacture": { 49 | "name": "Example.com", 50 | "url": [ 51 | "https://example.com" 52 | ], 53 | "contact": [ 54 | { 55 | "email": "support@example.com" 56 | } 57 | ] 58 | }, 59 | "supplier": { 60 | "name": "Example.com", 61 | "url": [ 62 | "https://example.com" 63 | ], 64 | "contact": [ 65 | { 66 | "email": "support@example.com" 67 | } 68 | ] 69 | } 70 | }, 71 | "components": [ 72 | { 73 | "type": "library", 74 | "bom-ref": "pkg:npm/libraryA@1.0.0", 75 | "purl": "pkg:npm/libraryA@1.0.0", 76 | "name": "Library A", 77 | "version": "1.0.0", 78 | "description": "Library A description" 79 | }, 80 | { 81 | "type": "library", 82 | "bom-ref": "pkg:npm/libraryB@1.0.0", 83 | "purl": "pkg:npm/libraryB@1.0.0", 84 | "name": "Library B", 85 | "version": "1.0.0", 86 | "description": "Library B description." 87 | } 88 | ] 89 | } 90 | -------------------------------------------------------------------------------- /test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-unique.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "timestamp": "2021-04-14T07:20:00.000Z", 8 | "component": { 9 | "type": "application", 10 | "bom-ref": "pkg:app/sample@2.0.0", 11 | "purl": "pkg:app/sample@2.0.0", 12 | "name": "sample app", 13 | "version": "2.0.0", 14 | "description": "Sample application", 15 | "hashes": [ 16 | { 17 | "alg": "SHA-1", 18 | "content": "1111aaaa2222cccc3333dddd4444eeee5555ffff" 19 | } 20 | ] 21 | }, 22 | "properties": [ 23 | { 24 | "name": "urn:example.com:disclaimer", 25 | "value": "This SBOM is current as of the date it was generated and is subject to change." 26 | }, 27 | { 28 | "name": "urn:example.com:classification", 29 | "value": "This SBOM is Confidential Information. Do not distribute." 30 | }, 31 | { 32 | "name": "urn:example.com:disclaimer", 33 | "value": "This SBOM is current as of the date it was generated and is subject to change." 34 | } 35 | ], 36 | "licenses": [ 37 | { 38 | "license": { 39 | "id": "Apache-2.0" 40 | } 41 | } 42 | ], 43 | "tools": [ 44 | { 45 | "vendor": "Super Duper Security Inc.", 46 | "name": "Super Duper Security Scanner", 47 | "version": "1.2.3", 48 | "hashes": [ 49 | { 50 | "alg": "SHA-1", 51 | "content": "6666ffff7777eeee8888dddd9999cccc0000bbbb" 52 | } 53 | ] 54 | } 55 | ], 56 | "manufacture": { 57 | "name": "Example.com", 58 | "url": [ 59 | "https://example.com" 60 | ], 61 | "contact": [ 62 | { 63 | "email": "support@example.com" 64 | } 65 | ] 66 | }, 67 | "supplier": { 68 | "name": "Example.com", 69 | "url": [ 70 | "https://example.com" 71 | ], 72 | "contact": [ 73 | { 74 | "email": "support@example.com" 75 | } 76 | ] 77 | } 78 | }, 79 | "components": [ 80 | { 81 | "type": "library", 82 | "bom-ref": "pkg:npm/libraryA@1.0.0", 83 | "purl": "pkg:npm/libraryA@1.0.0", 84 | "name": "Library A", 85 | "version": "1.0.0", 86 | "description": "Library A description" 87 | }, 88 | { 89 | "type": "library", 90 | "bom-ref": "pkg:npm/libraryB@1.0.0", 91 | "purl": "pkg:npm/libraryB@1.0.0", 92 | "name": "Library B", 93 | "version": "1.0.0", 94 | "description": "Library B description." 95 | } 96 | ] 97 | } 98 | -------------------------------------------------------------------------------- /test/custom/ibm/cdx-1-3-ibm-invalid-composition-components.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.3", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "timestamp": "2021-04-14T07:20:00.000Z", 8 | "tools": [ 9 | { 10 | "vendor": "IBM", 11 | "name": "IBM Cloud Continuous Delivery - Code Risk Analyzer", 12 | "version": "0.1.12", 13 | "hashes": [ 14 | { 15 | "alg": "SHA-1", 16 | "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 17 | } 18 | ] 19 | } 20 | ], 21 | "component": { 22 | "type": "application", 23 | "bom-ref": "pkg:app/sample@2.0.0", 24 | "purl": "pkg:app/sample@2.0.0", 25 | "name": "sample app", 26 | "version": "2.0.0", 27 | "description": "Sample application", 28 | "properties": [ 29 | { 30 | "name": "urn:ibm:names:identifier:deliverable:", 31 | "value": "71C22290D7DB11EBAA175CFD3E629A2A" 32 | } 33 | ], 34 | "licenses": [ 35 | { 36 | "license": { 37 | "id": "MIT" 38 | } 39 | } 40 | ] 41 | }, 42 | "manufacture": { 43 | "name": "Apache Software Foundation (ASF)", 44 | "url": [ 45 | "https://www.apache.org" 46 | ], 47 | "contact": [ 48 | { 49 | "email": "contact@apache.org" 50 | } 51 | ] 52 | }, 53 | "supplier": { 54 | "name": "IBM", 55 | "url": [ 56 | "https://www.ibm.com" 57 | ], 58 | "contact": [ 59 | { 60 | "email": "psirt@us.ibm.com" 61 | } 62 | ] 63 | }, 64 | "licenses": [ 65 | { 66 | "license": { 67 | "id": "Apache-2.0" 68 | } 69 | } 70 | ] 71 | }, 72 | "components": [ 73 | { 74 | "type": "library", 75 | "bom-ref": "pkg:npm/libraryA@1.0.0", 76 | "purl": "pkg:npm/libraryA@1.0.0", 77 | "name": "Library A", 78 | "version": "1.0.0", 79 | "description": "Library A description", 80 | "components": [ 81 | { 82 | "type": "library", 83 | "bom-ref": "pkg:npm/bad-nest@1.0.0", 84 | "purl": "pkg:npm/bad-nest@1.0.0", 85 | "name": "bad nest", 86 | "version": "1.0.0", 87 | "description": "Bad nested library" 88 | } 89 | ] 90 | }, 91 | { 92 | "type": "library", 93 | "bom-ref": "pkg:npm/libraryB@1.0.0", 94 | "purl": "pkg:npm/libraryB@1.0.0", 95 | "name": "Library B", 96 | "version": "1.0.0", 97 | "description": "Library B description." 98 | } 99 | ], 100 | "externalReferences": [ 101 | { 102 | "url": "https://www.example.com/", 103 | "comment": "An example website as a URL", 104 | "type": "website" 105 | } 106 | ] 107 | } -------------------------------------------------------------------------------- /test/custom/ibm/cdx-1-3-ibm-invalid-composition-metadata-component.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.3", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "timestamp": "2021-04-14T07:20:00.000Z", 8 | "tools": [ 9 | { 10 | "vendor": "IBM", 11 | "name": "IBM Cloud Continuous Delivery - Code Risk Analyzer", 12 | "version": "0.1.12", 13 | "hashes": [ 14 | { 15 | "alg": "SHA-1", 16 | "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 17 | } 18 | ] 19 | } 20 | ], 21 | "component": { 22 | "type": "application", 23 | "bom-ref": "pkg:app/sample@2.0.0", 24 | "purl": "pkg:app/sample@2.0.0", 25 | "name": "sample app", 26 | "version": "2.0.0", 27 | "description": "Sample application", 28 | "components": [ 29 | { 30 | "type": "library", 31 | "bom-ref": "pkg:npm/bad-nest@1.0.0", 32 | "purl": "pkg:npm/bad-nest@1.0.0", 33 | "name": "bad nest", 34 | "version": "1.0.0", 35 | "description": "Bad nested library" 36 | } 37 | ], 38 | "properties": [ 39 | { 40 | "name": "urn:ibm:names:identifier:deliverable:", 41 | "value": "71C22290D7DB11EBAA175CFD3E629A2A" 42 | } 43 | ], 44 | "licenses": [ 45 | { 46 | "license": { 47 | "id": "MIT" 48 | } 49 | } 50 | ] 51 | }, 52 | "manufacture": { 53 | "name": "Apache Software Foundation (ASF)", 54 | "url": [ 55 | "https://www.apache.org" 56 | ], 57 | "contact": [ 58 | { 59 | "email": "contact@apache.org" 60 | } 61 | ] 62 | }, 63 | "supplier": { 64 | "name": "IBM", 65 | "url": [ 66 | "https://www.ibm.com" 67 | ], 68 | "contact": [ 69 | { 70 | "email": "psirt@us.ibm.com" 71 | } 72 | ] 73 | }, 74 | "licenses": [ 75 | { 76 | "license": { 77 | "id": "Apache-2.0" 78 | } 79 | } 80 | ] 81 | }, 82 | "components": [ 83 | { 84 | "type": "library", 85 | "bom-ref": "pkg:npm/libraryA@1.0.0", 86 | "purl": "pkg:npm/libraryA@1.0.0", 87 | "name": "Library A", 88 | "version": "1.0.0", 89 | "description": "Library A description" 90 | }, 91 | { 92 | "type": "library", 93 | "bom-ref": "pkg:npm/libraryB@1.0.0", 94 | "purl": "pkg:npm/libraryB@1.0.0", 95 | "name": "Library B", 96 | "version": "1.0.0", 97 | "description": "Library B description." 98 | } 99 | ], 100 | "externalReferences": [ 101 | { 102 | "url": "https://www.example.com/", 103 | "comment": "An example website as a URL", 104 | "type": "website" 105 | } 106 | ] 107 | } 108 | -------------------------------------------------------------------------------- /test/custom/ibm/cdx-1-3-ibm-manual-data-example.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.3", 4 | "version": 1, 5 | "metadata": { 6 | "tools": [ 7 | { 8 | "vendor": "Aqua", 9 | "name": "Trivy", 10 | "version": "0.27.1", 11 | "hashes": [ 12 | { 13 | "alg": "SHA-1", 14 | "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 15 | } 16 | ] 17 | } 18 | ], 19 | "component": { 20 | "name": "Manual Package", 21 | "version": "1.1.1", 22 | "type": "library", 23 | "bom-ref": "pkg:npm/manual-package-example@1.1.1", 24 | "purl": "pkg:npm/manual-package-example@1.1.1", 25 | "properties": [ 26 | { 27 | "name": "urn:ibm:names:identifier:deliverable:", 28 | "value": "71C22290D7DB11EBAA175CFD3E629A2A" 29 | }, 30 | { 31 | "name": "urn:ibm:names:identifier:product:", 32 | "value": "5737-I23" 33 | }, 34 | { 35 | "name": "urn:ibm:names:identifier:product:", 36 | "value": "5737-I23" 37 | } 38 | ], 39 | "licenses": [ 40 | { 41 | "license": { 42 | "name": "IBM License (variant)", 43 | "url": "https://ibm.com/licenses/ibm-license.txt" 44 | } 45 | } 46 | ], 47 | "externalReferences": [ 48 | { 49 | "type": "website", 50 | "url": "https://mycompany.com/" 51 | }, 52 | { 53 | "type": "issue-tracker", 54 | "url": "https://github.com/bkimminich/juice-shop/issues" 55 | }, 56 | { 57 | "type": "vcs", 58 | "url": "git+https://github.com/bkimminich/juice-shop.git" 59 | } 60 | ] 61 | }, 62 | "authors": [ 63 | { 64 | 65 | } 66 | ], 67 | "manufacture": { 68 | "name": "IBM", 69 | "url":["https://www.ibm.com"], 70 | "contact":[{"email": "psirt@us.ibm.com"}] 71 | }, 72 | "supplier": { 73 | "name": "IBM", 74 | "url":["https://www.ibm.com"], 75 | "contact":[{"email": "psirt@us.ibm.com"}] 76 | }, 77 | "licenses": [ 78 | { 79 | "license": 80 | { 81 | "id": "Apache-2.0" 82 | } 83 | } 84 | ] 85 | }, 86 | "components": [ 87 | { 88 | "type": "library", 89 | "bom-ref": "pkg:npm/body-parser@1.19.0", 90 | "name": "body-parser", 91 | "version": "1.19.0", 92 | "description": "Node.js body parsing middleware", 93 | "properties": [ 94 | { 95 | "name": "TBD", 96 | "value": "TBD" 97 | } 98 | ], 99 | "hashes": [ 100 | { 101 | "alg": "SHA-1", 102 | "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 103 | } 104 | ], 105 | "licenses": [ 106 | { 107 | "license": { 108 | "id": "MIT" 109 | } 110 | } 111 | ], 112 | "purl": "pkg:npm/body-parser@1.19.0", 113 | "externalReferences": [ 114 | { 115 | "type": "website", 116 | "url": "https://github.com/expressjs/body-parser#readme" 117 | } 118 | ] 119 | } 120 | ], 121 | "externalReferences": [ 122 | { 123 | "url": "https://www.example.com/", 124 | "comment": "An example website as a URL", 125 | "type": "website" 126 | } 127 | ] 128 | } -------------------------------------------------------------------------------- /test/cyclonedx/cdx-1-2-invalid-license-name-has-expression.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.2", 4 | "serialNumber": "urn:uuid:1f860713-54b9-4253-ba5a-9554851904af", 5 | "version": 1, 6 | "metadata": { 7 | "timestamp": "2020-08-03T03:20:53.771Z", 8 | "tools": [ 9 | { 10 | "vendor": "CycloneDX", 11 | "name": "Node.js module", 12 | "version": "2.0.0" 13 | } 14 | ], 15 | "component": { 16 | "type": "library", 17 | "bom-ref": "pkg:npm/juice-shop@11.1.2", 18 | "name": "juice-shop", 19 | "version": "11.1.2", 20 | "description": "Probably the most modern and sophisticated insecure web application", 21 | "licenses": [ 22 | { 23 | "license": { 24 | "id": "MIT" 25 | } 26 | } 27 | ], 28 | "purl": "pkg:npm/juice-shop@11.1.2", 29 | "externalReferences": [ 30 | { 31 | "type": "website", 32 | "url": "https://owasp-juice.shop" 33 | }, 34 | { 35 | "type": "issue-tracker", 36 | "url": "https://github.com/bkimminich/juice-shop/issues" 37 | }, 38 | { 39 | "type": "vcs", 40 | "url": "git+https://github.com/bkimminich/juice-shop.git" 41 | } 42 | ] 43 | } 44 | }, 45 | "components": [ 46 | { 47 | "type": "library", 48 | "bom-ref": "pkg:npm/rc@1.2.8", 49 | "name": "rc", 50 | "version": "1.2.8", 51 | "description": "hardwired configuration loader", 52 | "hashes": [ 53 | { 54 | "alg": "SHA-1", 55 | "content": "cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" 56 | } 57 | ], 58 | "licenses": [ 59 | { 60 | "license": { 61 | "name": "(BSD-2-Clause OR MIT OR Apache-2.0)" 62 | } 63 | } 64 | ], 65 | "purl": "pkg:npm/rc@1.2.8", 66 | "externalReferences": [ 67 | { 68 | "type": "website", 69 | "url": "https://github.com/dominictarr/rc#readme" 70 | }, 71 | { 72 | "type": "issue-tracker", 73 | "url": "https://github.com/dominictarr/rc/issues" 74 | }, 75 | { 76 | "type": "vcs", 77 | "url": "git+https://github.com/dominictarr/rc.git" 78 | } 79 | ] 80 | } 81 | ] 82 | } -------------------------------------------------------------------------------- /test/cyclonedx/cdx-1-3-invalid-license-choice-oneof.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.3", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "component": { 8 | "type": "application", 9 | "bom-ref": "pkg:app/sample@1.0.0", 10 | "purl": "pkg:app/sample@1.0.0", 11 | "name": "ACME Application", 12 | "version": "2.0.0", 13 | "description": "ACME sample application", 14 | "licenses": [ 15 | { 16 | "license": { 17 | "id": "MIT", 18 | "name": "MIT License" 19 | } 20 | } 21 | ] 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/cyclonedx/cdx-1-3-invalid-spdx-license-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.3", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 6 | "metadata": { 7 | "component": { 8 | "type": "application", 9 | "bom-ref": "pkg:app/sample@1.0.0", 10 | "purl": "pkg:app/sample@1.0.0", 11 | "name": "ACME Application", 12 | "version": "2.0.0", 13 | "description": "ACME sample application" 14 | } 15 | }, 16 | "components": [ 17 | { 18 | "type": "library", 19 | "bom-ref": "pkg:lib/component1@1.0.0", 20 | "purl": "pkg:lib/component1@1.0.0", 21 | "name": "Component 1", 22 | "version": "1.0.0", 23 | "description": "Component 1 description", 24 | "licenses": [ 25 | { 26 | "license": { 27 | "id": "MIT" 28 | } 29 | } 30 | ] 31 | }, 32 | { 33 | "type": "library", 34 | "bom-ref": "pkg:lib/component2@1.0.0", 35 | "purl": "pkg:lib/component2@1.0.0", 36 | "name": "Component 2", 37 | "version": "1.0.0", 38 | "description": "Component 2 description", 39 | "licenses": [ 40 | { 41 | "license": { 42 | "id": "UNKNOWN" 43 | } 44 | } 45 | ] 46 | } 47 | ] 48 | } -------------------------------------------------------------------------------- /test/cyclonedx/cdx-1-3-license-list-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.3", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "component": { 8 | "type": "application", 9 | "bom-ref": "pkg:app/sample@1.0.0", 10 | "purl": "pkg:app/sample@1.0.0", 11 | "name": "ACME Application", 12 | "version": "2.0.0", 13 | "description": "ACME sample application" 14 | } 15 | }, 16 | "services":[ 17 | { 18 | "bom-ref": "service:example.com/myservices/foo", 19 | "name": "Foo", 20 | "decription": "Foo service", 21 | "endpoints": [ 22 | "https://example.com/myservice/foo" 23 | ] 24 | } 25 | ], 26 | "components": [ 27 | { 28 | "type": "library", 29 | "bom-ref": "pkg:lib/libraryA@1.0.0", 30 | "purl": "pkg:lib/libraryA@1.0.0", 31 | "name": "Library A", 32 | "version": "1.0.0", 33 | "description": "Library A description" 34 | }, 35 | { 36 | "type": "library", 37 | "bom-ref": "pkg:lib/libraryB@1.0.0", 38 | "purl": "pkg:lib/libraryB@1.0.0", 39 | "name": "Library B", 40 | "version": "1.0.0", 41 | "description": "Library B description." 42 | }, 43 | { 44 | "type": "library", 45 | "bom-ref": "pkg:lib/libraryC@1.0.0", 46 | "purl": "pkg:lib/libraryC@1.0.0", 47 | "name": "Library C", 48 | "version": "1.0.0", 49 | "description": "Library C description." 50 | }, 51 | { 52 | "type": "library", 53 | "bom-ref": "pkg:lib/libraryD@1.0.0", 54 | "purl": "pkg:lib/libraryD@1.0.0", 55 | "name": "Library D", 56 | "version": "1.0.0", 57 | "description": "Library D description." 58 | }, 59 | { 60 | "type": "library", 61 | "bom-ref": "pkg:lib/libraryE@1.0.0", 62 | "purl": "pkg:lib/libraryE@1.0.0", 63 | "name": "Library E", 64 | "version": "1.0.0", 65 | "description": "Library E description." 66 | }, 67 | { 68 | "type": "library", 69 | "bom-ref": "pkg:lib/libraryF@1.0.0", 70 | "purl": "pkg:lib/libraryF@1.0.0", 71 | "name": "Library F", 72 | "version": "1.0.0", 73 | "description": "Library F description." 74 | }, 75 | { 76 | "type": "library", 77 | "bom-ref": "pkg:lib/libraryG@1.0.0", 78 | "purl": "pkg:lib/libraryG@1.0.0", 79 | "name": "Library G", 80 | "version": "1.0.0", 81 | "description": "Library G description." 82 | }, 83 | { 84 | "type": "library", 85 | "bom-ref": "pkg:lib/libraryH@1.0.0", 86 | "purl": "pkg:lib/libraryH@1.0.0", 87 | "name": "Library H", 88 | "version": "1.0.0", 89 | "description": "Library H description." 90 | }, 91 | { 92 | "type": "library", 93 | "bom-ref": "pkg:lib/libraryJ@1.0.0", 94 | "purl": "pkg:lib/libraryJ@1.0.0", 95 | "name": "Library J", 96 | "version": "1.0.0", 97 | "description": "Library J description." 98 | } 99 | ] 100 | } 101 | -------------------------------------------------------------------------------- /test/cyclonedx/cdx-1-3-mature-example-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.3", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9", 6 | "externalReferences": [ 7 | { 8 | "url": "support@example.com", 9 | "comment": "Support for questions about SBOM contents", 10 | "type": "support" 11 | } 12 | ], 13 | "metadata": { 14 | "timestamp": "2022-10-12T19:07:00Z", 15 | "properties": [ 16 | { 17 | "name": "urn:example.com:classification", 18 | "value": "This SBOM is Confidential Information. Do not distribute." 19 | }, 20 | { 21 | "name": "urn:example.com:disclaimer", 22 | "value": "This SBOM is current as of the date it was generated and is subject to change." 23 | } 24 | ], 25 | "manufacture": { 26 | "name": "Example Co.", 27 | "url": [ 28 | "https://example.com" 29 | ], 30 | "contact": [ 31 | { 32 | "email": "contact@example.com" 33 | } 34 | ] 35 | }, 36 | "supplier": { 37 | "name": "Example Co. Distribution Dept.", 38 | "url": [ 39 | "https://example.com/software/" 40 | ], 41 | "contact": [ 42 | { 43 | "email": "distribution@example.com" 44 | } 45 | ] 46 | }, 47 | "component": { 48 | "type": "application", 49 | "bom-ref": "pkg:oci/example.com/product/application@10.0.4.0", 50 | "purl": "pkg:oci/example.com/product/application@10.0.4.0", 51 | "name": "Example Application v10.0.4", 52 | "description": "Example's Do-It-All application", 53 | "version": "10.0.4.0", 54 | "licenses": [ 55 | { 56 | "license": { 57 | "id": "Apache-2.0" 58 | } 59 | } 60 | ], 61 | "externalReferences": [ 62 | { 63 | "type": "website", 64 | "url": "https://example.com/application" 65 | } 66 | ], 67 | "properties": [ 68 | { 69 | "name": "urn:example.com:identifier:product", 70 | "value": "71C22290D7DB11EBAA175CFD3E629A2A" 71 | }, 72 | { 73 | "name": "urn:example.com:identifier:distribution", 74 | "value": "5737-I23" 75 | } 76 | ], 77 | "hashes": [ 78 | { 79 | "alg": "SHA-1", 80 | "content": "1111aaaa2222cccc3333dddd4444eeee5555ffff" 81 | } 82 | ], 83 | "supplier": { 84 | "name": "Example Co. Distribution Dept.", 85 | "url": [ 86 | "https://example.com" 87 | ], 88 | "contact": [ 89 | { 90 | "email": "distribution@example.com" 91 | } 92 | ] 93 | }, 94 | "publisher": "Example Inc. EMEA" 95 | }, 96 | "licenses": [ 97 | { 98 | "license": { 99 | "id": "Apache-1.0" 100 | } 101 | }, 102 | { 103 | "license": { 104 | "id": "Apache-2.0" 105 | } 106 | }, 107 | { 108 | "license": { 109 | "id": "GPL-3.0-only" 110 | } 111 | }, 112 | { 113 | "license": { 114 | "id": "MIT" 115 | } 116 | } 117 | ], 118 | "tools": [ 119 | { 120 | "vendor": "SecurityTools.com", 121 | "name": "Security Scanner v1.0", 122 | "version": "1.0.0-beta.1+0099", 123 | "hashes": [ 124 | { 125 | "alg": "SHA-1", 126 | "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 127 | } 128 | ] 129 | }, 130 | { 131 | "vendor": "SBOM.com", 132 | "name": "SBOM Generator v2.1", 133 | "version": "2.1.12", 134 | "hashes": [ 135 | { 136 | "alg": "SHA-1", 137 | "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 138 | } 139 | ] 140 | } 141 | ] 142 | }, 143 | "components": [ 144 | { 145 | "type": "library", 146 | "bom-ref": "pkg:npm/sample@2.0.0", 147 | "purl": "pkg:npm/sample@2.0.0", 148 | "name": "sample", 149 | "version": "2.0.0", 150 | "description": "Node.js Sampler package", 151 | "licenses": [ 152 | { 153 | "license": { 154 | "id": "MIT" 155 | } 156 | } 157 | ] 158 | }, 159 | { 160 | "type": "library", 161 | "bom-ref": "pkg:npm/body-parser@1.19.0", 162 | "purl": "pkg:npm/body-parser@1.19.0", 163 | "name": "body-parser", 164 | "version": "1.19.0", 165 | "description": "Node.js body parsing middleware", 166 | "licenses": [ 167 | { 168 | "license": { 169 | "id": "MIT" 170 | } 171 | } 172 | ], 173 | "hashes": [ 174 | { 175 | "alg": "SHA-1", 176 | "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 177 | } 178 | ] 179 | } 180 | ] 181 | } -------------------------------------------------------------------------------- /test/cyclonedx/cdx-1-3-min-required.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.3", 4 | "version": 1 5 | } 6 | -------------------------------------------------------------------------------- /test/cyclonedx/cdx-1-3-resource-list-none-found.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.3", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "licenses": [ 8 | { 9 | "license": { 10 | "id": "Apache-2.0" 11 | } 12 | } 13 | ] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/cyclonedx/cdx-1-3-syntax-err-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.3", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9", 6 | "metadata" { 7 | } 8 | -------------------------------------------------------------------------------- /test/cyclonedx/cdx-1-4-invalid-email-format.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", 6 | "metadata": { 7 | "component": { 8 | "type": "application", 9 | "bom-ref": "pkg:app/sample@1.0.0", 10 | "purl": "pkg:app/sample@1.0.0", 11 | "name": "ACME Application", 12 | "version": "2.0.0", 13 | "description": "ACME sample application" 14 | }, 15 | "supplier": { 16 | "name": "ACME", 17 | "contact": [ 18 | { 19 | "name": "ACME email (invalid, https prefix)", 20 | "email": "https://acme.com" 21 | } 22 | ] 23 | }, 24 | "licenses": [ 25 | { 26 | "license": { 27 | "id": "Apache-2.0" 28 | } 29 | } 30 | ] 31 | } 32 | } -------------------------------------------------------------------------------- /test/cyclonedx/cdx-1-4-license-policy-invalid-license-name.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "component": { 8 | "type": "application", 9 | "bom-ref": "pkg:app/sample@1.0.0", 10 | "purl": "pkg:app/sample@1.0.0", 11 | "name": "ACME Application", 12 | "version": "2.0.0", 13 | "description": "ACME sample application", 14 | "licenses": [ 15 | { 16 | "license": { 17 | "id": "MIT" 18 | } 19 | } 20 | ] 21 | }, 22 | "licenses": [ 23 | { 24 | "license": { 25 | "name": "bar" 26 | } 27 | } 28 | ] 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/cyclonedx/cdx-1-4-license-policy-invalid-spdx-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7e0", 6 | "metadata": { 7 | "component": { 8 | "type": "application", 9 | "bom-ref": "pkg:app/sample@1.0.0", 10 | "purl": "pkg:app/sample@1.0.0", 11 | "name": "ACME Application", 12 | "version": "2.0.0", 13 | "description": "ACME sample application", 14 | "licenses": [ 15 | { 16 | "license": { 17 | "id": "MIT" 18 | } 19 | } 20 | ] 21 | }, 22 | "licenses": [ 23 | { 24 | "license": { 25 | "id": "foo" 26 | } 27 | } 28 | ] 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/cyclonedx/cdx-1-4-mature-example-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "version": 1, 5 | "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9", 6 | "externalReferences": [ 7 | { 8 | "url": "support@example.com", 9 | "comment": "Support for questions about SBOM contents", 10 | "type": "support" 11 | } 12 | ], 13 | "metadata": { 14 | "timestamp": "2022-10-12T19:07:00Z", 15 | "properties": [ 16 | { 17 | "name": "urn:example.com:classification", 18 | "value": "This SBOM is Confidential Information. Do not distribute." 19 | }, 20 | { 21 | "name": "urn:example.com:disclaimer", 22 | "value": "This SBOM is current as of the date it was generated and is subject to change." 23 | } 24 | ], 25 | "manufacture": { 26 | "name": "Example Co.", 27 | "url": [ 28 | "https://example.com" 29 | ], 30 | "contact": [ 31 | { 32 | "email": "contact@example.com" 33 | } 34 | ] 35 | }, 36 | "supplier": { 37 | "name": "Example Co. Distribution Dept.", 38 | "url": [ 39 | "https://example.com/software/" 40 | ], 41 | "contact": [ 42 | { 43 | "email": "distribution@example.com" 44 | } 45 | ] 46 | }, 47 | "component": { 48 | "type": "application", 49 | "bom-ref": "pkg:oci/example.com/product/application@10.0.4.0", 50 | "purl": "pkg:oci/example.com/product/application@10.0.4.0", 51 | "name": "Example Application v10.0.4", 52 | "description": "Example's Do-It-All application", 53 | "version": "10.0.4.0", 54 | "licenses": [ 55 | { 56 | "license": { 57 | "id": "Apache-2.0" 58 | } 59 | } 60 | ], 61 | "externalReferences": [ 62 | { 63 | "type": "website", 64 | "url": "https://example.com/application" 65 | } 66 | ], 67 | "properties": [ 68 | { 69 | "name": "urn:example.com:identifier:product", 70 | "value": "71C22290D7DB11EBAA175CFD3E629A2A" 71 | }, 72 | { 73 | "name": "urn:example.com:identifier:distribution", 74 | "value": "5737-I23" 75 | } 76 | ], 77 | "hashes": [ 78 | { 79 | "alg": "SHA-1", 80 | "content": "1111aaaa2222cccc3333dddd4444eeee5555ffff" 81 | } 82 | ], 83 | "supplier": { 84 | "name": "Example Co. Distribution Dept.", 85 | "url": [ 86 | "https://example.com" 87 | ], 88 | "contact": [ 89 | { 90 | "email": "distribution@example.com" 91 | } 92 | ] 93 | }, 94 | "publisher": "Example Inc. EMEA" 95 | }, 96 | "licenses": [ 97 | { 98 | "license": { 99 | "id": "Apache-1.0" 100 | } 101 | }, 102 | { 103 | "license": { 104 | "id": "Apache-2.0" 105 | } 106 | }, 107 | { 108 | "license": { 109 | "id": "GPL-3.0-only" 110 | } 111 | }, 112 | { 113 | "license": { 114 | "id": "MIT" 115 | } 116 | } 117 | ], 118 | "tools": [ 119 | { 120 | "vendor": "SecurityTools.com", 121 | "name": "Security Scanner v1.0", 122 | "version": "1.0.0-beta.1+0099", 123 | "hashes": [ 124 | { 125 | "alg": "SHA-1", 126 | "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 127 | } 128 | ] 129 | }, 130 | { 131 | "vendor": "SBOM.com", 132 | "name": "SBOM Generator v2.1", 133 | "version": "2.1.12", 134 | "hashes": [ 135 | { 136 | "alg": "SHA-1", 137 | "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 138 | } 139 | ] 140 | } 141 | ] 142 | }, 143 | "components": [ 144 | { 145 | "type": "library", 146 | "bom-ref": "pkg:npm/sample@2.0.0", 147 | "purl": "pkg:npm/sample@2.0.0", 148 | "name": "sample", 149 | "version": "2.0.0", 150 | "description": "Node.js Sampler package", 151 | "licenses": [ 152 | { 153 | "license": { 154 | "id": "MIT" 155 | } 156 | } 157 | ] 158 | }, 159 | { 160 | "type": "library", 161 | "bom-ref": "pkg:npm/body-parser@1.19.0", 162 | "purl": "pkg:npm/body-parser@1.19.0", 163 | "name": "body-parser", 164 | "version": "1.19.0", 165 | "description": "Node.js body parsing middleware", 166 | "licenses": [ 167 | { 168 | "license": { 169 | "id": "MIT" 170 | } 171 | } 172 | ], 173 | "hashes": [ 174 | { 175 | "alg": "SHA-1", 176 | "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 177 | } 178 | ] 179 | } 180 | ] 181 | } -------------------------------------------------------------------------------- /test/cyclonedx/cdx-1-4-min-required.json: -------------------------------------------------------------------------------- 1 | { 2 | "bomFormat": "CycloneDX", 3 | "specVersion": "1.4", 4 | "version": 1 5 | } 6 | -------------------------------------------------------------------------------- /test/ibm/config/custom-ibm.json: -------------------------------------------------------------------------------- 1 | { 2 | "validation": { 3 | "metadata": { 4 | "_selector": "metadata.properties", 5 | "properties": [ 6 | { 7 | "name": "urn:ibm:legal:disclaimer", 8 | "value": "This SBOM is IBM Confidential Information\\. The person\\(s\\) to whom IBM provides this SBOM may only share the SBOM with those within its company who have a need to know\\. For clarity, this SBOM may not be shared with any other company or other third-party\\. IBM offers no representations or warranties regarding the SBOM\\.", 9 | "_validate_description": "matches fixed value", 10 | "_validate_key": "name", 11 | "_validate_unique": "name" 12 | }, 13 | { 14 | "name": "urn:ibm:legal:coverage", 15 | "value": "This SBOM is current as of the date it was generated and is subject to change\\. This SBOM covers the content of the indicated component, but does not cover the content of any components or dependencies therein \\(which may be covered by their own SBOMs provided by their respective suppliers\\)\\.", 16 | "_validate_description": "matches fixed value", 17 | "_validate_key": "name", 18 | "_validate_unique": "name" 19 | } 20 | ] 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /test/policy/license-policy-family-name-usage-conflict.json: -------------------------------------------------------------------------------- 1 | { 2 | "policies": [ 3 | { 4 | "id": "", 5 | "name": "Some license v1", 6 | "family": "TEST", 7 | "usagePolicy": "allow" 8 | }, 9 | { 10 | "id": "", 11 | "name": "Some license v2", 12 | "family": "TEST", 13 | "usagePolicy": "allow" 14 | }, 15 | { 16 | "id": "", 17 | "name": "Some license v3", 18 | "family": "TEST", 19 | "usagePolicy": "deny" 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /test/policy/license-policy-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "policies": [ 3 | { 4 | "id": "TEST-GOOD-LICENSE", 5 | "name": "Test Good License", 6 | "family": "TEST", 7 | "usagePolicy": "allow", 8 | "annotationRefs": [""], 9 | "notes": [""], 10 | "urls": [""] 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /test/policy/license-policy-license-expression-test-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "policies": [ 3 | { 4 | "id": "Good", 5 | "name": "Good license v1", 6 | "family": "Good", 7 | "usagePolicy": "allow" 8 | }, 9 | { 10 | "id": "Bad", 11 | "name": "Bad license v1", 12 | "family": "Bad", 13 | "usagePolicy": "deny" 14 | }, 15 | { 16 | "id": "Maybe", 17 | "name": "Maybe license v1", 18 | "family": "Maybe", 19 | "usagePolicy": "needs-review" 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /test/spdx/README.md: -------------------------------------------------------------------------------- 1 | 19 | 20 | # Test cases 21 | 22 | ## Functional 23 | 24 | | Test file | schema | description | 25 | | :-- | :-- | :-- | 26 | | [spdx-2-2-min-required.json](spdx-2-2-min-required.json) | 2.2 | Unit test with only top-level, req. fields; i.e., `"required" : [ "SPDXID", "name", "spdxVersion", "dataLicense", "creationInfo" ]` and for creationInfo: `"required" : [ "created" ],` | 27 | | [spdx-2-2-missing-creationinfo.json](spdx-2-2-missing-creationinfo.json) | 2.2 | Unit test missing a single, top-level, req. field; i.e., missing `"creationInfo"` | 28 | -------------------------------------------------------------------------------- /test/spdx/spdx-2-2-min-required.json: -------------------------------------------------------------------------------- 1 | { 2 | "SPDXID" : "SPDXRef-DOCUMENT", 3 | "name" : "spdx-min-required", 4 | "spdxVersion" : "SPDX-2.2", 5 | "dataLicense" : "CC0-1.0", 6 | "creationInfo" : { 7 | "created" : "2022-01-14T00:00:00Z" 8 | }, 9 | "documentNamespace" : "https://sbom-utility.org/test/spdx/" 10 | } -------------------------------------------------------------------------------- /test/spdx/spdx-2-2-missing-creationinfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "SPDXID" : "SPDXRef-DOCUMENT", 3 | "name" : "spdx-min-required-missing-creationinfo", 4 | "spdxVersion" : "SPDX-2.2", 5 | "dataLicense" : "CC0-1.0", 6 | "documentNamespace" : "https://sbom-utility.org/test/spdx/" 7 | } -------------------------------------------------------------------------------- /utils/config.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package utils 19 | 20 | import ( 21 | "fmt" 22 | "os" 23 | "path/filepath" 24 | 25 | "github.com/ibm/sbom-utility/log" 26 | ) 27 | 28 | func FindVerifyConfigFileAbsPath(logger *log.MiniLogger, filename string) (absFilename string, err error) { 29 | logger.Enter() 30 | defer logger.Exit() 31 | 32 | logger.Tracef("filename: %s", filename) 33 | 34 | if len(filename) == 0 { 35 | err = fmt.Errorf("invalid config filename: `%s`", filename) 36 | return 37 | } 38 | 39 | // first, see if the config file is found at the location 40 | // that may have been provided via the command line argument 41 | if _, err = os.Stat(filename); err == nil { 42 | absFilename = filename 43 | logger.Tracef("found config file `%s` at location provided.", absFilename) 44 | return 45 | } 46 | 47 | // if the filename was not passed using an absolute path, attempt to find it 48 | // relative to the executable directory then the current working directory 49 | if !filepath.IsAbs(filename) { 50 | // first, attempt to find file relative to the executable 51 | tmpFilename := filepath.Join(GlobalFlags.ExecDir, filename) 52 | logger.Tracef("Checking for config relative to executable: `%s`...", tmpFilename) 53 | if _, err = os.Stat(tmpFilename); err == nil { 54 | absFilename = tmpFilename 55 | logger.Tracef("found config file relative to executable: `%s`", absFilename) 56 | return 57 | } 58 | 59 | // Last, attempt to find the config file in the current working directory 60 | // Note: this is sometimes needed in IDE/test environments 61 | tmpFilename = filepath.Join(GlobalFlags.WorkingDir, filename) 62 | logger.Tracef("Checking for config relative to working directory: `%s`...", tmpFilename) 63 | if _, err = os.Stat(tmpFilename); err == nil { 64 | absFilename = tmpFilename 65 | logger.Tracef("found config file relative to working directory: `%s`", absFilename) 66 | return 67 | } 68 | } 69 | 70 | logger.Tracef("returning config absolute filename: `%s`", absFilename) 71 | return 72 | } 73 | -------------------------------------------------------------------------------- /utils/convert.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package utils 19 | 20 | import ( 21 | "encoding/json" 22 | "fmt" 23 | ) 24 | 25 | func IsValidJsonMap(test string) bool { 26 | var js map[string]interface{} 27 | err := json.Unmarshal([]byte(test), &js) 28 | return err == nil 29 | } 30 | 31 | func IsValidJsonRaw(test []byte) bool { 32 | var js interface{} 33 | err := json.Unmarshal(test, &js) 34 | return err == nil 35 | } 36 | 37 | // NOTE: simple wrapper method on json package to standardize parms 38 | func ConvertMapToJson(mapIn interface{}) (string, error) { 39 | // Indent each level with 2 space chars. 40 | byteMapOut, err := json.MarshalIndent(mapIn, "", " ") 41 | return string(byteMapOut), err 42 | } 43 | 44 | func ConvertStructToMap(structIn interface{}) (mapOut map[string]interface{}, err error) { 45 | var bytesOut []byte 46 | bytesOut, err = json.Marshal(structIn) 47 | 48 | if err != nil { 49 | return 50 | } 51 | err = json.Unmarshal(bytesOut, &mapOut) 52 | return 53 | } 54 | 55 | // TODO: function NOT complete, only placeholder type switch 56 | func ConvertAnyToAny(values ...interface{}) { 57 | //fmt.Printf("values=%v\n", values) 58 | for index, value := range values { 59 | fmt.Printf("value[%d] (%T): %+v\n", index, value, value) 60 | switch t := value.(type) { 61 | case int: 62 | case uint: 63 | case int32: 64 | case int64: 65 | case uint64: 66 | fmt.Println("Type is an integer:", t) 67 | case float32: 68 | case float64: 69 | fmt.Println("Type is a float:", t) 70 | case string: 71 | fmt.Println("Type is a string:", t) 72 | case nil: 73 | fmt.Println("Type is nil.") 74 | case bool: 75 | fmt.Println("Type is a bool:", t) 76 | default: 77 | fmt.Printf("Type is unknown!: %v\n", t) 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /utils/flags.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package utils 19 | 20 | import ( 21 | "fmt" 22 | 23 | "github.com/ibm/sbom-utility/log" 24 | ) 25 | 26 | // Globals 27 | var GlobalFlags CommandFlags 28 | 29 | type CommandFlags struct { 30 | // Not flags, but "main" package var copies 31 | Project string 32 | Binary string 33 | Version string 34 | WorkingDir string 35 | ExecDir string 36 | 37 | // Configurations 38 | ConfigSchemaFile string 39 | ConfigCustomValidationFile string 40 | ConfigLicensePolicyFile string 41 | 42 | // persistent flags (common to all commands) 43 | Quiet bool // suppresses all non-essential (informational) output from a command. Overrides any other log-level commands. 44 | Trace bool // trace logging 45 | Debug bool // debug logging 46 | InputFile string 47 | OutputFile string 48 | OutputSbomFormat string 49 | 50 | // License flags 51 | //LicensePolicyConfigFile string 52 | 53 | // Validate (local) flags 54 | ForcedJsonSchemaFile string 55 | Variant string 56 | ValidateProperties bool 57 | CustomValidation bool 58 | CustomValidationOptions CustomValidationFlags 59 | 60 | // Summary formats (i.e., only valid for summary) 61 | // NOTE: "query" and "list" (raw) commands always returns JSON by default 62 | OutputFormat string // e.g., TXT (default), CSV, markdown (normalized to lowercase) 63 | 64 | // Log indent 65 | LogOutputIndentCallstack bool 66 | } 67 | 68 | type CustomValidationFlags struct { 69 | Composition bool 70 | License bool 71 | Properties bool 72 | } 73 | 74 | // format and output the MyFlags struct as a string using Go's Stringer interface 75 | func (flags *CommandFlags) String() string { 76 | value, err := log.FormatStruct(flags) 77 | 78 | if err != nil { 79 | return fmt.Sprintf("%s\n", err.Error()) 80 | } 81 | return value 82 | } 83 | --------------------------------------------------------------------------------