@@ -15,6 +15,27 @@ const (
1515 SBOM_SPDX = "SPDX"
1616)
1717
18+ // ValidationResult represents the outcome of validating a Software Bill of Materials (SBOM).
19+ //
20+ // It provides detailed information about the validation process, including:
21+ // - Whether the SBOM is valid (`IsValid`).
22+ // - The detected SBOM type (e.g., CycloneDX, SPDX).
23+ // - The SBOM schema or specification version.
24+ // - A list of any validation errors encountered.
25+ // - The schema file or source used during validation.
26+ // - The detected input format (e.g., JSON, XML, etc.).
27+ //
28+ // This struct is returned by `ValidateSBOMData` and can be serialized to JSON
29+ // for use in CLI tools, APIs, or automated pipelines.
30+ type ValidationResult struct {
31+ IsValid bool `json:"isValid"`
32+ SBOMType string `json:"sbomType,omitempty"`
33+ SBOMVersion string `json:"sbomVersion,omitempty"`
34+ ValidationErrors []string `json:"validationErrors,omitempty"`
35+ SchemaUsed string `json:"schemaUsed,omitempty"`
36+ DetectedFormat string `json:"detectedFormat,omitempty"`
37+ }
38+
1839// Embed all JSON schema files from the schemas/cyclonedx directory
1940//
2041//go:embed schemas/cyclonedx/*.json schemas/spdx/*.json
@@ -61,27 +82,49 @@ var schemaFS embed.FS
6182// } else {
6283// fmt.Println("SBOM validation errors:", errors)
6384// }
64- func ValidateSBOMData (sbomContent []byte ) (bool , []string , error ) {
85+ func ValidateSBOMData (sbomContent []byte ) (* ValidationResult , error ) {
86+ result := & ValidationResult {}
87+
6588 if isJSON (sbomContent ) {
89+ result .DetectedFormat = "JSON"
90+
6691 sbomType , err := detectSBOMType (string (sbomContent ))
6792 if err != nil {
68- return false , nil , fmt .Errorf ("error detecting SBOM Type %s " , err . Error () )
93+ return result , fmt .Errorf ("error detecting SBOM Type %v " , err )
6994 }
95+ result .SBOMType = sbomType
7096
7197 sbomSchemaVersion , err := extractSBOMVersion (string (sbomContent ), sbomType )
7298 if err != nil {
73- return false , nil , fmt .Errorf ("failed to extract version: %v" , err )
99+ return result , fmt .Errorf ("failed to extract SBOM version: %v" , err )
74100 }
101+ result .SBOMVersion = sbomSchemaVersion
75102
76103 schema , err := loadSBOMSchema (sbomSchemaVersion , sbomType )
77104 if err != nil {
78- return false , nil , fmt .Errorf ("failed to load schema: %v" , err )
105+ return result , fmt .Errorf ("failed to load schema: %v" , err )
106+ }
107+
108+ isValid , validationErrors , err := validateSBOM (schema , string (sbomContent ))
109+ if err != nil {
110+ return result , fmt .Errorf ("validation error: %v" , err )
111+ }
112+
113+ result .IsValid = isValid
114+ result .ValidationErrors = validationErrors
115+
116+ // for SPDX SBOMs split the type and version (ie: SPDX-2.3)
117+ if strings .HasPrefix (sbomType , SBOM_SPDX ) {
118+ result .SBOMType = SBOM_SPDX
119+ result .SBOMVersion , _ = getSPDXVersion (sbomType )
79120 }
80121
81- return validateSBOM ( schema , string ( sbomContent ))
122+ return result , nil
82123
83124 } else {
84- return false , nil , fmt .Errorf ("unsupported file format" )
125+ result .IsValid = false
126+ result .DetectedFormat = "non-JSON"
127+ return result , fmt .Errorf ("unsupported file format" )
85128 }
86129}
87130
0 commit comments