diff --git a/integration/copy_test.go b/integration/copy_test.go index a94264b6..dbe88d97 100644 --- a/integration/copy_test.go +++ b/integration/copy_test.go @@ -1068,6 +1068,25 @@ func (s *CopySuite) TestCopyAtomicExtension(c *check.C) { assertDirImagesAreEqual(c, filepath.Join(topDir, "dirDA"), filepath.Join(topDir, "dirDD")) } +// copyWithSignedIdentity creates a copy of an unsigned image, adding a signature for an unrelated identity +// This should be easier than using standalone-sign. +func copyWithSignedIdentity(c *check.C, src, dest, signedIdentity, signBy, registriesDir string) { + topDir, err := ioutil.TempDir("", "copyWithSignedIdentity") + c.Assert(err, check.IsNil) + defer os.RemoveAll(topDir) + + signingDir := filepath.Join(topDir, "signing-temp") + assertSkopeoSucceeds(c, "", "copy", "--src-tls-verify=false", src, "dir:"+signingDir) + // Unknown error in Travis: https://github.com/containers/skopeo/issues/1093 + // c.Logf("%s", combinedOutputOfCommand(c, "ls", "-laR", signingDir)) + assertSkopeoSucceeds(c, "^$", "standalone-sign", "-o", filepath.Join(signingDir, "signature-1"), + filepath.Join(signingDir, "manifest.json"), signedIdentity, signBy) + // Unknown error in Travis: https://github.com/containers/skopeo/issues/1093 + // c.Logf("%s", combinedOutputOfCommand(c, "ls", "-laR", signingDir)) + assertSkopeoSucceeds(c, "", "--registries.d", registriesDir, "copy", "--dest-tls-verify=false", "dir:"+signingDir, dest) +} + +// Both mirroring support in registries.conf, and mirrored remapIdentity support in policy.json func (s *CopySuite) TestCopyVerifyingMirroredSignatures(c *check.C) { const regPrefix = "docker://localhost:5006/myns/mirroring-" @@ -1078,7 +1097,7 @@ func (s *CopySuite) TestCopyVerifyingMirroredSignatures(c *check.C) { c.Skip(fmt.Sprintf("Signing not supported: %v", err)) } - topDir, err := ioutil.TempDir("", "mirrored-signatures") // FIXME: Will this be used? + topDir, err := ioutil.TempDir("", "mirrored-signatures") c.Assert(err, check.IsNil) defer os.RemoveAll(topDir) registriesDir := filepath.Join(topDir, "registries.d") // An empty directory to disable sigstore use @@ -1112,16 +1131,10 @@ func (s *CopySuite) TestCopyVerifyingMirroredSignatures(c *check.C) { assertSkopeoFails(c, ".*Source image rejected: None of the signatures were accepted, reasons: Signature for identity localhost:5006/myns/mirroring-primary:direct is not accepted; Signature for identity localhost:5006/myns/mirroring-mirror:mirror-signed is not accepted.*", "--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"primary:mirror-signed", dirDest) - // Create a signature for mirroring-primary:primary-signed without pushing there. This should be easier than using standalone-sign. - signingDir := filepath.Join(topDir, "signing-temp") - assertSkopeoSucceeds(c, "", "copy", "--src-tls-verify=false", regPrefix+"primary:unsigned", "dir:"+signingDir) - // Unknown error in Travis: https://github.com/containers/skopeo/issues/1093 - // c.Logf("%s", combinedOutputOfCommand(c, "ls", "-laR", signingDir)) - assertSkopeoSucceeds(c, "^$", "standalone-sign", "-o", filepath.Join(signingDir, "signature-1"), - filepath.Join(signingDir, "manifest.json"), "localhost:5006/myns/mirroring-primary:primary-signed", "personal@example.com") - // Unknown error in Travis: https://github.com/containers/skopeo/issues/1093 - // c.Logf("%s", combinedOutputOfCommand(c, "ls", "-laR", signingDir)) - assertSkopeoSucceeds(c, "", "--registries.d", registriesDir, "copy", "--dest-tls-verify=false", "dir:"+signingDir, regPrefix+"mirror:primary-signed") + // Create a signature for mirroring-primary:primary-signed without pushing there. + copyWithSignedIdentity(c, regPrefix+"primary:unsigned", regPrefix+"mirror:primary-signed", + "localhost:5006/myns/mirroring-primary:primary-signed", "personal@example.com", + registriesDir) // Verify that a correctly signed image for the primary is accessible using the primary's reference assertSkopeoSucceeds(c, "", "--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"primary:primary-signed", dirDest) // … but verify that while it is accessible using the mirror location @@ -1129,6 +1142,20 @@ func (s *CopySuite) TestCopyVerifyingMirroredSignatures(c *check.C) { // … verify it is NOT accessible when requiring a signature. assertSkopeoFails(c, ".*Source image rejected: None of the signatures were accepted, reasons: Signature for identity localhost:5006/myns/mirroring-primary:direct is not accepted; Signature for identity localhost:5006/myns/mirroring-mirror:mirror-signed is not accepted; Signature for identity localhost:5006/myns/mirroring-primary:primary-signed is not accepted.*", "--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"mirror:primary-signed", dirDest) + + assertSkopeoSucceeds(c, "", "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", "--dest-tls-verify=false", regPrefix+"primary:unsigned", regPrefix+"remap:remapped") + // Verify that while a remapIdentity image is accessible using the remapped (mirror) location + assertSkopeoSucceeds(c, "" /* no --policy */, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"remap:remapped", dirDest) + // … it is NOT accessible when requiring a signature … + assertSkopeoFails(c, ".*Source image rejected: None of the signatures were accepted, reasons: Signature for identity localhost:5006/myns/mirroring-primary:direct is not accepted; Signature for identity localhost:5006/myns/mirroring-mirror:mirror-signed is not accepted; Signature for identity localhost:5006/myns/mirroring-primary:primary-signed is not accepted.*", "--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"remap:remapped", dirDest) + // … until signed. + copyWithSignedIdentity(c, regPrefix+"remap:remapped", regPrefix+"remap:remapped", + "localhost:5006/myns/mirroring-primary:remapped", "personal@example.com", + registriesDir) + assertSkopeoSucceeds(c, "", "--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"remap:remapped", dirDest) + // To be extra clear about the semantics, verify that the signedPrefix (primary) location never exists + // and only the remapped prefix (mirror) is accessed. + assertSkopeoFails(c, ".*Error initializing source docker://localhost:5006/myns/mirroring-primary:remapped:.*manifest unknown: manifest unknown.*", "--policy", policy, "--registries.d", registriesDir, "--registries-conf", "fixtures/registries.conf", "copy", "--src-tls-verify=false", regPrefix+"primary:remapped", dirDest) } func (s *SkopeoSuite) TestCopySrcWithAuth(c *check.C) { diff --git a/integration/fixtures/policy.json b/integration/fixtures/policy.json index 85251e35..dba1043e 100644 --- a/integration/fixtures/policy.json +++ b/integration/fixtures/policy.json @@ -34,6 +34,18 @@ "keyPath": "@keydir@/personal-pubkey.gpg" } ], + "localhost:5006/myns/mirroring-remap": [ + { + "type": "signedBy", + "keyType": "GPGKeys", + "keyPath": "@keydir@/personal-pubkey.gpg", + "signedIdentity": { + "type": "remapIdentity", + "prefix": "localhost:5006/myns/mirroring-remap", + "signedPrefix": "localhost:5006/myns/mirroring-primary" + } + } + ], "docker.io/openshift": [ { "type": "insecureAcceptAnything"