├── CODEOWNERS
├── .golangci.yml
├── .gitpod.yml
├── NOTICE
├── testdata
├── valid-empty-components.json
├── valid-empty-components.xml
├── snapshots
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-empty-components.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-empty-components.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-metadata-timestamp.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-timestamp.json
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-minimal-viable.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-minimal-viable.xml
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-metadata-license.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-license.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-service-empty-objects.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-author.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-metadata-author.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-component-swhid.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-metadata-supplier.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-component-omniborId.json
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-component-ref.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-metadata-manufacturer.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-service-empty-objects.json
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-supplier.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-component-swid.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-license-id.json
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-lifecycle.json
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-license-expression.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-metadata-manufacture.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-component-swid.json
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-manufacturer.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-component-swhid.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-license-name.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-lifecycle.xml
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-component-omniborId.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-manufacture.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-metadata-tool-deprecated.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-component-authors.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-component-manufacturer.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-component-manufacturer.json
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-assembly.json
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-definitions.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-component-ref.xml
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-component-authors.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-tool-deprecated.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-definitions.xml
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-assembly.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-dependency.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-dependency.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-component-types.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-license-id.xml
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-license-expression.xml
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-component-types.xml
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-license-name.xml
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-external-reference.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-external-reference.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-metadata-tool.xml
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-component-swid-full.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-tool.json
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-component-swid-full.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-properties.xml
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-component-hashes.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-properties.json
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-license-licensing.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-license-licensing.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-compositions.json
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-component-hashes.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-compositions.xml
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-service.xml
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-patch.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-patch.json
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-service.json
│ ├── cyclonedx-go-TestXmlBOMEncoder_EncodeVersion-func1-1.0.bom.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-annotation.json
│ ├── cyclonedx-go-TestRoundTripXML-func1-valid-annotation.xml
│ ├── cyclonedx-go-TestRoundTripJSON-func1-valid-evidence.json
│ └── cyclonedx-go-TestRoundTripXML-func1-valid-evidence.xml
├── valid-metadata-timestamp.json
├── valid-metadata-timestamp.xml
├── valid-minimal-viable.json
├── valid-minimal-viable.xml
├── valid-metadata-license.json
├── valid-metadata-license.xml
├── valid-component-swhid.json
├── valid-metadata-author.json
├── valid-component-omniborId.json
├── valid-component-ref.json
├── valid-metadata-author.xml
├── valid-metadata-supplier.json
├── valid-lifecycle.json
├── valid-license-id.json
├── valid-service-empty-objects.json
├── valid-license-expression.json
├── valid-metadata-supplier.xml
├── valid-component-swid.xml
├── valid-component-swid.json
├── valid-metadata-manufacturer.json
├── valid-metadata-manufacturer.xml
├── valid-service-empty-objects.xml
├── valid-component-swhid.xml
├── valid-license-name.json
├── valid-metadata-manufacture.xml
├── valid-metadata-manufacture.json
├── valid-component-manufacturer.xml
├── valid-component-omniborId.xml
├── valid-component-authors.json
├── valid-component-manufacturer.json
├── valid-assembly.json
├── valid-lifecycle.xml
├── valid-definitions.json
├── valid-metadata-tool-deprecated.json
├── valid-metadata-tool-deprecated.xml
├── valid-component-ref.xml
├── valid-component-authors.xml
├── valid-definitions.xml
├── valid-dependency.json
├── valid-assembly.xml
├── valid-dependency.xml
├── valid-component-types.json
├── valid-external-reference.json
├── valid-license-expression.xml
├── valid-license-id.xml
├── valid-license-name.xml
├── valid-metadata-tool.json
├── valid-component-types.xml
├── valid-component-swid-full.xml
├── valid-external-reference.xml
├── valid-component-swid-full.json
├── valid-metadata-tool.xml
├── valid-license-licensing.json
├── valid-properties.xml
├── valid-properties.json
├── valid-component-hashes.xml
├── valid-compositions.json
├── valid-license-licensing.xml
├── valid-component-hashes.json
├── valid-compositions.xml
├── valid-patch.json
├── valid-service.json
├── valid-service.xml
├── valid-annotation.json
├── valid-patch.xml
├── valid-evidence.json
└── valid-annotation.xml
├── Makefile
├── .gitignore
├── go.mod
├── .github
├── dependabot.yml
└── workflows
│ ├── goreleaser.yml
│ └── ci.yml
├── Dockerfile.gitpod
├── validate_test.go
├── .goreleaser.yml
├── .licenserc.yml
├── copy.go
├── cyclonedx_string.go
├── link_example_test.go
├── decode.go
├── .idea
└── icon.svg
├── validate_json_test.go
├── cyclonedx_test.go
├── validate_xml_test.go
├── go.sum
├── roundtrip_test.go
├── decode_test.go
├── README.md
└── encode.go
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @CycloneDX/go-maintainers
2 |
--------------------------------------------------------------------------------
/.golangci.yml:
--------------------------------------------------------------------------------
1 | linters:
2 | enable:
3 | - asciicheck
4 | - errorlint
5 | - gofmt
6 | - gosec
7 | - wastedassign
8 |
--------------------------------------------------------------------------------
/.gitpod.yml:
--------------------------------------------------------------------------------
1 | image:
2 | file: Dockerfile.gitpod
3 |
4 | tasks:
5 | - init: make build
6 |
7 | vscode:
8 | extensions:
9 | - golang.Go
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | CycloneDX Go
2 | Copyright (c) OWASP Foundation
3 |
4 | This product includes software developed by the
5 | CycloneDX community (https://cyclonedx.org/).
--------------------------------------------------------------------------------
/testdata/valid-empty-components.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/testdata/valid-empty-components.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-empty-components.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-empty-components.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": []
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-timestamp.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "timestamp": "2020-04-13T20:20:39+00:00"
8 | },
9 | "components": []
10 | }
11 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-timestamp.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2020-04-07T07:01:00Z
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/testdata/valid-minimal-viable.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "name": "acme-library"
10 | }
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | build:
2 | go build -v
3 | .PHONY: build
4 |
5 | test:
6 | go test -v -cover
7 | .PHONY: test
8 |
9 | clean:
10 | go clean
11 | .PHONY: clean
12 |
13 | generate:
14 | go generate
15 | .PHONY: generate
16 |
17 | lint:
18 | golangci-lint run
19 | .PHONY: lint
20 |
21 | all: clean build test
22 | .PHONY: all
23 |
--------------------------------------------------------------------------------
/testdata/valid-minimal-viable.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | acme-library
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-metadata-timestamp.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2020-04-07T07:01:00Z
5 |
6 |
7 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-timestamp.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "timestamp": "2020-04-13T20:20:39+00:00"
8 | },
9 | "components": []
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-minimal-viable.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "name": "acme-library"
10 | }
11 | ]
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-minimal-viable.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | acme-library
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-license.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "licenses": [
8 | {
9 | "license": {
10 | "id": "Apache-2.0"
11 | }
12 | }
13 | ]
14 | },
15 | "components": []
16 | }
17 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-license.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Apache-2.0
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-metadata-license.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Apache-2.0
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-license.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "licenses": [
8 | {
9 | "license": {
10 | "id": "Apache-2.0"
11 | }
12 | }
13 | ]
14 | },
15 | "components": []
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/testdata/valid-component-swhid.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "author": "Acme Super Heros",
10 | "name": "Acme Application",
11 | "version": "9.1.1",
12 | "swhid": ["swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2"]
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-author.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "authors": [
8 | {
9 | "bom-ref": "author-1",
10 | "name": "Samantha Wright",
11 | "email": "samantha.wright@example.com",
12 | "phone": "800-555-1212"
13 | }
14 | ]
15 | },
16 | "components": []
17 | }
18 |
--------------------------------------------------------------------------------
/testdata/valid-component-omniborId.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "author": "Acme Super Heros",
10 | "name": "Acme Application",
11 | "version": "9.1.1",
12 | "omniborId": ["gitoid:blob:sha1:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"]
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 |
8 | # Test binary, built with `go test -c`
9 | *.test
10 |
11 | # Output of the go coverage tool, specifically when used with LiteIDE
12 | *.out
13 |
14 | # Dependency directories (remove the comment below to include it)
15 | # vendor/
16 |
17 | # IntelliJ / GoLand
18 | .idea/*
19 | !.idea/icon.svg
20 | *.iml
21 |
22 | # SBOMs generated during CI
23 | /bom.json
24 | /bom.xml
25 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-service-empty-objects.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Stock ticker service
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/testdata/valid-component-ref.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "bom-ref": "123",
10 | "name": "acme-library",
11 | "version": "1.0.0"
12 | },
13 | {
14 | "type": "library",
15 | "bom-ref": "456",
16 | "name": "acme-library",
17 | "version": "1.0.0"
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-author.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "authors": [
8 | {
9 | "bom-ref": "author-1",
10 | "name": "Samantha Wright",
11 | "email": "samantha.wright@example.com",
12 | "phone": "800-555-1212"
13 | }
14 | ]
15 | },
16 | "components": []
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-metadata-author.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Samantha Wright
7 | samantha.wright@example.com
8 | 800-555-1212
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-author.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Samantha Wright
7 | samantha.wright@example.com
8 | 800-555-1212
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-component-swhid.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "author": "Acme Super Heros",
10 | "name": "Acme Application",
11 | "version": "9.1.1",
12 | "swhid": [
13 | "swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2"
14 | ]
15 | }
16 | ]
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-metadata-supplier.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme, Inc.
6 | https://example.com
7 |
8 | Acme Distribution
9 | distribution@example.com
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-supplier.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "supplier": {
8 | "name": "Acme, Inc.",
9 | "url": [
10 | "https://example.com"
11 | ],
12 | "contact": [
13 | {
14 | "name": "Acme Distribution",
15 | "email": "distribution@example.com"
16 | }
17 | ]
18 | }
19 | },
20 | "components": []
21 | }
22 |
--------------------------------------------------------------------------------
/testdata/valid-lifecycle.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "lifecycles": [
8 | {
9 | "phase": "build"
10 | },
11 | {
12 | "phase": "post-build"
13 | },
14 | {
15 | "name": "platform-integration-testing",
16 | "description": "Integration testing specific to the runtime platform"
17 | }
18 | ]
19 | },
20 | "components": []
21 | }
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-component-omniborId.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "author": "Acme Super Heros",
10 | "name": "Acme Application",
11 | "version": "9.1.1",
12 | "omniborId": [
13 | "gitoid:blob:sha1:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
14 | ]
15 | }
16 | ]
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/testdata/valid-license-id.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "publisher": "Acme Inc",
10 | "group": "com.acme",
11 | "name": "tomcat-catalina",
12 | "version": "9.0.14",
13 | "licenses": [
14 | {
15 | "license": {
16 | "id": "Apache-2.0"
17 | }
18 | }
19 | ]
20 | }
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/testdata/valid-service-empty-objects.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "services": [
7 | {
8 | "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8",
9 | "provider": {
10 | "contact": [
11 | ]
12 | },
13 | "name": "Stock ticker service",
14 | "endpoints": [
15 | ],
16 | "data": [
17 | ],
18 | "externalReferences": [
19 | ]
20 | }
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/testdata/valid-license-expression.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "publisher": "Acme Inc",
10 | "group": "com.acme",
11 | "name": "tomcat-catalina",
12 | "version": "9.0.14",
13 | "licenses": [
14 | {
15 | "expression": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0"
16 | }
17 | ]
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-supplier.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme, Inc.
6 | https://example.com
7 |
8 | Acme Distribution
9 | distribution@example.com
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-component-ref.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "bom-ref": "123",
9 | "type": "library",
10 | "name": "acme-library",
11 | "version": "1.0.0"
12 | },
13 | {
14 | "bom-ref": "456",
15 | "type": "library",
16 | "name": "acme-library",
17 | "version": "1.0.0"
18 | }
19 | ]
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/testdata/valid-component-swid.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Super Heros
6 | Acme Application
7 | 9.1.1
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/testdata/valid-component-swid.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "author": "Acme Super Heros",
10 | "name": "Acme Application",
11 | "version": "9.1.1",
12 | "swid": {
13 | "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1",
14 | "name": "Acme Application",
15 | "version": "9.1.1"
16 | }
17 | }
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-manufacturer.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "manufacturer": {
8 | "name": "Acme, Inc.",
9 | "url": [
10 | "https://example.com"
11 | ],
12 | "contact": [
13 | {
14 | "name": "Acme Professional Services",
15 | "email": "professional.services@example.com"
16 | }
17 | ]
18 | }
19 | },
20 | "components": []
21 | }
22 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-metadata-manufacturer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme, Inc.
6 | https://example.com
7 |
8 | Acme Professional Services
9 | professional.services@example.com
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-service-empty-objects.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "services": [
7 | {
8 | "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8",
9 | "provider": {
10 | "name": "",
11 | "contact": []
12 | },
13 | "name": "Stock ticker service",
14 | "endpoints": [],
15 | "data": [],
16 | "externalReferences": []
17 | }
18 | ]
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-manufacturer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme, Inc.
6 | https://example.com
7 |
8 | Acme Professional Services
9 | professional.services@example.com
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-supplier.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "supplier": {
8 | "name": "Acme, Inc.",
9 | "url": [
10 | "https://example.com"
11 | ],
12 | "contact": [
13 | {
14 | "name": "Acme Distribution",
15 | "email": "distribution@example.com"
16 | }
17 | ]
18 | }
19 | },
20 | "components": []
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-component-swid.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Super Heros
6 | Acme Application
7 | 9.1.1
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/testdata/valid-service-empty-objects.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Stock ticker service
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/testdata/valid-component-swhid.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Super Heros
6 | Acme Application
7 | 9.1.1
8 | swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2
9 | swh:1:cnt:618152ea559a168bbcbb5e294a9ed024d3859793
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-license-id.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "publisher": "Acme Inc",
10 | "group": "com.acme",
11 | "name": "tomcat-catalina",
12 | "version": "9.0.14",
13 | "licenses": [
14 | {
15 | "license": {
16 | "id": "Apache-2.0"
17 | }
18 | }
19 | ]
20 | }
21 | ]
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-lifecycle.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "lifecycles": [
8 | {
9 | "phase": "build"
10 | },
11 | {
12 | "phase": "post-build"
13 | },
14 | {
15 | "name": "platform-integration-testing",
16 | "description": "Integration testing specific to the runtime platform"
17 | }
18 | ]
19 | },
20 | "components": []
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-license-expression.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "publisher": "Acme Inc",
10 | "group": "com.acme",
11 | "name": "tomcat-catalina",
12 | "version": "9.0.14",
13 | "licenses": [
14 | {
15 | "expression": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0"
16 | }
17 | ]
18 | }
19 | ]
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-metadata-manufacture.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme, Inc.
6 | https://example.com
7 |
8 | Acme Professional Services
9 | professional.services@example.com
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/testdata/valid-license-name.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "publisher": "Acme Inc",
10 | "group": "com.acme",
11 | "name": "tomcat-catalina",
12 | "version": "9.0.14",
13 | "licenses": [
14 | {
15 | "license": {
16 | "name": "Apache License 2.0",
17 | "acknowledgement": "concluded"
18 | }
19 | }
20 | ]
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/CycloneDX/cyclonedx-go
2 |
3 | go 1.20
4 |
5 | require (
6 | github.com/bradleyjkemp/cupaloy/v2 v2.8.0
7 | github.com/stretchr/testify v1.10.0
8 | github.com/terminalstatic/go-xsd-validate v0.1.6
9 | github.com/xeipuuv/gojsonschema v1.2.0
10 | )
11 |
12 | require (
13 | github.com/davecgh/go-spew v1.1.1 // indirect
14 | github.com/pmezard/go-difflib v1.0.0 // indirect
15 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
16 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
17 | gopkg.in/yaml.v3 v3.0.1 // indirect
18 | )
19 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-component-swid.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "author": "Acme Super Heros",
10 | "name": "Acme Application",
11 | "version": "9.1.1",
12 | "swid": {
13 | "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1",
14 | "name": "Acme Application",
15 | "version": "9.1.1"
16 | }
17 | }
18 | ]
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-manufacturer.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "manufacturer": {
8 | "name": "Acme, Inc.",
9 | "url": [
10 | "https://example.com"
11 | ],
12 | "contact": [
13 | {
14 | "name": "Acme Professional Services",
15 | "email": "professional.services@example.com"
16 | }
17 | ]
18 | }
19 | },
20 | "components": []
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-component-swhid.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Super Heros
6 | Acme Application
7 | 9.1.1
8 | swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2
9 | swh:1:cnt:618152ea559a168bbcbb5e294a9ed024d3859793
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-manufacture.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme, Inc.
6 | https://example.com
7 |
8 | Acme Professional Services
9 | professional.services@example.com
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-manufacture.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "manufacture": {
8 | "bom-ref": "manufacture-1",
9 | "name": "Acme, Inc.",
10 | "url": [
11 | "https://example.com"
12 | ],
13 | "contact": [
14 | {
15 | "bom-ref": "contact-1",
16 | "name": "Acme Professional Services",
17 | "email": "professional.services@example.com"
18 | }
19 | ]
20 | }
21 | },
22 | "components": []
23 | }
24 |
--------------------------------------------------------------------------------
/testdata/valid-component-manufacturer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Acme, Inc.
7 | https://example.com
8 |
9 | Acme Professional Services
10 | professional.services@example.com
11 |
12 |
13 | Acme Application
14 | 9.1.1
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/testdata/valid-component-omniborId.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Super Heros
6 | Acme Application
7 | 9.1.1
8 | gitoid:blob:sha1:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
9 | gitoid:blob:sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-license-name.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "publisher": "Acme Inc",
10 | "group": "com.acme",
11 | "name": "tomcat-catalina",
12 | "version": "9.0.14",
13 | "licenses": [
14 | {
15 | "license": {
16 | "name": "Apache License 2.0",
17 | "acknowledgement": "concluded"
18 | }
19 | }
20 | ]
21 | }
22 | ]
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/testdata/valid-component-authors.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "name": "Acme Application",
10 | "version": "9.1.1",
11 | "authors": [
12 | {
13 | "name": "Anthony Edward Stark",
14 | "phone": "555-212-970-4133",
15 | "email": "ironman@example.org"
16 | },
17 | {
18 | "name": "Peter Benjamin Parker",
19 | "email": "spiderman@example.org"
20 | }
21 | ]
22 | }
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "docker"
4 | directory: "/"
5 | reviewers:
6 | - "CycloneDX/go-maintainers"
7 | schedule:
8 | # We only have one Dockerfile for the Gitpod workspace
9 | # right now, and it's not critical to be super up-to-date.
10 | interval: "monthly"
11 | - package-ecosystem: "gomod"
12 | directory: "/"
13 | reviewers:
14 | - "CycloneDX/go-maintainers"
15 | schedule:
16 | interval: "daily"
17 | - package-ecosystem: "github-actions"
18 | directory: "/"
19 | reviewers:
20 | - "CycloneDX/go-maintainers"
21 | schedule:
22 | interval: "daily"
23 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-lifecycle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | build
7 |
8 |
9 | post-build
10 |
11 |
12 | platform-integration-testing
13 | Integration testing specific to the runtime platform
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-component-omniborId.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Super Heros
6 | Acme Application
7 | 9.1.1
8 | gitoid:blob:sha1:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
9 | gitoid:blob:sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-manufacture.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "manufacture": {
8 | "bom-ref": "manufacture-1",
9 | "name": "Acme, Inc.",
10 | "url": [
11 | "https://example.com"
12 | ],
13 | "contact": [
14 | {
15 | "bom-ref": "contact-1",
16 | "name": "Acme Professional Services",
17 | "email": "professional.services@example.com"
18 | }
19 | ]
20 | }
21 | },
22 | "components": []
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/testdata/valid-component-manufacturer.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "name": "Acme Application",
10 | "version": "9.1.1",
11 | "manufacturer": {
12 | "name": "Acme, Inc.",
13 | "url": [
14 | "https://example.com"
15 | ],
16 | "contact": [
17 | {
18 | "name": "Acme Professional Services",
19 | "email": "professional.services@example.com"
20 | }
21 | ]
22 | }
23 | }
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/testdata/valid-assembly.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "name": "acme-library-a",
10 | "version": "1.0.0",
11 | "components": [
12 | {
13 | "type": "library",
14 | "name": "acme-library-b",
15 | "version": "2.0.0"
16 | }
17 | ]
18 | }
19 | ],
20 | "services": [
21 | {
22 | "name": "acme-service-a",
23 | "services": [
24 | {
25 | "name": "acme-service-b"
26 | }
27 | ]
28 | }
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-metadata-tool-deprecated.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Awesome Vendor
7 | Awesome Tool
8 | 9.1.2
9 |
10 | 25ed8e31b995bb927966616df2a42b979a2717f0
11 | a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/testdata/valid-lifecycle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | build
7 |
8 |
9 | post-build
10 |
11 |
12 | platform-integration-testing
13 | Integration testing specific to the runtime platform
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/testdata/valid-definitions.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "definitions": {
7 | "standards": [
8 | {
9 | "bom-ref": "std-ref-1",
10 | "name": "CycloneDX",
11 | "version": "1.6",
12 | "description": "A full-stack Bill of Materials standard that provides advanced supply chain capabilities for cyber risk reduction.",
13 | "owner": "OWASP",
14 | "externalReferences": [
15 | {
16 | "type": "website",
17 | "url": "https://cyclonedx.org"
18 | }
19 | ]
20 | }
21 | ]
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-component-authors.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "authors": [
10 | {
11 | "name": "Anthony Edward Stark",
12 | "email": "ironman@example.org",
13 | "phone": "555-212-970-4133"
14 | },
15 | {
16 | "name": "Peter Benjamin Parker",
17 | "email": "spiderman@example.org"
18 | }
19 | ],
20 | "name": "Acme Application",
21 | "version": "9.1.1"
22 | }
23 | ]
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-component-manufacturer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Acme, Inc.
7 | https://example.com
8 |
9 | Acme Professional Services
10 | professional.services@example.com
11 |
12 |
13 | Acme Application
14 | 9.1.1
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-component-manufacturer.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "manufacturer": {
10 | "name": "Acme, Inc.",
11 | "url": [
12 | "https://example.com"
13 | ],
14 | "contact": [
15 | {
16 | "name": "Acme Professional Services",
17 | "email": "professional.services@example.com"
18 | }
19 | ]
20 | },
21 | "name": "Acme Application",
22 | "version": "9.1.1"
23 | }
24 | ]
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-tool-deprecated.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "tools": [
8 | {
9 | "vendor": "Awesome Vendor",
10 | "name": "Awesome Tool",
11 | "version": "9.1.2",
12 | "hashes": [
13 | {
14 | "alg": "SHA-1",
15 | "content": "25ed8e31b995bb927966616df2a42b979a2717f0"
16 | },
17 | {
18 | "alg": "SHA-256",
19 | "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df"
20 | }
21 | ]
22 | }
23 | ]
24 | },
25 | "components": []
26 | }
--------------------------------------------------------------------------------
/testdata/valid-metadata-tool-deprecated.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Awesome Vendor
7 | Awesome Tool
8 | 9.1.2
9 |
10 | 25ed8e31b995bb927966616df2a42b979a2717f0
11 | a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-assembly.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "name": "acme-library-a",
10 | "version": "1.0.0",
11 | "components": [
12 | {
13 | "type": "library",
14 | "name": "acme-library-b",
15 | "version": "2.0.0"
16 | }
17 | ]
18 | }
19 | ],
20 | "services": [
21 | {
22 | "name": "acme-service-a",
23 | "services": [
24 | {
25 | "name": "acme-service-b"
26 | }
27 | ]
28 | }
29 | ]
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-definitions.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "definitions": {
7 | "standards": [
8 | {
9 | "bom-ref": "std-ref-1",
10 | "name": "CycloneDX",
11 | "version": "1.6",
12 | "description": "A full-stack Bill of Materials standard that provides advanced supply chain capabilities for cyber risk reduction.",
13 | "owner": "OWASP",
14 | "externalReferences": [
15 | {
16 | "url": "https://cyclonedx.org",
17 | "type": "website"
18 | }
19 | ]
20 | }
21 | ]
22 | }
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-component-ref.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | acme-library
6 | 1.0.0
7 |
8 |
9 | acme-library
10 | 1.0.0
11 |
12 |
13 |
14 |
15 | acme-library
16 | 1.0.0
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-component-authors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Anthony Edward Stark
8 | ironman@example.org
9 | 555-212-970-4133
10 |
11 |
12 | Peter Benjamin Parker
13 | spiderman@example.org
14 |
15 |
16 | Acme Application
17 | 9.1.1
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-tool-deprecated.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "tools": [
8 | {
9 | "vendor": "Awesome Vendor",
10 | "name": "Awesome Tool",
11 | "version": "9.1.2",
12 | "hashes": [
13 | {
14 | "alg": "SHA-1",
15 | "content": "25ed8e31b995bb927966616df2a42b979a2717f0"
16 | },
17 | {
18 | "alg": "SHA-256",
19 | "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df"
20 | }
21 | ]
22 | }
23 | ]
24 | },
25 | "components": []
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/testdata/valid-component-ref.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | acme-library
6 | 1.0.0
7 |
8 |
9 | acme-library
10 | 1.0.0
11 |
12 |
13 |
14 |
15 | acme-library
16 | 1.0.0
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-definitions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | CycloneDX
7 | 1.6
8 | A full-stack Bill of Materials standard that provides advanced supply chain capabilities for cyber risk reduction.
9 | OWASP
10 |
11 |
12 | https://cyclonedx.org
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/testdata/valid-component-authors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Anthony Edward Stark
8 | ironman@example.org
9 | 555-212-970-4133
10 |
11 |
12 | Peter Benjamin Parker
13 | spiderman@example.org
14 |
15 |
16 | Acme Application
17 | 9.1.1
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-assembly.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | acme-library-a
6 | 1.0.0
7 |
8 |
9 | acme-library-b
10 | 2.0.0
11 |
12 |
13 |
14 |
15 |
16 |
17 | acme-service-a
18 |
19 |
20 | acme-service-b
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Dockerfile.gitpod:
--------------------------------------------------------------------------------
1 | # This file is part of CycloneDX Go
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the “License”);
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an “AS IS” BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | #
15 | # SPDX-License-Identifier: Apache-2.0
16 | # Copyright (c) OWASP Foundation. All Rights Reserved.
17 |
18 | FROM gitpod/workspace-go:latest@sha256:8985eb7cf5f155eb83f07294e9bd1a7e8066f969711f51a166ef60d17d409eb0
19 |
--------------------------------------------------------------------------------
/testdata/valid-definitions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | CycloneDX
7 | 1.6
8 | A full-stack Bill of Materials standard that provides advanced supply chain capabilities for cyber risk reduction.
9 | OWASP
10 |
11 |
12 | https://cyclonedx.org
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/testdata/valid-dependency.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "bom-ref": "library-a",
9 | "type": "library",
10 | "name": "library-a",
11 | "version": "1.0.0"
12 | },
13 | {
14 | "bom-ref": "library-b",
15 | "type": "library",
16 | "name": "library-b",
17 | "version": "1.0.0"
18 | },
19 | {
20 | "bom-ref": "library-c",
21 | "type": "library",
22 | "name": "library-c",
23 | "version": "1.0.0"
24 | }
25 | ],
26 | "dependencies": [
27 | {
28 | "ref": "library-a",
29 | "dependsOn": []
30 | },
31 | {
32 | "ref": "library-b",
33 | "dependsOn": [
34 | "library-c"
35 | ]
36 | }
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/validate_test.go:
--------------------------------------------------------------------------------
1 | // This file is part of CycloneDX Go
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the “License”);
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an “AS IS” BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // SPDX-License-Identifier: Apache-2.0
16 | // Copyright (c) OWASP Foundation. All Rights Reserved.
17 |
18 | package cyclonedx
19 |
20 | type validator interface {
21 | Validate(bom []byte, specVersion SpecVersion) error
22 | }
23 |
--------------------------------------------------------------------------------
/testdata/valid-assembly.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | acme-library-a
6 | 1.0.0
7 |
8 |
9 | acme-library-b
10 | 2.0.0
11 |
12 |
13 |
14 |
15 |
16 |
17 | acme-service-a
18 |
19 |
20 | acme-service-b
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-dependency.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "bom-ref": "library-a",
9 | "type": "library",
10 | "name": "library-a",
11 | "version": "1.0.0"
12 | },
13 | {
14 | "bom-ref": "library-b",
15 | "type": "library",
16 | "name": "library-b",
17 | "version": "1.0.0"
18 | },
19 | {
20 | "bom-ref": "library-c",
21 | "type": "library",
22 | "name": "library-c",
23 | "version": "1.0.0"
24 | }
25 | ],
26 | "dependencies": [
27 | {
28 | "ref": "library-a",
29 | "dependsOn": []
30 | },
31 | {
32 | "ref": "library-b",
33 | "dependsOn": [
34 | "library-c"
35 | ]
36 | }
37 | ]
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-dependency.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | acme-library-a
6 | 1.0.0
7 |
8 |
9 | acme-library-b
10 | 1.0.0
11 |
12 |
13 | acme-library-b
14 | 1.0.0
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/testdata/valid-dependency.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | acme-library-a
6 | 1.0.0
7 |
8 |
9 | acme-library-b
10 | 1.0.0
11 |
12 |
13 | acme-library-b
14 | 1.0.0
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.goreleaser.yml:
--------------------------------------------------------------------------------
1 | builds:
2 | # This is a library project, we don't want to build any binaries.
3 | # Building and testing is performed in the CI workflow
4 | - skip: true
5 |
6 | release:
7 | prerelease: auto
8 |
9 | source:
10 | enabled: true
11 |
12 | sboms:
13 | - artifacts: source
14 | documents:
15 | - "${artifact}.cdx.sbom"
16 | cmd: cyclonedx-gomod
17 | args: [ "mod", "-licenses", "-json", "-output", "$document", "./.." ]
18 |
19 | milestones:
20 | - name_template: "{{ .Tag }}"
21 | close: true
22 |
23 | changelog:
24 | use: github
25 | sort: asc
26 | groups:
27 | - title: Features
28 | regexp: "^.*feat[(\\w)]*:+.*$"
29 | order: 0
30 | - title: Fixes
31 | regexp: "^.*fix[(\\w)]*:+.*$"
32 | order: 1
33 | - title: Building and Packaging
34 | regexp: "^.*build[(\\w)]*:+.*$"
35 | order: 2
36 | - title: Documentation
37 | regexp: "^.*docs[(\\w)]*:+.*$"
38 | order: 3
39 | - title: Others
40 | order: 999
41 | filters:
42 | exclude:
43 | - '^test:'
44 | - '^Merge '
--------------------------------------------------------------------------------
/.github/workflows/goreleaser.yml:
--------------------------------------------------------------------------------
1 | name: GoReleaser
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'v*'
7 |
8 | permissions: { }
9 |
10 | jobs:
11 | goreleaser:
12 | name: Release
13 | timeout-minutes: 5
14 | runs-on: ubuntu-latest
15 | permissions:
16 | contents: write
17 | steps:
18 | - name: Checkout Repository
19 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
20 | with:
21 | fetch-depth: 0
22 | - name: Setup Go
23 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # tag=v5.5.0
24 | with:
25 | go-version: "1.22"
26 | check-latest: true
27 | - name: Install cyclonedx-gomod
28 | uses: CycloneDX/gh-gomod-generate-sbom@efc74245d6802c8cefd925620515442756c70d8f # tag=v2.0.0
29 | with:
30 | version: v1
31 | - name: Run GoReleaser
32 | uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # tag=v6.3.0
33 | with:
34 | version: latest
35 | args: release --clean
36 | env:
37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38 |
--------------------------------------------------------------------------------
/testdata/valid-component-types.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "name": "application-a",
10 | "version": "1.0"
11 | },
12 | {
13 | "type": "library",
14 | "name": "library-a",
15 | "version": "1.0"
16 | },
17 | {
18 | "type": "framework",
19 | "name": "framework-a",
20 | "version": "1.0"
21 | },
22 | {
23 | "type": "container",
24 | "name": "container-a",
25 | "version": "1.0"
26 | },
27 | {
28 | "type": "operating-system",
29 | "name": "operating-system-a",
30 | "version": "1.0"
31 | },
32 | {
33 | "type": "firmware",
34 | "name": "firmware-a",
35 | "version": "1.0"
36 | },
37 | {
38 | "type": "device",
39 | "name": "device-a",
40 | "version": "1.0"
41 | },
42 | {
43 | "type": "file",
44 | "name": "file-a",
45 | "version": "1.0"
46 | }
47 | ]
48 | }
49 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-component-types.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "name": "application-a",
10 | "version": "1.0"
11 | },
12 | {
13 | "type": "library",
14 | "name": "library-a",
15 | "version": "1.0"
16 | },
17 | {
18 | "type": "framework",
19 | "name": "framework-a",
20 | "version": "1.0"
21 | },
22 | {
23 | "type": "container",
24 | "name": "container-a",
25 | "version": "1.0"
26 | },
27 | {
28 | "type": "operating-system",
29 | "name": "operating-system-a",
30 | "version": "1.0"
31 | },
32 | {
33 | "type": "firmware",
34 | "name": "firmware-a",
35 | "version": "1.0"
36 | },
37 | {
38 | "type": "device",
39 | "name": "device-a",
40 | "version": "1.0"
41 | },
42 | {
43 | "type": "file",
44 | "name": "file-a",
45 | "version": "1.0"
46 | }
47 | ]
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-license-id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Inc
6 | com.acme
7 | tomcat-catalina
8 | 9.0.14
9 | Modified version of Apache Catalina
10 | required
11 |
12 | 3942447fac867ae5cdb3229b658f4d48
13 | e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a
14 | f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b
15 | e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282
16 |
17 |
18 |
19 | Apache-2.0
20 |
21 |
22 | pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-license-expression.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Inc
6 | com.acme
7 | tomcat-catalina
8 | 9.0.14
9 | Modified version of Apache Catalina
10 | required
11 |
12 | 3942447fac867ae5cdb3229b658f4d48
13 | e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a
14 | f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b
15 | e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282
16 |
17 |
18 | EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
19 |
20 | pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-component-types.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | application-a
6 | 1.0
7 |
8 |
9 | library-a
10 | 1.0
11 |
12 |
13 | framework-a
14 | 1.0
15 |
16 |
17 | container-a
18 | 1.0
19 |
20 |
21 | operating-system-a
22 | 1.0
23 |
24 |
25 | firmware-a
26 | 1.0
27 |
28 |
29 | device-a
30 | 1.0
31 |
32 |
33 | file-a
34 | 1.0
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-license-name.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Inc
6 | com.acme
7 | tomcat-catalina
8 | 9.0.14
9 | Modified version of Apache Catalina
10 | required
11 |
12 | 3942447fac867ae5cdb3229b658f4d48
13 | e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a
14 | f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b
15 | e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282
16 |
17 |
18 |
19 | Apache License 2.0
20 |
21 |
22 | pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/testdata/valid-external-reference.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "publisher": "Acme Inc",
10 | "group": "org.example",
11 | "name": "mylibrary",
12 | "version": "1.0.0",
13 | "externalReferences": [
14 | {
15 | "type": "advisories",
16 | "url": "https://example.org/security/feed/csaf",
17 | "comment": "Security advisories from the vendor"
18 | },
19 | {
20 | "type": "bom",
21 | "url": "https://example.org/support/sbom/portal-server/1.0.0",
22 | "comment": "An external SBOM that describes what this component includes",
23 | "hashes": [
24 | {
25 | "alg": "SHA-256",
26 | "content": "708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313"
27 | }
28 | ]
29 | },
30 | {
31 | "type": "documentation",
32 | "url": "https://example.org/support/documentation/portal-server/1.0.0",
33 | "comment": "Vendor provided documentation for the product"
34 | }
35 | ]
36 | }
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/testdata/valid-license-expression.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Inc
6 | com.acme
7 | tomcat-catalina
8 | 9.0.14
9 | Modified version of Apache Catalina
10 | required
11 |
12 | 3942447fac867ae5cdb3229b658f4d48
13 | e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a
14 | f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b
15 | e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282
16 |
17 |
18 | EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
19 |
20 | pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.licenserc.yml:
--------------------------------------------------------------------------------
1 | header:
2 | license:
3 | spdx-id: Apache-2.0
4 | copyright-owner: OWASP Foundation
5 | content: |
6 | This file is part of CycloneDX Go
7 |
8 | Licensed under the Apache License, Version 2.0 (the “License”);
9 | you may not use this file except in compliance with the License.
10 | You may obtain a copy of the License at
11 |
12 | http://www.apache.org/licenses/LICENSE-2.0
13 |
14 | Unless required by applicable law or agreed to in writing, software
15 | distributed under the License is distributed on an “AS IS” BASIS,
16 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 | See the License for the specific language governing permissions and
18 | limitations under the License.
19 |
20 | SPDX-License-Identifier: Apache-2.0
21 | Copyright (c) OWASP Foundation. All Rights Reserved.
22 | paths-ignore:
23 | - "**/*.md"
24 | - "**/go.mod"
25 | - "**/go.sum"
26 | - "**/testdata/**"
27 | - ".github/**"
28 | - ".idea/**"
29 | - ".gitignore"
30 | - ".gitpod.yml"
31 | - ".golangci.yml"
32 | - ".goreleaser.yml"
33 | - ".licenserc.yml"
34 | - "CODEOWNERS"
35 | - "LICENSE"
36 | - "Makefile"
37 | - "NOTICE"
38 | - "cyclonedx_string.go"
39 | - "schema/**"
--------------------------------------------------------------------------------
/testdata/valid-license-id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Inc
6 | com.acme
7 | tomcat-catalina
8 | 9.0.14
9 | Modified version of Apache Catalina
10 | required
11 |
12 | 3942447fac867ae5cdb3229b658f4d48
13 | e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a
14 | f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b
15 | e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282
16 |
17 |
18 |
19 | Apache-2.0
20 |
21 |
22 | pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-external-reference.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | org.example
6 | mylibrary
7 | 1.0.0
8 |
9 |
10 | https://example.org/security/feed/csaf
11 | Security advisories from the vendor
12 |
13 |
14 | https://example.org/support/sbom/portal-server/1.0.0
15 | An external SBOM that describes what this component includes
16 |
17 | f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b
18 |
19 |
20 |
21 | https://example.org/support/documentation/portal-server/1.0.0
22 | Vendor provided documentation for the product
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-external-reference.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "publisher": "Acme Inc",
10 | "group": "org.example",
11 | "name": "mylibrary",
12 | "version": "1.0.0",
13 | "externalReferences": [
14 | {
15 | "url": "https://example.org/security/feed/csaf",
16 | "comment": "Security advisories from the vendor",
17 | "type": "advisories"
18 | },
19 | {
20 | "url": "https://example.org/support/sbom/portal-server/1.0.0",
21 | "comment": "An external SBOM that describes what this component includes",
22 | "hashes": [
23 | {
24 | "alg": "SHA-256",
25 | "content": "708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313"
26 | }
27 | ],
28 | "type": "bom"
29 | },
30 | {
31 | "url": "https://example.org/support/documentation/portal-server/1.0.0",
32 | "comment": "Vendor provided documentation for the product",
33 | "type": "documentation"
34 | }
35 | ]
36 | }
37 | ]
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/testdata/valid-license-name.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Inc
6 | com.acme
7 | tomcat-catalina
8 | 9.0.14
9 | Modified version of Apache Catalina
10 | required
11 |
12 | 3942447fac867ae5cdb3229b658f4d48
13 | e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a
14 | f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b
15 | e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282
16 |
17 |
18 |
19 | Apache License 2.0
20 |
21 |
22 | pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "tools": {
8 | "components": [
9 | {
10 | "type": "application",
11 | "group": "Awesome Vendor",
12 | "name": "Awesome Tool",
13 | "version": "9.1.2",
14 | "hashes": [
15 | {
16 | "alg": "SHA-1",
17 | "content": "25ed8e31b995bb927966616df2a42b979a2717f0"
18 | },
19 | {
20 | "alg": "SHA-256",
21 | "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df"
22 | }
23 | ]
24 | }
25 | ],
26 | "services": [
27 | {
28 | "provider": {
29 | "name": "Acme Org",
30 | "url": [
31 | "https://example.com"
32 | ]
33 | },
34 | "group": "com.example",
35 | "name": "Acme Signing Server",
36 | "description": "Signs artifacts",
37 | "endpoints": [
38 | "https://example.com/sign",
39 | "https://example.com/verify",
40 | "https://example.com/tsa"
41 | ]
42 | }
43 | ]
44 | }
45 | },
46 | "components": []
47 | }
--------------------------------------------------------------------------------
/testdata/valid-component-types.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | application-a
6 | 1.0
7 |
8 |
9 | library-a
10 | 1.0
11 |
12 |
13 | framework-a
14 | 1.0
15 |
16 |
17 | container-a
18 | 1.0
19 |
20 |
21 | operating-system-a
22 | 1.0
23 |
24 |
25 | firmware-a
26 | 1.0
27 |
28 |
29 | device-a
30 | 1.0
31 |
32 |
33 | file-a
34 | 1.0
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-metadata-tool.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Awesome Vendor
8 | Awesome Tool
9 | 9.1.2
10 |
11 | 25ed8e31b995bb927966616df2a42b979a2717f0
12 | a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df
13 |
14 |
15 |
16 |
17 |
18 |
19 | Acme Org
20 | https://example.com
21 |
22 | com.example
23 | Acme Signing Server
24 | Signs artifacts
25 |
26 | https://example.com/sign
27 | https://example.com/verify
28 | https://example.com/tsa
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/testdata/valid-component-swid-full.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Super Heros
6 | Acme Application
7 | 9.1.1
8 |
9 | PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-component-swid-full.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Super Heros
6 | Acme Application
7 | 9.1.1
8 |
9 | PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-metadata-tool.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "tools": {
8 | "components": [
9 | {
10 | "type": "application",
11 | "group": "Awesome Vendor",
12 | "name": "Awesome Tool",
13 | "version": "9.1.2",
14 | "hashes": [
15 | {
16 | "alg": "SHA-1",
17 | "content": "25ed8e31b995bb927966616df2a42b979a2717f0"
18 | },
19 | {
20 | "alg": "SHA-256",
21 | "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df"
22 | }
23 | ]
24 | }
25 | ],
26 | "services": [
27 | {
28 | "provider": {
29 | "name": "Acme Org",
30 | "url": [
31 | "https://example.com"
32 | ]
33 | },
34 | "group": "com.example",
35 | "name": "Acme Signing Server",
36 | "description": "Signs artifacts",
37 | "endpoints": [
38 | "https://example.com/sign",
39 | "https://example.com/verify",
40 | "https://example.com/tsa"
41 | ]
42 | }
43 | ]
44 | }
45 | },
46 | "components": []
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/testdata/valid-external-reference.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | org.example
6 | mylibrary
7 | 1.0.0
8 |
9 |
10 | https://example.org/security/feed/csaf
11 | Security advisories from the vendor
12 |
13 |
14 | https://example.org/support/sbom/portal-server/1.0.0
15 | An external SBOM that describes what this component includes
16 |
17 | f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b
18 |
19 |
20 |
21 | https://example.org/support/documentation/portal-server/1.0.0
22 | Vendor provided documentation for the product
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/testdata/valid-component-swid-full.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "author": "Acme Super Heros",
10 | "name": "Acme Application",
11 | "version": "9.1.1",
12 | "swid": {
13 | "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1",
14 | "name": "Acme Application",
15 | "version": "9.1.1",
16 | "text": {
17 | "contentType": "text/xml",
18 | "encoding": "base64",
19 | "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg=="
20 | }
21 | }
22 | }
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/copy.go:
--------------------------------------------------------------------------------
1 | // This file is part of CycloneDX Go
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the “License”);
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an “AS IS” BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // SPDX-License-Identifier: Apache-2.0
16 | // Copyright (c) OWASP Foundation. All Rights Reserved.
17 |
18 | package cyclonedx
19 |
20 | import (
21 | "bytes"
22 | "encoding/gob"
23 | "fmt"
24 | )
25 |
26 | // copy creates a deep copy of the BOM in a given destination.
27 | // Copying is currently done by encoding and decoding the BOM struct using gob.
28 | // In the future we may choose to switch to a more efficient strategy,
29 | // and consider to export this API.
30 | func (b BOM) copy(dst *BOM) error {
31 | buf := bytes.Buffer{}
32 | err := gob.NewEncoder(&buf).Encode(b)
33 | if err != nil {
34 | return fmt.Errorf("failed to encode bom: %w", err)
35 | }
36 |
37 | err = gob.NewDecoder(&buf).Decode(dst)
38 | if err != nil {
39 | return fmt.Errorf("failed to decode bom: %w", err)
40 | }
41 |
42 | return nil
43 | }
44 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-component-swid-full.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "author": "Acme Super Heros",
10 | "name": "Acme Application",
11 | "version": "9.1.1",
12 | "swid": {
13 | "text": {
14 | "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==",
15 | "contentType": "text/xml",
16 | "encoding": "base64"
17 | },
18 | "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1",
19 | "name": "Acme Application",
20 | "version": "9.1.1"
21 | }
22 | }
23 | ]
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/testdata/valid-metadata-tool.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Awesome Vendor
8 | Awesome Tool
9 | 9.1.2
10 |
11 | 25ed8e31b995bb927966616df2a42b979a2717f0
12 | a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df
13 |
14 |
15 |
16 |
17 |
18 |
19 | Acme Org
20 | https://example.com
21 |
22 | com.example
23 | Acme Signing Server
24 | Signs artifacts
25 |
26 | https://example.com/sign
27 | https://example.com/verify
28 | https://example.com/tsa
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-properties.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Bar
6 | You
7 | Two
8 | Foo
9 |
10 |
11 |
12 |
13 | acme-library
14 | 1.0.0
15 |
16 |
17 | Apache-2.0
18 |
19 | Bar
20 | You
21 | Two
22 | Foo
23 |
24 |
25 |
26 |
27 | Bar
28 | Foo
29 |
30 |
31 |
32 |
33 |
34 | org.partner
35 | Stock ticker service
36 |
37 | https://partner.org/api/v1/stock
38 |
39 |
40 | Bar
41 | Foo
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/cyclonedx_string.go:
--------------------------------------------------------------------------------
1 | // Code generated by "stringer -linecomment -output cyclonedx_string.go -type MediaType,SpecVersion"; DO NOT EDIT.
2 |
3 | package cyclonedx
4 |
5 | import "strconv"
6 |
7 | func _() {
8 | // An "invalid array index" compiler error signifies that the constant values have changed.
9 | // Re-run the stringer command to generate them again.
10 | var x [1]struct{}
11 | _ = x[MediaTypeJSON-1]
12 | _ = x[MediaTypeXML-2]
13 | _ = x[MediaTypeProtobuf-3]
14 | }
15 |
16 | const _MediaType_name = "application/vnd.cyclonedx+jsonapplication/vnd.cyclonedx+xmlapplication/x.vnd.cyclonedx+protobuf"
17 |
18 | var _MediaType_index = [...]uint8{0, 30, 59, 95}
19 |
20 | func (i MediaType) String() string {
21 | i -= 1
22 | if i < 0 || i >= MediaType(len(_MediaType_index)-1) {
23 | return "MediaType(" + strconv.FormatInt(int64(i+1), 10) + ")"
24 | }
25 | return _MediaType_name[_MediaType_index[i]:_MediaType_index[i+1]]
26 | }
27 | func _() {
28 | // An "invalid array index" compiler error signifies that the constant values have changed.
29 | // Re-run the stringer command to generate them again.
30 | var x [1]struct{}
31 | _ = x[SpecVersion1_0-1]
32 | _ = x[SpecVersion1_1-2]
33 | _ = x[SpecVersion1_2-3]
34 | _ = x[SpecVersion1_3-4]
35 | _ = x[SpecVersion1_4-5]
36 | _ = x[SpecVersion1_5-6]
37 | _ = x[SpecVersion1_6-7]
38 | }
39 |
40 | const _SpecVersion_name = "1.01.11.21.31.41.51.6"
41 |
42 | var _SpecVersion_index = [...]uint8{0, 3, 6, 9, 12, 15, 18, 21}
43 |
44 | func (i SpecVersion) String() string {
45 | i -= 1
46 | if i < 0 || i >= SpecVersion(len(_SpecVersion_index)-1) {
47 | return "SpecVersion(" + strconv.FormatInt(int64(i+1), 10) + ")"
48 | }
49 | return _SpecVersion_name[_SpecVersion_index[i]:_SpecVersion_index[i+1]]
50 | }
51 |
--------------------------------------------------------------------------------
/testdata/valid-license-licensing.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "publisher": "Acme Inc",
10 | "group": "com.acme",
11 | "name": "cryptographic-provider",
12 | "version": "2.2.0",
13 | "licenses": [
14 | {
15 | "license": {
16 | "bom-ref": "acme-license-1",
17 | "name": "Acme Commercial License",
18 | "acknowledgement": "concluded",
19 | "licensing": {
20 | "altIds": [
21 | "acme", "acme-license"
22 | ],
23 | "licensor": {
24 | "organization": {
25 | "name": "Acme Inc",
26 | "contact": [
27 | {
28 | "name": "Acme Licensing Fulfillment",
29 | "email": "licensing@example.com"
30 | }
31 | ]
32 | }
33 | },
34 | "licensee": {
35 | "organization": {
36 | "name": "Example Co."
37 | }
38 | },
39 | "purchaser": {
40 | "individual": {
41 | "name": "Samantha Wright",
42 | "email": "samantha.wright@gmail.com",
43 | "phone": "800-555-1212"
44 | }
45 | },
46 | "purchaseOrder": "PO-12345",
47 | "licenseTypes": ["appliance"],
48 | "lastRenewal": "2022-04-13T20:20:39+00:00",
49 | "expiration": "2023-04-13T20:20:39+00:00"
50 | }
51 | }
52 | }
53 | ]
54 | }
55 | ]
56 | }
--------------------------------------------------------------------------------
/testdata/valid-properties.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Bar
6 | You
7 | Two
8 | Foo
9 |
10 |
11 |
12 |
13 | acme-library
14 | 1.0.0
15 |
16 |
17 | Apache-2.0
18 |
19 | Bar
20 | You
21 | Two
22 | Foo
23 |
24 |
25 |
26 |
27 | Bar
28 | Foo
29 |
30 |
31 |
32 |
33 |
34 | org.partner
35 | Stock ticker service
36 |
37 | https://partner.org/api/v1/stock
38 |
39 |
40 | Bar
41 | Foo
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 |
11 | permissions: { }
12 |
13 | jobs:
14 | licensecheck:
15 | name: License Check
16 | timeout-minutes: 5
17 | runs-on: ubuntu-latest
18 | steps:
19 | - name: Checkout Repository
20 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
21 | - name: Check license headers
22 | uses: apache/skywalking-eyes@5c5b974209f0de5d905f37deb69369068ebfc15c # tag=v0.7.0
23 | with:
24 | config: .licenserc.yml
25 |
26 | lint:
27 | name: Lint
28 | timeout-minutes: 5
29 | runs-on: ubuntu-latest
30 | steps:
31 | - name: Checkout Repository
32 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
33 | - name: Setup Go
34 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # tag=v5.5.0
35 | with:
36 | go-version: "1.22"
37 | check-latest: true
38 | cache: false
39 | - name: Run golangci-lint
40 | uses: golangci/golangci-lint-action@ec5d18412c0aeab7936cb16880d708ba2a64e1ae # tag=v6.2.0
41 | with:
42 | version: latest
43 | args: --verbose
44 |
45 | test:
46 | name: Test
47 | timeout-minutes: 5
48 | runs-on: ubuntu-latest
49 | strategy:
50 | matrix:
51 | go:
52 | - "1.20"
53 | - "1.21"
54 | - "1.22"
55 | steps:
56 | - name: Setup Go
57 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # tag=v5.5.0
58 | with:
59 | go-version: ${{ matrix.go }}
60 | check-latest: true
61 | - name: Checkout Repository
62 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
63 | - name: Test
64 | run: make test
65 |
--------------------------------------------------------------------------------
/link_example_test.go:
--------------------------------------------------------------------------------
1 | // This file is part of CycloneDX Go
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the “License”);
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an “AS IS” BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // SPDX-License-Identifier: Apache-2.0
16 | // Copyright (c) OWASP Foundation. All Rights Reserved.
17 |
18 | package cyclonedx_test
19 |
20 | import (
21 | "fmt"
22 |
23 | cdx "github.com/CycloneDX/cyclonedx-go"
24 | )
25 |
26 | func ExampleNewBOMLink() {
27 | bom := cdx.NewBOM()
28 | bom.SerialNumber = "urn:uuid:bd064d10-4238-4a2e-9517-216f79ed77ad"
29 | bom.Version = 2
30 | bom.Metadata = &cdx.Metadata{
31 | Component: &cdx.Component{
32 | BOMRef: "pkg:golang/github.com/CycloneDX/cyclonedx-go@v0.5.0?type=module",
33 | Type: cdx.ComponentTypeLibrary,
34 | Name: "github.com/CycloneDX/cyclonedx-go",
35 | Version: "v0.5.0",
36 | PackageURL: "pkg:golang/github.com/CycloneDX/cyclonedx-go@v0.5.0?type=module",
37 | },
38 | }
39 |
40 | link, _ := cdx.NewBOMLink(bom.SerialNumber, bom.Version, nil)
41 | deepLink, _ := cdx.NewBOMLink(bom.SerialNumber, bom.Version, bom.Metadata.Component)
42 |
43 | fmt.Println(link.String())
44 | fmt.Println(deepLink.String())
45 |
46 | // Output:
47 | // urn:cdx:bd064d10-4238-4a2e-9517-216f79ed77ad/2
48 | // urn:cdx:bd064d10-4238-4a2e-9517-216f79ed77ad/2#pkg%3Agolang%2Fgithub.com%2FCycloneDX%2Fcyclonedx-go%40v0.5.0%3Ftype%3Dmodule
49 | }
50 |
--------------------------------------------------------------------------------
/testdata/valid-properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "properties": [
8 | {
9 | "name": "Foo",
10 | "value": "Bar"
11 | },
12 | {
13 | "name": "Foo",
14 | "value": "You"
15 | },
16 | {
17 | "name": "Foo",
18 | "value": "Two"
19 | },
20 | {
21 | "name": "Bar",
22 | "value": "Foo"
23 | }
24 | ]
25 | },
26 | "components": [
27 | {
28 | "type": "library",
29 | "name": "acme-library",
30 | "version": "1.0.0",
31 | "licenses": [
32 | {
33 | "license": {
34 | "id": "Apache-2.0",
35 | "properties": [
36 | {
37 | "name": "Foo",
38 | "value": "Bar"
39 | },
40 | {
41 | "name": "Foo",
42 | "value": "You"
43 | },
44 | {
45 | "name": "Foo",
46 | "value": "Two"
47 | },
48 | {
49 | "name": "Bar",
50 | "value": "Foo"
51 | }
52 | ]
53 | }
54 | }
55 | ],
56 | "properties": [
57 | {
58 | "name": "Foo",
59 | "value": "Bar"
60 | }
61 | ]
62 | }
63 | ],
64 | "services": [
65 | {
66 | "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8",
67 | "group": "org.partner",
68 | "name": "Stock ticker service",
69 | "endpoints": [
70 | "https://partner.org/api/v1/stock"
71 | ],
72 | "properties": [
73 | {
74 | "name": "Foo",
75 | "value": "Bar"
76 | }
77 | ]
78 | }
79 | ]
80 | }
81 |
--------------------------------------------------------------------------------
/decode.go:
--------------------------------------------------------------------------------
1 | // This file is part of CycloneDX Go
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the “License”);
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an “AS IS” BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // SPDX-License-Identifier: Apache-2.0
16 | // Copyright (c) OWASP Foundation. All Rights Reserved.
17 |
18 | package cyclonedx
19 |
20 | import (
21 | "encoding/json"
22 | "encoding/xml"
23 | "io"
24 | )
25 |
26 | type BOMDecoder interface {
27 | Decode(bom *BOM) error
28 | }
29 |
30 | func NewBOMDecoder(reader io.Reader, format BOMFileFormat) BOMDecoder {
31 | if format == BOMFileFormatJSON {
32 | return &jsonBOMDecoder{reader: reader}
33 | }
34 | return &xmlBOMDecoder{reader: reader}
35 | }
36 |
37 | type jsonBOMDecoder struct {
38 | reader io.Reader
39 | }
40 |
41 | // Decode implements the BOMDecoder interface.
42 | func (j jsonBOMDecoder) Decode(bom *BOM) error {
43 | bytes, err := io.ReadAll(j.reader)
44 | if err != nil {
45 | return err
46 | }
47 | return json.Unmarshal(bytes, bom)
48 | }
49 |
50 | type xmlBOMDecoder struct {
51 | reader io.Reader
52 | }
53 |
54 | // Decode implements the BOMDecoder interface.
55 | func (x xmlBOMDecoder) Decode(bom *BOM) error {
56 | err := xml.NewDecoder(x.reader).Decode(bom)
57 | if err != nil {
58 | return err
59 | }
60 |
61 | for specVersion, xmlNs := range xmlNamespaces {
62 | if xmlNs == bom.XMLNS {
63 | bom.SpecVersion = specVersion
64 | break
65 | }
66 | }
67 |
68 | return nil
69 | }
70 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-component-hashes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | acme-example
6 | 1.0.0
7 |
8 | 641b6e166f8b33c5e959e2adcc18b1c7
9 | 9188560f22e0b73070d2efce670c74af2bdf30af
10 | d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964
11 | d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad
12 | 74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6
13 | 7478c7cf41c883a04ee89f1813f687886d53fa86f791fff90690c6221e3853aa
14 | a1eea7229716487ad2ebe96b2f997a8408f32f14047994fbcc99b49012cf86c96dbd518e5d57a61b0e57dd37dd0b48f5
15 | 7d584825bc1767dfabe7e82b45ccb7a1119b145fa17e76b885e71429c706cef0a3171bc6575b968eec5da56a7966c02fec5402fcee55097ac01d40c550de9d20
16 | d8779633380c050bccf4e733b763ab2abd8ad2db60b517d47fd29bbf76433237
17 | e728ba56c2da995a559a178116c594e8bee4894a79ceb4399d8f479e5563cb1942b85936f646d14170717c576b14db7a
18 | f8ce8d612a6c85c96cf7cebc230f6ddef26e6cedcfbc4a41c766033cc08c6ba097d1470948226807fb2d88d2a2b6fc0ff5e5440e93a603086fdd568bafcd1a9d
19 | 26cdc7fb3fd65fc3b621a4ef70bc7d2489d5c19e70c76cf7ec20e538df0047cf
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "properties": [
8 | {
9 | "name": "Foo",
10 | "value": "Bar"
11 | },
12 | {
13 | "name": "Foo",
14 | "value": "You"
15 | },
16 | {
17 | "name": "Foo",
18 | "value": "Two"
19 | },
20 | {
21 | "name": "Bar",
22 | "value": "Foo"
23 | }
24 | ]
25 | },
26 | "components": [
27 | {
28 | "type": "library",
29 | "name": "acme-library",
30 | "version": "1.0.0",
31 | "licenses": [
32 | {
33 | "license": {
34 | "id": "Apache-2.0",
35 | "properties": [
36 | {
37 | "name": "Foo",
38 | "value": "Bar"
39 | },
40 | {
41 | "name": "Foo",
42 | "value": "You"
43 | },
44 | {
45 | "name": "Foo",
46 | "value": "Two"
47 | },
48 | {
49 | "name": "Bar",
50 | "value": "Foo"
51 | }
52 | ]
53 | }
54 | }
55 | ],
56 | "properties": [
57 | {
58 | "name": "Foo",
59 | "value": "Bar"
60 | }
61 | ]
62 | }
63 | ],
64 | "services": [
65 | {
66 | "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8",
67 | "group": "org.partner",
68 | "name": "Stock ticker service",
69 | "endpoints": [
70 | "https://partner.org/api/v1/stock"
71 | ],
72 | "properties": [
73 | {
74 | "name": "Foo",
75 | "value": "Bar"
76 | }
77 | ]
78 | }
79 | ]
80 | }
81 |
82 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-license-licensing.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "publisher": "Acme Inc",
10 | "group": "com.acme",
11 | "name": "cryptographic-provider",
12 | "version": "2.2.0",
13 | "licenses": [
14 | {
15 | "license": {
16 | "bom-ref": "acme-license-1",
17 | "name": "Acme Commercial License",
18 | "acknowledgement": "concluded",
19 | "licensing": {
20 | "altIds": [
21 | "acme",
22 | "acme-license"
23 | ],
24 | "licensor": {
25 | "organization": {
26 | "name": "Acme Inc",
27 | "contact": [
28 | {
29 | "name": "Acme Licensing Fulfillment",
30 | "email": "licensing@example.com"
31 | }
32 | ]
33 | }
34 | },
35 | "licensee": {
36 | "organization": {
37 | "name": "Example Co."
38 | }
39 | },
40 | "purchaser": {
41 | "individual": {
42 | "name": "Samantha Wright",
43 | "email": "samantha.wright@gmail.com",
44 | "phone": "800-555-1212"
45 | }
46 | },
47 | "purchaseOrder": "PO-12345",
48 | "licenseTypes": [
49 | "appliance"
50 | ],
51 | "lastRenewal": "2022-04-13T20:20:39+00:00",
52 | "expiration": "2023-04-13T20:20:39+00:00"
53 | }
54 | }
55 | }
56 | ]
57 | }
58 | ]
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-license-licensing.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Inc
6 | com.acme
7 | cryptographic-provider
8 | 2.2.0
9 |
10 |
11 | Acme Commercial License
12 |
13 |
14 | acme
15 | acme-license
16 |
17 |
18 |
19 | Acme Inc
20 |
21 | Acme Licensing Fulfillment
22 | licensing@example.com
23 |
24 |
25 |
26 |
27 |
28 | Example Co.
29 |
30 |
31 |
32 |
33 | Samantha Wright
34 | samantha.wright@gmail.com
35 | 800-555-1212
36 |
37 |
38 | PO-12345
39 |
40 | appliance
41 |
42 | 2022-04-13T20:20:39+00:00
43 | 2023-04-13T20:20:39+00:00
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/testdata/valid-component-hashes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | acme-example
6 | 1.0.0
7 |
8 | 641b6e166f8b33c5e959e2adcc18b1c7
9 | 9188560f22e0b73070d2efce670c74af2bdf30af
10 | d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964
11 | d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad
12 | 74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6
13 | 7478c7cf41c883a04ee89f1813f687886d53fa86f791fff90690c6221e3853aa
14 | a1eea7229716487ad2ebe96b2f997a8408f32f14047994fbcc99b49012cf86c96dbd518e5d57a61b0e57dd37dd0b48f5
15 | 7d584825bc1767dfabe7e82b45ccb7a1119b145fa17e76b885e71429c706cef0a3171bc6575b968eec5da56a7966c02fec5402fcee55097ac01d40c550de9d20
16 | d8779633380c050bccf4e733b763ab2abd8ad2db60b517d47fd29bbf76433237
17 | e728ba56c2da995a559a178116c594e8bee4894a79ceb4399d8f479e5563cb1942b85936f646d14170717c576b14db7a
18 | f8ce8d612a6c85c96cf7cebc230f6ddef26e6cedcfbc4a41c766033cc08c6ba097d1470948226807fb2d88d2a2b6fc0ff5e5440e93a603086fdd568bafcd1a9d
19 | 26cdc7fb3fd65fc3b621a4ef70bc7d2489d5c19e70c76cf7ec20e538df0047cf
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.idea/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
--------------------------------------------------------------------------------
/testdata/valid-compositions.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "component": {
8 | "bom-ref": "acme-application-1.0",
9 | "type": "application",
10 | "name": "Acme Application",
11 | "version": "1.0"
12 | }
13 | },
14 | "components": [
15 | {
16 | "bom-ref": "pkg:maven/partner/shaded-library@1.0",
17 | "type": "library",
18 | "name": "Partner Shaded Library",
19 | "version": "1.0",
20 | "purl": "pkg:maven/partner/shaded-library@1.0",
21 | "components": [
22 | {
23 | "bom-ref": "pkg:maven/ossproject/library@2.0",
24 | "type": "library",
25 | "name": "Some Opensource Library",
26 | "version": "2.0",
27 | "purl": "pkg:maven/ossproject/library@2.0"
28 | }
29 | ]
30 | },
31 | {
32 | "type": "library",
33 | "name": "Acme Library",
34 | "version": "3.0",
35 | "purl": "pkg:maven/acme/library@3.0"
36 | }
37 | ],
38 | "dependencies": [
39 | {
40 | "ref": "acme-application-1.0",
41 | "dependsOn": [
42 | "pkg:maven/partner/shaded-library@1.0",
43 | "pkg:maven/acme/library@3.0"
44 | ]
45 | }
46 | ],
47 | "vulnerabilities": [
48 | {
49 | "bom-ref": "vulnerability-1",
50 | "id": "ACME-12345",
51 | "source": {
52 | "name": "Acme Inc"
53 | }
54 | }
55 | ],
56 | "compositions": [
57 | {
58 | "bom-ref": "composition-1",
59 | "aggregate": "complete",
60 | "assemblies": [
61 | "pkg:maven/partner/shaded-library@1.0"
62 | ],
63 | "dependencies": [
64 | "acme-application-1.0"
65 | ]
66 | },
67 | {
68 | "aggregate": "unknown",
69 | "assemblies": [
70 | "pkg:maven/acme/library@3.0"
71 | ]
72 | },
73 | {
74 | "aggregate": "incomplete_first_party_only",
75 | "vulnerabilities": [
76 | "vulnerability-1"
77 | ]
78 | }
79 | ]
80 | }
81 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-compositions.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "metadata": {
7 | "component": {
8 | "bom-ref": "acme-application-1.0",
9 | "type": "application",
10 | "name": "Acme Application",
11 | "version": "1.0"
12 | }
13 | },
14 | "components": [
15 | {
16 | "bom-ref": "pkg:maven/partner/shaded-library@1.0",
17 | "type": "library",
18 | "name": "Partner Shaded Library",
19 | "version": "1.0",
20 | "purl": "pkg:maven/partner/shaded-library@1.0",
21 | "components": [
22 | {
23 | "bom-ref": "pkg:maven/ossproject/library@2.0",
24 | "type": "library",
25 | "name": "Some Opensource Library",
26 | "version": "2.0",
27 | "purl": "pkg:maven/ossproject/library@2.0"
28 | }
29 | ]
30 | },
31 | {
32 | "type": "library",
33 | "name": "Acme Library",
34 | "version": "3.0",
35 | "purl": "pkg:maven/acme/library@3.0"
36 | }
37 | ],
38 | "dependencies": [
39 | {
40 | "ref": "acme-application-1.0",
41 | "dependsOn": [
42 | "pkg:maven/partner/shaded-library@1.0",
43 | "pkg:maven/acme/library@3.0"
44 | ]
45 | }
46 | ],
47 | "compositions": [
48 | {
49 | "bom-ref": "composition-1",
50 | "aggregate": "complete",
51 | "assemblies": [
52 | "pkg:maven/partner/shaded-library@1.0"
53 | ],
54 | "dependencies": [
55 | "acme-application-1.0"
56 | ]
57 | },
58 | {
59 | "aggregate": "unknown",
60 | "assemblies": [
61 | "pkg:maven/acme/library@3.0"
62 | ]
63 | },
64 | {
65 | "aggregate": "incomplete_first_party_only",
66 | "vulnerabilities": [
67 | "vulnerability-1"
68 | ]
69 | }
70 | ],
71 | "vulnerabilities": [
72 | {
73 | "bom-ref": "vulnerability-1",
74 | "id": "ACME-12345",
75 | "source": {
76 | "name": "Acme Inc"
77 | }
78 | }
79 | ]
80 | }
81 |
82 |
--------------------------------------------------------------------------------
/validate_json_test.go:
--------------------------------------------------------------------------------
1 | // This file is part of CycloneDX Go
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the “License”);
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an “AS IS” BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // SPDX-License-Identifier: Apache-2.0
16 | // Copyright (c) OWASP Foundation. All Rights Reserved.
17 |
18 | package cyclonedx
19 |
20 | import (
21 | "errors"
22 | "fmt"
23 |
24 | "github.com/xeipuuv/gojsonschema"
25 | )
26 |
27 | var jsonSchemaFiles = map[SpecVersion]string{
28 | SpecVersion1_2: "file://./schema/bom-1.2.schema.json",
29 | SpecVersion1_3: "file://./schema/bom-1.3.schema.json",
30 | SpecVersion1_4: "file://./schema/bom-1.4.schema.json",
31 | SpecVersion1_5: "file://./schema/bom-1.5.schema.json",
32 | SpecVersion1_6: "file://./schema/bom-1.6.schema.json",
33 | }
34 |
35 | type jsonValidator struct{}
36 |
37 | func newJSONValidator() validator {
38 | return &jsonValidator{}
39 | }
40 |
41 | func (jv jsonValidator) Validate(bom []byte, specVersion SpecVersion) error {
42 | schemaFilePath, ok := jsonSchemaFiles[specVersion]
43 | if !ok {
44 | return fmt.Errorf("no json schema known for spec version %s", specVersion)
45 | }
46 |
47 | schemaLoader := gojsonschema.NewReferenceLoader(schemaFilePath)
48 | documentLoader := gojsonschema.NewBytesLoader(bom)
49 |
50 | result, err := gojsonschema.Validate(schemaLoader, documentLoader)
51 | if err != nil {
52 | return fmt.Errorf("failed to validate: %w", err)
53 | }
54 |
55 | if result.Valid() {
56 | return nil
57 | }
58 |
59 | errSummary := fmt.Sprintf("encountered %d validation errors:", len(result.Errors()))
60 | for _, verr := range result.Errors() {
61 | errSummary += fmt.Sprintf("\n - %s", verr.String())
62 | }
63 |
64 | return errors.New(errSummary)
65 | }
66 |
--------------------------------------------------------------------------------
/cyclonedx_test.go:
--------------------------------------------------------------------------------
1 | // This file is part of CycloneDX Go
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the “License”);
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an “AS IS” BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // SPDX-License-Identifier: Apache-2.0
16 | // Copyright (c) OWASP Foundation. All Rights Reserved.
17 |
18 | package cyclonedx
19 |
20 | import (
21 | "testing"
22 |
23 | "github.com/bradleyjkemp/cupaloy/v2"
24 | "github.com/stretchr/testify/assert"
25 | "github.com/stretchr/testify/require"
26 | )
27 |
28 | var snapShooter = cupaloy.NewDefaultConfig().
29 | WithOptions(cupaloy.SnapshotSubdirectory("./testdata/snapshots"))
30 |
31 | func TestBool(t *testing.T) {
32 | assert.Equal(t, true, *Bool(true))
33 | assert.Equal(t, false, *Bool(false))
34 | }
35 |
36 | func TestMediaType_WithVersion(t *testing.T) {
37 | t.Run("ShouldReturnVersionedMediaType", func(t *testing.T) {
38 | res, err := MediaTypeJSON.WithVersion(SpecVersion1_2)
39 | require.NoError(t, err)
40 | require.Equal(t, "application/vnd.cyclonedx+json; version=1.2", res)
41 | })
42 |
43 | t.Run("ShouldReturnErrorForSpecLowerThan1.2AndJSON", func(t *testing.T) {
44 | _, err := MediaTypeJSON.WithVersion(SpecVersion1_1)
45 | require.Error(t, err)
46 | })
47 | }
48 |
49 | func TestVulnerability_Properties(t *testing.T) {
50 | // GIVEN
51 | properties := []Property{}
52 | vuln := Vulnerability{
53 | Properties: &properties,
54 | }
55 |
56 | // EXPECT
57 | assert.Equal(t, 0, len(*vuln.Properties))
58 | }
59 |
60 | func assertValidBOM(t *testing.T, bomBytes []byte, format BOMFileFormat, version SpecVersion) {
61 | var v validator
62 | if format == BOMFileFormatJSON {
63 | v = newJSONValidator()
64 | } else {
65 | v = newXMLValidator()
66 | }
67 | err := v.Validate(bomBytes, version)
68 | require.NoError(t, err)
69 | }
70 |
--------------------------------------------------------------------------------
/validate_xml_test.go:
--------------------------------------------------------------------------------
1 | // This file is part of CycloneDX Go
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the “License”);
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an “AS IS” BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // SPDX-License-Identifier: Apache-2.0
16 | // Copyright (c) OWASP Foundation. All Rights Reserved.
17 |
18 | package cyclonedx
19 |
20 | import (
21 | "fmt"
22 | "sync"
23 |
24 | "github.com/terminalstatic/go-xsd-validate"
25 | )
26 |
27 | var xmlSchemaFiles = map[SpecVersion]string{
28 | SpecVersion1_0: "./schema/bom-1.0.xsd",
29 | SpecVersion1_1: "./schema/bom-1.1.xsd",
30 | SpecVersion1_2: "./schema/bom-1.2.xsd",
31 | SpecVersion1_3: "./schema/bom-1.3.xsd",
32 | SpecVersion1_4: "./schema/bom-1.4.xsd",
33 | SpecVersion1_5: "./schema/bom-1.5.xsd",
34 | SpecVersion1_6: "./schema/bom-1.6.xsd",
35 | }
36 |
37 | var xsdValidateInitOnce sync.Once
38 |
39 | type xmlValidator struct{}
40 |
41 | func newXMLValidator() validator {
42 | var initErr error
43 | xsdValidateInitOnce.Do(func() {
44 | initErr = xsdvalidate.Init()
45 | })
46 | if initErr != nil {
47 | panic(initErr)
48 | }
49 |
50 | return &xmlValidator{}
51 | }
52 |
53 | func (xv xmlValidator) Validate(bom []byte, specVersion SpecVersion) error {
54 | schemaFilePath, ok := xmlSchemaFiles[specVersion]
55 | if !ok {
56 | return fmt.Errorf("no xml schema known for spec version %s", specVersion)
57 | }
58 |
59 | xsdHandler, err := xsdvalidate.NewXsdHandlerUrl(schemaFilePath, xsdvalidate.ParsErrVerbose)
60 | if err != nil {
61 | return fmt.Errorf("failed to parse schema: %w", err)
62 | }
63 | defer xsdHandler.Free()
64 |
65 | xmlHandler, err := xsdvalidate.NewXmlHandlerMem(bom, xsdvalidate.ParsErrVerbose)
66 | if err != nil {
67 | return fmt.Errorf("failed to parse bom xml: %w", err)
68 | }
69 | defer xmlHandler.Free()
70 |
71 | return xsdHandler.Validate(xmlHandler, xsdvalidate.ValidErrDefault)
72 | }
73 |
--------------------------------------------------------------------------------
/testdata/valid-license-licensing.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Inc
6 | com.acme
7 | cryptographic-provider
8 | 2.2.0
9 |
10 |
11 | Acme Commercial License
12 |
13 |
14 | acme
15 | acme-license
16 |
17 |
18 |
19 | Acme Inc
20 |
21 | Acme Licensing Fulfillment
22 | licensing@example.com
23 |
24 |
25 |
26 |
27 |
28 | Example Co.
29 |
30 |
31 |
32 |
33 | Samantha Wright
34 | samantha.wright@gmail.com
35 | 800-555-1212
36 |
37 |
38 | PO-12345
39 |
40 | appliance
41 |
42 | 2022-04-13T20:20:39+00:00
43 | 2023-04-13T20:20:39+00:00
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/testdata/valid-component-hashes.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "name": "acme-example",
10 | "version": "1.0.0",
11 | "hashes": [
12 | {
13 | "alg": "MD5",
14 | "content": "641b6e166f8b33c5e959e2adcc18b1c7"
15 | },
16 | {
17 | "alg": "SHA-1",
18 | "content": "9188560f22e0b73070d2efce670c74af2bdf30af"
19 | },
20 | {
21 | "alg": "SHA-256",
22 | "content": "d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964"
23 | },
24 | {
25 | "alg": "SHA-384",
26 | "content": "d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad"
27 | },
28 | {
29 | "alg": "SHA-512",
30 | "content": "74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6"
31 | },
32 | {
33 | "alg": "SHA3-256",
34 | "content": "7478c7cf41c883a04ee89f1813f687886d53fa86f791fff90690c6221e3853aa"
35 | },
36 | {
37 | "alg": "SHA3-384",
38 | "content": "a1eea7229716487ad2ebe96b2f997a8408f32f14047994fbcc99b49012cf86c96dbd518e5d57a61b0e57dd37dd0b48f5"
39 | },
40 | {
41 | "alg": "SHA3-512",
42 | "content": "7d584825bc1767dfabe7e82b45ccb7a1119b145fa17e76b885e71429c706cef0a3171bc6575b968eec5da56a7966c02fec5402fcee55097ac01d40c550de9d20"
43 | },
44 | {
45 | "alg": "BLAKE2b-256",
46 | "content": "d8779633380c050bccf4e733b763ab2abd8ad2db60b517d47fd29bbf76433237"
47 | },
48 | {
49 | "alg": "BLAKE2b-384",
50 | "content": "e728ba56c2da995a559a178116c594e8bee4894a79ceb4399d8f479e5563cb1942b85936f646d14170717c576b14db7a"
51 | },
52 | {
53 | "alg": "BLAKE2b-512",
54 | "content": "f8ce8d612a6c85c96cf7cebc230f6ddef26e6cedcfbc4a41c766033cc08c6ba097d1470948226807fb2d88d2a2b6fc0ff5e5440e93a603086fdd568bafcd1a9d"
55 | },
56 | {
57 | "alg": "BLAKE3",
58 | "content": "26cdc7fb3fd65fc3b621a4ef70bc7d2489d5c19e70c76cf7ec20e538df0047cf"
59 | }
60 | ]
61 | }
62 | ]
63 | }
64 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-component-hashes.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "name": "acme-example",
10 | "version": "1.0.0",
11 | "hashes": [
12 | {
13 | "alg": "MD5",
14 | "content": "641b6e166f8b33c5e959e2adcc18b1c7"
15 | },
16 | {
17 | "alg": "SHA-1",
18 | "content": "9188560f22e0b73070d2efce670c74af2bdf30af"
19 | },
20 | {
21 | "alg": "SHA-256",
22 | "content": "d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964"
23 | },
24 | {
25 | "alg": "SHA-384",
26 | "content": "d4835048a0f57c74b8fb617d5366ab81376fc92bebe9a93bf24ba7f9da6c9aeeb6179f5d1361f6533211b15f3224cbad"
27 | },
28 | {
29 | "alg": "SHA-512",
30 | "content": "74a51ff45e4c11df9ba1f0094282c80489649cb157a75fa337992d2d4592a5a1b8cb4525de8db0ae25233553924d76c36e093ea7fa9df4e5b8b07fd2e074efd6"
31 | },
32 | {
33 | "alg": "SHA3-256",
34 | "content": "7478c7cf41c883a04ee89f1813f687886d53fa86f791fff90690c6221e3853aa"
35 | },
36 | {
37 | "alg": "SHA3-384",
38 | "content": "a1eea7229716487ad2ebe96b2f997a8408f32f14047994fbcc99b49012cf86c96dbd518e5d57a61b0e57dd37dd0b48f5"
39 | },
40 | {
41 | "alg": "SHA3-512",
42 | "content": "7d584825bc1767dfabe7e82b45ccb7a1119b145fa17e76b885e71429c706cef0a3171bc6575b968eec5da56a7966c02fec5402fcee55097ac01d40c550de9d20"
43 | },
44 | {
45 | "alg": "BLAKE2b-256",
46 | "content": "d8779633380c050bccf4e733b763ab2abd8ad2db60b517d47fd29bbf76433237"
47 | },
48 | {
49 | "alg": "BLAKE2b-384",
50 | "content": "e728ba56c2da995a559a178116c594e8bee4894a79ceb4399d8f479e5563cb1942b85936f646d14170717c576b14db7a"
51 | },
52 | {
53 | "alg": "BLAKE2b-512",
54 | "content": "f8ce8d612a6c85c96cf7cebc230f6ddef26e6cedcfbc4a41c766033cc08c6ba097d1470948226807fb2d88d2a2b6fc0ff5e5440e93a603086fdd568bafcd1a9d"
55 | },
56 | {
57 | "alg": "BLAKE3",
58 | "content": "26cdc7fb3fd65fc3b621a4ef70bc7d2489d5c19e70c76cf7ec20e538df0047cf"
59 | }
60 | ]
61 | }
62 | ]
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-compositions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Application
6 | 1.0
7 |
8 |
9 |
10 |
11 | Partner Shaded Library
12 | 1.0
13 | pkg:maven/partner/shaded-library@1.0
14 |
15 |
16 | Some Opensource Library
17 | 2.0
18 | pkg:maven/ossproject/library@2.0
19 |
20 |
21 |
22 |
23 | Acme Library
24 | 2.0
25 | pkg:maven/acme/library@3.0
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | complete
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | unknown
46 |
47 |
48 |
49 |
50 |
51 | incomplete_first_party_only
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | ACME-12345
60 |
61 | Acme Inc
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M=
2 | github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0=
3 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
5 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
7 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
8 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
9 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
10 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
11 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
12 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
13 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
14 | github.com/terminalstatic/go-xsd-validate v0.1.6 h1:TenYeQ3eY631qNi1/cTmLH/s2slHPRKTTHT+XSHkepo=
15 | github.com/terminalstatic/go-xsd-validate v0.1.6/go.mod h1:18lsvYFofBflqCrvo1umpABZ99+GneNTw2kEEc8UPJw=
16 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
17 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
18 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
19 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
20 | github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
21 | github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
22 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
23 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
24 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
25 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
26 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
27 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-service.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.acme
6 | stock-java-client
7 | 1.0.12
8 |
9 | e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a
10 |
11 |
12 |
13 | Apache-2.0
14 |
15 |
16 | pkg:maven/com.acme/stock-java-client@1.0.12
17 |
18 |
19 |
20 |
21 |
22 | Partner Org
23 | https://partner.org
24 |
25 | Support
26 | support@partner
27 | 800-555-1212
28 |
29 |
30 | org.partner
31 | Stock ticker service
32 | 2020-Q2
33 | Provides real-time stock information
34 |
35 | https://partner.org/api/v1/lookup
36 | https://partner.org/api/v1/stock
37 |
38 | true
39 | true
40 |
41 | PII
42 | PIFI
43 | pubic
44 | partner-data
45 |
46 |
47 |
48 | Partner license
49 |
50 |
51 |
52 |
53 | http://partner.org
54 |
55 |
56 | http://api.partner.org/swagger
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/testdata/valid-compositions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Application
6 | 1.0
7 |
8 |
9 |
10 |
11 | Partner Shaded Library
12 | 1.0
13 | pkg:maven/partner/shaded-library@1.0
14 |
15 |
16 | Some Opensource Library
17 | 2.0
18 | pkg:maven/ossproject/library@2.0
19 |
20 |
21 |
22 |
23 | Acme Library
24 | 2.0
25 | pkg:maven/acme/library@3.0
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | ACME-12345
37 |
38 | Acme Inc
39 |
40 |
41 |
42 |
43 |
44 | complete
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | unknown
54 |
55 |
56 |
57 |
58 |
59 | incomplete_first_party_only
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-patch.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.acme
6 | sample-library
7 | 1.0.0
8 |
9 |
10 |
11 | org.example
12 | sample-library
13 | 1.0.0
14 |
15 |
16 |
17 |
18 |
19 | blah
20 | uri/to/changes.diff
21 |
22 |
23 |
24 | JIRA-17240
25 | Great new feature that does something
26 |
27 | Acme Org
28 | https://issues.acme.org/17240
29 |
30 |
31 |
32 |
33 |
34 |
35 | blah
36 | uri/to/changes.diff
37 |
38 |
39 |
40 | CVE-2019-9997
41 | CVE-2019-9997
42 | blah blah
43 |
44 | NVD
45 | https://nvd.nist.gov/vuln/detail/CVE-2019-9997
46 |
47 |
48 | http://some/other/site-1
49 | http://some/other/site-2
50 |
51 |
52 |
53 | JIRA-874319
54 | Enable to do something
55 |
56 | Example Org
57 | https://issues.example.org/874319
58 |
59 |
60 | http://some/other/site-1
61 | http://some/other/site-2
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/testdata/valid-patch.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "group": "com.acme",
10 | "name": "sample-library",
11 | "version": "1.0.0",
12 | "pedigree": {
13 | "ancestors": [
14 | {
15 | "type": "library",
16 | "group": "org.example",
17 | "name": "sample-library",
18 | "version": "1.0.0"
19 | }
20 | ],
21 | "patches": [
22 | {
23 | "type": "unofficial",
24 | "diff": {
25 | "text": {
26 | "contentType": "text/plain",
27 | "encoding": "base64",
28 | "content": "blah"
29 | },
30 | "url": "uri/to/changes.diff"
31 | },
32 | "resolves": [
33 | {
34 | "type": "enhancement",
35 | "id": "JIRA-17240",
36 | "description": "Great new feature that does something",
37 | "source": {
38 | "name": "Acme Org",
39 | "url": "https://issues.acme.org/17240"
40 | }
41 | }
42 | ]
43 | },
44 | {
45 | "type": "backport",
46 | "diff": {
47 | "text": {
48 | "contentType": "text/plain",
49 | "encoding": "base64",
50 | "content": "blah"
51 | },
52 | "url": "uri/to/changes.diff"
53 | },
54 | "resolves": [
55 | {
56 | "type": "security",
57 | "id": "CVE-2019-9997",
58 | "name": "CVE-2019-9997",
59 | "description": "blah blah",
60 | "source": {
61 | "name": "NVD",
62 | "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9997"
63 | },
64 | "references": [
65 | "http://some/other/site-1",
66 | "http://some/other/site-2"
67 | ]
68 | },
69 | {
70 | "type": "defect",
71 | "id": "JIRA-874319",
72 | "description": "Enable to do something",
73 | "source": {
74 | "name": "Example Org",
75 | "url": "https://issues.example.org/874319"
76 | },
77 | "references": [
78 | "http://some/other/site-1",
79 | "http://some/other/site-2"
80 | ]
81 | }
82 | ]
83 | }
84 | ]
85 | }
86 | }
87 | ]
88 | }
89 |
--------------------------------------------------------------------------------
/testdata/valid-service.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "bom-ref": "pkg:npm/acme/component@1.0.0",
9 | "type": "library",
10 | "publisher": "Acme Inc",
11 | "group": "com.acme",
12 | "name": "stock-java-client",
13 | "version": "1.0.12",
14 | "hashes": [
15 | {
16 | "alg": "SHA-1",
17 | "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a"
18 | }
19 | ],
20 | "licenses": [
21 | {
22 | "license": {
23 | "id": "Apache-2.0"
24 | }
25 | }
26 | ],
27 | "purl": "pkg:maven/com.acme/stock-java-client@1.0.12"
28 | }
29 | ],
30 | "services": [
31 | {
32 | "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8",
33 | "provider": {
34 | "name": "Partner Org",
35 | "url": [
36 | "https://partner.org"
37 | ],
38 | "contact": [
39 | {
40 | "name": "Support",
41 | "email": "support@partner.com",
42 | "phone": "800-555-1212"
43 | }
44 | ]
45 | },
46 | "group": "org.partner",
47 | "name": "Stock ticker service",
48 | "version": "2020-Q2",
49 | "description": "Provides real-time stock information",
50 | "endpoints": [
51 | "https://partner.org/api/v1/lookup",
52 | "https://partner.org/api/v1/stock"
53 | ],
54 | "authenticated": true,
55 | "x-trust-boundary": true,
56 | "data": [
57 | {
58 | "classification": "PII",
59 | "flow": "inbound"
60 | },
61 | {
62 | "classification": "PIFI",
63 | "flow": "outbound"
64 | },
65 | {
66 | "classification": "pubic",
67 | "flow": "bi-directional"
68 | },
69 | {
70 | "classification": "partner-data",
71 | "flow": "unknown"
72 | }
73 | ],
74 | "licenses": [
75 | {
76 | "license": {
77 | "name": "Partner license"
78 | }
79 | }
80 | ],
81 | "externalReferences": [
82 | {
83 | "type": "website",
84 | "url": "http://partner.org"
85 | },
86 | {
87 | "type": "documentation",
88 | "url": "http://api.partner.org/swagger"
89 | }
90 | ]
91 | }
92 | ],
93 | "dependencies": [
94 | {
95 | "ref": "pkg:maven/com.acme/stock-java-client@1.0.12",
96 | "dependsOn": [
97 | "b2a46a4b-8367-4bae-9820-95557cfe03a8"
98 | ]
99 | }
100 | ]
101 | }
102 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-patch.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "library",
9 | "group": "com.acme",
10 | "name": "sample-library",
11 | "version": "1.0.0",
12 | "pedigree": {
13 | "ancestors": [
14 | {
15 | "type": "library",
16 | "group": "org.example",
17 | "name": "sample-library",
18 | "version": "1.0.0"
19 | }
20 | ],
21 | "patches": [
22 | {
23 | "diff": {
24 | "text": {
25 | "content": "blah",
26 | "contentType": "text/plain",
27 | "encoding": "base64"
28 | },
29 | "url": "uri/to/changes.diff"
30 | },
31 | "resolves": [
32 | {
33 | "id": "JIRA-17240",
34 | "description": "Great new feature that does something",
35 | "source": {
36 | "name": "Acme Org",
37 | "url": "https://issues.acme.org/17240"
38 | },
39 | "type": "enhancement"
40 | }
41 | ],
42 | "type": "unofficial"
43 | },
44 | {
45 | "diff": {
46 | "text": {
47 | "content": "blah",
48 | "contentType": "text/plain",
49 | "encoding": "base64"
50 | },
51 | "url": "uri/to/changes.diff"
52 | },
53 | "resolves": [
54 | {
55 | "id": "CVE-2019-9997",
56 | "name": "CVE-2019-9997",
57 | "description": "blah blah",
58 | "source": {
59 | "name": "NVD",
60 | "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9997"
61 | },
62 | "references": [
63 | "http://some/other/site-1",
64 | "http://some/other/site-2"
65 | ],
66 | "type": "security"
67 | },
68 | {
69 | "id": "JIRA-874319",
70 | "description": "Enable to do something",
71 | "source": {
72 | "name": "Example Org",
73 | "url": "https://issues.example.org/874319"
74 | },
75 | "references": [
76 | "http://some/other/site-1",
77 | "http://some/other/site-2"
78 | ],
79 | "type": "defect"
80 | }
81 | ],
82 | "type": "backport"
83 | }
84 | ]
85 | }
86 | }
87 | ]
88 | }
89 |
90 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-service.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "bom-ref": "pkg:npm/acme/component@1.0.0",
9 | "type": "library",
10 | "publisher": "Acme Inc",
11 | "group": "com.acme",
12 | "name": "stock-java-client",
13 | "version": "1.0.12",
14 | "hashes": [
15 | {
16 | "alg": "SHA-1",
17 | "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a"
18 | }
19 | ],
20 | "licenses": [
21 | {
22 | "license": {
23 | "id": "Apache-2.0"
24 | }
25 | }
26 | ],
27 | "purl": "pkg:maven/com.acme/stock-java-client@1.0.12"
28 | }
29 | ],
30 | "services": [
31 | {
32 | "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8",
33 | "provider": {
34 | "name": "Partner Org",
35 | "url": [
36 | "https://partner.org"
37 | ],
38 | "contact": [
39 | {
40 | "name": "Support",
41 | "email": "support@partner.com",
42 | "phone": "800-555-1212"
43 | }
44 | ]
45 | },
46 | "group": "org.partner",
47 | "name": "Stock ticker service",
48 | "version": "2020-Q2",
49 | "description": "Provides real-time stock information",
50 | "endpoints": [
51 | "https://partner.org/api/v1/lookup",
52 | "https://partner.org/api/v1/stock"
53 | ],
54 | "authenticated": true,
55 | "x-trust-boundary": true,
56 | "data": [
57 | {
58 | "flow": "inbound",
59 | "classification": "PII"
60 | },
61 | {
62 | "flow": "outbound",
63 | "classification": "PIFI"
64 | },
65 | {
66 | "flow": "bi-directional",
67 | "classification": "pubic"
68 | },
69 | {
70 | "flow": "unknown",
71 | "classification": "partner-data"
72 | }
73 | ],
74 | "licenses": [
75 | {
76 | "license": {
77 | "name": "Partner license"
78 | }
79 | }
80 | ],
81 | "externalReferences": [
82 | {
83 | "url": "http://partner.org",
84 | "type": "website"
85 | },
86 | {
87 | "url": "http://api.partner.org/swagger",
88 | "type": "documentation"
89 | }
90 | ]
91 | }
92 | ],
93 | "dependencies": [
94 | {
95 | "ref": "pkg:maven/com.acme/stock-java-client@1.0.12",
96 | "dependsOn": [
97 | "b2a46a4b-8367-4bae-9820-95557cfe03a8"
98 | ]
99 | }
100 | ]
101 | }
102 |
103 |
--------------------------------------------------------------------------------
/testdata/valid-service.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.acme
6 | stock-java-client
7 | 1.0.12
8 |
9 | e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a
10 |
11 |
12 |
13 | Apache-2.0
14 |
15 |
16 | pkg:maven/com.acme/stock-java-client@1.0.12
17 |
18 |
19 |
20 |
21 |
22 | Partner Org
23 | https://partner.org
24 |
25 | Support
26 | support@partner
27 | 800-555-1212
28 |
29 |
30 | org.partner
31 | Stock ticker service
32 | 2020-Q2
33 | Provides real-time stock information
34 |
35 | https://partner.org/api/v1/lookup
36 | https://partner.org/api/v1/stock
37 |
38 | true
39 | true
40 |
41 | PII
42 | PIFI
43 | pubic
44 | partner-data
45 |
46 |
47 |
48 | Partner license
49 |
50 |
51 |
52 |
53 | http://partner.org
54 |
55 |
56 | http://api.partner.org/swagger
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/roundtrip_test.go:
--------------------------------------------------------------------------------
1 | // This file is part of CycloneDX Go
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the “License”);
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an “AS IS” BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // SPDX-License-Identifier: Apache-2.0
16 | // Copyright (c) OWASP Foundation. All Rights Reserved.
17 |
18 | package cyclonedx
19 |
20 | import (
21 | "bytes"
22 | "os"
23 | "path/filepath"
24 | "testing"
25 |
26 | "github.com/stretchr/testify/assert"
27 | "github.com/stretchr/testify/require"
28 | )
29 |
30 | func TestRoundTripJSON(t *testing.T) {
31 | bomFilePaths, err := filepath.Glob("./testdata/*.json")
32 | require.NoError(t, err)
33 |
34 | for _, bomFilePath := range bomFilePaths {
35 | t.Run(filepath.Base(bomFilePath), func(t *testing.T) {
36 | // Read original BOM JSON
37 | inputFile, err := os.Open(bomFilePath)
38 | require.NoError(t, err)
39 |
40 | // Decode BOM
41 | var bom BOM
42 | require.NoError(t, NewBOMDecoder(inputFile, BOMFileFormatJSON).Decode(&bom))
43 | inputFile.Close()
44 |
45 | // Prepare encoding destination
46 | buf := bytes.Buffer{}
47 |
48 | // Encode BOM again
49 | err = NewBOMEncoder(&buf, BOMFileFormatJSON).
50 | SetPretty(true).
51 | Encode(&bom)
52 | require.NoError(t, err)
53 |
54 | // Sanity checks: BOM has to be valid
55 | assertValidBOM(t, buf.Bytes(), BOMFileFormatJSON, SpecVersion1_6)
56 |
57 | // Compare with snapshot
58 | assert.NoError(t, snapShooter.SnapshotMulti(filepath.Base(bomFilePath), buf.String()))
59 | })
60 | }
61 | }
62 |
63 | func TestRoundTripXML(t *testing.T) {
64 | bomFilePaths, err := filepath.Glob("./testdata/*.xml")
65 | require.NoError(t, err)
66 |
67 | for _, bomFilePath := range bomFilePaths {
68 | t.Run(filepath.Base(bomFilePath), func(t *testing.T) {
69 | // Read original BOM XML
70 | inputFile, err := os.Open(bomFilePath)
71 | require.NoError(t, err)
72 |
73 | // Decode BOM
74 | var bom BOM
75 | require.NoError(t, NewBOMDecoder(inputFile, BOMFileFormatXML).Decode(&bom))
76 | inputFile.Close()
77 |
78 | // Prepare encoding destination
79 | buf := bytes.Buffer{}
80 |
81 | // Encode BOM again
82 | err = NewBOMEncoder(&buf, BOMFileFormatXML).
83 | SetPretty(true).
84 | Encode(&bom)
85 | require.NoError(t, err)
86 |
87 | // Sanity check: BOM has to be valid
88 | assertValidBOM(t, buf.Bytes(), BOMFileFormatXML, SpecVersion1_6)
89 |
90 | // Compare with snapshot
91 | assert.NoError(t, snapShooter.SnapshotMulti(filepath.Base(bomFilePath), buf.String()))
92 | })
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/testdata/valid-annotation.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "bom-ref": "component-a",
9 | "type": "library",
10 | "name": "Component A",
11 | "version": "1.0.0"
12 | }
13 | ],
14 | "annotations": [
15 | {
16 | "bom-ref": "annotation-1",
17 | "subjects": [
18 | "component-a"
19 | ],
20 | "annotator": {
21 | "organization": {
22 | "name": "Acme, Inc.",
23 | "url": [
24 | "https://example.com"
25 | ],
26 | "contact": [
27 | {
28 | "name": "Acme Professional Services",
29 | "email": "professional.services@example.com"
30 | }
31 | ]
32 | }
33 | },
34 | "timestamp": "2022-01-01T00:00:00Z",
35 | "text": "This is a sample annotation made by an organization"
36 | },
37 | {
38 | "bom-ref": "annotation-2",
39 | "subjects": [
40 | "component-a"
41 | ],
42 | "annotator": {
43 | "individual": {
44 | "name": "Samantha Wright",
45 | "email": "samantha.wright@example.com",
46 | "phone": "800-555-1212"
47 | }
48 | },
49 | "timestamp": "2022-01-01T00:00:00Z",
50 | "text": "This is a sample annotation made by a person"
51 | },
52 | {
53 | "bom-ref": "annotation-3",
54 | "subjects": [
55 | "component-a"
56 | ],
57 | "annotator": {
58 | "component": {
59 | "type": "application",
60 | "name": "Awesome Tool",
61 | "version": "9.1.2"
62 | }
63 | },
64 | "timestamp": "2022-01-01T00:00:00Z",
65 | "text": "This is a sample annotation made by a component"
66 | },
67 | {
68 | "bom-ref": "annotation-4",
69 | "subjects": [
70 | "component-a"
71 | ],
72 | "annotator": {
73 | "service": {
74 | "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8",
75 | "provider": {
76 | "name": "Partner Org",
77 | "url": [
78 | "https://partner.org"
79 | ]
80 | },
81 | "group": "org.partner",
82 | "name": "BOM Annotation Service",
83 | "version": "2020-Q2",
84 | "endpoints": [
85 | "https://partner.org/api/v1/inspect",
86 | "https://partner.org/api/v1/annotate"
87 | ],
88 | "authenticated": true,
89 | "x-trust-boundary": true,
90 | "data": [
91 | {
92 | "classification": "public",
93 | "flow": "bi-directional"
94 | }
95 | ]
96 | }
97 | },
98 | "timestamp": "2022-01-01T00:00:00Z",
99 | "text": "This is a sample annotation made by a service"
100 | }
101 | ]
102 | }
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestXmlBOMEncoder_EncodeVersion-func1-1.0.bom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Acme Inc
6 | com.acme
7 | tomcat-catalina
8 | 9.0.14
9 | Modified version of Apache Catalina
10 | required
11 |
12 | 3942447fac867ae5cdb3229b658f4d48
13 | e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a
14 | f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b
15 | e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282
16 |
17 |
18 |
19 | Apache-2.0
20 |
21 |
22 | pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar
23 | false
24 |
25 |
26 | org.example
27 | mylibrary
28 | 1.0.0
29 | required
30 |
31 | 2342c2eaf1feb9a80195dbaddf2ebaa3
32 | 68b78babe00a053f9e35ec6a2d9080f5b90122b0
33 | 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313
34 | 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef
35 |
36 | Copyright Example Inc. All rights reserved.
37 | cpe:/a:example:myapplication:1.0.0
38 | pkg:maven/com.example/myapplication@1.0.0?packaging=war
39 | false
40 |
41 |
42 | com.example
43 | myframework
44 | 1.0.0
45 | Example Inc, enterprise framework
46 | required
47 |
48 | cfcb0b64aacd2f81c1cd546543de965a
49 | 7fbeef2346c45d565c3341f037bce4e088af8a52
50 | 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1
51 | 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79
52 |
53 |
54 |
55 | Some random license
56 |
57 |
58 | pkg:maven/com.example/myframework@1.0.0?packaging=war
59 | false
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/decode_test.go:
--------------------------------------------------------------------------------
1 | // This file is part of CycloneDX Go
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the “License”);
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an “AS IS” BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // SPDX-License-Identifier: Apache-2.0
16 | // Copyright (c) OWASP Foundation. All Rights Reserved.
17 |
18 | package cyclonedx
19 |
20 | import (
21 | "strings"
22 | "testing"
23 |
24 | "github.com/stretchr/testify/assert"
25 | "github.com/stretchr/testify/require"
26 | )
27 |
28 | func TestNewBOMDecoder(t *testing.T) {
29 | assert.IsType(t, &jsonBOMDecoder{}, NewBOMDecoder(nil, BOMFileFormatJSON))
30 | assert.IsType(t, &xmlBOMDecoder{}, NewBOMDecoder(nil, BOMFileFormatXML))
31 | }
32 |
33 | func TestXmlBOMDecoder_Decode_InvalidXML(t *testing.T) {
34 | var bom BOM
35 | err := NewBOMDecoder(strings.NewReader("invalid"), BOMFileFormatXML).Decode(&bom)
36 | require.Error(t, err)
37 | }
38 |
39 | func TestJsonBOMDecoder_Decode_InvalidJson(t *testing.T) {
40 | var bom BOM
41 | err := NewBOMDecoder(strings.NewReader("{}invalid"), BOMFileFormatJSON).Decode(&bom)
42 | require.Error(t, err)
43 | }
44 |
45 | func TestXmlBOMDecoder_Decode(t *testing.T) {
46 | t.Run("ShouldSetSpecVersion", func(t *testing.T) {
47 | testCases := []struct {
48 | bomContent string
49 | specVersion SpecVersion
50 | }{
51 | {
52 | bomContent: ``,
53 | specVersion: SpecVersion1_0,
54 | },
55 | {
56 | bomContent: ``,
57 | specVersion: SpecVersion1_1,
58 | },
59 | {
60 | bomContent: ``,
61 | specVersion: SpecVersion1_2,
62 | },
63 | {
64 | bomContent: ``,
65 | specVersion: SpecVersion1_3,
66 | },
67 | {
68 | bomContent: ``,
69 | specVersion: SpecVersion1_4,
70 | },
71 | {
72 | bomContent: ``,
73 | specVersion: SpecVersion(0),
74 | },
75 | }
76 |
77 | for _, tc := range testCases {
78 | t.Run(tc.specVersion.String(), func(t *testing.T) {
79 | var bom BOM
80 | err := NewBOMDecoder(strings.NewReader(tc.bomContent), BOMFileFormatXML).Decode(&bom)
81 | require.NoError(t, err)
82 | require.Equal(t, tc.specVersion, bom.SpecVersion)
83 | })
84 | }
85 | })
86 | }
87 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-annotation.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "bom-ref": "component-a",
9 | "type": "library",
10 | "name": "Component A",
11 | "version": "1.0.0"
12 | }
13 | ],
14 | "annotations": [
15 | {
16 | "bom-ref": "annotation-1",
17 | "subjects": [
18 | "component-a"
19 | ],
20 | "annotator": {
21 | "organization": {
22 | "name": "Acme, Inc.",
23 | "url": [
24 | "https://example.com"
25 | ],
26 | "contact": [
27 | {
28 | "name": "Acme Professional Services",
29 | "email": "professional.services@example.com"
30 | }
31 | ]
32 | }
33 | },
34 | "timestamp": "2022-01-01T00:00:00Z",
35 | "text": "This is a sample annotation made by an organization"
36 | },
37 | {
38 | "bom-ref": "annotation-2",
39 | "subjects": [
40 | "component-a"
41 | ],
42 | "annotator": {
43 | "individual": {
44 | "name": "Samantha Wright",
45 | "email": "samantha.wright@example.com",
46 | "phone": "800-555-1212"
47 | }
48 | },
49 | "timestamp": "2022-01-01T00:00:00Z",
50 | "text": "This is a sample annotation made by a person"
51 | },
52 | {
53 | "bom-ref": "annotation-3",
54 | "subjects": [
55 | "component-a"
56 | ],
57 | "annotator": {
58 | "component": {
59 | "type": "application",
60 | "name": "Awesome Tool",
61 | "version": "9.1.2"
62 | }
63 | },
64 | "timestamp": "2022-01-01T00:00:00Z",
65 | "text": "This is a sample annotation made by a component"
66 | },
67 | {
68 | "bom-ref": "annotation-4",
69 | "subjects": [
70 | "component-a"
71 | ],
72 | "annotator": {
73 | "service": {
74 | "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8",
75 | "provider": {
76 | "name": "Partner Org",
77 | "url": [
78 | "https://partner.org"
79 | ]
80 | },
81 | "group": "org.partner",
82 | "name": "BOM Annotation Service",
83 | "version": "2020-Q2",
84 | "endpoints": [
85 | "https://partner.org/api/v1/inspect",
86 | "https://partner.org/api/v1/annotate"
87 | ],
88 | "authenticated": true,
89 | "x-trust-boundary": true,
90 | "data": [
91 | {
92 | "flow": "bi-directional",
93 | "classification": "public"
94 | }
95 | ]
96 | }
97 | },
98 | "timestamp": "2022-01-01T00:00:00Z",
99 | "text": "This is a sample annotation made by a service"
100 | }
101 | ]
102 | }
103 |
104 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-annotation.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Component A
6 | 1.0.0
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Acme, Inc.
17 | https://example.com
18 |
19 | Acme Professional Services
20 | professional.services@example.com
21 |
22 |
23 |
24 | 2020-04-07T07:01:00Z
25 | This is a sample annotation made by an organization
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | Samantha Wright
34 | samantha.wright@example.com
35 | 800-555-1212
36 |
37 |
38 | 2020-04-07T07:01:00Z
39 | This is a sample annotation made by an person
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | Awesome Tool
48 | 9.1.2
49 |
50 |
51 | 2020-04-07T07:01:00Z
52 | This is a sample annotation made by a component
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | Partner Org
62 | https://partner.org
63 |
64 | Support
65 | support@partner
66 | 800-555-1212
67 |
68 |
69 | org.partner
70 | BOM Annotation Service
71 | 2020-Q2
72 |
73 | https://partner.org/api/v1/inspect
74 | https://partner.org/api/v1/annotate
75 |
76 | true
77 | true
78 |
79 | pubic
80 |
81 |
82 |
83 | 2020-04-07T07:01:00Z
84 | This is a sample annotation made by a service
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/testdata/valid-patch.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.acme
6 | sample-library
7 | 1.0.0
8 |
9 |
10 |
11 | org.example
12 | sample-library
13 | 1.0.0
14 |
15 |
16 |
17 |
18 |
19 | blah
20 | uri/to/changes.diff
21 |
22 |
23 |
24 | JIRA-17240
25 | Great new feature that does something
26 |
27 | Acme Org
28 | https://issues.acme.org/17240
29 |
30 |
31 |
32 |
33 |
34 |
35 | blah
36 | uri/to/changes.diff
37 |
38 |
39 |
40 | CVE-2019-9997
41 | CVE-2019-9997
42 | blah blah
43 |
44 | NVD
45 | https://nvd.nist.gov/vuln/detail/CVE-2019-9997
46 |
47 |
48 | http://some/other/site-1
49 | http://some/other/site-2
50 |
51 |
52 |
53 | JIRA-874319
54 | Enable to do something
55 |
56 | Example Org
57 | https://issues.example.org/874319
58 |
59 |
60 | http://some/other/site-1
61 | http://some/other/site-2
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cyclonedx-go
2 |
3 | [](https://github.com/CycloneDX/cyclonedx-go/actions/workflows/ci.yml)
4 | [](https://goreportcard.com/report/github.com/CycloneDX/cyclonedx-go)
5 | [](https://pkg.go.dev/github.com/CycloneDX/cyclonedx-go)
6 | [](LICENSE)
7 | [](https://cyclonedx.org/)
8 | [](https://cyclonedx.org/slack/invite)
9 | [](https://groups.io/g/CycloneDX)
10 | [](https://twitter.com/CycloneDX_Spec)
11 |
12 | *cyclonedx-go is a Go library to consume and produce CycloneDX Software Bill of Materials (SBOM)*
13 |
14 | > If you just want to create BOMs for your Go projects, see [*cyclonedx-gomod*](https://github.com/CycloneDX/cyclonedx-gomod)
15 |
16 | ## Installation
17 |
18 | ```
19 | go get github.com/CycloneDX/cyclonedx-go
20 | ```
21 |
22 | ## Usage
23 |
24 | Please refer to the module's [documentation](https://pkg.go.dev/github.com/CycloneDX/cyclonedx-go#section-documentation).
25 | Also, checkout the [`examples`](./example_test.go) to get an idea of how this library may be used.
26 |
27 | ## Compatibility
28 |
29 | | cyclonedx-go versions | Supported Go versions | Supported CycloneDX spec |
30 | |:---------------------:|:---------------------:|:------------------------:|
31 | | < v0.4.0 | 1.14+ | 1.2 |
32 | | == v0.4.0 | 1.14+ | 1.3 |
33 | | >= v0.5.0, < v0.7.0 | 1.15+ | 1.4 |
34 | | >= v0.7.0, < v0.8.0 | 1.17+ | 1.0-1.4 |
35 | | == v0.8.0 | 1.18+ | 1.0-1.5 |
36 | | >= v0.9.0 | 1.20+ | 1.0-1.6 |
37 |
38 | We're aiming to support all [officially supported](https://golang.org/doc/devel/release.html#policy) Go versions, plus
39 | an additional older version.
40 |
41 | Prior to v0.7.0, this library only supported the latest version of the CycloneDX specification. While it is generally
42 | possible to *read* BOMs of an older spec, *writing* would exclusively produce BOMs conforming to the latest supported spec.
43 |
44 | Starting with v0.7.0, writing BOMs conforming to all previous version of the spec is also possible.
45 |
46 | ## Copyright & License
47 |
48 | CycloneDX Go is Copyright (c) OWASP Foundation. All Rights Reserved.
49 |
50 | Permission to modify and redistribute is granted under the terms of the Apache 2.0 license.
51 | See the [LICENSE](./LICENSE) file for the full license.
52 |
53 | ## Contributing
54 |
55 | [](https://gitpod.io/#https://github.com/CycloneDX/cyclonedx-go)
56 |
57 | Pull requests are welcome. But please read the
58 | [CycloneDX contributing guidelines](https://github.com/CycloneDX/.github/blob/master/CONTRIBUTING.md) first.
59 |
60 | It is generally expected that pull requests will include relevant tests. Tests are automatically run against all
61 | supported Go versions (see [Compatibility](#compatibility)) for every pull request.
62 |
--------------------------------------------------------------------------------
/testdata/valid-evidence.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "group": "com.google.code.findbugs",
10 | "name": "findbugs-project",
11 | "version": "3.0.0",
12 | "licenses": [
13 | {
14 | "license": {
15 | "id": "LGPL-3.0-or-later",
16 | "url": "https://www.gnu.org/licenses/lgpl-3.0-standalone.html"
17 | }
18 | }
19 | ],
20 | "purl": "pkg:maven/com.google.code.findbugs/findbugs-project@3.0.0",
21 | "evidence": {
22 | "identity": [
23 | {
24 | "field": "purl",
25 | "confidence": 1,
26 | "methods": [
27 | {
28 | "technique": "filename",
29 | "confidence": 0.1,
30 | "value": "findbugs-project-3.0.0.jar"
31 | },
32 | {
33 | "technique": "ast-fingerprint",
34 | "confidence": 0.9,
35 | "value": "61e4bc08251761c3a73b606b9110a65899cb7d44f3b14c81ebc1e67c98e1d9ab"
36 | },
37 | {
38 | "technique": "hash-comparison",
39 | "confidence": 0.7,
40 | "value": "7c547a9d67cc7bc315c93b6e2ff8e4b6b41ae5be454ac249655ecb5ca2a85abf"
41 | }
42 | ],
43 | "tools": [
44 | "bom-ref-of-tool-that-performed-analysis"
45 | ]
46 | }
47 | ],
48 | "occurrences": [
49 | {
50 | "bom-ref": "d6bf237e-4e11-4713-9f62-56d18d5e2079",
51 | "location": "/path/to/component"
52 | },
53 | {
54 | "bom-ref": "b574d5d1-e3cf-4dcd-9ba5-f3507eb1b175",
55 | "location": "/another/path/to/component"
56 | }
57 | ],
58 | "callstack": {
59 | "frames": [
60 | {
61 |
62 | "package": "com.apache.logging.log4j.core",
63 | "module": "Logger.class",
64 | "function": "logMessage",
65 | "parameters": [
66 | "com.acme.HelloWorld", "Level.INFO", "null", "Hello World"
67 | ],
68 | "line": 150,
69 | "column": 17,
70 | "fullFilename": "/path/to/log4j-core-2.14.0.jar!/org/apache/logging/log4j/core/Logger.class"
71 | },
72 | {
73 | "module": "HelloWorld.class",
74 | "function": "main",
75 | "line": 20,
76 | "column": 12,
77 | "fullFilename": "/path/to/HelloWorld.class"
78 | }
79 | ]
80 | },
81 | "licenses": [
82 | {
83 | "license": {
84 | "id": "Apache-2.0",
85 | "url": "http://www.apache.org/licenses/LICENSE-2.0"
86 | }
87 | },
88 | {
89 | "license": {
90 | "id": "LGPL-2.1-only",
91 | "url": "https://opensource.org/licenses/LGPL-2.1"
92 | }
93 | }
94 | ],
95 | "copyright": [
96 | {
97 | "text": "Copyright 2012 Google Inc. All Rights Reserved."
98 | },
99 | {
100 | "text": "Copyright (C) 2004,2005 Dave Brosius "
101 | },
102 | {
103 | "text": "Copyright (C) 2005 William Pugh"
104 | },
105 | {
106 | "text": "Copyright (C) 2004,2005 University of Maryland"
107 | }
108 | ]
109 | }
110 | }
111 | ]
112 | }
113 |
--------------------------------------------------------------------------------
/testdata/valid-annotation.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Component A
6 | 1.0.0
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Acme, Inc.
17 | https://example.com
18 |
19 | Acme Professional Services
20 | professional.services@example.com
21 |
22 |
23 |
24 | 2020-04-07T07:01:00Z
25 | This is a sample annotation made by an organization
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | Samantha Wright
34 | samantha.wright@example.com
35 | 800-555-1212
36 |
37 |
38 | 2020-04-07T07:01:00Z
39 | This is a sample annotation made by an person
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | Awesome Tool
48 | 9.1.2
49 |
50 |
51 | 2020-04-07T07:01:00Z
52 | This is a sample annotation made by a component
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | Partner Org
62 | https://partner.org
63 |
64 | Support
65 | support@partner
66 | 800-555-1212
67 |
68 |
69 | org.partner
70 | BOM Annotation Service
71 | 2020-Q2
72 |
73 | https://partner.org/api/v1/inspect
74 | https://partner.org/api/v1/annotate
75 |
76 | true
77 | true
78 |
79 | pubic
80 |
81 |
82 |
83 | 2020-04-07T07:01:00Z
84 | This is a sample annotation made by a service
85 |
86 |
87 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-evidence.json:
--------------------------------------------------------------------------------
1 | {
2 | "bomFormat": "CycloneDX",
3 | "specVersion": "1.6",
4 | "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5 | "version": 1,
6 | "components": [
7 | {
8 | "type": "application",
9 | "group": "com.google.code.findbugs",
10 | "name": "findbugs-project",
11 | "version": "3.0.0",
12 | "licenses": [
13 | {
14 | "license": {
15 | "id": "LGPL-3.0-or-later",
16 | "url": "https://www.gnu.org/licenses/lgpl-3.0-standalone.html"
17 | }
18 | }
19 | ],
20 | "purl": "pkg:maven/com.google.code.findbugs/findbugs-project@3.0.0",
21 | "evidence": {
22 | "identity": [
23 | {
24 | "field": "purl",
25 | "confidence": 1,
26 | "methods": [
27 | {
28 | "technique": "filename",
29 | "confidence": 0.1,
30 | "value": "findbugs-project-3.0.0.jar"
31 | },
32 | {
33 | "technique": "ast-fingerprint",
34 | "confidence": 0.9,
35 | "value": "61e4bc08251761c3a73b606b9110a65899cb7d44f3b14c81ebc1e67c98e1d9ab"
36 | },
37 | {
38 | "technique": "hash-comparison",
39 | "confidence": 0.7,
40 | "value": "7c547a9d67cc7bc315c93b6e2ff8e4b6b41ae5be454ac249655ecb5ca2a85abf"
41 | }
42 | ],
43 | "tools": [
44 | "bom-ref-of-tool-that-performed-analysis"
45 | ]
46 | }
47 | ],
48 | "occurrences": [
49 | {
50 | "bom-ref": "d6bf237e-4e11-4713-9f62-56d18d5e2079",
51 | "location": "/path/to/component"
52 | },
53 | {
54 | "bom-ref": "b574d5d1-e3cf-4dcd-9ba5-f3507eb1b175",
55 | "location": "/another/path/to/component"
56 | }
57 | ],
58 | "callstack": {
59 | "frames": [
60 | {
61 | "package": "com.apache.logging.log4j.core",
62 | "module": "Logger.class",
63 | "function": "logMessage",
64 | "parameters": [
65 | "com.acme.HelloWorld",
66 | "Level.INFO",
67 | "null",
68 | "Hello World"
69 | ],
70 | "line": 150,
71 | "column": 17,
72 | "fullFilename": "/path/to/log4j-core-2.14.0.jar!/org/apache/logging/log4j/core/Logger.class"
73 | },
74 | {
75 | "module": "HelloWorld.class",
76 | "function": "main",
77 | "line": 20,
78 | "column": 12,
79 | "fullFilename": "/path/to/HelloWorld.class"
80 | }
81 | ]
82 | },
83 | "licenses": [
84 | {
85 | "license": {
86 | "id": "Apache-2.0",
87 | "url": "http://www.apache.org/licenses/LICENSE-2.0"
88 | }
89 | },
90 | {
91 | "license": {
92 | "id": "LGPL-2.1-only",
93 | "url": "https://opensource.org/licenses/LGPL-2.1"
94 | }
95 | }
96 | ],
97 | "copyright": [
98 | {
99 | "text": "Copyright 2012 Google Inc. All Rights Reserved."
100 | },
101 | {
102 | "text": "Copyright (C) 2004,2005 Dave Brosius \u003cdbrosius@users.sourceforge.net\u003e"
103 | },
104 | {
105 | "text": "Copyright (C) 2005 William Pugh"
106 | },
107 | {
108 | "text": "Copyright (C) 2004,2005 University of Maryland"
109 | }
110 | ]
111 | }
112 | }
113 | ]
114 | }
115 |
116 |
--------------------------------------------------------------------------------
/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-evidence.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.google.code.findbugs
6 | findbugs-project
7 | 3.0.0
8 |
9 |
10 | LGPL-3.0-or-later
11 | https://www.gnu.org/licenses/lgpl-3.0-standalone.html
12 |
13 |
14 | pkg:maven/com.google.code.findbugs/findbugs-project@3.0.0
15 |
16 |
17 | purl
18 | 1
19 |
20 |
21 | filename
22 | 0.1
23 | findbugs-project-3.0.0.jar
24 |
25 |
26 | ast-fingerprint
27 | 0.9
28 | 61e4bc08251761c3a73b606b9110a65899cb7d44f3b14c81ebc1e67c98e1d9ab
29 |
30 |
31 | hash-comparison
32 | 0.7
33 | 7c547a9d67cc7bc315c93b6e2ff8e4b6b41ae5be454ac249655ecb5ca2a85abf
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | /path/to/component
43 |
44 |
45 | /another/path/to/component
46 |
47 |
48 |
49 |
50 |
51 | com.apache.logging.log4j.core
52 | Logger.class
53 | logMessage
54 |
55 | com.acme.HelloWorld
56 | Level.INFO
57 | null
58 | Hello World
59 |
60 | 150
61 | 17
62 | /path/to/log4j-core-2.14.0.jar!/org/apache/logging/log4j/core/Logger.class
63 |
64 |
65 | HelloWorld.class
66 | main
67 | 20
68 | 12
69 | /path/to/HelloWorld.class
70 |
71 |
72 |
73 |
74 |
75 | Apache-2.0
76 | http://www.apache.org/licenses/LICENSE-2.0
77 |
78 |
79 | LGPL-2.1-only
80 | https://opensource.org/licenses/LGPL-2.1
81 |
82 |
83 |
84 | Copyright 2012 Google Inc. All Rights Reserved.
85 | Copyright (C) 2004,2005 Dave Brosius <dbrosius@users.sourceforge.net>
86 | Copyright (C) 2005 William Pugh
87 | Copyright (C) 2004,2005 University of Maryland
88 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/encode.go:
--------------------------------------------------------------------------------
1 | // This file is part of CycloneDX Go
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the “License”);
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an “AS IS” BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | //
15 | // SPDX-License-Identifier: Apache-2.0
16 | // Copyright (c) OWASP Foundation. All Rights Reserved.
17 |
18 | package cyclonedx
19 |
20 | import (
21 | "encoding/json"
22 | "encoding/xml"
23 | "fmt"
24 | "io"
25 | )
26 |
27 | type BOMEncoder interface {
28 | // Encode encodes a given BOM.
29 | Encode(bom *BOM) error
30 |
31 | // EncodeVersion encodes a given BOM in a specific version of the specification.
32 | // Choosing a lower spec version than what the BOM was constructed for will result
33 | // in loss of information. The original BOM struct is guaranteed to not be modified.
34 | EncodeVersion(bom *BOM, version SpecVersion) error
35 |
36 | // SetPretty toggles prettified output.
37 | SetPretty(pretty bool) BOMEncoder
38 |
39 | // SetEscapeHTML toggles escaped HTML output.
40 | SetEscapeHTML(escapeHTML bool) BOMEncoder
41 | }
42 |
43 | func NewBOMEncoder(writer io.Writer, format BOMFileFormat) BOMEncoder {
44 | if format == BOMFileFormatJSON {
45 | return &jsonBOMEncoder{writer: writer, escapeHTML: true}
46 | }
47 | return &xmlBOMEncoder{writer: writer}
48 | }
49 |
50 | type jsonBOMEncoder struct {
51 | writer io.Writer
52 | pretty bool
53 | escapeHTML bool
54 | }
55 |
56 | // Encode implements the BOMEncoder interface.
57 | func (j jsonBOMEncoder) Encode(bom *BOM) error {
58 | if bom.SpecVersion < SpecVersion1_2 {
59 | return fmt.Errorf("json format is not supported for specification versions lower than %s", SpecVersion1_2)
60 | }
61 |
62 | encoder := json.NewEncoder(j.writer)
63 | encoder.SetEscapeHTML(j.escapeHTML)
64 | if j.pretty {
65 | encoder.SetIndent("", " ")
66 | }
67 |
68 | return encoder.Encode(bom)
69 | }
70 |
71 | // EncodeVersion implements the BOMEncoder interface.
72 | func (j jsonBOMEncoder) EncodeVersion(bom *BOM, specVersion SpecVersion) (err error) {
73 | bom, err = bom.copyAndConvert(specVersion)
74 | if err != nil {
75 | return
76 | }
77 |
78 | return j.Encode(bom)
79 | }
80 |
81 | // SetPretty implements the BOMEncoder interface.
82 | func (j *jsonBOMEncoder) SetPretty(pretty bool) BOMEncoder {
83 | j.pretty = pretty
84 | return j
85 | }
86 |
87 | // SetEscapeHTML implements the BOMEncoder interface.
88 | func (j *jsonBOMEncoder) SetEscapeHTML(escapeHTML bool) BOMEncoder {
89 | j.escapeHTML = escapeHTML
90 | return j
91 | }
92 |
93 | type xmlBOMEncoder struct {
94 | writer io.Writer
95 | pretty bool
96 | }
97 |
98 | // Encode implements the BOMEncoder interface.
99 | func (x xmlBOMEncoder) Encode(bom *BOM) error {
100 | if _, err := fmt.Fprintf(x.writer, xml.Header); err != nil {
101 | return err
102 | }
103 |
104 | encoder := xml.NewEncoder(x.writer)
105 | if x.pretty {
106 | encoder.Indent("", " ")
107 | }
108 |
109 | return encoder.Encode(bom)
110 | }
111 |
112 | // EncodeVersion implements the BOMEncoder interface.
113 | func (x xmlBOMEncoder) EncodeVersion(bom *BOM, specVersion SpecVersion) (err error) {
114 | bom, err = bom.copyAndConvert(specVersion)
115 | if err != nil {
116 | return
117 | }
118 |
119 | return x.Encode(bom)
120 | }
121 |
122 | // SetPretty implements the BOMEncoder interface.
123 | func (x *xmlBOMEncoder) SetPretty(pretty bool) BOMEncoder {
124 | x.pretty = pretty
125 | return x
126 | }
127 |
128 | // SetEscapeHTML implements the BOMEncoder interface.
129 | func (j *xmlBOMEncoder) SetEscapeHTML(escapeHTML bool) BOMEncoder {
130 | // NOOP -- XML always needs to escape HTML
131 | return j
132 | }
133 |
--------------------------------------------------------------------------------