github.com/vchain-us/vcn@v0.9.11-0.20210921212052-a2484d23c0b3/pkg/bom/cyclone_dx.go (about) 1 /* 2 * Copyright (c) 2021 CodeNotary, Inc. All Rights Reserved. 3 * This software is released under GPL3. 4 * The full license information can be found under: 5 * https://www.gnu.org/licenses/gpl-3.0.en.html 6 * 7 */ 8 9 package bom 10 11 import ( 12 "bytes" 13 "os" 14 "path/filepath" 15 "strconv" 16 17 cdx "github.com/CycloneDX/cyclonedx-go" 18 19 "github.com/vchain-us/vcn/pkg/bom/artifact" 20 "github.com/vchain-us/vcn/pkg/meta" 21 ) 22 23 var hashNames = map[artifact.HashType]cdx.HashAlgorithm{ 24 artifact.HashMD5: cdx.HashAlgoMD5, 25 artifact.HashSHA1: cdx.HashAlgoSHA1, 26 artifact.HashSHA256: cdx.HashAlgoSHA256, 27 artifact.HashSHA384: cdx.HashAlgoSHA384, 28 artifact.HashSHA512: cdx.HashAlgoSHA512, 29 } 30 31 func OutputCycloneDX(a artifact.Artifact, filename string, format cdx.BOMFileFormat) error { 32 f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) 33 if err != nil { 34 return err 35 } 36 defer f.Close() 37 38 buf := new(bytes.Buffer) 39 encoder := cdx.NewBOMEncoder(buf, format) 40 encoder.SetPretty(true) 41 42 bom := convertToCyclone(a) 43 44 err = encoder.Encode(bom) 45 if err != nil { 46 return err 47 } 48 49 c := buf.Bytes() 50 51 _, err = f.Write(c) 52 return err 53 } 54 55 func convertToCyclone(a artifact.Artifact) *cdx.BOM { 56 bom := cdx.NewBOM() 57 58 bom.Metadata = &cdx.Metadata{ 59 Tools: &[]cdx.Tool{ 60 { 61 Vendor: "Codenotary", 62 Name: "vcn", 63 Version: meta.Version(), 64 }, 65 }, 66 } 67 68 name := filepath.Base(a.Path()) 69 bom.Metadata.Component = &cdx.Component{ 70 Name: name, 71 Type: cdx.ComponentTypeApplication, 72 } 73 74 deps := a.Dependencies() 75 comps := make([]cdx.Component, len(deps)) 76 for i, dep := range deps { 77 hashName, ok := hashNames[dep.HashType] 78 if !ok { 79 hashName = "" 80 } 81 pkgUrl := Purl(a, dep) 82 comps[i] = cdx.Component{ 83 BOMRef: name + "-" + strconv.Itoa(i+1), 84 Type: cdx.ComponentTypeLibrary, 85 Name: dep.Name, 86 Version: dep.Version, 87 PackageURL: pkgUrl, 88 Hashes: &[]cdx.Hash{ 89 { 90 Algorithm: hashName, 91 Value: dep.Hash, 92 }, 93 }, 94 } 95 if dep.License != "" { 96 comps[i].Licenses = &cdx.Licenses{cdx.LicenseChoice{Expression: dep.License}} 97 } 98 props := make([]cdx.Property, 1, 2) 99 props[0] = cdx.Property{Name: "LinkType", Value: DepLinkType(a, dep)} 100 trustLevel := artifact.TrustLevelName(dep.TrustLevel) 101 if trustLevel != "" { 102 props = append(props, cdx.Property{Name: "TrustLevel", Value: trustLevel}) 103 } 104 comps[i].Properties = &props 105 } 106 bom.Components = &comps 107 108 return bom 109 }