On Fri, Oct 20, 2023 at 04:07:21PM -0400, David Benjamin wrote:
> Thanks for the comments! Responses inline.
> 
> On Thu, Oct 19, 2023 at 3:17 PM Ilari Liusvaara <ilariliusva...@welho.com>
> wrote:
> 
> > Some quick thoughts:
> >
> > - The multiple certificates from one ACME order really scares me. It
> >   seems to me that can lead to all sorts of trouble.
> >
> 
> Certainly open to different mechanisms, though could you elaborate on
> the trouble? We started with this one because it's actually just fixing a
> mechanism ACME *already has*. RFC 8555, 7.4.2 has this bit:
>
>    The server MAY provide one or more link relation header fields
>    [RFC8288] with relation "alternate".  Each such field SHOULD express
>    an alternative certificate chain starting with the same end-entity
>    certificate.  This can be used to express paths to various trust
>    anchors.  Clients can fetch these alternates and use their own
>    heuristics to decide which is optimal.

Note the part "the same end-entity certificate.". The way I interpretted
the draft, returning different end-entity certificates would be allowed.


> Whether anyone has ever used this, I don't know. The "and use their own
> heuristics to decide which is optimal" bit is quite absurd. :-) Relative to
> that, all we've done is:

Yes, that gets sometimes used.


> But I suspect we'll want to define one where you make multiple orders too.
> That would probably work better for, e.g., Merkle Tree certs where the two
> issuances complete at very different times. But then, conversely, when the
> two paths actually share an end-entity certificate, I imagine a single
> order would be better so the CA knows it only needs to generate one
> signature. And then when they don't share an end-entity certificate but are
> similar enough in lifetime and issuance time, either seems fine, so we
> figured this was a reasonable starting point.

Well, I do not think it is feasible to use the normal ACME issuance
mechanism for Merkle Tree certificates. The issuance is just too slow.

And things like ACME ARI (which is required for actually handling
revocations) inherently assume each order can only result one 
certificate.
 
 
> > - If there can be only one certificate, one could send all the chains
> >   in one go via fist sending the certificate, then issuer chains each
> >   ended by entry describing the trust anchor.
> >
> 
> I'm not quite sure if I've parsed this right, but are you thinking of one
> file that somehow describes all alternatives together? That's plausible
> too. Like I said, we mostly did this one because ACME already did it, so we
> inferred that was The ACME Way. :-)

Yes, one file describing all alternatives together. I think that is
easier to work with than the existing alternatives mechanism (I don't
think most clients even support that).


> > - I am not sure this is useful for the client->server direction.
> >
> 
> Eh, it costs ~nothing to define it in both directions, just a global
> s/client/relying party/ and s/server/subscriber/ across the document. :-) I
> figure we may as well define it in both directions, and if some client
> certificate deployments find it useful, cool. On the Chrome side, if the
> operating systems could give us something like this, with pre-made paths
> and unambiguous rules for when to send each, I would be overjoyed. We spend
> quite a lot of time helping people debug misconfigurations and quirks
> around client certificate selection.

How useful it is is different from how difficult it is to specify. :-)


> > What I think is a simpler version that might work:
> >
> >
> > Information from root program to CA:
> >
> > - Root program name.
> > - For each trust anchor:
> >   * Trust anchor certificate.
> >   * First version TA appeared in.
> >   * Expiry time
> >   * List of indices.
> >
> > Indices can be reused after all TAs using those have expired.
> >
> >
> > Information from CA to TLS server for each TA:
> >
> > - For each root program:
> >   * Root program name
> >   * The first version TA appeared in.
> >   * List of indices.
> >
> > CA MUST NOT include entries that expire before the certificate.
> >
> >
> > Information from TLS client to TLS server:
> >
> > - Root program name.
> > - Root program version.
> > - List of revoked indices.
> >
> > The revoked indices specifies TAs that have been recently removed
> > before expiry (there could still be unexpired certificates out
> > there).
> >
> >
> > Chain is usable if it includes an entry where:
> >
> > a) Root program name matches, AND
> > b) Root program version is at least the first version, AND
> > c) Intersection of indices and revoked indices is empty.
> >
> > If TLS server has multiple configured certificates, it should skip ones
> > that have no usable chains. If no certificate has usable chain, it
> > should act like the extension was not sent.
> >
> 
> If I'm parsing this right, I think the main issue here is this presumes a
> removed CA will stop issuing certificates:
> 
> Suppose some CA is in v2 and then was removed in v3. We need to ensure
> certificates issued by that CA don't match a v3 client, so the server will
> send a different one. Immediately after removal, there are plenty of
> existing certs that predate v3's definition, so the relying party needs to
> ship in exclusion. However, we would like the exclusion to eventually fall
> off, or every historical removal will be sent in every ClientHello ever.

