Re: [TLS] WGLC for draft-ietf-tls-ticketrequests

Tommy Pauly <> Mon, 03 February 2020 05:01 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 870281208C6 for <>; Sun, 2 Feb 2020 21:01:05 -0800 (PST)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -2.001
X-Spam-Status: No, score=-2.001 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (2048-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id 8QqVK8LiQjTh for <>; Sun, 2 Feb 2020 21:01:01 -0800 (PST)
Received: from ( []) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id BD2D51208BA for <>; Sun, 2 Feb 2020 21:01:01 -0800 (PST)
Received: from pps.filterd ( []) by ( with SMTP id 0134prew028291; Sun, 2 Feb 2020 21:00:59 -0800
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; h=sender : from : message-id : content-type : mime-version : subject : date : in-reply-to : cc : to : references; s=20180706; bh=rvnyuRVKrsXAXLz+aqQFFQguW47zfqn6EscbMFm3S98=; b=rGIVNo5WrRWsBPX3201SQqOorC1wzyd/oYr71O08K43m3z2RNzb3fYEATPC/6145YEVk kRBJOPZAblQHXV639ahTUaGyCBEfC5ozfytlrI3/jxVRPg8Si3B/26yK7bV8WETqXnVL Otpd5KXf+3L2SBYfCVFTlmFi035kio2QvvDBoUlYkVAcHvWNnhoig8eSB5olBWKyUEBb qOr01GZ7LYK33yUwcIQTTPUW9jJ7b7PSM5oAu7yC0fVCndigpLmRqoT9KBOT2hU/XpXG F7Uj74vpA3uLq1cdKRMjy5+6/AVc3YHPOKBgfcvgRJ4tRXoGjx94ypphPzbY0guqa6o0 nA==
Received: from ( []) by with ESMTP id 2xw6snfvw8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Sun, 02 Feb 2020 21:00:59 -0800
Received: from ( []) by (Oracle Communications Messaging Server 64bit (built Jul 4 2019)) with ESMTPS id <>; Sun, 02 Feb 2020 21:00:59 -0800 (PST)
Received: from by (Oracle Communications Messaging Server 64bit (built May 7 2019)) id <>; Sun, 02 Feb 2020 21:00:59 -0800 (PST)
X-Va-T-CD: 3ab6cfbeef9fe0930bcbd49ada4d0cd2
X-Va-E-CD: 7f7e14a8463c26a765e1ab3769b5d901
X-Va-R-CD: 6a2bc58b15f70a522f15c151e4c2a302
X-Va-CD: 0
X-Va-ID: 61d3819c-0559-43c1-b887-79fb9445e93a
X-V-T-CD: 3ab6cfbeef9fe0930bcbd49ada4d0cd2
X-V-E-CD: 7f7e14a8463c26a765e1ab3769b5d901
X-V-R-CD: 6a2bc58b15f70a522f15c151e4c2a302
X-V-CD: 0
X-V-ID: 0ba4722e-7fa2-4ca4-9063-bbea2da39bcb
X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2020-02-02_09:,, signatures=0
Received: from [] (unknown []) by (Oracle Communications Messaging Server 64bit (built May 7 2019)) with ESMTPSA id <>; Sun, 02 Feb 2020 21:00:59 -0800 (PST)
From: Tommy Pauly <>
Message-id: <>
Content-type: multipart/alternative; boundary="Apple-Mail=_A282E02D-F24D-4722-B397-BAF590D82E22"
MIME-version: 1.0 (Mac OS X Mail 13.4 \(3608.\))
Date: Sun, 02 Feb 2020 21:00:58 -0800
In-reply-to: <>
Cc: Viktor Dukhovni <>
References: <> <> <> <>
X-Mailer: Apple Mail (2.3608.
X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2020-02-02_09:, , signatures=0
Archived-At: <>
Subject: Re: [TLS] WGLC for draft-ietf-tls-ticketrequests
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "This is the mailing list for the Transport Layer Security working group of the IETF." <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Mon, 03 Feb 2020 05:01:06 -0000

I spoke with Viktor this afternoon about various scenarios being discussed on this thread. Going through the different use cases was very helpful in elucidating what functionality is appropriate.

The use cases we discussed are as follows. A and B are about multiple ticket requests. C and D are about ticket reuse. E is about both.

A. Multiple Tickets: Client with concurrent connections
In this scenario, a client may want to, from one initial TLS session, retrieve tickets for a pool of future connections. For this example, say this is four connections in a pool. On the initial connection, the client requests four tickets. It then can create four more connections, each with a unique ticket. From then on, each of those connections only requests a single ticket more, so as to get a ticket to replace the one they consumed. This allows a constant-sized pool of connections, where each connection gets to use tickets to resume.

If the server rejects a ticket due to deleting the session, the client can either continue to ask for one new ticket for each connection in the pool, or recognize that the tickets are no longer valid, and thus ask for a new batch (say, four new tickets) on the next handshake.

B. Multiple Tickets: Client with connection racing
For a client that wants a single connection, but may race connection establishment across address families (classic Happy Eyeballs) and interfaces (as in a mobile device case), the client may request a handful of tickets up front to allow connection racing. When racing, the client may consume, via connection attempts, more than one ticket to get one successful connection. For example, a client make use a ticket on a connection attempt over Wi-Fi, but then try LTE if Wi-Fi is stalling, and thus consume two tickets but only completes one connection. So, whenever a client knows it has consumed more tickets, it should try to repopulate the tickets. Note that it only knows how many it consumed *after* one is established, so it shouldn’t run its ticket collection dry on every connection attempt. Rather, it would probably make most sense to have enough tickets for two connection establishment attempts, such that any time many are consumed, the following handshake has the opportunity to ask for more.

If the server rejects a ticket due to deleting the session, all raced attempts for establishment will likely fail to resume together. Just like the case in which a client consumes many tickets due to racing, the client can only change the number of tickets it asks for on the *subsequent* handshake.

C. Single Ticket Reuse: Clients with trusted connection to the server, all/most clients reuse
If, in a controlled environment, a deployment wants to reuse tickets for resumption, the server can choose to allow that, and clients can choose to support that. If each client only needs a single ticket (since it can reuse its tickets), it doesn’t need to signal about multiple tickets. The one case in which it does need a new ticket is if the server deletes the session.

If the server knows that the majority of its clients reuse tickets, it can choose to simply give out a ticket only on the first handshake for a given client, or when a session has been deleted. For this case, no signaling should be needed.

D. Single Ticket Reuse: Clients wants to reuse (and server supports), most other clients do not reuse
As a variation, a server that supports ticket reuse in a situation when most of its clients do not support ticket reuse cannot simply only hand out tickets upon initial handshake, since most clients would then stop resuming. Instead, it would prefer to, by default, hand out a new ticket. For clients that *did* support reuse, it would be useful to have a signal. This signal is effectively a boolean to indicate that the client is happy with the tickets it currently has, and will reuse them unless the server gives out new tickets.

E. Multiple Ticket Reuse: Client want separate tickets for concurrent connections, that are later reused
Viktor described a case in which a client is split across multiple processes, so could be convenient to have independent tickets that are all retrieved from an initial connection that requested multiple handshakes, but the individual processes would want to treat those tickets as reusable until the server deleted the session. This case would want to both be able to request multiple tickets, and signal that reuse is possible.


The questions I think that are most relevant are, based on our discussion:

How many distinct pieces of information are there that could be communicated from client to server?
Are any of these pieces fundamentally entangled, or should they be communicated separately? Is any capability lost by allowing them to be communicated separately?

To answer question 1, there are a few possible pieces of information that the client can send:
First is the item in the current draft, the Integer number of tickets that a client would like to receive from the server, based on the client’s current knowledge (how many tickets it already has, and if it is a new handshake or a resumption). This shows up in cases (A), (B), and (E).
Next is the Boolean value that indicates that a client intends to reuse the ticket(s) it already has, as a request to the server to only send tickets if the old one won’t work. This is what Viktor originally proposed to use as a sentinel value in the Integer space. This shows up in cases (C), (D), and (E).
A third possible item is a case that was brought up in our discussion: the Integer number of tickets that a client would like to receive if the current resumption attempt fails. The idea here is that a client in case (A) would be happy to only receive one ticket if the session is still valid, but would possibly want an entirely new batch (such as 4) if the resumption fails, so it can restock its ticket pool. This is certainly an interesting case, and one that I do consider to be in scope for the document, but I do have concerns that it does not apply well to all cases. For example, in scenario (B), the client is racing multiple connection attempts. If two or more raced attempts do hit the server at the same time, and the session state has been deleted, having all of them start to request more tickets than they would otherwise may end up requesting too many. Since the cases like (B) do often need to adjust their requests on subsequent handshakes, it seems to me that it is simpler to have only one value, and err on the side of requesting too few tickets on occasion instead of requesting some exponential amount. However, if people have particular opinions on this, I’d like to hear them!

So, to sum up, there are two possible Integer values to send, and one possible Boolean value to send.

To answer question 2, I’d point to the example use cases to conclude that, at the very least, the Integer number of tickets, and Boolean client intent to reuse tickets, are indeed separate pieces of information. Cases (A) and (B) only are concerned with the number of tickets. Cases (C) and (D) are only concerned with signaling ticket reuse. Case (E) could take advantage of both.

If we consider that these two pieces of information are independent, and can be used either separately or together, we can evaluate the possible approaches:
The initial proposal to carve out a sentinel value from the Integer request count space to signal the reuse Boolean. This approach has the downsides of not allowing the values to be communicated together, as well as requires that any implementation that supports one value must also write logic to support the other. As we see above, many of the use cases only need one.
The ticket_request struct could contain two separate values, an Integer and a Boolean. In this case, the values can be communicated alongside on another, which is good. It does still require handling both values in an implementation that only uses one.
Use the ticket_request extension for the Integer, and create a new prefer_ticket_reuse extension for the Boolean. This allows flexibility of communication, and also allows the semantics of this new extension to be defined, and to potentially have server response (which the ticket_request extension doesn’t have).

Viktor expressed two concerns with the separation proposed in approach 3:

First, the concern that the working group wouldn’t work on any more extensions around tickets. I hope that this would not be the case! Any valid use case that the working group sees fit to work on should be open to be worked on, and it is not the intent of the ticket request draft to preclude any future extensions that interact with tickets in other ways, such as specifying reuse policies.

Second, the concern that server processing logic would be too complex if these values weren’t combined. This I do want to dig into a bit.
From the server’s perspective, there should be three possibilities: the client uses only the ticket_request extension, the client uses only the prefer_ticket_reuse extension, or the client uses both the ticket_request and prefer_ticket_reuse extensions.
If the server supports both extensions, it should wait to process all client extensions before deciding how many tickets to send back. If the prefer_ticket_reuse extension is present, it would choose to not generate any new tickets unless session state was explicitly deleted; in that case, it would send tickets with a count hinted by ticket_request. My impression is that this does not actually constitute any more complexity in server implementation than if the values were present in a single extension, since the generation of tickets should wait until the server has finished the handshake anyway. The difference in implementation is only in the parsing, not in the processing.


Based on this analysis, I’d recommend the following:
The proposal for hinting ticket reuse should be written up as a new draft proposing an extension, with discussion on use cases around ticket reuse. The reuse discussion can continue around that document.
Consider adding text to draft-ietf-tls-ticketrequests to explain the fact that when racing connections, the client won’t necessarily know the number of tickets it will “consume”, so it should either have enough tickets for two subsequent handshake resumptions; or else use fewer tickets but potentially run out.

> On Feb 2, 2020, at 11:05 AM, Tommy Pauly <> wrote:
>> On Feb 2, 2020, at 9:53 AM, Viktor Dukhovni <> wrote:
>> On Sun, Feb 02, 2020 at 06:42:56AM -0800, Tommy Pauly wrote:
>>> If you did need a sentinel to indicate that you wanted to try to reuse
>>> a ticket (which you can always try if you want), it would make more
>>> sense to just make that sentinel be 255, etc, rather than creating two
>>> sentinels.
>> Sure, if you want to swap my 0 <-> 255, that'd be fine by me, then
>> 0--254 are "natural", and 255 means "only as needed".  If that's what it
>> takes to reach a compromise, I'm on board.
>>> The ticket reuse signaling that is proposed really is orthogonal to the *count* of tickets.
>> Except that it really isn't.  Reuse means: 0 tickets or 1 ticket when
>> the one presented is or soon will become unusable.  There's no way to
>> decouple that from the ticket count.
> I don’t see why one should limit the number of tickets that can be requested to only 1 in a case in which a client wants ticket reuse, since the entire point of this extension message is to allow requesting multiple. I understand that there may be some scenarios in which a client requests multiple on the initial handshake, and then wants only one more after that, but that’s not necessarily the case.
> For example, I connect once, and request 4 tickets so I can do happy eyeballs attempts (one for v4 and v6 on each Wi-Fi and Cell, say). When I try to connect later, I end up using all four of those tickets on attempts, but only one succeeds. Now I want 4 more, but only have one connection. If you wanted to have your ticket reuse signaling in this case, you’d want to express “either give me 4 new tickets, or let me know I can reuse the previous four”, in which case overloading values in the number of tickets is indeed reducing the expressivity of the mechanism.
> Tommy
>> -- 
>>   Viktor.
>> _______________________________________________
>> TLS mailing list
>> <>
>> <>
> _______________________________________________
> TLS mailing list
> <>
> <>