github.com/google/osv-scalibr@v0.4.1/binary/proto/vex.go (about)

     1  // Copyright 2025 Google LLC
     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  package proto
    16  
    17  import (
    18  	"errors"
    19  
    20  	"github.com/google/osv-scalibr/inventory/vex"
    21  
    22  	spb "github.com/google/osv-scalibr/binary/proto/scan_result_go_proto"
    23  )
    24  
    25  var (
    26  	// --- Errors
    27  
    28  	// ErrVulnIdentifiersAndMatchsAllSet will be returned if both VulnIdentifiers and MatchesAllVulns are set.
    29  	ErrVulnIdentifiersAndMatchsAllSet = errors.New("cannot set both VulnIdentifiers and MatchesAllVulns")
    30  
    31  	// structToProtoVEX is a map of struct VEX justifications to their corresponding proto values.
    32  	structToProtoVEX = map[vex.Justification]spb.VexJustification{
    33  		vex.Unspecified:                                 spb.VexJustification_VEX_JUSTIFICATION_UNSPECIFIED,
    34  		vex.ComponentNotPresent:                         spb.VexJustification_COMPONENT_NOT_PRESENT,
    35  		vex.VulnerableCodeNotPresent:                    spb.VexJustification_VULNERABLE_CODE_NOT_PRESENT,
    36  		vex.VulnerableCodeNotInExecutePath:              spb.VexJustification_VULNERABLE_CODE_NOT_IN_EXECUTE_PATH,
    37  		vex.VulnerableCodeCannotBeControlledByAdversary: spb.VexJustification_VULNERABLE_CODE_CANNOT_BE_CONTROLLED_BY_ADVERSARY,
    38  		vex.InlineMitigationAlreadyExists:               spb.VexJustification_INLINE_MITIGATION_ALREADY_EXISTS,
    39  	}
    40  	// protoToStructVEX is a map of proto VEX justifications to their corresponding struct values.
    41  	// It is initialized from structToProtoVEX during runtime to ensure both maps are in sync.
    42  	protoToStructVEX = func() map[spb.VexJustification]vex.Justification {
    43  		m := make(map[spb.VexJustification]vex.Justification)
    44  		for k, v := range structToProtoVEX {
    45  			m[v] = k
    46  		}
    47  		if len(m) != len(structToProtoVEX) {
    48  			panic("protoToStructAnnotations does not contain all values from structToProtoAnnotations")
    49  		}
    50  		return m
    51  	}()
    52  )
    53  
    54  // --- Struct to Proto
    55  
    56  // PackageVEXToProto converts a struct PackageExploitabilitySignal to its proto representation.
    57  func PackageVEXToProto(v *vex.PackageExploitabilitySignal) (*spb.PackageExploitabilitySignal, error) {
    58  	if v == nil {
    59  		return nil, nil
    60  	}
    61  	if len(v.VulnIdentifiers) != 0 && v.MatchesAllVulns {
    62  		return nil, ErrVulnIdentifiersAndMatchsAllSet
    63  	}
    64  
    65  	p := &spb.PackageExploitabilitySignal{
    66  		Plugin:        v.Plugin,
    67  		Justification: structToProtoVEX[v.Justification],
    68  	}
    69  	if v.MatchesAllVulns {
    70  		p.VulnFilter = &spb.PackageExploitabilitySignal_MatchesAllVulns{MatchesAllVulns: true}
    71  	} else {
    72  		p.VulnFilter = &spb.PackageExploitabilitySignal_VulnIdentifiers{
    73  			VulnIdentifiers: &spb.VulnIdentifiers{Identifiers: v.VulnIdentifiers},
    74  		}
    75  	}
    76  	return p, nil
    77  }
    78  
    79  // FindingVEXToProto converts a struct FindingExploitabilitySignal to its proto representation.
    80  func FindingVEXToProto(v *vex.FindingExploitabilitySignal) *spb.FindingExploitabilitySignal {
    81  	if v == nil {
    82  		return nil
    83  	}
    84  
    85  	return &spb.FindingExploitabilitySignal{
    86  		Plugin:        v.Plugin,
    87  		Justification: structToProtoVEX[v.Justification],
    88  	}
    89  }
    90  
    91  // --- Proto to Struct
    92  
    93  // PackageVEXToStruct converts a proto PackageExploitabilitySignal to its struct representation.
    94  func PackageVEXToStruct(p *spb.PackageExploitabilitySignal) (*vex.PackageExploitabilitySignal, error) {
    95  	if p == nil {
    96  		return nil, nil
    97  	}
    98  
    99  	v := &vex.PackageExploitabilitySignal{
   100  		Plugin:        p.Plugin,
   101  		Justification: protoToStructVEX[p.Justification],
   102  	}
   103  	if ids := p.GetVulnIdentifiers(); ids != nil {
   104  		v.VulnIdentifiers = ids.Identifiers
   105  	} else {
   106  		v.MatchesAllVulns = p.GetMatchesAllVulns()
   107  	}
   108  	return v, nil
   109  }
   110  
   111  // FindingVEXToStruct converts a proto FindingExploitabilitySignal to its struct representation.
   112  func FindingVEXToStruct(p *spb.FindingExploitabilitySignal) *vex.FindingExploitabilitySignal {
   113  	if p == nil {
   114  		return nil
   115  	}
   116  
   117  	return &vex.FindingExploitabilitySignal{
   118  		Plugin:        p.Plugin,
   119  		Justification: protoToStructVEX[p.Justification],
   120  	}
   121  }