8383-define (spdx_download_location , ~ " https://github.com/erlang/otp/releases" ).
8484-define (spdx_homepage , ~ " https://www.erlang.org" ).
8585-define (spdx_purl_meta_data , ~ " ?vcs_url=git+https://github.com/erlang/otp.git" ).
86- -define (spdx_version , ~ " SPDX-2.2 " ).
86+ -define (spdx_version , ~ " SPDX-2.3 " ).
8787-define (otp_version , 'OTP_VERSION' ). % file name of the OTP version
8888-define (spdx_project_purl , #{ ~ " comment" => ~ " " ,
8989 ~ " referenceCategory" => ~ " PACKAGE-MANAGER" ,
@@ -551,7 +551,8 @@ sbom_fixing_functions(ScanResults) ->
551551 {fun fix_project_package_version /2 , 'OTP_VERSION' },
552552 {fun fix_has_extracted_license_info /2 , extracted_license_info ()},
553553 {fun fix_project_purl /2 , ? spdx_project_purl },
554- {fun fix_beam_licenses /2 , {Licenses , Copyrights }} ].
554+ {fun fix_beam_licenses /2 , {Licenses , Copyrights }}
555+ ].
555556
556557fix_project_name (ProjectName , #{ ~ " documentDescribes" := [ ProjectName0 ],
557558 ~ " packages" := Packages }= Sbom ) ->
@@ -1172,7 +1173,7 @@ create_spdx_package(Pkg) ->
11721173 Supplier = Pkg # spdx_package .'supplier' ,
11731174 Purl1 = case Pkg # spdx_package .'purl' of
11741175 false -> [];
1175- _ -> [ Pkg # spdx_package .'purl' ]
1176+ _ -> Pkg # spdx_package .'purl'
11761177 end ,
11771178 #{ ~ " SPDXID" => SPDXID ,
11781179 ~ " versionInfo" => VersionInfo ,
@@ -1888,7 +1889,8 @@ create_spdx_package_record(PackageName, Vsn, Description, SpdxPackageFiles,
18881889 VerificationCodeValue = generate_verification_code_value (SpdxPackageFiles ),
18891890 Purl1 = case Purl of
18901891 false -> false ;
1891- true -> create_externalRef_purl (Description , otp_purl (PackageName , Vsn ))
1892+ true -> [create_externalRef_purl (Description , otp_purl (PackageName , Vsn )),
1893+ fix_openvex_reference ()]
18921894 end ,
18931895 # spdx_package {
18941896 'SPDXID' = SpdxPackageName ,
@@ -1911,6 +1913,19 @@ create_spdx_package_record(PackageName, Vsn, Description, SpdxPackageFiles,
19111913 }.
19121914
19131915
1916+ fix_openvex_reference () ->
1917+ OTPMajorVersion = hd (string :split (get_otp_version (), " ." )),
1918+ Reference = openvex_iri (OTPMajorVersion ),
1919+ #{
1920+ ~ " referenceCategory" => ~ " SECURITY" ,
1921+ ~ " referenceLocator" => Reference ,
1922+ ~ " referenceType" => ~ " advisory"
1923+ }.
1924+
1925+ % % Branch = ~"28" or similar. just the current version number.
1926+ openvex_iri (Branch ) when is_binary (Branch ) ->
1927+ <<" https://erlang.org/download/vex/otp-" , Branch /binary , " .openvex.json" >>.
1928+
19141929otp_app_license_mapping (Name ) ->
19151930 case Name of
19161931 ~ " edoc" -> ~ " Apache-2.0 OR LGPL-2.1-or-later" ;
@@ -2375,16 +2390,23 @@ test_project_purl(#{~"documentDescribes" := [ProjectName], ~"packages" := Packag
23752390 ok .
23762391
23772392test_packages_purl (#{~ " documentDescribes" := [ProjectName ], ~ " packages" := Packages }= _Sbom ) ->
2378- OTPPackages = lists :filter (fun (#{~ " SPDXID" := Id , ~ " name" := Name }) -> ProjectName =/= Id andalso lists :member (Name , minimum_otp_apps ()) end , Packages ),
2379- true = lists :all (fun (#{~ " name" := Name , ~ " versionInfo" := Version , ~ " externalRefs" := [#{~ " referenceLocator" := RefLoc }= Ref ]}) ->
2393+ OTPPackages = lists :filter (fun (#{~ " SPDXID" := Id , ~ " name" := Name }) ->
2394+ ProjectName =/= Id andalso lists :member (Name , minimum_otp_apps ())
2395+ end , Packages ),
2396+ true = lists :all (fun (#{~ " name" := Name , ~ " versionInfo" := Version ,
2397+ ~ " externalRefs" := [#{~ " referenceLocator" := RefLoc }= Ref ,
2398+ OpenVex ]}) ->
23802399 ExternalRef = create_externalRef_purl (~ " " , otp_purl (Name , Version )),
23812400 ExternalRef1 = maps :remove (~ " comment" , ExternalRef ),
23822401 Ref1 = maps :remove (~ " comment" , Ref ),
23832402
2403+ ExpectedVEX = fix_openvex_reference (),
2404+
23842405 % % check expected external ref
23852406 ExternalRef1 =:= Ref1 andalso
23862407 % % check metadata is included in purl
2387- nomatch =/= string :find (RefLoc , ? spdx_purl_meta_data )
2408+ nomatch =/= string :find (RefLoc , ? spdx_purl_meta_data ) andalso
2409+ ExpectedVEX == OpenVex
23882410 end , OTPPackages ),
23892411 ok .
23902412
@@ -3202,12 +3224,13 @@ fetch_app_from_table(OTPVersion, App0) ->
32023224convert_range (Version ) ->
32033225 string :split (Version , " ." , all ).
32043226
3205-
3227+ % % Branch = "otp-28"
32063228init_openvex_file (Branch ) ->
32073229 Ts = calendar :system_time_to_rfc3339 (erlang :system_time (microsecond ), [{unit , microsecond }]),
3230+ [~ " otp" , Version ] = string :split (Branch , ~ " -" ),
32083231 #{
32093232 ~ " @context" => ~ " https://openvex.dev/ns/v0.2.0" ,
3210- ~ " @id" => << " https://openvex.dev/docs/public/otp/vex- " , Branch / binary >> ,
3233+ ~ " @id" => openvex_iri ( Version ) ,
32113234 ~ " author" => ~ " vexctl" ,
32123235 ~ " timestamp" => erlang :list_to_binary (Ts ),
32133236 ~ " version" => 1 ,
0 commit comments