sigstore / protobuf-specs

Protocol Buffer specifications
Apache License 2.0
23 stars 29 forks source link

Trust root: switch to a trust "pool" over a set of CA chains #249

Open woodruffw opened 8 months ago

woodruffw commented 8 months ago

This would be a full generalization of #245: the TrustRoot as currently specified contains a 2D list (a list of CAs, each with one or more cert "chains"), which is now how X.509 talks about path validation (path validation in X.509 is an abstract graph construction, ending at any trust anchor regardless of whether it's self-signed or not).

As a concrete proposal: repeated CertificateAuthority certificate_authorities = 3; would be replaced by repeated X509Certificate trust_anchors or similar. This would remove some of their fields that are currently present in the CertificateAuthority message, but AFAICT these are mostly duplicates of X.509 state anyways (e.g. the subject and validity period).

From here, the semantics of trust_anchors would be "first chain wins," i.e. the trust distributor can decide whether to put an intermediate or root in the trust anchors, and clients are (per X.509) perfectly entitled to terminate chain construction as soon at they reach the trust anchor, even if the member is not a self-signed root. This would essentially imply the same thing as #245, but without the explicit ordering (since there is no true ordering in a cert pool).

CC @haydentherapper @jku @loosebazooka 🙂

loosebazooka commented 8 months ago

Would we lose the other metadata in CAs? Validity period doesn't necessarily need to march up with what is provided by the certificate. We could choose to deprecate it earlier than the certificate defined validity period. Url is also something we use in sigstore Java to define our signers

woodruffw commented 8 months ago

Would we lose the other metadata in CAs? Validity period doesn't necessarily need to march up with what is provided by the certificate. We could choose to deprecate it earlier than the certificate defined validity period.

Ah, I hadn't thought of this. To make sure I understand: is the value of an external validity that the trust root might still want to distribute a compromised CA, but limit its applicability to the period before the compromise? That makes sense if so, and seems like a good thing; I have some ideas for equivalent approaches if that's what it's needed for 🙂

Url is also something we use in sigstore Java to define our signers

Could you share an example of this? I don't think we look at the URL at all in sigstore-python, I'm wondering if we're missing something.

haydentherapper commented 8 months ago

In general I'm supportive of this, though Appu's question about keeping track of validity needs to be solved. Two thoughts:

Can we also have repeated X509Certificate untrusted_certs or repeated X509Certificate chain_builders so that we can distribute intermediates alongside trust anchors?

Besides the validity question, is there a benefit in keeping the existing field and making this a one-of? Providing the exact chain could be an performance optimization to avoid chain building, for example where you might have only one valid path through a bunch of intermediates.

Ah, I hadn't thought of this. To make sure I understand: is the value of an external validity that the trust root might still want to distribute a compromised CA, but limit its applicability to the period before the compromise? That makes sense if so, and seems like a good thing; I have some ideas for equivalent approaches if that's what it's needed for 🙂

Compromise is one reason (though in practice it may be hard to determine the window of compromise and we may be forced to rotate). The other is preventing a cryptographically valid CA wrt to its validity window from continuing issuing certificates after the signing key has been rotated. For example, maybe we forget to destroy the signing key after rotation, and someone steals it and uses it while the CA cert is still valid.

loosebazooka commented 8 months ago

Could you share an example of this? I don't think we look at the URL at all in sigstore-python, I'm wondering if we're missing something.

We use it to populate our fulcio client. We grab the only "valid" CA and apply it as our fulcio instance for signing. We don't need to do this I guess. But it makes trusted_root.json all that is needed (except oidc) to configure a signing client -- https://github.com/sigstore/sigstore-java/blob/main/sigstore-java/src/main/java/dev/sigstore/fulcio/client/FulcioClient.java#L79

jku commented 8 months ago

Could you share an example of this? I don't think we look at the URL at all in sigstore-python, I'm wondering if we're missing something.

This is something I want to do as it would really enable bootstrapping from just a trusted_root.json. The only issues I know of are: