摘要
- wolfSSL 5.9.2 披露:在启用 RPK 的构建中,未协商的裸公钥曾可代替预期的 X.509 证书,从而绕过证书链验证。修复把“未另行协商”明确解释为 X.509,并拒绝实际形态与协商结果不一致的凭据。
- RFC 7250 与 TLS 1.3 将 Raw Public Key 定义为合法且必须显式选择的证书类型,线上只携带一个 DER 编码的
SubjectPublicKeyInfo。握手可以证明对应私钥的持有,却不会凭空产生签发者、主体、有效期或应用角色。 - 安全接受需要两份互不替代的证据:运行端确实协商了 RPK;外部绑定源此刻仍把这枚 SPKI 授权给指定主机、服务、设备或角色。连接成功和业务成功都不是这两项事实的替身。
一枚真密钥走错了验证通道
wolfSSL 在 5.9.2 版本说明中把 CVE-2026-55960 列为高危问题。条件是构建启用了 HAVE_RPK。在这种情况下,对端即使没有与本端协商 Raw Public Key,也可能发送一枚裸公钥并被接受为 X.509 的替代物。裸公钥本来就没有证书链;旧路径因此没有执行预期的链信任验证。
范围不能被夸大。独立构建默认不启用 RPK,--enable-all 才会把它带入。公开资料没有给出利用数量,也没有给出完整受影响版本区间。能够确认的是一条更具普遍性的失权路径:输入对象的形态反过来决定了验证制度,覆盖了握手已经作出的选择。
修复重新确立顺序。没有显式协商其他类型时,预期值就是 X.509;客户端比较服务器实际发来的形态与已选择类型,服务器也对客户端凭据做对称检查。不一致就返回 UNSUPPORTED_CERTIFICATE。对应 PR 还加入了两个方向的回归测试。
这不是“解析更严格”这么简单。解析器能够读懂一枚 SPKI,不代表它有权把证书链验证切换成裸公钥验证。类型协商首先授予某套验证规则执行权,收到的对象只能进入那条已获授权的通道。
裸公钥在线上究竟带了什么
RFC 7250 登记了 Raw Public Key 的 CertificateType 值 2,并定义 client_certificate_type 与 server_certificate_type。客户端说明自己能提供或处理哪些类型,服务器从共同集合中选择。它是一段受握手保护的协议决定,而不是库函数根据内容“自动识别”。
选择 RPK 后,Certificate 消息只装入一个 DER 编码的 SubjectPublicKeyInfo:算法标识、可选算法参数和公钥比特串。它与 X.509 证书内部的 SPKI 是同一种结构,但证书的其他部分不在场。
RFC 8446 在 TLS 1.3 中明确保留 RawPublicKey(2)。一旦协商成功,certificate_list 最多只有一个承载 SPKI 的条目。该标准同时给出了缺省规则:除非明确协商其他类型,证书类型必须是 X.509v3。
于是产生一条双向约束。已经选择 RPK 时,不能因为没有证书链就把合法凭据当残次品;没有选择 RPK 时,也不能因为 SPKI 结构正确就把它当便捷替代。需要核对的是“协商类型—实际形态”这对事实。
私钥持有证明没有给机器命名
TLS 1.3 的 CertificateVerify 将签名绑定到握手 transcript,说明对端持有与所给公钥对应的私钥;Finished 再确认双方握手状态一致。这份证明很强,但答案很窄:当前对端控制了这枚密钥。
它没有说明这枚密钥属于哪台设备、哪个 DNS 名称或哪个业务角色。RFC 5280 显示出两种凭据之间被主动移走的语义。在 X.509 中,CA 的签名认证公钥材料与证书主体之间的绑定;被签名的证书体还包括签发者、主体、序列号、有效期以及扩展。依赖方仍须验证路径、名称和策略,证书本身也不等于应用授权。但这些可验证陈述在裸 SPKI 中根本不存在。
所以 RFC 7250 要求通过带外机制把公钥与呈现它的实体绑定,并要求实现检查该绑定的状态。“状态”二字把问题从初次登记推向整个生命周期。制造时写入的指纹可能曾经正确;DNS 中的 TLSA 记录可能曾经正确;首次连接保存的键值也可能曾经正确。轮换、泄露、重新分配或退役之后,历史匹配不再等于当前身份。
外部绑定账本至少要保存:规范身份与角色;主机、服务、端口或对端范围;精确 DER SPKI 或指纹;授权者;生效和到期时间;前代与后继密钥;撤回状态;更新渠道;以及哪些验证端已经拒绝旧密钥。
实现接口把“外部”变成了可审计调用
wolfSSL 的 RPK 文档要求显式开启能力、配置双方证书类型,并由应用提供验证回调,在 TLS 之外认证收到的密钥。其 TLS 1.3 与 GnuTLS 互通示例能够建立连接,但在应用验证逻辑缺席时仍报告对端未验证。协议互通与身份成立是两个里程碑。
GnuTLS 从另一侧展示了最小数据模型。它可以按 host 与 service 查找已存公钥,区分“没有记录”和“记录存在但密钥不符”,还能附加到期时间或使用自定义后端。其文档也明确指出,普通证书验证无法处理没有证书体的 RPK,必须使用带外比较或类似 TOFU 的连续性规则。
接口存在并不意味着控制已经执行。运维证据还要回答:谁写入了首条记录,更新通道由谁签名,回调是否在本次握手实际运行,查询的是哪一版账本,命中之后开放了什么权限。
DANE 与固件把身份放在不同的时钟上
RFC 7250 把 DANE 列为一种外部绑定方式。RFC 6698 允许 DNSSEC 保护的 TLSA 记录选择 SPKI,并用完整值或摘要匹配。服务名称由此可以在 DNS 信任域内与密钥材料建立关系。
但发布不等于验证。客户端必须验证 DNSSEC,正确理解 TLSA usage、selector 与 matching type,并比较正确对象。没有执行这些步骤的客户端,不受那条记录约束。
轮换进一步暴露分布式状态。RFC 7671 建议先发布新关联,等待旧缓存过期,再部署相应密钥或证书,最后删除过时关联。过渡期间,不同验证端可能合理地看到不同代际。证据必须说明每个重要端点看到了哪一代、双密钥重叠是否仍在批准窗口内。
受限设备使用另一种慢时钟。RFC 7925 把 RPK 描述为无需承担完整证书与 PKI 成本的公钥密码入口,但设备通常要在通信前获得服务器公钥或其摘要。若设备寿命超过十年,信任变更依赖固件、配置下发与离线设备回归。握手字节变少,只是把生命周期工作移出了线路。
一次绿色连接至少要拆成七个事实
第一,配置允许哪些类型。第二,ClientHello 实际提供了什么。第三,双方最终选择了什么。第四,线上收到的是证书还是 SPKI。第五,CertificateVerify 与 Finished 是否证明了对应私钥持有。第六,哪一个外部来源、哪一版本、以何种新鲜度把该 SPKI 绑定到当前身份和角色。第七,应用最终放行了哪一项操作。
如果日志只保存 TLS success,类型混淆将无从追查。相同的成功位可能来自未协商 RPK、过期绑定、没有运行的回调或越界角色。相反,一枚由对端真实控制的 SPKI 被拒绝,也可能正是验证权边界有效的表现。
Heng Lu 的运行代码优先原则在这里提供的是证据方法,而不是替代 TLS 事实。RFC 规定语义,IANA 分配扩展编号,DNS 或配置系统发布绑定主张;最后的接受权在实际进程中,由类型不符拒绝、外部查询和应用授权分支共同执行。2026 年的补丁之所以重要,是因为它改变了这条执行路径。
证据边界
公开材料足以支持缺陷性质、受限构建条件和修复方式,但不能支持“已经被利用”、暴露部署数量或完整版本区间。本文也不把 RPK 判定为天然弱于 X.509。
在封闭且可更新的设备体系内,显式协商并由受保护账本绑定的裸公钥可以是合理选择。X.509 同样会因路径验证、状态或名称策略错误而失败。真正不能接受的是:一种凭据继承另一种凭据的放行结果,却逃开后者应执行的验证规则。
Sources
- wolfSSL 5.9.2 release
- wolfSSL PR 10702
- wolfSSL Raw Public Key support
- RFC 7250 — Using Raw Public Keys in TLS and DTLS
- RFC 8446 — TLS 1.3
- RFC 5280 — Internet X.509 PKI Certificate and CRL Profile
- RFC 7925 — TLS/DTLS Profiles for the Internet of Things
- RFC 6698 — DANE TLSA
- RFC 7671 — DANE Operations
- IANA TLS ExtensionType registry
- GnuTLS Raw public keys
- GnuTLS certificate verification
- Heng Lu — Running-Code Primacy
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
