mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
b947cab073
This adds SBOM information for submodules, which are not managed by Espressif. Meaning there is no fork for them in the espressif namespace. Other submodules should add sbom.yml manifest file to the root of their git repository. The SBOM information for submodules is stored in the .gitmodules file. Each SBOM related variable has the "sbom-" prefix and the following variables may be used: sbom-version: submodule version sbom-cpe: CPE record if available in NVD. This will be used by the SBOM tool to check for possible submodule vulnerabilities. The version in the CPE can be replaced with the "{}" placeholder, which will be replaced by the "sbom-version" value from above. sbom-supplier: Person or organization who is providing the submodule. It has to start with "Person:" or "Organization:" prefix as required by the SPDX-2.2 standard. sbom-url: URL to the project if exists, e.g. github. sbom-description: Project description. sbom-hash: Submodule SHA as recorded in the git-tree. This field is used by CI to check that the submodule checkout hash and info in .gitmodules are in sync. IOW if submodule is updated and it has SBOM info in .gitmodules, the .gitmodules has to be updated too. The test is part of this commit. The checkout has of the submodule can be found by using "git submodule status". Example for micro-ecc submodule ---8<--- [submodule "components/bootloader/subproject/components/micro-ecc/micro-ecc"] path = components/bootloader/subproject/components/micro-ecc/micro-ecc url = ../../kmackay/micro-ecc.git sbom-version = 1.0 sbom-cpe = cpe:2.3🅰️micro-ecc_project:micro-ecc:{}:*:*:*:*:*:*:* sbom-supplier = Person: Ken MacKay sbom-url = https://github.com/kmackay/micro-ecc sbom-description = A small and fast ECDH and ECDSA implementation for 8-bit, 32-bit, and 64-bit processors sbom-hash = d037ec89546fad14b5c4d5456c2e23a71e554966 ---8<--- Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
70 lines
2.6 KiB
Python
70 lines
2.6 KiB
Python
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
import os
|
|
from subprocess import run
|
|
from typing import Dict, List
|
|
|
|
|
|
def run_cmd(cmd: List[str]) -> str:
|
|
"""Simple helper to run command and return it's stdout."""
|
|
proc = run(cmd, capture_output=True, check=True, text=True)
|
|
return proc.stdout.strip()
|
|
|
|
|
|
def get_gitwdir() -> str:
|
|
"""Return absolute path to the current git working tree."""
|
|
return run_cmd(['git', 'rev-parse', '--show-toplevel'])
|
|
|
|
|
|
def get_submodules_info() -> List[Dict[str,str]]:
|
|
"""Return list of submodules, where each submodule is represented
|
|
as dictionary with name, path and hash keys."""
|
|
cmd = ['git', 'submodule', '--quiet', 'foreach','echo "$name,$sm_path,$sha1"']
|
|
out = run_cmd(cmd)
|
|
submodules = []
|
|
for line in out.splitlines():
|
|
name, sm_path, sha1 = line.split(',')
|
|
submodules += [{'name': name, 'path': sm_path, 'hash': sha1}]
|
|
|
|
return submodules
|
|
|
|
|
|
def get_submodules_config() -> Dict[str,str]:
|
|
"""Return dictionary, where key is variable name and value
|
|
is variable value in git's --list(dot) format. Only variables
|
|
starting with "submodule." are returned and this prefix is removed
|
|
to make it simple to match against the submodule info dictionary."""
|
|
gitmodules_fn = os.path.join(get_gitwdir(), '.gitmodules')
|
|
gitmodules_data = run_cmd(['git', 'config', '--list', '--file', gitmodules_fn])
|
|
prefix = 'submodule.'
|
|
config = {}
|
|
for line in gitmodules_data.splitlines():
|
|
var, val = line.split('=', maxsplit=1)
|
|
if not var.startswith(prefix):
|
|
continue
|
|
# remove "submodule." prefix
|
|
var = var[len(prefix):]
|
|
config[var] = val
|
|
|
|
return config
|
|
|
|
|
|
def test_sha() -> None:
|
|
""" Check that submodule SHA1 in git-tree and .gitmodules match
|
|
if sbom-hash variable is available in the .gitmodules file.
|
|
"""
|
|
submodules = get_submodules_info()
|
|
config = get_submodules_config()
|
|
|
|
for submodule in submodules:
|
|
sbom_hash = config.get(submodule['name'] + '.sbom-hash')
|
|
if not sbom_hash:
|
|
continue
|
|
msg = (f'Submodule \"{submodule["name"]}\" SHA \"{submodule["hash"]}\" in git '
|
|
f'tree does not match SHA \"{sbom_hash}\" recorded in .gitmodules. '
|
|
f'Please update \"sbom-hash\" in .gitmodules for \"{submodule["name"]}\" '
|
|
f'and also please do not forget to update version and other submodule '
|
|
f'information if necessary. It is important to keep this information '
|
|
f'up-to-date for SBOM generation.')
|
|
assert submodule['hash'] == sbom_hash, msg
|