Merge branch 'master' into kazuho/session-ticket-context
diff --git a/include/picotls.h b/include/picotls.h
index 85aa24e..70abcf8 100644
--- a/include/picotls.h
+++ b/include/picotls.h
@@ -982,6 +982,13 @@
*/
ptls_cipher_suite_t **tls12_cipher_suites;
/**
+ * (optional) session ID Context to segment resumption
+ */
+ struct {
+ uint8_t bytes[PTLS_SHA256_DIGEST_SIZE];
+ uint8_t is_set : 1;
+ } ticket_context;
+ /**
* (optional) list of CAs advertised to clients as supported in the CertificateRequest message; each item must be DNs in DER
* format. The values are sent to the client only when `ptls_context_t::require_client_authentication` is set to true.
*/
diff --git a/lib/picotls.c b/lib/picotls.c
index f37ff96..7f8fd9a 100644
--- a/lib/picotls.c
+++ b/lib/picotls.c
@@ -1703,10 +1703,13 @@
ptls_buffer_push16(buf, csid);
/* ticket_age_add */
ptls_buffer_push32(buf, ticket_age_add);
- /* server-name */
+ /* session ID context */
ptls_buffer_push_block(buf, 2, {
- if (server_name != NULL)
+ if (ctx->ticket_context.is_set) {
+ ptls_buffer_pushv(buf, ctx->ticket_context.bytes, sizeof(ctx->ticket_context.bytes));
+ } else if (server_name != NULL) {
ptls_buffer_pushv(buf, server_name, strlen(server_name));
+ }
});
/* alpn */
ptls_buffer_push_block(buf, 1, {
@@ -1719,7 +1722,7 @@
return ret;
}
-int decode_session_identifier(uint64_t *issued_at, ptls_iovec_t *psk, uint32_t *ticket_age_add, ptls_iovec_t *server_name,
+int decode_session_identifier(uint64_t *issued_at, ptls_iovec_t *psk, uint32_t *ticket_age_add, ptls_iovec_t *ticket_ctx,
uint16_t *key_exchange_id, uint16_t *csid, ptls_iovec_t *negotiated_protocol, const uint8_t *src,
const uint8_t *const end)
{
@@ -1745,7 +1748,7 @@
if ((ret = ptls_decode32(ticket_age_add, &src, end)) != 0)
goto Exit;
ptls_decode_open_block(src, end, 2, {
- *server_name = ptls_iovec_init(src, end - src);
+ *ticket_ctx = ptls_iovec_init(src, end - src);
src = end;
});
ptls_decode_open_block(src, end, 1, {
@@ -4006,7 +4009,7 @@
ptls_iovec_t ch_trunc)
{
ptls_buffer_t decbuf;
- ptls_iovec_t ticket_psk, ticket_server_name, ticket_negotiated_protocol;
+ ptls_iovec_t ticket_psk, ticket_ctx, ticket_negotiated_protocol;
uint64_t issue_at, now = tls->ctx->get_time->cb(tls->ctx->get_time);
uint32_t age_add;
uint16_t ticket_key_exchange_id, ticket_csid;
@@ -4029,7 +4032,7 @@
default: /* decryption failure */
continue;
}
- if (decode_session_identifier(&issue_at, &ticket_psk, &age_add, &ticket_server_name, &ticket_key_exchange_id, &ticket_csid,
+ if (decode_session_identifier(&issue_at, &ticket_psk, &age_add, &ticket_ctx, &ticket_key_exchange_id, &ticket_csid,
&ticket_negotiated_protocol, decbuf.base, decbuf.base + decbuf.off) != 0)
continue;
/* check age */
@@ -4046,15 +4049,22 @@
if (tls->ctx->max_early_data_size != 0 && delta <= PTLS_EARLY_DATA_MAX_DELAY)
*accept_early_data = 1;
}
- /* check server-name */
- if (ticket_server_name.len != 0) {
- if (tls->server_name == NULL)
- continue;
- if (!vec_is_string(ticket_server_name, tls->server_name))
+ /* check ticket context */
+ if (tls->ctx->ticket_context.is_set) {
+ if (!(ticket_ctx.len == sizeof(tls->ctx->ticket_context.bytes) &&
+ memcmp(ticket_ctx.base, tls->ctx->ticket_context.bytes, ticket_ctx.len) == 0))
continue;
} else {
- if (tls->server_name != NULL)
- continue;
+ /* check server-name */
+ if (ticket_ctx.len != 0) {
+ if (tls->server_name == NULL)
+ continue;
+ if (!vec_is_string(ticket_ctx, tls->server_name))
+ continue;
+ } else {
+ if (tls->server_name != NULL)
+ continue;
+ }
}
{ /* check key-exchange */
ptls_key_exchange_algorithm_t **a;