@@ -359,6 +359,30 @@ def get_csaf_security_advisory(product):
359359 return security_advisory
360360
361361
362+ CDX_STATE_TO_OPENVEX_STATUS = {
363+ "resolved" : openvex .Status .fixed ,
364+ "resolved_with_pedigree" : openvex .Status .fixed ,
365+ "exploitable" : openvex .Status .affected ,
366+ "in_triage" : openvex .Status .under_investigation ,
367+ "false_positive" : openvex .Status .not_affected ,
368+ "not_affected" : openvex .Status .not_affected ,
369+ }
370+
371+
372+ justification_ovex = openvex .Justification
373+ CDX_JUSTIFICATION_TO_OPENVEX_JUSTIFICATION = {
374+ "code_not_present" : justification_ovex .vulnerable_code_not_present ,
375+ "code_not_reachable" : justification_ovex .vulnerable_code_not_in_execute_path ,
376+ "protected_at_perimeter" : justification_ovex .vulnerable_code_cannot_be_controlled_by_adversary ,
377+ "protected_at_runtime" : justification_ovex .inline_mitigations_already_exist ,
378+ "protected_by_compiler" : justification_ovex .inline_mitigations_already_exist ,
379+ "protected_by_mitigating_control" : justification_ovex .inline_mitigations_already_exist ,
380+ "requires_configuration" : justification_ovex .vulnerable_code_cannot_be_controlled_by_adversary ,
381+ "requires_dependency" : justification_ovex .component_not_present ,
382+ "requires_environment" : justification_ovex .vulnerable_code_cannot_be_controlled_by_adversary ,
383+ }
384+
385+
362386def get_openvex_timestamp ():
363387 return datetime .now (UTC ).isoformat ()
364388
@@ -373,24 +397,42 @@ def get_openvex_vulnerability(vulnerability):
373397
374398
375399def get_openvex_statement (vulnerability ):
376- products = [
400+ components = [
377401 openvex .Component1 (field_id = package .package_url )
378402 for package in vulnerability .affected_packages .all ()
379403 ]
380404
381- status = openvex .Status .under_investigation
405+ status = default_status = openvex .Status .under_investigation
406+ status_notes = msgspec .UNSET
407+ justification = msgspec .UNSET
408+ impact_statement = msgspec .UNSET
409+ action_statement = msgspec .UNSET
410+
382411 vulnerability_analyses = vulnerability .vulnerability_analyses .all ()
383412 if len (vulnerability_analyses ) == 1 :
384413 analysis = vulnerability_analyses [0 ]
385- print (analysis )
414+ status = CDX_STATE_TO_OPENVEX_STATUS .get (analysis .state , default_status )
415+ status_notes = analysis .detail
416+
417+ if analysis .justification :
418+ justification = CDX_JUSTIFICATION_TO_OPENVEX_JUSTIFICATION .get (analysis .justification )
419+ if justification == msgspec .UNSET and status == openvex .Status .not_affected :
420+ impact_statement = "Unknown"
421+
422+ if analysis .responses :
423+ action_statement = ", " .join (analysis .responses )
424+ elif status == openvex .Status .affected :
425+ action_statement = "Unknown"
386426
387427 return openvex .Statement (
388428 vulnerability = get_openvex_vulnerability (vulnerability ),
389429 timestamp = get_openvex_timestamp (),
390- products = products ,
430+ products = components ,
391431 status = status ,
392- # status_notes: analysis.detail
393- # justification: analysis.justification
432+ status_notes = status_notes ,
433+ justification = justification ,
434+ impact_statement = impact_statement ,
435+ action_statement = action_statement ,
394436 )
395437
396438
0 commit comments