[openssl-dev] cert_cb and TLS tickets

David Benjamin davidben at google.com
Sat Dec 10 19:26:16 UTC 2016


(Resending from an address which is actually subscribed. Apologies if this
causes anyone to receive this twice.)

Here's the patch series which flipped it:
https://boringssl.googlesource.com/boringssl/+/4eb95ccfd64d46fad23f36238690594d02518467
https://boringssl.googlesource.com/boringssl/+/34202b93b6195e9c55402a6bc2653956d0cd26d8
https://boringssl.googlesource.com/boringssl/+/f01f42a2ce161657c6413ef71d7c04262c7abd56
https://boringssl.googlesource.com/boringssl/+/a933c38f1af3ad7b03974ca7d7300b9df2162117

This is mostly compatible but not completely, so OpenSSL may not be able to
do it. Actually, Fedor, you might be amused to learn Node even incompatible
with it before this change:
https://github.com/nodejs/node/pull/9347

The motivation was to flip our session resumption and cipher suite logic.
cert_cb must be called before cipher selection, and extensions must be
processed before cert_cb, hence the full reorder. (We'd already replaced
OpenSSL's callbacks with BoringSSL's "early callback" mentioned elsewhere
in the thread.) But I agree this is also a more sensible ordering.

Suppose a server which prefers GCM > CBC receives:
ClientHello{cipher_suites={GCM, CBC}, ticket=session{CBC}}

The preferred cipher suite is GCM, but OpenSSL will opt to resume the
session and end up negotiating CBC. This may happen if the client or server
changed but retained ticket continuity. (Common for servers. Or client
might persist sessions.) After those changes, BoringSSL will pick the
cipher first and only resume if the cipher matches.

The suboptimal negotiation is temporary in TLS 1.2, so it's not that
important. This assumes TLS 1.2 sessions are short-lived and TLS 1.2 ticket
renewal is rare (or at least doesn't extend lifetimes).

In TLS 1.3, we have psk_dhe_ke, renewal actually refreshes keys, resumption
is more valuable (0-RTT, while 1.2 1-RTT can be done with False Start), and
there may later be an extension to renew with fresh identity assertion. I
anticipate 1.3 resumption to be more continuous. This suboptimal
negotiation now persists. Better to pay a resumption miss once and break
the cycle.

Fortunately, the "cert_cb before ciphers" rule is only true in TLS 1.2
where cipher suites include the key type. TLS 1.3's decoupled negotiation
means OpenSSL can do reordered negotiation in 1.3 without breaking cert_cb
compatibility but keep 1.2's negotiation old-style. We did it for both
because it's easier to reason about, cleaner, and "mostly compatible".

Hope this helps,

David

On Sat, Dec 10, 2016 at 9:17 AM Fedor Indutny <fedor at indutny.com> wrote:

> Alessandro,
>
> Indeed I just checked BoringSSL's source and it calls cert_cb before
> resuming the session. Inviting David Benjamin into this conversation.
>
> David,
>
> Do you have any insights or motivation to share with us? The way BoringSSL
> handles session resumption + cert_cb is a correct one in my opinion, and
> I'm trying to persuade everyone here in this too :)
>
> Thank you,
> Fedor.
>
> On Sat, Dec 10, 2016 at 2:35 PM, Alessandro Ghedini <alessandro at ghedini.me
> > wrote:
>
> On Sat, Dec 10, 2016 at 11:13:48AM +0100, Fedor Indutny wrote:
> > This totally makes sense. Unfortunately, adding a new API method for this
> > means that I'll have to re-introduce ClientHello parser in bud, and make
> a
> > wider use of it in Node.js again.
>
> FWIW, BoringSSL offers an early callback that is passed a semi-parsed CH,
> and
> an API to extract specific extensions from it (though this returns the raw
> unparsed extension body). Something similar could be adopted for OpenSSL.
>
> Whether this should be called in the CH post process phase (immediately
> before
> cert_cb) or much earlier (like BoringSSL) is likely to affect the
> implementation
> though (e.g. I'm not sure if the CH buffer is still available in the post
> process).
>
> Might be worth noting that BoringSSL changed the CH processing recently, by
> moving the session resumption logic after cert_cb, which means cert_cb is
> now
> called every time, but without a SSL_SESSION being available. So calling
> the
> cert_cb unconditionally is not unheard of.
>
> Cheers
>
> --
> openssl-dev mailing list
> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
>
>
> --
> openssl-dev mailing list
> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mta.openssl.org/pipermail/openssl-dev/attachments/20161210/b5a02e96/attachment.html>


More information about the openssl-dev mailing list