关注了就能看到更多这么棒的文章哦~
Supporting PGP keys and signatures in the kernel
By Jake Edge
January 25, 2022
DeepL assisted translation
https://lwn.net/Articles/882426/
几周前,我们介绍了为 Fedora 添加完整性管理(integrity-management)功能的建议。其中的一个主要卖点是,可以把这个完整性检查(integrity check)完全基于 Fedora 使用的 RPM 包文件中内置的 PGP 签名来完成。但是内核需要能够对 PGP 签名进行验签,才能让 Fedora 的这个功能起效果。有人提议在内核中增加这个功能,但内核开发社区的一些人似乎对于在内核里面支持 PGP 不怎么感兴趣。
Roberto Sassu 提议在 David Howells 的早期工作基础之上来增加对 PGP 密钥和签名的支持。Sassu 还提议在内核中加入 Digest Lists Integrity Module (DIGLIM),他是 Fedora 中负责在发行版里支持 DIGLIM 的提案人。该提案最初是针对 Fedora 36 的,但在 DIGLIM 和 PGP 支持进入 kernel mainline 之前,这个功能不可能被某个 Fedora 版本采用。
Parser
为了处理密钥和签名,内核就需要理解 PGP 格式,所以 Sassu 建议在内核中加入一个解析器。不出意料 这引起了很多抱怨。Maciej S. Szmigiero 想知道是否有更好的方法:
PGP 密钥不就是带有额外元数据(metadata)的 RSA/ECC/EdDSA 密钥吗?难道它们不能由用户空间来把(复杂的)PGP 格式解开,然后采用类似于某些 SSH 认证的方式来把原始数据加载到内核中吗?
这将使我们不必在内核中添加复杂的 parser(众所周知这是不少 bug 的来源)[…] 。
Sassu 说 Howells 已经实现了一个 parser,遵循 PGP 数据的 RFC。但是将其进一步解开成另一种格式,还仍然需要一个 parser。此外,那段代码已经用几种不同的方式进行过测试:
我用一个临时的 fault injector 来对该实现进行了深入的测试,以了解该代码是否能够正确处理错误情况。我还开发了一个 fuzzer(模糊器),在数据被内核读取之前来破坏这些数据。最后,我检查了是否有内存泄漏的问题。当然我同意,还是有可能有漏网的 bug。
Sassu 同时说,Szmigiero 称为 "内核内 PGP 信任网(in-kernel PGP Web of Trust)" 的功能将限制在小范围内使用。内核里的某些 keyring,比如 Integrity Measurement Architecture(IMA)keyring,要求被添加到其中的各个密钥都要由内核 keyring 上的另一个 key 来担保(vouched for)。Sassu 在 patch set 中实现的一部分功能就是来支持检查密钥中的 PGP 签名,如果检查失败则拒绝该密钥。
但是 Szmigiero 仍然对内核中的 parser 感到担忧:
用户空间中的 parser 比起内核中的 parser 要更好,因为万一某个地方出现了 bug 的话后果会轻得多。而经验表明,parser 特别容易出现错误。用户空间的实现也可以是控制为严格管理的 sandbox 来获得更高的安全性。
他还指出可以使用现有的 OpenPGP 的用户空间 parser,但 Sassu 并不认为这条道路会更加轻松:
然而,在我看来,定义一种新的格式来上传 RSA 密钥及签名来避免 PGP 的复杂性,这种做法的风险也并不小。而且,这似乎并不比已经在内核中的 PKCS#7 更复杂。
[…] 我的另一个担心是,使用 OpenPGP 库的这种方法仍然需要 Linux 发行商将他们所拥有的源数据转换为另一种格式。他们必须对这个转换动作进行认证,哪怕是在用户空间完成的也一样。比起对一个在用户空间中运行的包含了很多其他功能的库进行验证,也许把原始数据以及用来在内核中最低限度地验证处理 PGP 密钥和签名的功能放在内核里会更容易,。
PGP deprecated?
Jason A. Donenfeld 对在内核中添加 PGP 支持有一个更根本的担忧:"加密工程界(crypto engineering world)的普遍共识是,PGP 应该被淘汰。" 他引用了 2019 年的一篇博文,作为 PGP(以及实现它的应用程序,如 GnuPG)的广泛问题的一个例子。他建议使用基于 Ed25519 的签名机制,在用户空间使用 Minisign 或 signify 之类的东西,并在内核中只使用最小的代码;他说,这可以确保 "只有很少的可用功能会被破坏"。
但是 James Bottomley 不同意。虽然有很多人反对 PGP,但是 "实际上没有人能够想出一个更好用的替代品"。此外,Ed25519 不被可信平台模块(TPM,Trusted Platform Module)支持,而且可能永远不会支持,因为当 TPM 标准组织增加新的算法时,它可能会跳过 Ed25519 而直接选择更强大的算法。他说,加密社区经常想要最小化解决方案,但这些解决方案 "只有相对比较小的使用场景,没有未来的用例来证明(no future proofing)",而更复杂的可扩展解决方案则被批评为 "是一把'瑞士军刀'"。
Antony Vennard 认为这是一个错误的看待问题的方式。内核中已经有对 PKCS #7 的支持了,增加 PGP 的支持会让事情变得更加复杂:
我们已经有一个可扩展的系统,在内核中的实现已经很复杂了。这个 patch 希望能增加另一个来实现同样目的的系统,而不是利用现有代码的用户空间解决方案。我认为后者更可取,也更安全。
Sassu 回答说,要使用替代机制仍有障碍。无论采用何种密钥格式,仍需要某种 parser 以及验证密钥签名的方法,这些都需要在内核中出现才行。他已经考虑了这些问题,并相信他的方法达到了正确的平衡:
经过几次迭代试图从 patch set 中删除不那么重要的内容,我得出的结论是,能同时拥有密钥和签名的逻辑就是最好的折衷方案了。诚然,这意味着要为内核做更多的维护工作,但这能确保与当前生态系统的互操作性达到最佳。
我认为代码并没有复杂到无法进行 review 的程度。
虽然 PGP 格式有很多不同的数据包类型(packet types),但内核内的 parser "只需要解析 key、user ID 和 signature packet 以及 subpacket",他说。分发系统生态方面的问题是他对其他其他解决方案一个担忧;"我认为强迫所有 Linux 分发系统都这样做似乎并不现实"。但是如果一个最小化的 PGP parser 可以被审核通过,那么发行版的那些使用场景就可以得到支持:
解析 PGP 格式里的数据似乎是唯一的障碍。一旦我们确信可以正确地解析这少数几种类型的 packet,那么剩下的就只是要重复使用已经存在的机制就够了。而且这样可以让人们采用安全功能的时候感到更加容易。
他在给 Donenfeld 的回复中进一步阐述了发行版这边的困难。要切换到新的软件包签名机制(比如像 Donenfeld 建议的那样,采用基于 Ed25519 的机制)对发行版来说是一个重大转变,这可能需要数年才能完成:
更具体地说,第一个任务就是修改 RPM 的签名方式(以及它们的验证方式)。第二项任务是换一种方式来认证公钥。最后,Linux 发行商将不得不改变他们的构建功能的基础设施来使用新的认证密钥,提供一个新版本的 rpm 软件包管理器可以根据新的密钥作为输入来产生一个不同类型的签名,并将其嵌入到 RPM 头。
[……]这套 patch 的目的是能尽快地提供一些 security 功能,大大减轻 Linux 发行商管理这些安全功能的负担。
Donenfeld 对发行版这边要做的工作表示同情,但他指出,这最终还是出于短期思维和长期思维的对比:与其投入大量工作过渡到更好的方案(这里需要 "评估 最好的方案 是什么"),不如继续支持一个有缺陷的(但可以用的)系统,这是一条更容易的前进道路。他想知道是不是应该停止这种想法,至少对于 PGP 来说:
我对长期思考与短期思考没有什么技术上的发言权, 但我觉得 PGP 就是这样一个例子, 人们知道它的缺陷已经有几十年了, 但由于人们继续采用短期的解决方案, 生态系统不断扩展, 一个接一个, 现在已经来到了内核的门口了。也许在某个时候,需要有人停下脚步说,"短期方案之路到此为止",可能才会逐渐有动力去寻找长期的解决方案,例如可行的 PGP 的替代品?这只是我的想法。
虽然 Ed25519 可能很有吸引力, Konstantin Ryabitsev 说, 但是它的密钥管理还有待改进:
我觉得 Ed25519 的私钥管理非常简陋。多数情况下它只是保存在磁盘的某个地方,通常也没有用任何 passphrase 加密。
尽管 GnuPG 有很多遗留问题,但至少在 GnuPG 2.3 中通过 OpenPGP smartcards 或 TPM integration 功能很好地支持了 hardware off-load (硬件处理),而我们对 ed25519 最好的支持就是 minisign 中实现的 passphrase 保护(甚至这个功能也是非常简陋的,如果你需要对 10 件东西签名,就需要 10 次输入 passphrase,因为没有任何形式的 passphrase agent 代理)。
他说,把对 FIDO2 的支持整合到 OpenSSH 中是 "我最近看到的 PKI(公钥基础设施,public-key infrastructure)签名方面最有希望的非 PGP 的方向"。多年来,密钥管理一直是许多公钥签名方案的一个已知弱点,因此他 "担心这将导致整体安全性算下来其实损失比收益大"。
目前还不太清楚这个提议最终结果会是怎样。内核显然是存储密钥的 "可靠" 位置,而验证用这些密钥制作的签名在逻辑上就是这个功能的延伸。但是,对于 PGP 以及再添加一个复杂格式的内核 parser 这两个担忧非常难以克服。
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~