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  }