3.3. NewSessionTicket 握手消息
该消息由服务器在 TLS 握手期间、ChangeCipherSpec 消息之前发送。如果服务器在 ServerHello 中包含了 SessionTicket 扩展, 则 必须 (MUST) 发送该消息。如果服务器没有在 ServerHello 中包含 SessionTicket 扩展, 则 不得 (MUST NOT) 发送该消息。该消息包含在用于创建和验证 Finished 消息的散列中。在完整握手的情况下, 服务器 必须 (MUST) 在发送票据之前验证客户端的 Finished 消息。在客户端验证服务器的 Finished 消息之前, 它 不得 (MUST NOT) 把该票据视为有效。如果服务器在 ServerHello 中包含了 SessionTicket 扩展之后, 又决定不想包含票据, 则它在 NewSessionTicket 握手消息中发送一个零长度票据。
如果服务器成功验证了客户端的票据, 则它 可以 (MAY) 通过在缩写握手中于 ServerHello 之后包含一条 NewSessionTicket 握手消息来续签该票据。客户端在验证服务器的 Finished 消息之后, 应当尽快开始为新连接使用该新票据。请注意, 由于更新后的票据在握手完成之前签发, 客户端可能在发起新连接之前尚未启用该新票据。在成功验证客户端的 Finished 消息之前, 服务器 不得 (MUST NOT) 假定客户端实际收到了更新后的票据。
NewSessionTicket 握手消息已被分配编号 4, 其定义在本节末尾给出。ticket_lifetime_hint 字段包含服务器关于该票据应存储多久的提示。该取值以网络字节序的 32 位无符号整数表示生命周期 (以秒为单位), 相对于收到该票据的时刻。取值 0 保留, 用于表示该票据的生命周期未指定。客户端 应当 (SHOULD) 在该时间到期时删除该票据及关联状态。它可以基于本地策略更早地删除该票据。服务器 可以 (MAY) 把票据视为比 ticket_lifetime_hint 中所述更短或更长的时间段内有效。
struct {
HandshakeType msg_type;
uint24 length;
select (HandshakeType) {
case hello_request: HelloRequest;
case client_hello: ClientHello;
case server_hello: ServerHello;
case certificate: Certificate;
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;
case server_hello_done: ServerHelloDone;
case certificate_verify: CertificateVerify;
case client_key_exchange: ClientKeyExchange;
case finished: Finished;
case session_ticket: NewSessionTicket; /* NEW */
} body;
} Handshake;
struct {
uint32 ticket_lifetime_hint;
opaque ticket<0..2^16-1>;
} NewSessionTicket;