75
75
from cve_bin_tool .util import ProductInfo
76
76
from cve_bin_tool .version import VERSION
77
77
from cve_bin_tool .version_scanner import VersionScanner
78
+ from cve_bin_tool .vex_manager .parse import VEXParse
78
79
79
80
sys .excepthook = excepthook # Always install excepthook for entrypoint module.
80
81
@@ -180,12 +181,6 @@ def main(argv=None):
180
181
default = "" ,
181
182
help = "provide input filename" ,
182
183
)
183
- input_group .add_argument (
184
- "--triage-input-file" ,
185
- action = "store" ,
186
- default = "" ,
187
- help = "provide input filename for triage data" ,
188
- )
189
184
input_group .add_argument (
190
185
"-C" , "--config" , action = "store" , default = "" , help = "provide config file"
191
186
)
@@ -358,7 +353,7 @@ def main(argv=None):
358
353
output_group .add_argument (
359
354
"--vex-type" ,
360
355
action = "store" ,
361
- default = "cyclonedx " ,
356
+ default = "" ,
362
357
choices = ["cyclonedx" , "csaf" , "openvex" ],
363
358
help = "specify type of vulnerability exchange (vex) to generate (default: cyclonedx)" ,
364
359
)
@@ -380,6 +375,19 @@ def main(argv=None):
380
375
default = "" ,
381
376
help = "Vendor/Supplier of Product" ,
382
377
)
378
+ output_group .add_argument (
379
+ "-rr" ,
380
+ "--revision-reason" ,
381
+ action = "store" ,
382
+ default = "" ,
383
+ help = "a reason for the update to the vex document should be specified in double quotes" ,
384
+ )
385
+ output_group .add_argument (
386
+ "--filter-triage" ,
387
+ action = "store_true" ,
388
+ default = False ,
389
+ help = "Filter cves based on triage data from Vex file" ,
390
+ )
383
391
parser .add_argument (
384
392
"-e" ,
385
393
"--exclude" ,
@@ -917,6 +925,7 @@ def main(argv=None):
917
925
and not args ["package_list" ]
918
926
and not args ["merge" ]
919
927
and not args ["sbom_file" ]
928
+ and not args ["vex_file" ]
920
929
):
921
930
parser .print_usage ()
922
931
with ErrorHandler (logger = LOGGER , mode = ErrorMode .NoTrace ):
@@ -1009,7 +1018,7 @@ def main(argv=None):
1009
1018
triage_data : TriageData
1010
1019
total_files : int = 0
1011
1020
parsed_data : dict [ProductInfo , TriageData ] = {}
1012
-
1021
+ vex_product_info : dict [ str , str ] = {}
1013
1022
# Package List parsing
1014
1023
if args ["package_list" ]:
1015
1024
sbom_root = args ["package_list" ]
@@ -1021,18 +1030,6 @@ def main(argv=None):
1021
1030
LOGGER .debug (f"{ product_info } , { triage_data } " )
1022
1031
cve_scanner .get_cves (product_info , triage_data )
1023
1032
1024
- if args ["triage_input_file" ]:
1025
- input_engine = InputEngine (
1026
- args ["triage_input_file" ],
1027
- logger = LOGGER ,
1028
- error_mode = error_mode ,
1029
- filetype = "vex" ,
1030
- )
1031
- parsed_data = input_engine .parse_input ()
1032
- for product_info , triage_data in parsed_data .items ():
1033
- LOGGER .debug (f"{ product_info } , { triage_data } " )
1034
- cve_scanner .get_cves (product_info , triage_data )
1035
-
1036
1033
if args ["input_file" ]:
1037
1034
input_engine = InputEngine (
1038
1035
args ["input_file" ], logger = LOGGER , error_mode = error_mode
@@ -1092,6 +1089,41 @@ def main(argv=None):
1092
1089
LOGGER .debug (f"{ product_info } , { triage_data } " )
1093
1090
cve_scanner .get_cves (product_info , triage_data )
1094
1091
1092
+ if args ["vex_file" ]:
1093
+ # for now use cyclonedx as auto detection is not implemented in latest pypi package of lib4vex
1094
+ vexdata = VEXParse (
1095
+ filename = args ["vex_file" ],
1096
+ vextype = "cyclonedx" ,
1097
+ logger = LOGGER ,
1098
+ )
1099
+ parsed_vex_data = vexdata .parse_vex ()
1100
+ vex_product_info = vexdata .vex_product_info
1101
+ if not parsed_data :
1102
+ # assume the vex file being scanned is a standalone file
1103
+ args ["filter_triage" ] = False
1104
+ parsed_data = parsed_vex_data
1105
+ for product_info , triage_data in parsed_data .items ():
1106
+ LOGGER .debug (f"{ product_info } , { triage_data } " )
1107
+ cve_scanner .get_cves (product_info , triage_data )
1108
+ else :
1109
+ LOGGER .info (
1110
+ f"VEX file { args ['vex_file' ]} is not a standalone file and will be used as a triage file"
1111
+ )
1112
+ # need to do validation on the sbom part
1113
+ # need to implement is_linked() function which will check the linkage.
1114
+ if args ["sbom_file" ]:
1115
+ LOGGER .warning (
1116
+ f"SBOM file: { args ['sbom_file' ]} is not linked to VEX file: { args ['vex_file' ]} ."
1117
+ )
1118
+ for product_info , triage_data in parsed_vex_data .items ():
1119
+ LOGGER .debug (f"{ product_info } , { triage_data } " )
1120
+ if product_info in parsed_data :
1121
+ cve_scanner .get_cves (product_info , triage_data )
1122
+ else :
1123
+ LOGGER .info (
1124
+ f"Product: { product_info .product } with Version: { product_info .version } not found in Parsed Data, is valid vex file being used?"
1125
+ )
1126
+
1095
1127
LOGGER .info ("Overall CVE summary: " )
1096
1128
LOGGER .info (
1097
1129
f"There are { cve_scanner .products_with_cve } products with known CVEs detected"
@@ -1105,19 +1137,29 @@ def main(argv=None):
1105
1137
)
1106
1138
)
1107
1139
LOGGER .info (f"Known CVEs in { affected_string } :" )
1108
- vex_product_info : dict [str , str ] = {}
1109
- if args ["vex_output" ]:
1140
+ if args ["vex_type" ] or args ["vex_output" ]:
1141
+ # If vex_type is provided, then use it, else use cyclonedx as default vex_output should be provide in this case
1142
+ # If vex_output is provided, then use it, else use product, release and vendor to generate the vex file.
1143
+ if args ["vex_output" ] and not args ["vex_type" ]:
1144
+ # default vex_type is cyclonedx
1145
+ args ["vex_type" ] = "cyclonedx"
1110
1146
if args ["product" ] and args ["release" ] and args ["vendor" ]:
1111
1147
vex_product_info = {
1112
1148
"product" : args ["product" ],
1113
1149
"release" : args ["release" ],
1114
1150
"vendor" : args ["vendor" ],
1151
+ "revision_reason" : args ["revision_reason" ],
1115
1152
}
1153
+ elif args ["vex_file" ]:
1154
+ vex_product_info ["revision_reason" ] = args ["revision_reason" ]
1116
1155
else :
1117
1156
LOGGER .error (
1118
1157
"Please provide --product, --release and --vendor for VEX generation"
1119
1158
)
1120
1159
return ERROR_CODES [InsufficientArgs ]
1160
+
1161
+ if args ["vex_file" ] and args ["filter_triage" ]:
1162
+ cve_scanner .filter_triage_data ()
1121
1163
# Creates an Object for OutputEngine
1122
1164
output = OutputEngine (
1123
1165
all_cve_data = cve_scanner .all_cve_data ,
0 commit comments