如果你为欧洲市场开发软件,很可能已经有人向你索要过软件物料清单。《网络韧性法案》要求制造商编制一份并保存在技术文档中,而在任何监管机构提出要求之前,你的客户往往早就问起了。当你的产品内嵌了一个组件库时,这个问题就落到了我们身上。
从这个版本开始,每一个 sgcWebSockets 安装程序都会作出回答。安装程序会在安装目录中写入一份 CycloneDX 物料清单,文件名为 sbom.cdx.json,其中列出了构建这个库所用的顶层组件,以及它们的版本和许可证。
由安装程序生成,而不是手工维护
有意思的地方不是这个文件本身,而是它从哪里来。靠人手工更新的物料清单会悄无声息地过期,而一份报告了你早已不再发布的版本的合规文档,比根本没有文档还要糟糕。
所以它并不是手工维护的。安装程序脚本会在构建时运行一个生成器,而该生成器会从真正拥有各个版本号的文件中读取它们:产品版本来自 history.txt,Indy 来自 IdVers.inc,zlib 来自 zlib.h,OpenSSL 来自静态链接单元。只要其中任何一个值无法读取,生成器就会报错停止,安装程序的构建随之失败。它从不猜测,也从不退回到某个人当初手工填写的值。
实际效果就是 SBOM 不可能脱节。升级 zlib 之后,你下一次构建的安装程序就会如实反映,无需任何人去记住这件事。
它描述的是你的版本,而不是一个泛化的产品
这一部分最有可能与你相关。物料清单并非对所有版本都相同,因为各个版本包含的第三方代码并不一样。
Enterprise 和 All-Access 会编译随 sgcWebSockets 一起提供的定制版 Indy,而这个分支自带了它自己的 zlib。Core、Standard 和 Professional 则基于你的 Delphi 或 C++ Builder 安装中自带的 Indy 进行构建,我们既不对其分支,也不进行再分发。对于这些版本,我们根本无法诚实地声明某个 Indy 版本,因为版本取决于你的 IDE 提供的是哪一个。
因此,一份泛化的通用 SBOM 对大多数安装来说都会是错的。取而代之,安装程序会为它正在打包的那个版本生成文档,因此你收到的文件描述的正是你实际拥有的内容。
| 版本 | Indy | zlib |
|---|---|---|
| Core、Standard、Professional | 由你的 IDE 提供,我们不再分发 | 通过同一个 Indy 进入产品 |
| Enterprise、All-Access | 定制的 Indy 分支,标明版本 | 内置随附的副本,标明版本 |
里面有什么
该文档采用 CycloneDX 1.6 JSON 格式,这是一种常见的机器可读格式,现有的清单管理和扫描工具都已经能够识别。除了组件之外,它还记录了每个组件的许可证、它是由我们再分发还是由你的 IDE 提供,以及它在源码树中的位置。
在有用的地方,它还会附带 VEX 声明。如果某个已知 CVE 影响到了某个组件版本,但从我们的代码中无法触发,文档会连同原因一起明确说明,而不是把判断留给你。这些条目会随着组件版本的变化自动出现或消失,因为生成器是根据它读到的版本来判断的,而不是根据某个人留下的注记。
在哪里找到它
请到你的安装目录中查看,就在 history.txt 和许可证文件旁边。
C:\Program Files (x86)\sgcWebSockets\sbom.cdx.json
你可以把它交给你所使用的任何清单管理工具,把它附在供应商问卷上,或者把其中的条目并入你为自己产品编制的物料清单。如果你的合规团队需要其他格式,或者希望我们针对某个具体构建填写一份供应商评估表,请通过联系表单告诉我们你所使用的产品、版本和版本号。
有一件事我们刻意没有做
我们不会在本网站上公开发布 SBOM。《网络韧性法案》要求制造商编制一份并保存在技术文档中,但并不要求公开发布,而且把组件清单交给任何提出索要的人,也没有多少好处。把它随产品一起发布,可以让它送到有权获得它的人手中,也就是被许可方,以及在提出要求时的市场监管机构。
你可以在我们的《网络韧性法案》页面上进一步了解我们应对该法规的方式。
