mirror of
https://github.com/containers/podman.git
synced 2025-11-29 09:37:38 +08:00
Add --sign-by-sq-fingerprint to push operations
This adds a new feature that allows signing using Sequoia-backed keys. The existing options to sign using GPG-backed keys (and sigstore) remain unchanged, and continue to use the same backends as usual. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
@@ -3,9 +3,9 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -13,9 +13,13 @@ import (
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
. "github.com/onsi/gomega/gexec"
|
||||
"go.podman.io/image/v5/signature/simplesequoia"
|
||||
"go.podman.io/storage/pkg/archive"
|
||||
)
|
||||
|
||||
// testSequoiaKeyFingerprint is a fingerprint of a test Sequoia key in testdata.
|
||||
const testSequoiaKeyFingerprint = "50DDE898DF4E48755C8C2B7AF6F908B6FA48A229"
|
||||
|
||||
var _ = Describe("Podman push", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
@@ -235,22 +239,26 @@ var _ = Describe("Podman push", func() {
|
||||
Expect(push2).Should(ExitCleanly())
|
||||
|
||||
if !IsRemote() { // Remote does not support signing
|
||||
By("pushing and pulling with --sign-by-sigstore-private-key")
|
||||
// Ideally, this should set SystemContext.RegistriesDirPath, but Podman currently doesn’t
|
||||
// expose that as an option. So, for now, modify /etc/directly, and skip testing sigstore if
|
||||
// we don’t have permission to do so.
|
||||
lookasideDir, err := filepath.Abs(filepath.Join(podmanTest.TempDir, "test-lookaside"))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
systemRegistriesDAddition := "/etc/containers/registries.d/podman-test-only-temporary-addition.yaml"
|
||||
cmd := exec.Command("cp", "testdata/sigstore-registries.d-fragment.yaml", systemRegistriesDAddition)
|
||||
output, err := cmd.CombinedOutput()
|
||||
registriesDFragment, err := os.ReadFile("testdata/sigstore-registries.d-fragment.yaml")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
registriesDFragment = bytes.ReplaceAll(registriesDFragment, []byte("@lookasideDir@"), []byte(lookasideDir))
|
||||
err = os.WriteFile(systemRegistriesDAddition, registriesDFragment, 0644)
|
||||
if err != nil {
|
||||
GinkgoWriter.Printf("Skipping sigstore tests because /etc/containers/registries.d isn’t writable: %s\n", string(output))
|
||||
GinkgoWriter.Printf("Skipping sigstore tests because /etc/containers/registries.d isn’t writable: %s\n", err)
|
||||
} else {
|
||||
By("pushing and pulling with --sign-by-sigstore-private-key")
|
||||
defer func() {
|
||||
err := os.Remove(systemRegistriesDAddition)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
}()
|
||||
// Generate a signature verification policy file
|
||||
policyPath := generatePolicyFile(podmanTest.TempDir, 5003)
|
||||
policyPath := generatePolicyFile(podmanTest.TempDir, 5003, "testdata/sequoia-key.pub")
|
||||
defer os.Remove(policyPath)
|
||||
|
||||
// Verify that the policy rejects unsigned images
|
||||
@@ -289,6 +297,40 @@ var _ = Describe("Podman push", func() {
|
||||
pull = podmanTest.Podman([]string{"pull", "-q", "--tls-verify=false", "--signature-policy", policyPath, "localhost:5003/sigstore-signed-params"})
|
||||
pull.WaitWithDefaultTimeout()
|
||||
Expect(pull).Should(ExitCleanly())
|
||||
|
||||
signer, err := simplesequoia.NewSigner(
|
||||
simplesequoia.WithSequoiaHome("testdata"),
|
||||
simplesequoia.WithKeyFingerprint(testSequoiaKeyFingerprint),
|
||||
)
|
||||
if err != nil {
|
||||
GinkgoWriter.Printf("Skipping Sequoia tests because simplesequoia.NewSigner failed: %s\n", err)
|
||||
} else {
|
||||
signer.Close()
|
||||
|
||||
By("pushing and pulling with --sign-by-sq-fingerprint")
|
||||
absSequoiaHome, err := filepath.Abs("testdata")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
defer os.Unsetenv("SEQUOIA_HOME")
|
||||
os.Setenv("SEQUOIA_HOME", absSequoiaHome)
|
||||
|
||||
// Verify that the policy rejects unsigned images
|
||||
push = podmanTest.Podman([]string{"push", "-q", "--tls-verify=false", "--remove-signatures", ALPINE, "localhost:5003/simple-sq-signed"})
|
||||
push.WaitWithDefaultTimeout()
|
||||
Expect(push).Should(ExitCleanly())
|
||||
|
||||
pull = podmanTest.Podman([]string{"pull", "-q", "--tls-verify=false", "--signature-policy", policyPath, "localhost:5003/simple-sq-signed"})
|
||||
pull.WaitWithDefaultTimeout()
|
||||
Expect(pull).To(ExitWithError(125, "A signature was required, but no signature exists"))
|
||||
|
||||
// Sign an image, and verify it is accepted.
|
||||
push = podmanTest.Podman([]string{"push", "-q", "--tls-verify=false", "--remove-signatures", "--sign-by-sq-fingerprint", testSequoiaKeyFingerprint, ALPINE, "localhost:5003/simple-sq-signed"})
|
||||
push.WaitWithDefaultTimeout()
|
||||
Expect(push).Should(ExitCleanly())
|
||||
|
||||
pull = podmanTest.Podman([]string{"pull", "-q", "--tls-verify=false", "--signature-policy", policyPath, "localhost:5003/simple-sq-signed"})
|
||||
pull.WaitWithDefaultTimeout()
|
||||
Expect(pull).Should(ExitCleanly())
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user