I think the mechansism is essentially the same as in the draft, just
with different wording. After sufficiently long time after distrust
(max cert lifetime + few days) the revocations can be dropped.


> If the CA ceases operation, the exclusions can be dropped then. But the CA
> may have good reasons to keep issuing. Consider root rotation. Unupdated
> clients won't trust the new root, and servers may still need to work with
> those clients for a long period of time. The CA may quite reasonably wish
> to continue issuing from that root until that is no longer the case. This
> may even happen during a distrust: it could be that one population of
> clients no longer trusts the CA, while another population of clients
> (perhaps some unupdatable devices somewhere) *only* trusts that CA. Servers
> that need to serve both populations could then deploy a different
> certificate for each, in which case the removed CA might continue issuing.
> It only takes *one* population of relying parties for it to be useful to
> keep issuing from that CA. And as long as *any* server has certificates
> from that CA installed, we need to account for them in cert selection
> somehow.

Oh yeah, that causes problems.

Maybe simplest attempt at fix would be to add revoked-in-version to
trust anchor information for revoked trust anchors.

Then TLS server can check v_first <= version < v_revoke.

Then after transition period:

- Old client: root_program, v_old, no revoke.
  * Old chain: Passes all checks.
  * New chain: v_first > version, so fails version check.
- New client: root_program, v_new, no revoke.
  * Old chain: version >= v_revoke, so fails version check.
  * New chain: Passes all checks.

 
> The way to square this is to have both a lower bound *and* an optional
> upper bound. If the CA knows it in v1, v2, but not v3 onwards, it can tell
> the server this. Once you add the upper bound, I *think* your sketch is
> basically our design (though I may have missed something). The main
> difference is rather than store a range in manifest and inclusion list,
> we've just listed each version individually. If you've got a
> latest_version_at_issuance entry, it means the range has no upper bound.

My sketch also has expiry, which immediately expires the root.

 
> We listed them out because that makes versions a bit more independent,
> which allows the root program to adjust its label allocations over time.
> For example, maybe the root program later decides it'd be useful to mark
> CAs that use some algorithm. Or perhaps some keys changed hands and we'd
> like to reflect that in the labels. Now, there's a little subtlety here
> because label changes take some time to be reliable. But after max_age +
> max_lifetime, all certificates will have the new information available.
> (Before then, the trust expression creation process will just tell you that
> you need to account for both old and new entries, so you may need to add a
> few more labels.) Also, when we went to describe the root program
> operation, it was much more straightforward to just talk about versions as
> independent, with minimal cross-talk between them.

It is possible to change label sets of old versions, the label changes
just take some time to propagate (the longest revoke holddown among
trust anchors covered). :-)

 
> Of course, labels probably won't change between versions much, so a range
> scheme would make the list more compact. We didn't go with that just
> because the exploded one was less complicated. We did some estimates and it
> didn't look like the compression was actually needed, so we omitted it.
> (These are not sent in TLS connections, just in the root program -> CA ->
> subscriber flow. We don't want them to be *humongous*, but we don't need to
> squeeze them that tightly.) But if folks prefer ranges, that's easy enough
> to add.

One thing I noticed is that the information is sorted, presumably for
binary search. However, straightforward binary search will not work
because of the variable length entries (and there are no sync markers
either).




-Ilari

_______________________________________________
TLS mailing list
TLS@ietf.org
https://www.ietf.org/mailman/listinfo/tls

Reply via email to