Re: [TLS] I-D Action: draft-housley-tls-tls13-cert-with-extern-psk-02.txt

Russ Housley <> Fri, 28 September 2018 20:41 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 7BF8D130E68 for <>; Fri, 28 Sep 2018 13:41:00 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -1.9
X-Spam-Status: No, score=-1.9 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001] autolearn=ham autolearn_force=no
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id 1gqDJhlt7mdU for <>; Fri, 28 Sep 2018 13:40:58 -0700 (PDT)
Received: from ( []) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 7A9BD127B92 for <>; Fri, 28 Sep 2018 13:40:58 -0700 (PDT)
Received: from localhost (localhost []) by (Postfix) with ESMTP id 5BE7E300A3D for <>; Fri, 28 Sep 2018 16:40:56 -0400 (EDT)
X-Virus-Scanned: amavisd-new at
Received: from ([]) by localhost ( []) (amavisd-new, port 10026) with ESMTP id bd_e--bQVOzu for <>; Fri, 28 Sep 2018 16:40:54 -0400 (EDT)
Received: from [] ( []) by (Postfix) with ESMTPSA id B2951300438; Fri, 28 Sep 2018 16:40:54 -0400 (EDT)
Content-Type: text/plain; charset=us-ascii
Mime-Version: 1.0 (Mac OS X Mail 11.5 \(3445.9.1\))
From: Russ Housley <>
In-Reply-To: <>
Date: Fri, 28 Sep 2018 16:40:54 -0400
Content-Transfer-Encoding: quoted-printable
Message-Id: <>
References: <> <> <>
To: David Benjamin <>
X-Mailer: Apple Mail (2.3445.9.1)
Archived-At: <>
Subject: Re: [TLS] I-D Action: draft-housley-tls-tls13-cert-with-extern-psk-02.txt
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: Fri, 28 Sep 2018 20:41:01 -0000


Thanks for reading the draft.

> The resumption flow in this draft looks odd to me. While the handshake flow is the same, the use cases differ between which identity should be in play and when to use it. Separate extensions and documents may be better. (I suppose saying the semantics change completely between resumption and external PSK is also an option, but that seems weird?)

This was my initial approach, offering just the certificate with an external PSK in the document, but Nick and Martin asked for the resumption PSK to be added.  I wish you had spoken back then ...

> First, identities:
> In the external PSK use case, my read is you intend for the certificate to still be the server identity? It seems external PSK is just meant as extra input to the key schedule and not authentication since it may be shared amongst a group. (I'll note that, if your concern is we've lost all our asymmetric crypto, trusting the CertificateVerify for authentication is a little fuzzy. Is the scenario that the group is trusted not to attack each other?)

No, that is not the concern.  I want to mix a PSK into the key schedule today, then in the future when a large-scale quantum computer comes into existence, the communications that were recorded are still unable to be decrypted, even though the attacker can learn the (EC)DHE shared secret.

Thus, I can trust the CertificateVerify today for authentication, but I am also relying on the external PSK for the long-term protection of the session content.

> The use case for resumption is very different. The one I'm familiar with is to avoid a resumption/0-RTT cliff when the client considers the CertificateVerify expired. As before, It needs to be clearly defined which identity is in use. This is particularly complicated with 0-RTT, where only the PSK is available for early data, and swapping identities is problematic. (HTTP/2 cross-name pooling gets especially messy.)
> This conflicts with the external PSK case which wants the certificate identity. The document addresses this in 3.3, by requiring the two to be identical, but this breaks much of the use case. It's rather common for servers to rotate certificates without dropping their session cache, to avoid a resumption cliff. (This assumes the protocol, e.g., HTTPS, does not care exactly which certificate is used, just that they are valid for a name.) This proposal leaves a gap in that scenario and means such servers must add extra state to sessions and conditionally disable 0-RTT in some cases.
> Such servers could fall back to 1-RTT resumption, which could use the certificate and ignore the PSK, but this mechanism is not very useful without 0-RTT. The benefit of 1-RTT resumption is bandwidth and CPU from not sending the certificate. But 1-RTT resumption/certs sends the certificate anyway. You may as well just do a full handshake.

Dealing with the use cases that were advocated by Nick and Martin, I cam up with this approach:

       IF client includes early_data
       /* prove server still has access to private key */
               send_client_hello(early_data, resumption_psk)
               IF msg.cert ^= context.previous_cert

       /* allow server to change certificate and private key */
               send_client_hello(NULL, resumption_psk)
               IF msg.cert ^= context.previous_cert
                       context.previous_cert = msg.cert

This avoids any change of identity when early_data is present.

> Second, when to use it:
> In the external PSK case, I gather the goal is to use the external PSK all the time? It carries no auth, so expiry is fuzzy. If you support it, you enable it.
> The resumption use case involves the client expiring the CertificateVerify signature. This is purely client policy which the server doesn't know a priori. Long before the signature is expired, the server shouldn't use tls_cert_with_psk because it's a bandwidth+CPU waste. After the signature has expired is too late. The client wouldn't be willing to encrypt early data at that point. (The client would also need to account for servers that don't support this draft.) tls_cert_with_psk should be used before but near expiry.
> The advertisement then wants extra meaning: I offered you a PSK identity (with some early data if you accept it) that I will accept instead of your certificate, but it is nearing expiry. Renewals will be rejected soon. So, in addition to using the PSK, consider re-asserting ownership of your certificate, to keep renewals useful.
> These two together suggest a slightly different design for in the resumption case.
> 1. If the client's session is, say, 75% of the way through the CertificateVerify life adds the extension. Otherwise, it omits it.
> 2. The server can acknowledge this extension to do PSK+Certs. Probably with 0-RTT as it's largely pointless otherwise.
> 3. The connection is authenticated with the PSK as before.
> 4. But any tickets issued off the connection authenticated with the certificate, which may be different.

Martin spoke for a positive confirmation that the server still has access to the private key.  I do not see that with step 3.

> Finally, on a more minor note:
>    TLS 1.3 does not permit the server to send a CertificateRequest
>    message when a PSK is being used.  This restriction is removed when
>    the "tls_cert_with_psk" extension is negotiated, allowing the
>    certificate-based authentication for both the client and the server.
>    If certificate-based client authentication is desired, this is
>    accomplished by the client sending the Certificate and
>    CertificateVerify messages as described in Sections 4.4.2 and 4.4.3
>    of [RFC8446].
> This restriction should be retained with 0-RTT, otherwise things become really strange with the connection's client identity changing partway through.

Martin spoke for the use of early_data when the server is using the same certificate.  If you look at the previous version of may draft, you will see it is aligned with your approach.