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

How to get the Fulcio root certificate securely in verify-blob? #2134

Closed
wata727 opened this issue Aug 5, 2022 · 4 comments
Closed

How to get the Fulcio root certificate securely in verify-blob? #2134

wata727 opened this issue Aug 5, 2022 · 4 comments
Labels
question Further information is requested

Comments

@wata727
Copy link
Contributor

wata727 commented Aug 5, 2022

First of all, thank you for the great project and everyone involved in it. I'm a maintainer of an OSS project using cosign to sign release binaries. Our project uses GoReleaser for signing, and we run the following commands on the checksum:

COSIGN_EXPERIMENTAL=1 cosign sign-blob --output-certificate=checksum.txt.pem --output-signature=checksum.txt.keyless.sig checksum.txt

https://github.com/terraform-linters/tflint/blob/e7668cb182999e93a2e79534968d8ad686c14f14/.goreleaser.yml#L26-L37

To verify this, we provide a verification example as follows:

cosign verify-blob --cert checksums.txt.pem --signature checksums.txt.keyless.sig --certificate-github-workflow-repository=terraform-linters/tflint checksums.txt

https://github.com/terraform-linters/tflint/blob/e7668cb182999e93a2e79534968d8ad686c14f14/README.md#verification

However, I understand that this way does not verify the checksum.txt.pem's certificate chain against the Fulcio root trust, so it is not sufficient:
https://github.com/sigstore/cosign/blob/v1.10.1/cmd/cosign/cli/verify/verify_blob.go#L122-L129

To avoid this, I understand that I need to pass the Fulcio root certificate with the --certificate-chain option:
https://github.com/sigstore/cosign/blob/v1.10.1/cmd/cosign/cli/verify/verify_blob.go#L131-L139

Now the question is, how can I get this root certificate securely?

I have confirmed that I can get certificates locally using TUF by cosign initialize. I can use this to build a certificate chain like this:

cosign initialize
cat ~/.sigstore/root/targets/fulcio_intermediate_v1.crt.pem > fulcio_chained.crt.pem
echo >> fulcio_chained.crt.pem
cat ~/.sigstore/root/targets/fulcio.crt.pem >> fulcio_chained.crt.pem
echo >> fulcio_chained.crt.pem
cat ~/.sigstore/root/targets/fulcio_v1.crt.pem >> fulcio_chained.crt.pem

cosign verify-blob --cert checksums.txt.pem --cert-chain fulcio_chained.crt.pem --signature checksums.txt.keyless.sig --certificate-github-workflow-repository=terraform-linters/tflint checksums.txt
Verified OK

But I'm not sure I can trust this local cache. In my opinion, it's safest to also get this root certificate by the TUF client, like COSIGN_EXPERIMENTAL=1 cosign verify-blob:
https://github.com/sigstore/cosign/blob/v1.10.1/cmd/cosign/cli/verify/verify_blob.go#L220-L227

What do you think about this? Is there a better way?

@wata727 wata727 added the question Further information is requested label Aug 5, 2022
@asraa
Copy link
Contributor

asraa commented Aug 5, 2022

Hi @wata727! Thanks for the very thoughtful question, this is great.

You are exactly correct that that way does not verify the certificate chain. I think this was noted in a prior issue, but I can't find it right now.

To avoid this, I understand that I need to pass the Fulcio root certificate with the --certificate-chain option:

Correct.

But I'm not sure I can trust this local cache. In my opinion, it's safest to also get this root certificate by the TUF client, like

Yes, actually cosign initialize performs the same retrieval of the targets GetRoots() and GetIntermediates() like the code you linked to.

This is the code run to GetRoots():
https://github.com/sigstore/sigstore/blob/dbd7b3ace9d39828d0ee8d0e5b6a73101fe094aa/pkg/fulcioroots/fulcioroots.go#L83-L95

It creates a new TUF environment and gets the targets by name of the file or usage.

This is also what's called when you run cosign initialize.

That local cache is a full TUF repository that chains up to an embedded root in cosign, as is the GetRoots() in memory. I do agree though that it is less safe to pick and choose the files from the cache manually, since you are relying on knowing which filenames to chose by hand.

Honestly, by default, if no certificate chain is provided, then we SHOULD verify against the root pool retrieved from GetRoots().

@haydentherapper do you know if there was any discussion about this?

@haydentherapper
Copy link
Contributor

There hasn't been discussion about that. It'd be changing this behavior or this. Originally I will guess the thought was that by providing only the certificate, it's just a vehicle for providing the public key.
I'm fine with changing the behavior, either to mandate a chain be provided or fetch from TUF.

@wata727
Copy link
Contributor Author

wata727 commented Aug 6, 2022

Thank you for answering my question.

Honestly, by default, if no certificate chain is provided, then we SHOULD verify against the root pool retrieved from GetRoots().

Agreed.

I'm fine with changing the behavior, either to mandate a chain be provided or fetch from TUF.

Thank you for your comment. I've opened a PR to change the behavior. I would be happy to discuss the implementation here #2139.

@wata727
Copy link
Contributor Author

wata727 commented Aug 10, 2022

#2139 is merged. With this fix, the certificate chain will be verified against the Fulcio root trust by default if you pass the --cert option.

The answer to this question is "Fulio root trust is retrieved automatically, so you don't need to pass it with --cert-chain".

Thank you again to everyone who answered the question and participated in the code review.

@wata727 wata727 closed this as completed Aug 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants