├── .github └── workflows │ ├── go-ossf-slsa3-publish.yml │ ├── go.yml │ └── image.yaml ├── .gitignore ├── .ko.yaml ├── .slsa-goreleaser.yml ├── CODEOWNERS ├── LICENSE ├── Makefile ├── README.md ├── cmd └── sbom-scorecard │ ├── cmd │ ├── root.go │ └── scorecard.go │ └── main.go ├── examples ├── dropwizard.cyclonedx.json ├── invalid.json ├── julia.spdx.json ├── openfeature-javasdk.cyclonedx.xml ├── photon.spdx.json └── spdx-example.tv ├── go.mod ├── go.sum ├── go.work ├── go.work.sum ├── pkg ├── cdx │ ├── cdx_report.go │ └── cdx_report_test.go ├── scorecard │ └── scorecard.go └── spdx │ ├── document.go │ ├── document_test.go │ ├── spdx_report.go │ ├── spdx_report_test.go │ └── test_data │ ├── missionlz.spdx.json │ └── nginx.spdx.json ├── result.png ├── sbom-scorecard.yml ├── slsa ├── goreleaser-darwin-amd64.yml ├── goreleaser-darwin-arm64.yml ├── goreleaser-linux-amd64.yml ├── goreleaser-linux-arm64.yml ├── goreleaser-windows-amd64.yml ├── goreleaser-windows-arm64.yml └── template.yml └── usage.gif /.github/workflows/go-ossf-slsa3-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | # This workflow lets you compile your Go project using a SLSA3 compliant builder. 7 | # This workflow will generate a so-called "provenance" file describing the steps 8 | # that were performed to generate the final binary. 9 | # The project is an initiative of the OpenSSF (openssf.org) and is developed at 10 | # https://github.com/slsa-framework/slsa-github-generator. 11 | # The provenance file can be verified using https://github.com/slsa-framework/slsa-verifier. 12 | # For more information about SLSA and how it improves the supply-chain, visit slsa.dev. 13 | 14 | name: SLSA Go releaser 15 | on: 16 | workflow_dispatch: 17 | release: 18 | types: [created] 19 | 20 | permissions: read-all 21 | 22 | jobs: 23 | # Generate ldflags dynamically. 24 | # Optional: only needed for ldflags. 25 | args: 26 | runs-on: ubuntu-latest 27 | outputs: 28 | commit-date: ${{ steps.ldflags.outputs.commit-date }} 29 | commit: ${{ steps.ldflags.outputs.commit }} 30 | version: ${{ steps.ldflags.outputs.version }} 31 | tree-state: ${{ steps.ldflags.outputs.tree-state }} 32 | steps: 33 | - id: checkout 34 | uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # tag=v2.3.4 35 | with: 36 | fetch-depth: 0 37 | - id: ldflags 38 | run: | 39 | echo "commit-date=$(git log --date=iso8601-strict -1 --pretty=%ct)" >> "$GITHUB_OUTPUT" 40 | echo "commit=$GITHUB_SHA" >> "$GITHUB_OUTPUT" 41 | echo "version=$(git describe --tags --always --dirty | cut -c2-)" >> "$GITHUB_OUTPUT" 42 | echo "tree-state=$(if git diff --quiet; then echo "clean"; else echo "dirty"; fi)" >> "$GITHUB_OUTPUT" 43 | 44 | # Trusted builder. 45 | build: 46 | permissions: 47 | id-token: write # To sign the provenance. 48 | contents: write # To upload assets to release. 49 | actions: read # To read the workflow path. 50 | needs: args 51 | strategy: 52 | matrix: 53 | os: 54 | - linux 55 | - windows 56 | - darwin 57 | arch: 58 | - amd64 59 | - arm64 60 | uses: slsa-framework/slsa-github-generator/.github/workflows/builder_go_slsa3.yml@v1.5.0 61 | with: 62 | go-version: 1.17 63 | # Optional: only needed if using ldflags. 64 | evaluated-envs: "COMMIT_DATE:${{needs.args.outputs.commit-date}}, COMMIT:${{needs.args.outputs.commit}}, VERSION:${{needs.args.outputs.version}}, TREE_STATE:${{needs.args.outputs.tree-state}}" 65 | config-file: slsa/goreleaser-${{matrix.os}}-${{matrix.arch}}.yml 66 | 67 | verification: 68 | needs: 69 | - build 70 | runs-on: ubuntu-latest 71 | permissions: read-all 72 | steps: 73 | - name: Install the verifier 74 | uses: slsa-framework/slsa-verifier/actions/installer@v2.1.0 75 | 76 | - name: Download assets 77 | env: 78 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 79 | ATT_FILE_NAME: "${{ needs.build.outputs.go-binary-name }}.intoto.jsonl" 80 | ARTIFACT: ${{ needs.build.outputs.go-binary-name }} 81 | run: | 82 | set -euo pipefail 83 | 84 | gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p $ARTIFACT 85 | gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p "$ATT_FILE_NAME" 86 | 87 | - name: Verify assets 88 | env: 89 | ARTIFACT: ${{ needs.build.outputs.go-binary-name }} 90 | ATT_FILE_NAME: "${{ needs.build.outputs.go-binary-name }}.intoto.jsonl" 91 | run: | 92 | set -euo pipefail 93 | 94 | echo "Verifying $ARTIFACT using $ATT_FILE_NAME" 95 | slsa-verifier verify-artifact --provenance-path "$ATT_FILE_NAME" \ 96 | --source-uri "github.com/$GITHUB_REPOSITORY" \ 97 | --source-tag "$GITHUB_REF_NAME" \ 98 | "$ARTIFACT" 99 | -------------------------------------------------------------------------------- /.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: make build 26 | 27 | - name: Test 28 | run: make test 29 | -------------------------------------------------------------------------------- /.github/workflows/image.yaml: -------------------------------------------------------------------------------- 1 | name: image 2 | 3 | on: 4 | workflow_dispatch: 5 | release: 6 | types: [created] 7 | 8 | permissions: 9 | contents: read 10 | packages: write 11 | id-token: write 12 | 13 | jobs: 14 | image: 15 | runs-on: ubuntu-latest 16 | outputs: 17 | commit-date: ${{ steps.ldflags.outputs.commit-date }} 18 | commit: ${{ steps.ldflags.outputs.commit }} 19 | version: ${{ steps.ldflags.outputs.version }} 20 | tree-state: ${{ steps.ldflags.outputs.tree-state }} 21 | steps: 22 | - uses: actions/checkout@v3 23 | - uses: actions/setup-go@v3 24 | with: 25 | go-version: 1.19 26 | check-latest: true 27 | - uses: sigstore/cosign-installer@v2.8.1 28 | - uses: ko-build/setup-ko@v0.6 29 | - id: ldflags 30 | run: | 31 | echo "commit-date=$(git log --date=iso8601-strict -1 --pretty=%ct)" >> "$GITHUB_OUTPUT" 32 | echo "commit=$GITHUB_SHA" >> "$GITHUB_OUTPUT" 33 | echo "version=$(git describe --tags --always --dirty | cut -c2-)" >> "$GITHUB_OUTPUT" 34 | echo "tree-state=$(if git diff --quiet; then echo "clean"; else echo "dirty"; fi)" >> "$GITHUB_OUTPUT" 35 | - name: downcase REPO 36 | run: | 37 | echo "REPO=${GITHUB_REPOSITORY,,}" >>${GITHUB_ENV} 38 | - name: Publish and sign image 39 | env: 40 | KO_DOCKER_REPO: ghcr.io/${{ env.REPO }} 41 | COSIGN_EXPERIMENTAL: 'true' 42 | run: | 43 | export LDGLAGS="-X main.Version=${{needs.args.outputs.version}} -X main.Commit=${{needs.args.outputs.commit}} -X main.CommitDate=${{needs.args.outputs.commit-date}} -X main.TreeState=${{needs.args.outputs.tree-state}}" 44 | echo "${{ github.token }}" | ko login ghcr.io --username "${{ github.actor }}" --password-stdin 45 | img=$(ko build --bare --platform=all -t latest -t ${{ github.sha }} ./cmd/sbom-scorecard) 46 | echo "built ${img}" 47 | cosign sign ${img} \ 48 | -a sha=${{ github.sha }} \ 49 | -a run_id=${{ github.run_id }} \ 50 | -a run_attempt=${{ github.run_attempt }} 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /sbom-scorecard 2 | /bin 3 | coverage.txt 4 | .vscode/settings.json 5 | .idea/ -------------------------------------------------------------------------------- /.ko.yaml: -------------------------------------------------------------------------------- 1 | baseImageOverride: cgr.dev/chainguard/static:latest 2 | 3 | builds: 4 | - id: sbom-scorecard 5 | ldflags: 6 | - "{{ .Env.LDFLAGS }}" -------------------------------------------------------------------------------- /.slsa-goreleaser.yml: -------------------------------------------------------------------------------- 1 | # Version for this file. 2 | version: 1 3 | 4 | # (Optional) List of env variables used during compilation. 5 | env: 6 | - GO111MODULE=on 7 | - CGO_ENABLED=0 8 | 9 | # (Optional) Flags for the compiler. 10 | flags: 11 | - -trimpath 12 | - -tags=netgo 13 | 14 | # The OS to compile for. `GOOS` env variable will be set to this value. 15 | goos: linux 16 | 17 | # The architecture to compile for. `GOARCH` env variable will be set to this value. 18 | goarch: amd64 19 | 20 | # (Optional) Entrypoint to compile. 21 | main: ./cmd/sbom-scorecard/main.go 22 | 23 | # (Optional) Working directory. (default: root of the project) 24 | # dir: ./relative/path/to/dir 25 | 26 | # Binary output name. 27 | # {{ .Os }} will be replaced by goos field in the config file. 28 | # {{ .Arch }} will be replaced by goarch field in the config file. 29 | binary: sbom-scorecard-{{ .Os }}-{{ .Arch }} 30 | 31 | # (Optional) ldflags generated dynamically in the workflow, and set as the `evaluated-envs` input variables in the workflow. 32 | ldflags: 33 | - "-X main.Version={{ .Env.VERSION }}" 34 | - "-X main.Commit={{ .Env.COMMIT }}" 35 | - "-X main.CommitDate={{ .Env.COMMIT_DATE }}" 36 | - "-X main.TreeState={{ .Env.TREE_STATE }}" 37 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | @justinabrahms 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2022 eBay Inc 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VERSION=$(shell git describe --tags --always) 2 | COMMIT=$(shell git rev-parse HEAD) 3 | BUILD=$(shell date +%FT%T%z) 4 | PKG=github.com/eBay/sbom-scorecard 5 | 6 | 7 | LDFLAGS="-X $(PKG).version=$(VERSION) -X $(PKG).commit=$(COMMIT) -X $(PKG).date=$(BUILD)" 8 | 9 | .DEFAULT_GOAL := build 10 | 11 | .PHONY: build 12 | build: ## Build a version 13 | go build -ldflags ${LDFLAGS} -o bin/sbom-scorecard cmd/sbom-scorecard/main.go 14 | 15 | .PHONY: clean 16 | clean: ## Remove temporary files 17 | go clean 18 | 19 | .PHONY: test 20 | test: ## Run the unit tests 21 | echo 'mode: atomic' > coverage.txt && go test -covermode=atomic -coverprofile=coverage.txt -v -race -timeout=30s ./... 22 | 23 | phony: 24 | @echo Use specific targets to download individual needed files. 25 | 26 | examples: examples/julia.spdx.json examples/dropwizard.cyclonedx.json examples/openfeature-javasdk.cyclonedx.xml 27 | examples/julia.spdx.json: 28 | curl -Lo examples/julia.spdx.json https://github.com/JuliaLang/julia/raw/master/julia.spdx.json 29 | examples/dropwizard.cyclonedx.json: 30 | curl -Lo examples/dropwizard.cyclonedx.json https://github.com/CycloneDX/bom-examples/raw/master/SBOM/dropwizard-1.3.15/bom.json 31 | examples/openfeature-javasdk.cyclonedx.xml: 32 | curl -Lo examples/openfeature-javasdk.cyclonedx.xml https://s01.oss.sonatype.org/content/repositories/snapshots/dev/openfeature/sdk/0.3.1-SNAPSHOT/sdk-0.3.1-20221014.132148-1-cyclonedx.xml 33 | 34 | slsa: slsa/goreleaser-linux-amd64.yml slsa/goreleaser-linux-arm64.yml slsa/goreleaser-darwin-amd64.yml slsa/goreleaser-darwin-arm64.yml slsa/goreleaser-windows-amd64.yml slsa/goreleaser-windows-arm64.yml 35 | 36 | slsa/goreleaser-linux-amd64.yml: 37 | GOOS=linux GOARCH=amd64 make TEMPLATE 38 | slsa/goreleaser-linux-arm64.yml: 39 | GOOS=linux GOARCH=arm64 make TEMPLATE 40 | 41 | slsa/goreleaser-darwin-amd64.yml: 42 | GOOS=darwin GOARCH=amd64 make TEMPLATE 43 | slsa/goreleaser-darwin-arm64.yml: 44 | GOOS=darwin GOARCH=arm64 make TEMPLATE 45 | 46 | slsa/goreleaser-windows-amd64.yml: 47 | GOOS=windows GOARCH=amd64 make TEMPLATE 48 | slsa/goreleaser-windows-arm64.yml: 49 | GOOS=windows GOARCH=arm64 make TEMPLATE 50 | 51 | TEMPLATE: 52 | cat slsa/template.yml | sed -e s/OS_HERE/${GOOS}/g | sed -e s/ARCH_HERE/${GOARCH}/g > slsa/goreleaser-${GOOS}-${GOARCH}.yml 53 | 54 | gif: 55 | npx terminalizer render sbom-scorecard --output usage.gif 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SBOM Scorecard 2 | 3 | [![Project Status: WIP – Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](https://www.repostatus.org/badges/latest/wip.svg)](https://www.repostatus.org/#wip) 4 | 5 | When generating first-party SBOMs, it's hard to know if you're generating something good (e.g. rich metadata that you can query later) or not. This tool hopes to quantify what a well-generated SBOM looks like. 6 | 7 | SPDX, CycloneDX and Syft are all in scope for this repo. 8 | 9 | ![](./usage.gif) 10 | 11 | ![](./result.png) 12 | 13 | ## Installation and Usage 14 | 15 | 1. Download the pre-compiled, platform-appropriate binary from 16 | the project's [releases page](https://github.com/eBay/sbom-scorecard/releases) and save it as `sbom-scorecard`. 17 | 2. Install it via go: `go install github.com/ebay/sbom-scorecard/cmd/sbom-scorecard@latest` 18 | 3. Run it from source: `git clone https://github.com/eBay/sbom-scorecard; alias sbom-scorecard="go run $PWD/cmd/sbom-scorecard/main.go"` 19 | 20 | From there, you can score an SBOM with: 21 | 22 | ``` 23 | sbom-scorecard score examples/julia.spdx.json 24 | ``` 25 | 26 | We do our best to guess the right format, but you can specify it with: 27 | 28 | ``` 29 | sbom-scorecard score --sbomtype spdx examples/julia.spdx.json 30 | ``` 31 | 32 | For other options, run the help subcommand. 33 | 34 | ``` 35 | sbom-scorecard help 36 | ``` 37 | 38 | ## Scoring. 39 | 40 | Here are the metrics by which we score. This is evolving. 41 | 42 | 1. Is it a spec-compliant? 43 | 2. Does it have information about how it was generated? 44 | 1. Does it have the software that was used? 45 | 2. Do we know the version/sha of that software? 46 | 3. For the packages: 47 | 1. Do they have ids defined (purls, etc)? 48 | 2. Do they have versions and/or shas? 49 | 3. Do they have licenses defined? 50 | 51 | We weight these differently. 52 | 53 | Spec compliance is weighted 25%. 54 | Information about how an sbom was generated is worth 15%. 55 | The remaining 60% is split across the packages who are direct dependencies. 56 | 57 | ### Examples 58 | 59 | In this example, from the Julia project.. 60 | 61 | ``` 62 | 34 total packages 63 | 0 total files 64 | 100% have licenses. 65 | 0% have package digest. 66 | 0% have purls. 67 | 0% have CPEs. 68 | 0% have file digest. 69 | Spec valid? true 70 | ``` 71 | 72 | This would result in: 73 | | Criteria | Result | Points | 74 | |-----------------|--------|--------| 75 | | Spec compliant | true | 25/25 | 76 | | Generation Info | N/A | 15/15 | 77 | | Packages | | | 78 | | ...IDs | 0% | 0/20 | 79 | | ...versions | 0% | 0/20 | 80 | | ...licenses | 100% | 20/20 | 81 | 82 | So that's 60% (including the whole 15% because we don't have generation info implemented yet) 83 | 84 | This example is from the dropwizard project: 85 | 86 | ``` 87 | 167 total packages 88 | 79% have licenses. 89 | 100% have package digest. 90 | 100% have purls. 91 | 0% have CPEs. 92 | Spec valid? true 93 | ``` 94 | 95 | This results in: 96 | | Criteria | Result | Points | 97 | |-----------------|--------------------|--------| 98 | | Spec compliant | true | 25/25 | 99 | | Generation Info | N/A | 15/15 | 100 | | Packages | | | 101 | | ...IDs | 50% (missing CPEs) | 10/20 | 102 | | ...versions | 100% | 20/20 | 103 | | ...licenses | 79% | 16/20 | 104 | 105 | So that's 86% (including the 15% b/c generation info isn't implemented). 106 | 107 | ## Open Questions 108 | 109 | 1. Should package info really be split? 110 | 1. Should we break "license info" out as it's own top-level criteria? 111 | -------------------------------------------------------------------------------- /cmd/sbom-scorecard/cmd/root.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | func init() { 11 | rootCmd.AddCommand(scoreCmd) 12 | } 13 | 14 | var rootCmd = &cobra.Command{ 15 | Use: "sbom-scorecard", 16 | Short: "sbom-scorecard evaluates the quality of the SBOM", 17 | } 18 | 19 | func Execute() { 20 | if err := rootCmd.Execute(); err != nil { 21 | fmt.Fprintln(os.Stderr, err) 22 | os.Exit(1) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /cmd/sbom-scorecard/cmd/scorecard.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "errors" 8 | 9 | "strings" 10 | 11 | "github.com/ebay/sbom-scorecard/pkg/cdx" 12 | "github.com/ebay/sbom-scorecard/pkg/scorecard" 13 | "github.com/ebay/sbom-scorecard/pkg/spdx" 14 | "github.com/spf13/cobra" 15 | ) 16 | 17 | var flags = struct { 18 | sbomType string 19 | outputFormat string 20 | debug bool 21 | }{} 22 | 23 | type options struct { 24 | sbomType string 25 | // path to file being evaluated 26 | path string 27 | outputFormat string 28 | debug bool 29 | } 30 | 31 | func init() { 32 | scoreCmd.PersistentFlags().StringVar(&flags.sbomType, "sbomtype", "guess", "type of sbom being evaluated") 33 | scoreCmd.PersistentFlags().StringVar(&flags.outputFormat, "outputFormat", "text", "format to output") 34 | scoreCmd.PersistentFlags().BoolVar(&flags.debug, "debug", false, "debug output") 35 | 36 | _ = scoreCmd.MarkPersistentFlagRequired("sbomType") 37 | } 38 | 39 | func determineSbomType(filepath string) string { 40 | content, err := os.ReadFile(filepath) 41 | if err != nil { 42 | panic(fmt.Sprintf("Error! %v", err)) 43 | } 44 | 45 | if strings.Contains(strings.ToLower(string(content)), "spdx") { 46 | return "spdx" 47 | } 48 | return "cdx" 49 | } 50 | 51 | var scoreCmd = &cobra.Command{ 52 | Use: "score", 53 | Short: "score evaluates the SBOM being passed and outputs based on the composition and completion", 54 | Run: func(cmd *cobra.Command, args []string) { 55 | 56 | opts, err := validateFlags(args) 57 | if err != nil { 58 | fmt.Printf("unable to validate flags: %v\n", err) 59 | os.Exit(1) 60 | } 61 | 62 | var r scorecard.SbomReport 63 | 64 | if opts.sbomType == "guess" { 65 | opts.sbomType = determineSbomType(opts.path) 66 | if opts.debug { 67 | print("Guessed: " + opts.sbomType + "\n") 68 | } 69 | } 70 | 71 | switch opts.sbomType { 72 | case "spdx": 73 | r = spdx.GetSpdxReport(opts.path) 74 | case "cdx": 75 | r = cdx.GetCycloneDXReport(opts.path) 76 | } 77 | 78 | if opts.outputFormat == "json" { 79 | fmt.Println(scorecard.JsonGrade(r)) 80 | } else { 81 | if opts.debug { 82 | print(r.Report()) 83 | print("==\n") 84 | } 85 | scorecard.GradeTableFormat(r) 86 | } 87 | }, 88 | } 89 | 90 | func validateFlags(args []string) (options, error) { 91 | var opts options 92 | opts.sbomType = flags.sbomType 93 | if flags.sbomType != "spdx" && 94 | flags.sbomType != "cdx" && 95 | flags.sbomType != "guess" { 96 | return opts, errors.New(fmt.Sprintf("Unknown sbomType %s", flags.sbomType)) 97 | } 98 | 99 | opts.outputFormat = flags.outputFormat 100 | if flags.outputFormat != "text" && flags.outputFormat != "json" { 101 | return opts, errors.New(fmt.Sprintf("Unknown outputFormat %s", flags.outputFormat)) 102 | } 103 | 104 | if len(args) != 1 { 105 | return opts, fmt.Errorf("expected positional argument for file_path") 106 | } 107 | opts.path = args[0] 108 | opts.debug = flags.debug 109 | return opts, nil 110 | } 111 | -------------------------------------------------------------------------------- /cmd/sbom-scorecard/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/ebay/sbom-scorecard/cmd/sbom-scorecard/cmd" 5 | ) 6 | 7 | func main() { 8 | cmd.Execute() 9 | } 10 | -------------------------------------------------------------------------------- /examples/invalid.json: -------------------------------------------------------------------------------- 1 | { 2 | "makeJSON": "happy" 3 | }This is intentionally invalid 4 | -------------------------------------------------------------------------------- /examples/julia.spdx.json: -------------------------------------------------------------------------------- 1 | { 2 | "spdxVersion": "SPDX-2.2", 3 | "dataLicense": "CC0-1.0", 4 | "SPDXID": "SPDXRef-DOCUMENT", 5 | "name": "julia-spdx", 6 | "documentNamespace": "https://julialang.org/spdxdocs/julia-spdx-156599cd-b5aa-442c-a0d4-72ed73a46d16", 7 | "creationInfo": { 8 | "creators": [ 9 | "Organization: julialang.org ()", 10 | "Person: Simon Avery ()" 11 | ], 12 | "created": "2022-05-19T06:17:33Z" 13 | }, 14 | "packages": [ 15 | { 16 | "name": "Julia", 17 | "SPDXID": "SPDXRef-JuliaMain", 18 | "versionInfo": "1.9.0-DEV", 19 | "packageFileName": "./", 20 | "downloadLocation": "git+https://github.com/JuliaLang/julia.git@v1.9.0-DEV", 21 | "filesAnalyzed": false, 22 | "homepage": "https://julialang.org", 23 | "licenseConcluded": "LicenseRef-23", 24 | "licenseDeclared": "LicenseRef-23", 25 | "copyrightText": "Copyright (c) 2009-2022: Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors: https://github.com/JuliaLang/julia/contributors", 26 | "summary": "Julia is a high-level, high-performance dynamic language for technical computing.", 27 | "comment": "In addition to the source code described by this package, Julia pulls in code from many other repositories, which are also described in this document. See relationships for details." 28 | }, 29 | { 30 | "name": "Pkg.jl", 31 | "SPDXID": "SPDXRef-JuliaPkg", 32 | "downloadLocation": "git+https://github.com/JuliaLang/Pkg.jl.git", 33 | "filesAnalyzed": false, 34 | "homepage": "https://julialang.org", 35 | "sourceInfo": "The git hash of the version in use can be found in the file stdlib/Pkg.version", 36 | "licenseConcluded": "MIT", 37 | "licenseDeclared": "MIT", 38 | "copyrightText": "Copyright (c) 2017-2021: Stefan Karpinski, Kristoffer Carlsson, Fredrik Ekre, David Varela, Ian Butterworth, and contributors: https://github.com/JuliaLang/Pkg.jl/graphs/contributors", 39 | "summary": "Julia's package manager, shipped with Julia v1.0 and above" 40 | }, 41 | { 42 | "name": "Statistics.jl", 43 | "SPDXID": "SPDXRef-JuliaStatistics", 44 | "downloadLocation": "git+https://github.com/JuliaStats/Statistics.jl.git", 45 | "filesAnalyzed": false, 46 | "homepage": "https://juliastats.org", 47 | "sourceInfo": "The git hash of the version in use can be found in the file stdlib/Statistics.version", 48 | "licenseConcluded": "MIT", 49 | "licenseDeclared": "MIT", 50 | "copyrightText": "Copyright (c) 2012-2016: Jeff Bezanson, Stefan Karpinski, Viral B. Shah, Dahua Lin, Simon Byrne, Andreas Noack, Douglas Bates, John Myles White, Simon Kornblith, and other contributors.", 51 | "summary": "Development repository for the Statistics standard library (stdlib) that ships with Julia." 52 | }, 53 | { 54 | "name": "libCURL.jl", 55 | "SPDXID": "SPDXRef-JuliaCurl", 56 | "downloadLocation": "git+https://github.com/JuliaWeb/LibCURL.jl.git", 57 | "filesAnalyzed": false, 58 | "homepage": "https://julialang.org", 59 | "sourceInfo": "The git hash of the version in use can be found in the file stdlib/libCURL.version", 60 | "licenseConcluded": "MIT", 61 | "licenseDeclared": "MIT", 62 | "copyrightText": "Copyright (c) 2013: JuliaWeb contributors", 63 | "summary": "Julia wrapper for libCURL" 64 | }, 65 | { 66 | "name": "Downloads.jl", 67 | "SPDXID": "SPDXRef-JuliaDownloads", 68 | "downloadLocation": "git+https://github.com/JuliaLang/Downloads.jl.git", 69 | "filesAnalyzed": false, 70 | "homepage": "https://julialang.org", 71 | "sourceInfo": "The git hash of the version in use can be found in the file stdlib/Downloads.version", 72 | "licenseConcluded": "MIT", 73 | "licenseDeclared": "MIT", 74 | "copyrightText": "Copyright (c) 2020 Stefan Karpinski and contributors", 75 | "summary": "The Downloads package provides a single function, download, which provides cross-platform, multi-protocol, in-process download functionality implemented with libcurl." 76 | }, 77 | { 78 | "name": "ArgTools.jl", 79 | "SPDXID": "SPDXRef-JuliaArgTools", 80 | "downloadLocation": "git+https://github.com/JuliaIO/ArgTools.jl.git", 81 | "filesAnalyzed": false, 82 | "homepage": "https://julialang.org", 83 | "sourceInfo": "The git hash of the version in use can be found in the file stdlib/ArgTools.version", 84 | "licenseConcluded": "MIT", 85 | "licenseDeclared": "MIT", 86 | "copyrightText": "Copyright (c) 2020 Stefan Karpinski and contributors", 87 | "summary": "ArgTools provides tools for creating consistent, flexible APIs that work with various kinds of function arguments." 88 | }, 89 | { 90 | "name": "Tar.jl", 91 | "SPDXID": "SPDXRef-JuliaTar", 92 | "downloadLocation": "git+https://github.com/JuliaIO/Tar.jl.git", 93 | "filesAnalyzed": false, 94 | "homepage": "https://julialang.org", 95 | "sourceInfo": "The git hash of the version in use can be found in the file stdlib/Tar.version", 96 | "licenseConcluded": "MIT", 97 | "licenseDeclared": "MIT", 98 | "copyrightText": "Copyright (c) 2019 Stefan Karpinski and contributors", 99 | "summary": "The Tar package can list, extract and create POSIX TAR archives (tarballs) as specified in POSIX 1003.1-2001." 100 | }, 101 | { 102 | "name": "NetworkOptions.jl", 103 | "SPDXID": "SPDXRef-JuliaNetworkOptions", 104 | "downloadLocation": "git+https://github.com/JuliaLang/NetworkOptions.jl.git", 105 | "filesAnalyzed": false, 106 | "homepage": "https://julialang.org", 107 | "sourceInfo": "The git hash of the version in use can be found in the file stdlib/NetworkOptions.version", 108 | "licenseConcluded": "MIT", 109 | "licenseDeclared": "MIT", 110 | "copyrightText": "Copyright (c) 2020 Stefan Karpinski and contributors", 111 | "summary": "The NetworkOptions package acts as a mediator between ways of configuring network transport mechanisms (SSL/TLS, SSH, proxies, etc.) and Julia packages that provide access to transport mechanisms." 112 | }, 113 | { 114 | "name": "SuiteSparse.jl", 115 | "SPDXID": "SPDXRef-JuliaSuiteSparse", 116 | "downloadLocation": "git+https://github.com/JuliaSparse/SuiteSparse.jl.git", 117 | "filesAnalyzed": false, 118 | "homepage": "https://julialang.org", 119 | "sourceInfo": "The git hash of the version in use can be found in the file stdlib/SuiteSparse.version", 120 | "licenseConcluded": "MIT", 121 | "licenseDeclared": "MIT", 122 | "copyrightText": "Copyright (c) 2009-2021: Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors: https://github.com/JuliaLang/julia/contributors", 123 | "summary": "SuiteSparse.jl provides Julia wrappers for the SuiteSparse library, and provides Julia's sparse linear algebra capabilities - specifically the solvers." 124 | }, 125 | { 126 | "name": "SparseArrays.jl", 127 | "SPDXID": "SPDXRef-JuliaSparseArrays", 128 | "downloadLocation": "git+https://github.com/JuliaSparse/SparseArrays.jl.git", 129 | "filesAnalyzed": false, 130 | "homepage": "https://julialang.org", 131 | "sourceInfo": "The git hash of the version in use can be found in the file stdlib/SparseArrays.version", 132 | "licenseConcluded": "MIT", 133 | "licenseDeclared": "MIT", 134 | "copyrightText": "Copyright (c) 2009-2021: Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors: https://github.com/JuliaLang/julia/contributors", 135 | "summary": "SparseArrays.jl provides Julia's sparse linear algebra capabilities." 136 | }, 137 | { 138 | "name": "SHA.jl", 139 | "SPDXID": "SPDXRef-JuliaSHA", 140 | "downloadLocation": "git+https://github.com/JuliaCrypto/SHA.jl.git", 141 | "filesAnalyzed": false, 142 | "homepage": "https://julialang.org", 143 | "sourceInfo": "The git hash of the version in use can be found in the file stdlib/SHA.version", 144 | "licenseConcluded": "MIT", 145 | "licenseDeclared": "MIT", 146 | "copyrightText": "Copyright (c) 2014: Elliot Saba", 147 | "summary": "A performant, 100% native-julia SHA1, SHA2, and SHA3 implementation" 148 | }, 149 | { 150 | "name": "dSFMT", 151 | "SPDXID": "SPDXRef-dSFMT", 152 | "downloadLocation": "git+https://github.com/MersenneTwister-Lab/dSFMT.git", 153 | "filesAnalyzed": false, 154 | "homepage": "https://github.com/MersenneTwister-Lab/dSFMT", 155 | "sourceInfo": "The git hash of the version in use can be found in the file deps/dsfmt.version", 156 | "licenseConcluded": "BSD-3-Clause", 157 | "licenseDeclared": "BSD-3-Clause", 158 | "copyrightText": "Copyright (c) 2007, 2008, 2009 Mutsuo Saito, Makoto Matsumoto and Hiroshima University. Copyright (c) 2011, 2002 Mutsuo Saito, Makoto Matsumoto, Hiroshima University and The University of Tokyo.", 159 | "summary": "Double precision SIMD-oriented Fast Mersenne Twister" 160 | }, 161 | { 162 | "name": "OpenLibm", 163 | "SPDXID": "SPDXRef-OpenLibm", 164 | "downloadLocation": "git+https://github.com/JuliaMath/openlibm.git", 165 | "filesAnalyzed": false, 166 | "homepage": "https://julialang.org", 167 | "sourceInfo": "The git hash of the version in use can be found in the file deps/openlibm.version", 168 | "licenseConcluded": "MIT", 169 | "licenseDeclared": "MIT AND BSD-2-Clause-FreeBSD AND ISC", 170 | "copyrightText": "Copyright (c) 2011-14 The Julia Project. Copyright (c) 2008 Stephen L. Moshier steve@moshier.net Copyright 1992-2011 The FreeBSD Project. All rights reserved. Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.", 171 | "summary": "High quality system independent, portable, open source libm implementation" 172 | }, 173 | { 174 | "name": "GMP", 175 | "SPDXID": "SPDXRef-GMP", 176 | "downloadLocation": "https://gmplib.org/download/gmp/", 177 | "filesAnalyzed": false, 178 | "homepage": "https://gmplib.org/", 179 | "sourceInfo": "The version in use can be found in the file deps/gmp.version", 180 | "licenseConcluded": "LGPL-3.0-or-later", 181 | "licenseDeclared": "LGPL-3.0-or-later OR GPL-2.0-or-later", 182 | "copyrightText": "Copyright 1991, 1996, 1999, 2000, 2007 Free Software Foundation, Inc.", 183 | "summary": "GNU MP is a portable library written in C for arbitrary precision arithmetic on integers, rational numbers, and floating-point numbers." 184 | }, 185 | { 186 | "name": "libgit2", 187 | "SPDXID": "SPDXRef-libgit2", 188 | "downloadLocation": "git+https://github.com/libgit2/libgit2.git", 189 | "filesAnalyzed": false, 190 | "homepage": "https://libgit2.org", 191 | "sourceInfo": "The version in use can be found in the file deps/libgit2.version", 192 | "licenseConcluded": "LicenseRef-GPL-2.0-only-with-libgit2-exception", 193 | "licenseDeclared": "LicenseRef-GPL-2.0-only-with-libgit2-exception", 194 | "copyrightText": "libgit2 is Copyright (C) the libgit2 contributors, unless otherwise stated. See the AUTHORS file for details.", 195 | "summary": "A cross-platform, linkable library implementation of Git that you can use in your application." 196 | }, 197 | { 198 | "name": "curl", 199 | "SPDXID": "SPDXRef-curl", 200 | "downloadLocation": "git+https://github.com/curl/curl.git", 201 | "filesAnalyzed": false, 202 | "homepage": "https://curl.se", 203 | "sourceInfo": "The version in use can be found in the file deps/curl.version", 204 | "licenseConcluded": "curl", 205 | "licenseDeclared": "curl", 206 | "copyrightText": "Copyright (c) 1996 - 2021, Daniel Stenberg, daniel@haxx.se, and many contributors, see the THANKS file.", 207 | "summary": "A command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET and TFTP. libcurl offers a myriad of powerful features" 208 | }, 209 | { 210 | "name": "libssh2", 211 | "SPDXID": "SPDXRef-libssh2", 212 | "downloadLocation": "git+https://github.com/libssh2/libssh2.git", 213 | "filesAnalyzed": false, 214 | "homepage": "https://www.libssh2.org", 215 | "sourceInfo": "The version in use can be found in the file deps/libssh2.version", 216 | "licenseConcluded": "BSD-3-Clause", 217 | "licenseDeclared": "BSD-3-Clause", 218 | "copyrightText": "Copyright (c) 2004-2007 Sara Golemon \nCopyright (c) 2005,2006 Mikhail Gusarov \nCopyright (c) 2006-2007 The Written Word, Inc.\nCopyright (c) 2007 Eli Fant \nCopyright (c) 2009-2021 Daniel Stenberg\nCopyright (C) 2008, 2009 Simon Josefsson\nCopyright (c) 2000 Markus Friedl\nCopyright (c) 2015 Microsoft Corp.\nAll rights reserved.", 219 | "summary": "libssh2 is a library implementing the SSH2 protocol, available under the revised BSD license." 220 | }, 221 | { 222 | "name": "mbedtls", 223 | "SPDXID": "SPDXRef-mbedtls", 224 | "downloadLocation": "git+https://github.com/ARMmbed/mbedtls.git", 225 | "filesAnalyzed": false, 226 | "homepage": "https://tls.mbed.org", 227 | "sourceInfo": "The version in use can be found in the file deps/mbedtls.version", 228 | "licenseConcluded": "Apache-2.0", 229 | "licenseDeclared": "Apache-2.0", 230 | "copyrightText": "NOASSERTION", 231 | "summary": "An open source, portable, easy to use, readable and flexible SSL library." 232 | }, 233 | { 234 | "name": "mpfr", 235 | "SPDXID": "SPDXRef-mpfr", 236 | "downloadLocation": "https://www.mpfr.org/", 237 | "filesAnalyzed": false, 238 | "homepage": "https://www.mpfr.org/", 239 | "sourceInfo": "The version in use can be found in the file deps/mpfr.version", 240 | "licenseConcluded": "LGPL-3.0-or-later", 241 | "licenseDeclared": "LGPL-3.0-or-later", 242 | "copyrightText": "Copyright 2000-2020 Free Software Foundation, Inc.", 243 | "summary": "The MPFR library is a C library for multiple-precision floating-point computations with correct rounding." 244 | }, 245 | { 246 | "name": "OpenBLAS", 247 | "SPDXID": "SPDXRef-OpenBLAS", 248 | "downloadLocation": "git+https://github.com/xianyi/OpenBLAS.git", 249 | "filesAnalyzed": false, 250 | "homepage": "https://www.openblas.net", 251 | "sourceInfo": "The git hash of the version in use can be found in the file deps/openblas.version", 252 | "licenseConcluded": "BSD-3-Clause", 253 | "licenseDeclared": "BSD-3-Clause", 254 | "copyrightText": "Copyright (c) 2011-2014, The OpenBLAS Project", 255 | "summary": "OpenBLAS is an optimized BLAS library based on GotoBLAS2 1.13 BSD version." 256 | }, 257 | { 258 | "name": "LAPACK", 259 | "SPDXID": "SPDXRef-LAPACK", 260 | "downloadLocation": "https://www.netlib.org/lapack/", 261 | "filesAnalyzed": false, 262 | "homepage": "https://netlib.org/", 263 | "sourceInfo": "The version in use can be found in the file deps/openblas.version", 264 | "licenseConcluded": "BSD-3-Clause", 265 | "licenseDeclared": "BSD-3-Clause", 266 | "copyrightText": "Copyright (c) 1992-2013 The University of Tennessee and The University of Tennessee Research Foundation. All rights reserved.\nCopyright (c) 2000-2013 The University of California Berkeley. All rights reserved.\nCopyright (c) 2006-2013 The University of Colorado Denver. All rights reserved.", 267 | "summary": "LAPACK is written in Fortran 90 and provides routines for solving systems of simultaneous linear equations, least-squares solutions of linear systems of equations, eigenvalue problems, and singular value problems." 268 | }, 269 | { 270 | "name": "PCRE", 271 | "SPDXID": "SPDXRef-PCRE", 272 | "downloadLocation": "git+https://github.com/PhilipHazel/pcre2.git", 273 | "filesAnalyzed": false, 274 | "homepage": "https://www.pcre.org", 275 | "sourceInfo": "The version in use can be found in the file deps/pcre.version", 276 | "licenseConcluded": "BSD-3-Clause", 277 | "licenseDeclared": "BSD-3-Clause", 278 | "copyrightText": "Copyright (c) 1997-2021 University of Cambridge All rights reserved.\nCopyright(c) 2009-2021 Zoltan Herczeg\n", 279 | "summary": "PCRE2 is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language." 280 | }, 281 | { 282 | "name": "LibSuiteSparse", 283 | "SPDXID": "SPDXRef-LibSuiteSparse", 284 | "packageFileName": "./", 285 | "downloadLocation": "git+https://github.com/DrTimothyAldenDavis/SuiteSparse.git", 286 | "filesAnalyzed": false, 287 | "homepage": "https://people.engr.tamu.edu/davis/suitesparse.html", 288 | "sourceInfo": "The version in use can be found in the file deps/libsuitesparse.version", 289 | "licenseConcluded": "GPL-2.0-or-later", 290 | "licenseDeclared": "LGPL-2.0-or-later AND GPL-2.0-or-later AND BSD-3 AND Apache-2.0 ", 291 | "licenseComments": "SuiteSparse consists of many modules, each of which is licensed separately.", 292 | "copyrightText": "AMD, Copyright (c), 1996-2015, Timothy A. Davis,\nBTF, Copyright (C) 2004-2013, University of Florida\nCAMD, Copyright (c) by Timothy A. Davis, Yanqing Chen, Patrick R. Amestoy, and Iain S. Duff. All Rights Reserved.\nCCOLAMD: Copyright (C) 2005-2016, Univ. of Florida. Authors: Timothy A. Davis, Sivasankaran Rajamanickam, and Stefan Larimore. Closely based on COLAMD by Davis, Stefan Larimore, in collaboration with Esmond Ng, and John Gilbert.\nCHOLMOD/Check Module. Copyright (C) 2005-2006, Timothy A. Davis\nCHOLMOD/Cholesky module, Copyright (C) 2005-2006, Timothy A. Davis.\nCHOLMOD/Core Module. Copyright (C) 2005-2006, Univ. of Florida. Author: Timothy A. Davis.\nCHOLMOD/Demo Module. Copyright (C) 2005-2006, Timothy A. Davis.\nCHOLMOD/Include/* files. Copyright (C) 2005-2006, either Univ. of Florida or T. Davis, depending on the file\nCHOLMOD/MATLAB Module. Copyright (C) 2005-2006, Timothy A. Davis.\nCHOLMOD/MatrixOps Module. Copyright (C) 2005-2006, Timothy A. Davis.\nCHOLMOD/Modify Module. Copyright (C) 2005-2006, Timothy A. Davis and William W. Hager.\nCHOLMOD/Partition Module. Copyright (C) 2005-2006, Univ. of Florida. Author: Timothy A. Davis\nCHOLMOD/Supernodal Module. Copyright (C) 2005-2006, Timothy A. Davis\nCHOLMOD/Tcov Module. Copyright (C) 2005-2006, Timothy A. Davis\nCHOLMOD/Valgrind Module. Copyright (C) 2005-2006, Timothy A. Davis.\nCOLAMD, Copyright 1998-2016, Timothy A. Davis.\nCSparse, Copyright (c) 2006, Timothy A. Davis.\nCXSparse: Copyright (c) 2006, Timothy A. Davis.\nGPUQREngine, Copyright (c) 2013, Timothy A. Davis, Sencer Nuri Yeralan, and Sanjay Ranka.\nKLU, Copyright (C) 2004-2013, University of Florida by Timothy A. Davis and Ekanathan Palamadai.\nLDL, Copyright (c) 2005-2013 by Timothy A. Davis.\nThe MATLAB_Tools collection of packages is Copyright (c), Timothy A. Davis, All Rights Reserved, with the exception of the spqr_rank package, which is Copyright (c), Timothy A. Davis and Les Foster, All Rights Reserved\nMATLAB_Tools, SSMULT, Copyright (c) 2007-2011, Timothy A. Davis,\nMongoose Graph Partitioning Library Copyright (C) 2017-2018, Scott P. Kolodziej, Nuri S. Yeralan, Timothy A. Davis, William W. Hager\nRBio toolbox. Copyright (C) 2006-2009, Timothy A. Davis\nSLIP_LU: (c) 2019-2020, Chris Lourenco, Jinhao Chen, Erick Moreno-Centeno, Timothy A. Davis, Texas A&M University. \nSPQR, Copyright 2008-2016 by Timothy A. Davis.\nSuiteSparse_GPURuntime Copyright (c) 2013-2016, Timothy A. Davis, Sencer Nuri Yeralan, and Sanjay Ranka.\nUMFPACK, Copyright 1995-2009 by Timothy A. Davis.", 293 | "summary": "The official SuiteSparse library: a suite of sparse matrix algorithms authored or co-authored by Tim Davis, Texas A&M University" 294 | }, 295 | { 296 | "name": "LibBlasTrampoline", 297 | "SPDXID": "SPDXRef-LibBlasTrampoline", 298 | "downloadLocation": "git+https://github.com/JuliaLinearAlgebra/libblastrampoline.git", 299 | "filesAnalyzed": false, 300 | "homepage": "https://github.com/JuliaLinearAlgebra", 301 | "sourceInfo": "The version in use can be found in the file deps/blastrampoline.version", 302 | "licenseConcluded": "MIT", 303 | "licenseDeclared": "MIT", 304 | "copyrightText": "Copyright (c) 2021: Elliot Saba, Viral B. Shah, Julia Computing.", 305 | "summary": "Using PLT trampolines to provide a BLAS and LAPACK demuxing library." 306 | }, 307 | { 308 | "name": "NGHTTP2", 309 | "SPDXID": "SPDXRef-NGHTTP2", 310 | "downloadLocation": "git+https://github.com/nghttp2/nghttp2.git", 311 | "filesAnalyzed": false, 312 | "homepage": "https://nghttp2.org", 313 | "sourceInfo": "The version in use can be found in the file deps/Version.make", 314 | "licenseConcluded": "MIT", 315 | "licenseDeclared": "MIT", 316 | "copyrightText": "Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa\nCopyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors", 317 | "summary": "nghttp2 is an implementation of HTTP/2 and its header compression algorithm HPACK in C." 318 | }, 319 | { 320 | "name": "libunwind", 321 | "SPDXID": "SPDXRef-libunwind", 322 | "downloadLocation": "git+https://github.com/libunwind/libunwind.git", 323 | "filesAnalyzed": false, 324 | "homepage": "http://www.nongnu.org/libunwind/", 325 | "sourceInfo": "The git hash of the version in use can be found in the file deps/unwind.version", 326 | "licenseConcluded": "MIT", 327 | "licenseDeclared": "MIT", 328 | "copyrightText": "Copyright (c) 2002 Hewlett-Packard Co.", 329 | "summary": "The primary goal of this project is to define a portable and efficient C programming interface (API) to determine the call-chain of a program." 330 | }, 331 | { 332 | "name": "libuv", 333 | "SPDXID": "SPDXRef-libuv", 334 | "supplier": "Organization: julialang.org ()", 335 | "originator": "Organization: libuv.org ()", 336 | "downloadLocation": "git+https://github.com/JuliaLang/libuv.git", 337 | "filesAnalyzed": false, 338 | "homepage": "https://libuv.org", 339 | "sourceInfo": "The git hash of the version in use can be found in the file deps/libuv.version", 340 | "licenseConcluded": "MIT", 341 | "licenseDeclared": "MIT", 342 | "copyrightText": "Copyright (c) 2015-present libuv project contributors", 343 | "summary": "libuv is a multi-platform support library with a focus on asynchronous I/O. It was primarily developed for use by Node.js, but it's also used by Luvit, Julia, pyuv, and others.", 344 | "comment": "The Julia project has forked libuv and maintains their own repository of the code" 345 | }, 346 | { 347 | "name": "llvm", 348 | "SPDXID": "SPDXRef-llvm", 349 | "supplier": "Organization: julialang.org ()", 350 | "originator": "Organization: llvm.org ()", 351 | "downloadLocation": "git+https://github.com/JuliaLang/llvm-project.git", 352 | "filesAnalyzed": false, 353 | "homepage": "https://llvm.org", 354 | "sourceInfo": "The version in use can be found in the file deps/llvm.version", 355 | "licenseConcluded": "Apache-2.0 WITH LLVM-exception", 356 | "licenseDeclared": "Apache-2.0 WITH LLVM-exception", 357 | "copyrightText": "The LLVM project does not collect copyright assignments, which means that the copyright for the code in the project is held by the respective contributors", 358 | "summary": "The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.", 359 | "comment": "The Julia project has forked llvm and maintains their own repository of the code" 360 | }, 361 | { 362 | "name": "utf8proc", 363 | "SPDXID": "SPDXRef-utf8proc", 364 | "downloadLocation": "git+https://github.com/JuliaLang/utf8proc.git", 365 | "filesAnalyzed": false, 366 | "homepage": "https://github.com/JuliaStrings/utf8proc", 367 | "sourceInfo": "The git hash of the version in use can be found in the file deps/utf8proc.version", 368 | "licenseConcluded": "MIT", 369 | "licenseDeclared": "MIT", 370 | "copyrightText": "Copyright © 2014-2019 by Steven G. Johnson, Jiahao Chen, Tony Kelman, Jonas Fonseca, and other contributors listed in the git history.", 371 | "summary": "utf8proc is a small, clean C library that provides Unicode normalization, case-folding, and other operations for data in the UTF-8 encoding." 372 | }, 373 | { 374 | "name": "7-Zip", 375 | "SPDXID": "SPDXRef-7zip", 376 | "downloadLocation": "https://sourceforge.net/projects/p7zip/files/p7zip", 377 | "filesAnalyzed": false, 378 | "homepage": "https://www.7-zip.org", 379 | "sourceInfo": "The version in use can be found in the file deps/p7zip.version", 380 | "licenseConcluded": "LGPL-3.0-or-later", 381 | "licenseDeclared": "LGPL-3.0-or-later AND BSD-3", 382 | "copyrightText": "Copyright (C) 1999-2021 Igor Pavlov", 383 | "summary": "7-Zip is a file archiver with a high compression ratio." 384 | }, 385 | { 386 | "name": "zlib", 387 | "SPDXID": "SPDXRef-zlib", 388 | "downloadLocation": "git+https://github.com/madler/zlib.git", 389 | "filesAnalyzed": false, 390 | "homepage": "https://zlib.net", 391 | "sourceInfo": "The git hash of the version in use can be found in the file deps/zlib.version", 392 | "licenseConcluded": "Zlib", 393 | "licenseDeclared": "Zlib", 394 | "copyrightText": "Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler", 395 | "summary": "A massively spiffy yet delicately unobtrusive compression library." 396 | }, 397 | { 398 | "name": "patchelf", 399 | "SPDXID": "SPDXRef-patchelf", 400 | "downloadLocation": "git+https://github.com/NixOS/patchelf.git", 401 | "filesAnalyzed": false, 402 | "homepage": "https://nixos.org/patchelf.html", 403 | "sourceInfo": "The version in use can be found in the file deps/patchelf.version", 404 | "licenseConcluded": "GPL-3.0-or-later", 405 | "licenseDeclared": "GPL-3.0-or-later", 406 | "copyrightText": "Copyright (C) 2007 Free Software Foundation, Inc. ", 407 | "summary": "A small utility to modify the dynamic linker and RPATH of ELF executables.", 408 | "comment": "PATCHELF is not part of the Julia binary. It is a tool used as part of building the binary, a bit like a compiler. Julia chooses to build the tool from source during the build process as a convenience." 409 | }, 410 | { 411 | "name": "objconv", 412 | "SPDXID": "SPDXRef-objconv", 413 | "downloadLocation": "https://www.agner.org/optimize/objconv.zip", 414 | "filesAnalyzed": false, 415 | "homepage": "https://www.agner.org/optimize/#objconv", 416 | "licenseConcluded": "GPL-3.0-or-later", 417 | "licenseDeclared": "GPL-3.0-or-later", 418 | "copyrightText": "By Agner Fog © 2018", 419 | "summary": "A utility for cross-platform development of function libraries, for converting and modifying object files and for dumping and disassembling object and executable files for all x86 and x86-64 platforms.", 420 | "comment": "OBJCONV is not part of the Julia binary. It is a tool used as part of building the binary, a bit like a compiler. Julia chooses to build the tool from source during the build process as a convenience." 421 | }, 422 | { 423 | "name": "libwhich", 424 | "SPDXID": "SPDXRef-libwhich", 425 | "downloadLocation": "git+https://github.com/vtjnash/libwhich.git", 426 | "filesAnalyzed": false, 427 | "homepage": "https://github.com/vtjnash/libwhich", 428 | "sourceInfo": "The git hash of the version in use can be found in the file stdlib/libwhich.version", 429 | "licenseConcluded": "MIT", 430 | "licenseDeclared": "MIT", 431 | "copyrightText": "Copyright (c) 2017 Jameson Nash", 432 | "summary": "Like `which`, for dynamic libraries", 433 | "comment": "LIBWHICH is not part of the Julia binary. It is a tool used as part of building the binary, a bit like a compiler. Julia chooses to build the tool from source during the build process as a convenience." 434 | } 435 | ], 436 | "hasExtractedLicensingInfos": [ 437 | { 438 | "licenseId": "LicenseRef-GPL-2.0-only-with-libgit2-exception", 439 | "extractedText": "Note that the only valid version of the GPL as far as this project is concerned is _this_ particular version of the license (ie v2, not v2.2 or v3.x or whatever), unless explicitly otherwise stated.\n----------------------------------------------------------------------\nIn addition to the permissions in the GNU General Public License, the authors give you unlimited permission to link the compiled version of this library into combinations with other programs, and to distribute those combinations without any restriction coming from the use of this file. (The General Public License restrictions do apply in other respects; for example, they cover modification of the file, and distribution when not linked into a combined executable.)\n----------------------------------------------------------------------\nGNU GENERAL PUBLIC LICENSE\nVersion 2, June 1991\n\nCopyright (C) 1989, 1991 Free Software Foundation, Inc.\n59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\nEveryone is permitted to copy and distribute verbatim copies\nof this license document, but changing it is not allowed.\n... [more text]", 440 | "name": "GPL-2.0-only-with-libgit2-exception" 441 | } 442 | ], 443 | "relationships": [ 444 | { 445 | "spdxElementId": "SPDXRef-JuliaPkg", 446 | "relationshipType": "BUILD_DEPENDENCY_OF", 447 | "relatedSpdxElement": "SPDXRef-JuliaMain" 448 | }, 449 | { 450 | "spdxElementId": "SPDXRef-JuliaStatistics", 451 | "relationshipType": "BUILD_DEPENDENCY_OF", 452 | "relatedSpdxElement": "SPDXRef-JuliaMain" 453 | }, 454 | { 455 | "spdxElementId": "SPDXRef-JuliaCurl", 456 | "relationshipType": "BUILD_DEPENDENCY_OF", 457 | "relatedSpdxElement": "SPDXRef-JuliaMain" 458 | }, 459 | { 460 | "spdxElementId": "SPDXRef-JuliaDownloads", 461 | "relationshipType": "BUILD_DEPENDENCY_OF", 462 | "relatedSpdxElement": "SPDXRef-JuliaMain" 463 | }, 464 | { 465 | "spdxElementId": "SPDXRef-JuliaArgTools", 466 | "relationshipType": "BUILD_DEPENDENCY_OF", 467 | "relatedSpdxElement": "SPDXRef-JuliaMain" 468 | }, 469 | { 470 | "spdxElementId": "SPDXRef-JuliaTar", 471 | "relationshipType": "BUILD_DEPENDENCY_OF", 472 | "relatedSpdxElement": "SPDXRef-JuliaMain" 473 | }, 474 | { 475 | "spdxElementId": "SPDXRef-JuliaNetworkOptions", 476 | "relationshipType": "BUILD_DEPENDENCY_OF", 477 | "relatedSpdxElement": "SPDXRef-JuliaMain" 478 | }, 479 | { 480 | "spdxElementId": "SPDXRef-JuliaSuiteSparse", 481 | "relationshipType": "BUILD_DEPENDENCY_OF", 482 | "relatedSpdxElement": "SPDXRef-JuliaMain" 483 | }, 484 | { 485 | "spdxElementId": "SPDXRef-JuliaSparseArrays", 486 | "relationshipType": "BUILD_DEPENDENCY_OF", 487 | "relatedSpdxElement": "SPDXRef-JuliaMain" 488 | }, 489 | { 490 | "spdxElementId": "SPDXRef-JuliaSHA", 491 | "relationshipType": "BUILD_DEPENDENCY_OF", 492 | "relatedSpdxElement": "SPDXRef-JuliaMain" 493 | }, 494 | { 495 | "spdxElementId": "SPDXRef-dSFMT", 496 | "relationshipType": "BUILD_DEPENDENCY_OF", 497 | "relatedSpdxElement": "SPDXRef-JuliaMain" 498 | }, 499 | { 500 | "spdxElementId": "SPDXRef-OpenLibm", 501 | "relationshipType": "BUILD_DEPENDENCY_OF", 502 | "relatedSpdxElement": "SPDXRef-JuliaMain" 503 | }, 504 | { 505 | "spdxElementId": "SPDXRef-GMP", 506 | "relationshipType": "BUILD_DEPENDENCY_OF", 507 | "relatedSpdxElement": "SPDXRef-JuliaMain" 508 | }, 509 | { 510 | "spdxElementId": "SPDXRef-libgit2", 511 | "relationshipType": "BUILD_DEPENDENCY_OF", 512 | "relatedSpdxElement": "SPDXRef-JuliaMain" 513 | }, 514 | { 515 | "spdxElementId": "SPDXRef-curl", 516 | "relationshipType": "BUILD_DEPENDENCY_OF", 517 | "relatedSpdxElement": "SPDXRef-JuliaMain" 518 | }, 519 | { 520 | "spdxElementId": "SPDXRef-libssh2", 521 | "relationshipType": "BUILD_DEPENDENCY_OF", 522 | "relatedSpdxElement": "SPDXRef-JuliaMain" 523 | }, 524 | { 525 | "spdxElementId": "SPDXRef-mbedtls", 526 | "relationshipType": "BUILD_DEPENDENCY_OF", 527 | "relatedSpdxElement": "SPDXRef-JuliaMain" 528 | }, 529 | { 530 | "spdxElementId": "SPDXRef-mpfr", 531 | "relationshipType": "BUILD_DEPENDENCY_OF", 532 | "relatedSpdxElement": "SPDXRef-JuliaMain" 533 | }, 534 | { 535 | "spdxElementId": "SPDXRef-OpenBLAS", 536 | "relationshipType": "BUILD_DEPENDENCY_OF", 537 | "relatedSpdxElement": "SPDXRef-JuliaMain" 538 | }, 539 | { 540 | "spdxElementId": "SPDXRef-LAPACK", 541 | "relationshipType": "BUILD_DEPENDENCY_OF", 542 | "relatedSpdxElement": "SPDXRef-JuliaMain" 543 | }, 544 | { 545 | "spdxElementId": "SPDXRef-PCRE", 546 | "relationshipType": "BUILD_DEPENDENCY_OF", 547 | "relatedSpdxElement": "SPDXRef-JuliaMain" 548 | }, 549 | { 550 | "spdxElementId": "SPDXRef-LibSuiteSparse", 551 | "relationshipType": "BUILD_DEPENDENCY_OF", 552 | "relatedSpdxElement": "SPDXRef-JuliaMain" 553 | }, 554 | { 555 | "spdxElementId": "SPDXRef-LibBlasTrampoline", 556 | "relationshipType": "BUILD_DEPENDENCY_OF", 557 | "relatedSpdxElement": "SPDXRef-JuliaMain" 558 | }, 559 | { 560 | "spdxElementId": "SPDXRef-NGHTTP2", 561 | "relationshipType": "BUILD_DEPENDENCY_OF", 562 | "relatedSpdxElement": "SPDXRef-JuliaMain" 563 | }, 564 | { 565 | "spdxElementId": "SPDXRef-libunwind", 566 | "relationshipType": "BUILD_DEPENDENCY_OF", 567 | "relatedSpdxElement": "SPDXRef-JuliaMain" 568 | }, 569 | { 570 | "spdxElementId": "SPDXRef-libuv", 571 | "relationshipType": "BUILD_DEPENDENCY_OF", 572 | "relatedSpdxElement": "SPDXRef-JuliaMain" 573 | }, 574 | { 575 | "spdxElementId": "SPDXRef-llvm", 576 | "relationshipType": "BUILD_DEPENDENCY_OF", 577 | "relatedSpdxElement": "SPDXRef-JuliaMain" 578 | }, 579 | { 580 | "spdxElementId": "SPDXRef-utf8proc", 581 | "relationshipType": "BUILD_DEPENDENCY_OF", 582 | "relatedSpdxElement": "SPDXRef-JuliaMain" 583 | }, 584 | { 585 | "spdxElementId": "SPDXRef-7zip", 586 | "relationshipType": "RUNTIME_DEPENDENCY_OF", 587 | "relatedSpdxElement": "SPDXRef-JuliaMain" 588 | }, 589 | { 590 | "spdxElementId": "SPDXRef-zlib", 591 | "relationshipType": "BUILD_DEPENDENCY_OF", 592 | "relatedSpdxElement": "SPDXRef-JuliaMain" 593 | }, 594 | { 595 | "spdxElementId": "SPDXRef-patchelf", 596 | "relationshipType": "BUILD_TOOL_OF", 597 | "relatedSpdxElement": "SPDXRef-JuliaMain" 598 | }, 599 | { 600 | "spdxElementId": "SPDXRef-objconv", 601 | "relationshipType": "BUILD_TOOL_OF", 602 | "relatedSpdxElement": "SPDXRef-JuliaMain" 603 | }, 604 | { 605 | "spdxElementId": "SPDXRef-libwhich", 606 | "relationshipType": "BUILD_TOOL_OF", 607 | "relatedSpdxElement": "SPDXRef-JuliaMain" 608 | } 609 | ], 610 | "documentDescribes": [ 611 | "SPDXRef-JuliaMain" 612 | ] 613 | } 614 | -------------------------------------------------------------------------------- /examples/openfeature-javasdk.cyclonedx.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2022-10-14T13:22:20Z 5 | 6 | 7 | OWASP Foundation 8 | CycloneDX Maven plugin 9 | 2.7.2 10 | 11 | f4f0e5aa6c0d5f709b304511547647a6 12 | 13a77f9af6a286c9bfc8c00e5d75ff6e9920d4ce 13 | d565f805cfd5e57af6a345e537e78b42ffd56fad094c74443e2a197a4e097538 14 | 92ff49fbb954b0341c38daddb30965fd9e8bb909e7e8a66dc65da5d6a958d021c6fe611c0b12314ae02f849de95101efe5b93470050dfb8090a459481ffa736a 15 | e15a47303e035e6612c37f08ebc105674f84cafd779ab52398ce263e67ce93d9d5e4c7c2ddda2f73584b6071a9f1a9da 16 | 17 | 18 | 19 | 20 | dev.openfeature 21 | sdk 22 | 0.3.1-SNAPSHOT 23 | This is the Java implementation of OpenFeature, a vendor-agnostic abstraction library for evaluating feature flags. 24 | 25 | 26 | Apache-2.0 27 | https://www.apache.org/licenses/LICENSE-2.0 28 | 29 | 30 | pkg:maven/dev.openfeature/sdk@0.3.1-SNAPSHOT?type=jar 31 | https://github.com/open-feature/java-sdk 32 | 33 | 34 | 35 | 36 | org.projectlombok 37 | lombok 38 | 1.18.24 39 | Spice up your java: Automatic Resource Management, automatic generation of getters, setters, equals, hashCode and toString, and more! 40 | required 41 | 42 | a1651eaa9c999c61131d32feab16fcde 43 | 13a394eed5c4f9efb2a6d956e2086f1d81e857d9 44 | d3584bc2db03f059f984fb0a9c119aac1fa0da578a448e69fc3f68b36584c749 45 | 8cc3aadb065b747bfe1b0741bb83ecdffe710692f31bd59e95907ff755d424c7586d3e532e7c5660509f610799f74d65956bdb5eba98a8871a449dd3d4cba061 46 | 4201d85661dfdcd98e2094f093e9ffee1b6e4d0aa89062dcff01d7880c6933ae190e1d8a452502c206e912bb8880f119 47 | 48 | 49 | 50 | MIT 51 | 52 | 53 | pkg:maven/org.projectlombok/lombok@1.18.24?type=jar 54 | https://github.com/projectlombok/lombok/issueshttp://github.com/projectlombok/lombok 55 | 56 | 57 | com.github.spotbugs 58 | spotbugs 59 | 4.7.2 60 | SpotBugs: Because it's easy! 61 | optional 62 | 63 | b0f9b609636c8cd55f1da51f2d637c19 64 | f4f76809e3a2bd998f6d9aa74fed05d0a7402ceb 65 | df5205f4d87ed53ff5b847c6aedc55d605966c0f8f9820d9c6be5ba517b09bcd 66 | 8e0fb2091a546b4d40110903ac059c0b0bda81be500e60bc78dfb4751248e978dcda0f60407b6e040fe173113769f763e44c3052c165e24289f157fd6ee63fce 67 | b01d1dc155a38afe59983c3ca3f78b0815cd2e6f9a6627b31b4b8da7f0ca5de7e7b163cb58d542a05d7aa26f99e6fc45 68 | 69 | 70 | 71 | LGPL-2.1-only 72 | 73 | 74 | pkg:maven/com.github.spotbugs/spotbugs@4.7.2?type=jar 75 | https://github.com/spotbugs/spotbugs/ 76 | 77 | 78 | OW2 79 | org.ow2.asm 80 | asm 81 | 9.3 82 | ASM, a very small and fast Java bytecode manipulation framework 83 | 84 | e1c3b96035117ab516ffe0de9bd696e0 85 | 8e6300ef51c1d801a7ed62d07cd221aca3a90640 86 | 1263369b59e29c943918de11d6d6152e2ec6085ce63e5710516f8c67d368e4bc 87 | 04362f50a2b66934c2635196bf8e6bd2adbe4435f312d1d97f4733c911e070f5693941a70f586928437043d01d58994325e63744e71886ae53a62c824927a4d4 88 | 304aa6673d587a68a06dd8601c6db0dc4d387f89a058b7600459522d94780e9e8d87a2778604fc41b81c43a57bf49ad6 89 | 90 | 91 | 92 | BSD-3-Clause 93 | https://opensource.org/licenses/BSD-3-Clause 94 | 95 | 96 | pkg:maven/org.ow2.asm/asm@9.3?type=jar 97 | http://www.ow2.org/https://gitlab.ow2.org/asm/asm/issueshttps://mail.ow2.org/wws/arc/asm/https://gitlab.ow2.org/asm/asm/ 98 | 99 | 100 | OW2 101 | org.ow2.asm 102 | asm-analysis 103 | 9.3 104 | Static code analysis API of ASM, a very small and fast Java bytecode manipulation framework 105 | 106 | 11e43c0220b3f6b4791b8abf7b4cc7ef 107 | 4b071f211b37c38e0e9f5998550197c8593f6ad8 108 | 37fd5392bb2cf4c15f202ffefd46d0e92bb34ff848c549f30d426a60d6b29495 109 | 0bb033b176c8893bfceba098381f5fef429096d5fe9c6b3eb6fdaac63d88dd059d44f3f296851573fe461888288ca2fa61dadae30530fa08fb3d6214c27915fe 110 | dc2de1e9a75eac66c2ea9b02e7b80f3ec34d20c59bb8ab963a32bc759103f9f67395e0e258fda8f8ad4d5477d8a1c4c5 111 | 112 | 113 | 114 | BSD-3-Clause 115 | https://opensource.org/licenses/BSD-3-Clause 116 | 117 | 118 | pkg:maven/org.ow2.asm/asm-analysis@9.3?type=jar 119 | http://www.ow2.org/https://gitlab.ow2.org/asm/asm/issueshttps://mail.ow2.org/wws/arc/asm/https://gitlab.ow2.org/asm/asm/ 120 | 121 | 122 | OW2 123 | org.ow2.asm 124 | asm-commons 125 | 9.3 126 | Usefull class adapters based on ASM, a very small and fast Java bytecode manipulation framework 127 | 128 | 16e6ac17d33ad97baa415c42e9d93d38 129 | 1f2a432d1212f5c352ae607d7b61dcae20c20af5 130 | a347c24732db2aead106b6e5996a015b06a3ef86e790a4f75b61761f0d2f7f39 131 | 0bd9c61553808b8a12822f009ea5622918033a9fa8cb6e3ef319bbff08dda00cf439b5653f25d8f3362f02166530a0eabe2664f1169bcd63e2ed93a603c13874 132 | 3efa92bf8e3fd41bb72728979e5e1fba057bd45da2b860c4566a2295d0885a2645413d0e0a35e832ea767aba040935fc 133 | 134 | 135 | 136 | BSD-3-Clause 137 | https://opensource.org/licenses/BSD-3-Clause 138 | 139 | 140 | pkg:maven/org.ow2.asm/asm-commons@9.3?type=jar 141 | http://www.ow2.org/https://gitlab.ow2.org/asm/asm/issueshttps://mail.ow2.org/wws/arc/asm/https://gitlab.ow2.org/asm/asm/ 142 | 143 | 144 | OW2 145 | org.ow2.asm 146 | asm-tree 147 | 9.3 148 | Tree API of ASM, a very small and fast Java bytecode manipulation framework 149 | 150 | f087bfb911ff93957e44860de3e73c46 151 | 78d2ecd61318b5a58cd04fb237636c0e86b77d97 152 | ae629c2609f39681ef8d140a42a23800464a94f2d23e36d8f25cd10d5e4caff4 153 | 666318e09f4ae02652a64ce2ddd4dd51275a1917108061155aa8d1d9956e9d54bc259d0586ed7cd745c6ac00ab54fbfdd577f6ce915a158fc2eef373d65d445c 154 | 8cb10354310a0a47ecf49388ea4fa1410988e5ec6bacba661496791c947cfc97d6b5765c64703c05f54b1cb79281d5fa 155 | 156 | 157 | 158 | BSD-3-Clause 159 | https://opensource.org/licenses/BSD-3-Clause 160 | 161 | 162 | pkg:maven/org.ow2.asm/asm-tree@9.3?type=jar 163 | http://www.ow2.org/https://gitlab.ow2.org/asm/asm/issueshttps://mail.ow2.org/wws/arc/asm/https://gitlab.ow2.org/asm/asm/ 164 | 165 | 166 | OW2 167 | org.ow2.asm 168 | asm-util 169 | 9.3 170 | Utilities for ASM, a very small and fast Java bytecode manipulation framework 171 | 172 | d6d0ac4e5c0be9a25a426c70c714b17b 173 | 9595bc05510d0bd4b610188b77333fe4851a1975 174 | 70f78f291ca0298afdb567fa85c5667869bc3da3914784816413853994962192 175 | cd37f77075631784b1b3d62cbbcb610160780885f333b4be7d90a9667e31f731fe6b152793ed56fe862fc2d0772a960ed8056791f7d273c047c0e9541a0d5b39 176 | 999f032b801c20e08a6160efa2f2b8c12950a5d4d6bd764c9cb5e05b2fe1949e0df9426346f3c5c7a25fd93669208b64 177 | 178 | 179 | 180 | BSD-3-Clause 181 | https://opensource.org/licenses/BSD-3-Clause 182 | 183 | 184 | pkg:maven/org.ow2.asm/asm-util@9.3?type=jar 185 | http://www.ow2.org/https://gitlab.ow2.org/asm/asm/issueshttps://mail.ow2.org/wws/arc/asm/https://gitlab.ow2.org/asm/asm/ 186 | 187 | 188 | The Apache Software Foundation 189 | org.apache.bcel 190 | bcel 191 | 6.5.0 192 | Apache Commons Bytecode Engineering Library 193 | 194 | 4de81e833dd77627809d1458b984d2fa 195 | 79b1975ec0c7a6c1a15e19fb3a58cc4041b4aaea 196 | bdeb381d0d19999e221e6a0f8d8bf44f5b19c2e57eabf68b70dc098652aefaf5 197 | bbc1dcf1ec8ce9f62afebc08011fdbe32e2712967d76af5ae19b29ee5aaa8be9dfef14fcf30257a4ca9dfba34e9701aa12dc3acb880be6df874a36d11469d6df 198 | 9f4d2fa4462584089a941aa239fec7d8bff848eeee8ce0e8eee7d5298d5371c0b8e50e25d96d8d2a93ef58454d4e4fd3 199 | 200 | 201 | 202 | Apache-2.0 203 | 204 | 205 | pkg:maven/org.apache.bcel/bcel@6.5.0?type=jar 206 | http://www.apache.org/https://issues.apache.org/jira/browse/BCELhttps://mail-archives.apache.org/mod_mbox/commons-user/https://gitbox.apache.org/repos/asf?p=commons-bcel.githttps://builds.apache.org/https://repository.apache.org/service/local/staging/deploy/maven2 207 | 208 | 209 | net.jcip 210 | jcip-annotations 211 | 1.0 212 | 213 | 9d5272954896c5a5d234f66b7372b17a 214 | afba4942caaeaf46aab0b976afd57cc7c181467e 215 | be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0 216 | cb312b3f571d91ef183c119d878f50464ffd97f853b7311cba386463f295e8b7b3a5a89ed4269a045cacd5aa7cb4c803d4882854a0fddefa9bbc28c72aa6c786 217 | 20d12f4a68736b8df736b1de233baff5d8ac5d71b92a1ca10dc1eb61293ef88bd3cb434ab71e9027a6d303849e098f28 218 | 219 | 220 | pkg:maven/net.jcip/jcip-annotations@1.0?type=jar 221 | 222 | 223 | org.dom4j 224 | dom4j 225 | 2.1.3 226 | flexible XML framework for Java 227 | 228 | 41efcf234c5a05a8c590f9b51d53ca66 229 | a75914155a9f5808963170ec20653668a2ffd2fd 230 | 549f3007c6290f6a901e57d1d331b4ed0e6bf7384f78bf10316ffceeca834de6 231 | c17d210d2a3d304ae03f725fcc6644e44185c945807f4980681972cbff946b5468d1dec84eb4f660627ee1f86ad4b8372990cd63ab956d4eb75a22d20dbd9cd1 232 | 930553b442d977537ccc76cf230d28f4c41d19ff438a5a33481942c3cc4dbe42378180c5cfdaf3872a0a8ec5e3518bb5 233 | 234 | 235 | 236 | BSD-3-Clause 237 | 238 | 239 | pkg:maven/org.dom4j/dom4j@2.1.3?type=jar 240 | 241 | 242 | The Apache Software Foundation 243 | org.apache.commons 244 | commons-lang3 245 | 3.12.0 246 | Apache Commons Lang, a package of Java utility classes for the 247 | classes that are in java.lang's hierarchy, or are considered to be so 248 | standard as to justify existence in java.lang. 249 | 250 | 19fe50567358922bdad277959ea69545 251 | c6842c86792ff03b9f1d1fe2aab8dc23aa6c6f0e 252 | d919d904486c037f8d193412da0c92e22a9fa24230b9d67a57855c5c31c7e94e 253 | fbdbc0943cb3498b0148e86a39b773f97c8e6013740f72dbc727faeabea402073e2cc8c4d68198e5fc6b08a13b7700236292e99d4785f2c9989f2e5fac11fd81 254 | c34b8a0e0eba2168ad56fedeb7a1d710b6f1d3f1ce6aae99a4e0247bd120efbbadc8dcb2f731045b8a16e3efd30604dc 255 | 256 | 257 | 258 | Apache-2.0 259 | 260 | 261 | pkg:maven/org.apache.commons/commons-lang3@3.12.0?type=jar 262 | https://issues.apache.org/jira/browse/LANGhttps://gitbox.apache.org/repos/asf?p=commons-lang.githttps://builds.apache.org/https://mail-archives.apache.org/mod_mbox/commons-user/https://www.apache.org/https://repository.apache.org/service/local/staging/deploy/maven2 263 | 264 | 265 | The Apache Software Foundation 266 | org.apache.commons 267 | commons-text 268 | 1.9 269 | Apache Commons Text is a library focused on algorithms working on strings. 270 | 271 | c1c130c369aa86bfe4f7a7a920bc0223 272 | ba6ac8c2807490944a0a27f6f8e68fb5ed2e80e2 273 | 0812f284ac5dd0d617461d9a2ab6ac6811137f25122dfffd4788a4871e732d00 274 | ad39787c96445737904e343593c03aa4c4e76bd1516ff45e70fc1efd8a53439b1b104c3b0fed4e431d9291ebabf4bff2e5547e0c6510f59160b8ea620bad2ae2 275 | 1dbd63c231233e8f24d76a19d7676a136e68abe4fc1ab9dcd4457ef9ab31deb30d5efc7c89372315b9375689d2a590a1 276 | 277 | 278 | 279 | Apache-2.0 280 | 281 | 282 | pkg:maven/org.apache.commons/commons-text@1.9?type=jar 283 | https://issues.apache.org/jira/browse/TEXThttps://gitbox.apache.org/repos/asf?p=commons-text.githttps://builds.apache.org/https://mail-archives.apache.org/mod_mbox/commons-user/https://www.apache.org/https://repository.apache.org/service/local/staging/deploy/maven2 284 | 285 | 286 | com.github.spotbugs 287 | spotbugs-annotations 288 | 4.7.2 289 | Annotations the SpotBugs tool supports 290 | required 291 | 292 | f9d6498ee19a3e9ace207f1f6d32bd1d 293 | 3546c0a24a083e7fdfdf5986bef76b19c477a264 294 | e2b4c654b2d7897490cf1f22a009ac677be4c92bfc493a0dedb5706f5e489839 295 | d306545aae5e8498a26d2a370c2deb1540d01add801240ececf4a3d5e9b3db6d93258c193e8e827c57cafd8d8d02b681998bd5ba14438ca1e1b36f7d1e37dd73 296 | 82d9d467f1b61829bea927dacd631c82fc4435bfde438d85325f7abd3fdab5d994b0c0f38ef2ad8b35e98211f7a2c4c1 297 | 298 | 299 | 300 | LGPL-2.1-only 301 | 302 | 303 | pkg:maven/com.github.spotbugs/spotbugs-annotations@4.7.2?type=jar 304 | https://github.com/spotbugs/spotbugs/ 305 | 306 | 307 | com.google.code.gson 308 | gson 309 | 2.9.1 310 | Gson JSON library 311 | 312 | 0d507d266dcf7eea4b53fc3778d901c9 313 | 02cc2131b98ebfb04e2b2c7dfb84431f4045096b 314 | 378534e339e6e6d50b1736fb3abb76f1c15d1be3f4c13cec6d536412e23da603 315 | 10bf91c79ab151b684834e3ca8ba7d7e19742a3eeb580bde690fba433f9fffe3abbd79ed3fe3f97986c3a2badc4d14e28835a8ef89167b4b9cc6014242338769 316 | c50274278af61678dffff13f07de80e6eb1b3522a1f51c71c6b86a8d4911a35e015988e0835c9ef007097bac3417f5ca 317 | 318 | 319 | 320 | Apache-2.0 321 | https://www.apache.org/licenses/LICENSE-2.0 322 | 323 | 324 | pkg:maven/com.google.code.gson/gson@2.9.1?type=jar 325 | https://github.com/google/gson/issueshttps://github.com/google/gson/https://oss.sonatype.org/service/local/staging/deploy/maven2/ 326 | 327 | 328 | The Jaxen Project 329 | jaxen 330 | jaxen 331 | 1.2.0 332 | Jaxen is a universal XPath engine for Java. 333 | 334 | c32cf69356254b8f5050fce6e86358e9 335 | c10535a925bd35129a4329bc75065cc6b5293f2c 336 | 70feef9dd75ad064def05a3ce8975aeba515ee7d1be146d12199c8828a64174c 337 | cad582fc12d0741e9e6fd7e0cf80a50feb04f5ef42043df96f8a5b78476c77695d8b43836d2241f76b35676ea759921edd25eaeb2c04ec916eb138aa2901ce5f 338 | 8932691b6f88cc0f78a18a995200606713a5a58bcdf1573c78ba856425ce9aed550b90658e1f9a0b13763f2468f7dadf 339 | 340 | 341 | 342 | BSD License 2.0 343 | https://raw.githubusercontent.com/jaxen-xpath/jaxen/master/LICENSE.txt 344 | 345 | 346 | pkg:maven/jaxen/jaxen@1.2.0?type=jar 347 | http://www.cafeconleche.org/jaxenhttps://oss.sonatype.org/service/local/staging/deploy/maven2/https://github.com/jaxen-xpath/jaxen/issueshttps://markmail.org/search/?q=list%3Aorg.codehaus.jaxen.userhttps://github.com/jaxen-xpath/jaxen 348 | 349 | 350 | Saxonica 351 | net.sf.saxon 352 | Saxon-HE 353 | 11.4 354 | The XSLT and XQuery Processor 355 | 356 | 9f35652962ffe9b687fb7e3726600f03 357 | d926a13f2717ad1ea6e051550b8fd6207a587051 358 | 42e35494dc2e6b5e97256ae7cdf2b7ce30439c352566f35de02bed3a06a2b169 359 | 20f0fdeb8ac6923c130fb684d925cc01ba9457044eb3e44b020df92355a46468bbb9afe0d14008e2ea140eb2adcefc42b82fee251888d6bb56725931e40169c8 360 | e36a586e3edf05c953402a069a8f7cd74f4c88cdd3309867b3b103e84729b3e3a9ec573a5433cad9a9483c2e4a08890a 361 | 362 | 363 | 364 | MPL-2.0-no-copyleft-exception 365 | https://www.mozilla.org/MPL/2.0/ 366 | 367 | 368 | pkg:maven/net.sf.saxon/Saxon-HE@11.4?type=jar 369 | https://www.saxonica.com/https://saxonica.plan.io/projects/saxonmirrorhe/repository 370 | 371 | 372 | org.xmlresolver 373 | xmlresolver 374 | 4.4.3 375 | An XML entity/uri resolver 376 | 377 | 53b21e6362feb5a904408c5c154cd449 378 | aa8421211b0f69b5572d2d4b4252b2d87f957754 379 | 9d642c96c3f6811e20a9f6cfee3ca15ec84ecb939f6be639fee065670773a7d1 380 | 94a441ea1ae41718fd275b8590e5bf6edf022b8b31b46bdc1a86df7a225ea0df3c17612acb0ef05ba0690aa58f8b7d1d28107a1d0a7b91145a4504d749ef16c9 381 | be8263fea1af0281118ee523c9278d1e0beb17705aaee9f1e112cfdbb86013522fed25b985b5b27d97f2466efdc986d0 382 | 383 | 384 | 385 | Apache-2.0 386 | 387 | 388 | pkg:maven/org.xmlresolver/xmlresolver@4.4.3?type=jar 389 | 390 | 391 | 392 | The Apache Software Foundation 393 | org.apache.httpcomponents.client5 394 | httpclient5 395 | 5.1.3 396 | Apache HttpComponents Client 397 | 398 | 757bfb86277b9b11798db8fdb351bf74 399 | 13c984b7b881afcff3a7f0bb95878724a48a4b66 400 | 28c759254f4e35319e078bb6ffea75676608dc12cb243b24fb3c8732522977fe 401 | 4fb38b6bf164103e68320ce430776915a6831923eb3e0b6e6f29ff57647e6bd29efc07d46b107aec23bf9004cfd959fbda8153740ba0060260a54d67ccf8a093 402 | 8e6c7bc00b5e25c564faa6f20d01b26288163de846273943bdc7a043348cbe4a5540dc875ed057054c2af5c6e10f8147 403 | 404 | 405 | 406 | Apache-2.0 407 | 408 | 409 | pkg:maven/org.apache.httpcomponents.client5/httpclient5@5.1.3?type=jar 410 | https://issues.apache.org/jira/browse/HTTPCLIENThttps://lists.apache.org/list.html?httpclient-users@hc.apache.orghttps://www.apache.org/https://repository.apache.org/service/local/staging/deploy/maven2 411 | 412 | 413 | The Apache Software Foundation 414 | org.apache.httpcomponents.core5 415 | httpcore5-h2 416 | 5.1.3 417 | Apache HttpComponents HTTP/2 Core Components 418 | 419 | e12cc9746f6635675a408e641c95b177 420 | 4664b59b09f5ee008e37a963bbb92f4068e91696 421 | d0e78ba15aa8ebe77982b660ac4b09a95d6e035dbdbea762577dc1c8e2935807 422 | 76a22785285a3c12a98db24d678f1fd695cb4941be438fd80a7c41b4fbf804452694f93947579aba3bcee652671e362ae6d76bfb60a8db75518e52aba4ddad36 423 | cfead6178cd1cc30fcd9da2f8753897a2039e7915eded3278fb74545a49db68a10860ed064e9f52d0f1526e3cd7caa35 424 | 425 | 426 | 427 | Apache-2.0 428 | 429 | 430 | pkg:maven/org.apache.httpcomponents.core5/httpcore5-h2@5.1.3?type=jar 431 | https://issues.apache.org/jira/browse/HTTPCOREhttps://lists.apache.org/list.html?httpclient-users@hc.apache.orghttps://www.apache.org/https://repository.apache.org/service/local/staging/deploy/maven2 432 | 433 | 434 | The Apache Software Foundation 435 | commons-codec 436 | commons-codec 437 | 1.15 438 | The Apache Commons Codec package contains simple encoder and decoders for 439 | various formats such as Base64 and Hexadecimal. In addition to these 440 | widely used encoders and decoders, the codec package also maintains a 441 | collection of phonetic encoding utilities. 442 | 443 | 303baf002ce6d382198090aedd9d79a2 444 | 49d94806b6e3dc933dacbd8acb0fdbab8ebd1e5d 445 | b3e9f6d63a790109bf0d056611fbed1cf69055826defeb9894a71369d246ed63 446 | da30a716770795fce390e4dd340a8b728f220c6572383ffef55bd5839655d5611fcc06128b2144f6cdcb36f53072a12ec80b04afee787665e7ad0b6e888a6787 447 | 05d0506283716472175d44c2a4766523397bf8a007c18848f9c9a61718cc8aa437f9cb4b91771037ab29a960860b62a0 448 | 449 | 450 | 451 | Apache-2.0 452 | 453 | 454 | pkg:maven/commons-codec/commons-codec@1.15?type=jar 455 | https://issues.apache.org/jira/browse/CODEChttps://github.com/apache/commons-codechttps://builds.apache.org/https://mail-archives.apache.org/mod_mbox/commons-user/https://www.apache.org/https://repository.apache.org/service/local/staging/deploy/maven2 456 | 457 | 458 | The Apache Software Foundation 459 | org.apache.httpcomponents.core5 460 | httpcore5 461 | 5.1.3 462 | Apache HttpComponents HTTP/1.1 core components 463 | 464 | e3311847fc70a84038fb2c079dd08c4a 465 | d1638d1e5f2793f187d4144c702a93524ba6fd3b 466 | f2bf2f2c7772169c9e30699719667ad30f9b46c4e9d7841907deb2d12d9923fe 467 | c9b439da0fb0124f37676686c69f8fdb824a30e0d6a3b9ebc0ebca5555727ae18cc5a146d8874b4cfe6fa966d5eb6083a44c379a76017ec79863596a23c571b3 468 | 63d37103c0b040ed9f0c70af0bcc9792c68afe8c7da5f445f30458c7c802524f07a1bdb573661e680955a257e0fb6b4c 469 | 470 | 471 | 472 | Apache-2.0 473 | 474 | 475 | pkg:maven/org.apache.httpcomponents.core5/httpcore5@5.1.3?type=jar 476 | https://issues.apache.org/jira/browse/HTTPCOREhttps://lists.apache.org/list.html?httpclient-users@hc.apache.orghttps://www.apache.org/https://repository.apache.org/service/local/staging/deploy/maven2 477 | 478 | 479 | xml-apis 480 | xml-apis 481 | 1.4.01 482 | xml-commons provides an Apache-hosted set of DOM, SAX, and 483 | JAXP interfaces for use in other xml-based projects. Our hope is that we 484 | can standardize on both a common version and packaging scheme for these 485 | critical XML standards interfaces to make the lives of both our developers 486 | and users easier. The External Components portion of xml-commons contains 487 | interfaces that are defined by external standards organizations. For DOM, 488 | that's the W3C; for SAX it's David Megginson and sax.sourceforge.net; for 489 | JAXP it's Sun. 490 | 491 | 7eaad6fea5925cca6c36ee8b3e02ac9d 492 | 3789d9fada2d3d458c4ba2de349d48780f381ee3 493 | a840968176645684bb01aed376e067ab39614885f9eee44abe35a5f20ebe7fad 494 | 8db0283b6840cd6407957d296b802e3edf90653e2722f8e29f86c1c0b60996c4b43e9e065e6864dab89b2138ddb0174d9b4fdda4a93f94eeb884783db82f3268 495 | bce0ec0f0f692213a1110197c4a11c333673ae0630481255d12b441a8cba70aecfaf104c3d8d9b500ed2a0a19a2bfcce 496 | 497 | 498 | 499 | Apache-2.0 500 | 501 | 502 | SAX-PD 503 | http://www.saxproject.org/copying.html 504 | 505 | 506 | The W3C License 507 | http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/java-binding.zip 508 | 509 | 510 | pkg:maven/xml-apis/xml-apis@1.4.01?type=jar 511 | http://issues.apache.org/bugzilla/http://mail-archives.apache.org/mod_mbox/xml-commons-dev/https://svn.apache.org/viewvc/xml/commons/tags/xml-commons-external-1_4_01/ 512 | 513 | 514 | org.xmlresolver 515 | xmlresolver 516 | 4.4.3 517 | 518 | 2bf9b2983c518ababfc8d528539e51ef 519 | 89079ec236d9683bb5f6f5cf4bef0cfc01b46e55 520 | a57db23d75c3580cb15eb6e1a854683f4579cfd265f5cf1011a6983d9aed0f1f 521 | 2ad09a69beca1253d35143cb0016811197a2a967252dcec35ec2c4ccde605e7a4e869c2b45161fe38b93a6ac2d5fab95e28c0337ce0ea1126a3db2aac5462e65 522 | 37fa6d0e58bd9e6bda6afb892d1224977e9de16864c35a3189aa51f0a55327686fcdb2cc71b0a1b4005c4c4dc23aa8e2 523 | 524 | pkg:maven/org.xmlresolver/xmlresolver@4.4.3?classifier=data&type=jar 525 | 526 | 527 | QOS.ch 528 | org.slf4j 529 | slf4j-api 530 | 1.7.36 531 | The slf4j API 532 | required 533 | 534 | 872da51f5de7f3923da4de871d57fd85 535 | 6c62681a2f655b49963a5983b8b0950a6120ae14 536 | d3ef575e3e4979678dc01bf1dcce51021493b4d11fb7f1be8ad982877c16a1c0 537 | f9b033fc019a44f98b16048da7e2b59edd4a6a527ba60e358f65ab88e0afae03a9340f1b3e8a543d49fa542290f499c5594259affa1ff3e6e7bf3b428d4c610b 538 | 2b14ad035877087157e379d3277dcdcd79e58d6bdb147c47d29e377d75ce53ad42cafbf22f5fb7827c7e946ff4876b9a 539 | 540 | 541 | 542 | MIT 543 | https://opensource.org/licenses/MIT 544 | 545 | 546 | pkg:maven/org.slf4j/slf4j-api@1.7.36?type=jar 547 | http://www.qos.chhttps://oss.sonatype.org/service/local/staging/deploy/maven2/https://github.com/qos-ch/slf4j 548 | 549 | 550 | com.google.code.findbugs 551 | jsr305 552 | 3.0.2 553 | JSR305 Annotations for Findbugs 554 | required 555 | 556 | dd83accb899363c32b07d7a1b2e4ce40 557 | 25ea2e8b0c338a877313bd4672d3fe056ea78f0d 558 | 766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7 559 | bb09db62919a50fa5b55906013be6ca4fc7acb2e87455fac5eaf9ede2e41ce8bbafc0e5a385a561264ea4cd71bbbd3ef5a45e02d63277a201d06a0ae1636f804 560 | ca0b169d3eb2d0922dc031133a021f861a043bb3e405a88728215fd6ff00fa52fdc7347842dcc2031472e3726164bdc4 561 | 562 | 563 | 564 | Apache-2.0 565 | 566 | 567 | pkg:maven/com.google.code.findbugs/jsr305@3.0.2?type=jar 568 | https://code.google.com/p/jsr-305/https://oss.sonatype.org/service/local/staging/deploy/maven2/ 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | -------------------------------------------------------------------------------- /examples/photon.spdx.json: -------------------------------------------------------------------------------- 1 | { 2 | "SPDXID": "SPDXRef-DOCUMENT", 3 | "spdxVersion": "SPDX-2.2", 4 | "creationInfo": { 5 | "created": "2023-01-12T22:06:03Z", 6 | "creators": [ 7 | "Tool: tern-b8e13d1780cd3a02204226bba3d0772d95da24a0" 8 | ], 9 | "licenseListVersion": "3.19" 10 | }, 11 | "name": "Tern report for photon", 12 | "dataLicense": "CC0-1.0", 13 | "comment": "This document was generated by the Tern Project: https://github.com/tern-tools/tern", 14 | "documentNamespace": "https://spdx.org/spdxdocs/tern-report-b8e13d1780cd3a02204226bba3d0772d95da24a0-photon-21d2cd0a-064e-4198-8bf9-99882f2897aa", 15 | "documentDescribes": [ 16 | "SPDXRef-photon-3.0" 17 | ], 18 | "packages": [ 19 | { 20 | "name": "photon", 21 | "SPDXID": "SPDXRef-photon-3.0", 22 | "versionInfo": "3.0", 23 | "downloadLocation": "NOASSERTION", 24 | "filesAnalyzed": false, 25 | "licenseConcluded": "NOASSERTION", 26 | "licenseDeclared": "NOASSERTION", 27 | "copyrightText": "NOASSERTION" 28 | }, 29 | { 30 | "name": "ad1f1c6f4fef6e6208ebc53e701bf9937f4e05dce5f601b20c35d8a0ad7fdeff", 31 | "SPDXID": "SPDXRef-c8a2baeeb2", 32 | "packageFileName": "ad1f1c6f4fef6e6208ebc53e701bf9937f4e05dce5f601b20c35d8a0ad7fdeff", 33 | "downloadLocation": "NONE", 34 | "filesAnalyzed": false, 35 | "checksums": [ 36 | { 37 | "algorithm": "SHA256", 38 | "checksumValue": "c8a2baeeb2639816d78c44738c72246632d712195c634ce53e80fb5cbc0a50c8" 39 | } 40 | ], 41 | "licenseConcluded": "NOASSERTION", 42 | "licenseDeclared": "NOASSERTION", 43 | "copyrightText": "NOASSERTION", 44 | "comment": "Layer 1:\n\tinfo: Layer created by commands: /bin/sh -c #(nop) ADD file:03f8ed1169e4d338a7b5f3f94b3e25379a063f3718bb062533efa2ce61a21d35 in / \n\tinfo: Found 'VMware Photon OS/Linux' in /etc/os-release.\n\tinfo: Retrieved package metadata using tdnf default method. \n\n" 45 | }, 46 | { 47 | "name": "bash", 48 | "SPDXID": "SPDXRef-bash-4.4.18-4.ph3", 49 | "versionInfo": "4.4.18-4.ph3", 50 | "downloadLocation": "NOASSERTION", 51 | "filesAnalyzed": false, 52 | "licenseConcluded": "NOASSERTION", 53 | "licenseDeclared": "LicenseRef-92fe666", 54 | "copyrightText": "NONE", 55 | "comment": "bash:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 56 | }, 57 | { 58 | "name": "bzip2-libs", 59 | "SPDXID": "SPDXRef-bzip2-libs-1.0.8-2.ph3", 60 | "versionInfo": "1.0.8-2.ph3", 61 | "downloadLocation": "NOASSERTION", 62 | "filesAnalyzed": false, 63 | "licenseConcluded": "NOASSERTION", 64 | "licenseDeclared": "LicenseRef-f266d93", 65 | "copyrightText": "NONE", 66 | "comment": "bzip2-libs:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 67 | }, 68 | { 69 | "name": "ca-certificates", 70 | "SPDXID": "SPDXRef-ca-certificates-20190521-3.ph3", 71 | "versionInfo": "20190521-3.ph3", 72 | "downloadLocation": "NOASSERTION", 73 | "filesAnalyzed": false, 74 | "licenseConcluded": "NOASSERTION", 75 | "licenseDeclared": "LicenseRef-e06627e", 76 | "copyrightText": "NONE", 77 | "comment": "ca-certificates:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 78 | }, 79 | { 80 | "name": "ca-certificates-pki", 81 | "SPDXID": "SPDXRef-ca-certificates-pki-20190521-3.ph3", 82 | "versionInfo": "20190521-3.ph3", 83 | "downloadLocation": "NOASSERTION", 84 | "filesAnalyzed": false, 85 | "licenseConcluded": "NOASSERTION", 86 | "licenseDeclared": "LicenseRef-e06627e", 87 | "copyrightText": "NONE", 88 | "comment": "ca-certificates-pki:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 89 | }, 90 | { 91 | "name": "curl", 92 | "SPDXID": "SPDXRef-curl-7.86.0-3.ph3", 93 | "versionInfo": "7.86.0-3.ph3", 94 | "downloadLocation": "NOASSERTION", 95 | "filesAnalyzed": false, 96 | "licenseConcluded": "NOASSERTION", 97 | "licenseDeclared": "MIT", 98 | "copyrightText": "NONE", 99 | "comment": "curl:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 100 | }, 101 | { 102 | "name": "curl-libs", 103 | "SPDXID": "SPDXRef-curl-libs-7.86.0-3.ph3", 104 | "versionInfo": "7.86.0-3.ph3", 105 | "downloadLocation": "NOASSERTION", 106 | "filesAnalyzed": false, 107 | "licenseConcluded": "NOASSERTION", 108 | "licenseDeclared": "MIT", 109 | "copyrightText": "NONE", 110 | "comment": "curl-libs:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 111 | }, 112 | { 113 | "name": "e2fsprogs-libs", 114 | "SPDXID": "SPDXRef-e2fsprogs-libs-1.45.5-3.ph3", 115 | "versionInfo": "1.45.5-3.ph3", 116 | "downloadLocation": "NOASSERTION", 117 | "filesAnalyzed": false, 118 | "licenseConcluded": "NOASSERTION", 119 | "licenseDeclared": "LicenseRef-1e11d9a", 120 | "copyrightText": "NONE", 121 | "comment": "e2fsprogs-libs:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 122 | }, 123 | { 124 | "name": "elfutils-libelf", 125 | "SPDXID": "SPDXRef-elfutils-libelf-0.176-1.ph3", 126 | "versionInfo": "0.176-1.ph3", 127 | "downloadLocation": "NOASSERTION", 128 | "filesAnalyzed": false, 129 | "licenseConcluded": "NOASSERTION", 130 | "licenseDeclared": "LicenseRef-bba2b1d", 131 | "copyrightText": "NONE", 132 | "comment": "elfutils-libelf:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 133 | }, 134 | { 135 | "name": "expat", 136 | "SPDXID": "SPDXRef-expat-2.2.9-11.ph3", 137 | "versionInfo": "2.2.9-11.ph3", 138 | "downloadLocation": "NOASSERTION", 139 | "filesAnalyzed": false, 140 | "licenseConcluded": "NOASSERTION", 141 | "licenseDeclared": "MIT", 142 | "copyrightText": "NONE", 143 | "comment": "expat:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 144 | }, 145 | { 146 | "name": "expat-libs", 147 | "SPDXID": "SPDXRef-expat-libs-2.2.9-11.ph3", 148 | "versionInfo": "2.2.9-11.ph3", 149 | "downloadLocation": "NOASSERTION", 150 | "filesAnalyzed": false, 151 | "licenseConcluded": "NOASSERTION", 152 | "licenseDeclared": "MIT", 153 | "copyrightText": "NONE", 154 | "comment": "expat-libs:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 155 | }, 156 | { 157 | "name": "filesystem", 158 | "SPDXID": "SPDXRef-filesystem-1.1-4.ph3", 159 | "versionInfo": "1.1-4.ph3", 160 | "downloadLocation": "NOASSERTION", 161 | "filesAnalyzed": false, 162 | "licenseConcluded": "NOASSERTION", 163 | "licenseDeclared": "LicenseRef-92fe666", 164 | "copyrightText": "NONE", 165 | "comment": "filesystem:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 166 | }, 167 | { 168 | "name": "glibc", 169 | "SPDXID": "SPDXRef-glibc-2.28-22.ph3", 170 | "versionInfo": "2.28-22.ph3", 171 | "downloadLocation": "NOASSERTION", 172 | "filesAnalyzed": false, 173 | "licenseConcluded": "NOASSERTION", 174 | "licenseDeclared": "LicenseRef-0a9356a", 175 | "copyrightText": "NONE", 176 | "comment": "glibc:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 177 | }, 178 | { 179 | "name": "krb5", 180 | "SPDXID": "SPDXRef-krb5-1.17-2.ph3", 181 | "versionInfo": "1.17-2.ph3", 182 | "downloadLocation": "NOASSERTION", 183 | "filesAnalyzed": false, 184 | "licenseConcluded": "NOASSERTION", 185 | "licenseDeclared": "MIT", 186 | "copyrightText": "NONE", 187 | "comment": "krb5:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 188 | }, 189 | { 190 | "name": "libcap", 191 | "SPDXID": "SPDXRef-libcap-2.25-8.ph3", 192 | "versionInfo": "2.25-8.ph3", 193 | "downloadLocation": "NOASSERTION", 194 | "filesAnalyzed": false, 195 | "licenseConcluded": "NOASSERTION", 196 | "licenseDeclared": "LicenseRef-1e11d9a", 197 | "copyrightText": "NONE", 198 | "comment": "libcap:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 199 | }, 200 | { 201 | "name": "libdb", 202 | "SPDXID": "SPDXRef-libdb-5.3.28-2.ph3", 203 | "versionInfo": "5.3.28-2.ph3", 204 | "downloadLocation": "NOASSERTION", 205 | "filesAnalyzed": false, 206 | "licenseConcluded": "NOASSERTION", 207 | "licenseDeclared": "LicenseRef-88cb263", 208 | "copyrightText": "NONE", 209 | "comment": "libdb:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 210 | }, 211 | { 212 | "name": "libgcc", 213 | "SPDXID": "SPDXRef-libgcc-7.3.0-5.ph3", 214 | "versionInfo": "7.3.0-5.ph3", 215 | "downloadLocation": "NOASSERTION", 216 | "filesAnalyzed": false, 217 | "licenseConcluded": "NOASSERTION", 218 | "licenseDeclared": "LicenseRef-1e11d9a", 219 | "copyrightText": "NONE", 220 | "comment": "libgcc:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 221 | }, 222 | { 223 | "name": "libmetalink", 224 | "SPDXID": "SPDXRef-libmetalink-0.1.3-2.ph3", 225 | "versionInfo": "0.1.3-2.ph3", 226 | "downloadLocation": "NOASSERTION", 227 | "filesAnalyzed": false, 228 | "licenseConcluded": "NOASSERTION", 229 | "licenseDeclared": "MIT", 230 | "copyrightText": "NONE", 231 | "comment": "libmetalink:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 232 | }, 233 | { 234 | "name": "libsolv", 235 | "SPDXID": "SPDXRef-libsolv-0.6.35-8.ph3", 236 | "versionInfo": "0.6.35-8.ph3", 237 | "downloadLocation": "NOASSERTION", 238 | "filesAnalyzed": false, 239 | "licenseConcluded": "NOASSERTION", 240 | "licenseDeclared": "LicenseRef-f266d93", 241 | "copyrightText": "NONE", 242 | "comment": "libsolv:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 243 | }, 244 | { 245 | "name": "libssh2", 246 | "SPDXID": "SPDXRef-libssh2-1.9.0-2.ph3", 247 | "versionInfo": "1.9.0-2.ph3", 248 | "downloadLocation": "NOASSERTION", 249 | "filesAnalyzed": false, 250 | "licenseConcluded": "NOASSERTION", 251 | "licenseDeclared": "LicenseRef-f266d93", 252 | "copyrightText": "NONE", 253 | "comment": "libssh2:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 254 | }, 255 | { 256 | "name": "lua", 257 | "SPDXID": "SPDXRef-lua-5.3.5-4.ph3", 258 | "versionInfo": "5.3.5-4.ph3", 259 | "downloadLocation": "NOASSERTION", 260 | "filesAnalyzed": false, 261 | "licenseConcluded": "NOASSERTION", 262 | "licenseDeclared": "MIT", 263 | "copyrightText": "NONE", 264 | "comment": "lua:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 265 | }, 266 | { 267 | "name": "ncurses-libs", 268 | "SPDXID": "SPDXRef-ncurses-libs-6.1-5.ph3", 269 | "versionInfo": "6.1-5.ph3", 270 | "downloadLocation": "NOASSERTION", 271 | "filesAnalyzed": false, 272 | "licenseConcluded": "NOASSERTION", 273 | "licenseDeclared": "MIT", 274 | "copyrightText": "NONE", 275 | "comment": "ncurses-libs:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 276 | }, 277 | { 278 | "name": "nspr", 279 | "SPDXID": "SPDXRef-nspr-4.21-1.ph3", 280 | "versionInfo": "4.21-1.ph3", 281 | "downloadLocation": "NOASSERTION", 282 | "filesAnalyzed": false, 283 | "licenseConcluded": "NOASSERTION", 284 | "licenseDeclared": "LicenseRef-4afa27a", 285 | "copyrightText": "NONE", 286 | "comment": "nspr:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 287 | }, 288 | { 289 | "name": "nss-libs", 290 | "SPDXID": "SPDXRef-nss-libs-3.44-8.ph3", 291 | "versionInfo": "3.44-8.ph3", 292 | "downloadLocation": "NOASSERTION", 293 | "filesAnalyzed": false, 294 | "licenseConcluded": "NOASSERTION", 295 | "licenseDeclared": "LicenseRef-4afa27a", 296 | "copyrightText": "NONE", 297 | "comment": "nss-libs:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 298 | }, 299 | { 300 | "name": "openssl", 301 | "SPDXID": "SPDXRef-openssl-1.0.2ze-3.ph3", 302 | "versionInfo": "1.0.2ze-3.ph3", 303 | "downloadLocation": "NOASSERTION", 304 | "filesAnalyzed": false, 305 | "licenseConcluded": "NOASSERTION", 306 | "licenseDeclared": "OpenSSL", 307 | "copyrightText": "NONE", 308 | "comment": "openssl:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 309 | }, 310 | { 311 | "name": "photon-release", 312 | "SPDXID": "SPDXRef-photon-release-3.0-6.ph3", 313 | "versionInfo": "3.0-6.ph3", 314 | "downloadLocation": "NOASSERTION", 315 | "filesAnalyzed": false, 316 | "licenseConcluded": "NOASSERTION", 317 | "licenseDeclared": "LicenseRef-f124779", 318 | "copyrightText": "NONE", 319 | "comment": "photon-release:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 320 | }, 321 | { 322 | "name": "photon-repos", 323 | "SPDXID": "SPDXRef-photon-repos-3.0-8.ph3", 324 | "versionInfo": "3.0-8.ph3", 325 | "downloadLocation": "NOASSERTION", 326 | "filesAnalyzed": false, 327 | "licenseConcluded": "NOASSERTION", 328 | "licenseDeclared": "LicenseRef-f124779", 329 | "copyrightText": "NONE", 330 | "comment": "photon-repos:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 331 | }, 332 | { 333 | "name": "popt", 334 | "SPDXID": "SPDXRef-popt-1.16-5.ph3", 335 | "versionInfo": "1.16-5.ph3", 336 | "downloadLocation": "NOASSERTION", 337 | "filesAnalyzed": false, 338 | "licenseConcluded": "NOASSERTION", 339 | "licenseDeclared": "MIT", 340 | "copyrightText": "NONE", 341 | "comment": "popt:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 342 | }, 343 | { 344 | "name": "readline", 345 | "SPDXID": "SPDXRef-readline-7.0-2.ph3", 346 | "versionInfo": "7.0-2.ph3", 347 | "downloadLocation": "NOASSERTION", 348 | "filesAnalyzed": false, 349 | "licenseConcluded": "NOASSERTION", 350 | "licenseDeclared": "LicenseRef-d953b10", 351 | "copyrightText": "NONE", 352 | "comment": "readline:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 353 | }, 354 | { 355 | "name": "rpm-libs", 356 | "SPDXID": "SPDXRef-rpm-libs-4.14.3-6.ph3", 357 | "versionInfo": "4.14.3-6.ph3", 358 | "downloadLocation": "NOASSERTION", 359 | "filesAnalyzed": false, 360 | "licenseConcluded": "NOASSERTION", 361 | "licenseDeclared": "LicenseRef-1e11d9a", 362 | "copyrightText": "NONE", 363 | "comment": "rpm-libs:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 364 | }, 365 | { 366 | "name": "sqlite-libs", 367 | "SPDXID": "SPDXRef-sqlite-libs-3.35.5-1.ph3", 368 | "versionInfo": "3.35.5-1.ph3", 369 | "downloadLocation": "NOASSERTION", 370 | "filesAnalyzed": false, 371 | "licenseConcluded": "NOASSERTION", 372 | "licenseDeclared": "LicenseRef-116ca55", 373 | "copyrightText": "NONE", 374 | "comment": "sqlite-libs:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 375 | }, 376 | { 377 | "name": "tdnf", 378 | "SPDXID": "SPDXRef-tdnf-3.1.10-1.ph3", 379 | "versionInfo": "3.1.10-1.ph3", 380 | "downloadLocation": "NOASSERTION", 381 | "filesAnalyzed": false, 382 | "licenseConcluded": "NOASSERTION", 383 | "licenseDeclared": "LicenseRef-b5ef29a", 384 | "copyrightText": "NONE", 385 | "comment": "tdnf:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 386 | }, 387 | { 388 | "name": "tdnf-cli-libs", 389 | "SPDXID": "SPDXRef-tdnf-cli-libs-3.1.10-1.ph3", 390 | "versionInfo": "3.1.10-1.ph3", 391 | "downloadLocation": "NOASSERTION", 392 | "filesAnalyzed": false, 393 | "licenseConcluded": "NOASSERTION", 394 | "licenseDeclared": "LicenseRef-b5ef29a", 395 | "copyrightText": "NONE", 396 | "comment": "tdnf-cli-libs:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 397 | }, 398 | { 399 | "name": "toybox", 400 | "SPDXID": "SPDXRef-toybox-0.8.6-2.ph3", 401 | "versionInfo": "0.8.6-2.ph3", 402 | "downloadLocation": "NOASSERTION", 403 | "filesAnalyzed": false, 404 | "licenseConcluded": "NOASSERTION", 405 | "licenseDeclared": "LicenseRef-f266d93", 406 | "copyrightText": "NONE", 407 | "comment": "toybox:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 408 | }, 409 | { 410 | "name": "xz-libs", 411 | "SPDXID": "SPDXRef-xz-libs-5.2.4-2.ph3", 412 | "versionInfo": "5.2.4-2.ph3", 413 | "downloadLocation": "NOASSERTION", 414 | "filesAnalyzed": false, 415 | "licenseConcluded": "NOASSERTION", 416 | "licenseDeclared": "LicenseRef-bd8fbda", 417 | "copyrightText": "NONE", 418 | "comment": "xz-libs:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 419 | }, 420 | { 421 | "name": "zlib", 422 | "SPDXID": "SPDXRef-zlib-1.2.11-3.ph3", 423 | "versionInfo": "1.2.11-3.ph3", 424 | "downloadLocation": "NOASSERTION", 425 | "filesAnalyzed": false, 426 | "licenseConcluded": "NOASSERTION", 427 | "licenseDeclared": "zlib", 428 | "copyrightText": "NONE", 429 | "comment": "zlib:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 430 | }, 431 | { 432 | "name": "zstd-libs", 433 | "SPDXID": "SPDXRef-zstd-libs-1.4.5-2.ph3", 434 | "versionInfo": "1.4.5-2.ph3", 435 | "downloadLocation": "NOASSERTION", 436 | "filesAnalyzed": false, 437 | "licenseConcluded": "NOASSERTION", 438 | "licenseDeclared": "LicenseRef-d935702", 439 | "copyrightText": "NONE", 440 | "comment": "zstd-libs:\n\twarning: No metadata for key: copyright\n\twarning: No metadata for key: download_url\n\twarning: No metadata for key: checksum\n\twarning: No metadata for key: files\n\twarning: No metadata for key: pkg_licenses\n\twarning: No metadata for key: pkg_format\n\twarning: No metadata for key: src_name\n\twarning: No metadata for key: src_version\n" 441 | } 442 | ], 443 | "relationships": [ 444 | { 445 | "spdxElementId": "SPDXRef-DOCUMENT", 446 | "relatedSpdxElement": "SPDXRef-photon-3.0", 447 | "relationshipType": "DESCRIBES" 448 | }, 449 | { 450 | "spdxElementId": "SPDXRef-photon-3.0", 451 | "relatedSpdxElement": "SPDXRef-c8a2baeeb2", 452 | "relationshipType": "CONTAINS" 453 | }, 454 | { 455 | "spdxElementId": "SPDXRef-c8a2baeeb2", 456 | "relatedSpdxElement": "SPDXRef-bash-4.4.18-4.ph3", 457 | "relationshipType": "CONTAINS" 458 | }, 459 | { 460 | "spdxElementId": "SPDXRef-c8a2baeeb2", 461 | "relatedSpdxElement": "SPDXRef-bzip2-libs-1.0.8-2.ph3", 462 | "relationshipType": "CONTAINS" 463 | }, 464 | { 465 | "spdxElementId": "SPDXRef-c8a2baeeb2", 466 | "relatedSpdxElement": "SPDXRef-ca-certificates-20190521-3.ph3", 467 | "relationshipType": "CONTAINS" 468 | }, 469 | { 470 | "spdxElementId": "SPDXRef-c8a2baeeb2", 471 | "relatedSpdxElement": "SPDXRef-ca-certificates-pki-20190521-3.ph3", 472 | "relationshipType": "CONTAINS" 473 | }, 474 | { 475 | "spdxElementId": "SPDXRef-c8a2baeeb2", 476 | "relatedSpdxElement": "SPDXRef-curl-7.86.0-3.ph3", 477 | "relationshipType": "CONTAINS" 478 | }, 479 | { 480 | "spdxElementId": "SPDXRef-c8a2baeeb2", 481 | "relatedSpdxElement": "SPDXRef-curl-libs-7.86.0-3.ph3", 482 | "relationshipType": "CONTAINS" 483 | }, 484 | { 485 | "spdxElementId": "SPDXRef-c8a2baeeb2", 486 | "relatedSpdxElement": "SPDXRef-e2fsprogs-libs-1.45.5-3.ph3", 487 | "relationshipType": "CONTAINS" 488 | }, 489 | { 490 | "spdxElementId": "SPDXRef-c8a2baeeb2", 491 | "relatedSpdxElement": "SPDXRef-elfutils-libelf-0.176-1.ph3", 492 | "relationshipType": "CONTAINS" 493 | }, 494 | { 495 | "spdxElementId": "SPDXRef-c8a2baeeb2", 496 | "relatedSpdxElement": "SPDXRef-expat-2.2.9-11.ph3", 497 | "relationshipType": "CONTAINS" 498 | }, 499 | { 500 | "spdxElementId": "SPDXRef-c8a2baeeb2", 501 | "relatedSpdxElement": "SPDXRef-expat-libs-2.2.9-11.ph3", 502 | "relationshipType": "CONTAINS" 503 | }, 504 | { 505 | "spdxElementId": "SPDXRef-c8a2baeeb2", 506 | "relatedSpdxElement": "SPDXRef-filesystem-1.1-4.ph3", 507 | "relationshipType": "CONTAINS" 508 | }, 509 | { 510 | "spdxElementId": "SPDXRef-c8a2baeeb2", 511 | "relatedSpdxElement": "SPDXRef-glibc-2.28-22.ph3", 512 | "relationshipType": "CONTAINS" 513 | }, 514 | { 515 | "spdxElementId": "SPDXRef-c8a2baeeb2", 516 | "relatedSpdxElement": "SPDXRef-krb5-1.17-2.ph3", 517 | "relationshipType": "CONTAINS" 518 | }, 519 | { 520 | "spdxElementId": "SPDXRef-c8a2baeeb2", 521 | "relatedSpdxElement": "SPDXRef-libcap-2.25-8.ph3", 522 | "relationshipType": "CONTAINS" 523 | }, 524 | { 525 | "spdxElementId": "SPDXRef-c8a2baeeb2", 526 | "relatedSpdxElement": "SPDXRef-libdb-5.3.28-2.ph3", 527 | "relationshipType": "CONTAINS" 528 | }, 529 | { 530 | "spdxElementId": "SPDXRef-c8a2baeeb2", 531 | "relatedSpdxElement": "SPDXRef-libgcc-7.3.0-5.ph3", 532 | "relationshipType": "CONTAINS" 533 | }, 534 | { 535 | "spdxElementId": "SPDXRef-c8a2baeeb2", 536 | "relatedSpdxElement": "SPDXRef-libmetalink-0.1.3-2.ph3", 537 | "relationshipType": "CONTAINS" 538 | }, 539 | { 540 | "spdxElementId": "SPDXRef-c8a2baeeb2", 541 | "relatedSpdxElement": "SPDXRef-libsolv-0.6.35-8.ph3", 542 | "relationshipType": "CONTAINS" 543 | }, 544 | { 545 | "spdxElementId": "SPDXRef-c8a2baeeb2", 546 | "relatedSpdxElement": "SPDXRef-libssh2-1.9.0-2.ph3", 547 | "relationshipType": "CONTAINS" 548 | }, 549 | { 550 | "spdxElementId": "SPDXRef-c8a2baeeb2", 551 | "relatedSpdxElement": "SPDXRef-lua-5.3.5-4.ph3", 552 | "relationshipType": "CONTAINS" 553 | }, 554 | { 555 | "spdxElementId": "SPDXRef-c8a2baeeb2", 556 | "relatedSpdxElement": "SPDXRef-ncurses-libs-6.1-5.ph3", 557 | "relationshipType": "CONTAINS" 558 | }, 559 | { 560 | "spdxElementId": "SPDXRef-c8a2baeeb2", 561 | "relatedSpdxElement": "SPDXRef-nspr-4.21-1.ph3", 562 | "relationshipType": "CONTAINS" 563 | }, 564 | { 565 | "spdxElementId": "SPDXRef-c8a2baeeb2", 566 | "relatedSpdxElement": "SPDXRef-nss-libs-3.44-8.ph3", 567 | "relationshipType": "CONTAINS" 568 | }, 569 | { 570 | "spdxElementId": "SPDXRef-c8a2baeeb2", 571 | "relatedSpdxElement": "SPDXRef-openssl-1.0.2ze-3.ph3", 572 | "relationshipType": "CONTAINS" 573 | }, 574 | { 575 | "spdxElementId": "SPDXRef-c8a2baeeb2", 576 | "relatedSpdxElement": "SPDXRef-photon-release-3.0-6.ph3", 577 | "relationshipType": "CONTAINS" 578 | }, 579 | { 580 | "spdxElementId": "SPDXRef-c8a2baeeb2", 581 | "relatedSpdxElement": "SPDXRef-photon-repos-3.0-8.ph3", 582 | "relationshipType": "CONTAINS" 583 | }, 584 | { 585 | "spdxElementId": "SPDXRef-c8a2baeeb2", 586 | "relatedSpdxElement": "SPDXRef-popt-1.16-5.ph3", 587 | "relationshipType": "CONTAINS" 588 | }, 589 | { 590 | "spdxElementId": "SPDXRef-c8a2baeeb2", 591 | "relatedSpdxElement": "SPDXRef-readline-7.0-2.ph3", 592 | "relationshipType": "CONTAINS" 593 | }, 594 | { 595 | "spdxElementId": "SPDXRef-c8a2baeeb2", 596 | "relatedSpdxElement": "SPDXRef-rpm-libs-4.14.3-6.ph3", 597 | "relationshipType": "CONTAINS" 598 | }, 599 | { 600 | "spdxElementId": "SPDXRef-c8a2baeeb2", 601 | "relatedSpdxElement": "SPDXRef-sqlite-libs-3.35.5-1.ph3", 602 | "relationshipType": "CONTAINS" 603 | }, 604 | { 605 | "spdxElementId": "SPDXRef-c8a2baeeb2", 606 | "relatedSpdxElement": "SPDXRef-tdnf-3.1.10-1.ph3", 607 | "relationshipType": "CONTAINS" 608 | }, 609 | { 610 | "spdxElementId": "SPDXRef-c8a2baeeb2", 611 | "relatedSpdxElement": "SPDXRef-tdnf-cli-libs-3.1.10-1.ph3", 612 | "relationshipType": "CONTAINS" 613 | }, 614 | { 615 | "spdxElementId": "SPDXRef-c8a2baeeb2", 616 | "relatedSpdxElement": "SPDXRef-toybox-0.8.6-2.ph3", 617 | "relationshipType": "CONTAINS" 618 | }, 619 | { 620 | "spdxElementId": "SPDXRef-c8a2baeeb2", 621 | "relatedSpdxElement": "SPDXRef-xz-libs-5.2.4-2.ph3", 622 | "relationshipType": "CONTAINS" 623 | }, 624 | { 625 | "spdxElementId": "SPDXRef-c8a2baeeb2", 626 | "relatedSpdxElement": "SPDXRef-zlib-1.2.11-3.ph3", 627 | "relationshipType": "CONTAINS" 628 | }, 629 | { 630 | "spdxElementId": "SPDXRef-c8a2baeeb2", 631 | "relatedSpdxElement": "SPDXRef-zstd-libs-1.4.5-2.ph3", 632 | "relationshipType": "CONTAINS" 633 | } 634 | ], 635 | "hasExtractedLicensingInfos": [ 636 | { 637 | "extractedText": "BSD and GPLv2", 638 | "licenseId": "LicenseRef-d935702" 639 | }, 640 | { 641 | "extractedText": "MPLv2.0", 642 | "licenseId": "LicenseRef-4afa27a" 643 | }, 644 | { 645 | "extractedText": "GPLv3", 646 | "licenseId": "LicenseRef-92fe666" 647 | }, 648 | { 649 | "extractedText": "GPLv2+", 650 | "licenseId": "LicenseRef-1e11d9a" 651 | }, 652 | { 653 | "extractedText": "BSD", 654 | "licenseId": "LicenseRef-f266d93" 655 | }, 656 | { 657 | "extractedText": "GPLv2+ or LGPLv3+", 658 | "licenseId": "LicenseRef-bba2b1d" 659 | }, 660 | { 661 | "extractedText": "LGPLv2.1,GPLv2", 662 | "licenseId": "LicenseRef-b5ef29a" 663 | }, 664 | { 665 | "extractedText": "LGPLv2+", 666 | "licenseId": "LicenseRef-0a9356a" 667 | }, 668 | { 669 | "extractedText": "Apache License", 670 | "licenseId": "LicenseRef-f124779" 671 | }, 672 | { 673 | "extractedText": "Public Domain", 674 | "licenseId": "LicenseRef-116ca55" 675 | }, 676 | { 677 | "extractedText": "Custom", 678 | "licenseId": "LicenseRef-e06627e" 679 | }, 680 | { 681 | "extractedText": "GPLv2+ and GPLv3+ and LGPLv2+", 682 | "licenseId": "LicenseRef-bd8fbda" 683 | }, 684 | { 685 | "extractedText": "GPLv3+", 686 | "licenseId": "LicenseRef-d953b10" 687 | }, 688 | { 689 | "extractedText": "BSD and LGPLv2 and Sleepycat", 690 | "licenseId": "LicenseRef-88cb263" 691 | } 692 | ] 693 | } -------------------------------------------------------------------------------- /examples/spdx-example.tv: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ebay/sbom-scorecard 2 | 3 | go 1.19 4 | 5 | require github.com/spdx/tools-golang v0.4.0 6 | 7 | require ( 8 | github.com/davecgh/go-spew v1.1.1 // indirect 9 | github.com/inconshreveable/mousetrap v1.0.1 // indirect 10 | github.com/mattn/go-runewidth v0.0.12 // indirect 11 | github.com/pmezard/go-difflib v1.0.0 // indirect 12 | github.com/rivo/uniseg v0.1.0 // indirect 13 | github.com/spdx/gordf v0.0.0-20221230105357-b735bd5aac89 // indirect 14 | github.com/spf13/pflag v1.0.5 // indirect 15 | gopkg.in/yaml.v3 v3.0.1 // indirect 16 | ) 17 | 18 | require ( 19 | github.com/CycloneDX/cyclonedx-go v0.7.0 20 | github.com/alexeyco/simpletable v1.0.0 21 | github.com/spf13/cobra v1.6.1 22 | github.com/stretchr/testify v1.8.1 23 | ) 24 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/CycloneDX/cyclonedx-go v0.7.0 h1:jNxp8hL7UpcvPDFXjY+Y1ibFtsW+e5zyF9QoSmhK/zg= 2 | github.com/CycloneDX/cyclonedx-go v0.7.0/go.mod h1:W5Z9w8pTTL+t+yG3PCiFRGlr8PUlE0pGWzKSJbsyXkg= 3 | github.com/alexeyco/simpletable v1.0.0 h1:ZQ+LvJ4bmoeHb+dclF64d0LX+7QAi7awsfCrptZrpHk= 4 | github.com/alexeyco/simpletable v1.0.0/go.mod h1:VJWVTtGUnW7EKbMRH8cE13SigKGx/1fO2SeeOiGeBkk= 5 | github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= 6 | github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 7 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 8 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 9 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 10 | github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= 11 | github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= 12 | github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= 13 | github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 14 | github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow= 15 | github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= 16 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 17 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 18 | github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY= 19 | github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 20 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 21 | github.com/spdx/gordf v0.0.0-20201111095634-7098f93598fb/go.mod h1:uKWaldnbMnjsSAXRurWqqrdyZen1R7kxl8TkmWk2OyM= 22 | github.com/spdx/gordf v0.0.0-20221230105357-b735bd5aac89 h1:dArkMwZ7Mf2JiU8OfdmqIv8QaHT4oyifLIe1UhsF1SY= 23 | github.com/spdx/gordf v0.0.0-20221230105357-b735bd5aac89/go.mod h1:uKWaldnbMnjsSAXRurWqqrdyZen1R7kxl8TkmWk2OyM= 24 | github.com/spdx/tools-golang v0.4.0 h1:jdhnW8zYelURCbYTphiviFKZkWu51in0E4A1KT2csP0= 25 | github.com/spdx/tools-golang v0.4.0/go.mod h1:VHzvNsKAfAGqs4ZvwRL+7a0dNsL20s7lGui4K9C0xQM= 26 | github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= 27 | github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= 28 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 29 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 30 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 31 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 32 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 33 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 34 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 35 | github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= 36 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 37 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 38 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 39 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 40 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 41 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 42 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 43 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 44 | sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= 45 | -------------------------------------------------------------------------------- /go.work: -------------------------------------------------------------------------------- 1 | go 1.19 2 | 3 | use . 4 | -------------------------------------------------------------------------------- /go.work.sum: -------------------------------------------------------------------------------- 1 | github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= 2 | github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= 3 | github.com/spdx/gordf v0.0.0-20201111095634-7098f93598fb h1:bLo8hvc8XFm9J47r690TUKBzcjSWdJDxmjXJZ+/f92U= 4 | github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= 5 | github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= 6 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 7 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 8 | sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= 9 | -------------------------------------------------------------------------------- /pkg/cdx/cdx_report.go: -------------------------------------------------------------------------------- 1 | package cdx 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "fmt" 7 | "math" 8 | "os" 9 | "reflect" 10 | "strings" 11 | 12 | cdx "github.com/CycloneDX/cyclonedx-go" 13 | "github.com/ebay/sbom-scorecard/pkg/scorecard" 14 | ) 15 | 16 | type CycloneDXReport struct { 17 | valid bool 18 | docError error 19 | 20 | creationToolName int 21 | creationToolVersion int 22 | hasCreationTimestamp bool 23 | 24 | totalPackages int 25 | hasLicense int 26 | hasPackVersion int 27 | hasPackDigest int 28 | hasPurl int 29 | hasCPE int 30 | hasPurlOrCPE int 31 | } 32 | 33 | func (r *CycloneDXReport) Metadata() scorecard.ReportMetadata { 34 | return scorecard.ReportMetadata{ 35 | TotalPackages: r.totalPackages, 36 | } 37 | } 38 | 39 | var missingPackages = scorecard.ReportValue{ 40 | Ratio: 0, 41 | Reasoning: "No packages", 42 | } 43 | 44 | func (r *CycloneDXReport) Report() string { 45 | var sb strings.Builder 46 | sb.WriteString(fmt.Sprintf("%d total packages\n", r.totalPackages)) 47 | 48 | sb.WriteString(fmt.Sprintf("%d%% have versions.\n", scorecard.PrettyPercent(r.hasPackVersion, r.totalPackages))) 49 | sb.WriteString(fmt.Sprintf("%d%% have licenses.\n", scorecard.PrettyPercent(r.hasLicense, r.totalPackages))) 50 | sb.WriteString(fmt.Sprintf("%d%% have package digest.\n", scorecard.PrettyPercent(r.hasPackDigest, r.totalPackages))) 51 | sb.WriteString(fmt.Sprintf("%d%% have purls.\n", scorecard.PrettyPercent(r.hasPurl, r.totalPackages))) 52 | sb.WriteString(fmt.Sprintf("%d%% have CPEs.\n", scorecard.PrettyPercent(r.hasCPE, r.totalPackages))) 53 | 54 | sb.WriteString(fmt.Sprintf("Has creation info? %v\n", r.hasCreationInfo())) 55 | sb.WriteString(fmt.Sprintf("Spec valid? %v\n", r.valid)) 56 | return sb.String() 57 | } 58 | 59 | func (r *CycloneDXReport) hasCreationInfo() bool { 60 | return r.creationToolName > 0 && 61 | r.creationToolVersion > 0 && 62 | r.creationToolName == r.creationToolVersion 63 | } 64 | 65 | func (r *CycloneDXReport) IsSpecCompliant() scorecard.ReportValue { 66 | if !r.valid { 67 | return scorecard.ReportValue{ 68 | Ratio: 0, 69 | Reasoning: "Couldn't parse the SBOM", 70 | } 71 | } 72 | 73 | if r.docError != nil { 74 | return scorecard.ReportValue{ 75 | Ratio: 0, 76 | Reasoning: r.docError.Error(), 77 | } 78 | } 79 | return scorecard.ReportValue{Ratio: 1} 80 | } 81 | 82 | func (r *CycloneDXReport) PackageIdentification() scorecard.ReportValue { 83 | if r.totalPackages == 0 { 84 | return missingPackages 85 | } 86 | purlPercent := scorecard.PrettyPercent(r.hasPurl, r.totalPackages) 87 | cpePercent := scorecard.PrettyPercent(r.hasCPE, r.totalPackages) 88 | either := scorecard.PrettyPercent(r.hasPurlOrCPE, r.totalPackages) 89 | return scorecard.ReportValue{ 90 | // What percentage has both Purl or CPEs? 91 | Ratio: nanToZero(float32(r.hasPurlOrCPE) / float32(r.totalPackages)), 92 | Reasoning: fmt.Sprintf("%d%% have either a purl (%d%%) or CPE (%d%%)", either, purlPercent, cpePercent), 93 | } 94 | } 95 | 96 | func (r *CycloneDXReport) PackageVersions() scorecard.ReportValue { 97 | return scorecard.ReportValue{ 98 | Ratio: nanToZero(float32(r.hasPackVersion) / float32(r.totalPackages)), 99 | } 100 | } 101 | 102 | func (r *CycloneDXReport) PackageDigests() scorecard.ReportValue { 103 | return scorecard.ReportValue{ 104 | Ratio: nanToZero(float32(r.hasPackDigest) / float32(r.totalPackages)), 105 | } 106 | } 107 | 108 | func (r *CycloneDXReport) PackageLicenses() scorecard.ReportValue { 109 | return scorecard.ReportValue{ 110 | Ratio: nanToZero(float32(r.hasLicense) / float32(r.totalPackages)), 111 | } 112 | } 113 | 114 | func (r *CycloneDXReport) CreationInfo() scorecard.ReportValue { 115 | var score float32 116 | score = 1.0 117 | var reasoning []string 118 | 119 | if r.creationToolName == 0 { 120 | return scorecard.ReportValue{ 121 | Ratio: 0, 122 | Reasoning: "SBOM was not generated by a tool", 123 | } 124 | } 125 | 126 | if r.creationToolVersion == 0 { 127 | score -= .2 128 | reasoning = append(reasoning, "Creation tool does not list a version") 129 | 130 | } 131 | 132 | if !r.hasCreationTimestamp { 133 | score -= .2 134 | reasoning = append(reasoning, "Missing creation timestamp") 135 | } 136 | 137 | return scorecard.ReportValue{ 138 | Ratio: score, 139 | Reasoning: strings.Join(reasoning, ", "), 140 | } 141 | } 142 | 143 | func nanToZero(f float32) float32 { 144 | if math.IsNaN(float64(f)) { 145 | return 0 146 | } 147 | return f 148 | } 149 | 150 | func GetCycloneDXReport(filename string) scorecard.SbomReport { 151 | contents, err := os.ReadFile(filename) 152 | if err != nil { 153 | fmt.Printf("Error while opening %v for reading: %v", filename, err) 154 | return nil 155 | } 156 | 157 | r := CycloneDXReport{} 158 | formats := []cdx.BOMFileFormat{cdx.BOMFileFormatJSON, cdx.BOMFileFormatXML} 159 | 160 | sentinelBom := new(cdx.BOM) 161 | bom := new(cdx.BOM) 162 | for _, format := range formats { 163 | decoder := cdx.NewBOMDecoder(bytes.NewReader(contents), format) 164 | if err = decoder.Decode(bom); err != nil { 165 | r.valid = false 166 | r.docError = err 167 | } else if reflect.DeepEqual(bom, sentinelBom) { 168 | // If the bom was "decoded" but no fields made it over, it's not valid. 169 | r.valid = false 170 | r.docError = errors.New("SBOM decoded, but no fields were parsed.") 171 | } else { 172 | r.valid = true 173 | r.docError = nil 174 | break 175 | } 176 | } 177 | 178 | if !r.valid { 179 | return &r 180 | } 181 | 182 | if bom.Metadata != nil && bom.Metadata.Tools != nil { 183 | for _, t := range *bom.Metadata.Tools { 184 | if t.Name != "" { 185 | r.creationToolName += 1 186 | } 187 | if t.Version != "" { 188 | r.creationToolVersion += 1 189 | } 190 | } 191 | } 192 | 193 | if bom.Metadata.Timestamp != "" { 194 | r.hasCreationTimestamp = true 195 | } 196 | 197 | if bom.Components != nil { 198 | for _, p := range *bom.Components { 199 | r.totalPackages += 1 200 | if p.Licenses != nil && len(*p.Licenses) > 0 { 201 | r.hasLicense += 1 202 | } 203 | if p.Hashes != nil && len(*p.Hashes) > 0 { 204 | r.hasPackDigest += 1 205 | } 206 | if p.Version != "" { 207 | r.hasPackVersion += 1 208 | } 209 | if p.PackageURL != "" { 210 | r.hasPurl += 1 211 | } 212 | if p.CPE != "" { 213 | r.hasCPE += 1 214 | } 215 | if p.PackageURL != "" || p.CPE != "" { 216 | r.hasPurlOrCPE += 1 217 | } 218 | } 219 | } 220 | 221 | return &r 222 | } 223 | -------------------------------------------------------------------------------- /pkg/cdx/cdx_report_test.go: -------------------------------------------------------------------------------- 1 | package cdx 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/ebay/sbom-scorecard/pkg/scorecard" 8 | ) 9 | 10 | func assertTextEqual(t *testing.T, actual string, expected string) { 11 | if strings.Trim(actual, " \n") != expected { 12 | t.Log("Incorrect report text generated.\n" + 13 | "Got this:\n" + actual + "\n\n but expected:\n" + expected) 14 | t.Fail() 15 | } 16 | } 17 | 18 | func TestCycloneE2eReport(t *testing.T) { 19 | r := GetCycloneDXReport("../../examples/dropwizard.cyclonedx.json") 20 | 21 | report_text := r.Report() 22 | assertTextEqual(t, 23 | report_text, 24 | `167 total packages 25 | 100% have versions. 26 | 79% have licenses. 27 | 100% have package digest. 28 | 100% have purls. 29 | 0% have CPEs. 30 | Has creation info? true 31 | Spec valid? true`) 32 | } 33 | 34 | func TestCycloneE2eGrade(t *testing.T) { 35 | r := GetCycloneDXReport("../../examples/dropwizard.cyclonedx.json") 36 | 37 | report_text := scorecard.Grade(r) 38 | assertTextEqual(t, 39 | report_text, 40 | `Spec Compliance: 25/25 41 | Package ID: 20/20 (100% have either a purl (100%) or CPE (0%)) 42 | Package Versions: 20/20 43 | Package Licenses: 15/20 44 | Creation Info: 15/15 45 | Total points: 95/100 or 95%`) 46 | } 47 | 48 | func TestCycloneXML(t *testing.T) { 49 | r := GetCycloneDXReport("../../examples/openfeature-javasdk.cyclonedx.xml") 50 | 51 | report_text := scorecard.Grade(r) 52 | assertTextEqual(t, 53 | report_text, 54 | `Spec Compliance: 25/25 55 | Package ID: 20/20 (100% have either a purl (100%) or CPE (0%)) 56 | Package Versions: 20/20 57 | Package Licenses: 18/20 58 | Creation Info: 15/15 59 | Total points: 98/100 or 98%`) 60 | } 61 | 62 | func TestCycloneInvalid(t *testing.T) { 63 | r := GetCycloneDXReport("../../examples/invalid.json") 64 | 65 | report_text := scorecard.Grade(r) 66 | assertTextEqual(t, 67 | report_text, 68 | `Spec Compliance: 0/25 (Couldn't parse the SBOM) 69 | Package ID: 0/20 (No packages) 70 | Package Versions: 0/20 71 | Package Licenses: 0/20 72 | Creation Info: 0/15 (SBOM was not generated by a tool) 73 | Total points: 0/100 or 0%`) 74 | } 75 | -------------------------------------------------------------------------------- /pkg/scorecard/scorecard.go: -------------------------------------------------------------------------------- 1 | package scorecard 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "math" 7 | "strings" 8 | 9 | "github.com/alexeyco/simpletable" 10 | ) 11 | 12 | type ReportValue struct { 13 | Ratio float32 14 | Reasoning string 15 | } 16 | 17 | const validPoints = 25 18 | const generationPoints = 15 19 | const packageSectionWeight = 20 20 | 21 | // TODO capture generation points 22 | 23 | type ReportMetadata struct { 24 | TotalPackages int 25 | } 26 | 27 | type SbomReport interface { 28 | IsSpecCompliant() ReportValue 29 | PackageIdentification() ReportValue 30 | PackageVersions() ReportValue 31 | PackageLicenses() ReportValue 32 | CreationInfo() ReportValue 33 | Metadata() ReportMetadata 34 | Report() string 35 | } 36 | 37 | type ScoreValue struct { 38 | ReportValue 39 | MaxPoints float32 40 | } 41 | 42 | func (sv *ScoreValue) Score() float32 { 43 | if math.IsNaN(float64(sv.Ratio)) { 44 | return 0 45 | } 46 | return sv.Ratio * sv.MaxPoints 47 | } 48 | 49 | type ReportResult struct { 50 | Compliance ScoreValue 51 | PackageIdentification ScoreValue 52 | PackageVersions ScoreValue 53 | PackageLicenses ScoreValue 54 | CreationInfo ScoreValue 55 | Total ScoreValue 56 | Metadata ReportMetadata 57 | } 58 | 59 | func reportValueToScore(rv ReportValue, maxPoints float32) ScoreValue { 60 | sv := ScoreValue{ 61 | MaxPoints: maxPoints, 62 | } 63 | sv.Ratio = rv.Ratio 64 | sv.Reasoning = rv.Reasoning 65 | return sv 66 | } 67 | 68 | func getScore(sr SbomReport) ReportResult { 69 | rr := ReportResult{ 70 | Compliance: reportValueToScore(sr.IsSpecCompliant(), validPoints), 71 | PackageIdentification: reportValueToScore(sr.PackageIdentification(), packageSectionWeight), 72 | PackageVersions: reportValueToScore(sr.PackageVersions(), packageSectionWeight), 73 | PackageLicenses: reportValueToScore(sr.PackageLicenses(), packageSectionWeight), 74 | CreationInfo: reportValueToScore(sr.CreationInfo(), generationPoints), 75 | Metadata: ReportMetadata{ 76 | TotalPackages: sr.Metadata().TotalPackages, 77 | }, 78 | } 79 | var totalPoints float32 80 | var maxPoints float32 81 | 82 | maxPoints += rr.Compliance.MaxPoints 83 | totalPoints += rr.Compliance.Score() 84 | 85 | maxPoints += rr.PackageIdentification.MaxPoints 86 | totalPoints += rr.PackageIdentification.Score() 87 | 88 | maxPoints += rr.PackageVersions.MaxPoints 89 | totalPoints += rr.PackageVersions.Score() 90 | 91 | maxPoints += rr.PackageLicenses.MaxPoints 92 | totalPoints += rr.PackageLicenses.Score() 93 | 94 | maxPoints += rr.CreationInfo.MaxPoints 95 | totalPoints += rr.CreationInfo.Score() 96 | 97 | rr.Total = ScoreValue{ 98 | MaxPoints: maxPoints, 99 | } 100 | rr.Total.Ratio = totalPoints / maxPoints 101 | 102 | return rr 103 | } 104 | 105 | func JsonGrade(sr SbomReport) string { 106 | out, _ := json.Marshal(getScore(sr)) 107 | return string(out) 108 | } 109 | 110 | func getReportValueInfo(title string, sv ScoreValue) string { 111 | var sb strings.Builder 112 | sb.WriteString(fmt.Sprintf("%s: %d/%d", title, int(sv.Score()), int(sv.MaxPoints))) 113 | if sv.Reasoning != "" { 114 | sb.WriteString(fmt.Sprintf(" (%s)", sv.Reasoning)) 115 | } 116 | sb.WriteString("\n") 117 | return sb.String() 118 | } 119 | 120 | func Grade(sr SbomReport) string { 121 | sv := getScore(sr) 122 | var sb strings.Builder 123 | 124 | sb.WriteString(getReportValueInfo("Spec Compliance", sv.Compliance)) 125 | sb.WriteString(getReportValueInfo("Package ID", sv.PackageIdentification)) 126 | sb.WriteString(getReportValueInfo("Package Versions", sv.PackageVersions)) 127 | sb.WriteString(getReportValueInfo("Package Licenses", sv.PackageLicenses)) 128 | sb.WriteString(getReportValueInfo("Creation Info", sv.CreationInfo)) 129 | 130 | sb.WriteString(fmt.Sprintf("Total points: %d/%d or %d%%\n", int(sv.Total.Score()), int(sv.Total.MaxPoints), PrettyPercent(int(sv.Total.Score()), int(sv.Total.MaxPoints)))) 131 | 132 | return sb.String() 133 | } 134 | 135 | func GradeTableFormat(sr SbomReport) { 136 | sv := getScore(sr) 137 | table := simpletable.New() 138 | 139 | table.Header = &simpletable.Header{ 140 | Cells: []*simpletable.Cell{ 141 | {Align: simpletable.AlignCenter, Text: "#"}, 142 | {Align: simpletable.AlignCenter, Text: "Criteria"}, 143 | {Align: simpletable.AlignCenter, Text: "Points"}, 144 | {Align: simpletable.AlignCenter, Text: "Reasoning"}, 145 | }, 146 | } 147 | 148 | var n int 149 | 150 | var cells [][]*simpletable.Cell 151 | n++ 152 | cells = append(cells, genCell("Spec Compliance", n, sv.Compliance)) 153 | n++ 154 | cells = append(cells, genCell("Package ID", n, sv.PackageIdentification)) 155 | n++ 156 | cells = append(cells, genCell("Package Versions", n, sv.PackageVersions)) 157 | n++ 158 | cells = append(cells, genCell("Package Licenses", n, sv.PackageLicenses)) 159 | n++ 160 | cells = append(cells, genCell("Creation Info", n, sv.CreationInfo)) 161 | 162 | table.Body = &simpletable.Body{Cells: cells} 163 | total := fmt.Sprintf("Total points: %d/%d or %d%%\n", int(sv.Total.Score()), int(sv.Total.MaxPoints), PrettyPercent(int(sv.Total.Score()), int(sv.Total.MaxPoints))) 164 | table.Footer = &simpletable.Footer{Cells: []*simpletable.Cell{ 165 | {Align: simpletable.AlignCenter, Span: 4, Text: yellow(total)}, 166 | }} 167 | 168 | table.SetStyle(simpletable.StyleUnicode) 169 | table.Println() 170 | } 171 | 172 | func genCell(title string, n int, scoreValue ScoreValue) []*simpletable.Cell { 173 | return *&[]*simpletable.Cell{ 174 | {Text: fmt.Sprintf("%d", n)}, 175 | {Text: title}, 176 | {Text: fmt.Sprintf("%d/%d", int(scoreValue.Score()), int(scoreValue.MaxPoints))}, 177 | {Text: red(fmt.Sprintf("%v", scoreValue.Reasoning))}, 178 | } 179 | } 180 | 181 | // ANSI color codes: https://talyian.github.io/ansicolors/ 182 | const ( 183 | ColorDefault = "\x1b[39m" 184 | ColorRed = "\x1b[91m" 185 | ColorYellow = "\x1b[93m" 186 | ) 187 | 188 | func red(s string) string { 189 | return fmt.Sprintf("%s%s%s", ColorRed, s, ColorDefault) 190 | } 191 | func yellow(s string) string { 192 | return fmt.Sprintf("%s%s%s", ColorYellow, s, ColorDefault) 193 | } 194 | 195 | func PrettyPercent(num, denom int) int { 196 | if denom == 0 { 197 | return 0 198 | } 199 | return 100 * (1.0 * num) / denom 200 | } 201 | -------------------------------------------------------------------------------- /pkg/spdx/document.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package spdx 4 | 5 | import ( 6 | "bytes" 7 | "errors" 8 | "fmt" 9 | "os" 10 | 11 | spdx_json "github.com/spdx/tools-golang/json" 12 | spdx_rdf "github.com/spdx/tools-golang/rdfloader" 13 | spdx_tv "github.com/spdx/tools-golang/tvloader" 14 | 15 | "github.com/spdx/tools-golang/spdx/common" 16 | "github.com/spdx/tools-golang/spdx/v2_2" 17 | "github.com/spdx/tools-golang/spdx/v2_3" 18 | ) 19 | 20 | const errOpenDoc = "opening SPDX %s document: %w" 21 | 22 | var ErrUnknownFormat = fmt.Errorf("unrecognized document format") 23 | 24 | type Document_22 v2_2.Document 25 | type Document_23 v2_3.Document 26 | 27 | type Package struct { 28 | PackageLicenseConcluded string 29 | PackageLicenseDeclared string 30 | PackageExternalReferences []*PackageExternalReference 31 | PackageChecksums []common.Checksum 32 | PackageVersion string 33 | } 34 | 35 | type File struct { 36 | Checksums []common.Checksum 37 | } 38 | 39 | func LoadDocument(path string) (Document, error) { 40 | f, err := os.ReadFile(path) 41 | if err != nil { 42 | return nil, fmt.Errorf("opening SPDX document: %w", err) 43 | } 44 | 45 | doc23, err := spdx_json.Load2_3(bytes.NewReader(f)) 46 | if err == nil && doc23 != nil { 47 | return documentFromSPDX(doc23) 48 | } 49 | doc23, err = spdx_rdf.Load2_3(bytes.NewReader(f)) 50 | if err == nil && doc23 != nil { 51 | return documentFromSPDX(doc23) 52 | } 53 | doc23, err = spdx_tv.Load2_3(bytes.NewReader(f)) 54 | if err == nil && doc23 != nil { 55 | return documentFromSPDX(doc23) 56 | } 57 | 58 | doc22, err := spdx_json.Load2_2(bytes.NewReader(f)) 59 | if err == nil && doc22 != nil { 60 | return documentFromSPDX(doc22) 61 | } 62 | doc22, err = spdx_rdf.Load2_2(bytes.NewReader(f)) 63 | if err == nil && doc22 != nil { 64 | return documentFromSPDX(doc22) 65 | } 66 | doc22, err = spdx_tv.Load2_2(bytes.NewReader(f)) 67 | if err == nil && doc22 != nil { 68 | return documentFromSPDX(doc22) 69 | } 70 | 71 | return nil, ErrUnknownFormat 72 | } 73 | 74 | func getFiles(doc interface{}) []File { 75 | files := []File{} 76 | switch castDoc := doc.(type) { 77 | case *Document_22: 78 | for _, of := range castDoc.Files { 79 | f := File{Checksums: of.Checksums} 80 | files = append(files, f) 81 | } 82 | case *Document_23: 83 | for _, of := range castDoc.Files { 84 | f := File{} 85 | f.Checksums = of.Checksums 86 | files = append(files, f) 87 | } 88 | } 89 | return files 90 | } 91 | 92 | func documentFromSPDX(doc interface{}) (Document, error) { 93 | switch castDoc := doc.(type) { 94 | case *v2_2.Document: 95 | d := Document_22(*castDoc) 96 | return &d, nil 97 | case *v2_3.Document: 98 | d := Document_23(*castDoc) 99 | return &d, nil 100 | } 101 | return nil, errors.New("unrecognized document format") 102 | } 103 | 104 | func (d *Document_22) Version() string { 105 | return version(d) 106 | } 107 | 108 | func (d *Document_22) GetCreationInfo() *CreationInfo { 109 | return creationInfo(d) 110 | } 111 | 112 | func (d *Document_23) Version() string { 113 | return version(d) 114 | } 115 | 116 | func (d *Document_23) GetCreationInfo() *CreationInfo { 117 | return creationInfo(d) 118 | } 119 | 120 | func NewPackage() *Package { 121 | return &Package{} 122 | } 123 | 124 | func (p *Package) read22(sp *v2_2.Package) { 125 | p.PackageExternalReferences = externalReferences(sp) 126 | p.PackageLicenseConcluded = sp.PackageLicenseConcluded 127 | p.PackageLicenseDeclared = sp.PackageLicenseDeclared 128 | p.PackageChecksums = sp.PackageChecksums 129 | p.PackageVersion = sp.PackageVersion 130 | } 131 | 132 | func (p *Package) read23(sp *v2_3.Package) { 133 | p.PackageExternalReferences = externalReferences(sp) 134 | p.PackageLicenseConcluded = sp.PackageLicenseConcluded 135 | p.PackageLicenseDeclared = sp.PackageLicenseDeclared 136 | p.PackageChecksums = sp.PackageChecksums 137 | p.PackageVersion = sp.PackageVersion 138 | } 139 | 140 | func (d *Document_22) GetFiles() []File { 141 | return getFiles(d) 142 | } 143 | 144 | func (d *Document_23) GetFiles() []File { 145 | return getFiles(d) 146 | } 147 | 148 | func (d *Document_23) GetPackages() []Package { 149 | packages := []Package{} 150 | for _, p := range d.Packages { 151 | np := Package{} 152 | np.read23(p) 153 | packages = append(packages, np) 154 | } 155 | return packages 156 | } 157 | 158 | func (d *Document_22) GetPackages() []Package { 159 | packages := []Package{} 160 | for _, p := range d.Packages { 161 | np := Package{} 162 | np.read22(p) 163 | packages = append(packages, np) 164 | } 165 | return packages 166 | } 167 | 168 | type CreationInfo struct { 169 | LicenseListVersion string 170 | Creators []common.Creator 171 | Created string 172 | CreatorComment string 173 | } 174 | 175 | type PackageExternalReference struct { 176 | Category string 177 | RefType string 178 | Locator string 179 | ExternalRefComment string 180 | } 181 | 182 | type Document interface { 183 | Version() string 184 | GetCreationInfo() *CreationInfo 185 | GetPackages() []Package 186 | GetFiles() []File 187 | } 188 | 189 | func externalReferences(pkg interface{}) []*PackageExternalReference { 190 | refs := []*PackageExternalReference{} 191 | switch castPkg := pkg.(type) { 192 | case *v2_2.Package: 193 | if castPkg.PackageExternalReferences == nil { 194 | return nil 195 | } 196 | 197 | for _, p := range castPkg.PackageExternalReferences { 198 | refs = append(refs, &PackageExternalReference{ 199 | Category: p.Category, 200 | RefType: p.RefType, 201 | Locator: p.Locator, 202 | ExternalRefComment: p.ExternalRefComment, 203 | }) 204 | } 205 | case *v2_3.Package: 206 | if castPkg.PackageExternalReferences == nil { 207 | return nil 208 | } 209 | 210 | for _, p := range castPkg.PackageExternalReferences { 211 | refs = append(refs, &PackageExternalReference{ 212 | Category: p.Category, 213 | RefType: p.RefType, 214 | Locator: p.Locator, 215 | ExternalRefComment: p.ExternalRefComment, 216 | }) 217 | } 218 | } 219 | 220 | return refs 221 | } 222 | 223 | func creationInfo(doc Document) *CreationInfo { 224 | var ci *CreationInfo 225 | creators := []common.Creator{} 226 | 227 | switch castDoc := doc.(type) { 228 | case *Document_22: 229 | if castDoc.CreationInfo == nil { 230 | return nil 231 | } 232 | ci = &CreationInfo{ 233 | LicenseListVersion: castDoc.CreationInfo.LicenseListVersion, 234 | Created: castDoc.CreationInfo.Created, 235 | CreatorComment: castDoc.CreationInfo.CreatorComment, 236 | } 237 | if castDoc.CreationInfo.Creators != nil { 238 | creators = castDoc.CreationInfo.Creators 239 | } 240 | case *Document_23: 241 | if castDoc.CreationInfo == nil { 242 | return nil 243 | } 244 | ci = &CreationInfo{ 245 | LicenseListVersion: castDoc.CreationInfo.LicenseListVersion, 246 | Created: castDoc.CreationInfo.Created, 247 | CreatorComment: castDoc.CreationInfo.CreatorComment, 248 | } 249 | if castDoc.CreationInfo.Creators != nil { 250 | creators = castDoc.CreationInfo.Creators 251 | } 252 | } 253 | ci.Creators = creators 254 | return ci 255 | } 256 | 257 | func version(doc Document) string { 258 | switch doc.(type) { 259 | case *Document_22: 260 | return "2.2" 261 | case *Document_23: 262 | return "2.3" 263 | } 264 | return "" 265 | } 266 | -------------------------------------------------------------------------------- /pkg/spdx/document_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package spdx 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func TestLoadDocument(t *testing.T) { 12 | // Test 2.3 document load 13 | doc, err := LoadDocument("test_data/nginx.spdx.json") 14 | require.NoError(t, err) 15 | require.NotNil(t, doc) 16 | _, ok := doc.(*Document_23) 17 | require.True(t, ok) 18 | 19 | // Test 2.3 document load 20 | doc, err = LoadDocument("test_data/missionlz.spdx.json") 21 | require.NoError(t, err) 22 | require.NotNil(t, doc) 23 | // Currently 2.3 will open 2.2 docs. So this will fail 24 | // _, ok = doc.(*Document_22) 25 | // require.True(t, ok) 26 | } 27 | 28 | func TestLoadTV22(t *testing.T) { 29 | doc, err := LoadDocument("../../examples/spdx-example.tv") 30 | require.NoError(t, err) 31 | require.NotNil(t, doc) 32 | // even though this is actually a 2.2 doc, it does validly parse into a 2.3 doc. 33 | _, ok := doc.(*Document_23) 34 | require.True(t, ok) 35 | } 36 | -------------------------------------------------------------------------------- /pkg/spdx/spdx_report.go: -------------------------------------------------------------------------------- 1 | package spdx 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/ebay/sbom-scorecard/pkg/scorecard" 8 | spdx_common "github.com/spdx/tools-golang/spdx/common" 9 | 10 | "regexp" 11 | ) 12 | 13 | var isNumeric = regexp.MustCompile(`\d`) 14 | 15 | var missingPackages = scorecard.ReportValue{ 16 | Ratio: 0, 17 | Reasoning: "No packages", 18 | } 19 | 20 | type SpdxReport struct { 21 | doc Document 22 | docError error 23 | valid bool 24 | 25 | totalPackages int 26 | totalFiles int 27 | hasLicense int 28 | hasPackDigest int 29 | hasPurl int 30 | hasCPE int 31 | hasPurlOrCPE int 32 | hasFileDigest int 33 | hasPackVer int 34 | } 35 | 36 | func (r *SpdxReport) Metadata() scorecard.ReportMetadata { 37 | return scorecard.ReportMetadata{ 38 | TotalPackages: r.totalPackages, 39 | } 40 | } 41 | 42 | func (r *SpdxReport) Report() string { 43 | var sb strings.Builder 44 | sb.WriteString(fmt.Sprintf("%d total packages\n", r.totalPackages)) 45 | sb.WriteString(fmt.Sprintf("%d total files\n", r.totalFiles)) 46 | sb.WriteString(fmt.Sprintf("%d%% have licenses.\n", scorecard.PrettyPercent(r.hasLicense, r.totalPackages))) 47 | sb.WriteString(fmt.Sprintf("%d%% have package digest.\n", scorecard.PrettyPercent(r.hasPackDigest, r.totalPackages))) 48 | sb.WriteString(fmt.Sprintf("%d%% have package versions.\n", scorecard.PrettyPercent(r.hasPackVer, r.totalPackages))) 49 | sb.WriteString(fmt.Sprintf("%d%% have purls.\n", scorecard.PrettyPercent(r.hasPurl, r.totalPackages))) 50 | sb.WriteString(fmt.Sprintf("%d%% have CPEs.\n", scorecard.PrettyPercent(r.hasCPE, r.totalPackages))) 51 | sb.WriteString(fmt.Sprintf("%d%% have file digest.\n", scorecard.PrettyPercent(r.hasFileDigest, r.totalFiles))) 52 | sb.WriteString(fmt.Sprintf("Spec valid? %v\n", r.valid)) 53 | sb.WriteString(fmt.Sprintf("Has creation info? %v\n", r.CreationInfo().Ratio == 1)) 54 | 55 | return sb.String() 56 | } 57 | 58 | func (r *SpdxReport) IsSpecCompliant() scorecard.ReportValue { 59 | if r.docError != nil { 60 | return scorecard.ReportValue{ 61 | Ratio: 0, 62 | Reasoning: r.docError.Error(), 63 | } 64 | } 65 | return scorecard.ReportValue{Ratio: 1} 66 | } 67 | 68 | func (r *SpdxReport) PackageIdentification() scorecard.ReportValue { 69 | if r.totalPackages == 0 { 70 | return missingPackages 71 | } 72 | purlPercent := scorecard.PrettyPercent(r.hasPurl, r.totalPackages) 73 | cpePercent := scorecard.PrettyPercent(r.hasCPE, r.totalPackages) 74 | either := scorecard.PrettyPercent(r.hasPurlOrCPE, r.totalPackages) 75 | return scorecard.ReportValue{ 76 | // What percentage has both Purl & CPEs? 77 | Ratio: float32(r.hasPurlOrCPE) / float32(r.totalPackages), 78 | Reasoning: fmt.Sprintf("%d%% have either purls (%d%%) or CPEs (%d%%)", either, purlPercent, cpePercent), 79 | } 80 | } 81 | 82 | func (r *SpdxReport) PackageVersions() scorecard.ReportValue { 83 | if r.totalPackages == 0 { 84 | return scorecard.ReportValue{ 85 | Ratio: 0, 86 | Reasoning: "No packages", 87 | } 88 | } 89 | return scorecard.ReportValue{ 90 | Ratio: float32(r.hasPackVer) / float32(r.totalPackages), 91 | } 92 | } 93 | 94 | func (r *SpdxReport) PackageLicenses() scorecard.ReportValue { 95 | if r.totalPackages == 0 { 96 | return scorecard.ReportValue{ 97 | Ratio: 0, 98 | Reasoning: "No packages", 99 | } 100 | } 101 | return scorecard.ReportValue{ 102 | Ratio: float32(r.hasLicense) / float32(r.totalPackages), 103 | } 104 | } 105 | 106 | func (r *SpdxReport) CreationInfo() scorecard.ReportValue { 107 | foundTool := false 108 | hasVersion := false 109 | 110 | if r.doc == nil || r.doc.GetCreationInfo() == nil { 111 | return scorecard.ReportValue{ 112 | Ratio: 0, 113 | Reasoning: "No creation info found", 114 | } 115 | } 116 | 117 | for _, creator := range r.doc.GetCreationInfo().Creators { 118 | if creator.CreatorType == "Tool" { 119 | foundTool = true 120 | if isNumeric.MatchString(creator.Creator) { 121 | hasVersion = true 122 | } 123 | } 124 | } 125 | 126 | if !foundTool { 127 | return scorecard.ReportValue{ 128 | Ratio: 0, 129 | Reasoning: "No tool was used to create the sbom", 130 | } 131 | } 132 | 133 | var score float32 134 | score = 1.0 135 | reasons := []string{} 136 | 137 | if !hasVersion { 138 | score -= .2 139 | reasons = append(reasons, "The tool used to create the sbom does not have a version") 140 | } 141 | 142 | if r.doc.GetCreationInfo().Created == "" { 143 | score -= .2 144 | reasons = append(reasons, "There is no timestamp for when the sbom was created") 145 | } 146 | 147 | return scorecard.ReportValue{ 148 | Ratio: score, 149 | Reasoning: strings.Join(reasons, ", "), 150 | } 151 | 152 | } 153 | 154 | func GetSpdxReport(filename string) scorecard.SbomReport { 155 | sr := SpdxReport{} 156 | doc, err := LoadDocument(filename) 157 | if err != nil { 158 | fmt.Printf("loading document: %v\n", err) 159 | return &sr 160 | } 161 | 162 | // try to load the SPDX file's contents as a json file, version 2.2 163 | sr.doc = doc 164 | sr.docError = err 165 | sr.valid = err == nil 166 | if sr.doc != nil { 167 | packages := sr.doc.GetPackages() 168 | 169 | for _, p := range packages { 170 | sr.totalPackages += 1 171 | if p.PackageLicenseConcluded != "NONE" && 172 | p.PackageLicenseConcluded != "NOASSERTION" && 173 | p.PackageLicenseConcluded != "" { 174 | sr.hasLicense += 1 175 | } else if p.PackageLicenseDeclared != "NONE" && 176 | p.PackageLicenseDeclared != "NOASSERTION" && 177 | p.PackageLicenseDeclared != "" { 178 | sr.hasLicense += 1 179 | } 180 | 181 | if len(p.PackageChecksums) > 0 { 182 | sr.hasPackDigest += 1 183 | } 184 | 185 | var foundCPE bool 186 | var foundPURL bool 187 | for _, ref := range p.PackageExternalReferences { 188 | if !foundPURL && ref.RefType == spdx_common.TypePackageManagerPURL { 189 | sr.hasPurl += 1 190 | foundPURL = true 191 | } 192 | 193 | if !foundCPE && strings.HasPrefix(ref.RefType, "cpe") { 194 | sr.hasCPE += 1 195 | foundCPE = true 196 | } 197 | } 198 | if foundCPE && foundPURL { 199 | sr.hasPurlOrCPE += 1 200 | } 201 | 202 | if p.PackageVersion != "" { 203 | sr.hasPackVer += 1 204 | } 205 | } 206 | 207 | for _, file := range sr.doc.GetFiles() { 208 | sr.totalFiles += 1 209 | if len(file.Checksums) > 0 { 210 | sr.hasFileDigest += 1 211 | } 212 | } 213 | } 214 | return &sr 215 | } 216 | -------------------------------------------------------------------------------- /pkg/spdx/spdx_report_test.go: -------------------------------------------------------------------------------- 1 | package spdx 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/ebay/sbom-scorecard/pkg/scorecard" 8 | ) 9 | 10 | var report_tests = []struct { 11 | path string 12 | expected string 13 | }{ 14 | {"../../examples/julia.spdx.json", `34 total packages 15 | 0 total files 16 | 100% have licenses. 17 | 0% have package digest. 18 | 2% have package versions. 19 | 0% have purls. 20 | 0% have CPEs. 21 | 0% have file digest. 22 | Spec valid? true 23 | Has creation info? false`}, 24 | {"../../examples/photon.spdx.json", `38 total packages 25 | 0 total files 26 | 94% have licenses. 27 | 2% have package digest. 28 | 97% have package versions. 29 | 0% have purls. 30 | 0% have CPEs. 31 | 0% have file digest. 32 | Spec valid? true 33 | Has creation info? true`}, 34 | } 35 | 36 | func TestSpdxE2eReport(t *testing.T) { 37 | for _, e := range report_tests { 38 | res := GetSpdxReport(e.path) 39 | report_text := res.Report() 40 | if strings.Trim(report_text, " \n") != e.expected { 41 | t.Errorf("GetSpdxReport(%v) = %v, expected %v", 42 | e.path, strings.Trim(report_text, " \n"), e.expected) 43 | } 44 | } 45 | } 46 | 47 | var grade_tests = []struct { 48 | path string 49 | expected string 50 | }{ 51 | {"../../examples/julia.spdx.json", `Spec Compliance: 25/25 52 | Package ID: 0/20 (0% have either purls (0%) or CPEs (0%)) 53 | Package Versions: 0/20 54 | Package Licenses: 20/20 55 | Creation Info: 0/15 (No tool was used to create the sbom) 56 | Total points: 45/100 or 45%`}, 57 | {"../../examples/photon.spdx.json", `Spec Compliance: 25/25 58 | Package ID: 0/20 (0% have either purls (0%) or CPEs (0%)) 59 | Package Versions: 19/20 60 | Package Licenses: 18/20 61 | Creation Info: 15/15 62 | Total points: 78/100 or 78%`}, 63 | } 64 | 65 | func TestSpdxE2eGrade(t *testing.T) { 66 | for _, e := range grade_tests { 67 | res := GetSpdxReport(e.path) 68 | report_text := scorecard.Grade(res) 69 | if strings.Trim(report_text, " \n") != e.expected { 70 | t.Errorf("GetSpdxReport(%v) = %v, expected %v", 71 | e.path, strings.Trim(report_text, " \n"), e.expected) 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eBay/sbom-scorecard/dc7a7080db71fba617f6287615feeee175626435/result.png -------------------------------------------------------------------------------- /sbom-scorecard.yml: -------------------------------------------------------------------------------- 1 | # The configurations that used for the recording, feel free to edit them 2 | config: 3 | 4 | # Specify a command to be executed 5 | # like `/bin/bash -l`, `ls`, or any other commands 6 | # the default is bash for Linux 7 | # or powershell.exe for Windows 8 | command: bash -l 9 | 10 | # Specify the current working directory path 11 | # the default is the current working directory path 12 | cwd: /tmp 13 | 14 | # Export additional ENV variables 15 | env: 16 | recording: true 17 | 18 | # Explicitly set the number of columns 19 | # or use `auto` to take the current 20 | # number of columns of your shell 21 | cols: 100 22 | 23 | # Explicitly set the number of rows 24 | # or use `auto` to take the current 25 | # number of rows of your shell 26 | rows: 42 27 | 28 | # Amount of times to repeat GIF 29 | # If value is -1, play once 30 | # If value is 0, loop indefinitely 31 | # If value is a positive number, loop n times 32 | repeat: 0 33 | 34 | # Quality 35 | # 1 - 100 36 | quality: 100 37 | 38 | # Delay between frames in ms 39 | # If the value is `auto` use the actual recording delays 40 | frameDelay: auto 41 | 42 | # Maximum delay between frames in ms 43 | # Ignored if the `frameDelay` isn't set to `auto` 44 | # Set to `auto` to prevent limiting the max idle time 45 | maxIdleTime: 5000 46 | 47 | # The surrounding frame box 48 | # The `type` can be null, window, floating, or solid` 49 | # To hide the title use the value null 50 | # Don't forget to add a backgroundColor style with a null as type 51 | frameBox: 52 | type: floating 53 | title: Terminalizer 54 | style: 55 | border: 0px black solid 56 | # boxShadow: none 57 | # margin: 0px 58 | 59 | # Add a watermark image to the rendered gif 60 | # You need to specify an absolute path for 61 | # the image on your machine or a URL, and you can also 62 | # add your own CSS styles 63 | watermark: 64 | imagePath: null 65 | style: 66 | position: absolute 67 | right: 15px 68 | bottom: 15px 69 | width: 100px 70 | opacity: 0.9 71 | 72 | # Cursor style can be one of 73 | # `block`, `underline`, or `bar` 74 | cursorStyle: block 75 | 76 | # Font family 77 | # You can use any font that is installed on your machine 78 | # in CSS-like syntax 79 | fontFamily: "Monaco, Lucida Console, Ubuntu Mono, Monospace" 80 | 81 | # The size of the font 82 | fontSize: 12 83 | 84 | # The height of lines 85 | lineHeight: 1 86 | 87 | # The spacing between letters 88 | letterSpacing: 0 89 | 90 | # Theme 91 | theme: 92 | background: "transparent" 93 | foreground: "#afafaf" 94 | cursor: "#c7c7c7" 95 | black: "#232628" 96 | red: "#fc4384" 97 | green: "#b3e33b" 98 | yellow: "#ffa727" 99 | blue: "#75dff2" 100 | magenta: "#ae89fe" 101 | cyan: "#708387" 102 | white: "#d5d5d0" 103 | brightBlack: "#626566" 104 | brightRed: "#ff7fac" 105 | brightGreen: "#c8ed71" 106 | brightYellow: "#ebdf86" 107 | brightBlue: "#75dff2" 108 | brightMagenta: "#ae89fe" 109 | brightCyan: "#b1c6ca" 110 | brightWhite: "#f9f9f4" 111 | 112 | # Records, feel free to edit them 113 | records: 114 | - delay: 1 115 | content: "$ " 116 | - delay: 646 117 | content: go install github.com/ebay/sbom-scorecard/cmd/sbom-scorecard@latest 118 | - delay: 1158 119 | content: "\r\n" 120 | - delay: 1041 121 | content: "go: downloading github.com/ebay/sbom-scorecard v0.0.0-20230117174011-effef3b7e792\r\n" 122 | - delay: 845 123 | content: "go: finding module for package github.com/spdx/gordf/uri\r\ngo: finding module for package github.com/spdx/gordf/rdfloader/parser\r\ngo: finding module for package github.com/spdx/gordf/rdfloader\r\ngo: finding module for package github.com/spdx/gordf/rdfwriter\r\n" 124 | - delay: 289 125 | content: "go: downloading github.com/spdx/gordf v0.0.0-20221230105357-b735bd5aac89\r\n" 126 | - delay: 560 127 | content: "go: found github.com/spdx/gordf/rdfloader in github.com/spdx/gordf v0.0.0-20221230105357-b735bd5aac89\r\ngo: found github.com/spdx/gordf/rdfloader/parser in github.com/spdx/gordf v0.0.0-20221230105357-b735bd5aac89\r\ngo: found github.com/spdx/gordf/rdfwriter in github.com/spdx/gordf v0.0.0-20221230105357-b735bd5aac89\r\ngo: found github.com/spdx/gordf/uri in github.com/spdx/gordf v0.0.0-20221230105357-b735bd5aac89\r\n" 128 | - delay: 1235 129 | content: "\e]7;file://C02C780ZMD6R/Users/jabrahms/src/github.com/ericaabrahms/sbom-scorecard-website\aC02C780ZMD6R:sbom-scorecard-website jabrahms$ " 130 | - delay: 378 131 | content: s 132 | - delay: 83 133 | content: b 134 | - delay: 11 135 | content: o 136 | - delay: 89 137 | content: m 138 | - delay: 29 139 | content: '-' 140 | - delay: 13 141 | content: s 142 | - delay: 14 143 | content: c 144 | - delay: 15 145 | content: o 146 | - delay: 11 147 | content: r 148 | - delay: 37 149 | content: 'ecard ' 150 | - delay: 153 151 | content: s 152 | - delay: 87 153 | content: c 154 | - delay: 98 155 | content: o 156 | - delay: 03 157 | content: r 158 | - delay: 47 159 | content: e 160 | - delay: 71 161 | content: ' ' 162 | - delay: 49 163 | content: '~' 164 | - delay: 81 165 | content: / 166 | - delay: 67 167 | content: D 168 | - delay: 09 169 | content: o 170 | - delay: 31 171 | content: w 172 | - delay: 89 173 | content: nloads/ 174 | - delay: 43 175 | content: p 176 | - delay: 20 177 | content: h 178 | - delay: 89 179 | content: o 180 | - delay: 28 181 | content: "\aton." 182 | - delay: 264 183 | content: j 184 | - delay: 96 185 | content: 'son.txt ' 186 | - delay: 184 187 | content: "\r\n" 188 | - delay: 54 189 | content: "Guessed: spdx\r\n38 total packages\r\n0 total files\r\n94% have licenses.\r\n2% have package digest.\r\n97% have package versions.\r\n0% have purls.\r\n0% have CPEs.\r\n0% have file digest.\r\nSpec valid? true\r\nHas creation info? true\r\n==\r\nSpec Compliance: 25/25\r\nPackage ID: 0/20 (0% have purls and 0% have CPEs)\r\nPackage Versions: 0/20\r\nPackage Licenses: 0/20\r\nCreation Info: 15/15\r\nTotal points: 40/100 or 40%\r\n\e]7;file://C02C780ZMD6R/Users/jabrahms/src/github.com/ericaabrahms/sbom-scorecard-website\aC02C780ZMD6R:sbom-scorecard-website jabrahms$ " 190 | - delay: 18139 191 | content: "logout\r\n\r\nSaving session..." 192 | - delay: 12 193 | content: "completed.\r\n" 194 | -------------------------------------------------------------------------------- /slsa/goreleaser-darwin-amd64.yml: -------------------------------------------------------------------------------- 1 | # Version for this file. 2 | version: 1 3 | 4 | # (Optional) List of env variables used during compilation. 5 | env: 6 | - GO111MODULE=on 7 | - CGO_ENABLED=0 8 | 9 | # (Optional) Flags for the compiler. 10 | flags: 11 | - -trimpath 12 | - -tags=netgo 13 | 14 | # The OS to compile for. `GOOS` env variable will be set to this value. 15 | goos: darwin 16 | 17 | # The architecture to compile for. `GOARCH` env variable will be set to this value. 18 | goarch: amd64 19 | 20 | # (Optional) Entrypoint to compile. 21 | main: ./cmd/sbom-scorecard/main.go 22 | 23 | # (Optional) Working directory. (default: root of the project) 24 | # dir: ./relative/path/to/dir 25 | 26 | # Binary output name. 27 | # {{ .Os }} will be replaced by goos field in the config file. 28 | # {{ .Arch }} will be replaced by goarch field in the config file. 29 | binary: sbom-scorecard-{{ .Os }}-{{ .Arch }} 30 | 31 | # (Optional) ldflags generated dynamically in the workflow, and set as the `evaluated-envs` input variables in the workflow. 32 | ldflags: 33 | - "-X main.Version={{ .Env.VERSION }}" 34 | - "-X main.Commit={{ .Env.COMMIT }}" 35 | - "-X main.CommitDate={{ .Env.COMMIT_DATE }}" 36 | - "-X main.TreeState={{ .Env.TREE_STATE }}" 37 | -------------------------------------------------------------------------------- /slsa/goreleaser-darwin-arm64.yml: -------------------------------------------------------------------------------- 1 | # Version for this file. 2 | version: 1 3 | 4 | # (Optional) List of env variables used during compilation. 5 | env: 6 | - GO111MODULE=on 7 | - CGO_ENABLED=0 8 | 9 | # (Optional) Flags for the compiler. 10 | flags: 11 | - -trimpath 12 | - -tags=netgo 13 | 14 | # The OS to compile for. `GOOS` env variable will be set to this value. 15 | goos: darwin 16 | 17 | # The architecture to compile for. `GOARCH` env variable will be set to this value. 18 | goarch: arm64 19 | 20 | # (Optional) Entrypoint to compile. 21 | main: ./cmd/sbom-scorecard/main.go 22 | 23 | # (Optional) Working directory. (default: root of the project) 24 | # dir: ./relative/path/to/dir 25 | 26 | # Binary output name. 27 | # {{ .Os }} will be replaced by goos field in the config file. 28 | # {{ .Arch }} will be replaced by goarch field in the config file. 29 | binary: sbom-scorecard-{{ .Os }}-{{ .Arch }} 30 | 31 | # (Optional) ldflags generated dynamically in the workflow, and set as the `evaluated-envs` input variables in the workflow. 32 | ldflags: 33 | - "-X main.Version={{ .Env.VERSION }}" 34 | - "-X main.Commit={{ .Env.COMMIT }}" 35 | - "-X main.CommitDate={{ .Env.COMMIT_DATE }}" 36 | - "-X main.TreeState={{ .Env.TREE_STATE }}" 37 | -------------------------------------------------------------------------------- /slsa/goreleaser-linux-amd64.yml: -------------------------------------------------------------------------------- 1 | # Version for this file. 2 | version: 1 3 | 4 | # (Optional) List of env variables used during compilation. 5 | env: 6 | - GO111MODULE=on 7 | - CGO_ENABLED=0 8 | 9 | # (Optional) Flags for the compiler. 10 | flags: 11 | - -trimpath 12 | - -tags=netgo 13 | 14 | # The OS to compile for. `GOOS` env variable will be set to this value. 15 | goos: linux 16 | 17 | # The architecture to compile for. `GOARCH` env variable will be set to this value. 18 | goarch: amd64 19 | 20 | # (Optional) Entrypoint to compile. 21 | main: ./cmd/sbom-scorecard/main.go 22 | 23 | # (Optional) Working directory. (default: root of the project) 24 | # dir: ./relative/path/to/dir 25 | 26 | # Binary output name. 27 | # {{ .Os }} will be replaced by goos field in the config file. 28 | # {{ .Arch }} will be replaced by goarch field in the config file. 29 | binary: sbom-scorecard-{{ .Os }}-{{ .Arch }} 30 | 31 | # (Optional) ldflags generated dynamically in the workflow, and set as the `evaluated-envs` input variables in the workflow. 32 | ldflags: 33 | - "-X main.Version={{ .Env.VERSION }}" 34 | - "-X main.Commit={{ .Env.COMMIT }}" 35 | - "-X main.CommitDate={{ .Env.COMMIT_DATE }}" 36 | - "-X main.TreeState={{ .Env.TREE_STATE }}" 37 | -------------------------------------------------------------------------------- /slsa/goreleaser-linux-arm64.yml: -------------------------------------------------------------------------------- 1 | # Version for this file. 2 | version: 1 3 | 4 | # (Optional) List of env variables used during compilation. 5 | env: 6 | - GO111MODULE=on 7 | - CGO_ENABLED=0 8 | 9 | # (Optional) Flags for the compiler. 10 | flags: 11 | - -trimpath 12 | - -tags=netgo 13 | 14 | # The OS to compile for. `GOOS` env variable will be set to this value. 15 | goos: linux 16 | 17 | # The architecture to compile for. `GOARCH` env variable will be set to this value. 18 | goarch: arm64 19 | 20 | # (Optional) Entrypoint to compile. 21 | main: ./cmd/sbom-scorecard/main.go 22 | 23 | # (Optional) Working directory. (default: root of the project) 24 | # dir: ./relative/path/to/dir 25 | 26 | # Binary output name. 27 | # {{ .Os }} will be replaced by goos field in the config file. 28 | # {{ .Arch }} will be replaced by goarch field in the config file. 29 | binary: sbom-scorecard-{{ .Os }}-{{ .Arch }} 30 | 31 | # (Optional) ldflags generated dynamically in the workflow, and set as the `evaluated-envs` input variables in the workflow. 32 | ldflags: 33 | - "-X main.Version={{ .Env.VERSION }}" 34 | - "-X main.Commit={{ .Env.COMMIT }}" 35 | - "-X main.CommitDate={{ .Env.COMMIT_DATE }}" 36 | - "-X main.TreeState={{ .Env.TREE_STATE }}" 37 | -------------------------------------------------------------------------------- /slsa/goreleaser-windows-amd64.yml: -------------------------------------------------------------------------------- 1 | # Version for this file. 2 | version: 1 3 | 4 | # (Optional) List of env variables used during compilation. 5 | env: 6 | - GO111MODULE=on 7 | - CGO_ENABLED=0 8 | 9 | # (Optional) Flags for the compiler. 10 | flags: 11 | - -trimpath 12 | - -tags=netgo 13 | 14 | # The OS to compile for. `GOOS` env variable will be set to this value. 15 | goos: windows 16 | 17 | # The architecture to compile for. `GOARCH` env variable will be set to this value. 18 | goarch: amd64 19 | 20 | # (Optional) Entrypoint to compile. 21 | main: ./cmd/sbom-scorecard/main.go 22 | 23 | # (Optional) Working directory. (default: root of the project) 24 | # dir: ./relative/path/to/dir 25 | 26 | # Binary output name. 27 | # {{ .Os }} will be replaced by goos field in the config file. 28 | # {{ .Arch }} will be replaced by goarch field in the config file. 29 | binary: sbom-scorecard-{{ .Os }}-{{ .Arch }} 30 | 31 | # (Optional) ldflags generated dynamically in the workflow, and set as the `evaluated-envs` input variables in the workflow. 32 | ldflags: 33 | - "-X main.Version={{ .Env.VERSION }}" 34 | - "-X main.Commit={{ .Env.COMMIT }}" 35 | - "-X main.CommitDate={{ .Env.COMMIT_DATE }}" 36 | - "-X main.TreeState={{ .Env.TREE_STATE }}" 37 | -------------------------------------------------------------------------------- /slsa/goreleaser-windows-arm64.yml: -------------------------------------------------------------------------------- 1 | # Version for this file. 2 | version: 1 3 | 4 | # (Optional) List of env variables used during compilation. 5 | env: 6 | - GO111MODULE=on 7 | - CGO_ENABLED=0 8 | 9 | # (Optional) Flags for the compiler. 10 | flags: 11 | - -trimpath 12 | - -tags=netgo 13 | 14 | # The OS to compile for. `GOOS` env variable will be set to this value. 15 | goos: windows 16 | 17 | # The architecture to compile for. `GOARCH` env variable will be set to this value. 18 | goarch: arm64 19 | 20 | # (Optional) Entrypoint to compile. 21 | main: ./cmd/sbom-scorecard/main.go 22 | 23 | # (Optional) Working directory. (default: root of the project) 24 | # dir: ./relative/path/to/dir 25 | 26 | # Binary output name. 27 | # {{ .Os }} will be replaced by goos field in the config file. 28 | # {{ .Arch }} will be replaced by goarch field in the config file. 29 | binary: sbom-scorecard-{{ .Os }}-{{ .Arch }} 30 | 31 | # (Optional) ldflags generated dynamically in the workflow, and set as the `evaluated-envs` input variables in the workflow. 32 | ldflags: 33 | - "-X main.Version={{ .Env.VERSION }}" 34 | - "-X main.Commit={{ .Env.COMMIT }}" 35 | - "-X main.CommitDate={{ .Env.COMMIT_DATE }}" 36 | - "-X main.TreeState={{ .Env.TREE_STATE }}" 37 | -------------------------------------------------------------------------------- /slsa/template.yml: -------------------------------------------------------------------------------- 1 | # Version for this file. 2 | version: 1 3 | 4 | # (Optional) List of env variables used during compilation. 5 | env: 6 | - GO111MODULE=on 7 | - CGO_ENABLED=0 8 | 9 | # (Optional) Flags for the compiler. 10 | flags: 11 | - -trimpath 12 | - -tags=netgo 13 | 14 | # The OS to compile for. `GOOS` env variable will be set to this value. 15 | goos: OS_HERE 16 | 17 | # The architecture to compile for. `GOARCH` env variable will be set to this value. 18 | goarch: ARCH_HERE 19 | 20 | # (Optional) Entrypoint to compile. 21 | main: ./cmd/sbom-scorecard/main.go 22 | 23 | # (Optional) Working directory. (default: root of the project) 24 | # dir: ./relative/path/to/dir 25 | 26 | # Binary output name. 27 | # {{ .Os }} will be replaced by goos field in the config file. 28 | # {{ .Arch }} will be replaced by goarch field in the config file. 29 | binary: sbom-scorecard-{{ .Os }}-{{ .Arch }} 30 | 31 | # (Optional) ldflags generated dynamically in the workflow, and set as the `evaluated-envs` input variables in the workflow. 32 | ldflags: 33 | - "-X main.Version={{ .Env.VERSION }}" 34 | - "-X main.Commit={{ .Env.COMMIT }}" 35 | - "-X main.CommitDate={{ .Env.COMMIT_DATE }}" 36 | - "-X main.TreeState={{ .Env.TREE_STATE }}" 37 | -------------------------------------------------------------------------------- /usage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eBay/sbom-scorecard/dc7a7080db71fba617f6287615feeee175626435/usage.gif --------------------------------------------------------------------------------