[TLS] OCSP Stapling confusion

Daniel Kahn Gillmor <dkg@fifthhorseman.net> Mon, 10 December 2018 01:12 UTC

Return-Path: <dkg@fifthhorseman.net>
X-Original-To: tls@ietfa.amsl.com
Delivered-To: tls@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 14AA9130DD2 for <tls@ietfa.amsl.com>; Sun, 9 Dec 2018 17:12:23 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -4.189
X-Spam-Level:
X-Spam-Status: No, score=-4.189 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, T_SPF_PERMERROR=0.01, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id CjDLKnssi_pn for <tls@ietfa.amsl.com>; Sun, 9 Dec 2018 17:12:20 -0800 (PST)
Received: from che.mayfirst.org (che.mayfirst.org [162.247.75.118]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 0E26B128AFB for <tls@ietf.org>; Sun, 9 Dec 2018 17:12:19 -0800 (PST)
Received: from fifthhorseman.net (unknown [IPv6:2001:470:1f07:60d:506c:b3ff:fe17:51b2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by che.mayfirst.org (Postfix) with ESMTPSA id EB4F1F99A for <tls@ietf.org>; Sun, 9 Dec 2018 20:12:18 -0500 (EST)
Received: by fifthhorseman.net (Postfix, from userid 1000) id 4F5092055A; Sun, 9 Dec 2018 20:11:51 -0500 (EST)
From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
To: tls@ietf.org
Date: Sun, 09 Dec 2018 20:11:48 -0500
Message-ID: <877egitcbv.fsf@fifthhorseman.net>
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="=-=-="; micalg="pgp-sha512"; protocol="application/pgp-signature"
Archived-At: <https://mailarchive.ietf.org/arch/msg/tls/CB5_f1s4i3KAJDk1ZmOR2zeDIOg>
Subject: [TLS] OCSP Stapling confusion
X-BeenThere: tls@ietf.org
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." <tls.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/tls>, <mailto:tls-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/tls/>
List-Post: <mailto:tls@ietf.org>
List-Help: <mailto:tls-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tls>, <mailto:tls-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 10 Dec 2018 01:12:23 -0000

I was trying to sort out concrete, specific advice for OCSP stapling
that provides security benefits for the server (and not just performance
and privacy benefits).  Either i'm easily confused, or it's a mess.  I
hope it's the former, please unconfuse me!

Given the IAB's statement from nearly two years ago about the value in
OCSP stapling [0], it's a little distressing to me how difficult it
seems to be to get it right in today's landscape.

  [0]   https://mailarchive.ietf.org/arch/msg/ietf-announce/j0JIIGhD-xvbaWxtGm2-pFK0JQ8

In the bullet points below, i'll refer to the status requester as the
"client", and the party returning the status as the "server".  I'm aware
that the roles could be reversed if the server is requesting client
certs, but i'm going to punt on that wrinkle for now, since the
straightforward/common case is confusing enough.

 * the status_request TLS extension doesn't provide a mechanism for
   stapling OCSP for intermediate certs.

 * the status_request_v2 extension does provide a mechanism for stapling
   intermediate OCSP, but it is deprecated by TLS 1.3 and TLS servers
   responding with a TLS 1.3 handshake MUST NOT send
   status_request_v2 in the ServerHello.

 * the location of the stapled response has changed between TLS 1.2 and
   TLS 1.3 -- in 1.2 and below, the OCSP response data is carried in a
   CertificateStatus message.  In 1.3, it's in an Extension object
   associated with a Certificate, which allows certificate stapling for
   intermediate certs.  this is a good thing!  but a TLS client capable
   of both 1.2 and 1.3 that wants to be rigorous about stapling in both
   protocol versions has a much more complicated set of logic to worry
   about.

 * the certificate_status extension has its own internal extension
   point:

        enum { ocsp(1), (255) } CertificateStatusType;

   This goes against the "have one joint, and keep it well-oiled" design
   pattern we've learned over the years, because now you have the
   extension itself (certificate_status) and its own config selector.

   This results in another 8-bit registry to maintain: [1]
   
   [1] https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#certificate-status

   I think we should have omitted this additional joint, and just
   defined the certificate_status extension to be ocsp_status, without
   this field.  If someone wants to introduce a new status type, they
   can introduce a distinct TLS extension later.

 * I see no requirement that the CertificateStatusType in the
   CertificateStatus record actually matches the CertificateStatusType
   in the status_request extension sent by the client.

 * In TLS 1.2 and earlier, there is no obligation for a server which
   replies with the certificate_status extension to actually publish a
   CertificateStatus message.

 * Furthermore, if a status_request arrives at a TLS 1.2 or earlier
   server with a CertificateStatusType other than ocsp(1), or with
   non-empty ResponderID or Extensions members, it's conceivable that
   the server couldn't accurately create a corresponding OCSP response
   (either because it does not know about, or cannot contact any of the
   requested OCSP responders, or is for whatever reason unable to apply
   the requested OCSP extension(s).

 * the TLS Feature Request x.509v3 extension only indicates which
   extensions are supported in a generic, per-extension way.  So while a
   CA might be able to assert "this server will always reply with a
   status_request extension for this certificate", it doesn't appear to
   guarantee that (in 1.2) the server will actually send a
   CertificateStatus message at all, even if a status_request extension
   is sent, let alone whether the contents of that CertificateStatus
   message will be related to the client's status_request.  And in 1.3
   it doesn't guarantee that status_type will be ocsp(1) for the
   status_request extension that is sent.

 * Without the TLS Feature Request x.509v3 extension in the server's
   cert, there's no way to ensure that a compromised server can't just
   block the client from ever learning any OCSP details (e.g. by
   controlling the client's network).


So i think this is a big swirling mishmash of not-quite-compatible and
not-quite-complete specs, especially as we think about TLS clients and
servers that want to be interoperable with both TLS 1.2 and TLS 1.3.

In trying to figure out reasonable, useful guidance, and to make the TLS
Feature Request X.509v3 extension somehow useful, i'm tempted to try to
write up a clarifying/simplifying specification that actually cleans up
some of the semantics of status_request by cleaning up and enforcing the
currently-expected semantics.

In particular, i would want to propose something like:

 * regardless of TLS version, clients SHOULD NOT send status_request_v2,
   and servers SHOULD NOT return it even if the client supplies it.  If
   you want stapling for your intermediate certs, you need to have
   negotiated TLS 1.3.  (i think this is in line with the deprecation
   announced in 8446)

 * ask IANA to lock down the CertificateStatusType registry, or maybe
   remove it altogether.  status_type would then become just a legacy
   fixed value of 0x01 ("ocsp")

 * clients SHOULD always send ResponderID of length 0 and rely on the
   server to select an OCSP responder based on the AIA X.509v3
   extension's "OCSP" and "CA Issuers" fields in the server's
   certificate's X.509v3 extensions.

 * i'm not sure what to do about the Extensions field in status_request.
   For simplicty's sake, i'd like to say it should always be empty.  how
   much would we lose if we lost the ability to force in
   id-pkix-ocsp-nonce.

 * I'd like to redefine the semantics of what the TLS Feature Extension
   means for X.509 if it includes the status_request integer (5).  In
   TLS 1.2 and earlier, it means that if the client sends a
   status_request extension, a server MUST always send a
   CertificateStatus message after its Certificate message, and that
   CertificateStatus message MUST have status_type set to ocsp(1).  for
   TLS v1.3, it means that each CertificateEntry that contains this cert
   should also have a status_request extension, and that the extension's
   contents should match the expectations for v1.2 CertificateStatus
   messages described above (e.g., status_type=ocsp(1), no ResponderID).


additional conclusions for CAs
------------------------------

 * CAs must not issue certificates with a TLS Feature extension that
   indicates status_request_v2 for any server that intends to use the
   certificate with TLS 1.3, since TLS 1.3 servers are prohibited from
   responding with status_request_v2 extensions anywhere.


what do folks think of the above simplifications and subtle shifts in
semantics of already-defined code?  Is it worth trying to collect all
this into a single document with clear guidance to implementers, and a
promise that we will not extend status_request to non-ocsp mechanisms,
so that the X.509 TLS Feature Extension can be meaningfully applied for
this purpose?

Or does such a document already exist?  should we be encouraging
stapling as much as possible for security, in addition to performance
and privacy enhancements?

   --dkg