Re: [lamps] Last Call: <draft-ietf-lamps-hash-of-root-key-cert-extn-02.txt> (Hash Of Root Key Certificate Extension) to Informational RFC

Daniel Kahn Gillmor <dkg@fifthhorseman.net> Fri, 04 January 2019 00:07 UTC

Return-Path: <dkg@fifthhorseman.net>
X-Original-To: ietf@ietfa.amsl.com
Delivered-To: ietf@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id A9EEC130DEE; Thu, 3 Jan 2019 16:07:52 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.89
X-Spam-Level:
X-Spam-Status: No, score=-1.89 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, T_SPF_PERMERROR=0.01] 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 mhh7bfo73R6X; Thu, 3 Jan 2019 16:07:50 -0800 (PST)
Received: from che.mayfirst.org (che.mayfirst.org [IPv6:2001:470:1:116::7]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 43CF5131379; Thu, 3 Jan 2019 16:07:50 -0800 (PST)
Received: from fifthhorseman.net (ool-6c3a0662.static.optonline.net [108.58.6.98]) (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 68BEAF99A; Thu, 3 Jan 2019 19:07:46 -0500 (EST)
Received: by fifthhorseman.net (Postfix, from userid 1000) id 978842039A; Thu, 3 Jan 2019 18:12:29 -0500 (EST)
From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
To: Russ Housley <housley@vigilsec.com>
Cc: IETF <ietf@ietf.org>, LAMPS WG <spasm@ietf.org>, draft-ietf-lamps-hash-of-root-key-cert-extn@ietf.org
Subject: Re: [lamps] Last Call: <draft-ietf-lamps-hash-of-root-key-cert-extn-02.txt> (Hash Of Root Key Certificate Extension) to Informational RFC
In-Reply-To: <38891959-38F6-4FA5-B7B1-ACB50921E300@vigilsec.com>
References: <154594881588.11855.12133790922363153381.idtracker@ietfa.amsl.com> <1AB99D11-5B25-4A97-9FFD-17E318ADD739@vpnc.org> <87va35o7pe.fsf@fifthhorseman.net> <38891959-38F6-4FA5-B7B1-ACB50921E300@vigilsec.com>
Date: Thu, 03 Jan 2019 18:12:21 -0500
Message-ID: <87k1jlnxnu.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/ietf/3IkYUsR_3CfTzLMeeo3XCTAHKOU>
X-BeenThere: ietf@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: IETF-Discussion <ietf.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/ietf>, <mailto:ietf-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/ietf/>
List-Post: <mailto:ietf@ietf.org>
List-Help: <mailto:ietf-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/ietf>, <mailto:ietf-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 04 Jan 2019 00:07:53 -0000

Hi Russ--

thanks for the followup.

On Thu 2019-01-03 15:07:42 -0500, Russ Housley wrote:
> I could add a sentence here:
>
> 	If both checks succeed, then the potential Root CA certificate is
> 	added to the trust anchor store and the current  Root CA
> 	certificate is removed.
>
> Does that resolve your concern?

Yes, this final addition clarifies the intent of the document, thank
you.  I might prefer if it was active voice instead of passive, just to
be clearer about who is doing the addition and removal to the trust
store.  Is there a reason to avoid RFC 2119 language in these
descriptions?

> Please take a look at RFC 4210, Section 4.4 ("Root CA Key Update").

Please cite the relevant section number directly in the draft!

> The way that I read the section, it is describing a technique for
> protecting the new public key using the previous private key and vice
> versa.  The technique involves both old-with-new and new-with-old.
>
> To be more clear, I will refer to "this advice" in all of the places
> that reference RFC 4210.  The current text uses "this advice" in one
> place and "this technique" in another place.  I hope that will be more
> clear.

So i think you're now saying that people updating a key should use RFC
4210§4.4 guidance *in addition* to including the HashOfRootKey extension
in C1.  If that's what you mean, the draft should say it explicitly.

But (using the RFC 4210 terms), let's think about what happens to the
PSE (Personal Security Environment), the trust store (meaning the list
of trusted roots, which is a subset of the PSE, i guess, feel free to
correct if i'm misunderstanding 4210) and various certificates assuming
there are multiple heterogeneous subscribers seen by a single relying
party.

I'm working here on a TLS assumption -- if you're using these certs for
some other purpose (like LAMPS) maybe it won't apply, i'm not sure.  The
"Repository" referred to in RFC 4210 isn't something that many X.509
verification stacks have access to (and even if it was, checking it
during failed verification might raise privacy or latency concerns).

In my notation below, the CA starts with self-signed C1, and then moves
(via HashOfRootKey) to self-signed C2.  Meanwhile, the CA has also
generated COwN (the oldWithNew cert) and CNwO (the newWithOld cert).
(C1 is oldWithOld, and C2 is newWithNew, in 4210 lingo).

In my example, an end-entity cert might be written as EA or EB, and will
be signed by the root authority directly (i'm omitting traditional
intermediate certs for the sake of simplicity, though i note that COwN
and CNwO are effectively intermediate certs).

A valid simple certificate chain where end entity A is certified by the
first version of the CA looks like this: EA←C1.  Let's assume that all
servers ship their root CA certs as well (though TLS doesn't explicitly
require that, and people who care about latency are likely to try to
omit them -- should this draft explicitly recommend that TLS servers
ship root certs all the time just in case?).

in this example scenario, the relying party visits site end entity A
(which whose cert has been issued by the new C2), and then end entity B
(which is still using a cert issued by C1).

        | Trust |       | cert  |
 event  | Store | PSE   | chain | valid?   
--------+-------+-------+-------+----------
start   | C1    | C1    |       |
visit A | C2    | C1,C2 | EA←C2 | EA = ✓
visit B | C2    | C1,C2 | EB←C1 | EB = ?


It looks to me like EB will not validate, since:

 1) C1 is no longer a trusted root, despite being in the PSE
 
 2) COwN is not available to the relying party (and might not be known
    to server B either), so no chain can be formed to the only trusted
    root, C2

What am i missing?  This looks like a recipe for one party (A) to
accidentally damage another party (B) due to lack of coordination.

Furthermore, what happens if the relying party comes across CNwO before
C2?  It validates (signed by C1) but it is not self-signed.  But its
SPKI also matches C1's HashOfRootKey extension.  If it gets processed as
a new root, then C2 will *not* get processed (because C1 is already out
of the trust store, and C2 doesn't have the same HashOfRootKey as C1).
So now you'll have some RPs that have CNwO in their root store, and
others that have C2, depending on when they encountered it.  Hopefully
that won't cause any problems, but it makes me nervous.

Alternately, maybe this process *only* triggers when the cert we're
examining is self-signed.  Maybe the text "Whenever a new Root CA
certificate is received" is meant to only apply to self-signed
certificates?  perhaps it should be clearer on that, if that's the case
(subsequent text in that paragraph refers to "the self-signed
certificate", but the only "self-signed" antecedent in that paragraph is
the original "Root CA self-signed certificate" -- C1, not a potential
C2).

> The whole point of the old-with-new and new-with-old advice is that
> all of the certificates can be validated to either the old trust
> anchor or the new one.

only if the relying party has access both COwN cert as well as C2,
right?  If the TLS server ships only C1, then the RP is out of luck.

should COwN have the same subjectPublicKeyIdentifier extension as C1?
should CNwO have the same subjectPublicKeyIdentifier as C2?  if so,
should we say so explicitly?


>> So, without this draft offering a strong and immediate revocation
>> mechanism, and without it cleaning up the pre-existing new-root-cert
>> import mechanism, it does *not* make "rollover more secure" (since all
>> existing insecure channels will continue to exist).  It just makes good
>> rollover more convenient/automatic.
>
> Yes, that is the point of the extension.

thanks, that matches my mental model.

One other open question occurs to me: Should the relying party also
verify that Subject information (or other identity info) in the new cert
matches the old certificate?  I'm imagining a case where the old root CA
("O=L'Emporium de Foobar,OU=Authorité Racine,C=FR") ends up replacing
itself with ("O=Вооружённые Силы Союза Советских Социалистических
Республик,C=SU").  That would be pretty weird and upsetting, especially
if i didn't know how my "new" Soviet military cert got into my trust
store.  Would it be legitimate to cabin the scope of this rollover to
identical Subjects?

Finally, should a relying party place any bounds on the lifetime of the
new cert?  What if C2 appears, but has an *earlier* notBefore date than
C1?  that seems weird but maybe it isn't a problem.  But what if i've
added a cert to my root store with an known expiration date, and i don't
*want* a subsequent cert to suddenly have a later expiration date? (for
example, perhaps i'm in school and the school issues its own annual
certificate authority which i'm fine with accepting for now, but i don't
want to trust it after graduation)

How can an implementation determine the intent of the local system's
inclusion of certificate in the root store?  Should we encourage trust
store implementations to be able mark certificates as DO NOT UPDATE?  or
should we instead encourage users to understand inclusion of a
certificate in a root store as effectively unbounded in duration,
despite the existence of a validUntil field?

        --dkg