sbom-utility icon indicating copy to clipboard operation
sbom-utility copied to clipboard

Add support for "legacy" and new `Tool` structure introduced in CycloneDX v1.5

Open mrutkows opened this issue 1 year ago • 1 comments

TODO: figure out how to support both current (object)/legacy(array) tools in Metadata.Tools field. Currently, we use an interface{} placeholder in our struct bindings which is NOT ideal for many things we are trying to do with entity hashing, normalization, etc.

type CDXToolLegacy struct {
    Name               string                  `json:"name,omitempty"`
    Version            string                  `json:"version,omitempty"`
    Vendor             string                  `json:"vendor,omitempty"`
    Hashes             *[]CDXHash              `json:"hashes,omitempty"`
    ExternalReferences *[]CDXExternalReference `json:"externalReferences,omitempty"`
}
type CDXTools struct {
  Components *[]CDXComponent `json:"components,omitempty"`
  Services   *[]CDXService   `json:"services,omitempty"`
}

which are both referenced from:

type CDXMetadata struct {
	Timestamp    string                      `json:"timestamp,omitempty" scvs:"bom:core:timestamp"` // urn:owasp:scvs:bom:core:timestamp
	Tools        interface{}                 `json:"tools,omitempty"`                               // v1.2: added; v1.5: "tools" is now an interface{}
	Authors      *[]CDXOrganizationalContact `json:"authors,omitempty"`
	Component    *CDXComponent               `json:"component,omitempty"`
	Manufacturer *CDXOrganizationalEntity    `json:"manufacture,omitempty"` // NOTE: Typo is in spec.
	Supplier     *CDXOrganizationalEntity    `json:"supplier,omitempty"`
	Licenses     *[]CDXLicenseChoice         `json:"licenses,omitempty"`    // v1.3 added
	Properties   *[]CDXProperty              `json:"properties,omitempty"`  // v1.3 added
	Lifecycles   *[]CDXLifecycle             `json:"lifecycles,omitempty"`  // v1.5 added
	Manufacture  *CDXOrganizationalEntity    `json:"manufacture,omitempty"` // v1.5: deprecated
}

See: https://stackoverflow.com/questions/47057240/parsing-multiple-json-types-into-the-same-struct on possible ways to do this efficiently...

mrutkows avatar May 08 '24 19:05 mrutkows

Note: we already handle the marshaling:

	if IsInterfaceASlice(value.Tools) {
		arrayTools, ok := value.Tools.([]CDXLegacyCreationTool)
		if ok && len(arrayTools) > 0 {
			temp["tools"] = arrayTools
		}
	} else {
		tools, ok := value.Tools.(CDXCreationTools)
		if ok {
			temp["tools"] = tools
		}
	}

mrutkows avatar May 09 '24 13:05 mrutkows