Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verification materials: certificate versus certificate chain? #29

Closed
woodruffw opened this issue Nov 23, 2022 · 8 comments
Closed

Verification materials: certificate versus certificate chain? #29

woodruffw opened this issue Nov 23, 2022 · 8 comments
Labels
enhancement New feature or request

Comments

@woodruffw
Copy link
Member

I noticed this while looking through the generated Python code for the protobufs. A VerificationMaterial is defined to contain an entire certificate chain:

// VerificationMaterial captures details on the materials used to verify
// signatures.
message VerificationMaterial {
        oneof content {
                PublicKeyIdentifier public_key = 1;
                X509CertificateChain x509_certificate_chain = 2;
        }
}

I might be misunderstand the use case or context here, but this doesn't currently make sense to me: a bundle bearing its own entire certificate chain is equivalent during verification to a signature from any untrusted signing party, since anybody could substitute the "public good" Fulcio cert chain for their own cert chain.

So, my question: is this intended to be an intermediate (non-terminated) cert chain, or is there some other use case that I'm missing? For sigstore-python, we almost certainly want to pass just one certificate in with our verification materials, and rely on TUF or another out-of-band system (like baked-in certs) to obtain the rest of the chain.

@woodruffw woodruffw added the enhancement New feature or request label Nov 23, 2022
@woodruffw
Copy link
Member Author

CC @znewman01, since you probably have thoughts/insights here!

@znewman01
Copy link
Contributor

This is an annoying terminology bug (see also sigstore/cosign#2472 ). There are two possible types of chain:

  1. (generic certificate chain) A chain from a leaf cert up to a trusted root.
  2. (Fulcio intermediate certificate chain) A chain from a Fulcio intermediate up to a pool of Fulcio roots.
  3. (truncated certificate chain) A chain from a leaf cert up to a trusted intermediate, which separately chains up to a trusted root.

A lot of Cosign/Sigstore uses the word "chain" to mean concept (2), and then when you provide a "chain" we automatically trust it: sigstore/cosign#2472

I think this should be avoided. Instead, anything that is automatically trusted should be referred to as a "root" of some sort.

For sigstore-python, we almost certainly want to pass just one certificate in with our verification materials, and rely on TUF or another out-of-band system (like baked-in certs) to obtain the rest of the chain.

This makes perfect sense, and is the primary use case. However, you could imagine viewing "one certificate" as "a chain of certificates of length 1" and maybe there'd even be settings where you'd want "a chain of certificates of length >1" (especially when using Sigstore with an existing CA).

So we meant this "chain" to be (3): a chain from (and including) the leaf cert up to the trusted intermediate; the trusted intermediate would be supplied out-of-band, using TUF.


Probably worth elaborating here in the docs.

@haydentherapper
Copy link
Collaborator

I don’t see a need to be too prescriptive with not including a root in the chain. Like TLS, verification can just ignore it if it’s present.

@znewman01
Copy link
Contributor

I don’t see a need to be too prescriptive with not including a root in the chain. Like TLS, verification can just ignore it if it’s present.

Agreed. But we should be prescriptive about not trusting the root from the chain.

@woodruffw
Copy link
Member Author

Thanks both! So, just to clarify: the presence of a certificate chain in a bundle, even a fully rooted one, should always be verified against the separately obtained Fulcio root (and potentially intermediates)? Am I understanding that correctly?

(And, by corollary: any root cert included in the chain should be completely ignored, potentially with a warning?)

@woodruffw
Copy link
Member Author

And then, one last question to make sure I understand everything 🙂: the reason we need support for chains and not just a single X.509 cert is because we want to support other (potentially private?) deployments of Sigstore, ones where leaf certs potentially have much longer verification chains? Or is there another use case?

@znewman01
Copy link
Contributor

And then, one last question to make sure I understand everything 🙂: the reason we need support for chains and not just a single X.509 cert is because we want to support other (potentially private?) deployments of Sigstore, ones where leaf certs potentially have much longer verification chains? Or is there another use case?

The use case that I'm most familiar with involves a traditional pre-existing CA used for identity (in place of Fulcio). I know there are folks trying to do that.

But you could also imagine a setting where you didn't distribute all Fulcio intermediates via TUF. (Maybe you make a fresh child intermediate on service start time, and staple that to returned certs. This is secondary to the other use case.

@woodruffw
Copy link
Member Author

Thanks again! I think that fully addresses my questions, so I'll close this out 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants