mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Add tests for loadManifest digest verification
Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
parent
1e653ab645
commit
74528be903
2 changed files with 128 additions and 0 deletions
|
@ -8,11 +8,13 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/docker/distribution/digest"
|
||||||
"github.com/docker/docker/image"
|
"github.com/docker/docker/image"
|
||||||
"github.com/docker/docker/pkg/tarsum"
|
"github.com/docker/docker/pkg/tarsum"
|
||||||
"github.com/docker/docker/registry"
|
"github.com/docker/docker/registry"
|
||||||
"github.com/docker/docker/runconfig"
|
"github.com/docker/docker/runconfig"
|
||||||
"github.com/docker/docker/utils"
|
"github.com/docker/docker/utils"
|
||||||
|
"github.com/docker/libtrust"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -181,3 +183,121 @@ func TestManifestTarsumCache(t *testing.T) {
|
||||||
t.Fatalf("Unexpected json value\nExpected:\n%s\nActual:\n%s", v1compat, manifest.History[0].V1Compatibility)
|
t.Fatalf("Unexpected json value\nExpected:\n%s\nActual:\n%s", v1compat, manifest.History[0].V1Compatibility)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestManifestDigestCheck ensures that loadManifest properly verifies the
|
||||||
|
// remote and local digest.
|
||||||
|
func TestManifestDigestCheck(t *testing.T) {
|
||||||
|
tmp, err := utils.TestDirectory("")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(tmp)
|
||||||
|
store := mkTestTagStore(tmp, t)
|
||||||
|
defer store.graph.driver.Cleanup()
|
||||||
|
|
||||||
|
archive, err := fakeTar()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
img := &image.Image{ID: testManifestImageID}
|
||||||
|
if err := store.graph.Register(img, archive); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := store.Tag(testManifestImageName, testManifestTag, testManifestImageID, false); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cs, err := img.GetCheckSum(store.graph.ImageRoot(testManifestImageID)); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if cs != "" {
|
||||||
|
t.Fatalf("Non-empty checksum file after register")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate manifest
|
||||||
|
payload, err := store.newManifest(testManifestImageName, testManifestImageName, testManifestTag)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error generating test manifest: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pk, err := libtrust.GenerateECP256PrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error generating private key: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sig, err := libtrust.NewJSONSignature(payload)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error creating signature: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := sig.Sign(pk); err != nil {
|
||||||
|
t.Fatalf("error signing manifest bytes: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
signedBytes, err := sig.PrettySignature("signatures")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error getting signed bytes: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dgst, err := digest.FromBytes(payload)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error getting digest of manifest: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// use this as the "bad" digest
|
||||||
|
zeroDigest, err := digest.FromBytes([]byte{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error making zero digest: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remote and local match, everything should look good
|
||||||
|
local, _, _, err := store.loadManifest(signedBytes, dgst.String(), dgst)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error verifying local and remote digest: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if local != dgst {
|
||||||
|
t.Fatalf("local digest not correctly calculated: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// remote and no local, since pulling by tag
|
||||||
|
local, _, _, err = store.loadManifest(signedBytes, "tag", dgst)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error verifying tag pull and remote digest: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if local != dgst {
|
||||||
|
t.Fatalf("local digest not correctly calculated: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// remote and differing local, this is the most important to fail
|
||||||
|
local, _, _, err = store.loadManifest(signedBytes, zeroDigest.String(), dgst)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("error expected when verifying with differing local digest")
|
||||||
|
}
|
||||||
|
|
||||||
|
// no remote, no local (by tag)
|
||||||
|
local, _, _, err = store.loadManifest(signedBytes, "tag", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error verifying manifest without remote digest: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if local != dgst {
|
||||||
|
t.Fatalf("local digest not correctly calculated: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// no remote, with local
|
||||||
|
local, _, _, err = store.loadManifest(signedBytes, dgst.String(), "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error verifying manifest without remote digest: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if local != dgst {
|
||||||
|
t.Fatalf("local digest not correctly calculated: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// bad remote, we fail the check.
|
||||||
|
local, _, _, err = store.loadManifest(signedBytes, dgst.String(), zeroDigest)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("error expected when verifying with differing remote digest")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/docker/docker/daemon/graphdriver"
|
"github.com/docker/docker/daemon/graphdriver"
|
||||||
_ "github.com/docker/docker/daemon/graphdriver/vfs" // import the vfs driver so it is used in the tests
|
_ "github.com/docker/docker/daemon/graphdriver/vfs" // import the vfs driver so it is used in the tests
|
||||||
"github.com/docker/docker/image"
|
"github.com/docker/docker/image"
|
||||||
|
"github.com/docker/docker/trust"
|
||||||
"github.com/docker/docker/utils"
|
"github.com/docker/docker/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -60,9 +61,16 @@ func mkTestTagStore(root string, t *testing.T) *TagStore {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trust, err := trust.NewTrustStore(root + "/trust")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
tagCfg := &TagStoreConfig{
|
tagCfg := &TagStoreConfig{
|
||||||
Graph: graph,
|
Graph: graph,
|
||||||
Events: events.New(),
|
Events: events.New(),
|
||||||
|
Trust: trust,
|
||||||
}
|
}
|
||||||
store, err := NewTagStore(path.Join(root, "tags"), tagCfg)
|
store, err := NewTagStore(path.Join(root, "tags"), tagCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue