6. 验证服务身份 (Verifying Service Identity)
6. 验证服务身份 (Verifying Service Identity)
本节为应用客户端软件实现者提供规则和指南, 用于实现应用服务身份验证算法.
6.1. 概述 (Overview)
从高层看, 客户端通过执行以下动作验证应用服务身份.各动作会在后续小节中定义:
-
客户端基于源域以及可选的所连接服务类型, 构造可接受参考标识符列表.
-
服务器以 PKIX 证书形式提供其标识符.
-
客户端检查每个参考标识符与呈现标识符, 以寻找匹配.
-
检查参考标识符与呈现标识符时, 客户端匹配标识符的源域, 并可选地匹配其应用服务类型.
除检查标识符外, 客户端自然还可能执行进一步检查, 以确保服务器被授权提供所请求的服务.不过, 这些检查并不是验证证书中呈现的应用服务身份, 因此具体方法, 例如查询本地策略信息, 不在本文范围内.
6.2. 构造参考标识符列表 (Constructing a List of Reference Identifiers)
6.2.1. 规则 (Rules)
客户端必须构造可接受参考标识符列表, 且必须独立于服务呈现的标识符来完成构造.
客户端用于构造参考标识符列表的输入可能包括用户在界面中键入的 URI, 例如网站 HTTPS URL, 已配置的账户信息, 例如用于检索信息或连接网络的特定主机域名或 URI, 这可能不同于用户名中的 DNS 域名部分, 网页中的超链接, 该链接触发浏览器检索媒体对象或脚本, 或者能够产生源域和应用服务类型的其他信息组合.
客户端可能需要从收到的输入中提取源域和应用服务类型.提取的数据必须只包含能够从输入中安全解析出的信息, 例如从 URI 的 "host" 组件或等价组件解析完全限定 DNS 域名, 或从 URI scheme 派生应用服务类型; 或者包含以不受网络攻击者篡改的方式派生的信息, 例如从通过客户端或系统配置显式建立的委派域取得数据, 通过 [DNSSEC] 解析数据, 或从人类用户显式信任的第三方域映射服务取得数据, 且客户端与该服务通信的连接或关联同时提供双向认证和完整性检查.这些考虑只适用于从输入中提取源域.如果输入本身无效或被污染, 例如用户点击了钓鱼攻击中恶意实体提供的链接, 客户端仍可能最终与意外的应用服务通信.
示例: 给定输入 URI
<sips:[email protected]>, 客户端会从 "scheme" 派生应用服务类型 "sip", 并从 "host" 组件或等价组件解析域名 "example.net".
列表中的每个参考标识符都应基于源域, 且不应基于派生域, 例如通过源域的 DNS 解析发现的主机名或域名.该规则很重要, 因为只有用户输入与呈现标识符之间的匹配, 才能让客户端确信该证书可合法用于保护客户端与服务器的通信.交互式客户端只有一种场景可以覆盖此建议并与源域以外的域名通信: 人类用户已将应用服务证书 "固定 (pin)" 到该替代域名, 如第 6.6.4 节和第 7.1 节进一步讨论.在这种情况下, 客户端用于构造参考标识符列表的输入可能包含多个完全限定 DNS 域名, 即源域和固定证书中的替代域.
客户端使用完全限定 DNS 域名和应用服务类型的组合, 按以下规则构造参考标识符列表:
-
列表应包含 DNS-ID.DNS-ID 类型的参考标识符可直接从完全限定 DNS 域名构造, 该域名可以是输入中包含或安全派生出的源域, 也可以是通过用户配置与源域显式关联的派生域.
-
如果该应用服务类型的服务器通常通过 DNS SRV 记录发现, 列表应包含 SRV-ID.
-
如果出于安全目的, 该应用服务类型的服务器通常与 URI 关联, 即正式协议文档规定在服务器证书中使用 URI, 列表应包含 URI-ID.
-
列表可以包含 CN-ID, 主要是为了与已部署基础设施保持向后兼容.
客户端在参考标识符列表中包含哪些标识符类型属于本地策略.例如, 在某些部署环境中, 只连接特定服务类型的客户端, 例如只连接 IM 服务的客户端, 可以被配置为只接受包含该应用服务类型 SRV-ID 的证书.在这种情况下, 客户端只会在参考标识符列表中包含与该应用服务类型匹配的 SRV-ID, 而不会包含 DNS-ID.相反, 更宽松的客户端, 即使也只连接特定服务类型, 也可能同时包含 SRV-ID 和 DNS-ID.
实现说明: 客户端软件实现者在可预见的未来很可能需要支持 CN-ID, 因为包含 CN-ID 的证书部署非常广泛.建议实现者持续关注证书签发策略的现状, 并在未来可行时迁移 away from CN-ID 支持.
实现说明: 客户端不需要以证书中的实际格式构造上述标识符, 例如 ASN.1 类型.它只需构造这些标识符在匹配目的上的功能等价物.
安全警告: 客户端禁止构造对应于 Common Name 类型以外相对可分辨名称 (RDN) 的参考标识符, 也禁止在呈现标识符中检查 Common Name 类型以外的 RDN.
6.2.2. 示例 (Examples)
通过 HTTPS 连接到 "www.example.com" 网站的 Web 浏览器可能有两个参考标识符: "www.example.com" 的 DNS-ID, 以及作为回退的 "www.example.com" 的 CN-ID.
通过 IMAPS 连接到 "example.net" 邮件服务且解析为 "mail.example.net" 的邮件用户代理可能有五个参考标识符: "_imaps.example.net" 的 SRV-ID (见 [EMAIL-SRV]), "example.net" 和 "mail.example.net" 的 DNS-ID, 以及作为回退的 "example.net" 和 "mail.example.net" 的 CN-ID.旧式邮件用户代理不会支持 [EMAIL-SRV], 因此通常会被显式配置为连接到 "mail.example.net"; 支持 SRV 的用户代理会从 "[email protected]" 形式的电子邮件地址派生 "example.net", 但也可能接受 "mail.example.net" 作为该服务参考标识符的 DNS 域名部分.
通过 SIP 连接到 "voice.example.edu" 语音服务的 VoIP 用户代理可能只有一个参考标识符: "sip:voice.example.edu" 的 URI-ID (见 [SIP-CERTS]).
通过 XMPP 连接到 "im.example.org" 即时消息服务的 IM 客户端可能有三个参考标识符: "_xmpp-client.im.example.org" 的 SRV-ID (见 [XMPP])、"im.example.org" 的 DNS-ID, 以及 XMPP 专用的 "XmppAddr" 值 "im.example.org" (见 [XMPP]).
6.3. 准备寻找匹配 (Preparing to Seek a Match)
客户端构造参考标识符列表并收到服务器以 PKIX 证书形式呈现的标识符后, 会检查其参考标识符与呈现标识符以寻找匹配.如果客户端耗尽参考标识符列表仍未找到匹配, 搜索失败.如果任一呈现标识符与某个参考标识符匹配, 搜索成功, 此时客户端应停止搜索.
实现说明: 客户端可被配置为执行多次搜索, 即匹配多个参考标识符.尽管本规范并不禁止这种行为, 但匹配多个参考标识符的规则属于实现事项或未来规范事项.
安全警告: 如果呈现标识符包含 DNS-ID、SRV-ID、URI-ID 或客户端支持的任何应用专用标识符类型, 客户端禁止为 CN-ID 类型参考标识符寻找匹配.
在应用后续章节给出的比较规则之前, 客户端可能需要按如下方式把参考标识符拆分成 DNS 域名部分和应用服务类型部分:
-
DNS-ID 类型参考标识符不包含应用服务类型部分, 因此可直接作为 DNS 域名用于比较.例如, "www.example.com" 的 DNS-ID 会得到 DNS 域名部分 "www.example.com".
-
CN-ID 类型参考标识符也不包含应用服务类型部分, 因此可直接作为 DNS 域名用于比较.如前所述, 本文规定 CN-ID 始终包含形式匹配 DNS 域名的字符串, 因而将 CN-ID 与包含用户友好名称的 Common Name 区分开来.
-
对 SRV-ID 类型参考标识符, DNS 域名部分是 Name, 应用服务类型部分是 Service.例如, "_imaps.example.net" 的 SRV-ID 会拆分为 DNS 域名部分 "example.net" 和应用服务类型部分 "imaps", 后者按 [EMAIL-SRV] 映射到 IMAP 应用协议.
-
对 URI-ID 类型参考标识符, DNS 域名部分是 "host" 组件或等价组件中的 "reg-name" 部分, 应用服务类型部分是与 [URI] 中 [ABNF] "scheme" 规则匹配的 scheme 名称关联的应用服务类型, 不包括 ":" 分隔符.如前所述, 本文规定 URI-ID 始终包含 "host" 组件或等价组件, 且其中包含 "reg-name".只匹配 [URI] 中的 "reg-name" 规则会把验证限制为 DNS 域名, 从而将 URI-ID 与包含 IP 地址、仅包含主机名, 或根本不包含 "host" 组件的 uniformResourceIdentifier 条目区分开.此外, 提取 "reg-name" 可能需要按 [URI] 的说明规范化 URI.例如, "sip:voice.example.edu" 的 URI-ID 会拆分为 DNS 域名部分 "voice.example.edu" 和应用服务类型 "sip", 后者按 [SIP-CERTS] 关联到 SIP 应用协议.
参考标识符的 DNS 域名部分和应用服务类型部分的详细比较规则见后续章节.
6.4. 匹配 DNS 域名部分 (Matching the DNS Domain Name Portion)
客户端必须按以下规则匹配参考标识符的 DNS 域名部分, 并且也应按第 6.5 节检查应用服务类型.规则会因待检查域是 "传统域名" 还是 "国际化域名" 而不同, 这两个术语在第 2.2 节中定义.此外, 为满足支持包含通配符 "*" 的呈现标识符的客户端需求, 本文为所谓 "通配符证书" 定义了补充规则.最后, 本文还规定了可检查 "CN-ID" 标识符类型的条件.
6.4.1. 检查传统域名 (Checking of Traditional Domain Names)
如果参考标识符的 DNS 域名部分是 "传统域名", 则把参考标识符与呈现标识符匹配时, 应按 [DNS-CASE] 澄清的方式, 对域名标签集合执行大小写不敏感的 ASCII 比较.例如, "WWW.Example.Com" 会在比较时转换为小写 "www.example.com".除第 6.4.3 节中通配符标签检查规则补充的情况外, 每个标签都必须匹配, 名称才被视为匹配.
6.4.2. 检查国际化域名 (Checking of Internationalized Domain Names)
如果参考标识符的 DNS 域名部分是国际化域名, 实现必须在检查域名前把其中任何 U-label [IDNA-DEFS] 转换为 A-label.根据 [IDNA-PROTO], A-label 必须按大小写不敏感的 ASCII 比较.除第 6.4.3 节中通配符标签检查规则补充的情况外, 每个标签都必须匹配, 域名才被视为匹配.另见第 7.2 节关于国际化域名中通配符的讨论.
6.4.3. 检查通配符证书 (Checking of Wildcard Certificates)
采用本规范规则的客户端可以把参考标识符与 DNS 域名部分包含通配符 "*" 的呈现标识符匹配, 该通配符可以构成标签的一部分或整个标签, 标签和域名的含义遵循 [DNS-CONCEPTS].
通配符证书的安全特性见第 7.2 节.
如果客户端把参考标识符与 DNS 域名部分包含通配符 "*" 的呈现标识符匹配, 则适用以下规则:
-
如果通配符所在标签不是呈现标识符的最左标签, 客户端不应尝试匹配, 例如不匹配 bar.*.example.net.
-
如果通配符是呈现标识符最左标签中的唯一字符, 客户端不应把它与参考标识符最左标签以外的任何内容比较.例如, *.example.com 会匹配 foo.example.com, 但不会匹配 bar.foo.example.com 或 example.com.
-
客户端可以匹配通配符不是标签唯一字符的呈现标识符, 例如 baz*.example.net、baz.example.net 和 bz.example.net 分别会被视为匹配 baz1.example.net、foobaz.example.net 和 buzz.example.net.不过, 如果通配符嵌入在国际化域名 [IDNA-PROTO] 的 A-label 或 U-label [IDNA-DEFS] 中, 客户端不应尝试匹配.
6.4.4. 检查 Common Name (Checking of Common Names)
如前所述, 如果呈现标识符包含 DNS-ID、SRV-ID、URI-ID 或客户端支持的任何应用专用标识符类型, 客户端禁止为 CN-ID 类型参考标识符寻找匹配.
因此, 当且仅当呈现标识符不包含 DNS-ID、SRV-ID、URI-ID 或客户端支持的任何应用专用标识符类型时, 客户端才可以作为最后手段检查 subject 字段 Common Name 中形式匹配完全限定 DNS 域名的字符串, 即 CN-ID.如果客户端选择把 CN-ID 类型参考标识符与该字符串比较, 它必须遵循 DNS-ID、SRV-ID 或 URI-ID 类型标识符的 DNS 域名部分比较规则, 如第 6.4.1 节、第 6.4.2 节和第 6.4.3 节所述.
6.5. 匹配应用服务类型部分 (Matching the Application Service Type Portion)
客户端检查 SRV-ID 和 URI-ID 类型标识符时, 必须不仅检查标识符的 DNS 域名部分, 还必须检查应用服务类型部分.客户端按第 6.3 节所述把标识符拆分为 DNS 域名部分和应用服务类型部分, 然后按第 6.4 节检查 DNS 域名部分, 并按以下小节检查应用服务类型部分.
实现说明: SRV-ID 或 URI-ID 类型标识符提供可检查的应用服务类型部分, 但该部分只与 SRV-ID 或 URI-ID 自身的 DNS 域名部分组合.例如, 如果客户端参考标识符列表包含 "_xmpp-client.im.example.org" 的 SRV-ID 和 "apps.example.net" 的 DNS-ID, 客户端会检查 (a) 应用服务类型 "xmpp-client" 与 DNS 域名 "im.example.org" 的组合, 以及 (b) DNS 域名 "apps.example.net".客户端不会检查 (c) 应用服务类型 "xmpp-client" 与 DNS 域名 "apps.example.net" 的组合, 因为其参考标识符列表中没有 "_xmpp-client.apps.example.net" 的 SRV-ID.
6.5.1. SRV-ID
SRV-ID 的应用服务名称部分, 例如 "imaps", 必须根据 [DNS-SRV] 以大小写不敏感方式匹配.注意, "_" 字符会按 [SRVNAME] 加在 DNS SRV 记录和 SRV-ID 中的服务标识符前面, 因而无需包含在任何比较中.
6.5.2. URI-ID
URI-ID 的 scheme 名称部分, 例如 "sip", 必须根据 [URI] 以大小写不敏感方式匹配.注意, ":" 字符是 scheme 名称与 URI 其余部分之间的分隔符, 因而无需包含在任何比较中.
6.6. 结果 (Outcome)
匹配过程的结果属于以下情形之一.
6.6.1. 情形 1: 找到匹配 (Match Found)
如果客户端找到与参考标识符匹配的呈现标识符, 则服务身份检查成功.在这种情况下, 客户端必须把匹配到的参考标识符用作应用服务的已验证身份.
6.6.2. 情形 2: 未找到匹配, 但证书已固定 (No Match Found, Pinned Certificate)
如果客户端没有找到与任何参考标识符匹配的呈现标识符, 但客户端此前已把应用服务证书固定到为本次通信尝试构造的列表中的某个参考标识符, 即第 1.8 节所解释的 "pinning", 且呈现证书与固定证书匹配, 包括第 7.1 节描述的上下文, 则服务身份检查成功.
6.6.3. 情形 3: 未找到匹配, 且无固定证书 (No Match Found, No Pinned Certificate)
如果客户端没有找到与任何参考标识符匹配的呈现标识符, 且此前没有把证书固定到为本次通信尝试构造的列表中的任何参考标识符, 则客户端必须按第 6.6.4 节处理.
6.6.4. 回退 (Fallback)
如果客户端是由人类用户直接控制的交互式客户端, 则它应告知用户存在身份不匹配, 并以错误证书错误自动终止通信尝试.这种行为更可取, 因为它能防止用户在敌对场景下无意绕过安全保护.
安全警告: 一些交互式客户端为高级用户提供选项, 允许其在存在身份不匹配的情况下继续接受, 从而把证书 "固定" 到客户端为本次通信尝试构造的列表中的某个参考标识符.虽然这种行为在某些专门场景中可能适当, 但一般而言只应暴露给高级用户.即便如此, 也需要极其谨慎地处理.例如, 应先鼓励高级用户终止通信尝试; 如果高级用户仍选择继续, 则强制其查看完整认证路径, 然后才允许其按用户选择临时或永久固定证书.
否则, 如果客户端是不受人类用户直接控制的自动化应用, 则它应以错误证书错误终止通信尝试, 并适当记录错误.自动化应用可以提供禁用此行为的配置项, 但默认必须启用该行为.