这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战
8月份更文挑战主题:TLS1.3协议 |
---|
TLS1.3系列文章(6):TLS1.3握手之扩展载荷(1) |
许多TLS消息是由TLV(Tag-Length-Value)结构组成的。结构信息如下:
- "extension_type"表示特定扩展类型。
- "extension_data"包含特定扩展类型内容。
扩展消息通常下,以请求/响应的方式出现在握手流程中(尽管一些扩展没有对应的响应信息)。客户端在ClientHello消息中发送其扩展请求,服务器在ServerHello、EncryptedExtensions和HelloRetryRequest消息中发送其扩展响应。服务器在CertificateRequest消息中发送扩展请求,客户端可能以Certificate消息进行响应。服务器也可以在NewSessionTicket中发送未经请求的扩展,但客户端不直接响应这些。
在某些TLS实现中,除了HelloRetryRequest消息中的cookie扩展外,除非对端主动发起扩展请求,否则本端禁止主动发送扩展响应消息。这种情况下,如果收到了没有请求的响应的消息,本端应该发送“unsupported_extension"告警信息。
下表给出了扩展消息可能出现的握手流程位置,任何实现在收到一个可识别但是未经请求的扩展载荷,那么必须发送“illegal_parameter"消息。
当存在不同类型的多个扩展载荷时,扩展可以以任何顺序出现,但“pre_shared_key”必须是ClientHello中的最后一个扩展(但在ServerHello扩展块中可以出现在任何位置)
与TLS 1.2不同的是,TLS 1.3即使在resumption-PSK模式下,每次握手都重新协商扩展。然而,0-RTT参数是在先前握手中协商的,不匹配可能需要拒绝0-RTT。
2.4.1 Supported Versions
载荷结构如下:
“supported_version”载荷在客户端表示客户端支持的TLS版本号信息;在服务端表示服务端选中的TLS版本信息。Supported_Version载荷中按照优先级顺序列出了支持的TLS版本号,优先级高的在前。这个规范的实现必须在扩展中发送包含准备协商的TLS所有版本。
supported_version扩展载荷是TLS1.3新增扩展信息。如果想要协商TLS1.3,那么在ClientHello中必须包含此扩展信息。如果协商之前的TLS版本,则使用version字段进行协商。
supported_version字段的优先级要高于version字段的优先级。
协商TLS 1.3之前版本TLS的服务端必须设置ServerHello.version,且不能发送“supported_versions”扩展。 协商TLS 1.3的服务器必须以包含选定版本值(0x0304)的"supported_versions"扩展响应。必须将ServerHello.legacy_version字段设置为0x0303 (TLS 1.2)。客户端必须在处理其余ServerHello之前检查此扩展(虽然必须解析ServerHello来读取扩展)。如果此扩展出现,客户端必须忽略ServerHello.legacy_version值,且必须只使用"supported_versions"扩展来确定选定版本。如果ServerHello 中的"supported_versions"扩展包含客户端没提供的版本或者包含TLS 1.3之前的版本,客户端必须以"illegal_parameter" 告警终止握手。
2.4.2 Cookie
Cookie有两个主要目的:
- 允许服务器强制客户端展示其网络地址可达性(从而提供DoS保护)。 这主要用于非面向连接的传输
- 允许服务器向客户端卸载状态,从而可以发送HelloRetryRequest而不存储任何状态。 服务器通过将ClientHello的哈希存储在HelloRetryRequest cookie中(用一些合适的完整性算法保护)来实现。
有点类似于TCP中的Cookie机制、以及IKEv2中的Cookie机制
当发送HelloRetryRequest时,服务器可以向客户端提供“cookie”扩展(这是通常规则(只能发送出现在ClientHello中的扩展)的一个例外)。 当发送新的ClientHello时,客户端必须将HelloRetryRequest中收到的cookie复制到新ClientHello中的“cookie”扩展中。 客户端不得在后续连接initial ClientHello中使用Cookie。无状态服务器可能在第一个和第二个ClientHello之间接收到一个change_cipher_spec类型的未加密数据。因为服务器不存储任何状态,看起来就像接收到的第一个消息。无状态服务器必须忽略这些数据。
未完待续....