名义上,在纯粹的“X.509”理念中,SSL 客户端应该以它认为合适的任何方式获取服务器的证书和所有需要的中间 CA 证书,但特别是通过与Directory对话,这是一个巨大的全球 LDAP 服务器,其中包含一切。
不幸的是,目录从未存在过(太集中、太复杂),因此实际协议必须包含一些用于发送证书本身的规定。它发生在SSL/TLS中:服务器发送自己的证书和一堆“可能帮助”客户端的其他证书。事实上,TLS 标准甚至指定服务器必须发送一个 ready-to-validate 链:
certificate_list
This is a sequence (chain) of certificates. The sender's
certificate MUST come first in the list. Each following
certificate MUST directly certify the one preceding it. Because
certificate validation requires that root keys be distributed
independently, the self-signed certificate that specifies the root
certificate authority MAY be omitted from the chain, under the
assumption that the remote end must already possess it in order to
validate it in any case.
特别要注意,自签名根本身可能包含也可能不包含。客户端从来不需要这个根(也从来没有),但发送它是“传统的”(IT 中的无数传统之一;没有用,但大多是无害的)。
如果无法验证服务器发送的确切链,客户端应该能够“按原样”验证证书链,并且允许(如“道德上合理的”)根据 TLS 标准拒绝握手。但是,如果服务器发送的内容不能直接使用,客户端也被允许(并鼓励)尝试重建一些其他链并验证它。现代浏览器可以做到这一点;他们将尝试使用本地已知的中间 CA 证书(在安装时获得或缓存),并且还可以下载额外的 CA 证书,遵循证书本身中的 URL(Authority Information Access扩展名)。至少(最近的)Windows 上的 IE 会这样做,但是,为了避免令人讨厌的先有鸡还是先有蛋的情况,它只会遵循http://URL,而不是https://. 在网络不稳定或超时的情况下,这些额外的下载可能需要一些时间,并且会使握手的健壮性降低。
总结:发送根不是强制性的,而是传统的(每次完整握手 +1 kB 的网络开销不太可能对性能产生任何显着甚至可检测的影响)。发送中间 CA 名义上是必需的,实际上是推荐的,尽管现代浏览器/操作系统可以通过使用替代证书链构建策略来恢复。