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"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution/digest"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/pkg/tarsum"
|
||||
"github.com/docker/docker/registry"
|
||||
"github.com/docker/docker/runconfig"
|
||||
"github.com/docker/docker/utils"
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// 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/vfs" // import the vfs driver so it is used in the tests
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/trust"
|
||||
"github.com/docker/docker/utils"
|
||||
)
|
||||
|
||||
|
@ -60,9 +61,16 @@ func mkTestTagStore(root string, t *testing.T) *TagStore {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
trust, err := trust.NewTrustStore(root + "/trust")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tagCfg := &TagStoreConfig{
|
||||
Graph: graph,
|
||||
Events: events.New(),
|
||||
Trust: trust,
|
||||
}
|
||||
store, err := NewTagStore(path.Join(root, "tags"), tagCfg)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue