3.2 KiB
title | tags |
---|---|
How to verify downloaded cosign signatures | cosign, images, containers |
We're currently working on a way to update the containers we're using for Dangerzone without having to issue new releases.
In order to do that, we push new container images to a container registry, and sign them with an hardware key.
In addition, we want to do the verification part without issuing HTTP requests, to avoid leaking the fact we're doing the check.
Signing the image is pretty straighforward, but verifying wasn't. There are tools for this but they mainly expect you're online and its okay to make network requests.
Signing the image
In order to use --sk
, you need to compile your own version of cosign
, which adds suport for hardware keys.
git clone https://github.com/sigstore/cosign.git
cd cosign
make cosign-pivkey-pkcs11key
Then, initialize the key.:
cosign piv-tool generate-key
# Or in case you want to disable the "touch" requirement
cosign piv-tool generate-key --touch-policy=never
And sign:
docker login
./cosign sign --sk ghcr.io/almet/dangerzone/dangerzone@sha256:fa948726aac29a6ac49f01ec8fbbac18522b35b2491fdf716236a0b3502a2ca7
You might also need the public key handy. Here is how to get it:
./dev/cosign/cosign public-key --sk > pub.key
Verifying the signature
First, download the signatures locally and store them in signature.json
cosign download signature ghcr.io/almet/dangerzone/dangerzone@sha256:fa948726aac29a6ac49f01ec8fbbac18522b35b2491fdf716236a0b3502a2ca7 > signatures.json
Then, we will need to extract the information from this signatures.json
file, and verify it in two different ways:
Either just check the signature against the payload, but bear in mind this won't do all the bells and whistles that come with sigstore / cosign. It will just verify that the signature matches the provided key.
# Extract the payload and the signature
cat signatures.json | tail -1 | jq -r .Base64Signature | base64 -d > signature
cat signatures.json | tail -1 | jq -r .Payload | base64 -d > payload
# Then, verify it with openssl
openssl dgst -sha256 -verify pub.key -signature signature payload
# Or with cosign
cosign verify-blob --key pub.key -signature signature payload
If you want (and you probably do) to verify the signature for the payload, the signed entry timestamp for rekor and the integrity of the rest of the properties (Sigstore SET), we will need to convert some of the keys to match the expected ones, and then invoke cosign:
# Convert the signature to a format known by --bundle
cat signatures.json | tail -1 | jq -r .Payload | base64 -d > payload
cat signatures.json | tail -1 | jq '{base64Signature: .Base64Signature, Payload, cert: .Cert, chain: .Chain, rekorBundle: {SignedEntryTimestamp: .Bundle.SignedEntryTimestamp, Payload: {body: .Bundle.Payload.body, integratedTime: .Bundle.Payload.integratedTime, logIndex: .Bundle.Payload.logIndex, logID: .Bundle.Payload.logID}}, RFC3161Timestamp}' > bundle.json
# And then use it when verifying
cosign verify-blob --key pub.key --bundle bundle.json payload
And 🎉, we've verified the signature offline!