RFC-0134:软件更新时间依赖项

RFC-0134:软件更新时间依赖关系
状态已接受
领域
  • 软件交付
说明

取消了作为软件更新依赖项的时间同步。

问题
  • 78423
Gerrit 更改
  • 559721
作者
审核人
提交日期(年-月-日)2021-07-24
审核日期(年-月-日)2021-10-06

总结

此 RFC 消除了作为软件更新依赖项的时间同步。

设计初衷

Fuchsia 设备报告固定的“退避时间”,直到从网络或实时时钟同步时间。报告的时间目前实现为报告基础映像构建的大致时间,可能是几个月前。

与其他提前启动的用户不同,系统更新检查不会等待时间同步。如果在更新检查期间时间未同步,软件包解析器可能会间接使用往返时间作为 TLS 证书验证的一部分。这样做存在以下问题:

  1. 当退避时间早于证书的创建日期时,更新会失败并显示 CertNotValidYet 错误。由于可以通过不同的名称访问更新服务器和软件包服务器,因此该故障可能会出现在多个组件中。在这种情况下,如果时间同步中断,设备将会卡住,且不再更新。
  2. 在往返期间有效的过期证书可用于提供更新响应和软件包。

取消时间同步作为软件更新过程的依赖项可以解决第一个问题,并提高更新的可靠性。

设计

此 RFC 建议,软件更新不应依赖于可用的准确时间。

这意味着,它将:

  • 允许证书采用未来的有效期。

  • 即使时间已同步,也始终使用退避时间来验证证书。

实现

需要实现自定义 TLS 证书验证程序,并在 omaha-clientpkg-resolver 中使用该验证程序。

在构建期间,验证程序将从 UTC 时钟对象的 ClockDetails 获取往返时间,并将其保留为结构体的一个字段。

验证程序将使用 WebPKIVerifier 以及返回往返时间的时间函数来实现 ServerCertVerifier 特征,如果 WebPKIVerifier 返回 CertNotValidYet 错误,请使用处于证书有效期内的时间再创建一个 WebPKIVerifier 特征,然后重新调用它。

性能

自定义验证程序只是封装了幸福路径的 WebPKIVerifier,并且仅在第一次调用返回 CertNotValidYet 错误时才会调用 WebPKIVerifier 两次。

工效学设计

不适用

向后兼容性

API 没有任何变化。

安全注意事项

此设计将接受以下有效证书:

  • 晚于往返时间的过期 TLS 证书
  • 未来的 TLS 证书

虽然这并不理想,但第一种情况已经发生,因此不属于回归问题,而第二种情况的风险非常低。

此外,即使设备被诱骗安装了恶意更新,我们仍会验证执行情况,因此该设备无法启动并将还原。我们还具有回滚保护功能,因此签名的旧 build 也无法正常工作。

请注意,使用已泄露的证书和 DNS 控制的攻击者可能会诱使时间系统接受任意时间,因此即使我们让更新检查等待时间同步,这对这种情况也毫无帮助。

证书吊销不在此 RFC 范畴内,但在其他 RFC 的探讨中是一个很好的探索领域,尽管这种解决方案可能需要将过期的证书列为无限期吊销。

隐私注意事项

不会对隐私产生任何影响。

测试

对自定义证书验证程序进行广泛测试,确保其以后仅在一切都有效时接受证书。

针对 omaha-clientpkg-resolver 的集成测试,用于验证更新是否适用于非常旧的时间。

文档

不适用

缺点、替代方案和未知情况

替代方案:等待时间同步

在此模型中,我们在时间同步之前不会更新,虽然这为我们带来了一些安全优势,但这并不多,因为时间同步也可能会受损,但是这种模型使更新依赖于时间同步,而时间同步可能会由于各种原因而中断,从而导致更新的可靠性降低。

替代方案:等待时间,但在截止日期后更新

在此模型中,我们会等待任意时间的同步时间,并在时间尚未同步时执行更新检查。

虽然这种方法可以解决前一种替代方案的主要缺点,但其他方面也比较敏感。延迟是任意的:如果遇到启动循环的设备所延迟的时间短于此延迟,该延迟也永远不会更新。

此外,我们仍然依赖于往返时间,这可能意味着需要放宽证书验证的严格程度。

早期技术和参考资料

ChromeOS 没有这种问题,因为它没有往返时间,而且没有在 1970 年有效的 Google TLS 证书。