mirror of
https://github.com/almet/notmyidea.git
synced 2025-04-28 11:32:39 +02:00
80 lines
3.2 KiB
Markdown
80 lines
3.2 KiB
Markdown
---
|
|
title: How to verify downloaded cosign signatures
|
|
tags: cosign, images, containers
|
|
---
|
|
|
|
We're currently working on a way to update the containers we're using for [Dangerzone](https://dangerzone.rocks) 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.
|
|
|
|
```bash
|
|
git clone https://github.com/sigstore/cosign.git
|
|
cd cosign
|
|
make cosign-pivkey-pkcs11key
|
|
```
|
|
|
|
Then, initialize the key.:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
./dev/cosign/cosign public-key --sk > pub.key
|
|
```
|
|
|
|
## Verifying the signature
|
|
|
|
First, download the signatures locally and store them in `signature.json`
|
|
|
|
```bash
|
|
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.
|
|
|
|
```bash
|
|
# 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:
|
|
|
|
```bash
|
|
# 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 :tada:, we've verified the signature offline!
|