From 2bc432e5ecddbf8b3333b8288d7ed504bcfdba11 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Thu, 19 Jan 2017 16:28:43 -0800 Subject: [PATCH 1/2] image: Port to go-digest Outsource this stuff to avoid duplication of effort. newDescriptor was returning just the hex and createHashedBlob (its only consumer) was fixing that (by the "Normalize the hashed digest" comment) so it didn't have to split the hash (Hex) back off. But that seems confusing to me, so I've fixed newDescriptor to create a non-busted digest which we split back apart in createHashedBlob. Signed-off-by: W. Trevor King --- image/descriptor.go | 16 +++++++++------- image/image_test.go | 20 ++++++++++---------- image/manifest_test.go | 22 ++++++++++------------ 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/image/descriptor.go b/image/descriptor.go index 75fd390..f19642c 100644 --- a/image/descriptor.go +++ b/image/descriptor.go @@ -15,8 +15,6 @@ package image import ( - "crypto/sha256" - "encoding/hex" "encoding/json" "fmt" "io" @@ -24,6 +22,7 @@ import ( "path/filepath" "strings" + "github.com/opencontainers/go-digest" "github.com/pkg/errors" ) @@ -116,8 +115,13 @@ func (d *descriptor) validate(w walker, mts []string) error { } func (d *descriptor) validateContent(r io.Reader) error { - h := sha256.New() - n, err := io.Copy(h, r) + parsed, err := digest.Parse(d.Digest) + if err != nil { + return err + } + + verifier := parsed.Verifier() + n, err := io.Copy(verifier, r) if err != nil { return errors.Wrap(err, "error generating hash") } @@ -126,9 +130,7 @@ func (d *descriptor) validateContent(r io.Reader) error { return errors.New("size mismatch") } - digest := "sha256:" + hex.EncodeToString(h.Sum(nil)) - - if digest != d.Digest { + if !verifier.Verified() { return errors.New("digest mismatch") } diff --git a/image/image_test.go b/image/image_test.go index e8e7284..35ecb29 100644 --- a/image/image_test.go +++ b/image/image_test.go @@ -18,8 +18,6 @@ import ( "archive/tar" "bytes" "compress/gzip" - "crypto/sha256" - "fmt" "io" "io/ioutil" "os" @@ -28,6 +26,7 @@ import ( "strings" "testing" + "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -298,14 +297,16 @@ func createHashedBlob(name string) (descriptor, error) { return descriptor{}, err } - // Rename the file to hashed-digest name. - err = os.Rename(name, filepath.Join(filepath.Dir(name), desc.Digest)) + parsed, err := digest.Parse(desc.Digest) if err != nil { return descriptor{}, err } - //Normalize the hashed digest. - desc.Digest = "sha256:" + desc.Digest + // Rename the file to hashed-digest name. + err = os.Rename(name, filepath.Join(filepath.Dir(name), parsed.Hex())) + if err != nil { + return descriptor{}, err + } return desc, nil } @@ -317,15 +318,14 @@ func newDescriptor(name string) (descriptor, error) { } defer file.Close() - // generate sha256 hash - hash := sha256.New() - size, err := io.Copy(hash, file) + digester := digest.SHA256.Digester() + size, err := io.Copy(digester.Hash(), file) if err != nil { return descriptor{}, err } return descriptor{ - Digest: fmt.Sprintf("%x", hash.Sum(nil)), + Digest: digester.Digest().String(), Size: size, }, nil } diff --git a/image/manifest_test.go b/image/manifest_test.go index 81242e1..b75ac0a 100644 --- a/image/manifest_test.go +++ b/image/manifest_test.go @@ -18,14 +18,14 @@ import ( "archive/tar" "bytes" "compress/gzip" - "crypto/sha256" - "fmt" "io" "io/ioutil" "os" "path/filepath" "strings" "testing" + + "github.com/opencontainers/go-digest" ) func TestUnpackLayerDuplicateEntries(t *testing.T) { @@ -90,18 +90,17 @@ func TestUnpackLayer(t *testing.T) { gw.Close() f.Close() - // generate sha256 hash - h := sha256.New() + digester := digest.SHA256.Digester() file, err := os.Open(tarfile) if err != nil { t.Fatal(err) } defer file.Close() - _, err = io.Copy(h, file) + _, err = io.Copy(digester.Hash(), file) if err != nil { t.Fatal(err) } - err = os.Rename(tarfile, filepath.Join(tmp1, "blobs", "sha256", fmt.Sprintf("%x", h.Sum(nil)))) + err = os.Rename(tarfile, filepath.Join(tmp1, "blobs", "sha256", digester.Digest().Hex())) if err != nil { t.Fatal(err) } @@ -109,7 +108,7 @@ func TestUnpackLayer(t *testing.T) { testManifest := manifest{ Layers: []descriptor{descriptor{ MediaType: "application/vnd.oci.image.layer.v1.tar+gzip", - Digest: fmt.Sprintf("sha256:%s", fmt.Sprintf("%x", h.Sum(nil))), + Digest: digester.Digest().String(), }}, } err = testManifest.unpack(newPathWalker(tmp1), filepath.Join(tmp1, "rootfs")) @@ -151,18 +150,17 @@ func TestUnpackLayerRemovePartialyUnpackedFile(t *testing.T) { gw.Close() f.Close() - // generate sha256 hash - h := sha256.New() + digester := digest.SHA256.Digester() file, err := os.Open(tarfile) if err != nil { t.Fatal(err) } defer file.Close() - _, err = io.Copy(h, file) + _, err = io.Copy(digester.Hash(), file) if err != nil { t.Fatal(err) } - err = os.Rename(tarfile, filepath.Join(tmp1, "blobs", "sha256", fmt.Sprintf("%x", h.Sum(nil)))) + err = os.Rename(tarfile, filepath.Join(tmp1, "blobs", "sha256", digester.Digest().Hex())) if err != nil { t.Fatal(err) } @@ -170,7 +168,7 @@ func TestUnpackLayerRemovePartialyUnpackedFile(t *testing.T) { testManifest := manifest{ Layers: []descriptor{descriptor{ MediaType: "application/vnd.oci.image.layer.v1.tar+gzip", - Digest: fmt.Sprintf("sha256:%s", fmt.Sprintf("%x", h.Sum(nil))), + Digest: digester.Digest().String(), }}, } err = testManifest.unpack(newPathWalker(tmp1), filepath.Join(tmp1, "rootfs")) From adb0766b4dde2dabd5b27736c9f623088ea1bb7b Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Thu, 19 Jan 2017 16:38:53 -0800 Subject: [PATCH 2/2] glide.yaml: Lock go-digest to v1.0.0-rc0 By editing glide.yaml and then running: $ make update-deps to update the hash. This way we can bump go-digest intentionally when we feel so inclined. Signed-off-by: W. Trevor King --- glide.lock | 4 ++-- glide.yaml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/glide.lock b/glide.lock index a94dad3..3994d7a 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 9b4441d8a5beafc0334e55c3c0c98e32b60d51d7b0ceba8110b61b26f2b498fa -updated: 2017-02-06T10:48:09.882426248+08:00 +hash: 96d33c78edbe7fe735d07563db6d34f7493db27e52984ada2ff5aaa2ea434979 +updated: 2017-02-06T21:22:16.913065811-08:00 imports: - name: github.com/inconshreveable/mousetrap version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 diff --git a/glide.yaml b/glide.yaml index a6c6944..379f28d 100644 --- a/glide.yaml +++ b/glide.yaml @@ -1,5 +1,7 @@ package: github.com/opencontainers/image-tools import: +- package: github.com/opencontainers/go-digest + version: v1.0.0-rc0 - package: github.com/opencontainers/image-spec version: v1.0.0-rc4 subpackages: